lpcware

DMA with UART0

Discussion created by lpcware Employee on Jun 15, 2016
Latest reply on Jun 15, 2016 by lpcware
Content originally posted in LPCWare by Scribe on Mon Sep 24 07:12:53 MST 2012
Hi guys,

I'm attempting to configure DMA with UART0, however, when receiving a byte, only UART interrupts are triggering to tell me I have data ready and these continue to trigger, whilst DMA interrupts aren't and there's no sign of data moving into my buffers. My DMA code is below, any suggestions where I may have gone wrong in the setup? I have enabled DMA in LPC_UART0->FCR.


typedef struct
{
uint32_t sourceEndPointer;
uint32_t destinationEndPointer;
uint32_t channelControlData;
uint32_t unused;
} DMA_ChannelControlStructure;

DMA_ChannelControlStructure dmaChannel0 __attribute__((at(0x10000400)));
DMA_ChannelControlStructure dmaChannel1 __attribute__((at(0x10000410)));

uint8_t UARTTXBuffer[256];
uint8_t UARTRXBuffer[256];

void configureDMA()
{
// Disable interrupts
NVIC_DisableIRQ( DMA_IRQn );

// Reset the DMA peripheral
LPC_SYSCON->PRESETCTRL &= ~(1 << 10);
LPC_SYSCON->PRESETCTRL |= (1 << 10);

// Enable DMA peripheral clock at the rate of the AHB clock
LPC_SYSCON->SYSAHBCLKCTRL |= (1 << 17);

LPC_DMA->CTRL_BASE_PTR = (uint32_t)(&dmaChannel0) & 0xFFFFFF00; // Point DMA control to the dmaChannel1 structure

uint32_t cfg = (1UL << 0) |// Enable the DMA controller
(0UL << 5) |// Enable user access control
(0UL << 6); // Configure as non-bufferable

LPC_DMA->CFG = cfg;

// Wait for the DMA controller to start-up
while( !(LPC_DMA->STATUS & 0x01) );

// Disable all channels and clear any bus error
LPC_DMA->CHNL_ENABLE_CLR = 0x01FFFFF;
LPC_DMA->ERR_CLR = 0x01;

// Configure DMA channel 0 (UART0 TX)
dmaChannel0.sourceEndPointer = (uint32_t)UARTTXBuffer + sizeof(UARTTXBuffer) - 1;
dmaChannel0.destinationEndPointer = 0x4000C000;
dmaChannel0.channelControlData = (1UL << 0 )  |// Use basic DMA transfer mode
(0UL << 3 )  |// Disable next burst
(0UL << 4 )  |// 1 DMA transfer per cycle
(0UL << 14 ) |// Rearbitrate the DMA cycle every transfer
(0UL << 18 ) |// No AHB read protection
(0UL << 21 ) |// No AHB write protection
(0UL << 24 ) |// Source data size is in bytes
(0UL << 26 ) |// Set the source address increment by 1 byte
(0UL << 28 ) |// Destination data size is in bytes
(3UL << 30 );// Set the destination address to not increment

// Configure DMA channel 1 (UART0 RX)
dmaChannel1.sourceEndPointer = 0x40008000;
dmaChannel1.destinationEndPointer = (uint32_t)UARTRXBuffer + sizeof(UARTRXBuffer) - 1;
dmaChannel1.channelControlData = (1UL << 0 )   |// Use basic DMA transfer mode
(0UL << 3 )   |// Disable next burst
(255UL << 4 ) |// 256 DMA transfers per cycle
(3UL << 14 )  |// Rearbitrate the DMA cycle every 8 transfers
(0UL << 18 )  |// No AHB read protection
(0UL << 21 )  |// No AHB write protection
(0UL << 24 )  |// Source data size is in bytes
(3UL << 26 )  |// Set the source address to not increment
(0UL << 28 )  |// Destination data size is in bytes
(0UL << 30 );// Set the destination address increment by 1 byte

LPC_DMA->CHNL_ENABLE_SET = (1UL << 0) |// Enable DMA channel 1
(1UL << 1);// Enable DMA channel 2
 
// Enable interrupts
NVIC_EnableIRQ( DMA_IRQn );

LPC_DMA->CHNL_IRQ_ENABLE = (1UL << 0) |// Enable IRQ Done for DMA channel 1
(1UL << 1);// Enable IRQ Done for DMA channel 2
}


Many thanks for any advice.

Outcomes