Teensy 3.5 DMA and PIT1 anomoly

Status
Not open for further replies.

MikeA

Member
Hi,

Can anyone explain why I need to set the NVIC priority for the PIT1 timer in order to use it to trigger the DMA? The code is a modifications of code on a previous thread to allow two different frequency waveforms on DAC0 and 1.

#define NSAMPLE 64
uint16_t dac0_buffer[NSAMPLE];
uint16_t dac1_buffer[NSAMPLE] ;

#define PDB_CONFIG (PDB_SC_TRGSEL(15) | PDB_SC_PDBEN | PDB_SC_CONT | PDB_SC_PDBIE | PDB_SC_DMAEN)
#define PDB_PERIOD (5)

void setup() {

while (!Serial && millis() < 800) ; // wait
Serial.println("DAC DMA");

// put some data into dac_buffer array
for (unsigned int i = 0; i < NSAMPLE; i++) {
float f = (float)i / (float)NSAMPLE;
dac0_buffer = -cosf(f * 2.0 * 3.14159) * 2000.0 + 2000;
}

for (unsigned int i = 0; i < NSAMPLE / 2; i++) {
dac1_buffer = i * 120 ;
}
for (unsigned int i = NSAMPLE / 2; i < NSAMPLE; i++) {
dac1_buffer = (NSAMPLE - i) * 120 ;
}
PIT1_setup() ;

// turn on DAC hardware
SIM_SCGC7 |= SIM_SCGC7_DMA;
SIM_SCGC6 |= SIM_SCGC6_DMAMUX;
DMA_CR = DMA_CR_EMLM | DMA_CR_EDBG; // minor loop mapping is available
SIM_SCGC2 |= SIM_SCGC2_DAC0;
DAC0_C0 = DAC_C0_DACEN; // 1.2V VDDA is DACREF_2

SIM_SCGC2 |= SIM_SCGC2_DAC1;
DAC1_C0 = DAC_C0_DACEN;

// set the programmable delay block to trigger DMA requests
SIM_SCGC6 |= SIM_SCGC6_PDB;
PDB0_IDLY = 1;
PDB0_MOD = PDB_PERIOD;
PDB0_SC = PDB_CONFIG | PDB_SC_LDOK;
PDB0_SC = PDB_CONFIG | PDB_SC_SWTRIG;
PDB0_CH0C1 = 0x0101;

DMAMUX0_CHCFG0 = 0 ;
DMAMUX0_CHCFG0 = DMAMUX_SOURCE_PDB | DMAMUX_ENABLE ;

// DMA will copy dac_buffer to the DAC on each PDB trigger

DMA_TCD0_SADDR = dac0_buffer;
DMA_TCD0_SOFF = 2;
DMA_TCD0_ATTR = DMA_TCD_ATTR_SSIZE(1) | DMA_TCD_ATTR_DSIZE(1);
DMA_TCD0_NBYTES_MLNO = 2;
DMA_TCD0_SLAST = -sizeof(dac0_buffer);
DMA_TCD0_DADDR = &DAC0_DAT0L;
DMA_TCD0_DOFF = 0;
DMA_TCD0_CITER_ELINKNO = sizeof(dac0_buffer) / 2;
DMA_TCD0_DLASTSGA = 0;
DMA_TCD0_BITER_ELINKNO = sizeof(dac0_buffer) / 2;
DMA_TCD0_CSR = 0; // no flags will loop the DMA forever

DMAMUX0_CHCFG1 = 0 ;
DMAMUX0_CHCFG1 = DMAMUX_SOURCE_PDB | DMAMUX_ENABLE | DMAMUX_TRIG;;

DMA_TCD1_SADDR = dac1_buffer;
DMA_TCD1_SOFF = 2;
DMA_TCD1_ATTR = DMA_TCD_ATTR_SSIZE(1) | DMA_TCD_ATTR_DSIZE(1);
DMA_TCD1_NBYTES_MLNO = 2;
DMA_TCD1_SLAST = -sizeof(dac1_buffer);
DMA_TCD1_DADDR = &DAC1_DAT0L;
DMA_TCD1_DOFF = 0;
DMA_TCD1_CITER_ELINKNO = sizeof(dac1_buffer) / 2;
DMA_TCD1_DLASTSGA = 0;
DMA_TCD1_BITER_ELINKNO = sizeof(dac1_buffer) / 2;
DMA_TCD1_CSR = 0; // no flags will loop the DMA forever

// DMA_CR |= DMA_CR_ERCA ; // set round robin priority
DMA_ERQ = 0x3; // enables 0 and 1
}

void loop() {
delay(5);
}
void pit1_isr() {
//Serial.println("pit irq") ;
}

void PIT1_setup () {
SIM_SCGC6 |= SIM_SCGC6_PIT ;
PIT_MCR = 0 ; // 0 enables the PIT timers
PIT_LDVAL1 = 50 ;
PIT_TCTRL1 = PIT_TCTRL_TEN ;//| PIT_TCTRL_TIE; // enables pit 1
PIT_TFLG1 = PIT_TFLG_TIF ; // clears flag prior to enabling IRQ
NVIC_SET_PRIORITY(IRQ_PIT_CH1, 250) ;
//NVIC_ENABLE_IRQ (IRQ_PIT_CH1) ;
}
 
Status
Not open for further replies.
Back
Top