Hi everyone,
I'm trying to set the DMA to get the USART RX data when it's available.
So I set up the DMA for a hardware trigger, 1 byte transfer (no BURST). The source USART RX (not incremented) to a buffer I declared in the RAM (incremented), and to be reloaded with the same descriptor at the end.
The transfer happens and I do get the data. But when the descriptor is reloaded, I suppose that the destination address does not get incremented, thus overwriting the previous data over and over...
As a work around, I implemented the DMA IRQ to increment my dest address at th end of a transfer, it is now working.
But isn't there a way for the DMA to automatically increment the dest address over several transfers ? (I did set the DSTINC flag in the XFERCFG register, but I suppose it's only incrementing the dest address within the same transfer...)
Many thanks.
Here's my code :
typedef enum _DMA_CHANNEL
{
DMA_CHANNEL_USART0_RX = 0,
DMA_CHANNEL_USART0_TX,
DMA_CHANNEL_USART1_RX,
DMA_CHANNEL_USART1_TX,
DMA_CHANNEL_USART2_RX,
DMA_CHANNEL_USART2_TX,
DMA_CHANNEL_USART3_RX,
DMA_CHANNEL_USART3_TX,
DMA_CHANNEL_USART4_RX,
DMA_CHANNEL_USART4_TX,
DMA_CHANNEL_SPI0_RX,
DMA_CHANNEL_SPI0_TX,
DMA_CHANNEL_SPI1_RX,
DMA_CHANNEL_SPI1_TX,
DMA_CHANNEL_I2C0_MST,
DMA_CHANNEL_I2C0_SLV,
DMA_CHANNEL_I2C1_MST,
DMA_CHANNEL_I2C1_SLV,
DMA_CHANNEL_I2C2_MST,
DMA_CHANNEL_I2C2_SLV,
DMA_CHANNEL_I2C3_MST,
DMA_CHANNEL_I2C3_SLV,
DMA_CHANNEL_DAC0,
DMA_CHANNEL_DAC1,
DMA_CHANNEL_CAPT1,
DMA_CHANNEL_COUNT
} T_DMA_CHANNEL;
typedef struct _DMA_DESCRIPTOR
{
volatile t_uint32 xfercfg; //!< Transfer configuration
t_uint8 *srcEndAddr; //!< Last source address of DMA transfer
t_uint8 *dstEndAddr; //!< Last destination address of DMA transfer
t_uint_32 *linkToNextDesc; //!< Address of next DMA descriptor in chain
} T_DMA_DESCRIPTOR;
__attribute__((aligned(512))) static T_DMA_DESCRIPTOR s_dma_descriptor_table[DMA_CHANNEL_COUNT] = {0};
t_uint8 rxBuffer[20] = { 0 };
DMA0->SRAMBASE = (t_uint32)s_dma_descriptor_table;
DMA0->CTRL = DMA_CTRL_ENABLE_MASK;
DMA0->COMMON->ENABLESET |= 1 << DMA_CHANNEL_USART0_RX;
DMA0->COMMON->INTENSET |= 1 << DMA_CHANNEL_USART0_RX;
DMA0->CHANNEL[DMA_CHANNEL_USART0_RX].CFG = 1 << DMA_CHANNEL_CFG_CHPRIORITY_SHIFT |
1 << DMA_CHANNEL_CFG_PERIPHREQEN_SHIFT |
1 << DMA_CHANNEL_CFG_HWTRIGEN_SHIFT |
1 << DMA_CHANNEL_CFG_TRIGPOL_SHIFT |
0 << DMA_CHANNEL_CFG_TRIGTYPE_SHIFT |
0 << DMA_CHANNEL_CFG_TRIGBURST_SHIFT |
0 << DMA_CHANNEL_CFG_BURSTPOWER_SHIFT |
1 << DMA_CHANNEL_CFG_SRCBURSTWRAP_SHIFT |
0 << DMA_CHANNEL_CFG_DSTBURSTWRAP_SHIFT;
DMA0->CHANNEL[DMA_CHANNEL_USART0_RX].XFERCFG = 1 << DMA_CHANNEL_XFERCFG_CFGVALID_SHIFT |
1 << DMA_CHANNEL_XFERCFG_RELOAD_SHIFT |
0 << DMA_CHANNEL_XFERCFG_SWTRIG_SHIFT |
0 << DMA_CHANNEL_XFERCFG_CLRTRIG_SHIFT |
1 << DMA_CHANNEL_XFERCFG_SETINTA_SHIFT |
0 << DMA_CHANNEL_XFERCFG_SETINTB_SHIFT |
0 << DMA_CHANNEL_XFERCFG_WIDTH_SHIFT |
0 << DMA_CHANNEL_XFERCFG_SRCINC_SHIFT |
1 << DMA_CHANNEL_XFERCFG_DSTINC_SHIFT |
0 << DMA_CHANNEL_XFERCFG_XFERCOUNT_SHIFT;
// Setup Descriptor
s_dma_descriptor_table[DMA_CHANNEL_USART0_RX].xfercfg = DMA0->CHANNEL[DMA_CHANNEL_USART0_RX].XFERCFG;
s_dma_descriptor_table[DMA_CHANNEL_USART0_RX].srcEndAddr = (t_uint8 *) &USART0->RXDAT;
s_dma_descriptor_table[DMA_CHANNEL_USART0_RX].dstEndAddr = rxBuffer;
s_dma_descriptor_table[DMA_CHANNEL_USART0_RX].linkToNextDesc = (t_uint32*) &s_dma_descriptor_table[DMA_CHANNEL_USART0_RX].xfercfg;
INPUTMUX->DMA_ITRIG_INMUX[DMA_CHANNEL_USART0_RX] = 0x9;
// The IRQ workaround solution that I tried
void DMA_IRQ_handler( void )
{
s_dma_descriptor_table[DMA_CHANNEL_USART0_RX].dstEndAddr++;
}
Hello jo mos ,
Yes, we can only reconfigure the channel descriptor in Single buffer mode, in descriptor re-configure
destination.
USART peripheral DMA, I guess you use Single buffer mode,
Have a great day,
TIC
-------------------------------------------------------------------------------
Note:
- If this post answers your question, please click the "Mark Correct" button. Thank you!
- We are following threads for 7 weeks after the last post, later replies are ignored
Please open a new thread and refer to the closed one, if you have a related question at a later point in time.
-------------------------------------------------------------------------------