Hello
I am attaching my code please help me out in this. I want to transfer a char array on to putty using UART by raising DMA request. It is printing only the first element. please help me in this
解決済! 解決策の投稿を見る。
Hi
Multiple triggers when there is one place available in a peripheral is incorrect and will cause failure. A single transfer on each trigger is the correct way to do it.
DMA is very useful since there is no CPU overhead involved but doing it the wrong way (multiple transfers for a single trigger is incorrect and so won't work) won't allow it to be solved.
There are possibly working examples in the SDKs or there is a proven one at the GIT hub link I gave. It may be easier to use something that functions as reference to get you over the present difficulties or re-read the eDMA users manual carefully to gain more understanding.
Regards
Mark
Hi
If you can send one byte from a buffer with DMA_TCD_CITER_ELINK set to 1, you should be able to send multiple bytes by just setting DMA_TCD_CITER_ELINK to the number of bytes too be sent. There should be nothing else to do.
However, make sure that you DO NOT TOUCH the DMA in operation until it has completed; either poll its operation or use its end of transfer interrupt to detect its completion.
It is best to use the "Insert Code" method to show code since reading code from screen shots is not very practical (especially if a line is to be copied as a quote, for example).
Regards
Mark
[uTasker project developer for Kinetis and i.MX RT]
Contact me by personal message or on the uTasker web site to discuss professional training, solutions to problems or product development requirements
Below is my code please do check and correct me if there are any corrections
//source address
DMA_TCD0_SADDR = (uint32_t)a;
/* Source offset disabled */
DMA_TCD0_SOFF = 0x01;
//Source data transfer size and Destination data transfer size
DMA_TCD0_ATTR=DMA_ATTR_SSIZE(0x00)|DMA_ATTR_DSIZE(0x00);
DMA_TCD0_NBYTES_MLNO= 0x04;
//Destination address
DMA_TCD0_DADDR =0x400EB007;
DMA_TCD0_CITER_ELINKNO = DMA_CITER_ELINKNO_CITER(4);
/* No adjustment to destination address */
DMA_TCD0_DLASTSGA = 0x00;
DMA_TCD0_BITER_ELINKNO = DMA_BITER_ELINKNO_BITER(4);
DMA_SERQ |= DMA_SERQ_SERQ_MASK;
DMA_TCD0_CSR = DMA_CSR_START_MASK;
Hi
DMA_TCD0_SOFF = 0x01;
is correct but DMA_TCD0_DOFF = 0;
should be added (and the comment corrected)
DMA_TCD0_DLASTSGA = 0x00;
is correct but it is best to add
DMA_TCD0_SLASTSGA = 0x00; too since these registers can be random at reset.
DMA_TCD0_DLASTSGA = -(sizeof(buffer)); is generally used if the output data is prepared in a circular buffer
You should set the DREQ flag in the DMA_TCD0_CSR register when working with peripherals otherwise each time there is a trigger 'all' bytes will be sent (overflow). The DREQ flag tells the eDMA to transfer only one byte per DMA trigger and not perform a burst transfer.
DMA_TCD0_NBYTES_MLNO= 0x04; is incorrect, it should be 1 since each transfer is a single byte and not 4.
DMA_SERQ |= DMA_SERQ_SERQ_MASK; may work but is not correct. It should be DMA_SERQ = 1; since you want to start operation only on this one channel.
DMA_TCD0_CSR = DMA_CSR_START_MASK; is also not correct since it is a software method of starting a transfer and not a peripheral driven one.
DMA_TCD0_CSR = DMA_CSR_DREQ; is correct, but it should be "before" the DMA_SERQ write. The first byte will automatically be started if the UART Tx Tx buffer is empty when DMA_SERQ = 1; is performed.
Regards
Mark
[uTasker project developer for Kinetis and i.MX RT]
Contact me by personal message or on the uTasker web site to discuss professional training, solutions to problems or product development requirements
Thank You for your response.
Now if i want to send 109 bytes in a single DMA request . Here I am facing lots for problem. Can you explain me this. How it is done.
Hi
To perform a multiple transfer on a single trigger the minor loop counter (MLNO) is used.
This is however not of use for a peripheral driver like a UART.
Regards
Mark
Then how to resolve this. Whether DMA is helpful in UART peripheral.
Hi
Multiple triggers when there is one place available in a peripheral is incorrect and will cause failure. A single transfer on each trigger is the correct way to do it.
DMA is very useful since there is no CPU overhead involved but doing it the wrong way (multiple transfers for a single trigger is incorrect and so won't work) won't allow it to be solved.
There are possibly working examples in the SDKs or there is a proven one at the GIT hub link I gave. It may be easier to use something that functions as reference to get you over the present difficulties or re-read the eDMA users manual carefully to gain more understanding.
Regards
Mark
hello sir,
Now i am facing problems in receive. I want to receive 4 bytes and store in the buffer but the buffer is loaded with same value. below i have written my code please go through it .
//Receive Function
{
DMA_SADDR_REG(dmach , ch) =0;
DMA_SADDR_REG(dmach , ch)|= DMA_SADDR_SADDR(0x4006B007); // CONFIGURING SOURCE ADDRESS
DMA_SOFF_REG(dmach,ch) =0;
DMA_ATTR_REG(dmach , ch) = (DMA_ATTR_SSIZE(0) | DMA_ATTR_DSIZE(0)); //CONFIGURING SOURCE ADDRESS SIZE
DMA_NBYTES_MLNO_REG(dmach , ch) = 0;
DMA_NBYTES_MLNO_REG(dmach , ch)|= (DMA_NBYTES_MLNO_NBYTES(0x04));
DMA_DADDR_REG(dmach , ch) = 0;
DMA_DADDR_REG(dmach , ch) |= DMA_DADDR_DADDR(val); //CONFIGURING DESTINATION ADDRESS ADDRESS
DMA_DOFF_REG(dmach , ch) = DMA_DOFF_DOFF(0x01);
DMA_BITER_ELINKNO_REG(dmach , ch) =0;
DMA_BITER_ELINKNO_REG(dmach , ch) = DMA_BITER_ELINKNO_BITER(0x4); //STARTING MAJOR ITERATION COUNT
DMA_CITER_ELINKNO_REG(dmach , ch) =0;
DMA_CITER_ELINKNO_REG(dmach , ch) = DMA_CITER_ELINKNO_CITER(0x4); // CURRENT MAJOR ITERATION COUNT
DMA_SERQ |= DMA_SERQ_SERQ_MASK;
DMA_CSR_REG(dmach , ch) = DMA_CSR_START_MASK; // START THE DMA
}