2016-12-20 03:05 PM
Does anyone have a working example of usb-cdc for an stm32l432 processor? The stm32l4xxCube libraries only have usb-hid examples for the stm32l432kc processor, however I need to have working usb-cdc capabilities. I have not been able to easily adapt the usb-cdc examples for other l4 devices to the l432.
#stm32l432 #usb-cdc #example #usb #l432Solved! Go to Solution.
2016-12-27 02:57 PM
Here's my working CDC Example for the stm32l4 System clockand general device setup has been pulled from the stm32l432 nucleo usb hid example. CDC setup has been pulled from CubeMx generated code and the STM32L476G_EVAL usb cdc example. This project echos anything written to the com port. The echo transmission occurs in the CDC_Itf_Recieve function of usbd_cdc_interface.c. CDC_Itf_Recieve is called by the usb interrupt after receiving data on the port. I haven't cleaned up the code, so it's a little messy in parts and not all of the comments make sense, but it should still be good enough to get started.
Edit: Code is attached to the comment in a zip. Click
https://community.st.com/0D50X00009XkYWiSAN
to view the attachment.Edit 2: I have found new clock settings that get more consistent results:
RCC_OscInitTypeDef RCC_OscInitStruct;
RCC_ClkInitTypeDef RCC_ClkInitStruct; RCC_PeriphCLKInitTypeDef PeriphClkInit; RCC_CRSInitTypeDef RCC_CRSInitStruct;RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_LSE|RCC_OSCILLATORTYPE_MSI;
RCC_OscInitStruct.LSEState = RCC_LSE_OFF; RCC_OscInitStruct.MSIState = RCC_MSI_ON; RCC_OscInitStruct.MSICalibrationValue = 0; RCC_OscInitStruct.MSIClockRange = RCC_MSIRANGE_6; RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_MSI; RCC_OscInitStruct.PLL.PLLM = 1; RCC_OscInitStruct.PLL.PLLN = 16; RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV7; RCC_OscInitStruct.PLL.PLLQ = RCC_PLLQ_DIV2; RCC_OscInitStruct.PLL.PLLR = RCC_PLLR_DIV2; if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) { Error_Handler(); }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_USB;
PeriphClkInit.UsbClockSelection = RCC_USBCLKSOURCE_PLLSAI1; //PeriphClkInit.PLLSAI1.PLLSAI1Source = RCC_PLLSOURCE_MSI; //PeriphClkInit.PLLSAI1.PLLSAI1M = 1; PeriphClkInit.PLLSAI1.PLLSAI1N = 24; PeriphClkInit.PLLSAI1.PLLSAI1P = RCC_PLLP_DIV7; PeriphClkInit.PLLSAI1.PLLSAI1Q = RCC_PLLQ_DIV2; PeriphClkInit.PLLSAI1.PLLSAI1R = RCC_PLLR_DIV2; PeriphClkInit.PLLSAI1.PLLSAI1ClockOut = RCC_PLLSAI1_48M2CLK; if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK) { Error_Handler(); }__HAL_RCC_PWR_CLK_ENABLE();
if (HAL_PWREx_ControlVoltageScaling(PWR_REGULATOR_VOLTAGE_SCALE1) != HAL_OK)
{ Error_Handler(); }HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq()/1000);
HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK);
HAL_RCCEx_EnableMSIPLLMode();
__HAL_RCC_CRS_CLK_ENABLE();
RCC_CRSInitStruct.Prescaler = RCC_CRS_SYNC_DIV1;
RCC_CRSInitStruct.Source = RCC_CRS_SYNC_SOURCE_USB; RCC_CRSInitStruct.Polarity = RCC_CRS_SYNC_POLARITY_RISING; RCC_CRSInitStruct.ReloadValue = __HAL_RCC_CRS_RELOADVALUE_CALCULATE(48000000,1000); RCC_CRSInitStruct.ErrorLimitValue = 34; RCC_CRSInitStruct.HSI48CalibrationValue = 32; HAL_RCCEx_CRSConfig(&RCC_CRSInitStruct);/* SysTick_IRQn interrupt configuration */
HAL_NVIC_SetPriority(SysTick_IRQn, 0, 0); ________________ Attachments : usb_test.zip : https://st--c.eu10.content.force.com/sfc/dist/version/download/?oid=00Db0000000YtG6&ids=0680X000006Hywp&d=%2Fa%2F0X0000000bFG%2Ffi9kGTkFZ_r1t6fcjjEZkibIaHFO4u.C7feyx.fCiKU&asPdf=false2016-12-21 07:42 AM
Success with CDC/VCP from CubeL4 EVAL ported to L476 RG on Nucleo.
Commented out the LED inits in main and the LED control toggle in Systick and it worked on Nucleo.
On What?
Dev board?
Your own Board?
Self powered?
Bus powered?
What have you got done?
What's it do?
You have some special Crystal-less clock concerns to take care of.
2016-12-21 08:16 AM
You're very welcome
Pfeifer.Jacob
. Best of luck with it.Let us know what comes of it.
2016-12-21 08:49 AM
Currently I am using a stm32l432kc nucleo board.
It is self powered from the usb code perspective (it is being powered through the onboard debugger which is connected to the usb bus).
I tried creating a project using cubemx, but it didn't enumerate with the computer. I suppose this could be do to an incorrect clock configuration. I then took an example for another board and managed to get the usb code to enumerate with the computer, but I get a babble error when the computer requests the line coding.
From what I understand the l432kc should be capable of crystal-less usb.
2016-12-21 09:05 AM
Last I checked - CubeMX is buggy. It Enables Vbus sensing -even if you tell it NO VBUS- and then doesn't enable the Vbus sense pin. They know about it....
https://community.st.com/0D50X00009Xkgo7SAB
So you Enumerate and then babble error. Not seen that but that sounds like a clock problem. Your device uses the HSI for the crystal-less and then uses some magic with the SOF, an LSE input or other some such SYNCABLE signal to trim the HSI if I remember right. Sorry to not be more conclusive but at least it enumerated (step one past)
Sounds clockish to me.
2016-12-21 09:11 AM
Thanks, I at least have another rabbit hole to run down now. I'll let you know if I get any results after looking at the clock
2016-12-27 02:57 PM
Here's my working CDC Example for the stm32l4 System clockand general device setup has been pulled from the stm32l432 nucleo usb hid example. CDC setup has been pulled from CubeMx generated code and the STM32L476G_EVAL usb cdc example. This project echos anything written to the com port. The echo transmission occurs in the CDC_Itf_Recieve function of usbd_cdc_interface.c. CDC_Itf_Recieve is called by the usb interrupt after receiving data on the port. I haven't cleaned up the code, so it's a little messy in parts and not all of the comments make sense, but it should still be good enough to get started.
Edit: Code is attached to the comment in a zip. Click
https://community.st.com/0D50X00009XkYWiSAN
to view the attachment.Edit 2: I have found new clock settings that get more consistent results:
RCC_OscInitTypeDef RCC_OscInitStruct;
RCC_ClkInitTypeDef RCC_ClkInitStruct; RCC_PeriphCLKInitTypeDef PeriphClkInit; RCC_CRSInitTypeDef RCC_CRSInitStruct;RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_LSE|RCC_OSCILLATORTYPE_MSI;
RCC_OscInitStruct.LSEState = RCC_LSE_OFF; RCC_OscInitStruct.MSIState = RCC_MSI_ON; RCC_OscInitStruct.MSICalibrationValue = 0; RCC_OscInitStruct.MSIClockRange = RCC_MSIRANGE_6; RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_MSI; RCC_OscInitStruct.PLL.PLLM = 1; RCC_OscInitStruct.PLL.PLLN = 16; RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV7; RCC_OscInitStruct.PLL.PLLQ = RCC_PLLQ_DIV2; RCC_OscInitStruct.PLL.PLLR = RCC_PLLR_DIV2; if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) { Error_Handler(); }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_USB;
PeriphClkInit.UsbClockSelection = RCC_USBCLKSOURCE_PLLSAI1; //PeriphClkInit.PLLSAI1.PLLSAI1Source = RCC_PLLSOURCE_MSI; //PeriphClkInit.PLLSAI1.PLLSAI1M = 1; PeriphClkInit.PLLSAI1.PLLSAI1N = 24; PeriphClkInit.PLLSAI1.PLLSAI1P = RCC_PLLP_DIV7; PeriphClkInit.PLLSAI1.PLLSAI1Q = RCC_PLLQ_DIV2; PeriphClkInit.PLLSAI1.PLLSAI1R = RCC_PLLR_DIV2; PeriphClkInit.PLLSAI1.PLLSAI1ClockOut = RCC_PLLSAI1_48M2CLK; if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK) { Error_Handler(); }__HAL_RCC_PWR_CLK_ENABLE();
if (HAL_PWREx_ControlVoltageScaling(PWR_REGULATOR_VOLTAGE_SCALE1) != HAL_OK)
{ Error_Handler(); }HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq()/1000);
HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK);
HAL_RCCEx_EnableMSIPLLMode();
__HAL_RCC_CRS_CLK_ENABLE();
RCC_CRSInitStruct.Prescaler = RCC_CRS_SYNC_DIV1;
RCC_CRSInitStruct.Source = RCC_CRS_SYNC_SOURCE_USB; RCC_CRSInitStruct.Polarity = RCC_CRS_SYNC_POLARITY_RISING; RCC_CRSInitStruct.ReloadValue = __HAL_RCC_CRS_RELOADVALUE_CALCULATE(48000000,1000); RCC_CRSInitStruct.ErrorLimitValue = 34; RCC_CRSInitStruct.HSI48CalibrationValue = 32; HAL_RCCEx_CRSConfig(&RCC_CRSInitStruct);/* SysTick_IRQn interrupt configuration */
HAL_NVIC_SetPriority(SysTick_IRQn, 0, 0); ________________ Attachments : usb_test.zip : https://st--c.eu10.content.force.com/sfc/dist/version/download/?oid=00Db0000000YtG6&ids=0680X000006Hywp&d=%2Fa%2F0X0000000bFG%2Ffi9kGTkFZ_r1t6fcjjEZkibIaHFO4u.C7feyx.fCiKU&asPdf=false