DMA and UART (MCF52233)?

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

DMA and UART (MCF52233)?

2,414 Views
admin
Specialist II
Hello!

I use in my project interrupts for the UART communication. When I set greater UART speed, some byte wasn't sended or received, because the UART generates too many Interrupts! So I will use the DMA for UART. To reduce the interrupts, i will generate an DMA receiv or send interrupt when 8 Bytes are transferred to the RAM or over the UART! This is my init function for the DMA Controller. But with this init Code, I can't read or send Bytes over the UART! Hope, you can help me! Or you have Application Notes?

static void init_dma0()
{
MCF_DMA_DMAREQC |= MCF_DMA_DMAREQC_DMAC2(0xC); // UART Transmit
MCF_DMA_DMAREQC |= MCF_DMA_DMAREQC_DMAC0(0x8); // UART Receive

MCF_SCM_GPACR0 |= 0x06; // Read, Write
MCF_SCM_GPACR1 |= 0x06; // Read, Write

MCF_SCM_PACR2 |= 0x60; // Read, Write // UART

MCF_DMA_SAR0 = MCF_UART0_URB; // Receiver UART Buffer
MCF_DMA_DAR0 = (volatile unsigned long)&recvBuf[0];

MCF_DMA_SAR2 = MCF_UART0_URB;
MCF_DMA_DAR2 = (volatile unsigned long)&sendBuf[0]; // Transmit UART Buffer

MCF_DMA_DCR2 |= MCF_DMA_DCR_DSIZE(0x1) | // Destination Size
MCF_DMA_DCR_SSIZE(0x1) | // Soure Size
MCF_DMA_DCR_SINC | // Source Increment
MCF_DMA_DCR_CS | // Single read/write
MCF_DMA_DCR_INT; // Internal interrupt signal is enabled
MCF_DMA_DCR_AA; // Autoalign enable


MCF_DMA_DCR0 |= MCF_DMA_DCR_DSIZE(0x1) | // Destination Size
MCF_DMA_DCR_SSIZE(0x1) | // Soure Size
MCF_DMA_DCR_DINC | // Destination Increment
MCF_DMA_DCR_CS | // Single read/write
MCF_DMA_DCR_EEXT | // Enable external request to initiate transfer

MCF_DMA_DCR_AA; // Autoalign enable


MCF_SCM_RAMBAR |= (MCF_SCM_RAMBAR_BDE | MCF_RAMBAR_SPV); // Backdoor enable and SPV Secondary Port Valid

MCF_DMA_BCR2 = 8; // Byte Count Register
MCF_DMA_BCR0 = 8; // Byte Count Register

mcf5223_interrupt_init(9, 5, dma0_isr);
mcf5223_interrupt_init(11, 6, dma0_isr);

MCF_INTC0_IMRL &= ~MCF_INTC_IMRL_MASK9;
MCF_INTC0_IMRL &= ~MCF_INTC_IMRL_MASK11;
}
Labels (1)
0 Kudos
2 Replies

332 Views
mjbcswitzerland
Specialist V
Oh yes, I forgot to mention.

What speed are you running the UART at?
The ColdFire should have enough processing power to handle interrupt operation on all UARTS at high rates without loosing interrupts.
If you are loosing them it may indicate other problems in your system (code segments disabling interrupts for quite long times?).
This is not to say that DMA should not be used because it is much more efficent in some cases (depening on protocol etc.) but it may be worth finding out why interrupts get lost in the first place.

Regards

Mark
0 Kudos

332 Views
mjbcswitzerland
Specialist V

Hi

- the access rights look good.

I think that I see a tx error in the code:
- when setting up the DMA for transmission you have the source and destination inverted. Source must be your buffer and destination the TX register.

Then you must also configure the UART but with disabled interrupt (if not already done).
If you now put 8 bytes into the tx buffer and enable the transmitter using
UMR1_2_0 = UART_TX_ENABLE; (your defines will be slightly different)
then the transmitter will start the DMA transfer process and after 8 bytes the DMA interrupt will occur.

Check the DMA status register if nothing happens since it will tell you if it aborted due to a bus error or similar and this will possibly indicate the source of any more problems.

Apart from the error with the inversion, the rest of the set up looks good.

In your interrupt routine you will then have to clear the DONE bit. I use the following sequence:
1. Disable DMA
2. Disable transmitter
3. Reset DONE bit

Regards

Mark Butcher
www.mjbc.ch / www.uTasker.com

0 Kudos