Skip to main content
Associate
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? 

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

STOne-32
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
Associate
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();
 }
}

 

STOne-32
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.

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

"If you feel a post has answered your question, please click ""Accept as Solution""."
DelaneyAuthorBest answer
Associate
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!

STOne-32
Technical Moderator
August 14, 2024

Hi @Delaney ,

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

Ciao

STOne-32.