Skip to main content
lauris
Associate III
May 22, 2015
Question

Failing to set up USART DMA TX

  • May 22, 2015
  • 2 replies
  • 734 views
Posted on May 22, 2015 at 15:33

Hello,

Can anyone help in pinpointing where and what I'm doing wrong when seting up USART DMA TX transmission. Working with STM32L152RB (STM32L discovery) and trying to setup USART1_TX overDMA1_Channel4,USART2_TX overDMA1_Channel7 andUSART3_TX overDMA1_Channel2 - acording to UM it should be like that. Below is how I'm setting it up (only USART1 others are same just peripherals and DMA channels differ and in init function I already wrote data which I'm passing, what I can see when debugging):

RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE);
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
USART_Init(0x40013800, { 115200,
USART_WordLength_8b,
USART_StopBits_1,
USART_Parity_No,
(USART_Mode_Rx | USART_Mode_Tx),
USART_HardwareFlowControl_None});
USART_Cmd(0x40013800, ENABLE);
DMA_ITConfig(DMA1_Channel4, DMA_IT_TC, ENABLE);
NVIC_Init({ NVIC_IRQChannel = DMA1_Channel4_IRQn, 
NVIC_IRQChannelPreemptionPriority = 0x0F, 
NVIC_IRQChannelSubPriority = 0x0F, 
NVIC_IRQChannelCmd = ENABLE});
GPIO_Init(GPIOA, { GPIO_Pin = (uint16_t)(1 << 
GPIO_PinSource10
), 
GPIO_Mode
= 
GPIO_Mode_AF
, 
GPIO_Speed
= 
GPIO_Speed_40MHz
, 
GPIO_OType
= 
GPIO_OType_PP
, 
GPIO_PuPd
= 
GPIO_PuPd_NOPULL
});
GPIO_PinAFConfig(GPIOA, GPIO_PinSource10, GPIO_AF_USART1);
GPIO_Init(GPIOA, { GPIO_Pin = (uint16_t)(1 << GPIO_PinSource9), 
GPIO_Mode
= 
GPIO_Mode_AF
, 
GPIO_Speed
= 
GPIO_Speed_40MHz
, 
GPIO_OType
= 
GPIO_OType_PP
, 
GPIO_PuPd
= 
GPIO_PuPd_NOPULL
});
GPIO_PinAFConfig(GPIOA, GPIO_PinSource9, GPIO_AF_USART1);
<<buffer setup>>
DMA_DeInit(DMA1_Channel4);
DMA_Init(DMA1_Channel4, { DMA_PeripheralBaseAddr = 0x40013804, 
DMA_MemoryBaseAddr = 0x20001344, 
DMA_DIR = DMA_DIR_PeripheralDST, 
DMA_BufferSize = 12, 
DMA_PeripheralInc = DMA_PeripheralInc_Disable, 
DMA_MemoryInc = DMA_MemoryInc_Enable, 
DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte, 
DMA_MemoryDataSize = DMA_MemoryDataSize_Byte, 
DMA_Mode = DMA_Mode_Normal, 
DMA_Priority = DMA_Priority_Low, 
DMA_M2M = DMA_M2M_Disable});
USART_DMACmd(USART1, USART_DMAReq_Tx, ENABLE);
USART_ClearFlag(USART1, USART_FLAG_TC);
DMA_Cmd(DMA1_Channel4, ENABLE);

all initialization passes without errors, but I am not getting anything on uart lines andDMA1_Channel4_IRQn never fires.
    This topic has been closed for replies.

    2 replies

    Tesla DeLorean
    Guru
    May 22, 2015
    Posted on May 22, 2015 at 18:36

    Here's what I have, and works for me..

    // STM32 USART2 DMA TX MULTI (Tx PA.2, Rx PA.3) STM32L152RE NUCLEO - sourcer32@gmail.com
    #include ''stm32l1xx.h''
    #include <
    string.h
    >
    /**************************************************************************************/
    void RCC_Configuration(void)
    {
    /* --------------------------- System Clocks Configuration -----------------*/
    /* USART2 clock enable */
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);
    /* GPIOA and DMA1 clock enable */
    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA | RCC_AHBPeriph_DMA1, ENABLE);
    }
    /**************************************************************************************/
    void GPIO_Configuration(void)
    {
    GPIO_InitTypeDef GPIO_InitStructure;
    /*-------------------------- GPIO Configuration ----------------------------*/
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2 | GPIO_Pin_3; // PA.2 USART2_TX, PA.3 USART2_RX
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
    GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
    GPIO_Init(GPIOA, &GPIO_InitStructure);
    /* Connect USART pins to AF */
    GPIO_PinAFConfig(GPIOA, GPIO_PinSource2, GPIO_AF_USART2);
    GPIO_PinAFConfig(GPIOA, GPIO_PinSource3, GPIO_AF_USART2);
    }
    /**************************************************************************************/
    void USART2_Configuration(void)
    {
    USART_InitTypeDef USART_InitStructure;
    /* USARTx configuration ------------------------------------------------------*/
    /* USARTx configured as follow:
    - BaudRate = 115200 baud
    - Word Length = 8 Bits
    - One Stop Bit
    - No parity
    - Hardware flow control disabled (RTS and CTS signals)
    - Receive and transmit enabled
    */
    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_Rx | USART_Mode_Tx;
    USART_Init(USART2, &USART_InitStructure);
    USART_Cmd(USART2, ENABLE);
    /* Enable the USART Tx DMA request */
    USART_DMACmd(USART2, USART_DMAReq_Tx, ENABLE);
    }
    /**************************************************************************************/
    // Output as a series of different length strings in a loop
    char StringA[] = ''The quick brown fox jumps over the lazy dog
    
    '';
    char StringB[] = ''Danger Zombies Ahead
    
    '';
    char StringC[] = ''Do not cross the streams
    
    '';
    int StringIndex = 0;
    char *StringList[] = { StringA, StringB, StringC, NULL };
    void DMA_Configuration(void)
    {
    DMA_InitTypeDef DMA_InitStructure;
    char *Buffer;
    // USART2_TX DMA2 Channel 7
    if (StringList[StringIndex] == NULL)
    StringIndex = 0;
    Buffer = StringList[StringIndex++];
    DMA_DeInit(DMA1_Channel7);
    DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&USART2->DR;
    DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)Buffer;
    DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST; // Transmit
    DMA_InitStructure.DMA_BufferSize = (uint16_t)strlen(Buffer);
    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_High;
    DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
    DMA_Init(DMA1_Channel7, &DMA_InitStructure);
    /* Enable DMA Channel Transfer Complete interrupt */
    DMA_ITConfig(DMA1_Channel7, DMA_IT_TC, ENABLE);
    /* Enable the DMA TX Channel */
    DMA_Cmd(DMA1_Channel7, ENABLE);
    }
    /**************************************************************************************/
    void DMA1_Channel7_IRQHandler(void) // USART2_TX
    {
    /* Test on DMA Stream Transfer Complete interrupt */
    if (DMA_GetITStatus(DMA1_IT_TC7))
    {
    /* Clear DMA Stream Transfer Complete interrupt pending bit */
    DMA_ClearITPendingBit(DMA1_IT_TC7);
    DMA_Configuration(); // Light off next string
    }
    }
    /**************************************************************************************/
    void NVIC_Configuration(void)
    {
    NVIC_InitTypeDef NVIC_InitStructure;
    /* Configure the Priority Group to 2 bits */
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
    /* Enable the USART2 TX DMA Interrupt */
    NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel7_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure);
    }
    /**************************************************************************************/
    int main(void)
    {
    RCC_Configuration();
    NVIC_Configuration();
    GPIO_Configuration();
    USART2_Configuration();
    DMA_Configuration();
    while(1); // Don't want to exit
    }
    /**************************************************************************************/
    #ifdef USE_FULL_ASSERT
    /**
    * @brief Reports the name of the source file and the source line number
    * where the assert_param error has occurred.
    * @param file: pointer to the source file name
    * @param line: assert_param error line source number
    * @retval None
    */
    void assert_failed(uint8_t* file, uint32_t line)
    {
    /* User can add his own implementation to report the file name and line number,
    ex: printf(''Wrong parameters value: file %s on line %d
    
    '', file, line) */
    while (1)
    {}
    }
    #endif
    /**************************************************************************************/

    Tips, Buy me a coffee, or three.. PayPal VenmoUp vote any posts that you find helpful, it shows what's working..
    lauris
    laurisAuthor
    Associate III
    May 25, 2015
    Posted on May 25, 2015 at 21:22

    Hello,

    well it worked on STM32L152VC, but not on STM32L152R8, will need to check if I can make it working on R8 too, in some way.