Skip to main content
Visitor II
August 6, 2024
Solved

USB issues related to USART speeds -- STM32L072

  • August 6, 2024
  • 4 replies
  • 1670 views

I've been working on an STM32L072 based project involving USB and USART4. I ran into an issue that puzzled me, so I figured I'd post about it here to help others. If there is a solution to this problem, even better!


My original design used USART4 as a serial port for MIDI and also set up USB as a MIDI device. USB wasn't working no matter what I tried. I thought it was an issue with my USB configuration / implementation. It turns out it was due to USART4 being set to 31250 baud.

 

Here is what I've observed:

  • If I set USART4 to 31250 baud, USB does not work (enumeration fails)
  • If I set USART4 to 115200 baud instead, USB works fine.
  • If I use USART1 instead of USART4, USB works fine, even when the speed is set to 31250.


I suspect there is some difference in clock source / implementation between USART1 and USART4 based on the fact that CubeMX only shows USART1 with a configurable clock source / source mux. Is that the case? 

    This topic has been closed for replies.
    Best answer by Delaney

    I made some progress and wanted to report back. I suspect the lower baud rate on USART4 was causing the USB idle task to not be called frequently enough for USB to function properly; maybe I was trying to put too much data through it and it was blocking for too long... 

    I set up a timer interrupt for the USB idle task so it's guaranteed to be called at a regular interval (I had it inside my main loop before), and that seems to have resolved the issue. 

    Thank you for looking into this and for your suggestions!

    4 replies

    Technical Moderator
    August 6, 2024

    Dear @Delaney ,

     

    Thank you for sharing ! Indeed your hypothesis seems interesting on  right clocks between different blocks - USB, System , APB1 and APB2  :

     

    STOne32_1-1722966181270.png

     

    STOne32_2-1722966324095.png

    If possible to let us know your Clocks settings ?  

    Thanks again.

    STOne-32.

    DelaneyAuthor
    Visitor II
    August 6, 2024

    Thank you for the reply.

    Here are my clock settings:

    Screen Shot 2024-08-06 at 10.46.59 AM.png

     

    void SystemClock_Config(void)
    {
     RCC_OscInitTypeDef RCC_OscInitStruct = {0};
     RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
     RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};
    
     /** Configure the main internal regulator output voltage
     */
     __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);
    
     /** Initializes the RCC Oscillators according to the specified parameters
     * in the RCC_OscInitTypeDef structure.
     */
     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.PLLMUL = RCC_PLLMUL_12;
     RCC_OscInitStruct.PLL.PLLDIV = RCC_PLLDIV_3;
     if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
     {
     Error_Handler();
     }
    
     /** Initializes the CPU, AHB and APB buses clocks
     */
     RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
     |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
     RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
     RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
     RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
     RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
    
     if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_1) != HAL_OK)
     {
     Error_Handler();
     }
     PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_USART1|RCC_PERIPHCLK_USB;
     PeriphClkInit.Usart1ClockSelection = RCC_USART1CLKSOURCE_PCLK2;
     PeriphClkInit.UsbClockSelection = RCC_USBCLKSOURCE_PLL;
     if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)
     {
     Error_Handler();
     }
    }

     

    Technical Moderator
    August 6, 2024

    Dear @Delaney ,

    Thanks for sharing,  may be this sentence is key "If I set USART4 to 31250 baud, USB does not work (enumeration fails)" How USB enumeration can fail due to USART4 baud rate at 31250 instead of 115200  ?

    may be to check how the MIDI Class and example is setup at application level and clocks synchronization.   Very interesting case.

    STOne-32.

    Super User
    August 6, 2024

    Is this a custom board? Is USART4 routed close to USB lines? Perhaps show a picture of the routing of these two signals?

    Would suspect a noise issue rather than something inside the chip preventing it from working. Surely the peripherals are independent at the internal level.

    DelaneyAuthorAnswer
    Visitor II
    August 14, 2024

    I made some progress and wanted to report back. I suspect the lower baud rate on USART4 was causing the USB idle task to not be called frequently enough for USB to function properly; maybe I was trying to put too much data through it and it was blocking for too long... 

    I set up a timer interrupt for the USB idle task so it's guaranteed to be called at a regular interval (I had it inside my main loop before), and that seems to have resolved the issue. 

    Thank you for looking into this and for your suggestions!

    Technical Moderator
    August 14, 2024

    Hi @Delaney ,

    much appreciated to be back and happy to see you solved the case.  

    Ciao

    STOne-32.