MCF5282_DMA0_DCR |= 0x00100000; // Source Size 1 (destination hold by default)
MCF5282_DMA0_DCR |= 0x20000000; // Enable Cycle Steal Mod
MCF5282_DMA0_DCR |= 0x00080000; // Enable Destination Increment
MCF5282_DMA0_DCR |= 0x00020000; // Destination Size 1
ptr = &ModNetUart->RxBuffer[ModNetUart->RxWritePtr];
MCF5282_DMA0_DAR = (DWORD)ptr; // Setup Destination Address
MCF5282_DMA0_BCR |= 0x00FFFFFF; // Setup Byte Count to 255 (ignores lower 2 bytes)
MCF5282_DMA0_SAR |= (DWORD)&MCF5282_UART1_URB; // Source to UART1 Receive Buffer
MCF5282_SCM_DMAREQC = 0x0009; // Setup DMA0 for UART1
MCF5282_DMA0_DCR |= 0x40000000; // External Enable
Now, what ends up happening is I enable the External DMA0 Enable, and I get an Error 0x21 in the MCF5282_DMA0_DSR register (Source Error).
Some points of confusion:
1). There is no clear way to setup DMA for only transmits or only recieves in the 5282 user manual.
2). There is a footnote in the UART register description saying DMA only works on channels 2 and 3 - but this is not clear and never repeated in the documentation.
3). The masking of Rx interrupts is described in a confusing manner in the documentation. What should the status of the IMR and UMR registers be for UART1 for DMA to work on only recieves?
Could anyone possibly provide me with some sample code for making DMA work on recieves for a 5282 core? I've seen a previous thread with samples for a 5223 transmit driven by an external peripheral, but was unable to adapt it for what I need. Thank you very much in advance for any help you can provide me with!
- Jason
Jason,
The UISR1/UIMR1 register allows you to select 4 interrupt sources, COS-CTS, DB-break, FFULL/RXRDY, and TXRDY.
If you use DMA for receiving data, then you have an option to trigger a DMA interrupt upon completion of the DMA’s transferring BCR0 bytes. As Mark pointed out, you don’t want to use the UART’s RXRDY interrupt when using DMA for receiving.
I’m working on the MCF5329 which has the same UART module but a little bit fancier DMA module. My situation is similar to yours in that my program would like to know when a message has been received. My messages are variable length and I don’t have a trailer sequence in my protocol to use. I’m looking at using a DMA timer interrupt to monitor the DMA’s transfer count (BCRn) since my protocol has some timing constraints. My other option is to set up a DMA transfer to continuously fill a ring-buffer
Do you need to look at or process each byte as it’s received?
It seems that you would save more cpu cycles by using interrupts for Rx, and DMA for Tx.
-- Wayne
NOTE
The DMA should not be used to write data to the UART transmit FIFO in
cycle steal mode. When the UART interrupt is used as a DMA request it
does not negate fast enough to get a single transfer. The UART transmit
FIFO only has one entry so the data from the second byte would be lost.
Which indicates you should be able to use the DMA on the 5282 in continous mode to write to the UART's transmit buffers. Unfortunately this results in only 2 bytes being sent, and the DMA doesn't hold off until the TB's are empty. But I see how it explains that the UART interrupt request happens too early before the transmit buffer has been sent.
Now if only continous mode worked properly...