2016-12-23 10:03 PM
Hi all,
I am currenly trying to set up a DMA transfer to UART TX.
I have a buffer
u8 u8ByteBuffer[] = 'UART Test...0.';In DMA-Interrupt (TX complete) I disable DMA with
DMA_Cmd(DMA2_Stream7, DISABLE);
Every 200ms I increment the position '0'i++;u8ByteBuffer[12] = i;and enable the DMA again after modify of the buffer.
DMA_Cmd(DMA2_Stream7, ENABLE);The string is sent via Uart, but the position 12 is in HTerm
some sort of random value and not the incremented value I would
expect, starting at 0x30.
When I step through the code via Keil debugger I see the correctly
incremented values and they are transmitted correctly to HTerm, but only in
debugger.
Can anyone give me a hint whats going wrong?
Here is my configuration:
DMAStream7_Channel4_Init();
DMA_ITConfig(DMA2_Stream7, DMA_IT_TC, ENABLE);USART_DMACmd(USART1, USART_DMAReq_Tx, ENABLE);DMA_Cmd(DMA2_Stream7, ENABLE);void DMA2_Stream7_IRQHandler(void)
{ if(DMA_GetITStatus(DMA2_Stream7, DMA_IT_TCIF7) != RESET) { DMA_ClearITPendingBit(DMA2_Stream7, DMA_IT_TCIF7); OnUartDMA(); }}void OnUartDMA(void)
{ DMA_Cmd(DMA2_Stream7, DISABLE);}void DMAStream7_Channel4_Init(void)
{ RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2, ENABLE);DMA_InitTypeDef DMA_InitStruct;
DMA_StructInit(&DMA_InitStruct); DMA_InitStruct.DMA_Channel = DMA_Channel_4; DMA_InitStruct.DMA_PeripheralBaseAddr = (uint32_t)&(USART1->DR); DMA_InitStruct.DMA_Memory0BaseAddr = (uint32_t)&u8ByteBuffer[0]; DMA_InitStruct.DMA_DIR = DMA_DIR_MemoryToPeripheral; DMA_InitStruct.DMA_BufferSize = 14; DMA_InitStruct.DMA_Priority = DMA_Priority_Medium;DMA_InitStruct.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
DMA_InitStruct.DMA_MemoryInc = DMA_MemoryInc_Enable;DMA_InitStruct.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
DMA_InitStruct.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;DMA_InitStruct.DMA_Mode = DMA_Mode_Normal;
// DMA_InitStruct.DMA_Mode = DMA_Mode_Circular;DMA_InitStruct.DMA_FIFOMode = DMA_FIFOMode_Disable;
DMA_InitStruct.DMA_FIFOThreshold = DMA_FIFOThreshold_HalfFull;DMA_InitStruct.DMA_MemoryBurst = DMA_MemoryBurst_Single;
DMA_InitStruct.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;DMA_Init(DMA2_Stream7, &DMA_InitStruct);
}static void USART_Config(void){ USART_InitTypeDef USART_InitStructure; USART_InitStructure.USART_BaudRate = 9600; USART_InitStructure.USART_WordLength = USART_WordLength_8b; USART_InitStructure.USART_StopBits = USART_StopBits_1; USART_InitStructure.USART_Parity = USART_Parity_No; USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;STM_EVAL_COMInit(COM1, &USART_InitStructure);
}#stm32f4-uart-dma-tx2016-12-24 12:05 AM
For SPI TX, when needing to send several blocks of Data, here is my std lib ref function:
// SPI4 RX is DMA2 Stream0 channel 4
#define DMA_RX_Channel DMA_Channel_4#define DMA_RX_Stream DMA2_Stream0#define DMA_RX_Flags DMA_FLAG_TCIF0 | DMA_FLAG_HTIF0 | DMA_FLAG_TEIF0 | DMA_FLAG_DMEIF0 | DMA_FLAG_FEIF0#define DMA_RX_TC_Flag DMA_FLAG_TCIF0#define DMA_TX_Channel DMA_Channel_4
#define DMA_TX_Stream DMA2_Stream1#define DMA_TX_Flags DMA_FLAG_TCIF1 | DMA_FLAG_HTIF1 | DMA_FLAG_TEIF1 | DMA_FLAG_DMEIF1 | DMA_FLAG_FEIF1 #define DMA_TX_TC_Flag DMA_FLAG_TCIF1#define SPI_DR_BASE_ADR (uint32_t) (&(SPI4->DR)) //0x4001300C
// we have to disable then enable the stream to extend the DMAvoid FT1_DMA_TX_Set(u32 blockstart, u16 nbofbytes) {DMA_ClearFlag(DMA_TX_Stream, DMA_TX_Flags);
DMA_Cmd(DMA_TX_Stream, DISABLE); while(DMA_GetCmdStatus(DMA_TX_Stream)==ENABLE) __NOP(); // wait for the DMA to be completely disabled FT1_DMA_TX_InitStruct.DMA_BufferSize = nbofbytes; FT1_DMA_TX_InitStruct.DMA_Memory0BaseAddr = blockstart; DMA_Init(DMA_TX_Stream, &FT1_DMA_TX_InitStruct); DMA_Cmd(DMA_TX_Stream, ENABLE); SPI_I2S_DMACmd(FT1_SPI, SPI_I2S_DMAReq_Tx, ENABLE);}Hope this gives a clue... this code works fine.