AnsweredAssumed Answered

[STM32F103] USART1 TX DMA only fires once

Question asked by marsh.randy on Aug 6, 2016
Latest reply on Aug 6, 2016 by marsh.randy
I have a problem, I wrote some code based of https://github.com/g4lvanix/STM32F1-workarea/tree/master/Project/STM32F10x_StdPeriph_Examples/USART/DMA_Polling and it only fires the USART1 TX DMA once for some reason, I tried to get smarter from the datasheet and reference manual but couldnt for the life of me figure out how to do it correctly.

The code is the following
      //RCC config
    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1 | RCC_APB2Periph_AFIO | RCC_APB2Periph_GPIOA, ENABLE);
  
    //GPIO config
    #define USART1_PORT GPIOA
    #define USART1_PIN_TX GPIO_Pin_9
    #define USART1_PIN_RX GPIO_Pin_10
    //initialize tx pin
    GPIO_InitTypeDef GPIO_InitStructure;
    GPIO_InitStructure.GPIO_Pin = USART1_PIN_TX;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
    GPIO_Init(USART1_PORT, &GPIO_InitStructure);
  
    //DMA config
    DMA_InitTypeDef DMA_InitStructure;
    #define USART1_TX_DMA_CHANNEL DMA1_Channel4
    #define USART1_RX_DMA_CHANNEL DMA1_Channel5
  
    /* USARTy TX DMA1 Channel (triggered by USARTy Tx event) Config */
    DMA_DeInit(USART1_TX_DMA_CHANNEL);
    DMA_InitStructure.DMA_PeripheralBaseAddr = USART1_BASE + 0x04;
    DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)txbuffer;
    DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;
    DMA_InitStructure.DMA_BufferSize = BUFFERSIZE;
    DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
    DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
    DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
    DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
    DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
    DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh;
    DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
    DMA_Init(USART1_TX_DMA_CHANNEL, &DMA_InitStructure);
  
    //usart config
    USART_InitTypeDef USART_InitStructure;
    USART_InitStructure.USART_BaudRate = 115200;
    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_Tx;
    USART_Init(USART1, &USART_InitStructure);
  

      //tx buffer for the first time
     //disable spi and dma
    USART_DMACmd(USART1, USART_DMAReq_Tx, DISABLE);
    USART_Cmd(USART1, DISABLE);
    DMA_Cmd(USART1_TX_DMA_CHANNEL, DISABLE);
    //reconfigure dma
    USART1_TX_DMA_CHANNEL->CMAR = (uint32_t)txbuffer;
    DMA_SetCurrDataCounter(USART1_TX_DMA_CHANNEL, 4);
  
    //tx dma
    DMA_Cmd(USART1_TX_DMA_CHANNEL, ENABLE);
    USART_DMACmd(USART1, USART_DMAReq_Tx, ENABLE);
    USART_Cmd(USART1, ENABLE);
    while (DMA_GetFlagStatus((int)USART1_TX_DMA_CHANNEL) == RESET);
    delay_ms(1000);
  
      //tx buffer again
    //disable spi and dma
    USART_DMACmd(USART1, USART_DMAReq_Tx, DISABLE);
    USART_Cmd(USART1, DISABLE);
    DMA_Cmd(USART1_TX_DMA_CHANNEL, DISABLE);
    //reconfigure dma
    USART1_TX_DMA_CHANNEL->CMAR = (uint32_t)txbuffer;
    DMA_SetCurrDataCounter(USART1_TX_DMA_CHANNEL, 4);
  
    //tx dma
    DMA_Cmd(USART1_TX_DMA_CHANNEL, ENABLE);
    USART_DMACmd(USART1, USART_DMAReq_Tx, ENABLE);
    USART_Cmd(USART1, ENABLE);
    while (DMA_GetFlagStatus((int)USART1_TX_DMA_CHANNEL) == RESET);
    delay_ms(1000);

It correctly transmits the buffer one time but fails to do it for a second time. As I said I couldn't get smart from the documentation and would appreciate a pointer to ether my mistake and/or a reference to the documentation about it.
Thank you in advance.

Outcomes