2323
2424#include "udc_common.h"
2525
26- #include "stm32_hsem.h"
27-
2826#include <zephyr/logging/log.h>
2927LOG_MODULE_REGISTER (udc_stm32 , CONFIG_UDC_DRIVER_LOG_LEVEL );
3028
@@ -50,6 +48,8 @@ struct udc_stm32_data {
5048 void (* pcd_prepare )(const struct device * dev );
5149 int (* clk_enable )(void );
5250 int (* clk_disable )(void );
51+ struct k_thread thread_data ;
52+ struct k_msgq msgq_data ;
5353};
5454
5555struct udc_stm32_config {
@@ -60,6 +60,18 @@ struct udc_stm32_config {
6060 uint16_t ep_mps ;
6161};
6262
63+ enum udc_stm32_msg_type {
64+ UDC_STM32_MSG_SETUP ,
65+ UDC_STM32_MSG_DATA_OUT ,
66+ UDC_STM32_MSG_DATA_IN ,
67+ };
68+
69+ struct udc_stm32_msg {
70+ uint8_t type ;
71+ uint8_t ep ;
72+ uint16_t rx_count ;
73+ };
74+
6375static int udc_stm32_lock (const struct device * dev )
6476{
6577 return udc_lock_internal (dev , K_FOREVER );
@@ -125,6 +137,26 @@ void HAL_PCD_ResumeCallback(PCD_HandleTypeDef *hpcd)
125137 udc_submit_event (priv -> dev , UDC_EVT_RESUME , 0 );
126138}
127139
140+ void HAL_PCD_SetupStageCallback (PCD_HandleTypeDef * hpcd )
141+ {
142+ struct udc_stm32_data * priv = hpcd2data (hpcd );
143+ struct udc_stm32_msg msg = {.type = UDC_STM32_MSG_SETUP };
144+ int err ;
145+
146+ err = k_msgq_put (& priv -> msgq_data , & msg , K_NO_WAIT );
147+
148+ if (err < 0 ) {
149+ LOG_ERR ("UDC Message queue overrun" );
150+ }
151+ }
152+
153+ void HAL_PCD_SOFCallback (PCD_HandleTypeDef * hpcd )
154+ {
155+ struct udc_stm32_data * priv = hpcd2data (hpcd );
156+
157+ udc_submit_event (priv -> dev , UDC_EVT_SOF , 0 );
158+ }
159+
128160static int usbd_ctrl_feed_dout (const struct device * dev , const size_t length )
129161{
130162 struct udc_stm32_data * priv = udc_get_private (dev );
@@ -143,57 +175,6 @@ static int usbd_ctrl_feed_dout(const struct device *dev, const size_t length)
143175 return 0 ;
144176}
145177
146- void HAL_PCD_SetupStageCallback (PCD_HandleTypeDef * hpcd )
147- {
148- struct udc_stm32_data * priv = hpcd2data (hpcd );
149- struct usb_setup_packet * setup = (void * )priv -> pcd .Setup ;
150- const struct device * dev = priv -> dev ;
151- struct net_buf * buf ;
152- int err ;
153-
154- buf = udc_ctrl_alloc (dev , USB_CONTROL_EP_OUT ,
155- sizeof (struct usb_setup_packet ));
156- if (buf == NULL ) {
157- LOG_ERR ("Failed to allocate for setup" );
158- return ;
159- }
160-
161- udc_ep_buf_set_setup (buf );
162- memcpy (buf -> data , setup , 8 );
163- net_buf_add (buf , 8 );
164-
165- udc_ctrl_update_stage (dev , buf );
166-
167- if (!buf -> len ) {
168- return ;
169- }
170-
171- if ((setup -> bmRequestType == 0 ) &&
172- (setup -> bRequest == USB_SREQ_SET_ADDRESS )) {
173- /* HAL requires we set the address before submitting status */
174- HAL_PCD_SetAddress (& priv -> pcd , setup -> wValue );
175- }
176-
177- if (udc_ctrl_stage_is_data_out (dev )) {
178- /* Allocate and feed buffer for data OUT stage */
179- err = usbd_ctrl_feed_dout (dev , udc_data_stage_length (buf ));
180- if (err == - ENOMEM ) {
181- udc_submit_ep_event (dev , buf , err );
182- }
183- } else if (udc_ctrl_stage_is_data_in (dev )) {
184- udc_ctrl_submit_s_in_status (dev );
185- } else {
186- udc_ctrl_submit_s_status (dev );
187- }
188- }
189-
190- void HAL_PCD_SOFCallback (PCD_HandleTypeDef * hpcd )
191- {
192- struct udc_stm32_data * priv = hpcd2data (hpcd );
193-
194- udc_submit_event (priv -> dev , UDC_EVT_SOF , 0 );
195- }
196-
197178static void udc_stm32_flush_tx_fifo (const struct device * dev )
198179{
199180 struct udc_stm32_data * priv = udc_get_private (dev );
@@ -275,6 +256,36 @@ void HAL_PCD_DataOutStageCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum)
275256{
276257 uint32_t rx_count = HAL_PCD_EP_GetRxCount (hpcd , epnum );
277258 struct udc_stm32_data * priv = hpcd2data (hpcd );
259+ struct udc_stm32_msg msg = {
260+ .type = UDC_STM32_MSG_DATA_OUT ,
261+ .ep = epnum ,
262+ .rx_count = rx_count ,
263+ };
264+ int err ;
265+
266+ err = k_msgq_put (& priv -> msgq_data , & msg , K_NO_WAIT );
267+ if (err != 0 ) {
268+ LOG_ERR ("UDC Message queue overrun" );
269+ }
270+ }
271+
272+ void HAL_PCD_DataInStageCallback (PCD_HandleTypeDef * hpcd , uint8_t epnum )
273+ {
274+ struct udc_stm32_data * priv = hpcd2data (hpcd );
275+ struct udc_stm32_msg msg = {
276+ .type = UDC_STM32_MSG_DATA_IN ,
277+ .ep = epnum ,
278+ };
279+ int err ;
280+
281+ err = k_msgq_put (& priv -> msgq_data , & msg , K_NO_WAIT );
282+ if (err != 0 ) {
283+ LOG_ERR ("UDC Message queue overrun" );
284+ }
285+ }
286+
287+ static void handle_msg_data_out (struct udc_stm32_data * priv , uint8_t epnum , uint16_t rx_count )
288+ {
278289 const struct device * dev = priv -> dev ;
279290 uint8_t ep = epnum | USB_EP_DIR_OUT ;
280291 struct net_buf * buf ;
@@ -312,9 +323,8 @@ void HAL_PCD_DataOutStageCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum)
312323 }
313324}
314325
315- void HAL_PCD_DataInStageCallback ( PCD_HandleTypeDef * hpcd , uint8_t epnum )
326+ static void handle_msg_data_in ( struct udc_stm32_data * priv , uint8_t epnum )
316327{
317- struct udc_stm32_data * priv = hpcd2data (hpcd );
318328 const struct device * dev = priv -> dev ;
319329 uint8_t ep = epnum | USB_EP_DIR_IN ;
320330 struct net_buf * buf ;
@@ -378,6 +388,69 @@ void HAL_PCD_DataInStageCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum)
378388 }
379389}
380390
391+ static void handle_msg_setup (struct udc_stm32_data * priv )
392+ {
393+ struct usb_setup_packet * setup = (void * )priv -> pcd .Setup ;
394+ const struct device * dev = priv -> dev ;
395+ struct net_buf * buf ;
396+ int err ;
397+
398+ buf = udc_ctrl_alloc (dev , USB_CONTROL_EP_OUT , sizeof (struct usb_setup_packet ));
399+ if (buf == NULL ) {
400+ LOG_ERR ("Failed to allocate for setup" );
401+ return ;
402+ }
403+
404+ udc_ep_buf_set_setup (buf );
405+ memcpy (buf -> data , setup , 8 );
406+ net_buf_add (buf , 8 );
407+
408+ udc_ctrl_update_stage (dev , buf );
409+
410+ if (!buf -> len ) {
411+ return ;
412+ }
413+
414+ if ((setup -> bmRequestType == 0 ) && (setup -> bRequest == USB_SREQ_SET_ADDRESS )) {
415+ /* HAL requires we set the address before submitting status */
416+ HAL_PCD_SetAddress (& priv -> pcd , setup -> wValue );
417+ }
418+
419+ if (udc_ctrl_stage_is_data_out (dev )) {
420+ /* Allocate and feed buffer for data OUT stage */
421+ err = usbd_ctrl_feed_dout (dev , udc_data_stage_length (buf ));
422+ if (err == - ENOMEM ) {
423+ udc_submit_ep_event (dev , buf , err );
424+ }
425+ } else if (udc_ctrl_stage_is_data_in (dev )) {
426+ udc_ctrl_submit_s_in_status (dev );
427+ } else {
428+ udc_ctrl_submit_s_status (dev );
429+ }
430+ }
431+
432+ static void udc_stm32_thread_handler (void * arg1 , void * arg2 , void * arg3 )
433+ {
434+ const struct device * dev = arg1 ;
435+ struct udc_stm32_data * priv = udc_get_private (dev );
436+ struct udc_stm32_msg msg ;
437+
438+ while (true) {
439+ k_msgq_get (& priv -> msgq_data , & msg , K_FOREVER );
440+ switch (msg .type ) {
441+ case UDC_STM32_MSG_SETUP :
442+ handle_msg_setup (priv );
443+ break ;
444+ case UDC_STM32_MSG_DATA_IN :
445+ handle_msg_data_in (priv , msg .ep );
446+ break ;
447+ case UDC_STM32_MSG_DATA_OUT :
448+ handle_msg_data_out (priv , msg .ep , msg .rx_count );
449+ break ;
450+ }
451+ }
452+ }
453+
381454#if DT_INST_NODE_HAS_PROP (0 , disconnect_gpios )
382455void HAL_PCDEx_SetConnectionState (PCD_HandleTypeDef * hpcd , uint8_t state )
383456{
@@ -1128,6 +1201,10 @@ static const struct gpio_dt_spec ulpi_reset =
11281201 GPIO_DT_SPEC_GET_OR (DT_PHANDLE (DT_INST (0 , st_stm32_otghs ), phys ), reset_gpios , {0 });
11291202#endif
11301203
1204+ static char udc_msgq_buf_0 [CONFIG_UDC_STM32_MAX_QMESSAGES * sizeof (struct udc_stm32_msg )];
1205+
1206+ K_THREAD_STACK_DEFINE (udc_stm32_stack_0 , CONFIG_UDC_STM32_STACK_SIZE );
1207+
11311208static int udc_stm32_driver_init0 (const struct device * dev )
11321209{
11331210 struct udc_stm32_data * priv = udc_get_private (dev );
@@ -1185,6 +1262,15 @@ static int udc_stm32_driver_init0(const struct device *dev)
11851262 priv -> clk_disable = priv_clock_disable ;
11861263 priv -> pcd_prepare = priv_pcd_prepare ;
11871264
1265+ k_msgq_init (& priv -> msgq_data , udc_msgq_buf_0 , sizeof (struct udc_stm32_msg ),
1266+ CONFIG_UDC_STM32_MAX_QMESSAGES );
1267+
1268+ k_thread_create (& priv -> thread_data , udc_stm32_stack_0 ,
1269+ K_THREAD_STACK_SIZEOF (udc_stm32_stack_0 ), udc_stm32_thread_handler ,
1270+ (void * )dev , NULL , NULL , K_PRIO_COOP (CONFIG_UDC_STM32_THREAD_PRIORITY ),
1271+ K_ESSENTIAL , K_NO_WAIT );
1272+ k_thread_name_set (& priv -> thread_data , dev -> name );
1273+
11881274 IRQ_CONNECT (UDC_STM32_IRQ , UDC_STM32_IRQ_PRI , udc_stm32_irq ,
11891275 DEVICE_DT_INST_GET (0 ), 0 );
11901276
0 commit comments