AnsweredAssumed Answered

Help with K22F eDMA

Question asked by Josh Jordan on Nov 20, 2014
Latest reply on Nov 20, 2014 by Josh Jordan

I am able to use the DMA in the KL26 to output to DMA using this tutorial Tutorial: PWM with DMA on ARM/Kinetis | MCU on Eclipse

But now I am using the K22F freedom board and have some problems.  I have tried using the dma channel bean and observed the code output but have not been able to see it work.  I have reduced the problem down to the following code- maybe a bit somewhere is being set incorrectly.  I have flextimer 0 channel 0 setup as a pwm and can see it output correctly if I change the value of FTM0_C0V in the debugger.  What I attempt to do is output a series of 5 pulses and then a 6th pulse set to 0 to turn off the pwm.  The following code is the dma bean output boiled down into readable code.  When this code runs, the FTM0_C0V remains zero and the dma never activates.

 

//setup clock gates for pwm and dma
SIM_SCGC6 |= SIM_SCGC6_FTM0_MASK|SIM_SCGC6_DMAMUX_MASK;
SIM_SCGC7 |= SIM_SCGC7_DMA_MASK;

 

//setup pwm module
FTM0_MOD = 74; //set timer period (75 ticks * 60MHz = 1.25us)
FTM0_C0SC = FTM_CnSC_ELSB_MASK|FTM_CnSC_MSB_MASK|FTM_CnSC_DMA_MASK; //edge-aligned pwm, enable dma request
PORTC_PCR1 |= PORT_PCR_MUX(4); //select alt4 for tmr0ch0 control see chapter 10 Signal Multiplexing and Signal Descriptions
FTM0_C0V = 0;
FTM0_SC = FTM_SC_CLKS(1); //enable FTM clock source

 

//configure channel 0 to send frame
DMAMUX_CHCFG0 = DMAMUX_CHCFG_ENBL_MASK|20; //see RM "DMA request sources"
DMA_ERQ &= ~(1<<0); //disable dma channel 0
DMA_TCD0_CSR = 0; //clears done flag and dreq bit
DMA_TCD0_NBYTES_MLNO = 2*6; //number of transfers
DMA_TCD0_ATTR = DMA_ATTR_SSIZE(1)|DMA_ATTR_DSIZE(1); //set source size, destination size to 16bits, no modulo
DMA_TCD0_SOFF = 2; //increment source by 2 bytes for 16bit transfers
DMA_TCD0_SADDR = (uint32_t)&dmabuf[0]; //dmabuf is uint16_t array containing {7, 14, 21, 28, 35, 0}
DMA_TCD0_DOFF = 0; //destination address doesnt increment
DMA_TCD0_DADDR = (uint32_t)&FTM0_C0V; //destination address
DMA_TCD0_CITER_ELINKNO = 1; //current major loop iteration for 1 transfer
DMA_TCD0_BITER_ELINKNO = 1; //beginning major loop iterations, 1 transfer only

DMA_TCD0_DLASTSGA = 0; //just to make sure

//reset timer count and channel flags
FTM0_CNT = 0; //make sure flag is clear when dma requests are enabled
FTM0_C0SC &= ~FTM_CnSC_CHF_MASK; //channel flag must be read and then written 0 to clear
//enable peripheral dma requests
DMA_ERQ |= (1<<0);

Outcomes