cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F4 modified buffer via DMA and UART is not transmitted correctly

Andreas S.
Associate II
Posted on December 24, 2016 at 07:03

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-tx
1 REPLY 1
Seb
ST Employee
Posted on December 24, 2016 at 09:05

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 DMA

void 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.