hi everyone ,I have this problem for several days and still no solution.
I want to send data to the PWM module's C0V register to change its duty cycle by enable the DMA.
But I really don't know what's wrong with my code .It seems that the DMA transmission is failed because the value of C0V is always 0.
I have succeed in generating pwm by updating the C0V through the MPU,like below:
while(1)
{
FTM0_C0V = pwm1;
FTM0_PWMLOAD |= FTM_PWMLOAD_LDOK_MASK;
}
and I've also succeed in transfering datas from memory to memory by using DMA.But it never works when I connect the DMA to PWM register.
By the way ,I'm using the DMA in periodic trigger mode,and I think I have configured the PIT module right.
My code are as follows:
//dma.c
/***channel init***/
void DMAinit(int chno,int sourceno)
{
SIM_SCGC6 |= SIM_SCGC6_DMAMUX_MASK;
DMA_SERQ|=DMA_SERQ_SERQ(chno) ;//enable the source chno
DMAMUX_CHCFG(chno)=(DMAMUX_CHCFG_ENBL_MASK | DMAMUX_CHCFG_SOURCE(sourceno));//enable dma channel chno,
DMAMUX_CHCFG(chno)|=DMAMUX_CHCFG_TRIG_MASK;//enable the periodic trigger
}
//DMA controler setting
void DMAset(uint32 *source_addr,uint32 *destiny_address,char sbits,char dbits,char nbytes,char chno,uint16 majorinter )
{
uint8 i;
i =chno ;//DMA number of channel
SIM_SCGC7 |= SIM_SCGC7_DMA_MASK; //enable DMA clock
DMA_SADDR(i) = (uint32)source_addr;//DMA source address
DMA_DADDR(i) = (uint32)destiny_address;//DMA destiny address
DMA_NBYTES_MLNO(i) =2;//minor loop nbytes
DMA_ATTR(i)= (DMA_ATTR_SSIZE(sbits)|DMA_ATTR_DSIZE(dbits)) ;//source and dest bits
DMA_SOFF(i) =0x2; //source address offset after each transfer
DMA_DOFF(i)=0x0;/source address offset after each transfer
DMA_SLAST(i) = -nbytes; //adjust the source address to the original address
DMA_DLAST_SGA(i) = -nbytes; /adjust the destiny address to the original address
DMA_CITER_ELINKNO(i) =DMA_CITER_ELINKNO_CITER( majorinter);//current major loop counts
DMA_BITER_ELINKNO(i) = DMA_BITER_ELINKNO_BITER(majorinter);//beginning major loop counts
DMA_CSR(i)|=DMA_CSR_BWC(3);//bandwidth control
//DMA_CSR(i)|=DMA_CSR_INTMAJOR_MASK;
DMA_CSR(i)|=DMA_CSR_START_MASK;//soft start
//DMA_SERQ|=DMA_SERQ_SERQ(chno) ;//enable hardware request chno (have done in the DMAinit)
}
//main.c
int main(void)
{
InitPWM();
hw_pit_init(PIT1,0x249f00);//set the timeout of PIT1
DMAinit(1,ftm0ch0_dmasc);//
DMAset(pwmdata,(uint32)&FTM0_C0V,1,1,buflength*2,1,30);
while(1);
return 0;
}
Solved! Go to Solution.
Hi,Paul
Thanks so much for checking my code so carefully.But I really have to say sorry .Because when I restart my job today(and that's why I reply late.) I finally found there's no problem with my code,it's just because the DMA transfer is so fast that I can only see the finally result : 0,and that's the same value when the CnV begins.When I changed the value ,I can see the right result now. And now I'm working on how to slow down the DMA.
Grace
Hi, Grace
I checked your code. I think I need to confirm something with you. As you mentioned, it seems that you tested two DMA function. One is FTM0 channel0 and the other is PIT. In your first testing, I cannot find FTM0 channel0 intial code. So please make sure that you enable DMA function in your FTM control register. For example, you need to set bit DMA in FTM0_C0SC.
In your second PIT testing, I find that your ciode seems still use FTM0 channel0 in your DMA setting. If my understanding on your testing is incorrect, please correct me.
Hope my reply can help you.
Best Regards
Paul
Hi,Paul
Thanks so much for checking my code so carefully.But I really have to say sorry .Because when I restart my job today(and that's why I reply late.) I finally found there's no problem with my code,it's just because the DMA transfer is so fast that I can only see the finally result : 0,and that's the same value when the CnV begins.When I changed the value ,I can see the right result now. And now I'm working on how to slow down the DMA.
Grace
Hi,
it is looking like you are faceing an errata. It is not clear what device with what silicon mask you are using. Therefore, please check silicon mask errata for the device you are using. Or just simply try to trigger DMA request by another source (another FTM module etc.).
Thank you ,I'm using K10,but I don't know what you mean by 'errata',I can't find it.Can you give me more direction?
Hi,
errata in general is a document which inludes description of all bugs (not correctly working parts) of device. In Kinetis case it describes all bugs for specified silicon mask. You can find the silicon mask on the chip directly under device name MK10.... (e.g. 2N22 can be silicin mask). After visit our freescale sites and search for kinetis K10 errata.
For example here you can find something:
Hi,Thank you so much that now I really find your suggestion lead me to the finally result!
It is an errta
e4588: DMAMUX: When using PIT with "always enabled" request, DMA request does
not deassert correctly.
anyway,after many efforts I solved the PIT problem.now it works with DMA.
but still I have another problem, I guess you can give me a hand again. The DMA destination value doesn't
change although it enters into the DMA interrupt at the first three times.later it works well .then it drops the first three values
I want to send. Any suggestion?
Thank you again.
Thank you ,it's useful for my later work.Though now I've checked it's not the problem of my code.