STM32F4xx HAL Driver master
STM32CubeF4 HAL / LL Drivers API Reference
Loading...
Searching...
No Matches
stm32f4xx_ll_usb.c
Go to the documentation of this file.
1
40
41/* Includes ------------------------------------------------------------------*/
42#include "stm32f4xx_hal.h"
43
47
48#if defined (HAL_PCD_MODULE_ENABLED) || defined (HAL_HCD_MODULE_ENABLED)
49#if defined (USB_OTG_FS) || defined (USB_OTG_HS)
50/* Private typedef -----------------------------------------------------------*/
51/* Private define ------------------------------------------------------------*/
52/* Private macro -------------------------------------------------------------*/
53/* Private variables ---------------------------------------------------------*/
54/* Private function prototypes -----------------------------------------------*/
55/* Private functions ---------------------------------------------------------*/
56#if defined (USB_OTG_FS) || defined (USB_OTG_HS)
57static HAL_StatusTypeDef USB_CoreReset(USB_OTG_GlobalTypeDef *USBx);
58
59/* Exported functions --------------------------------------------------------*/
63
75
83HAL_StatusTypeDef USB_CoreInit(USB_OTG_GlobalTypeDef *USBx, USB_OTG_CfgTypeDef cfg)
84{
86 if (cfg.phy_itface == USB_OTG_ULPI_PHY)
87 {
88 USBx->GCCFG &= ~(USB_OTG_GCCFG_PWRDWN);
89
90 /* Init The ULPI Interface */
91 USBx->GUSBCFG &= ~(USB_OTG_GUSBCFG_TSDPS | USB_OTG_GUSBCFG_ULPIFSLS | USB_OTG_GUSBCFG_PHYSEL);
92
93 /* Select vbus source */
94 USBx->GUSBCFG &= ~(USB_OTG_GUSBCFG_ULPIEVBUSD | USB_OTG_GUSBCFG_ULPIEVBUSI);
95 if (cfg.use_external_vbus == 1U)
96 {
97 USBx->GUSBCFG |= USB_OTG_GUSBCFG_ULPIEVBUSD;
98 }
99
100 /* Reset after a PHY select */
101 ret = USB_CoreReset(USBx);
102 }
103 else /* FS interface (embedded Phy) */
104 {
105 /* Select FS Embedded PHY */
106 USBx->GUSBCFG |= USB_OTG_GUSBCFG_PHYSEL;
107
108 /* Reset after a PHY select */
109 ret = USB_CoreReset(USBx);
110
111 if (cfg.battery_charging_enable == 0U)
112 {
113 /* Activate the USB Transceiver */
114 USBx->GCCFG |= USB_OTG_GCCFG_PWRDWN;
115 }
116 else
117 {
118 /* Deactivate the USB Transceiver */
119 USBx->GCCFG &= ~(USB_OTG_GCCFG_PWRDWN);
120 }
121 }
122
123 if (cfg.dma_enable == 1U)
124 {
125 USBx->GAHBCFG |= USB_OTG_GAHBCFG_HBSTLEN_2;
126 USBx->GAHBCFG |= USB_OTG_GAHBCFG_DMAEN;
127 }
128
129 return ret;
130}
131
132
139HAL_StatusTypeDef USB_SetTurnaroundTime(USB_OTG_GlobalTypeDef *USBx,
140 uint32_t hclk, uint8_t speed)
141{
142 uint32_t UsbTrd;
143
144 /* The USBTRD is configured according to the tables below, depending on AHB frequency
145 used by application. In the low AHB frequency range it is used to stretch enough the USB response
146 time to IN tokens, the USB turnaround time, so to compensate for the longer AHB read access
147 latency to the Data FIFO */
148 if (speed == USBD_FS_SPEED)
149 {
150 if ((hclk >= 14200000U) && (hclk < 15000000U))
151 {
152 /* hclk Clock Range between 14.2-15 MHz */
153 UsbTrd = 0xFU;
154 }
155 else if ((hclk >= 15000000U) && (hclk < 16000000U))
156 {
157 /* hclk Clock Range between 15-16 MHz */
158 UsbTrd = 0xEU;
159 }
160 else if ((hclk >= 16000000U) && (hclk < 17200000U))
161 {
162 /* hclk Clock Range between 16-17.2 MHz */
163 UsbTrd = 0xDU;
164 }
165 else if ((hclk >= 17200000U) && (hclk < 18500000U))
166 {
167 /* hclk Clock Range between 17.2-18.5 MHz */
168 UsbTrd = 0xCU;
169 }
170 else if ((hclk >= 18500000U) && (hclk < 20000000U))
171 {
172 /* hclk Clock Range between 18.5-20 MHz */
173 UsbTrd = 0xBU;
174 }
175 else if ((hclk >= 20000000U) && (hclk < 21800000U))
176 {
177 /* hclk Clock Range between 20-21.8 MHz */
178 UsbTrd = 0xAU;
179 }
180 else if ((hclk >= 21800000U) && (hclk < 24000000U))
181 {
182 /* hclk Clock Range between 21.8-24 MHz */
183 UsbTrd = 0x9U;
184 }
185 else if ((hclk >= 24000000U) && (hclk < 27700000U))
186 {
187 /* hclk Clock Range between 24-27.7 MHz */
188 UsbTrd = 0x8U;
189 }
190 else if ((hclk >= 27700000U) && (hclk < 32000000U))
191 {
192 /* hclk Clock Range between 27.7-32 MHz */
193 UsbTrd = 0x7U;
194 }
195 else /* if(hclk >= 32000000) */
196 {
197 /* hclk Clock Range between 32-200 MHz */
198 UsbTrd = 0x6U;
199 }
200 }
201 else if (speed == USBD_HS_SPEED)
202 {
203 UsbTrd = USBD_HS_TRDT_VALUE;
204 }
205 else
206 {
207 UsbTrd = USBD_DEFAULT_TRDT_VALUE;
208 }
209
210 USBx->GUSBCFG &= ~USB_OTG_GUSBCFG_TRDT;
211 USBx->GUSBCFG |= (uint32_t)((UsbTrd << 10) & USB_OTG_GUSBCFG_TRDT);
212
213 return HAL_OK;
214}
215
222HAL_StatusTypeDef USB_EnableGlobalInt(USB_OTG_GlobalTypeDef *USBx)
223{
224 USBx->GAHBCFG |= USB_OTG_GAHBCFG_GINT;
225 return HAL_OK;
226}
227
234HAL_StatusTypeDef USB_DisableGlobalInt(USB_OTG_GlobalTypeDef *USBx)
235{
236 USBx->GAHBCFG &= ~USB_OTG_GAHBCFG_GINT;
237 return HAL_OK;
238}
239
249HAL_StatusTypeDef USB_SetCurrentMode(USB_OTG_GlobalTypeDef *USBx, USB_OTG_ModeTypeDef mode)
250{
251 uint32_t ms = 0U;
252
253 USBx->GUSBCFG &= ~(USB_OTG_GUSBCFG_FHMOD | USB_OTG_GUSBCFG_FDMOD);
254
255 if (mode == USB_HOST_MODE)
256 {
257 USBx->GUSBCFG |= USB_OTG_GUSBCFG_FHMOD;
258
259 do
260 {
261 HAL_Delay(10U);
262 ms += 10U;
263 } while ((USB_GetMode(USBx) != (uint32_t)USB_HOST_MODE) && (ms < HAL_USB_CURRENT_MODE_MAX_DELAY_MS));
264 }
265 else if (mode == USB_DEVICE_MODE)
266 {
267 USBx->GUSBCFG |= USB_OTG_GUSBCFG_FDMOD;
268
269 do
270 {
271 HAL_Delay(10U);
272 ms += 10U;
273 } while ((USB_GetMode(USBx) != (uint32_t)USB_DEVICE_MODE) && (ms < HAL_USB_CURRENT_MODE_MAX_DELAY_MS));
274 }
275 else
276 {
277 return HAL_ERROR;
278 }
279
280 if (ms == HAL_USB_CURRENT_MODE_MAX_DELAY_MS)
281 {
282 return HAL_ERROR;
283 }
284
285 return HAL_OK;
286}
287
296HAL_StatusTypeDef USB_DevInit(USB_OTG_GlobalTypeDef *USBx, USB_OTG_CfgTypeDef cfg)
297{
299 uint32_t USBx_BASE = (uint32_t)USBx;
300 uint32_t i;
301
302 for (i = 0U; i < 15U; i++)
303 {
304 USBx->DIEPTXF[i] = 0U;
305 }
306
307#if defined(STM32F446xx) || defined(STM32F469xx) || defined(STM32F479xx) || defined(STM32F412Zx) \
308 || defined(STM32F412Vx) || defined(STM32F412Rx) || defined(STM32F412Cx) || defined(STM32F413xx) \
309 || defined(STM32F423xx)
310 /* VBUS Sensing setup */
311 if (cfg.vbus_sensing_enable == 0U)
312 {
313 USBx_DEVICE->DCTL |= USB_OTG_DCTL_SDIS;
314
315 /* Deactivate VBUS Sensing B */
316 USBx->GCCFG &= ~USB_OTG_GCCFG_VBDEN;
317
318 /* B-peripheral session valid override enable */
319 USBx->GOTGCTL |= USB_OTG_GOTGCTL_BVALOEN;
320 USBx->GOTGCTL |= USB_OTG_GOTGCTL_BVALOVAL;
321 }
322 else
323 {
324 /* Enable HW VBUS sensing */
325 USBx->GCCFG |= USB_OTG_GCCFG_VBDEN;
326 }
327#else
328 /* VBUS Sensing setup */
329 if (cfg.vbus_sensing_enable == 0U)
330 {
331 /*
332 * Disable HW VBUS sensing. VBUS is internally considered to be always
333 * at VBUS-Valid level (5V).
334 */
335 USBx_DEVICE->DCTL |= USB_OTG_DCTL_SDIS;
336 USBx->GCCFG |= USB_OTG_GCCFG_NOVBUSSENS;
337 USBx->GCCFG &= ~USB_OTG_GCCFG_VBUSBSEN;
338 USBx->GCCFG &= ~USB_OTG_GCCFG_VBUSASEN;
339 }
340 else
341 {
342 /* Enable HW VBUS sensing */
343 USBx->GCCFG &= ~USB_OTG_GCCFG_NOVBUSSENS;
344 USBx->GCCFG |= USB_OTG_GCCFG_VBUSBSEN;
345 }
346#endif /* defined(STM32F446xx) || defined(STM32F469xx) || defined(STM32F479xx) || defined(STM32F412Zx) ||
347 defined(STM32F412Vx) || defined(STM32F412Rx) || defined(STM32F412Cx) || defined(STM32F413xx) ||
348 defined(STM32F423xx) */
349
350 /* Restart the Phy Clock */
351 USBx_PCGCCTL = 0U;
352
353 if (cfg.phy_itface == USB_OTG_ULPI_PHY)
354 {
355 if (cfg.speed == USBD_HS_SPEED)
356 {
357 /* Set Core speed to High speed mode */
358 (void)USB_SetDevSpeed(USBx, USB_OTG_SPEED_HIGH);
359 }
360 else
361 {
362 /* Set Core speed to Full speed mode */
363 (void)USB_SetDevSpeed(USBx, USB_OTG_SPEED_HIGH_IN_FULL);
364 }
365 }
366 else
367 {
368 /* Set Core speed to Full speed mode */
369 (void)USB_SetDevSpeed(USBx, USB_OTG_SPEED_FULL);
370 }
371
372 /* Flush the FIFOs */
373 if (USB_FlushTxFifo(USBx, 0x10U) != HAL_OK) /* all Tx FIFOs */
374 {
375 ret = HAL_ERROR;
376 }
377
378 if (USB_FlushRxFifo(USBx) != HAL_OK)
379 {
380 ret = HAL_ERROR;
381 }
382
383 /* Clear all pending Device Interrupts */
384 USBx_DEVICE->DIEPMSK = 0U;
385 USBx_DEVICE->DOEPMSK = 0U;
386 USBx_DEVICE->DAINTMSK = 0U;
387
388 for (i = 0U; i < cfg.dev_endpoints; i++)
389 {
390 if ((USBx_INEP(i)->DIEPCTL & USB_OTG_DIEPCTL_EPENA) == USB_OTG_DIEPCTL_EPENA)
391 {
392 if (i == 0U)
393 {
394 USBx_INEP(i)->DIEPCTL = USB_OTG_DIEPCTL_SNAK;
395 }
396 else
397 {
398 USBx_INEP(i)->DIEPCTL = USB_OTG_DIEPCTL_EPDIS | USB_OTG_DIEPCTL_SNAK;
399 }
400 }
401 else
402 {
403 USBx_INEP(i)->DIEPCTL = 0U;
404 }
405
406 USBx_INEP(i)->DIEPTSIZ = 0U;
407 USBx_INEP(i)->DIEPINT = 0xFB7FU;
408 }
409
410 for (i = 0U; i < cfg.dev_endpoints; i++)
411 {
412 if ((USBx_OUTEP(i)->DOEPCTL & USB_OTG_DOEPCTL_EPENA) == USB_OTG_DOEPCTL_EPENA)
413 {
414 if (i == 0U)
415 {
416 USBx_OUTEP(i)->DOEPCTL = USB_OTG_DOEPCTL_SNAK;
417 }
418 else
419 {
420 USBx_OUTEP(i)->DOEPCTL = USB_OTG_DOEPCTL_EPDIS | USB_OTG_DOEPCTL_SNAK;
421 }
422 }
423 else
424 {
425 USBx_OUTEP(i)->DOEPCTL = 0U;
426 }
427
428 USBx_OUTEP(i)->DOEPTSIZ = 0U;
429 USBx_OUTEP(i)->DOEPINT = 0xFB7FU;
430 }
431
432 USBx_DEVICE->DIEPMSK &= ~(USB_OTG_DIEPMSK_TXFURM);
433
434 /* Disable all interrupts. */
435 USBx->GINTMSK = 0U;
436
437 /* Clear any pending interrupts */
438 USBx->GINTSTS = 0xBFFFFFFFU;
439
440 /* Enable the common interrupts */
441 if (cfg.dma_enable == 0U)
442 {
443 USBx->GINTMSK |= USB_OTG_GINTMSK_RXFLVLM;
444 }
445
446 /* Enable interrupts matching to the Device mode ONLY */
447 USBx->GINTMSK |= USB_OTG_GINTMSK_USBSUSPM | USB_OTG_GINTMSK_USBRST |
448 USB_OTG_GINTMSK_ENUMDNEM | USB_OTG_GINTMSK_IEPINT |
449 USB_OTG_GINTMSK_OEPINT | USB_OTG_GINTMSK_IISOIXFRM |
450 USB_OTG_GINTMSK_PXFRM_IISOOXFRM | USB_OTG_GINTMSK_WUIM;
451
452 if (cfg.Sof_enable != 0U)
453 {
454 USBx->GINTMSK |= USB_OTG_GINTMSK_SOFM;
455 }
456
457 if (cfg.vbus_sensing_enable == 1U)
458 {
459 USBx->GINTMSK |= (USB_OTG_GINTMSK_SRQIM | USB_OTG_GINTMSK_OTGINT);
460 }
461
462 return ret;
463}
464
473HAL_StatusTypeDef USB_FlushTxFifo(USB_OTG_GlobalTypeDef *USBx, uint32_t num)
474{
475 __IO uint32_t count = 0U;
476
477 /* Wait for AHB master IDLE state. */
478 do
479 {
480 count++;
481
482 if (count > HAL_USB_TIMEOUT)
483 {
484 return HAL_TIMEOUT;
485 }
486 } while ((USBx->GRSTCTL & USB_OTG_GRSTCTL_AHBIDL) == 0U);
487
488 /* Flush TX Fifo */
489 count = 0U;
490 USBx->GRSTCTL = (USB_OTG_GRSTCTL_TXFFLSH | (num << 6));
491
492 do
493 {
494 count++;
495
496 if (count > HAL_USB_TIMEOUT)
497 {
498 return HAL_TIMEOUT;
499 }
500 } while ((USBx->GRSTCTL & USB_OTG_GRSTCTL_TXFFLSH) == USB_OTG_GRSTCTL_TXFFLSH);
501
502 return HAL_OK;
503}
504
510HAL_StatusTypeDef USB_FlushRxFifo(USB_OTG_GlobalTypeDef *USBx)
511{
512 __IO uint32_t count = 0U;
513
514 /* Wait for AHB master IDLE state. */
515 do
516 {
517 count++;
518
519 if (count > HAL_USB_TIMEOUT)
520 {
521 return HAL_TIMEOUT;
522 }
523 } while ((USBx->GRSTCTL & USB_OTG_GRSTCTL_AHBIDL) == 0U);
524
525 /* Flush RX Fifo */
526 count = 0U;
527 USBx->GRSTCTL = USB_OTG_GRSTCTL_RXFFLSH;
528
529 do
530 {
531 count++;
532
533 if (count > HAL_USB_TIMEOUT)
534 {
535 return HAL_TIMEOUT;
536 }
537 } while ((USBx->GRSTCTL & USB_OTG_GRSTCTL_RXFFLSH) == USB_OTG_GRSTCTL_RXFFLSH);
538
539 return HAL_OK;
540}
541
553HAL_StatusTypeDef USB_SetDevSpeed(const USB_OTG_GlobalTypeDef *USBx, uint8_t speed)
554{
555 uint32_t USBx_BASE = (uint32_t)USBx;
556
557 USBx_DEVICE->DCFG |= speed;
558 return HAL_OK;
559}
560
569uint8_t USB_GetDevSpeed(const USB_OTG_GlobalTypeDef *USBx)
570{
571 uint32_t USBx_BASE = (uint32_t)USBx;
572 uint8_t speed;
573 uint32_t DevEnumSpeed = USBx_DEVICE->DSTS & USB_OTG_DSTS_ENUMSPD;
574
575 if (DevEnumSpeed == DSTS_ENUMSPD_HS_PHY_30MHZ_OR_60MHZ)
576 {
577 speed = USBD_HS_SPEED;
578 }
579 else if ((DevEnumSpeed == DSTS_ENUMSPD_FS_PHY_30MHZ_OR_60MHZ) ||
580 (DevEnumSpeed == DSTS_ENUMSPD_FS_PHY_48MHZ))
581 {
582 speed = USBD_FS_SPEED;
583 }
584 else
585 {
586 speed = 0xFU;
587 }
588
589 return speed;
590}
591
598HAL_StatusTypeDef USB_ActivateEndpoint(const USB_OTG_GlobalTypeDef *USBx, const USB_OTG_EPTypeDef *ep)
599{
600 uint32_t USBx_BASE = (uint32_t)USBx;
601 uint32_t epnum = (uint32_t)ep->num;
602
603 if (ep->is_in == 1U)
604 {
605 USBx_DEVICE->DAINTMSK |= USB_OTG_DAINTMSK_IEPM & (uint32_t)(1UL << (ep->num & EP_ADDR_MSK));
606
607 if ((USBx_INEP(epnum)->DIEPCTL & USB_OTG_DIEPCTL_USBAEP) == 0U)
608 {
609 USBx_INEP(epnum)->DIEPCTL |= (ep->maxpacket & USB_OTG_DIEPCTL_MPSIZ) |
610 ((uint32_t)ep->type << 18) | (epnum << 22) |
611 USB_OTG_DIEPCTL_SD0PID_SEVNFRM |
612 USB_OTG_DIEPCTL_USBAEP;
613 }
614 }
615 else
616 {
617 USBx_DEVICE->DAINTMSK |= USB_OTG_DAINTMSK_OEPM & ((uint32_t)(1UL << (ep->num & EP_ADDR_MSK)) << 16);
618
619 if (((USBx_OUTEP(epnum)->DOEPCTL) & USB_OTG_DOEPCTL_USBAEP) == 0U)
620 {
621 USBx_OUTEP(epnum)->DOEPCTL |= (ep->maxpacket & USB_OTG_DOEPCTL_MPSIZ) |
622 ((uint32_t)ep->type << 18) |
623 USB_OTG_DIEPCTL_SD0PID_SEVNFRM |
624 USB_OTG_DOEPCTL_USBAEP;
625 }
626 }
627 return HAL_OK;
628}
629
636HAL_StatusTypeDef USB_ActivateDedicatedEndpoint(const USB_OTG_GlobalTypeDef *USBx, const USB_OTG_EPTypeDef *ep)
637{
638 uint32_t USBx_BASE = (uint32_t)USBx;
639 uint32_t epnum = (uint32_t)ep->num;
640
641 /* Read DEPCTLn register */
642 if (ep->is_in == 1U)
643 {
644 if (((USBx_INEP(epnum)->DIEPCTL) & USB_OTG_DIEPCTL_USBAEP) == 0U)
645 {
646 USBx_INEP(epnum)->DIEPCTL |= (ep->maxpacket & USB_OTG_DIEPCTL_MPSIZ) |
647 ((uint32_t)ep->type << 18) | (epnum << 22) |
648 USB_OTG_DIEPCTL_SD0PID_SEVNFRM |
649 USB_OTG_DIEPCTL_USBAEP;
650 }
651
652 USBx_DEVICE->DEACHMSK |= USB_OTG_DAINTMSK_IEPM & (uint32_t)(1UL << (ep->num & EP_ADDR_MSK));
653 }
654 else
655 {
656 if (((USBx_OUTEP(epnum)->DOEPCTL) & USB_OTG_DOEPCTL_USBAEP) == 0U)
657 {
658 USBx_OUTEP(epnum)->DOEPCTL |= (ep->maxpacket & USB_OTG_DOEPCTL_MPSIZ) |
659 ((uint32_t)ep->type << 18) | (epnum << 22) |
660 USB_OTG_DOEPCTL_USBAEP;
661 }
662
663 USBx_DEVICE->DEACHMSK |= USB_OTG_DAINTMSK_OEPM & ((uint32_t)(1UL << (ep->num & EP_ADDR_MSK)) << 16);
664 }
665
666 return HAL_OK;
667}
668
675HAL_StatusTypeDef USB_DeactivateEndpoint(const USB_OTG_GlobalTypeDef *USBx, const USB_OTG_EPTypeDef *ep)
676{
677 uint32_t USBx_BASE = (uint32_t)USBx;
678 uint32_t epnum = (uint32_t)ep->num;
679
680 /* Read DEPCTLn register */
681 if (ep->is_in == 1U)
682 {
683 if ((USBx_INEP(epnum)->DIEPCTL & USB_OTG_DIEPCTL_EPENA) == USB_OTG_DIEPCTL_EPENA)
684 {
685 USBx_INEP(epnum)->DIEPCTL |= USB_OTG_DIEPCTL_SNAK;
686 USBx_INEP(epnum)->DIEPCTL |= USB_OTG_DIEPCTL_EPDIS;
687 }
688
689 USBx_DEVICE->DEACHMSK &= ~(USB_OTG_DAINTMSK_IEPM & (uint32_t)(1UL << (ep->num & EP_ADDR_MSK)));
690 USBx_DEVICE->DAINTMSK &= ~(USB_OTG_DAINTMSK_IEPM & (uint32_t)(1UL << (ep->num & EP_ADDR_MSK)));
691 USBx_INEP(epnum)->DIEPCTL &= ~(USB_OTG_DIEPCTL_USBAEP |
692 USB_OTG_DIEPCTL_MPSIZ |
693 USB_OTG_DIEPCTL_TXFNUM |
694 USB_OTG_DIEPCTL_SD0PID_SEVNFRM |
695 USB_OTG_DIEPCTL_EPTYP);
696 }
697 else
698 {
699 if ((USBx_OUTEP(epnum)->DOEPCTL & USB_OTG_DOEPCTL_EPENA) == USB_OTG_DOEPCTL_EPENA)
700 {
701 USBx_OUTEP(epnum)->DOEPCTL |= USB_OTG_DOEPCTL_SNAK;
702 USBx_OUTEP(epnum)->DOEPCTL |= USB_OTG_DOEPCTL_EPDIS;
703 }
704
705 USBx_DEVICE->DEACHMSK &= ~(USB_OTG_DAINTMSK_OEPM & ((uint32_t)(1UL << (ep->num & EP_ADDR_MSK)) << 16));
706 USBx_DEVICE->DAINTMSK &= ~(USB_OTG_DAINTMSK_OEPM & ((uint32_t)(1UL << (ep->num & EP_ADDR_MSK)) << 16));
707 USBx_OUTEP(epnum)->DOEPCTL &= ~(USB_OTG_DOEPCTL_USBAEP |
708 USB_OTG_DOEPCTL_MPSIZ |
709 USB_OTG_DOEPCTL_SD0PID_SEVNFRM |
710 USB_OTG_DOEPCTL_EPTYP);
711 }
712
713 return HAL_OK;
714}
715
722HAL_StatusTypeDef USB_DeactivateDedicatedEndpoint(const USB_OTG_GlobalTypeDef *USBx, const USB_OTG_EPTypeDef *ep)
723{
724 uint32_t USBx_BASE = (uint32_t)USBx;
725 uint32_t epnum = (uint32_t)ep->num;
726
727 /* Read DEPCTLn register */
728 if (ep->is_in == 1U)
729 {
730 if ((USBx_INEP(epnum)->DIEPCTL & USB_OTG_DIEPCTL_EPENA) == USB_OTG_DIEPCTL_EPENA)
731 {
732 USBx_INEP(epnum)->DIEPCTL |= USB_OTG_DIEPCTL_SNAK;
733 USBx_INEP(epnum)->DIEPCTL |= USB_OTG_DIEPCTL_EPDIS;
734 }
735
736 USBx_INEP(epnum)->DIEPCTL &= ~ USB_OTG_DIEPCTL_USBAEP;
737 USBx_DEVICE->DAINTMSK &= ~(USB_OTG_DAINTMSK_IEPM & (uint32_t)(1UL << (ep->num & EP_ADDR_MSK)));
738 }
739 else
740 {
741 if ((USBx_OUTEP(epnum)->DOEPCTL & USB_OTG_DOEPCTL_EPENA) == USB_OTG_DOEPCTL_EPENA)
742 {
743 USBx_OUTEP(epnum)->DOEPCTL |= USB_OTG_DOEPCTL_SNAK;
744 USBx_OUTEP(epnum)->DOEPCTL |= USB_OTG_DOEPCTL_EPDIS;
745 }
746
747 USBx_OUTEP(epnum)->DOEPCTL &= ~USB_OTG_DOEPCTL_USBAEP;
748 USBx_DEVICE->DAINTMSK &= ~(USB_OTG_DAINTMSK_OEPM & ((uint32_t)(1UL << (ep->num & EP_ADDR_MSK)) << 16));
749 }
750
751 return HAL_OK;
752}
753
764HAL_StatusTypeDef USB_EPStartXfer(USB_OTG_GlobalTypeDef *USBx, USB_OTG_EPTypeDef *ep, uint8_t dma)
765{
766 uint32_t USBx_BASE = (uint32_t)USBx;
767 uint32_t epnum = (uint32_t)ep->num;
768 uint16_t pktcnt;
769
770 /* IN endpoint */
771 if (ep->is_in == 1U)
772 {
773 /* Zero Length Packet? */
774 if (ep->xfer_len == 0U)
775 {
776 USBx_INEP(epnum)->DIEPTSIZ &= ~(USB_OTG_DIEPTSIZ_PKTCNT);
777 USBx_INEP(epnum)->DIEPTSIZ |= (USB_OTG_DIEPTSIZ_PKTCNT & (1U << 19));
778 USBx_INEP(epnum)->DIEPTSIZ &= ~(USB_OTG_DIEPTSIZ_XFRSIZ);
779 }
780 else
781 {
782 /* Program the transfer size and packet count
783 * as follows: xfersize = N * maxpacket +
784 * short_packet pktcnt = N + (short_packet
785 * exist ? 1 : 0)
786 */
787 USBx_INEP(epnum)->DIEPTSIZ &= ~(USB_OTG_DIEPTSIZ_XFRSIZ);
788 USBx_INEP(epnum)->DIEPTSIZ &= ~(USB_OTG_DIEPTSIZ_PKTCNT);
789
790 if (epnum == 0U)
791 {
792 if (ep->xfer_len > ep->maxpacket)
793 {
794 ep->xfer_len = ep->maxpacket;
795 }
796
797 USBx_INEP(epnum)->DIEPTSIZ |= (USB_OTG_DIEPTSIZ_PKTCNT & (1U << 19));
798 }
799 else
800 {
801 pktcnt = (uint16_t)((ep->xfer_len + ep->maxpacket - 1U) / ep->maxpacket);
802 USBx_INEP(epnum)->DIEPTSIZ |= (USB_OTG_DIEPTSIZ_PKTCNT & ((uint32_t)pktcnt << 19));
803
804 if (ep->type == EP_TYPE_ISOC)
805 {
806 USBx_INEP(epnum)->DIEPTSIZ &= ~(USB_OTG_DIEPTSIZ_MULCNT);
807 USBx_INEP(epnum)->DIEPTSIZ |= (USB_OTG_DIEPTSIZ_MULCNT & ((uint32_t)pktcnt << 29));
808 }
809 }
810
811 USBx_INEP(epnum)->DIEPTSIZ |= (USB_OTG_DIEPTSIZ_XFRSIZ & ep->xfer_len);
812 }
813
814 if (dma == 1U)
815 {
816 if ((uint32_t)ep->dma_addr != 0U)
817 {
818 USBx_INEP(epnum)->DIEPDMA = (uint32_t)(ep->dma_addr);
819 }
820
821 if (ep->type == EP_TYPE_ISOC)
822 {
823 if ((USBx_DEVICE->DSTS & (1U << 8)) == 0U)
824 {
825 USBx_INEP(epnum)->DIEPCTL |= USB_OTG_DIEPCTL_SODDFRM;
826 }
827 else
828 {
829 USBx_INEP(epnum)->DIEPCTL |= USB_OTG_DIEPCTL_SD0PID_SEVNFRM;
830 }
831 }
832
833 /* EP enable, IN data in FIFO */
834 USBx_INEP(epnum)->DIEPCTL |= (USB_OTG_DIEPCTL_CNAK | USB_OTG_DIEPCTL_EPENA);
835 }
836 else
837 {
838 /* EP enable, IN data in FIFO */
839 USBx_INEP(epnum)->DIEPCTL |= (USB_OTG_DIEPCTL_CNAK | USB_OTG_DIEPCTL_EPENA);
840
841 if (ep->type != EP_TYPE_ISOC)
842 {
843 /* Enable the Tx FIFO Empty Interrupt for this EP */
844 if (ep->xfer_len > 0U)
845 {
846 USBx_DEVICE->DIEPEMPMSK |= 1UL << (ep->num & EP_ADDR_MSK);
847 }
848 }
849 else
850 {
851 if ((USBx_DEVICE->DSTS & (1U << 8)) == 0U)
852 {
853 USBx_INEP(epnum)->DIEPCTL |= USB_OTG_DIEPCTL_SODDFRM;
854 }
855 else
856 {
857 USBx_INEP(epnum)->DIEPCTL |= USB_OTG_DIEPCTL_SD0PID_SEVNFRM;
858 }
859
860 (void)USB_WritePacket(USBx, ep->xfer_buff, ep->num, (uint16_t)ep->xfer_len, dma);
861 }
862 }
863 }
864 else /* OUT endpoint */
865 {
866 /* Program the transfer size and packet count as follows:
867 * pktcnt = N
868 * xfersize = N * maxpacket
869 */
870 USBx_OUTEP(epnum)->DOEPTSIZ &= ~(USB_OTG_DOEPTSIZ_XFRSIZ);
871 USBx_OUTEP(epnum)->DOEPTSIZ &= ~(USB_OTG_DOEPTSIZ_PKTCNT);
872
873 if (epnum == 0U)
874 {
875 if (ep->xfer_len > 0U)
876 {
877 ep->xfer_len = ep->maxpacket;
878 }
879
880 /* Store transfer size, for EP0 this is equal to endpoint max packet size */
881 ep->xfer_size = ep->maxpacket;
882
883 USBx_OUTEP(epnum)->DOEPTSIZ |= (USB_OTG_DOEPTSIZ_XFRSIZ & ep->xfer_size);
884 USBx_OUTEP(epnum)->DOEPTSIZ |= (USB_OTG_DOEPTSIZ_PKTCNT & (1U << 19));
885 }
886 else
887 {
888 if (ep->xfer_len == 0U)
889 {
890 USBx_OUTEP(epnum)->DOEPTSIZ |= (USB_OTG_DOEPTSIZ_XFRSIZ & ep->maxpacket);
891 USBx_OUTEP(epnum)->DOEPTSIZ |= (USB_OTG_DOEPTSIZ_PKTCNT & (1U << 19));
892 }
893 else
894 {
895 pktcnt = (uint16_t)((ep->xfer_len + ep->maxpacket - 1U) / ep->maxpacket);
896 ep->xfer_size = ep->maxpacket * pktcnt;
897
898 USBx_OUTEP(epnum)->DOEPTSIZ |= USB_OTG_DOEPTSIZ_PKTCNT & ((uint32_t)pktcnt << 19);
899 USBx_OUTEP(epnum)->DOEPTSIZ |= USB_OTG_DOEPTSIZ_XFRSIZ & ep->xfer_size;
900 }
901 }
902
903 if (dma == 1U)
904 {
905 if ((uint32_t)ep->xfer_buff != 0U)
906 {
907 USBx_OUTEP(epnum)->DOEPDMA = (uint32_t)(ep->xfer_buff);
908 }
909 }
910
911 if (ep->type == EP_TYPE_ISOC)
912 {
913 if ((USBx_DEVICE->DSTS & (1U << 8)) == 0U)
914 {
915 USBx_OUTEP(epnum)->DOEPCTL |= USB_OTG_DOEPCTL_SODDFRM;
916 }
917 else
918 {
919 USBx_OUTEP(epnum)->DOEPCTL |= USB_OTG_DOEPCTL_SD0PID_SEVNFRM;
920 }
921 }
922 /* EP enable */
923 USBx_OUTEP(epnum)->DOEPCTL |= (USB_OTG_DOEPCTL_CNAK | USB_OTG_DOEPCTL_EPENA);
924 }
925
926 return HAL_OK;
927}
928
929
936HAL_StatusTypeDef USB_EPStopXfer(const USB_OTG_GlobalTypeDef *USBx, USB_OTG_EPTypeDef *ep)
937{
938 __IO uint32_t count = 0U;
940 uint32_t USBx_BASE = (uint32_t)USBx;
941
942 /* IN endpoint */
943 if (ep->is_in == 1U)
944 {
945 /* EP enable, IN data in FIFO */
946 if (((USBx_INEP(ep->num)->DIEPCTL) & USB_OTG_DIEPCTL_EPENA) == USB_OTG_DIEPCTL_EPENA)
947 {
948 USBx_INEP(ep->num)->DIEPCTL |= (USB_OTG_DIEPCTL_SNAK);
949 USBx_INEP(ep->num)->DIEPCTL |= (USB_OTG_DIEPCTL_EPDIS);
950
951 do
952 {
953 count++;
954
955 if (count > 10000U)
956 {
957 ret = HAL_ERROR;
958 break;
959 }
960 } while (((USBx_INEP(ep->num)->DIEPCTL) & USB_OTG_DIEPCTL_EPENA) == USB_OTG_DIEPCTL_EPENA);
961 }
962 }
963 else /* OUT endpoint */
964 {
965 if (((USBx_OUTEP(ep->num)->DOEPCTL) & USB_OTG_DOEPCTL_EPENA) == USB_OTG_DOEPCTL_EPENA)
966 {
967 USBx_OUTEP(ep->num)->DOEPCTL |= (USB_OTG_DOEPCTL_SNAK);
968 USBx_OUTEP(ep->num)->DOEPCTL |= (USB_OTG_DOEPCTL_EPDIS);
969
970 do
971 {
972 count++;
973
974 if (count > 10000U)
975 {
976 ret = HAL_ERROR;
977 break;
978 }
979 } while (((USBx_OUTEP(ep->num)->DOEPCTL) & USB_OTG_DOEPCTL_EPENA) == USB_OTG_DOEPCTL_EPENA);
980 }
981 }
982
983 return ret;
984}
985
986
1000HAL_StatusTypeDef USB_WritePacket(const USB_OTG_GlobalTypeDef *USBx, uint8_t *src,
1001 uint8_t ch_ep_num, uint16_t len, uint8_t dma)
1002{
1003 uint32_t USBx_BASE = (uint32_t)USBx;
1004 uint8_t *pSrc = src;
1005 uint32_t count32b;
1006 uint32_t i;
1007
1008 if (dma == 0U)
1009 {
1010 count32b = ((uint32_t)len + 3U) / 4U;
1011 for (i = 0U; i < count32b; i++)
1012 {
1013 USBx_DFIFO((uint32_t)ch_ep_num) = __UNALIGNED_UINT32_READ(pSrc);
1014 pSrc++;
1015 pSrc++;
1016 pSrc++;
1017 pSrc++;
1018 }
1019 }
1020
1021 return HAL_OK;
1022}
1023
1031void *USB_ReadPacket(const USB_OTG_GlobalTypeDef *USBx, uint8_t *dest, uint16_t len)
1032{
1033 uint32_t USBx_BASE = (uint32_t)USBx;
1034 uint8_t *pDest = dest;
1035 uint32_t pData;
1036 uint32_t i;
1037 uint32_t count32b = (uint32_t)len >> 2U;
1038 uint16_t remaining_bytes = len % 4U;
1039
1040 for (i = 0U; i < count32b; i++)
1041 {
1042 __UNALIGNED_UINT32_WRITE(pDest, USBx_DFIFO(0U));
1043 pDest++;
1044 pDest++;
1045 pDest++;
1046 pDest++;
1047 }
1048
1049 /* When Number of data is not word aligned, read the remaining byte */
1050 if (remaining_bytes != 0U)
1051 {
1052 i = 0U;
1053 __UNALIGNED_UINT32_WRITE(&pData, USBx_DFIFO(0U));
1054
1055 do
1056 {
1057 *(uint8_t *)pDest = (uint8_t)(pData >> (8U * (uint8_t)(i)));
1058 i++;
1059 pDest++;
1060 remaining_bytes--;
1061 } while (remaining_bytes != 0U);
1062 }
1063
1064 return ((void *)pDest);
1065}
1066
1073HAL_StatusTypeDef USB_EPSetStall(const USB_OTG_GlobalTypeDef *USBx, const USB_OTG_EPTypeDef *ep)
1074{
1075 uint32_t USBx_BASE = (uint32_t)USBx;
1076 uint32_t epnum = (uint32_t)ep->num;
1077
1078 if (ep->is_in == 1U)
1079 {
1080 if (((USBx_INEP(epnum)->DIEPCTL & USB_OTG_DIEPCTL_EPENA) == 0U) && (epnum != 0U))
1081 {
1082 USBx_INEP(epnum)->DIEPCTL &= ~(USB_OTG_DIEPCTL_EPDIS);
1083 }
1084 USBx_INEP(epnum)->DIEPCTL |= USB_OTG_DIEPCTL_STALL;
1085 }
1086 else
1087 {
1088 if (((USBx_OUTEP(epnum)->DOEPCTL & USB_OTG_DOEPCTL_EPENA) == 0U) && (epnum != 0U))
1089 {
1090 USBx_OUTEP(epnum)->DOEPCTL &= ~(USB_OTG_DOEPCTL_EPDIS);
1091 }
1092 USBx_OUTEP(epnum)->DOEPCTL |= USB_OTG_DOEPCTL_STALL;
1093 }
1094
1095 return HAL_OK;
1096}
1097
1104HAL_StatusTypeDef USB_EPClearStall(const USB_OTG_GlobalTypeDef *USBx, const USB_OTG_EPTypeDef *ep)
1105{
1106 uint32_t USBx_BASE = (uint32_t)USBx;
1107 uint32_t epnum = (uint32_t)ep->num;
1108
1109 if (ep->is_in == 1U)
1110 {
1111 USBx_INEP(epnum)->DIEPCTL &= ~USB_OTG_DIEPCTL_STALL;
1112 if ((ep->type == EP_TYPE_INTR) || (ep->type == EP_TYPE_BULK))
1113 {
1114 USBx_INEP(epnum)->DIEPCTL |= USB_OTG_DIEPCTL_SD0PID_SEVNFRM; /* DATA0 */
1115 }
1116 }
1117 else
1118 {
1119 USBx_OUTEP(epnum)->DOEPCTL &= ~USB_OTG_DOEPCTL_STALL;
1120 if ((ep->type == EP_TYPE_INTR) || (ep->type == EP_TYPE_BULK))
1121 {
1122 USBx_OUTEP(epnum)->DOEPCTL |= USB_OTG_DOEPCTL_SD0PID_SEVNFRM; /* DATA0 */
1123 }
1124 }
1125 return HAL_OK;
1126}
1127
1133HAL_StatusTypeDef USB_StopDevice(USB_OTG_GlobalTypeDef *USBx)
1134{
1136 uint32_t USBx_BASE = (uint32_t)USBx;
1137 uint32_t i;
1138
1139 /* Clear Pending interrupt */
1140 for (i = 0U; i < 15U; i++)
1141 {
1142 USBx_INEP(i)->DIEPINT = 0xFB7FU;
1143 USBx_OUTEP(i)->DOEPINT = 0xFB7FU;
1144 }
1145
1146 /* Clear interrupt masks */
1147 USBx_DEVICE->DIEPMSK = 0U;
1148 USBx_DEVICE->DOEPMSK = 0U;
1149 USBx_DEVICE->DAINTMSK = 0U;
1150
1151 /* Flush the FIFO */
1152 ret = USB_FlushRxFifo(USBx);
1153 if (ret != HAL_OK)
1154 {
1155 return ret;
1156 }
1157
1158 ret = USB_FlushTxFifo(USBx, 0x10U);
1159 if (ret != HAL_OK)
1160 {
1161 return ret;
1162 }
1163
1164 return ret;
1165}
1166
1174HAL_StatusTypeDef USB_SetDevAddress(const USB_OTG_GlobalTypeDef *USBx, uint8_t address)
1175{
1176 uint32_t USBx_BASE = (uint32_t)USBx;
1177
1178 USBx_DEVICE->DCFG &= ~(USB_OTG_DCFG_DAD);
1179 USBx_DEVICE->DCFG |= ((uint32_t)address << 4) & USB_OTG_DCFG_DAD;
1180
1181 return HAL_OK;
1182}
1183
1189HAL_StatusTypeDef USB_DevConnect(const USB_OTG_GlobalTypeDef *USBx)
1190{
1191 uint32_t USBx_BASE = (uint32_t)USBx;
1192
1193 /* In case phy is stopped, ensure to ungate and restore the phy CLK */
1194 USBx_PCGCCTL &= ~(USB_OTG_PCGCCTL_STOPCLK | USB_OTG_PCGCCTL_GATECLK);
1195
1196 USBx_DEVICE->DCTL &= ~USB_OTG_DCTL_SDIS;
1197
1198 return HAL_OK;
1199}
1200
1206HAL_StatusTypeDef USB_DevDisconnect(const USB_OTG_GlobalTypeDef *USBx)
1207{
1208 uint32_t USBx_BASE = (uint32_t)USBx;
1209
1210 /* In case phy is stopped, ensure to ungate and restore the phy CLK */
1211 USBx_PCGCCTL &= ~(USB_OTG_PCGCCTL_STOPCLK | USB_OTG_PCGCCTL_GATECLK);
1212
1213 USBx_DEVICE->DCTL |= USB_OTG_DCTL_SDIS;
1214
1215 return HAL_OK;
1216}
1217
1223uint32_t USB_ReadInterrupts(USB_OTG_GlobalTypeDef const *USBx)
1224{
1225 uint32_t tmpreg;
1226
1227 tmpreg = USBx->GINTSTS;
1228 tmpreg &= USBx->GINTMSK;
1229
1230 return tmpreg;
1231}
1232
1239uint32_t USB_ReadChInterrupts(const USB_OTG_GlobalTypeDef *USBx, uint8_t chnum)
1240{
1241 uint32_t USBx_BASE = (uint32_t)USBx;
1242 uint32_t tmpreg;
1243
1244 tmpreg = USBx_HC(chnum)->HCINT;
1245 tmpreg &= USBx_HC(chnum)->HCINTMSK;
1246
1247 return tmpreg;
1248}
1249
1255uint32_t USB_ReadDevAllOutEpInterrupt(const USB_OTG_GlobalTypeDef *USBx)
1256{
1257 uint32_t USBx_BASE = (uint32_t)USBx;
1258 uint32_t tmpreg;
1259
1260 tmpreg = USBx_DEVICE->DAINT;
1261 tmpreg &= USBx_DEVICE->DAINTMSK;
1262
1263 return ((tmpreg & 0xffff0000U) >> 16);
1264}
1265
1271uint32_t USB_ReadDevAllInEpInterrupt(const USB_OTG_GlobalTypeDef *USBx)
1272{
1273 uint32_t USBx_BASE = (uint32_t)USBx;
1274 uint32_t tmpreg;
1275
1276 tmpreg = USBx_DEVICE->DAINT;
1277 tmpreg &= USBx_DEVICE->DAINTMSK;
1278
1279 return ((tmpreg & 0xFFFFU));
1280}
1281
1289uint32_t USB_ReadDevOutEPInterrupt(const USB_OTG_GlobalTypeDef *USBx, uint8_t epnum)
1290{
1291 uint32_t USBx_BASE = (uint32_t)USBx;
1292 uint32_t tmpreg;
1293
1294 tmpreg = USBx_OUTEP((uint32_t)epnum)->DOEPINT;
1295 tmpreg &= USBx_DEVICE->DOEPMSK;
1296
1297 return tmpreg;
1298}
1299
1307uint32_t USB_ReadDevInEPInterrupt(const USB_OTG_GlobalTypeDef *USBx, uint8_t epnum)
1308{
1309 uint32_t USBx_BASE = (uint32_t)USBx;
1310 uint32_t tmpreg;
1311 uint32_t msk;
1312 uint32_t emp;
1313
1314 msk = USBx_DEVICE->DIEPMSK;
1315 emp = USBx_DEVICE->DIEPEMPMSK;
1316 msk |= ((emp >> (epnum & EP_ADDR_MSK)) & 0x1U) << 7;
1317 tmpreg = USBx_INEP((uint32_t)epnum)->DIEPINT & msk;
1318
1319 return tmpreg;
1320}
1321
1328void USB_ClearInterrupts(USB_OTG_GlobalTypeDef *USBx, uint32_t interrupt)
1329{
1330 USBx->GINTSTS &= interrupt;
1331}
1332
1341uint32_t USB_GetMode(const USB_OTG_GlobalTypeDef *USBx)
1342{
1343 return ((USBx->GINTSTS) & 0x1U);
1344}
1345
1351HAL_StatusTypeDef USB_ActivateSetup(const USB_OTG_GlobalTypeDef *USBx)
1352{
1353 uint32_t USBx_BASE = (uint32_t)USBx;
1354
1355 /* Set the MPS of the IN EP0 to 64 bytes */
1356 USBx_INEP(0U)->DIEPCTL &= ~USB_OTG_DIEPCTL_MPSIZ;
1357
1358 USBx_DEVICE->DCTL |= USB_OTG_DCTL_CGINAK;
1359
1360 return HAL_OK;
1361}
1362
1373HAL_StatusTypeDef USB_EP0_OutStart(const USB_OTG_GlobalTypeDef *USBx, uint8_t dma, const uint8_t *psetup)
1374{
1375 uint32_t USBx_BASE = (uint32_t)USBx;
1376 uint32_t gSNPSiD = *(__IO const uint32_t *)(&USBx->CID + 0x1U);
1377
1378 if (gSNPSiD > USB_OTG_CORE_ID_300A)
1379 {
1380 if ((USBx_OUTEP(0U)->DOEPCTL & USB_OTG_DOEPCTL_EPENA) == USB_OTG_DOEPCTL_EPENA)
1381 {
1382 return HAL_OK;
1383 }
1384 }
1385
1386 USBx_OUTEP(0U)->DOEPTSIZ = 0U;
1387 USBx_OUTEP(0U)->DOEPTSIZ |= (USB_OTG_DOEPTSIZ_PKTCNT & (1U << 19));
1388 USBx_OUTEP(0U)->DOEPTSIZ |= (3U * 8U);
1389 USBx_OUTEP(0U)->DOEPTSIZ |= USB_OTG_DOEPTSIZ_STUPCNT;
1390
1391 if (dma == 1U)
1392 {
1393 USBx_OUTEP(0U)->DOEPDMA = (uint32_t)psetup;
1394 /* EP enable */
1395 USBx_OUTEP(0U)->DOEPCTL |= USB_OTG_DOEPCTL_EPENA | USB_OTG_DOEPCTL_USBAEP;
1396 }
1397
1398 return HAL_OK;
1399}
1400
1406static HAL_StatusTypeDef USB_CoreReset(USB_OTG_GlobalTypeDef *USBx)
1407{
1408 __IO uint32_t count = 0U;
1409
1410 /* Wait for AHB master IDLE state. */
1411 do
1412 {
1413 count++;
1414
1415 if (count > HAL_USB_TIMEOUT)
1416 {
1417 return HAL_TIMEOUT;
1418 }
1419 } while ((USBx->GRSTCTL & USB_OTG_GRSTCTL_AHBIDL) == 0U);
1420
1421 count = 10U;
1422
1423 /* few cycles before setting core reset */
1424 while (count > 0U)
1425 {
1426 count--;
1427 }
1428
1429 /* Core Soft Reset */
1430 USBx->GRSTCTL |= USB_OTG_GRSTCTL_CSRST;
1431
1432 do
1433 {
1434 count++;
1435
1436 if (count > HAL_USB_TIMEOUT)
1437 {
1438 return HAL_TIMEOUT;
1439 }
1440 } while ((USBx->GRSTCTL & USB_OTG_GRSTCTL_CSRST) == USB_OTG_GRSTCTL_CSRST);
1441
1442 return HAL_OK;
1443}
1444
1453HAL_StatusTypeDef USB_HostInit(USB_OTG_GlobalTypeDef *USBx, USB_OTG_CfgTypeDef cfg)
1454{
1456 uint32_t USBx_BASE = (uint32_t)USBx;
1457 uint32_t i;
1458
1459 /* Restart the Phy Clock */
1460 USBx_PCGCCTL = 0U;
1461
1462#if defined(STM32F446xx) || defined(STM32F469xx) || defined(STM32F479xx) || defined(STM32F412Zx) \
1463 || defined(STM32F412Vx) || defined(STM32F412Rx) || defined(STM32F412Cx) || defined(STM32F413xx) \
1464 || defined(STM32F423xx)
1465 /* Disable HW VBUS sensing */
1466 USBx->GCCFG &= ~(USB_OTG_GCCFG_VBDEN);
1467#else
1468 /*
1469 * Disable HW VBUS sensing. VBUS is internally considered to be always
1470 * at VBUS-Valid level (5V).
1471 */
1472 USBx->GCCFG |= USB_OTG_GCCFG_NOVBUSSENS;
1473 USBx->GCCFG &= ~USB_OTG_GCCFG_VBUSBSEN;
1474 USBx->GCCFG &= ~USB_OTG_GCCFG_VBUSASEN;
1475#endif /* defined(STM32F446xx) || defined(STM32F469xx) || defined(STM32F479xx) || defined(STM32F412Zx) ||
1476 defined(STM32F412Vx) || defined(STM32F412Rx) || defined(STM32F412Cx) || defined(STM32F413xx) ||
1477 defined(STM32F423xx) */
1478#if defined(STM32F412Zx) || defined(STM32F412Vx) || defined(STM32F412Rx) \
1479 || defined(STM32F412Cx) || defined(STM32F413xx) || defined(STM32F423xx)
1480 /* Disable Battery chargin detector */
1481 USBx->GCCFG &= ~(USB_OTG_GCCFG_BCDEN);
1482#endif /* defined(STM32F412Zx) || defined(STM32F412Vx) || defined(STM32F412Rx) ||
1483 defined(STM32F412Cx) || defined(STM32F413xx) || defined(STM32F423xx) */
1484
1485 if ((USBx->GUSBCFG & USB_OTG_GUSBCFG_PHYSEL) == 0U)
1486 {
1487 if (cfg.speed == USBH_FSLS_SPEED)
1488 {
1489 /* Force Device Enumeration to FS/LS mode only */
1490 USBx_HOST->HCFG |= USB_OTG_HCFG_FSLSS;
1491 }
1492 else
1493 {
1494 /* Set default Max speed support */
1495 USBx_HOST->HCFG &= ~(USB_OTG_HCFG_FSLSS);
1496 }
1497 }
1498 else
1499 {
1500 /* Set default Max speed support */
1501 USBx_HOST->HCFG &= ~(USB_OTG_HCFG_FSLSS);
1502 }
1503
1504 /* Make sure the FIFOs are flushed. */
1505 if (USB_FlushTxFifo(USBx, 0x10U) != HAL_OK) /* all Tx FIFOs */
1506 {
1507 ret = HAL_ERROR;
1508 }
1509
1510 if (USB_FlushRxFifo(USBx) != HAL_OK)
1511 {
1512 ret = HAL_ERROR;
1513 }
1514
1515 /* Clear all pending HC Interrupts */
1516 for (i = 0U; i < cfg.Host_channels; i++)
1517 {
1518 USBx_HC(i)->HCINT = CLEAR_INTERRUPT_MASK;
1519 USBx_HC(i)->HCINTMSK = 0U;
1520 }
1521
1522 /* Disable all interrupts. */
1523 USBx->GINTMSK = 0U;
1524
1525 /* Clear any pending interrupts */
1526 USBx->GINTSTS = CLEAR_INTERRUPT_MASK;
1527#if defined (USB_OTG_HS)
1528 if (USBx == USB_OTG_HS)
1529 {
1530 /* set Rx FIFO size */
1531 USBx->GRXFSIZ = 0x200U;
1532 USBx->DIEPTXF0_HNPTXFSIZ = (uint32_t)(((0x100U << 16) & USB_OTG_NPTXFD) | 0x200U);
1533 USBx->HPTXFSIZ = (uint32_t)(((0xE0U << 16) & USB_OTG_HPTXFSIZ_PTXFD) | 0x300U);
1534 }
1535 else
1536#endif /* defined (USB_OTG_HS) */
1537 {
1538 /* set Rx FIFO size */
1539 USBx->GRXFSIZ = 0x80U;
1540 USBx->DIEPTXF0_HNPTXFSIZ = (uint32_t)(((0x60U << 16) & USB_OTG_NPTXFD) | 0x80U);
1541 USBx->HPTXFSIZ = (uint32_t)(((0x40U << 16)& USB_OTG_HPTXFSIZ_PTXFD) | 0xE0U);
1542 }
1543
1544 /* Enable the common interrupts */
1545 if (cfg.dma_enable == 0U)
1546 {
1547 USBx->GINTMSK |= USB_OTG_GINTMSK_RXFLVLM;
1548 }
1549
1550 /* Enable interrupts matching to the Host mode ONLY */
1551 USBx->GINTMSK |= (USB_OTG_GINTMSK_PRTIM | USB_OTG_GINTMSK_HCIM | \
1552 USB_OTG_GINTMSK_SOFM | USB_OTG_GINTSTS_DISCINT | \
1553 USB_OTG_GINTMSK_PXFRM_IISOOXFRM | USB_OTG_GINTMSK_WUIM);
1554
1555 return ret;
1556}
1557
1568HAL_StatusTypeDef USB_InitFSLSPClkSel(const USB_OTG_GlobalTypeDef *USBx, uint8_t freq)
1569{
1570 uint32_t USBx_BASE = (uint32_t)USBx;
1571
1572 USBx_HOST->HCFG &= ~(USB_OTG_HCFG_FSLSPCS);
1573 USBx_HOST->HCFG |= (uint32_t)freq & USB_OTG_HCFG_FSLSPCS;
1574
1575 if (freq == HCFG_48_MHZ)
1576 {
1577 USBx_HOST->HFIR = HFIR_48_MHZ;
1578 }
1579 else if (freq == HCFG_6_MHZ)
1580 {
1581 USBx_HOST->HFIR = HFIR_6_MHZ;
1582 }
1583 else
1584 {
1585 return HAL_ERROR;
1586 }
1587
1588 return HAL_OK;
1589}
1590
1598HAL_StatusTypeDef USB_ResetPort(const USB_OTG_GlobalTypeDef *USBx)
1599{
1600 uint32_t USBx_BASE = (uint32_t)USBx;
1601
1602 __IO uint32_t hprt0 = 0U;
1603
1604 hprt0 = USBx_HPRT0;
1605
1606 hprt0 &= ~(USB_OTG_HPRT_PENA | USB_OTG_HPRT_PCDET |
1607 USB_OTG_HPRT_PENCHNG | USB_OTG_HPRT_POCCHNG);
1608
1609 USBx_HPRT0 = (USB_OTG_HPRT_PRST | hprt0);
1610 HAL_Delay(100U); /* See Note #1 */
1611 USBx_HPRT0 = ((~USB_OTG_HPRT_PRST) & hprt0);
1612 HAL_Delay(10U);
1613
1614 return HAL_OK;
1615}
1616
1625HAL_StatusTypeDef USB_DriveVbus(const USB_OTG_GlobalTypeDef *USBx, uint8_t state)
1626{
1627 uint32_t USBx_BASE = (uint32_t)USBx;
1628 __IO uint32_t hprt0 = 0U;
1629
1630 hprt0 = USBx_HPRT0;
1631
1632 hprt0 &= ~(USB_OTG_HPRT_PENA | USB_OTG_HPRT_PCDET |
1633 USB_OTG_HPRT_PENCHNG | USB_OTG_HPRT_POCCHNG);
1634
1635 if (((hprt0 & USB_OTG_HPRT_PPWR) == 0U) && (state == 1U))
1636 {
1637 USBx_HPRT0 = (USB_OTG_HPRT_PPWR | hprt0);
1638 }
1639 if (((hprt0 & USB_OTG_HPRT_PPWR) == USB_OTG_HPRT_PPWR) && (state == 0U))
1640 {
1641 USBx_HPRT0 = ((~USB_OTG_HPRT_PPWR) & hprt0);
1642 }
1643 return HAL_OK;
1644}
1645
1655uint32_t USB_GetHostSpeed(USB_OTG_GlobalTypeDef const *USBx)
1656{
1657 uint32_t USBx_BASE = (uint32_t)USBx;
1658 __IO uint32_t hprt0 = 0U;
1659
1660 hprt0 = USBx_HPRT0;
1661 return ((hprt0 & USB_OTG_HPRT_PSPD) >> 17);
1662}
1663
1669uint32_t USB_GetCurrentFrame(USB_OTG_GlobalTypeDef const *USBx)
1670{
1671 uint32_t USBx_BASE = (uint32_t)USBx;
1672
1673 return (USBx_HOST->HFNUM & USB_OTG_HFNUM_FRNUM);
1674}
1675
1700HAL_StatusTypeDef USB_HC_Init(USB_OTG_GlobalTypeDef *USBx, uint8_t ch_num,
1701 uint8_t epnum, uint8_t dev_address, uint8_t speed,
1702 uint8_t ep_type, uint16_t mps)
1703{
1705 uint32_t USBx_BASE = (uint32_t)USBx;
1706 uint32_t HCcharEpDir;
1707 uint32_t HCcharLowSpeed;
1708 uint32_t HostCoreSpeed;
1709
1710 /* Clear old interrupt conditions for this host channel. */
1711 USBx_HC((uint32_t)ch_num)->HCINT = CLEAR_INTERRUPT_MASK;
1712
1713 /* Enable channel interrupts required for this transfer. */
1714 switch (ep_type)
1715 {
1716 case EP_TYPE_CTRL:
1717 case EP_TYPE_BULK:
1718 USBx_HC((uint32_t)ch_num)->HCINTMSK = USB_OTG_HCINTMSK_XFRCM |
1719 USB_OTG_HCINTMSK_STALLM |
1720 USB_OTG_HCINTMSK_TXERRM |
1721 USB_OTG_HCINTMSK_DTERRM |
1722 USB_OTG_HCINTMSK_AHBERR |
1723 USB_OTG_HCINTMSK_NAKM;
1724
1725 if ((epnum & 0x80U) == 0x80U)
1726 {
1727 USBx_HC((uint32_t)ch_num)->HCINTMSK |= USB_OTG_HCINTMSK_BBERRM;
1728 }
1729 else
1730 {
1731#if defined (USB_OTG_HS)
1732 if (USBx == USB_OTG_HS)
1733 {
1734 USBx_HC((uint32_t)ch_num)->HCINTMSK |= USB_OTG_HCINTMSK_NYET |
1735 USB_OTG_HCINTMSK_ACKM;
1736 }
1737#endif /* defined (USB_OTG_HS) */
1738 }
1739 break;
1740
1741 case EP_TYPE_INTR:
1742 USBx_HC((uint32_t)ch_num)->HCINTMSK = USB_OTG_HCINTMSK_XFRCM |
1743 USB_OTG_HCINTMSK_STALLM |
1744 USB_OTG_HCINTMSK_TXERRM |
1745 USB_OTG_HCINTMSK_DTERRM |
1746 USB_OTG_HCINTMSK_NAKM |
1747 USB_OTG_HCINTMSK_AHBERR |
1748 USB_OTG_HCINTMSK_FRMORM;
1749
1750 if ((epnum & 0x80U) == 0x80U)
1751 {
1752 USBx_HC((uint32_t)ch_num)->HCINTMSK |= USB_OTG_HCINTMSK_BBERRM;
1753 }
1754
1755 break;
1756
1757 case EP_TYPE_ISOC:
1758 USBx_HC((uint32_t)ch_num)->HCINTMSK = USB_OTG_HCINTMSK_XFRCM |
1759 USB_OTG_HCINTMSK_ACKM |
1760 USB_OTG_HCINTMSK_AHBERR |
1761 USB_OTG_HCINTMSK_FRMORM;
1762
1763 if ((epnum & 0x80U) == 0x80U)
1764 {
1765 USBx_HC((uint32_t)ch_num)->HCINTMSK |= (USB_OTG_HCINTMSK_TXERRM | USB_OTG_HCINTMSK_BBERRM);
1766 }
1767 break;
1768
1769 default:
1770 ret = HAL_ERROR;
1771 break;
1772 }
1773
1774 /* Clear Hub Start Split transaction */
1775 USBx_HC((uint32_t)ch_num)->HCSPLT = 0U;
1776
1777 /* Enable host channel Halt interrupt */
1778 USBx_HC((uint32_t)ch_num)->HCINTMSK |= USB_OTG_HCINTMSK_CHHM;
1779
1780 /* Enable the top level host channel interrupt. */
1781 USBx_HOST->HAINTMSK |= 1UL << (ch_num & 0xFU);
1782
1783 /* Make sure host channel interrupts are enabled. */
1784 USBx->GINTMSK |= USB_OTG_GINTMSK_HCIM;
1785
1786 /* Program the HCCHAR register */
1787 if ((epnum & 0x80U) == 0x80U)
1788 {
1789 HCcharEpDir = (0x1U << 15) & USB_OTG_HCCHAR_EPDIR;
1790 }
1791 else
1792 {
1793 HCcharEpDir = 0U;
1794 }
1795
1796 HostCoreSpeed = USB_GetHostSpeed(USBx);
1797
1798 /* LS device plugged to HUB */
1799 if ((speed == HPRT0_PRTSPD_LOW_SPEED) && (HostCoreSpeed != HPRT0_PRTSPD_LOW_SPEED))
1800 {
1801 HCcharLowSpeed = (0x1U << 17) & USB_OTG_HCCHAR_LSDEV;
1802 }
1803 else
1804 {
1805 HCcharLowSpeed = 0U;
1806 }
1807
1808 USBx_HC((uint32_t)ch_num)->HCCHAR = (((uint32_t)dev_address << 22) & USB_OTG_HCCHAR_DAD) |
1809 ((((uint32_t)epnum & 0x7FU) << 11) & USB_OTG_HCCHAR_EPNUM) |
1810 (((uint32_t)ep_type << 18) & USB_OTG_HCCHAR_EPTYP) |
1811 ((uint32_t)mps & USB_OTG_HCCHAR_MPSIZ) |
1812 USB_OTG_HCCHAR_MC_0 | HCcharEpDir | HCcharLowSpeed;
1813
1814 if ((ep_type == EP_TYPE_INTR) || (ep_type == EP_TYPE_ISOC))
1815 {
1816 USBx_HC((uint32_t)ch_num)->HCCHAR |= USB_OTG_HCCHAR_ODDFRM;
1817 }
1818
1819 return ret;
1820}
1821
1832HAL_StatusTypeDef USB_HC_StartXfer(USB_OTG_GlobalTypeDef *USBx, USB_OTG_HCTypeDef *hc, uint8_t dma)
1833{
1834 uint32_t USBx_BASE = (uint32_t)USBx;
1835 uint32_t ch_num = (uint32_t)hc->ch_num;
1836 __IO uint32_t tmpreg;
1837 uint8_t is_oddframe;
1838 uint16_t len_words;
1839 uint16_t num_packets;
1840 uint16_t max_hc_pkt_count = HC_MAX_PKT_CNT;
1841
1842#if defined (USB_OTG_HS)
1843 if (USBx == USB_OTG_HS)
1844 {
1845 /* in DMA mode host Core automatically issues ping in case of NYET/NAK */
1846 if (dma == 1U)
1847 {
1848 if (((hc->ep_type == EP_TYPE_CTRL) || (hc->ep_type == EP_TYPE_BULK)) && (hc->do_ssplit == 0U))
1849 {
1850
1851 USBx_HC((uint32_t)ch_num)->HCINTMSK &= ~(USB_OTG_HCINTMSK_NYET |
1852 USB_OTG_HCINTMSK_ACKM |
1853 USB_OTG_HCINTMSK_NAKM);
1854 }
1855 }
1856 else
1857 {
1858 if ((hc->speed == USBH_HS_SPEED) && (hc->do_ping == 1U))
1859 {
1860 (void)USB_DoPing(USBx, hc->ch_num);
1861 return HAL_OK;
1862 }
1863 }
1864 }
1865#endif /* defined (USB_OTG_HS) */
1866
1867 if (hc->do_ssplit == 1U)
1868 {
1869 /* Set number of packet to 1 for Split transaction */
1870 num_packets = 1U;
1871
1872 if (hc->ep_is_in != 0U)
1873 {
1874 hc->XferSize = (uint32_t)num_packets * hc->max_packet;
1875 }
1876 else
1877 {
1878 if (hc->ep_type == EP_TYPE_ISOC)
1879 {
1880 if (hc->xfer_len > ISO_SPLT_MPS)
1881 {
1882 /* Isochrone Max Packet Size for Split mode */
1883 hc->XferSize = hc->max_packet;
1884 hc->xfer_len = hc->XferSize;
1885
1886 if ((hc->iso_splt_xactPos == HCSPLT_BEGIN) || (hc->iso_splt_xactPos == HCSPLT_MIDDLE))
1887 {
1888 hc->iso_splt_xactPos = HCSPLT_MIDDLE;
1889 }
1890 else
1891 {
1892 hc->iso_splt_xactPos = HCSPLT_BEGIN;
1893 }
1894 }
1895 else
1896 {
1897 hc->XferSize = hc->xfer_len;
1898
1899 if ((hc->iso_splt_xactPos != HCSPLT_BEGIN) && (hc->iso_splt_xactPos != HCSPLT_MIDDLE))
1900 {
1901 hc->iso_splt_xactPos = HCSPLT_FULL;
1902 }
1903 else
1904 {
1905 hc->iso_splt_xactPos = HCSPLT_END;
1906 }
1907 }
1908 }
1909 else
1910 {
1911 if ((dma == 1U) && (hc->xfer_len > hc->max_packet))
1912 {
1913 hc->XferSize = (uint32_t)num_packets * hc->max_packet;
1914 }
1915 else
1916 {
1917 hc->XferSize = hc->xfer_len;
1918 }
1919 }
1920 }
1921 }
1922 else
1923 {
1924 /* Compute the expected number of packets associated to the transfer */
1925 if (hc->xfer_len > 0U)
1926 {
1927 num_packets = (uint16_t)((hc->xfer_len + hc->max_packet - 1U) / hc->max_packet);
1928
1929 if (num_packets > max_hc_pkt_count)
1930 {
1931 num_packets = max_hc_pkt_count;
1932 hc->XferSize = (uint32_t)num_packets * hc->max_packet;
1933 }
1934 }
1935 else
1936 {
1937 num_packets = 1U;
1938 }
1939
1940 /*
1941 * For IN channel HCTSIZ.XferSize is expected to be an integer multiple of
1942 * max_packet size.
1943 */
1944 if (hc->ep_is_in != 0U)
1945 {
1946 hc->XferSize = (uint32_t)num_packets * hc->max_packet;
1947 }
1948 else
1949 {
1950 hc->XferSize = hc->xfer_len;
1951 }
1952 }
1953
1954 /* Initialize the HCTSIZn register */
1955 USBx_HC(ch_num)->HCTSIZ = (hc->XferSize & USB_OTG_HCTSIZ_XFRSIZ) |
1956 (((uint32_t)num_packets << 19) & USB_OTG_HCTSIZ_PKTCNT) |
1957 (((uint32_t)hc->data_pid << 29) & USB_OTG_HCTSIZ_DPID);
1958
1959 if (dma != 0U)
1960 {
1961 /* xfer_buff MUST be 32-bits aligned */
1962 USBx_HC(ch_num)->HCDMA = (uint32_t)hc->xfer_buff;
1963 }
1964
1965 is_oddframe = (((uint32_t)USBx_HOST->HFNUM & 0x01U) != 0U) ? 0U : 1U;
1966 USBx_HC(ch_num)->HCCHAR &= ~USB_OTG_HCCHAR_ODDFRM;
1967 USBx_HC(ch_num)->HCCHAR |= (uint32_t)is_oddframe << 29;
1968
1969 if (hc->do_ssplit == 1U)
1970 {
1971 /* Set Hub start Split transaction */
1972 USBx_HC((uint32_t)ch_num)->HCSPLT = ((uint32_t)hc->hub_addr << USB_OTG_HCSPLT_HUBADDR_Pos) |
1973 (uint32_t)hc->hub_port_nbr | USB_OTG_HCSPLT_SPLITEN;
1974
1975 /* unmask ack & nyet for IN/OUT transactions */
1976 USBx_HC((uint32_t)ch_num)->HCINTMSK |= (USB_OTG_HCINTMSK_ACKM |
1977 USB_OTG_HCINTMSK_NYET);
1978
1979 if ((hc->do_csplit == 1U) && (hc->ep_is_in == 0U))
1980 {
1981 USBx_HC((uint32_t)ch_num)->HCSPLT |= USB_OTG_HCSPLT_COMPLSPLT;
1982 USBx_HC((uint32_t)ch_num)->HCINTMSK |= USB_OTG_HCINTMSK_NYET;
1983 }
1984
1985 if (((hc->ep_type == EP_TYPE_ISOC) || (hc->ep_type == EP_TYPE_INTR)) &&
1986 (hc->do_csplit == 1U) && (hc->ep_is_in == 1U))
1987 {
1988 USBx_HC((uint32_t)ch_num)->HCSPLT |= USB_OTG_HCSPLT_COMPLSPLT;
1989 }
1990
1991 /* Position management for iso out transaction on split mode */
1992 if ((hc->ep_type == EP_TYPE_ISOC) && (hc->ep_is_in == 0U))
1993 {
1994 /* Set data payload position */
1995 switch (hc->iso_splt_xactPos)
1996 {
1997 case HCSPLT_BEGIN:
1998 /* First data payload for OUT Transaction */
1999 USBx_HC((uint32_t)ch_num)->HCSPLT |= USB_OTG_HCSPLT_XACTPOS_1;
2000 break;
2001
2002 case HCSPLT_MIDDLE:
2003 /* Middle data payload for OUT Transaction */
2004 USBx_HC((uint32_t)ch_num)->HCSPLT |= USB_OTG_HCSPLT_XACTPOS_Pos;
2005 break;
2006
2007 case HCSPLT_END:
2008 /* End data payload for OUT Transaction */
2009 USBx_HC((uint32_t)ch_num)->HCSPLT |= USB_OTG_HCSPLT_XACTPOS_0;
2010 break;
2011
2012 case HCSPLT_FULL:
2013 /* Entire data payload for OUT Transaction */
2014 USBx_HC((uint32_t)ch_num)->HCSPLT |= USB_OTG_HCSPLT_XACTPOS;
2015 break;
2016
2017 default:
2018 break;
2019 }
2020 }
2021 }
2022 else
2023 {
2024 /* Clear Hub Start Split transaction */
2025 USBx_HC((uint32_t)ch_num)->HCSPLT = 0U;
2026 }
2027
2028 /* Set host channel enable */
2029 tmpreg = USBx_HC(ch_num)->HCCHAR;
2030 tmpreg &= ~USB_OTG_HCCHAR_CHDIS;
2031
2032 /* make sure to set the correct ep direction */
2033 if (hc->ep_is_in != 0U)
2034 {
2035 tmpreg |= USB_OTG_HCCHAR_EPDIR;
2036 }
2037 else
2038 {
2039 tmpreg &= ~USB_OTG_HCCHAR_EPDIR;
2040 }
2041 tmpreg |= USB_OTG_HCCHAR_CHENA;
2042 USBx_HC(ch_num)->HCCHAR = tmpreg;
2043
2044 if (dma != 0U) /* dma mode */
2045 {
2046 return HAL_OK;
2047 }
2048
2049 if ((hc->ep_is_in == 0U) && (hc->xfer_len > 0U) && (hc->do_csplit == 0U))
2050 {
2051 switch (hc->ep_type)
2052 {
2053 /* Non periodic transfer */
2054 case EP_TYPE_CTRL:
2055 case EP_TYPE_BULK:
2056
2057 len_words = (uint16_t)((hc->xfer_len + 3U) / 4U);
2058
2059 /* check if there is enough space in FIFO space */
2060 if (len_words > (USBx->HNPTXSTS & 0xFFFFU))
2061 {
2062 /* need to process data in nptxfempty interrupt */
2063 USBx->GINTMSK |= USB_OTG_GINTMSK_NPTXFEM;
2064 }
2065 break;
2066
2067 /* Periodic transfer */
2068 case EP_TYPE_INTR:
2069 case EP_TYPE_ISOC:
2070 len_words = (uint16_t)((hc->xfer_len + 3U) / 4U);
2071 /* check if there is enough space in FIFO space */
2072 if (len_words > (USBx_HOST->HPTXSTS & 0xFFFFU)) /* split the transfer */
2073 {
2074 /* need to process data in ptxfempty interrupt */
2075 USBx->GINTMSK |= USB_OTG_GINTMSK_PTXFEM;
2076 }
2077 break;
2078
2079 default:
2080 break;
2081 }
2082
2083 /* Write packet into the Tx FIFO. */
2084 (void)USB_WritePacket(USBx, hc->xfer_buff, hc->ch_num, (uint16_t)hc->xfer_len, 0);
2085 }
2086
2087 return HAL_OK;
2088}
2089
2095uint32_t USB_HC_ReadInterrupt(const USB_OTG_GlobalTypeDef *USBx)
2096{
2097 uint32_t USBx_BASE = (uint32_t)USBx;
2098
2099 return ((USBx_HOST->HAINT) & 0xFFFFU);
2100}
2101
2109HAL_StatusTypeDef USB_HC_Halt(const USB_OTG_GlobalTypeDef *USBx, uint8_t hc_num)
2110{
2111 uint32_t USBx_BASE = (uint32_t)USBx;
2112 uint32_t hcnum = (uint32_t)hc_num;
2113 __IO uint32_t count = 0U;
2114 uint32_t HcEpType = (USBx_HC(hcnum)->HCCHAR & USB_OTG_HCCHAR_EPTYP) >> 18;
2115 uint32_t ChannelEna = (USBx_HC(hcnum)->HCCHAR & USB_OTG_HCCHAR_CHENA) >> 31;
2116 uint32_t SplitEna = (USBx_HC(hcnum)->HCSPLT & USB_OTG_HCSPLT_SPLITEN) >> 31;
2117
2118 /* In buffer DMA, Channel disable must not be programmed for non-split periodic channels.
2119 At the end of the next uframe/frame (in the worst case), the core generates a channel halted
2120 and disables the channel automatically. */
2121
2122 if ((((USBx->GAHBCFG & USB_OTG_GAHBCFG_DMAEN) == USB_OTG_GAHBCFG_DMAEN) && (SplitEna == 0U)) &&
2123 ((ChannelEna == 0U) || (((HcEpType == HCCHAR_ISOC) || (HcEpType == HCCHAR_INTR)))))
2124 {
2125 return HAL_OK;
2126 }
2127
2128 /* Check for space in the request queue to issue the halt. */
2129 if ((HcEpType == HCCHAR_CTRL) || (HcEpType == HCCHAR_BULK))
2130 {
2131 USBx_HC(hcnum)->HCCHAR |= USB_OTG_HCCHAR_CHDIS;
2132
2133 if ((USBx->GAHBCFG & USB_OTG_GAHBCFG_DMAEN) == 0U)
2134 {
2135 if ((USBx->HNPTXSTS & (0xFFU << 16)) == 0U)
2136 {
2137 USBx_HC(hcnum)->HCCHAR &= ~USB_OTG_HCCHAR_CHENA;
2138 USBx_HC(hcnum)->HCCHAR |= USB_OTG_HCCHAR_CHENA;
2139 do
2140 {
2141 count++;
2142
2143 if (count > 1000U)
2144 {
2145 break;
2146 }
2147 } while ((USBx_HC(hcnum)->HCCHAR & USB_OTG_HCCHAR_CHENA) == USB_OTG_HCCHAR_CHENA);
2148 }
2149 else
2150 {
2151 USBx_HC(hcnum)->HCCHAR |= USB_OTG_HCCHAR_CHENA;
2152 }
2153 }
2154 else
2155 {
2156 USBx_HC(hcnum)->HCCHAR |= USB_OTG_HCCHAR_CHENA;
2157 }
2158 }
2159 else
2160 {
2161 USBx_HC(hcnum)->HCCHAR |= USB_OTG_HCCHAR_CHDIS;
2162
2163 if ((USBx_HOST->HPTXSTS & (0xFFU << 16)) == 0U)
2164 {
2165 USBx_HC(hcnum)->HCCHAR &= ~USB_OTG_HCCHAR_CHENA;
2166 USBx_HC(hcnum)->HCCHAR |= USB_OTG_HCCHAR_CHENA;
2167 do
2168 {
2169 count++;
2170
2171 if (count > 1000U)
2172 {
2173 break;
2174 }
2175 } while ((USBx_HC(hcnum)->HCCHAR & USB_OTG_HCCHAR_CHENA) == USB_OTG_HCCHAR_CHENA);
2176 }
2177 else
2178 {
2179 USBx_HC(hcnum)->HCCHAR |= USB_OTG_HCCHAR_CHENA;
2180 }
2181 }
2182
2183 return HAL_OK;
2184}
2185
2193HAL_StatusTypeDef USB_DoPing(const USB_OTG_GlobalTypeDef *USBx, uint8_t ch_num)
2194{
2195 uint32_t USBx_BASE = (uint32_t)USBx;
2196 uint32_t chnum = (uint32_t)ch_num;
2197 uint32_t num_packets = 1U;
2198 uint32_t tmpreg;
2199
2200 USBx_HC(chnum)->HCTSIZ = ((num_packets << 19) & USB_OTG_HCTSIZ_PKTCNT) |
2201 USB_OTG_HCTSIZ_DOPING;
2202
2203 /* Set host channel enable */
2204 tmpreg = USBx_HC(chnum)->HCCHAR;
2205 tmpreg &= ~USB_OTG_HCCHAR_CHDIS;
2206 tmpreg |= USB_OTG_HCCHAR_CHENA;
2207 USBx_HC(chnum)->HCCHAR = tmpreg;
2208
2209 return HAL_OK;
2210}
2211
2217HAL_StatusTypeDef USB_StopHost(USB_OTG_GlobalTypeDef *USBx)
2218{
2220 uint32_t USBx_BASE = (uint32_t)USBx;
2221 __IO uint32_t count = 0U;
2222 uint32_t value;
2223 uint32_t i;
2224
2225 (void)USB_DisableGlobalInt(USBx);
2226
2227 /* Flush USB FIFO */
2228 if (USB_FlushTxFifo(USBx, 0x10U) != HAL_OK) /* all Tx FIFOs */
2229 {
2230 ret = HAL_ERROR;
2231 }
2232
2233 if (USB_FlushRxFifo(USBx) != HAL_OK)
2234 {
2235 ret = HAL_ERROR;
2236 }
2237
2238 /* Flush out any leftover queued requests. */
2239 for (i = 0U; i <= 15U; i++)
2240 {
2241 value = USBx_HC(i)->HCCHAR;
2242 value |= USB_OTG_HCCHAR_CHDIS;
2243 value &= ~USB_OTG_HCCHAR_CHENA;
2244 value &= ~USB_OTG_HCCHAR_EPDIR;
2245 USBx_HC(i)->HCCHAR = value;
2246 }
2247
2248 /* Halt all channels to put them into a known state. */
2249 for (i = 0U; i <= 15U; i++)
2250 {
2251 value = USBx_HC(i)->HCCHAR;
2252 value |= USB_OTG_HCCHAR_CHDIS;
2253 value |= USB_OTG_HCCHAR_CHENA;
2254 value &= ~USB_OTG_HCCHAR_EPDIR;
2255 USBx_HC(i)->HCCHAR = value;
2256
2257 do
2258 {
2259 count++;
2260
2261 if (count > 1000U)
2262 {
2263 break;
2264 }
2265 } while ((USBx_HC(i)->HCCHAR & USB_OTG_HCCHAR_CHENA) == USB_OTG_HCCHAR_CHENA);
2266 }
2267
2268 /* Clear any pending Host interrupts */
2269 USBx_HOST->HAINT = CLEAR_INTERRUPT_MASK;
2270 USBx->GINTSTS = CLEAR_INTERRUPT_MASK;
2271
2272 (void)USB_EnableGlobalInt(USBx);
2273
2274 return ret;
2275}
2276
2282HAL_StatusTypeDef USB_ActivateRemoteWakeup(const USB_OTG_GlobalTypeDef *USBx)
2283{
2284 uint32_t USBx_BASE = (uint32_t)USBx;
2285
2286 if ((USBx_DEVICE->DSTS & USB_OTG_DSTS_SUSPSTS) == USB_OTG_DSTS_SUSPSTS)
2287 {
2288 /* active Remote wakeup signalling */
2289 USBx_DEVICE->DCTL |= USB_OTG_DCTL_RWUSIG;
2290 }
2291
2292 return HAL_OK;
2293}
2294
2300HAL_StatusTypeDef USB_DeActivateRemoteWakeup(const USB_OTG_GlobalTypeDef *USBx)
2301{
2302 uint32_t USBx_BASE = (uint32_t)USBx;
2303
2304 /* active Remote wakeup signalling */
2305 USBx_DEVICE->DCTL &= ~(USB_OTG_DCTL_RWUSIG);
2306
2307 return HAL_OK;
2308}
2309#endif /* defined (USB_OTG_FS) || defined (USB_OTG_HS) */
2310
2314
2318#endif /* defined (USB_OTG_FS) || defined (USB_OTG_HS) */
2319#endif /* defined (HAL_PCD_MODULE_ENABLED) || defined (HAL_HCD_MODULE_ENABLED) */
2320
void HAL_Delay(uint32_t Delay)
This function provides minimum delay (in milliseconds) based on variable incremented.
This file contains all the functions prototypes for the HAL module driver.
HAL_StatusTypeDef
HAL Status structures definition.
@ HAL_TIMEOUT
@ HAL_ERROR
@ HAL_OK