I'm having a DMA problem that appears on the first time I use the DMA (subsequent DMA calls seem to be fine for some reason). Basically, an unrelated variable is getting written with garbage data. My flow is: I start up BLEcentral and press a button to enable the DMA.
The initial setup is given by these commands:
//SETUP AND ENABLE DMA uDMAEnable(UDMA0_BASE); //enable DMA uDMAControlBaseSet(UDMA0_BASE,sDMAControlTable); //specify dma control table EventRegister(EVENT_UDMA_PROG0,EVENT_TIMER0_A ); uDMAChannelDisable(UDMA0_BASE, UDMA_CHAN_TIMER0_A ); uDMAChannelAttributeDisable(UDMA0_BASE,UDMA_CHAN_TIMER0_A,UDMA_ATTR_USEBURST | UDMA_ATTR_ALTSELECT ); uDMAChannelAttributeEnable(UDMA0_BASE,UDMA_CHAN_TIMER0_A,UDMA_ATTR_HIGH_PRIORITY | UDMA_ATTR_REQMASK ); uDMAChannelPrioritySet(UDMA0_BASE,UDMA_CHAN_TIMER0_A);//set high priority uDMAChannelControlSet(UDMA0_BASE,UDMA_CHAN_TIMER0_A | UDMA_PRI_SELECT, UDMA_SIZE_32 | UDMA_SRC_INC_NONE | UDMA_DST_INC_NONE | UDMA_ARB_1); uDMAChannelTransferSet(UDMA0_BASE, UDMA_CHAN_TIMER0_A | UDMA_PRI_SELECT, UDMA_MODE_BASIC, (void *)(GPT1_BASE+GPT_O_TAR), (void *)(&val[0]),1); //ENABLE DMA uDMAChannelEnable(UDMA0_BASE, UDMA_CHAN_TIMER0_A); //enable dma gpt interrupt HWREG(GPT0_BASE+GPT_O_IMR) |= 0x00000020; //clear timer/dma flags TimerIntClear(GPT0_BASE,TIMER_TIMA_DMA); TimerIntClear(GPT1_BASE,TIMER_TIMA_TIMEOUT); HWREG(UDMA0_BASE+UDMA_O_REQDONE) |= 0x00000200; //clear req done flag for timer a TimerIntEnable(GPT0_BASE,TIMER_TIMA_DMA); //DMA interrupt enable TimerEnable(GPT0_BASE,TIMER_A); Hwi_Params_init(&hwiParams); hwiParams.enableInt = true; hwiParams.priority = 1; Hwi_construct(&hwi,INT_TIMER0A,GPT0_A_Isr,&hwiParams,NULL); //ISR for DMA DONE and re-setting up dma a second time.
When pressing the button, the following code is executed to allow the DMA to begin transferring when it gets a request
uDMAChannelAttributeDisable(UDMA0_BASE,UDMA_CHAN_TIMER0_A,UDMA_ATTR_USEBURST | UDMA_ATTR_ALTSELECT | UDMA_ATTR_REQMASK ); uDMAChannelTransferSet(UDMA0_BASE, UDMA_CHAN_TIMER0_A | UDMA_PRI_SELECT, UDMA_MODE_BASIC, (void *)(GPT1_BASE+GPT_O_TAR), (void *)(&val[0]) , 1);
where val is defined as
uint32_t val[2] ={0};
I set a breakpoint after this second DMA command and can watch the unrelated variable (lets call it varx and its defined as uint64_t varx[8]={0} ) change from varx[0] = 0 (its initialized value) to 2305850397631254600. Also since I've setup my DMA to run twice before stopping, the varx[1] gets changed from 0 to 1 on the second DMA transfer.
Obviously, this makes no sense for a number of reasons
1) the DMA is setup to be transferring val[0] and val[1], not varx[0] and varx[1].
2) val and varx are not located next to eachother in memory
3) the value 2305850397631254600 is constant and also much larger than the 32bit value contained in GPT1 TAR register
4) the DMA is triggering despite no event having occurred. It seems the first call to the DMA always causes it to do a transfer strangely.
Any ideas?
thanks