AnsweredAssumed Answered

Help - continuous DMA with PIT

Question asked by comsosysarch on Jan 3, 2012
Latest reply on Nov 30, 2012 by Lothar Eichelberger

I have been using various configurations of DMA and generally with a little work I have managed to get them all running. Now I am trying a continuous DMA stream triggered by the PIT.

 

I want two 16-bit transfers per minor cycle (ie PIT trigger) from two contiuguous table entries in data RAM to two rigsters offset by 16 byte addresses. Then I want a bunch of minor cycles before the table addresses go back to the beginning.

 

It is not working.

I am getting a huge number of transfers at the very first PIT trigger, instead of just one full minor loop per PIT trigger.

For instance I set the PIT for several seconds and then a few seconds after starting I suddenly get a horde of DMA transfers, not just one minor loop.

 

Some of the DMA and PIT setup code for this DMA channel:

// uint16_t table[][2];

DMA_TCD tmpTCD;tmpTCD.SADDR = (void *)&warble[0][0];tmpTCD.DADDR = (void *)&FTM1_BASE_PTR->MOD;// target first register address is base + 8// target second register address is base + 16 + 8 * n (24 with n = 1)// all destination registers and source table entries are 16 bits// DMA destination set to toggle between addresses 8 and 24, so offset by 16 (8 to 24, or 24 to 40) modulo 2 ^ 5 (32, so 40 maps back to 8 etc)// modulo disabled on source table entriestmpTCD.ATTR = DMA_ATTR_SMOD(0) | DMA_ATTR_SSIZE(1) | DMA_ATTR_DMOD(5) | DMA_ATTR_DSIZE(1);tmpTCD.DOFF = 16;// and source table offset is just the size of one entry, or 2 (16 bits)tmpTCD.SOFF = 2; // two 16-bit transfers per channel timer request is 4 bytes per requesttmpTCD.NBYTES_MLNO = 4;// the cycle completes after the source table entries have been exhaustedtmpTCD.CITER_ELINKNO = sizeof(table) / sizeof(table[0]);tmpTCD.BITER_ELINKNO = sizeof(table) / sizeof(table[0]);// when the cycle completes, reset the source address to the first source table entrytmpTCD.SLAST = -sizeof(warble);tmpTCD.DLAST_SGA = NULL;// use no SGA, no DREQ, no interrupts, just keep streaming table data to the PWM pintmpTCD.CSR = 0;startDMA(&tmpTCD, ALWAYS_ENABLED_54);PIT_BASE_PTR->MCR &= ~PIT_MCR_MDIS_MASK; // clear MDIS to enable modulePIT_BASE_PTR->MCR |= PIT_MCR_FRZ_MASK;PIT_BASE_PTR->CHANNEL[FTM_SPKR_DMA].LDVAL = 150000; // 3ms update at 50 MHz K60 internal buss clockPIT_BASE_PTR->CHANNEL[FTM_SPKR_DMA].TCTRL |= PIT_TCTRL_TEN_MASK; // enable requests

 Any ideas what I am messing up so badly?

 

Outcomes