AnsweredAssumed Answered

STM32429I-EVAL Can't get higher data rate than 1 megabit over USART.

Question asked by jab on May 14, 2014
Latest reply on May 14, 2014 by Clive One
I've tried porting the stm32cubef4 UART DMA example to use USART, but I still can't achieve faster speeds than 1 megabit. The MCU can apparently support speeds of up to 11 megabits, am I simply asking too much of the peripheral? My output essentially becomes random letters.

My configuration is as such:
Main:
int main(void)
{   
  /* STM32F4xx HAL library initialization:
       - Configure the Flash prefetch, instruction and Data caches
       - Configure the Systick to generate an interrupt each 1 msec
       - Set NVIC Group Priority to 4
       - Global MSP (MCU Support Package) initialization
     */
  HAL_Init();
   
  /* Configure the system clock to 180 Mhz */
  SystemClock_Config();
   
  /* Configure LED1, LED2 and LED3 */
  BSP_LED_Init(LED1);
  BSP_LED_Init(LED2);
  BSP_LED_Init(LED3);
   
  /*##-1- Configure the UART peripheral ######################################*/
  /* Put the USART peripheral in the Asynchronous mode (UART Mode) */
  /* UART1 configured as follow:
      - Word Length = 8 Bits
      - Stop Bit    = One Stop bit
      - Parity      = ODD parity
      - BaudRate    = 9600 baud
      - Hardware flow control disabled (RTS and CTS signals) */
  UsartHandle.Instance        = USARTx;
   
  UsartHandle.Init.BaudRate   = 1048576;
  UsartHandle.Init.WordLength = USART_WORDLENGTH_8B;
  UsartHandle.Init.StopBits   = USART_STOPBITS_1;
  UsartHandle.Init.Parity     = USART_PARITY_NONE;
     
  //UsartHandle.Init.HwFlowCtl  = UART_HWCONTROL_NONE;
     
  UsartHandle.Init.Mode       = USART_MODE_TX;
     
  UsartHandle.Init.CLKLastBit = USART_LASTBIT_DISABLE;
  UsartHandle.Init.CLKPhase     = USART_PHASE_1EDGE;
  UsartHandle.Init.CLKPolarity = USART_POLARITY_LOW;
     
   
  if(HAL_USART_Init(&UsartHandle) != HAL_OK)
  {
    /* Initialization Error */
    Error_Handler();
  }
    //Spam messages over serial.
    while(1)
    {
        /*##-2- Start the transmission process #####################################*/ 
        /* User start transmission data through "TxBuffer" buffer */
        if(HAL_USART_Transmit_DMA(&UsartHandle, (uint8_t*)aTxBuffer, TXBUFFERSIZE)!= HAL_OK)
        {
            /* Transfer error in transmission process */
            Error_Handler(); 
        }
         
        while (HAL_USART_GetState(&UsartHandle) != HAL_USART_STATE_READY)
        {
        }
    }
}
 
Clock setup:
static void SystemClock_Config(void)
{
  RCC_ClkInitTypeDef RCC_ClkInitStruct;
  RCC_OscInitTypeDef RCC_OscInitStruct;
 
  /* Enable Power Control clock */
  __PWR_CLK_ENABLE();
 
  /* The voltage scaling allows optimizing the power consumption when the device is
     clocked below the maximum system frequency, to update the voltage scaling value
     regarding system frequency refer to product datasheet.  */
  __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);
 
  /* Enable HSE Oscillator and activate PLL with HSE as source */
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
  RCC_OscInitStruct.HSEState = RCC_HSE_ON;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
  RCC_OscInitStruct.PLL.PLLM = 25;
  RCC_OscInitStruct.PLL.PLLN = 360;
  RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
  RCC_OscInitStruct.PLL.PLLQ = 7;
  HAL_RCC_OscConfig(&RCC_OscInitStruct);
   
  HAL_PWREx_ActivateOverDrive();
 
  /* Select PLL as system clock source and configure the HCLK, PCLK1 and PCLK2
     clocks dividers */
  RCC_ClkInitStruct.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2);
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4; 
  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2; 
  HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_5);
}

USART MSP Init:
void HAL_USART_MspInit(USART_HandleTypeDef *husart)
{
  static DMA_HandleTypeDef hdma_tx;
  static DMA_HandleTypeDef hdma_rx;
   
  GPIO_InitTypeDef  GPIO_InitStruct;
   
  /*##-1- Enable peripherals and GPIO Clocks #################################*/
  /* Enable GPIO clock */
  USARTx_TX_GPIO_CLK_ENABLE();
  USARTx_RX_GPIO_CLK_ENABLE();
  /* Enable USART1 clock */
  USARTx_CLK_ENABLE();
  /* Enable DMA2 clock */
  DMAx_CLK_ENABLE();  
   
  /*##-2- Configure peripheral GPIO ##########################################*/ 
  /* UART TX GPIO pin configuration  */
    GPIO_InitStruct.Pin = GPIO_PIN_10|GPIO_PIN_9|GPIO_PIN_8;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    GPIO_InitStruct.Speed = GPIO_SPEED_LOW;
    GPIO_InitStruct.Alternate = GPIO_AF7_USART1;
   
  HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
     
  /*##-3- Configure the DMA streams ##########################################*/
  /* Configure the DMA handler for Transmission process */
  hdma_tx.Instance                 = USARTx_TX_DMA_STREAM;
   
  hdma_tx.Init.Channel             = USARTx_TX_DMA_CHANNEL;
  hdma_tx.Init.Direction           = DMA_MEMORY_TO_PERIPH;
  hdma_tx.Init.PeriphInc           = DMA_PINC_DISABLE;
  hdma_tx.Init.MemInc              = DMA_MINC_ENABLE;
  hdma_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
  hdma_tx.Init.MemDataAlignment    = DMA_MDATAALIGN_BYTE;
  hdma_tx.Init.Mode                = DMA_NORMAL;
  hdma_tx.Init.Priority            = DMA_PRIORITY_LOW;
  hdma_tx.Init.FIFOMode            = DMA_FIFOMODE_DISABLE;        
  hdma_tx.Init.FIFOThreshold       = DMA_FIFO_THRESHOLD_FULL;
  hdma_tx.Init.MemBurst            = DMA_MBURST_INC4;
  hdma_tx.Init.PeriphBurst         = DMA_PBURST_INC4;
   
  HAL_DMA_Init(&hdma_tx);  
   
  /* Associate the initialized DMA handle to the UART handle */
  __HAL_LINKDMA(husart, hdmatx, hdma_tx);
     
  /* Configure the DMA handler for reception process */
  hdma_rx.Instance                 = USARTx_RX_DMA_STREAM;
   
  hdma_rx.Init.Channel             = USARTx_RX_DMA_CHANNEL;
  hdma_rx.Init.Direction           = DMA_PERIPH_TO_MEMORY;
  hdma_rx.Init.PeriphInc           = DMA_PINC_DISABLE;
  hdma_rx.Init.MemInc              = DMA_MINC_ENABLE;
  hdma_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
  hdma_rx.Init.MemDataAlignment    = DMA_MDATAALIGN_BYTE;
  hdma_rx.Init.Mode                = DMA_NORMAL;
  hdma_rx.Init.Priority            = DMA_PRIORITY_HIGH;
  hdma_rx.Init.FIFOMode            = DMA_FIFOMODE_DISABLE;        
  hdma_rx.Init.FIFOThreshold       = DMA_FIFO_THRESHOLD_FULL;
  hdma_rx.Init.MemBurst            = DMA_MBURST_INC4;
  hdma_rx.Init.PeriphBurst         = DMA_PBURST_INC4;
 
  HAL_DMA_Init(&hdma_rx);
     
  /* Associate the initialized DMA handle to the the UART handle */
  __HAL_LINKDMA(husart, hdmarx, hdma_rx);
     
  /*##-4- Configure the NVIC for DMA #########################################*/
  /* NVIC configuration for DMA transfer complete interrupt (USART1_TX) */
  HAL_NVIC_SetPriority(USARTx_DMA_TX_IRQn, 0, 1);
  HAL_NVIC_EnableIRQ(USARTx_DMA_TX_IRQn);
     
  /* NVIC configuration for DMA transfer complete interrupt (USART1_RX) */
  HAL_NVIC_SetPriority(USARTx_DMA_RX_IRQn, 0, 0);  
  HAL_NVIC_EnableIRQ(USARTx_DMA_RX_IRQn);
}

Am I missing anything obvious? Any help would be appreciated. Thanks in advance.

Outcomes