I'm having a hard with K60 when i'm trying to use DMA to capture the data from PTB0-PTB7.
I wanted to use PTA27 as the trigger of the DMA transmit,and then the DMA controller copy the data from PTB0-PTB7 to the buffer.
I have read a lot of articles about how to configure the DMA,however,i just can't make it.
I almost get mad.
first of all ,i read the Kinetis Peripheral Module Quick Reference and K60 Sub-Family Reference Manual and decided to write my own code.
i found that it is very easy to configure DMA,and i did as it told me.the Configuration steps are as below:
1. Write the eDMA control register (only necessary if the configuration of another than
the default is required)
2. Configure channel priority registers in the DCHPRIn (if necessary)
3. Enable error interrupts using either the DMAEEI or DMASEEI register (if
4. Write the transfer control descriptors for channels that will be used
5. Configure the appropriate peripheral module and configure the eDMA MUX to route
the activation signal to the appropriate channel
for 1: I checked the DMA_CR register and found that there is no need to change it.
for 2: since I only use one channel of DMA,the priority is not important,I left it in default configuration
for 3: OK ,I didn't know I would meet so many problems,I didn't enable any error interrupt .well,that is not a problem.I didn.t use it.
for 4:in this part ,I carefully checked all the TCD registers and write the one by one (except those i ever use)
here i copy my code bellow :
//write the TCD register
(DMA_BASE_PTR)->TCD.SADDR=0x400FF050;//am i right? the address of input data of PTB0 ?
(DMA_BASE_PTR)->TCD.SOFF=0x00;//always read the same address PTB0-PTB7,so the offset is 0
(DMA_BASE_PTR)->TCD.ATTR=0x00;//i don/t quite understand what is the Address Modulo,and i don't use it .
//and Source data transfer size is the same as the destination ,that is 8bit,
(DMA_BASE_PTR)->TCD.NBYTES_MLNO=0x01;//evey time only transmit one byte
(DMA_BASE_PTR)->TCD.SLAST=0x00;//because my sourse address will not change ,so the is nothing to adjust
(DMA_BASE_PTR)->TCD.DADDR=(uint32)(ImageBuf); //the destination address is a array imageBuff,so the address of the first byte is imageBuff,
(DMA_BASE_PTR)->TCD.DOFF=0x01;//when i finish copying one byte ,i should move to the next byte,
(DMA_BASE_PTR)->TCD.CITER_ELINKNO=320;//the majpr Iteration contains 320 times of single transmit.
(DMA_BASE_PTR)->TCD.DLAST_SGA=-320;//when finish the main cycle,we need to go back to the fist byte of our buffer,
(DMA_BASE_PTR)->TCD.BITER_ELINKNO=320; //related to CITER_ELINKNO,they must be the same
(DMA_BASE_PTR)->TCD.CSR=0x000B;//write the very important CSR register,disable elink,disable ESG,disable half-point interrupt,enable end-of-major loop interrput
for 5:i enable the PTA27,DMA_rising,and PTB0-PTB7 input ,pull-up,
then ,i almost forgot where i got the idea that i also should enable the clock that related .they are as followed:
SIM_SCGC7 |= SIM_SCGC7_DMA_MASK; //
SIM_SCGC6 |= SIM_SCGC6_DMAMUX_MASK; //
after this ,i got more information that i should also configure the DMAMUX,so i got the code bellow:
(DMAMUX_BASE_PTR)->CHCFG=0xB1;//enable the DMA,PS:the slot is 49d,that is the GPIOB
after this ,no more register remains to be configure,then enable all that need to be enable:
(DMA_BASE_PTR)->ERQ=0x00;//enable the DMA hardware request
OK,it seems i have write a lot .of course you needn't check line by line,that would be so boring
what i want to say most is that what on earth did i forget to configure?
the DMA is simply not woking at all.
i have tested that it can enter the external interrupt service,but it never go into the DMA interrupt service.My god!
Do you have some simple examples of how to use the DMA,just to read the GPIO data ,not working with the ADC or anything else.
Any help or information is of great value to me !