2024-08-06 09:36 AM
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:
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?
Solved! Go to Solution.
2024-08-14 07:52 AM
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!
2024-08-06 10:45 AM
Dear @Delaney ,
Thank you for sharing ! Indeed your hypothesis seems interesting on right clocks between different blocks - USB, System , APB1 and APB2 :
If possible to let us know your Clocks settings ?
Thanks again.
STOne-32.
2024-08-06 10:49 AM
Thank you for the reply.
Here are my clock settings:
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();
}
}
2024-08-06 11:23 AM
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.
2024-08-06 12:14 PM
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.
2024-08-14 07:52 AM
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!
2024-08-14 08:19 AM