1 /**
2 ******************************************************************************
3 * @file stm32l4xx_ll_usb.c
4 * @author MCD Application Team
5 * @brief USB Low Layer HAL module driver.
6 *
7 * This file provides firmware functions to manage the following
8 * functionalities of the USB Peripheral Controller:
9 * + Initialization/de-initialization functions
10 * + I/O operation functions
11 * + Peripheral Control functions
12 * + Peripheral State functions
13 *
14 ******************************************************************************
15 * @attention
16 *
17 * Copyright (c) 2017 STMicroelectronics.
18 * All rights reserved.
19 *
20 * This software is licensed under terms that can be found in the LICENSE file
21 * in the root directory of this software component.
22 * If no LICENSE file comes with this software, it is provided AS-IS.
23 *
24 ******************************************************************************
25 @verbatim
26 ==============================================================================
27 ##### How to use this driver #####
28 ==============================================================================
29 [..]
30 (#) Fill parameters of Init structure in USB_OTG_CfgTypeDef structure.
31
32 (#) Call USB_CoreInit() API to initialize the USB Core peripheral.
33
34 (#) The upper HAL HCD/PCD driver will call the right routines for its internal processes.
35
36 @endverbatim
37
38 ******************************************************************************
39 */
40
41 /* Includes ------------------------------------------------------------------*/
42 #include "stm32l4xx_hal.h"
43
44 /** @addtogroup STM32L4xx_LL_USB_DRIVER
45 * @{
46 */
47
48 #if defined (HAL_PCD_MODULE_ENABLED) || defined (HAL_HCD_MODULE_ENABLED)
49 #if defined (USB) || defined (USB_OTG_FS)
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)
57 static HAL_StatusTypeDef USB_CoreReset(USB_OTG_GlobalTypeDef *USBx);
58
59 /* Exported functions --------------------------------------------------------*/
60 /** @defgroup USB_LL_Exported_Functions USB Low Layer Exported Functions
61 * @{
62 */
63
64 /** @defgroup USB_LL_Exported_Functions_Group1 Initialization/de-initialization functions
65 * @brief Initialization and Configuration functions
66 *
67 @verbatim
68 ===============================================================================
69 ##### Initialization/de-initialization functions #####
70 ===============================================================================
71
72 @endverbatim
73 * @{
74 */
75
76 /**
77 * @brief Initializes the USB Core
78 * @param USBx USB Instance
79 * @param cfg pointer to a USB_OTG_CfgTypeDef structure that contains
80 * the configuration information for the specified USBx peripheral.
81 * @retval HAL status
82 */
USB_CoreInit(USB_OTG_GlobalTypeDef * USBx,USB_OTG_CfgTypeDef cfg)83 HAL_StatusTypeDef USB_CoreInit(USB_OTG_GlobalTypeDef *USBx, USB_OTG_CfgTypeDef cfg)
84 {
85 HAL_StatusTypeDef ret;
86
87 /* Select FS Embedded PHY */
88 USBx->GUSBCFG |= USB_OTG_GUSBCFG_PHYSEL;
89
90 /* Reset after a PHY select */
91 ret = USB_CoreReset(USBx);
92
93 if (cfg.battery_charging_enable == 0U)
94 {
95 /* Activate the USB Transceiver */
96 USBx->GCCFG |= USB_OTG_GCCFG_PWRDWN;
97 }
98 else
99 {
100 /* Deactivate the USB Transceiver */
101 USBx->GCCFG &= ~(USB_OTG_GCCFG_PWRDWN);
102 }
103
104 return ret;
105 }
106
107
108 /**
109 * @brief Set the USB turnaround time
110 * @param USBx USB Instance
111 * @param hclk: AHB clock frequency
112 * @retval USB turnaround time In PHY Clocks number
113 */
USB_SetTurnaroundTime(USB_OTG_GlobalTypeDef * USBx,uint32_t hclk,uint8_t speed)114 HAL_StatusTypeDef USB_SetTurnaroundTime(USB_OTG_GlobalTypeDef *USBx,
115 uint32_t hclk, uint8_t speed)
116 {
117 uint32_t UsbTrd;
118
119 /* The USBTRD is configured according to the tables below, depending on AHB frequency
120 used by application. In the low AHB frequency range it is used to stretch enough the USB response
121 time to IN tokens, the USB turnaround time, so to compensate for the longer AHB read access
122 latency to the Data FIFO */
123 if (speed == USBD_FS_SPEED)
124 {
125 if ((hclk >= 14200000U) && (hclk < 15000000U))
126 {
127 /* hclk Clock Range between 14.2-15 MHz */
128 UsbTrd = 0xFU;
129 }
130 else if ((hclk >= 15000000U) && (hclk < 16000000U))
131 {
132 /* hclk Clock Range between 15-16 MHz */
133 UsbTrd = 0xEU;
134 }
135 else if ((hclk >= 16000000U) && (hclk < 17200000U))
136 {
137 /* hclk Clock Range between 16-17.2 MHz */
138 UsbTrd = 0xDU;
139 }
140 else if ((hclk >= 17200000U) && (hclk < 18500000U))
141 {
142 /* hclk Clock Range between 17.2-18.5 MHz */
143 UsbTrd = 0xCU;
144 }
145 else if ((hclk >= 18500000U) && (hclk < 20000000U))
146 {
147 /* hclk Clock Range between 18.5-20 MHz */
148 UsbTrd = 0xBU;
149 }
150 else if ((hclk >= 20000000U) && (hclk < 21800000U))
151 {
152 /* hclk Clock Range between 20-21.8 MHz */
153 UsbTrd = 0xAU;
154 }
155 else if ((hclk >= 21800000U) && (hclk < 24000000U))
156 {
157 /* hclk Clock Range between 21.8-24 MHz */
158 UsbTrd = 0x9U;
159 }
160 else if ((hclk >= 24000000U) && (hclk < 27700000U))
161 {
162 /* hclk Clock Range between 24-27.7 MHz */
163 UsbTrd = 0x8U;
164 }
165 else if ((hclk >= 27700000U) && (hclk < 32000000U))
166 {
167 /* hclk Clock Range between 27.7-32 MHz */
168 UsbTrd = 0x7U;
169 }
170 else /* if(hclk >= 32000000) */
171 {
172 /* hclk Clock Range between 32-200 MHz */
173 UsbTrd = 0x6U;
174 }
175 }
176 else
177 {
178 UsbTrd = USBD_DEFAULT_TRDT_VALUE;
179 }
180
181 USBx->GUSBCFG &= ~USB_OTG_GUSBCFG_TRDT;
182 USBx->GUSBCFG |= (uint32_t)((UsbTrd << 10) & USB_OTG_GUSBCFG_TRDT);
183
184 return HAL_OK;
185 }
186
187 /**
188 * @brief USB_EnableGlobalInt
189 * Enables the controller's Global Int in the AHB Config reg
190 * @param USBx Selected device
191 * @retval HAL status
192 */
USB_EnableGlobalInt(USB_OTG_GlobalTypeDef * USBx)193 HAL_StatusTypeDef USB_EnableGlobalInt(USB_OTG_GlobalTypeDef *USBx)
194 {
195 USBx->GAHBCFG |= USB_OTG_GAHBCFG_GINT;
196 return HAL_OK;
197 }
198
199 /**
200 * @brief USB_DisableGlobalInt
201 * Disable the controller's Global Int in the AHB Config reg
202 * @param USBx Selected device
203 * @retval HAL status
204 */
USB_DisableGlobalInt(USB_OTG_GlobalTypeDef * USBx)205 HAL_StatusTypeDef USB_DisableGlobalInt(USB_OTG_GlobalTypeDef *USBx)
206 {
207 USBx->GAHBCFG &= ~USB_OTG_GAHBCFG_GINT;
208 return HAL_OK;
209 }
210
211 /**
212 * @brief USB_SetCurrentMode Set functional mode
213 * @param USBx Selected device
214 * @param mode current core mode
215 * This parameter can be one of these values:
216 * @arg USB_DEVICE_MODE Peripheral mode
217 * @arg USB_HOST_MODE Host mode
218 * @retval HAL status
219 */
USB_SetCurrentMode(USB_OTG_GlobalTypeDef * USBx,USB_ModeTypeDef mode)220 HAL_StatusTypeDef USB_SetCurrentMode(USB_OTG_GlobalTypeDef *USBx, USB_ModeTypeDef mode)
221 {
222 uint32_t ms = 0U;
223
224 USBx->GUSBCFG &= ~(USB_OTG_GUSBCFG_FHMOD | USB_OTG_GUSBCFG_FDMOD);
225
226 if (mode == USB_HOST_MODE)
227 {
228 USBx->GUSBCFG |= USB_OTG_GUSBCFG_FHMOD;
229
230 do
231 {
232 HAL_Delay(1U);
233 ms++;
234 } while ((USB_GetMode(USBx) != (uint32_t)USB_HOST_MODE) && (ms < 50U));
235 }
236 else if (mode == USB_DEVICE_MODE)
237 {
238 USBx->GUSBCFG |= USB_OTG_GUSBCFG_FDMOD;
239
240 do
241 {
242 HAL_Delay(1U);
243 ms++;
244 } while ((USB_GetMode(USBx) != (uint32_t)USB_DEVICE_MODE) && (ms < 50U));
245 }
246 else
247 {
248 return HAL_ERROR;
249 }
250
251 if (ms == 50U)
252 {
253 return HAL_ERROR;
254 }
255
256 return HAL_OK;
257 }
258
259 /**
260 * @brief USB_DevInit Initializes the USB_OTG controller registers
261 * for device mode
262 * @param USBx Selected device
263 * @param cfg pointer to a USB_OTG_CfgTypeDef structure that contains
264 * the configuration information for the specified USBx peripheral.
265 * @retval HAL status
266 */
USB_DevInit(USB_OTG_GlobalTypeDef * USBx,USB_OTG_CfgTypeDef cfg)267 HAL_StatusTypeDef USB_DevInit(USB_OTG_GlobalTypeDef *USBx, USB_OTG_CfgTypeDef cfg)
268 {
269 HAL_StatusTypeDef ret = HAL_OK;
270 uint32_t USBx_BASE = (uint32_t)USBx;
271 uint32_t i;
272
273 for (i = 0U; i < 15U; i++)
274 {
275 USBx->DIEPTXF[i] = 0U;
276 }
277
278 /* VBUS Sensing setup */
279 if (cfg.vbus_sensing_enable == 0U)
280 {
281 USBx_DEVICE->DCTL |= USB_OTG_DCTL_SDIS;
282
283 /* Deactivate VBUS Sensing B */
284 USBx->GCCFG &= ~USB_OTG_GCCFG_VBDEN;
285
286 /* B-peripheral session valid override enable */
287 USBx->GOTGCTL |= USB_OTG_GOTGCTL_BVALOEN;
288 USBx->GOTGCTL |= USB_OTG_GOTGCTL_BVALOVAL;
289 }
290 else
291 {
292 /* Enable HW VBUS sensing */
293 USBx->GCCFG |= USB_OTG_GCCFG_VBDEN;
294 }
295
296 /* Restart the Phy Clock */
297 USBx_PCGCCTL = 0U;
298
299 /* Device mode configuration */
300 USBx_DEVICE->DCFG |= DCFG_FRAME_INTERVAL_80;
301
302 /* Set Core speed to Full speed mode */
303 (void)USB_SetDevSpeed(USBx, USB_OTG_SPEED_FULL);
304
305 /* Flush the FIFOs */
306 if (USB_FlushTxFifo(USBx, 0x10U) != HAL_OK) /* all Tx FIFOs */
307 {
308 ret = HAL_ERROR;
309 }
310
311 if (USB_FlushRxFifo(USBx) != HAL_OK)
312 {
313 ret = HAL_ERROR;
314 }
315
316 /* Clear all pending Device Interrupts */
317 USBx_DEVICE->DIEPMSK = 0U;
318 USBx_DEVICE->DOEPMSK = 0U;
319 USBx_DEVICE->DAINTMSK = 0U;
320
321 for (i = 0U; i < cfg.dev_endpoints; i++)
322 {
323 if ((USBx_INEP(i)->DIEPCTL & USB_OTG_DIEPCTL_EPENA) == USB_OTG_DIEPCTL_EPENA)
324 {
325 if (i == 0U)
326 {
327 USBx_INEP(i)->DIEPCTL = USB_OTG_DIEPCTL_SNAK;
328 }
329 else
330 {
331 USBx_INEP(i)->DIEPCTL = USB_OTG_DIEPCTL_EPDIS | USB_OTG_DIEPCTL_SNAK;
332 }
333 }
334 else
335 {
336 USBx_INEP(i)->DIEPCTL = 0U;
337 }
338
339 USBx_INEP(i)->DIEPTSIZ = 0U;
340 USBx_INEP(i)->DIEPINT = 0xFB7FU;
341 }
342
343 for (i = 0U; i < cfg.dev_endpoints; i++)
344 {
345 if ((USBx_OUTEP(i)->DOEPCTL & USB_OTG_DOEPCTL_EPENA) == USB_OTG_DOEPCTL_EPENA)
346 {
347 if (i == 0U)
348 {
349 USBx_OUTEP(i)->DOEPCTL = USB_OTG_DOEPCTL_SNAK;
350 }
351 else
352 {
353 USBx_OUTEP(i)->DOEPCTL = USB_OTG_DOEPCTL_EPDIS | USB_OTG_DOEPCTL_SNAK;
354 }
355 }
356 else
357 {
358 USBx_OUTEP(i)->DOEPCTL = 0U;
359 }
360
361 USBx_OUTEP(i)->DOEPTSIZ = 0U;
362 USBx_OUTEP(i)->DOEPINT = 0xFB7FU;
363 }
364
365 USBx_DEVICE->DIEPMSK &= ~(USB_OTG_DIEPMSK_TXFURM);
366
367 /* Disable all interrupts. */
368 USBx->GINTMSK = 0U;
369
370 /* Clear any pending interrupts */
371 USBx->GINTSTS = 0xBFFFFFFFU;
372
373 /* Enable the common interrupts */
374 USBx->GINTMSK |= USB_OTG_GINTMSK_RXFLVLM;
375
376 /* Enable interrupts matching to the Device mode ONLY */
377 USBx->GINTMSK |= USB_OTG_GINTMSK_USBSUSPM | USB_OTG_GINTMSK_USBRST |
378 USB_OTG_GINTMSK_ENUMDNEM | USB_OTG_GINTMSK_IEPINT |
379 USB_OTG_GINTMSK_OEPINT | USB_OTG_GINTMSK_IISOIXFRM |
380 USB_OTG_GINTMSK_PXFRM_IISOOXFRM | USB_OTG_GINTMSK_WUIM;
381
382 if (cfg.Sof_enable != 0U)
383 {
384 USBx->GINTMSK |= USB_OTG_GINTMSK_SOFM;
385 }
386
387 if (cfg.vbus_sensing_enable == 1U)
388 {
389 USBx->GINTMSK |= (USB_OTG_GINTMSK_SRQIM | USB_OTG_GINTMSK_OTGINT);
390 }
391
392 return ret;
393 }
394
395 /**
396 * @brief USB_FlushTxFifo Flush a Tx FIFO
397 * @param USBx Selected device
398 * @param num FIFO number
399 * This parameter can be a value from 1 to 15
400 15 means Flush all Tx FIFOs
401 * @retval HAL status
402 */
USB_FlushTxFifo(USB_OTG_GlobalTypeDef * USBx,uint32_t num)403 HAL_StatusTypeDef USB_FlushTxFifo(USB_OTG_GlobalTypeDef *USBx, uint32_t num)
404 {
405 __IO uint32_t count = 0U;
406
407 /* Wait for AHB master IDLE state. */
408 do
409 {
410 count++;
411
412 if (count > 200000U)
413 {
414 return HAL_TIMEOUT;
415 }
416 } while ((USBx->GRSTCTL & USB_OTG_GRSTCTL_AHBIDL) == 0U);
417
418 /* Flush TX Fifo */
419 count = 0U;
420 USBx->GRSTCTL = (USB_OTG_GRSTCTL_TXFFLSH | (num << 6));
421
422 do
423 {
424 count++;
425
426 if (count > 200000U)
427 {
428 return HAL_TIMEOUT;
429 }
430 } while ((USBx->GRSTCTL & USB_OTG_GRSTCTL_TXFFLSH) == USB_OTG_GRSTCTL_TXFFLSH);
431
432 return HAL_OK;
433 }
434
435 /**
436 * @brief USB_FlushRxFifo Flush Rx FIFO
437 * @param USBx Selected device
438 * @retval HAL status
439 */
USB_FlushRxFifo(USB_OTG_GlobalTypeDef * USBx)440 HAL_StatusTypeDef USB_FlushRxFifo(USB_OTG_GlobalTypeDef *USBx)
441 {
442 __IO uint32_t count = 0U;
443
444 /* Wait for AHB master IDLE state. */
445 do
446 {
447 count++;
448
449 if (count > 200000U)
450 {
451 return HAL_TIMEOUT;
452 }
453 } while ((USBx->GRSTCTL & USB_OTG_GRSTCTL_AHBIDL) == 0U);
454
455 /* Flush RX Fifo */
456 count = 0U;
457 USBx->GRSTCTL = USB_OTG_GRSTCTL_RXFFLSH;
458
459 do
460 {
461 count++;
462
463 if (count > 200000U)
464 {
465 return HAL_TIMEOUT;
466 }
467 } while ((USBx->GRSTCTL & USB_OTG_GRSTCTL_RXFFLSH) == USB_OTG_GRSTCTL_RXFFLSH);
468
469 return HAL_OK;
470 }
471
472 /**
473 * @brief USB_SetDevSpeed Initializes the DevSpd field of DCFG register
474 * depending the PHY type and the enumeration speed of the device.
475 * @param USBx Selected device
476 * @param speed device speed
477 * This parameter can be one of these values:
478 * @arg USB_OTG_SPEED_FULL: Full speed mode
479 * @retval Hal status
480 */
USB_SetDevSpeed(USB_OTG_GlobalTypeDef * USBx,uint8_t speed)481 HAL_StatusTypeDef USB_SetDevSpeed(USB_OTG_GlobalTypeDef *USBx, uint8_t speed)
482 {
483 uint32_t USBx_BASE = (uint32_t)USBx;
484
485 USBx_DEVICE->DCFG |= speed;
486 return HAL_OK;
487 }
488
489 /**
490 * @brief USB_GetDevSpeed Return the Dev Speed
491 * @param USBx Selected device
492 * @retval speed device speed
493 * This parameter can be one of these values:
494 * @arg USBD_FS_SPEED: Full speed mode
495 */
USB_GetDevSpeed(USB_OTG_GlobalTypeDef * USBx)496 uint8_t USB_GetDevSpeed(USB_OTG_GlobalTypeDef *USBx)
497 {
498 uint32_t USBx_BASE = (uint32_t)USBx;
499 uint8_t speed;
500 uint32_t DevEnumSpeed = USBx_DEVICE->DSTS & USB_OTG_DSTS_ENUMSPD;
501
502 if ((DevEnumSpeed == DSTS_ENUMSPD_FS_PHY_30MHZ_OR_60MHZ) ||
503 (DevEnumSpeed == DSTS_ENUMSPD_FS_PHY_48MHZ))
504 {
505 speed = USBD_FS_SPEED;
506 }
507 else
508 {
509 speed = 0xFU;
510 }
511
512 return speed;
513 }
514
515 /**
516 * @brief Activate and configure an endpoint
517 * @param USBx Selected device
518 * @param ep pointer to endpoint structure
519 * @retval HAL status
520 */
USB_ActivateEndpoint(USB_OTG_GlobalTypeDef * USBx,USB_OTG_EPTypeDef * ep)521 HAL_StatusTypeDef USB_ActivateEndpoint(USB_OTG_GlobalTypeDef *USBx, USB_OTG_EPTypeDef *ep)
522 {
523 uint32_t USBx_BASE = (uint32_t)USBx;
524 uint32_t epnum = (uint32_t)ep->num;
525
526 if (ep->is_in == 1U)
527 {
528 USBx_DEVICE->DAINTMSK |= USB_OTG_DAINTMSK_IEPM & (uint32_t)(1UL << (ep->num & EP_ADDR_MSK));
529
530 if ((USBx_INEP(epnum)->DIEPCTL & USB_OTG_DIEPCTL_USBAEP) == 0U)
531 {
532 USBx_INEP(epnum)->DIEPCTL |= (ep->maxpacket & USB_OTG_DIEPCTL_MPSIZ) |
533 ((uint32_t)ep->type << 18) | (epnum << 22) |
534 USB_OTG_DIEPCTL_SD0PID_SEVNFRM |
535 USB_OTG_DIEPCTL_USBAEP;
536 }
537 }
538 else
539 {
540 USBx_DEVICE->DAINTMSK |= USB_OTG_DAINTMSK_OEPM & ((uint32_t)(1UL << (ep->num & EP_ADDR_MSK)) << 16);
541
542 if (((USBx_OUTEP(epnum)->DOEPCTL) & USB_OTG_DOEPCTL_USBAEP) == 0U)
543 {
544 USBx_OUTEP(epnum)->DOEPCTL |= (ep->maxpacket & USB_OTG_DOEPCTL_MPSIZ) |
545 ((uint32_t)ep->type << 18) |
546 USB_OTG_DIEPCTL_SD0PID_SEVNFRM |
547 USB_OTG_DOEPCTL_USBAEP;
548 }
549 }
550 return HAL_OK;
551 }
552
553 /**
554 * @brief Activate and configure a dedicated endpoint
555 * @param USBx Selected device
556 * @param ep pointer to endpoint structure
557 * @retval HAL status
558 */
USB_ActivateDedicatedEndpoint(USB_OTG_GlobalTypeDef * USBx,USB_OTG_EPTypeDef * ep)559 HAL_StatusTypeDef USB_ActivateDedicatedEndpoint(USB_OTG_GlobalTypeDef *USBx, USB_OTG_EPTypeDef *ep)
560 {
561 uint32_t USBx_BASE = (uint32_t)USBx;
562 uint32_t epnum = (uint32_t)ep->num;
563
564 /* Read DEPCTLn register */
565 if (ep->is_in == 1U)
566 {
567 if (((USBx_INEP(epnum)->DIEPCTL) & USB_OTG_DIEPCTL_USBAEP) == 0U)
568 {
569 USBx_INEP(epnum)->DIEPCTL |= (ep->maxpacket & USB_OTG_DIEPCTL_MPSIZ) |
570 ((uint32_t)ep->type << 18) | (epnum << 22) |
571 USB_OTG_DIEPCTL_SD0PID_SEVNFRM |
572 USB_OTG_DIEPCTL_USBAEP;
573 }
574
575 USBx_DEVICE->DEACHMSK |= USB_OTG_DAINTMSK_IEPM & (uint32_t)(1UL << (ep->num & EP_ADDR_MSK));
576 }
577 else
578 {
579 if (((USBx_OUTEP(epnum)->DOEPCTL) & USB_OTG_DOEPCTL_USBAEP) == 0U)
580 {
581 USBx_OUTEP(epnum)->DOEPCTL |= (ep->maxpacket & USB_OTG_DOEPCTL_MPSIZ) |
582 ((uint32_t)ep->type << 18) | (epnum << 22) |
583 USB_OTG_DOEPCTL_USBAEP;
584 }
585
586 USBx_DEVICE->DEACHMSK |= USB_OTG_DAINTMSK_OEPM & ((uint32_t)(1UL << (ep->num & EP_ADDR_MSK)) << 16);
587 }
588
589 return HAL_OK;
590 }
591
592 /**
593 * @brief De-activate and de-initialize an endpoint
594 * @param USBx Selected device
595 * @param ep pointer to endpoint structure
596 * @retval HAL status
597 */
USB_DeactivateEndpoint(USB_OTG_GlobalTypeDef * USBx,USB_OTG_EPTypeDef * ep)598 HAL_StatusTypeDef USB_DeactivateEndpoint(USB_OTG_GlobalTypeDef *USBx, USB_OTG_EPTypeDef *ep)
599 {
600 uint32_t USBx_BASE = (uint32_t)USBx;
601 uint32_t epnum = (uint32_t)ep->num;
602
603 /* Read DEPCTLn register */
604 if (ep->is_in == 1U)
605 {
606 if ((USBx_INEP(epnum)->DIEPCTL & USB_OTG_DIEPCTL_EPENA) == USB_OTG_DIEPCTL_EPENA)
607 {
608 USBx_INEP(epnum)->DIEPCTL |= USB_OTG_DIEPCTL_SNAK;
609 USBx_INEP(epnum)->DIEPCTL |= USB_OTG_DIEPCTL_EPDIS;
610 }
611
612 USBx_DEVICE->DEACHMSK &= ~(USB_OTG_DAINTMSK_IEPM & (uint32_t)(1UL << (ep->num & EP_ADDR_MSK)));
613 USBx_DEVICE->DAINTMSK &= ~(USB_OTG_DAINTMSK_IEPM & (uint32_t)(1UL << (ep->num & EP_ADDR_MSK)));
614 USBx_INEP(epnum)->DIEPCTL &= ~(USB_OTG_DIEPCTL_USBAEP |
615 USB_OTG_DIEPCTL_MPSIZ |
616 USB_OTG_DIEPCTL_TXFNUM |
617 USB_OTG_DIEPCTL_SD0PID_SEVNFRM |
618 USB_OTG_DIEPCTL_EPTYP);
619 }
620 else
621 {
622 if ((USBx_OUTEP(epnum)->DOEPCTL & USB_OTG_DOEPCTL_EPENA) == USB_OTG_DOEPCTL_EPENA)
623 {
624 USBx_OUTEP(epnum)->DOEPCTL |= USB_OTG_DOEPCTL_SNAK;
625 USBx_OUTEP(epnum)->DOEPCTL |= USB_OTG_DOEPCTL_EPDIS;
626 }
627
628 USBx_DEVICE->DEACHMSK &= ~(USB_OTG_DAINTMSK_OEPM & ((uint32_t)(1UL << (ep->num & EP_ADDR_MSK)) << 16));
629 USBx_DEVICE->DAINTMSK &= ~(USB_OTG_DAINTMSK_OEPM & ((uint32_t)(1UL << (ep->num & EP_ADDR_MSK)) << 16));
630 USBx_OUTEP(epnum)->DOEPCTL &= ~(USB_OTG_DOEPCTL_USBAEP |
631 USB_OTG_DOEPCTL_MPSIZ |
632 USB_OTG_DOEPCTL_SD0PID_SEVNFRM |
633 USB_OTG_DOEPCTL_EPTYP);
634 }
635
636 return HAL_OK;
637 }
638
639 /**
640 * @brief De-activate and de-initialize a dedicated endpoint
641 * @param USBx Selected device
642 * @param ep pointer to endpoint structure
643 * @retval HAL status
644 */
USB_DeactivateDedicatedEndpoint(USB_OTG_GlobalTypeDef * USBx,USB_OTG_EPTypeDef * ep)645 HAL_StatusTypeDef USB_DeactivateDedicatedEndpoint(USB_OTG_GlobalTypeDef *USBx, USB_OTG_EPTypeDef *ep)
646 {
647 uint32_t USBx_BASE = (uint32_t)USBx;
648 uint32_t epnum = (uint32_t)ep->num;
649
650 /* Read DEPCTLn register */
651 if (ep->is_in == 1U)
652 {
653 if ((USBx_INEP(epnum)->DIEPCTL & USB_OTG_DIEPCTL_EPENA) == USB_OTG_DIEPCTL_EPENA)
654 {
655 USBx_INEP(epnum)->DIEPCTL |= USB_OTG_DIEPCTL_SNAK;
656 USBx_INEP(epnum)->DIEPCTL |= USB_OTG_DIEPCTL_EPDIS;
657 }
658
659 USBx_INEP(epnum)->DIEPCTL &= ~ USB_OTG_DIEPCTL_USBAEP;
660 USBx_DEVICE->DAINTMSK &= ~(USB_OTG_DAINTMSK_IEPM & (uint32_t)(1UL << (ep->num & EP_ADDR_MSK)));
661 }
662 else
663 {
664 if ((USBx_OUTEP(epnum)->DOEPCTL & USB_OTG_DOEPCTL_EPENA) == USB_OTG_DOEPCTL_EPENA)
665 {
666 USBx_OUTEP(epnum)->DOEPCTL |= USB_OTG_DOEPCTL_SNAK;
667 USBx_OUTEP(epnum)->DOEPCTL |= USB_OTG_DOEPCTL_EPDIS;
668 }
669
670 USBx_OUTEP(epnum)->DOEPCTL &= ~USB_OTG_DOEPCTL_USBAEP;
671 USBx_DEVICE->DAINTMSK &= ~(USB_OTG_DAINTMSK_OEPM & ((uint32_t)(1UL << (ep->num & EP_ADDR_MSK)) << 16));
672 }
673
674 return HAL_OK;
675 }
676
677 /**
678 * @brief USB_EPStartXfer : setup and starts a transfer over an EP
679 * @param USBx Selected device
680 * @param ep pointer to endpoint structure
681 * @retval HAL status
682 */
USB_EPStartXfer(USB_OTG_GlobalTypeDef * USBx,USB_OTG_EPTypeDef * ep)683 HAL_StatusTypeDef USB_EPStartXfer(USB_OTG_GlobalTypeDef *USBx, USB_OTG_EPTypeDef *ep)
684 {
685 uint32_t USBx_BASE = (uint32_t)USBx;
686 uint32_t epnum = (uint32_t)ep->num;
687 uint16_t pktcnt;
688
689 /* IN endpoint */
690 if (ep->is_in == 1U)
691 {
692 /* Zero Length Packet? */
693 if (ep->xfer_len == 0U)
694 {
695 USBx_INEP(epnum)->DIEPTSIZ &= ~(USB_OTG_DIEPTSIZ_PKTCNT);
696 USBx_INEP(epnum)->DIEPTSIZ |= (USB_OTG_DIEPTSIZ_PKTCNT & (1U << 19));
697 USBx_INEP(epnum)->DIEPTSIZ &= ~(USB_OTG_DIEPTSIZ_XFRSIZ);
698 }
699 else
700 {
701 /* Program the transfer size and packet count
702 * as follows: xfersize = N * maxpacket +
703 * short_packet pktcnt = N + (short_packet
704 * exist ? 1 : 0)
705 */
706 USBx_INEP(epnum)->DIEPTSIZ &= ~(USB_OTG_DIEPTSIZ_XFRSIZ);
707 USBx_INEP(epnum)->DIEPTSIZ &= ~(USB_OTG_DIEPTSIZ_PKTCNT);
708 USBx_INEP(epnum)->DIEPTSIZ |= (USB_OTG_DIEPTSIZ_PKTCNT &
709 (((ep->xfer_len + ep->maxpacket - 1U) / ep->maxpacket) << 19));
710
711 USBx_INEP(epnum)->DIEPTSIZ |= (USB_OTG_DIEPTSIZ_XFRSIZ & ep->xfer_len);
712
713 if (ep->type == EP_TYPE_ISOC)
714 {
715 USBx_INEP(epnum)->DIEPTSIZ &= ~(USB_OTG_DIEPTSIZ_MULCNT);
716 USBx_INEP(epnum)->DIEPTSIZ |= (USB_OTG_DIEPTSIZ_MULCNT & (1U << 29));
717 }
718 }
719 /* EP enable, IN data in FIFO */
720 USBx_INEP(epnum)->DIEPCTL |= (USB_OTG_DIEPCTL_CNAK | USB_OTG_DIEPCTL_EPENA);
721
722 if (ep->type != EP_TYPE_ISOC)
723 {
724 /* Enable the Tx FIFO Empty Interrupt for this EP */
725 if (ep->xfer_len > 0U)
726 {
727 USBx_DEVICE->DIEPEMPMSK |= 1UL << (ep->num & EP_ADDR_MSK);
728 }
729 }
730 else
731 {
732 if ((USBx_DEVICE->DSTS & (1U << 8)) == 0U)
733 {
734 USBx_INEP(epnum)->DIEPCTL |= USB_OTG_DIEPCTL_SODDFRM;
735 }
736 else
737 {
738 USBx_INEP(epnum)->DIEPCTL |= USB_OTG_DIEPCTL_SD0PID_SEVNFRM;
739 }
740
741 (void)USB_WritePacket(USBx, ep->xfer_buff, ep->num, (uint16_t)ep->xfer_len);
742 }
743 }
744 else /* OUT endpoint */
745 {
746 /* Program the transfer size and packet count as follows:
747 * pktcnt = N
748 * xfersize = N * maxpacket
749 */
750 USBx_OUTEP(epnum)->DOEPTSIZ &= ~(USB_OTG_DOEPTSIZ_XFRSIZ);
751 USBx_OUTEP(epnum)->DOEPTSIZ &= ~(USB_OTG_DOEPTSIZ_PKTCNT);
752
753 if (ep->xfer_len == 0U)
754 {
755 USBx_OUTEP(epnum)->DOEPTSIZ |= (USB_OTG_DOEPTSIZ_XFRSIZ & ep->maxpacket);
756 USBx_OUTEP(epnum)->DOEPTSIZ |= (USB_OTG_DOEPTSIZ_PKTCNT & (1U << 19));
757 }
758 else
759 {
760 pktcnt = (uint16_t)((ep->xfer_len + ep->maxpacket - 1U) / ep->maxpacket);
761 ep->xfer_size = ep->maxpacket * pktcnt;
762
763 USBx_OUTEP(epnum)->DOEPTSIZ |= USB_OTG_DOEPTSIZ_PKTCNT & ((uint32_t)pktcnt << 19);
764 USBx_OUTEP(epnum)->DOEPTSIZ |= USB_OTG_DOEPTSIZ_XFRSIZ & ep->xfer_size;
765 }
766
767 if (ep->type == EP_TYPE_ISOC)
768 {
769 if ((USBx_DEVICE->DSTS & (1U << 8)) == 0U)
770 {
771 USBx_OUTEP(epnum)->DOEPCTL |= USB_OTG_DOEPCTL_SODDFRM;
772 }
773 else
774 {
775 USBx_OUTEP(epnum)->DOEPCTL |= USB_OTG_DOEPCTL_SD0PID_SEVNFRM;
776 }
777 }
778 /* EP enable */
779 USBx_OUTEP(epnum)->DOEPCTL |= (USB_OTG_DOEPCTL_CNAK | USB_OTG_DOEPCTL_EPENA);
780 }
781
782 return HAL_OK;
783 }
784
785 /**
786 * @brief USB_EP0StartXfer : setup and starts a transfer over the EP 0
787 * @param USBx Selected device
788 * @param ep pointer to endpoint structure
789 * @retval HAL status
790 */
USB_EP0StartXfer(USB_OTG_GlobalTypeDef * USBx,USB_OTG_EPTypeDef * ep)791 HAL_StatusTypeDef USB_EP0StartXfer(USB_OTG_GlobalTypeDef *USBx, USB_OTG_EPTypeDef *ep)
792 {
793 uint32_t USBx_BASE = (uint32_t)USBx;
794 uint32_t epnum = (uint32_t)ep->num;
795
796 /* IN endpoint */
797 if (ep->is_in == 1U)
798 {
799 /* Zero Length Packet? */
800 if (ep->xfer_len == 0U)
801 {
802 USBx_INEP(epnum)->DIEPTSIZ &= ~(USB_OTG_DIEPTSIZ_PKTCNT);
803 USBx_INEP(epnum)->DIEPTSIZ |= (USB_OTG_DIEPTSIZ_PKTCNT & (1U << 19));
804 USBx_INEP(epnum)->DIEPTSIZ &= ~(USB_OTG_DIEPTSIZ_XFRSIZ);
805 }
806 else
807 {
808 /* Program the transfer size and packet count
809 * as follows: xfersize = N * maxpacket +
810 * short_packet pktcnt = N + (short_packet
811 * exist ? 1 : 0)
812 */
813 USBx_INEP(epnum)->DIEPTSIZ &= ~(USB_OTG_DIEPTSIZ_XFRSIZ);
814 USBx_INEP(epnum)->DIEPTSIZ &= ~(USB_OTG_DIEPTSIZ_PKTCNT);
815
816 if (ep->xfer_len > ep->maxpacket)
817 {
818 ep->xfer_len = ep->maxpacket;
819 }
820 USBx_INEP(epnum)->DIEPTSIZ |= (USB_OTG_DIEPTSIZ_PKTCNT & (1U << 19));
821 USBx_INEP(epnum)->DIEPTSIZ |= (USB_OTG_DIEPTSIZ_XFRSIZ & ep->xfer_len);
822 }
823
824 /* EP enable, IN data in FIFO */
825 USBx_INEP(epnum)->DIEPCTL |= (USB_OTG_DIEPCTL_CNAK | USB_OTG_DIEPCTL_EPENA);
826
827 /* Enable the Tx FIFO Empty Interrupt for this EP */
828 if (ep->xfer_len > 0U)
829 {
830 USBx_DEVICE->DIEPEMPMSK |= 1UL << (ep->num & EP_ADDR_MSK);
831 }
832 }
833 else /* OUT endpoint */
834 {
835 /* Program the transfer size and packet count as follows:
836 * pktcnt = N
837 * xfersize = N * maxpacket
838 */
839 USBx_OUTEP(epnum)->DOEPTSIZ &= ~(USB_OTG_DOEPTSIZ_XFRSIZ);
840 USBx_OUTEP(epnum)->DOEPTSIZ &= ~(USB_OTG_DOEPTSIZ_PKTCNT);
841
842 if (ep->xfer_len > 0U)
843 {
844 ep->xfer_len = ep->maxpacket;
845 }
846
847 /* Store transfer size, for EP0 this is equal to endpoint max packet size */
848 ep->xfer_size = ep->maxpacket;
849
850 USBx_OUTEP(epnum)->DOEPTSIZ |= (USB_OTG_DOEPTSIZ_PKTCNT & (1U << 19));
851 USBx_OUTEP(epnum)->DOEPTSIZ |= (USB_OTG_DOEPTSIZ_XFRSIZ & ep->xfer_size);
852
853 /* EP enable */
854 USBx_OUTEP(epnum)->DOEPCTL |= (USB_OTG_DOEPCTL_CNAK | USB_OTG_DOEPCTL_EPENA);
855 }
856
857 return HAL_OK;
858 }
859
860
861 /**
862 * @brief USB_EPStoptXfer Stop transfer on an EP
863 * @param USBx usb device instance
864 * @param ep pointer to endpoint structure
865 * @retval HAL status
866 */
USB_EPStopXfer(USB_OTG_GlobalTypeDef * USBx,USB_OTG_EPTypeDef * ep)867 HAL_StatusTypeDef USB_EPStopXfer(USB_OTG_GlobalTypeDef *USBx, USB_OTG_EPTypeDef *ep)
868 {
869 __IO uint32_t count = 0U;
870 HAL_StatusTypeDef ret = HAL_OK;
871 uint32_t USBx_BASE = (uint32_t)USBx;
872
873 /* IN endpoint */
874 if (ep->is_in == 1U)
875 {
876 /* EP enable, IN data in FIFO */
877 if (((USBx_INEP(ep->num)->DIEPCTL) & USB_OTG_DIEPCTL_EPENA) == USB_OTG_DIEPCTL_EPENA)
878 {
879 USBx_INEP(ep->num)->DIEPCTL |= (USB_OTG_DIEPCTL_SNAK);
880 USBx_INEP(ep->num)->DIEPCTL |= (USB_OTG_DIEPCTL_EPDIS);
881
882 do
883 {
884 count++;
885
886 if (count > 10000U)
887 {
888 ret = HAL_ERROR;
889 break;
890 }
891 } while (((USBx_INEP(ep->num)->DIEPCTL) & USB_OTG_DIEPCTL_EPENA) == USB_OTG_DIEPCTL_EPENA);
892 }
893 }
894 else /* OUT endpoint */
895 {
896 if (((USBx_OUTEP(ep->num)->DOEPCTL) & USB_OTG_DOEPCTL_EPENA) == USB_OTG_DOEPCTL_EPENA)
897 {
898 USBx_OUTEP(ep->num)->DOEPCTL |= (USB_OTG_DOEPCTL_SNAK);
899 USBx_OUTEP(ep->num)->DOEPCTL |= (USB_OTG_DOEPCTL_EPDIS);
900
901 do
902 {
903 count++;
904
905 if (count > 10000U)
906 {
907 ret = HAL_ERROR;
908 break;
909 }
910 } while (((USBx_OUTEP(ep->num)->DOEPCTL) & USB_OTG_DOEPCTL_EPENA) == USB_OTG_DOEPCTL_EPENA);
911 }
912 }
913
914 return ret;
915 }
916
917
918 /**
919 * @brief USB_WritePacket : Writes a packet into the Tx FIFO associated
920 * with the EP/channel
921 * @param USBx Selected device
922 * @param src pointer to source buffer
923 * @param ch_ep_num endpoint or host channel number
924 * @param len Number of bytes to write
925 * @retval HAL status
926 */
USB_WritePacket(USB_OTG_GlobalTypeDef * USBx,uint8_t * src,uint8_t ch_ep_num,uint16_t len)927 HAL_StatusTypeDef USB_WritePacket(USB_OTG_GlobalTypeDef *USBx, uint8_t *src,
928 uint8_t ch_ep_num, uint16_t len)
929 {
930 uint32_t USBx_BASE = (uint32_t)USBx;
931 uint8_t *pSrc = src;
932 uint32_t count32b;
933 uint32_t i;
934
935 count32b = ((uint32_t)len + 3U) / 4U;
936 for (i = 0U; i < count32b; i++)
937 {
938 USBx_DFIFO((uint32_t)ch_ep_num) = __UNALIGNED_UINT32_READ(pSrc);
939 pSrc++;
940 pSrc++;
941 pSrc++;
942 pSrc++;
943 }
944
945 return HAL_OK;
946 }
947
948 /**
949 * @brief USB_ReadPacket : read a packet from the RX FIFO
950 * @param USBx Selected device
951 * @param dest source pointer
952 * @param len Number of bytes to read
953 * @retval pointer to destination buffer
954 */
USB_ReadPacket(USB_OTG_GlobalTypeDef * USBx,uint8_t * dest,uint16_t len)955 void *USB_ReadPacket(USB_OTG_GlobalTypeDef *USBx, uint8_t *dest, uint16_t len)
956 {
957 uint32_t USBx_BASE = (uint32_t)USBx;
958 uint8_t *pDest = dest;
959 uint32_t pData;
960 uint32_t i;
961 uint32_t count32b = (uint32_t)len >> 2U;
962 uint16_t remaining_bytes = len % 4U;
963
964 for (i = 0U; i < count32b; i++)
965 {
966 __UNALIGNED_UINT32_WRITE(pDest, USBx_DFIFO(0U));
967 pDest++;
968 pDest++;
969 pDest++;
970 pDest++;
971 }
972
973 /* When Number of data is not word aligned, read the remaining byte */
974 if (remaining_bytes != 0U)
975 {
976 i = 0U;
977 __UNALIGNED_UINT32_WRITE(&pData, USBx_DFIFO(0U));
978
979 do
980 {
981 *(uint8_t *)pDest = (uint8_t)(pData >> (8U * (uint8_t)(i)));
982 i++;
983 pDest++;
984 remaining_bytes--;
985 } while (remaining_bytes != 0U);
986 }
987
988 return ((void *)pDest);
989 }
990
991 /**
992 * @brief USB_EPSetStall : set a stall condition over an EP
993 * @param USBx Selected device
994 * @param ep pointer to endpoint structure
995 * @retval HAL status
996 */
USB_EPSetStall(USB_OTG_GlobalTypeDef * USBx,USB_OTG_EPTypeDef * ep)997 HAL_StatusTypeDef USB_EPSetStall(USB_OTG_GlobalTypeDef *USBx, USB_OTG_EPTypeDef *ep)
998 {
999 uint32_t USBx_BASE = (uint32_t)USBx;
1000 uint32_t epnum = (uint32_t)ep->num;
1001
1002 if (ep->is_in == 1U)
1003 {
1004 if (((USBx_INEP(epnum)->DIEPCTL & USB_OTG_DIEPCTL_EPENA) == 0U) && (epnum != 0U))
1005 {
1006 USBx_INEP(epnum)->DIEPCTL &= ~(USB_OTG_DIEPCTL_EPDIS);
1007 }
1008 USBx_INEP(epnum)->DIEPCTL |= USB_OTG_DIEPCTL_STALL;
1009 }
1010 else
1011 {
1012 if (((USBx_OUTEP(epnum)->DOEPCTL & USB_OTG_DOEPCTL_EPENA) == 0U) && (epnum != 0U))
1013 {
1014 USBx_OUTEP(epnum)->DOEPCTL &= ~(USB_OTG_DOEPCTL_EPDIS);
1015 }
1016 USBx_OUTEP(epnum)->DOEPCTL |= USB_OTG_DOEPCTL_STALL;
1017 }
1018
1019 return HAL_OK;
1020 }
1021
1022 /**
1023 * @brief USB_EPClearStall : Clear a stall condition over an EP
1024 * @param USBx Selected device
1025 * @param ep pointer to endpoint structure
1026 * @retval HAL status
1027 */
USB_EPClearStall(USB_OTG_GlobalTypeDef * USBx,USB_OTG_EPTypeDef * ep)1028 HAL_StatusTypeDef USB_EPClearStall(USB_OTG_GlobalTypeDef *USBx, USB_OTG_EPTypeDef *ep)
1029 {
1030 uint32_t USBx_BASE = (uint32_t)USBx;
1031 uint32_t epnum = (uint32_t)ep->num;
1032
1033 if (ep->is_in == 1U)
1034 {
1035 USBx_INEP(epnum)->DIEPCTL &= ~USB_OTG_DIEPCTL_STALL;
1036 if ((ep->type == EP_TYPE_INTR) || (ep->type == EP_TYPE_BULK))
1037 {
1038 USBx_INEP(epnum)->DIEPCTL |= USB_OTG_DIEPCTL_SD0PID_SEVNFRM; /* DATA0 */
1039 }
1040 }
1041 else
1042 {
1043 USBx_OUTEP(epnum)->DOEPCTL &= ~USB_OTG_DOEPCTL_STALL;
1044 if ((ep->type == EP_TYPE_INTR) || (ep->type == EP_TYPE_BULK))
1045 {
1046 USBx_OUTEP(epnum)->DOEPCTL |= USB_OTG_DOEPCTL_SD0PID_SEVNFRM; /* DATA0 */
1047 }
1048 }
1049 return HAL_OK;
1050 }
1051
1052 /**
1053 * @brief USB_StopDevice : Stop the usb device mode
1054 * @param USBx Selected device
1055 * @retval HAL status
1056 */
USB_StopDevice(USB_OTG_GlobalTypeDef * USBx)1057 HAL_StatusTypeDef USB_StopDevice(USB_OTG_GlobalTypeDef *USBx)
1058 {
1059 HAL_StatusTypeDef ret;
1060 uint32_t USBx_BASE = (uint32_t)USBx;
1061 uint32_t i;
1062
1063 /* Clear Pending interrupt */
1064 for (i = 0U; i < 15U; i++)
1065 {
1066 USBx_INEP(i)->DIEPINT = 0xFB7FU;
1067 USBx_OUTEP(i)->DOEPINT = 0xFB7FU;
1068 }
1069
1070 /* Clear interrupt masks */
1071 USBx_DEVICE->DIEPMSK = 0U;
1072 USBx_DEVICE->DOEPMSK = 0U;
1073 USBx_DEVICE->DAINTMSK = 0U;
1074
1075 /* Flush the FIFO */
1076 ret = USB_FlushRxFifo(USBx);
1077 if (ret != HAL_OK)
1078 {
1079 return ret;
1080 }
1081
1082 ret = USB_FlushTxFifo(USBx, 0x10U);
1083 if (ret != HAL_OK)
1084 {
1085 return ret;
1086 }
1087
1088 return ret;
1089 }
1090
1091 /**
1092 * @brief USB_SetDevAddress : Stop the usb device mode
1093 * @param USBx Selected device
1094 * @param address new device address to be assigned
1095 * This parameter can be a value from 0 to 255
1096 * @retval HAL status
1097 */
USB_SetDevAddress(USB_OTG_GlobalTypeDef * USBx,uint8_t address)1098 HAL_StatusTypeDef USB_SetDevAddress(USB_OTG_GlobalTypeDef *USBx, uint8_t address)
1099 {
1100 uint32_t USBx_BASE = (uint32_t)USBx;
1101
1102 USBx_DEVICE->DCFG &= ~(USB_OTG_DCFG_DAD);
1103 USBx_DEVICE->DCFG |= ((uint32_t)address << 4) & USB_OTG_DCFG_DAD;
1104
1105 return HAL_OK;
1106 }
1107
1108 /**
1109 * @brief USB_DevConnect : Connect the USB device by enabling Rpu
1110 * @param USBx Selected device
1111 * @retval HAL status
1112 */
USB_DevConnect(USB_OTG_GlobalTypeDef * USBx)1113 HAL_StatusTypeDef USB_DevConnect(USB_OTG_GlobalTypeDef *USBx)
1114 {
1115 uint32_t USBx_BASE = (uint32_t)USBx;
1116
1117 /* In case phy is stopped, ensure to ungate and restore the phy CLK */
1118 USBx_PCGCCTL &= ~(USB_OTG_PCGCCTL_STOPCLK | USB_OTG_PCGCCTL_GATECLK);
1119
1120 USBx_DEVICE->DCTL &= ~USB_OTG_DCTL_SDIS;
1121
1122 return HAL_OK;
1123 }
1124
1125 /**
1126 * @brief USB_DevDisconnect : Disconnect the USB device by disabling Rpu
1127 * @param USBx Selected device
1128 * @retval HAL status
1129 */
USB_DevDisconnect(USB_OTG_GlobalTypeDef * USBx)1130 HAL_StatusTypeDef USB_DevDisconnect(USB_OTG_GlobalTypeDef *USBx)
1131 {
1132 uint32_t USBx_BASE = (uint32_t)USBx;
1133
1134 /* In case phy is stopped, ensure to ungate and restore the phy CLK */
1135 USBx_PCGCCTL &= ~(USB_OTG_PCGCCTL_STOPCLK | USB_OTG_PCGCCTL_GATECLK);
1136
1137 USBx_DEVICE->DCTL |= USB_OTG_DCTL_SDIS;
1138
1139 return HAL_OK;
1140 }
1141
1142 /**
1143 * @brief USB_ReadInterrupts: return the global USB interrupt status
1144 * @param USBx Selected device
1145 * @retval HAL status
1146 */
USB_ReadInterrupts(USB_OTG_GlobalTypeDef * USBx)1147 uint32_t USB_ReadInterrupts(USB_OTG_GlobalTypeDef *USBx)
1148 {
1149 uint32_t tmpreg;
1150
1151 tmpreg = USBx->GINTSTS;
1152 tmpreg &= USBx->GINTMSK;
1153
1154 return tmpreg;
1155 }
1156
1157 /**
1158 * @brief USB_ReadDevAllOutEpInterrupt: return the USB device OUT endpoints interrupt status
1159 * @param USBx Selected device
1160 * @retval HAL status
1161 */
USB_ReadDevAllOutEpInterrupt(USB_OTG_GlobalTypeDef * USBx)1162 uint32_t USB_ReadDevAllOutEpInterrupt(USB_OTG_GlobalTypeDef *USBx)
1163 {
1164 uint32_t USBx_BASE = (uint32_t)USBx;
1165 uint32_t tmpreg;
1166
1167 tmpreg = USBx_DEVICE->DAINT;
1168 tmpreg &= USBx_DEVICE->DAINTMSK;
1169
1170 return ((tmpreg & 0xffff0000U) >> 16);
1171 }
1172
1173 /**
1174 * @brief USB_ReadDevAllInEpInterrupt: return the USB device IN endpoints interrupt status
1175 * @param USBx Selected device
1176 * @retval HAL status
1177 */
USB_ReadDevAllInEpInterrupt(USB_OTG_GlobalTypeDef * USBx)1178 uint32_t USB_ReadDevAllInEpInterrupt(USB_OTG_GlobalTypeDef *USBx)
1179 {
1180 uint32_t USBx_BASE = (uint32_t)USBx;
1181 uint32_t tmpreg;
1182
1183 tmpreg = USBx_DEVICE->DAINT;
1184 tmpreg &= USBx_DEVICE->DAINTMSK;
1185
1186 return ((tmpreg & 0xFFFFU));
1187 }
1188
1189 /**
1190 * @brief Returns Device OUT EP Interrupt register
1191 * @param USBx Selected device
1192 * @param epnum endpoint number
1193 * This parameter can be a value from 0 to 15
1194 * @retval Device OUT EP Interrupt register
1195 */
USB_ReadDevOutEPInterrupt(USB_OTG_GlobalTypeDef * USBx,uint8_t epnum)1196 uint32_t USB_ReadDevOutEPInterrupt(USB_OTG_GlobalTypeDef *USBx, uint8_t epnum)
1197 {
1198 uint32_t USBx_BASE = (uint32_t)USBx;
1199 uint32_t tmpreg;
1200
1201 tmpreg = USBx_OUTEP((uint32_t)epnum)->DOEPINT;
1202 tmpreg &= USBx_DEVICE->DOEPMSK;
1203
1204 return tmpreg;
1205 }
1206
1207 /**
1208 * @brief Returns Device IN EP Interrupt register
1209 * @param USBx Selected device
1210 * @param epnum endpoint number
1211 * This parameter can be a value from 0 to 15
1212 * @retval Device IN EP Interrupt register
1213 */
USB_ReadDevInEPInterrupt(USB_OTG_GlobalTypeDef * USBx,uint8_t epnum)1214 uint32_t USB_ReadDevInEPInterrupt(USB_OTG_GlobalTypeDef *USBx, uint8_t epnum)
1215 {
1216 uint32_t USBx_BASE = (uint32_t)USBx;
1217 uint32_t tmpreg;
1218 uint32_t msk;
1219 uint32_t emp;
1220
1221 msk = USBx_DEVICE->DIEPMSK;
1222 emp = USBx_DEVICE->DIEPEMPMSK;
1223 msk |= ((emp >> (epnum & EP_ADDR_MSK)) & 0x1U) << 7;
1224 tmpreg = USBx_INEP((uint32_t)epnum)->DIEPINT & msk;
1225
1226 return tmpreg;
1227 }
1228
1229 /**
1230 * @brief USB_ClearInterrupts: clear a USB interrupt
1231 * @param USBx Selected device
1232 * @param interrupt flag
1233 * @retval None
1234 */
USB_ClearInterrupts(USB_OTG_GlobalTypeDef * USBx,uint32_t interrupt)1235 void USB_ClearInterrupts(USB_OTG_GlobalTypeDef *USBx, uint32_t interrupt)
1236 {
1237 USBx->GINTSTS |= interrupt;
1238 }
1239
1240 /**
1241 * @brief Returns USB core mode
1242 * @param USBx Selected device
1243 * @retval return core mode : Host or Device
1244 * This parameter can be one of these values:
1245 * 0 : Host
1246 * 1 : Device
1247 */
USB_GetMode(USB_OTG_GlobalTypeDef * USBx)1248 uint32_t USB_GetMode(USB_OTG_GlobalTypeDef *USBx)
1249 {
1250 return ((USBx->GINTSTS) & 0x1U);
1251 }
1252
1253 /**
1254 * @brief Activate EP0 for Setup transactions
1255 * @param USBx Selected device
1256 * @retval HAL status
1257 */
USB_ActivateSetup(USB_OTG_GlobalTypeDef * USBx)1258 HAL_StatusTypeDef USB_ActivateSetup(USB_OTG_GlobalTypeDef *USBx)
1259 {
1260 uint32_t USBx_BASE = (uint32_t)USBx;
1261
1262 /* Set the MPS of the IN EP0 to 64 bytes */
1263 USBx_INEP(0U)->DIEPCTL &= ~USB_OTG_DIEPCTL_MPSIZ;
1264
1265 USBx_DEVICE->DCTL |= USB_OTG_DCTL_CGINAK;
1266
1267 return HAL_OK;
1268 }
1269
1270 /**
1271 * @brief Prepare the EP0 to start the first control setup
1272 * @param USBx Selected device
1273 * @param psetup pointer to setup packet
1274 * @retval HAL status
1275 */
USB_EP0_OutStart(USB_OTG_GlobalTypeDef * USBx,uint8_t * psetup)1276 HAL_StatusTypeDef USB_EP0_OutStart(USB_OTG_GlobalTypeDef *USBx, uint8_t *psetup)
1277 {
1278 uint32_t USBx_BASE = (uint32_t)USBx;
1279 uint32_t gSNPSiD = *(__IO uint32_t *)(&USBx->CID + 0x1U);
1280 UNUSED(psetup);
1281
1282 if (gSNPSiD > USB_OTG_CORE_ID_300A)
1283 {
1284 if ((USBx_OUTEP(0U)->DOEPCTL & USB_OTG_DOEPCTL_EPENA) == USB_OTG_DOEPCTL_EPENA)
1285 {
1286 return HAL_OK;
1287 }
1288 }
1289
1290 USBx_OUTEP(0U)->DOEPTSIZ = 0U;
1291 USBx_OUTEP(0U)->DOEPTSIZ |= (USB_OTG_DOEPTSIZ_PKTCNT & (1U << 19));
1292 USBx_OUTEP(0U)->DOEPTSIZ |= (3U * 8U);
1293 USBx_OUTEP(0U)->DOEPTSIZ |= USB_OTG_DOEPTSIZ_STUPCNT;
1294
1295 return HAL_OK;
1296 }
1297
1298 /**
1299 * @brief Reset the USB Core (needed after USB clock settings change)
1300 * @param USBx Selected device
1301 * @retval HAL status
1302 */
USB_CoreReset(USB_OTG_GlobalTypeDef * USBx)1303 static HAL_StatusTypeDef USB_CoreReset(USB_OTG_GlobalTypeDef *USBx)
1304 {
1305 __IO uint32_t count = 0U;
1306
1307 /* Wait for AHB master IDLE state. */
1308 do
1309 {
1310 count++;
1311
1312 if (count > 200000U)
1313 {
1314 return HAL_TIMEOUT;
1315 }
1316 } while ((USBx->GRSTCTL & USB_OTG_GRSTCTL_AHBIDL) == 0U);
1317
1318 /* Core Soft Reset */
1319 count = 0U;
1320 USBx->GRSTCTL |= USB_OTG_GRSTCTL_CSRST;
1321
1322 do
1323 {
1324 count++;
1325
1326 if (count > 200000U)
1327 {
1328 return HAL_TIMEOUT;
1329 }
1330 } while ((USBx->GRSTCTL & USB_OTG_GRSTCTL_CSRST) == USB_OTG_GRSTCTL_CSRST);
1331
1332 return HAL_OK;
1333 }
1334
1335 /**
1336 * @brief USB_HostInit : Initializes the USB OTG controller registers
1337 * for Host mode
1338 * @param USBx Selected device
1339 * @param cfg pointer to a USB_OTG_CfgTypeDef structure that contains
1340 * the configuration information for the specified USBx peripheral.
1341 * @retval HAL status
1342 */
USB_HostInit(USB_OTG_GlobalTypeDef * USBx,USB_OTG_CfgTypeDef cfg)1343 HAL_StatusTypeDef USB_HostInit(USB_OTG_GlobalTypeDef *USBx, USB_OTG_CfgTypeDef cfg)
1344 {
1345 HAL_StatusTypeDef ret = HAL_OK;
1346 uint32_t USBx_BASE = (uint32_t)USBx;
1347 uint32_t i;
1348
1349 /* Restart the Phy Clock */
1350 USBx_PCGCCTL = 0U;
1351
1352 /* Disable VBUS sensing */
1353 USBx->GCCFG &= ~(USB_OTG_GCCFG_VBDEN);
1354
1355 /* Disable Battery chargin detector */
1356 USBx->GCCFG &= ~(USB_OTG_GCCFG_BCDEN);
1357
1358 /* Set default Max speed support */
1359 USBx_HOST->HCFG &= ~(USB_OTG_HCFG_FSLSS);
1360
1361 /* Make sure the FIFOs are flushed. */
1362 if (USB_FlushTxFifo(USBx, 0x10U) != HAL_OK) /* all Tx FIFOs */
1363 {
1364 ret = HAL_ERROR;
1365 }
1366
1367 if (USB_FlushRxFifo(USBx) != HAL_OK)
1368 {
1369 ret = HAL_ERROR;
1370 }
1371
1372 /* Clear all pending HC Interrupts */
1373 for (i = 0U; i < cfg.Host_channels; i++)
1374 {
1375 USBx_HC(i)->HCINT = 0xFFFFFFFFU;
1376 USBx_HC(i)->HCINTMSK = 0U;
1377 }
1378
1379 /* Disable all interrupts. */
1380 USBx->GINTMSK = 0U;
1381
1382 /* Clear any pending interrupts */
1383 USBx->GINTSTS = 0xFFFFFFFFU;
1384
1385 /* set Rx FIFO size */
1386 USBx->GRXFSIZ = 0x80U;
1387 USBx->DIEPTXF0_HNPTXFSIZ = (uint32_t)(((0x60U << 16) & USB_OTG_NPTXFD) | 0x80U);
1388 USBx->HPTXFSIZ = (uint32_t)(((0x40U << 16)& USB_OTG_HPTXFSIZ_PTXFD) | 0xE0U);
1389 /* Enable the common interrupts */
1390 USBx->GINTMSK |= USB_OTG_GINTMSK_RXFLVLM;
1391
1392 /* Enable interrupts matching to the Host mode ONLY */
1393 USBx->GINTMSK |= (USB_OTG_GINTMSK_PRTIM | USB_OTG_GINTMSK_HCIM | \
1394 USB_OTG_GINTMSK_SOFM | USB_OTG_GINTSTS_DISCINT | \
1395 USB_OTG_GINTMSK_PXFRM_IISOOXFRM | USB_OTG_GINTMSK_WUIM);
1396
1397 return ret;
1398 }
1399
1400 /**
1401 * @brief USB_InitFSLSPClkSel : Initializes the FSLSPClkSel field of the
1402 * HCFG register on the PHY type and set the right frame interval
1403 * @param USBx Selected device
1404 * @param freq clock frequency
1405 * This parameter can be one of these values:
1406 * HCFG_48_MHZ : Full Speed 48 MHz Clock
1407 * HCFG_6_MHZ : Low Speed 6 MHz Clock
1408 * @retval HAL status
1409 */
USB_InitFSLSPClkSel(USB_OTG_GlobalTypeDef * USBx,uint8_t freq)1410 HAL_StatusTypeDef USB_InitFSLSPClkSel(USB_OTG_GlobalTypeDef *USBx, uint8_t freq)
1411 {
1412 uint32_t USBx_BASE = (uint32_t)USBx;
1413
1414 USBx_HOST->HCFG &= ~(USB_OTG_HCFG_FSLSPCS);
1415 USBx_HOST->HCFG |= (uint32_t)freq & USB_OTG_HCFG_FSLSPCS;
1416
1417 if (freq == HCFG_48_MHZ)
1418 {
1419 USBx_HOST->HFIR = 48000U;
1420 }
1421 else if (freq == HCFG_6_MHZ)
1422 {
1423 USBx_HOST->HFIR = 6000U;
1424 }
1425 else
1426 {
1427 /* ... */
1428 }
1429
1430 return HAL_OK;
1431 }
1432
1433 /**
1434 * @brief USB_OTG_ResetPort : Reset Host Port
1435 * @param USBx Selected device
1436 * @retval HAL status
1437 * @note (1)The application must wait at least 10 ms
1438 * before clearing the reset bit.
1439 */
USB_ResetPort(USB_OTG_GlobalTypeDef * USBx)1440 HAL_StatusTypeDef USB_ResetPort(USB_OTG_GlobalTypeDef *USBx)
1441 {
1442 uint32_t USBx_BASE = (uint32_t)USBx;
1443
1444 __IO uint32_t hprt0 = 0U;
1445
1446 hprt0 = USBx_HPRT0;
1447
1448 hprt0 &= ~(USB_OTG_HPRT_PENA | USB_OTG_HPRT_PCDET |
1449 USB_OTG_HPRT_PENCHNG | USB_OTG_HPRT_POCCHNG);
1450
1451 USBx_HPRT0 = (USB_OTG_HPRT_PRST | hprt0);
1452 HAL_Delay(100U); /* See Note #1 */
1453 USBx_HPRT0 = ((~USB_OTG_HPRT_PRST) & hprt0);
1454 HAL_Delay(10U);
1455
1456 return HAL_OK;
1457 }
1458
1459 /**
1460 * @brief USB_DriveVbus : activate or de-activate vbus
1461 * @param state VBUS state
1462 * This parameter can be one of these values:
1463 * 0 : Deactivate VBUS
1464 * 1 : Activate VBUS
1465 * @retval HAL status
1466 */
USB_DriveVbus(USB_OTG_GlobalTypeDef * USBx,uint8_t state)1467 HAL_StatusTypeDef USB_DriveVbus(USB_OTG_GlobalTypeDef *USBx, uint8_t state)
1468 {
1469 uint32_t USBx_BASE = (uint32_t)USBx;
1470 __IO uint32_t hprt0 = 0U;
1471
1472 hprt0 = USBx_HPRT0;
1473
1474 hprt0 &= ~(USB_OTG_HPRT_PENA | USB_OTG_HPRT_PCDET |
1475 USB_OTG_HPRT_PENCHNG | USB_OTG_HPRT_POCCHNG);
1476
1477 if (((hprt0 & USB_OTG_HPRT_PPWR) == 0U) && (state == 1U))
1478 {
1479 USBx_HPRT0 = (USB_OTG_HPRT_PPWR | hprt0);
1480 }
1481 if (((hprt0 & USB_OTG_HPRT_PPWR) == USB_OTG_HPRT_PPWR) && (state == 0U))
1482 {
1483 USBx_HPRT0 = ((~USB_OTG_HPRT_PPWR) & hprt0);
1484 }
1485 return HAL_OK;
1486 }
1487
1488 /**
1489 * @brief Return Host Core speed
1490 * @param USBx Selected device
1491 * @retval speed : Host speed
1492 * This parameter can be one of these values:
1493 * @arg HCD_SPEED_FULL: Full speed mode
1494 * @arg HCD_SPEED_LOW: Low speed mode
1495 */
USB_GetHostSpeed(USB_OTG_GlobalTypeDef * USBx)1496 uint32_t USB_GetHostSpeed(USB_OTG_GlobalTypeDef *USBx)
1497 {
1498 uint32_t USBx_BASE = (uint32_t)USBx;
1499 __IO uint32_t hprt0 = 0U;
1500
1501 hprt0 = USBx_HPRT0;
1502 return ((hprt0 & USB_OTG_HPRT_PSPD) >> 17);
1503 }
1504
1505 /**
1506 * @brief Return Host Current Frame number
1507 * @param USBx Selected device
1508 * @retval current frame number
1509 */
USB_GetCurrentFrame(USB_OTG_GlobalTypeDef * USBx)1510 uint32_t USB_GetCurrentFrame(USB_OTG_GlobalTypeDef *USBx)
1511 {
1512 uint32_t USBx_BASE = (uint32_t)USBx;
1513
1514 return (USBx_HOST->HFNUM & USB_OTG_HFNUM_FRNUM);
1515 }
1516
1517 /**
1518 * @brief Initialize a host channel
1519 * @param USBx Selected device
1520 * @param ch_num Channel number
1521 * This parameter can be a value from 1 to 15
1522 * @param epnum Endpoint number
1523 * This parameter can be a value from 1 to 15
1524 * @param dev_address Current device address
1525 * This parameter can be a value from 0 to 255
1526 * @param speed Current device speed
1527 * This parameter can be one of these values:
1528 * @arg USB_OTG_SPEED_FULL: Full speed mode
1529 * @arg USB_OTG_SPEED_LOW: Low speed mode
1530 * @param ep_type Endpoint Type
1531 * This parameter can be one of these values:
1532 * @arg EP_TYPE_CTRL: Control type
1533 * @arg EP_TYPE_ISOC: Isochronous type
1534 * @arg EP_TYPE_BULK: Bulk type
1535 * @arg EP_TYPE_INTR: Interrupt type
1536 * @param mps Max Packet Size
1537 * This parameter can be a value from 0 to 32K
1538 * @retval HAL state
1539 */
USB_HC_Init(USB_OTG_GlobalTypeDef * USBx,uint8_t ch_num,uint8_t epnum,uint8_t dev_address,uint8_t speed,uint8_t ep_type,uint16_t mps)1540 HAL_StatusTypeDef USB_HC_Init(USB_OTG_GlobalTypeDef *USBx, uint8_t ch_num,
1541 uint8_t epnum, uint8_t dev_address, uint8_t speed,
1542 uint8_t ep_type, uint16_t mps)
1543 {
1544 HAL_StatusTypeDef ret = HAL_OK;
1545 uint32_t USBx_BASE = (uint32_t)USBx;
1546 uint32_t HCcharEpDir;
1547 uint32_t HCcharLowSpeed;
1548 uint32_t HostCoreSpeed;
1549
1550 /* Clear old interrupt conditions for this host channel. */
1551 USBx_HC((uint32_t)ch_num)->HCINT = 0xFFFFFFFFU;
1552
1553 /* Enable channel interrupts required for this transfer. */
1554 switch (ep_type)
1555 {
1556 case EP_TYPE_CTRL:
1557 case EP_TYPE_BULK:
1558 USBx_HC((uint32_t)ch_num)->HCINTMSK = USB_OTG_HCINTMSK_XFRCM |
1559 USB_OTG_HCINTMSK_STALLM |
1560 USB_OTG_HCINTMSK_TXERRM |
1561 USB_OTG_HCINTMSK_DTERRM |
1562 USB_OTG_HCINTMSK_AHBERR |
1563 USB_OTG_HCINTMSK_NAKM;
1564
1565 if ((epnum & 0x80U) == 0x80U)
1566 {
1567 USBx_HC((uint32_t)ch_num)->HCINTMSK |= USB_OTG_HCINTMSK_BBERRM;
1568 }
1569 break;
1570
1571 case EP_TYPE_INTR:
1572 USBx_HC((uint32_t)ch_num)->HCINTMSK = USB_OTG_HCINTMSK_XFRCM |
1573 USB_OTG_HCINTMSK_STALLM |
1574 USB_OTG_HCINTMSK_TXERRM |
1575 USB_OTG_HCINTMSK_DTERRM |
1576 USB_OTG_HCINTMSK_NAKM |
1577 USB_OTG_HCINTMSK_AHBERR |
1578 USB_OTG_HCINTMSK_FRMORM;
1579
1580 if ((epnum & 0x80U) == 0x80U)
1581 {
1582 USBx_HC((uint32_t)ch_num)->HCINTMSK |= USB_OTG_HCINTMSK_BBERRM;
1583 }
1584
1585 break;
1586
1587 case EP_TYPE_ISOC:
1588 USBx_HC((uint32_t)ch_num)->HCINTMSK = USB_OTG_HCINTMSK_XFRCM |
1589 USB_OTG_HCINTMSK_ACKM |
1590 USB_OTG_HCINTMSK_AHBERR |
1591 USB_OTG_HCINTMSK_FRMORM;
1592
1593 if ((epnum & 0x80U) == 0x80U)
1594 {
1595 USBx_HC((uint32_t)ch_num)->HCINTMSK |= (USB_OTG_HCINTMSK_TXERRM | USB_OTG_HCINTMSK_BBERRM);
1596 }
1597 break;
1598
1599 default:
1600 ret = HAL_ERROR;
1601 break;
1602 }
1603
1604 /* Enable host channel Halt interrupt */
1605 USBx_HC((uint32_t)ch_num)->HCINTMSK |= USB_OTG_HCINTMSK_CHHM;
1606
1607 /* Enable the top level host channel interrupt. */
1608 USBx_HOST->HAINTMSK |= 1UL << (ch_num & 0xFU);
1609
1610 /* Make sure host channel interrupts are enabled. */
1611 USBx->GINTMSK |= USB_OTG_GINTMSK_HCIM;
1612
1613 /* Program the HCCHAR register */
1614 if ((epnum & 0x80U) == 0x80U)
1615 {
1616 HCcharEpDir = (0x1U << 15) & USB_OTG_HCCHAR_EPDIR;
1617 }
1618 else
1619 {
1620 HCcharEpDir = 0U;
1621 }
1622
1623 HostCoreSpeed = USB_GetHostSpeed(USBx);
1624
1625 /* LS device plugged to HUB */
1626 if ((speed == HPRT0_PRTSPD_LOW_SPEED) && (HostCoreSpeed != HPRT0_PRTSPD_LOW_SPEED))
1627 {
1628 HCcharLowSpeed = (0x1U << 17) & USB_OTG_HCCHAR_LSDEV;
1629 }
1630 else
1631 {
1632 HCcharLowSpeed = 0U;
1633 }
1634
1635 USBx_HC((uint32_t)ch_num)->HCCHAR = (((uint32_t)dev_address << 22) & USB_OTG_HCCHAR_DAD) |
1636 ((((uint32_t)epnum & 0x7FU) << 11) & USB_OTG_HCCHAR_EPNUM) |
1637 (((uint32_t)ep_type << 18) & USB_OTG_HCCHAR_EPTYP) |
1638 ((uint32_t)mps & USB_OTG_HCCHAR_MPSIZ) | HCcharEpDir | HCcharLowSpeed;
1639
1640 if ((ep_type == EP_TYPE_INTR) || (ep_type == EP_TYPE_ISOC))
1641 {
1642 USBx_HC((uint32_t)ch_num)->HCCHAR |= USB_OTG_HCCHAR_ODDFRM;
1643 }
1644
1645 return ret;
1646 }
1647
1648 /**
1649 * @brief Start a transfer over a host channel
1650 * @param USBx Selected device
1651 * @param hc pointer to host channel structure
1652 * @retval HAL state
1653 */
USB_HC_StartXfer(USB_OTG_GlobalTypeDef * USBx,USB_OTG_HCTypeDef * hc)1654 HAL_StatusTypeDef USB_HC_StartXfer(USB_OTG_GlobalTypeDef *USBx, USB_OTG_HCTypeDef *hc)
1655 {
1656 uint32_t USBx_BASE = (uint32_t)USBx;
1657 uint32_t ch_num = (uint32_t)hc->ch_num;
1658 __IO uint32_t tmpreg;
1659 uint8_t is_oddframe;
1660 uint16_t len_words;
1661 uint16_t num_packets;
1662 uint16_t max_hc_pkt_count = 256U;
1663
1664 /* Compute the expected number of packets associated to the transfer */
1665 if (hc->xfer_len > 0U)
1666 {
1667 num_packets = (uint16_t)((hc->xfer_len + hc->max_packet - 1U) / hc->max_packet);
1668
1669 if (num_packets > max_hc_pkt_count)
1670 {
1671 num_packets = max_hc_pkt_count;
1672 hc->XferSize = (uint32_t)num_packets * hc->max_packet;
1673 }
1674 }
1675 else
1676 {
1677 num_packets = 1U;
1678 }
1679
1680 /*
1681 * For IN channel HCTSIZ.XferSize is expected to be an integer multiple of
1682 * max_packet size.
1683 */
1684 if (hc->ep_is_in != 0U)
1685 {
1686 hc->XferSize = (uint32_t)num_packets * hc->max_packet;
1687 }
1688 else
1689 {
1690 hc->XferSize = hc->xfer_len;
1691 }
1692
1693 /* Initialize the HCTSIZn register */
1694 USBx_HC(ch_num)->HCTSIZ = (hc->XferSize & USB_OTG_HCTSIZ_XFRSIZ) |
1695 (((uint32_t)num_packets << 19) & USB_OTG_HCTSIZ_PKTCNT) |
1696 (((uint32_t)hc->data_pid << 29) & USB_OTG_HCTSIZ_DPID);
1697
1698 is_oddframe = (((uint32_t)USBx_HOST->HFNUM & 0x01U) != 0U) ? 0U : 1U;
1699 USBx_HC(ch_num)->HCCHAR &= ~USB_OTG_HCCHAR_ODDFRM;
1700 USBx_HC(ch_num)->HCCHAR |= (uint32_t)is_oddframe << 29;
1701
1702 /* Set host channel enable */
1703 tmpreg = USBx_HC(ch_num)->HCCHAR;
1704 tmpreg &= ~USB_OTG_HCCHAR_CHDIS;
1705
1706 /* make sure to set the correct ep direction */
1707 if (hc->ep_is_in != 0U)
1708 {
1709 tmpreg |= USB_OTG_HCCHAR_EPDIR;
1710 }
1711 else
1712 {
1713 tmpreg &= ~USB_OTG_HCCHAR_EPDIR;
1714 }
1715 tmpreg |= USB_OTG_HCCHAR_CHENA;
1716 USBx_HC(ch_num)->HCCHAR = tmpreg;
1717
1718 if ((hc->ep_is_in == 0U) && (hc->xfer_len > 0U))
1719 {
1720 switch (hc->ep_type)
1721 {
1722 /* Non periodic transfer */
1723 case EP_TYPE_CTRL:
1724 case EP_TYPE_BULK:
1725
1726 len_words = (uint16_t)((hc->xfer_len + 3U) / 4U);
1727
1728 /* check if there is enough space in FIFO space */
1729 if (len_words > (USBx->HNPTXSTS & 0xFFFFU))
1730 {
1731 /* need to process data in nptxfempty interrupt */
1732 USBx->GINTMSK |= USB_OTG_GINTMSK_NPTXFEM;
1733 }
1734 break;
1735
1736 /* Periodic transfer */
1737 case EP_TYPE_INTR:
1738 case EP_TYPE_ISOC:
1739 len_words = (uint16_t)((hc->xfer_len + 3U) / 4U);
1740 /* check if there is enough space in FIFO space */
1741 if (len_words > (USBx_HOST->HPTXSTS & 0xFFFFU)) /* split the transfer */
1742 {
1743 /* need to process data in ptxfempty interrupt */
1744 USBx->GINTMSK |= USB_OTG_GINTMSK_PTXFEM;
1745 }
1746 break;
1747
1748 default:
1749 break;
1750 }
1751
1752 /* Write packet into the Tx FIFO. */
1753 (void)USB_WritePacket(USBx, hc->xfer_buff, hc->ch_num, (uint16_t)hc->xfer_len);
1754 }
1755
1756 return HAL_OK;
1757 }
1758
1759 /**
1760 * @brief Read all host channel interrupts status
1761 * @param USBx Selected device
1762 * @retval HAL state
1763 */
USB_HC_ReadInterrupt(USB_OTG_GlobalTypeDef * USBx)1764 uint32_t USB_HC_ReadInterrupt(USB_OTG_GlobalTypeDef *USBx)
1765 {
1766 uint32_t USBx_BASE = (uint32_t)USBx;
1767
1768 return ((USBx_HOST->HAINT) & 0xFFFFU);
1769 }
1770
1771 /**
1772 * @brief Halt a host channel
1773 * @param USBx Selected device
1774 * @param hc_num Host Channel number
1775 * This parameter can be a value from 1 to 15
1776 * @retval HAL state
1777 */
USB_HC_Halt(USB_OTG_GlobalTypeDef * USBx,uint8_t hc_num)1778 HAL_StatusTypeDef USB_HC_Halt(USB_OTG_GlobalTypeDef *USBx, uint8_t hc_num)
1779 {
1780 uint32_t USBx_BASE = (uint32_t)USBx;
1781 uint32_t hcnum = (uint32_t)hc_num;
1782 __IO uint32_t count = 0U;
1783 uint32_t HcEpType = (USBx_HC(hcnum)->HCCHAR & USB_OTG_HCCHAR_EPTYP) >> 18;
1784 uint32_t ChannelEna = (USBx_HC(hcnum)->HCCHAR & USB_OTG_HCCHAR_CHENA) >> 31;
1785
1786 if (((USBx->GAHBCFG & USB_OTG_GAHBCFG_DMAEN) == USB_OTG_GAHBCFG_DMAEN) &&
1787 (ChannelEna == 0U))
1788 {
1789 return HAL_OK;
1790 }
1791
1792 /* Check for space in the request queue to issue the halt. */
1793 if ((HcEpType == HCCHAR_CTRL) || (HcEpType == HCCHAR_BULK))
1794 {
1795 USBx_HC(hcnum)->HCCHAR |= USB_OTG_HCCHAR_CHDIS;
1796
1797 if ((USBx->GAHBCFG & USB_OTG_GAHBCFG_DMAEN) == 0U)
1798 {
1799 if ((USBx->HNPTXSTS & (0xFFU << 16)) == 0U)
1800 {
1801 USBx_HC(hcnum)->HCCHAR &= ~USB_OTG_HCCHAR_CHENA;
1802 USBx_HC(hcnum)->HCCHAR |= USB_OTG_HCCHAR_CHENA;
1803 do
1804 {
1805 count++;
1806
1807 if (count > 1000U)
1808 {
1809 break;
1810 }
1811 } while ((USBx_HC(hcnum)->HCCHAR & USB_OTG_HCCHAR_CHENA) == USB_OTG_HCCHAR_CHENA);
1812 }
1813 else
1814 {
1815 USBx_HC(hcnum)->HCCHAR |= USB_OTG_HCCHAR_CHENA;
1816 }
1817 }
1818 }
1819 else
1820 {
1821 USBx_HC(hcnum)->HCCHAR |= USB_OTG_HCCHAR_CHDIS;
1822
1823 if ((USBx_HOST->HPTXSTS & (0xFFU << 16)) == 0U)
1824 {
1825 USBx_HC(hcnum)->HCCHAR &= ~USB_OTG_HCCHAR_CHENA;
1826 USBx_HC(hcnum)->HCCHAR |= USB_OTG_HCCHAR_CHENA;
1827 do
1828 {
1829 count++;
1830
1831 if (count > 1000U)
1832 {
1833 break;
1834 }
1835 } while ((USBx_HC(hcnum)->HCCHAR & USB_OTG_HCCHAR_CHENA) == USB_OTG_HCCHAR_CHENA);
1836 }
1837 else
1838 {
1839 USBx_HC(hcnum)->HCCHAR |= USB_OTG_HCCHAR_CHENA;
1840 }
1841 }
1842
1843 return HAL_OK;
1844 }
1845
1846 /**
1847 * @brief Initiate Do Ping protocol
1848 * @param USBx Selected device
1849 * @param hc_num Host Channel number
1850 * This parameter can be a value from 1 to 15
1851 * @retval HAL state
1852 */
USB_DoPing(USB_OTG_GlobalTypeDef * USBx,uint8_t ch_num)1853 HAL_StatusTypeDef USB_DoPing(USB_OTG_GlobalTypeDef *USBx, uint8_t ch_num)
1854 {
1855 uint32_t USBx_BASE = (uint32_t)USBx;
1856 uint32_t chnum = (uint32_t)ch_num;
1857 uint32_t num_packets = 1U;
1858 uint32_t tmpreg;
1859
1860 USBx_HC(chnum)->HCTSIZ = ((num_packets << 19) & USB_OTG_HCTSIZ_PKTCNT) |
1861 USB_OTG_HCTSIZ_DOPING;
1862
1863 /* Set host channel enable */
1864 tmpreg = USBx_HC(chnum)->HCCHAR;
1865 tmpreg &= ~USB_OTG_HCCHAR_CHDIS;
1866 tmpreg |= USB_OTG_HCCHAR_CHENA;
1867 USBx_HC(chnum)->HCCHAR = tmpreg;
1868
1869 return HAL_OK;
1870 }
1871
1872 /**
1873 * @brief Stop Host Core
1874 * @param USBx Selected device
1875 * @retval HAL state
1876 */
USB_StopHost(USB_OTG_GlobalTypeDef * USBx)1877 HAL_StatusTypeDef USB_StopHost(USB_OTG_GlobalTypeDef *USBx)
1878 {
1879 HAL_StatusTypeDef ret = HAL_OK;
1880 uint32_t USBx_BASE = (uint32_t)USBx;
1881 __IO uint32_t count = 0U;
1882 uint32_t value;
1883 uint32_t i;
1884
1885 (void)USB_DisableGlobalInt(USBx);
1886
1887 /* Flush USB FIFO */
1888 if (USB_FlushTxFifo(USBx, 0x10U) != HAL_OK) /* all Tx FIFOs */
1889 {
1890 ret = HAL_ERROR;
1891 }
1892
1893 if (USB_FlushRxFifo(USBx) != HAL_OK)
1894 {
1895 ret = HAL_ERROR;
1896 }
1897
1898 /* Flush out any leftover queued requests. */
1899 for (i = 0U; i <= 15U; i++)
1900 {
1901 value = USBx_HC(i)->HCCHAR;
1902 value |= USB_OTG_HCCHAR_CHDIS;
1903 value &= ~USB_OTG_HCCHAR_CHENA;
1904 value &= ~USB_OTG_HCCHAR_EPDIR;
1905 USBx_HC(i)->HCCHAR = value;
1906 }
1907
1908 /* Halt all channels to put them into a known state. */
1909 for (i = 0U; i <= 15U; i++)
1910 {
1911 value = USBx_HC(i)->HCCHAR;
1912 value |= USB_OTG_HCCHAR_CHDIS;
1913 value |= USB_OTG_HCCHAR_CHENA;
1914 value &= ~USB_OTG_HCCHAR_EPDIR;
1915 USBx_HC(i)->HCCHAR = value;
1916
1917 do
1918 {
1919 count++;
1920
1921 if (count > 1000U)
1922 {
1923 break;
1924 }
1925 } while ((USBx_HC(i)->HCCHAR & USB_OTG_HCCHAR_CHENA) == USB_OTG_HCCHAR_CHENA);
1926 }
1927
1928 /* Clear any pending Host interrupts */
1929 USBx_HOST->HAINT = 0xFFFFFFFFU;
1930 USBx->GINTSTS = 0xFFFFFFFFU;
1931
1932 (void)USB_EnableGlobalInt(USBx);
1933
1934 return ret;
1935 }
1936
1937 /**
1938 * @brief USB_ActivateRemoteWakeup active remote wakeup signalling
1939 * @param USBx Selected device
1940 * @retval HAL status
1941 */
USB_ActivateRemoteWakeup(USB_OTG_GlobalTypeDef * USBx)1942 HAL_StatusTypeDef USB_ActivateRemoteWakeup(USB_OTG_GlobalTypeDef *USBx)
1943 {
1944 uint32_t USBx_BASE = (uint32_t)USBx;
1945
1946 if ((USBx_DEVICE->DSTS & USB_OTG_DSTS_SUSPSTS) == USB_OTG_DSTS_SUSPSTS)
1947 {
1948 /* active Remote wakeup signalling */
1949 USBx_DEVICE->DCTL |= USB_OTG_DCTL_RWUSIG;
1950 }
1951
1952 return HAL_OK;
1953 }
1954
1955 /**
1956 * @brief USB_DeActivateRemoteWakeup de-active remote wakeup signalling
1957 * @param USBx Selected device
1958 * @retval HAL status
1959 */
USB_DeActivateRemoteWakeup(USB_OTG_GlobalTypeDef * USBx)1960 HAL_StatusTypeDef USB_DeActivateRemoteWakeup(USB_OTG_GlobalTypeDef *USBx)
1961 {
1962 uint32_t USBx_BASE = (uint32_t)USBx;
1963
1964 /* active Remote wakeup signalling */
1965 USBx_DEVICE->DCTL &= ~(USB_OTG_DCTL_RWUSIG);
1966
1967 return HAL_OK;
1968 }
1969 #endif /* defined (USB_OTG_FS) */
1970
1971 #if defined (USB)
1972 /**
1973 * @brief Initializes the USB Core
1974 * @param USBx USB Instance
1975 * @param cfg pointer to a USB_CfgTypeDef structure that contains
1976 * the configuration information for the specified USBx peripheral.
1977 * @retval HAL status
1978 */
USB_CoreInit(USB_TypeDef * USBx,USB_CfgTypeDef cfg)1979 HAL_StatusTypeDef USB_CoreInit(USB_TypeDef *USBx, USB_CfgTypeDef cfg)
1980 {
1981 /* Prevent unused argument(s) compilation warning */
1982 UNUSED(USBx);
1983 UNUSED(cfg);
1984
1985 /* NOTE : - This function is not required by USB Device FS peripheral, it is used
1986 only by USB OTG FS peripheral.
1987 - This function is added to ensure compatibility across platforms.
1988 */
1989
1990 return HAL_OK;
1991 }
1992
1993 /**
1994 * @brief USB_EnableGlobalInt
1995 * Enables the controller's Global Int in the AHB Config reg
1996 * @param USBx Selected device
1997 * @retval HAL status
1998 */
USB_EnableGlobalInt(USB_TypeDef * USBx)1999 HAL_StatusTypeDef USB_EnableGlobalInt(USB_TypeDef *USBx)
2000 {
2001 uint32_t winterruptmask;
2002
2003 /* Clear pending interrupts */
2004 USBx->ISTR = 0U;
2005
2006 /* Set winterruptmask variable */
2007 winterruptmask = USB_CNTR_CTRM | USB_CNTR_WKUPM |
2008 USB_CNTR_SUSPM | USB_CNTR_ERRM |
2009 USB_CNTR_SOFM | USB_CNTR_ESOFM |
2010 USB_CNTR_RESETM | USB_CNTR_L1REQM;
2011
2012 /* Set interrupt mask */
2013 USBx->CNTR = (uint16_t)winterruptmask;
2014
2015 return HAL_OK;
2016 }
2017
2018 /**
2019 * @brief USB_DisableGlobalInt
2020 * Disable the controller's Global Int in the AHB Config reg
2021 * @param USBx Selected device
2022 * @retval HAL status
2023 */
USB_DisableGlobalInt(USB_TypeDef * USBx)2024 HAL_StatusTypeDef USB_DisableGlobalInt(USB_TypeDef *USBx)
2025 {
2026 uint32_t winterruptmask;
2027
2028 /* Set winterruptmask variable */
2029 winterruptmask = USB_CNTR_CTRM | USB_CNTR_WKUPM |
2030 USB_CNTR_SUSPM | USB_CNTR_ERRM |
2031 USB_CNTR_SOFM | USB_CNTR_ESOFM |
2032 USB_CNTR_RESETM | USB_CNTR_L1REQM;
2033
2034 /* Clear interrupt mask */
2035 USBx->CNTR &= (uint16_t)(~winterruptmask);
2036
2037 return HAL_OK;
2038 }
2039
2040 /**
2041 * @brief USB_SetCurrentMode Set functional mode
2042 * @param USBx Selected device
2043 * @param mode current core mode
2044 * This parameter can be one of the these values:
2045 * @arg USB_DEVICE_MODE Peripheral mode
2046 * @retval HAL status
2047 */
USB_SetCurrentMode(USB_TypeDef * USBx,USB_ModeTypeDef mode)2048 HAL_StatusTypeDef USB_SetCurrentMode(USB_TypeDef *USBx, USB_ModeTypeDef mode)
2049 {
2050 /* Prevent unused argument(s) compilation warning */
2051 UNUSED(USBx);
2052 UNUSED(mode);
2053
2054 /* NOTE : - This function is not required by USB Device FS peripheral, it is used
2055 only by USB OTG FS peripheral.
2056 - This function is added to ensure compatibility across platforms.
2057 */
2058 return HAL_OK;
2059 }
2060
2061 /**
2062 * @brief USB_DevInit Initializes the USB controller registers
2063 * for device mode
2064 * @param USBx Selected device
2065 * @param cfg pointer to a USB_CfgTypeDef structure that contains
2066 * the configuration information for the specified USBx peripheral.
2067 * @retval HAL status
2068 */
USB_DevInit(USB_TypeDef * USBx,USB_CfgTypeDef cfg)2069 HAL_StatusTypeDef USB_DevInit(USB_TypeDef *USBx, USB_CfgTypeDef cfg)
2070 {
2071 /* Prevent unused argument(s) compilation warning */
2072 UNUSED(cfg);
2073
2074 /* Init Device */
2075 /* CNTR_FRES = 1 */
2076 USBx->CNTR = (uint16_t)USB_CNTR_FRES;
2077
2078 /* CNTR_FRES = 0 */
2079 USBx->CNTR = 0U;
2080
2081 /* Clear pending interrupts */
2082 USBx->ISTR = 0U;
2083
2084 /*Set Btable Address*/
2085 USBx->BTABLE = BTABLE_ADDRESS;
2086
2087 return HAL_OK;
2088 }
2089
2090 /**
2091 * @brief USB_FlushTxFifo : Flush a Tx FIFO
2092 * @param USBx : Selected device
2093 * @param num : FIFO number
2094 * This parameter can be a value from 1 to 15
2095 15 means Flush all Tx FIFOs
2096 * @retval HAL status
2097 */
USB_FlushTxFifo(USB_TypeDef * USBx,uint32_t num)2098 HAL_StatusTypeDef USB_FlushTxFifo(USB_TypeDef *USBx, uint32_t num)
2099 {
2100 /* Prevent unused argument(s) compilation warning */
2101 UNUSED(USBx);
2102 UNUSED(num);
2103
2104 /* NOTE : - This function is not required by USB Device FS peripheral, it is used
2105 only by USB OTG FS peripheral.
2106 - This function is added to ensure compatibility across platforms.
2107 */
2108
2109 return HAL_OK;
2110 }
2111
2112 /**
2113 * @brief USB_FlushRxFifo : Flush Rx FIFO
2114 * @param USBx : Selected device
2115 * @retval HAL status
2116 */
USB_FlushRxFifo(USB_TypeDef * USBx)2117 HAL_StatusTypeDef USB_FlushRxFifo(USB_TypeDef *USBx)
2118 {
2119 /* Prevent unused argument(s) compilation warning */
2120 UNUSED(USBx);
2121
2122 /* NOTE : - This function is not required by USB Device FS peripheral, it is used
2123 only by USB OTG FS peripheral.
2124 - This function is added to ensure compatibility across platforms.
2125 */
2126
2127 return HAL_OK;
2128 }
2129
2130 #if defined (HAL_PCD_MODULE_ENABLED)
2131 /**
2132 * @brief Activate and configure an endpoint
2133 * @param USBx Selected device
2134 * @param ep pointer to endpoint structure
2135 * @retval HAL status
2136 */
USB_ActivateEndpoint(USB_TypeDef * USBx,USB_EPTypeDef * ep)2137 HAL_StatusTypeDef USB_ActivateEndpoint(USB_TypeDef *USBx, USB_EPTypeDef *ep)
2138 {
2139 HAL_StatusTypeDef ret = HAL_OK;
2140 uint16_t wEpRegVal;
2141
2142 wEpRegVal = PCD_GET_ENDPOINT(USBx, ep->num) & USB_EP_T_MASK;
2143
2144 /* initialize Endpoint */
2145 switch (ep->type)
2146 {
2147 case EP_TYPE_CTRL:
2148 wEpRegVal |= USB_EP_CONTROL;
2149 break;
2150
2151 case EP_TYPE_BULK:
2152 wEpRegVal |= USB_EP_BULK;
2153 break;
2154
2155 case EP_TYPE_INTR:
2156 wEpRegVal |= USB_EP_INTERRUPT;
2157 break;
2158
2159 case EP_TYPE_ISOC:
2160 wEpRegVal |= USB_EP_ISOCHRONOUS;
2161 break;
2162
2163 default:
2164 ret = HAL_ERROR;
2165 break;
2166 }
2167
2168 PCD_SET_ENDPOINT(USBx, ep->num, (wEpRegVal | USB_EP_CTR_RX | USB_EP_CTR_TX));
2169
2170 PCD_SET_EP_ADDRESS(USBx, ep->num, ep->num);
2171
2172 if (ep->doublebuffer == 0U)
2173 {
2174 if (ep->is_in != 0U)
2175 {
2176 /*Set the endpoint Transmit buffer address */
2177 PCD_SET_EP_TX_ADDRESS(USBx, ep->num, ep->pmaadress);
2178 PCD_CLEAR_TX_DTOG(USBx, ep->num);
2179
2180 if (ep->type != EP_TYPE_ISOC)
2181 {
2182 /* Configure NAK status for the Endpoint */
2183 PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_NAK);
2184 }
2185 else
2186 {
2187 /* Configure TX Endpoint to disabled state */
2188 PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_DIS);
2189 }
2190 }
2191 else
2192 {
2193 /* Set the endpoint Receive buffer address */
2194 PCD_SET_EP_RX_ADDRESS(USBx, ep->num, ep->pmaadress);
2195
2196 /* Set the endpoint Receive buffer counter */
2197 PCD_SET_EP_RX_CNT(USBx, ep->num, ep->maxpacket);
2198 PCD_CLEAR_RX_DTOG(USBx, ep->num);
2199
2200 if (ep->num == 0U)
2201 {
2202 /* Configure VALID status for EP0 */
2203 PCD_SET_EP_RX_STATUS(USBx, ep->num, USB_EP_RX_VALID);
2204 }
2205 else
2206 {
2207 /* Configure NAK status for OUT Endpoint */
2208 PCD_SET_EP_RX_STATUS(USBx, ep->num, USB_EP_RX_NAK);
2209 }
2210 }
2211 }
2212 #if (USE_USB_DOUBLE_BUFFER == 1U)
2213 /* Double Buffer */
2214 else
2215 {
2216 if (ep->type == EP_TYPE_BULK)
2217 {
2218 /* Set bulk endpoint as double buffered */
2219 PCD_SET_BULK_EP_DBUF(USBx, ep->num);
2220 }
2221 else
2222 {
2223 /* Set the ISOC endpoint in double buffer mode */
2224 PCD_CLEAR_EP_KIND(USBx, ep->num);
2225 }
2226
2227 /* Set buffer address for double buffered mode */
2228 PCD_SET_EP_DBUF_ADDR(USBx, ep->num, ep->pmaaddr0, ep->pmaaddr1);
2229
2230 if (ep->is_in == 0U)
2231 {
2232 /* Clear the data toggle bits for the endpoint IN/OUT */
2233 PCD_CLEAR_RX_DTOG(USBx, ep->num);
2234 PCD_CLEAR_TX_DTOG(USBx, ep->num);
2235
2236 PCD_SET_EP_RX_STATUS(USBx, ep->num, USB_EP_RX_VALID);
2237 PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_DIS);
2238 }
2239 else
2240 {
2241 /* Clear the data toggle bits for the endpoint IN/OUT */
2242 PCD_CLEAR_RX_DTOG(USBx, ep->num);
2243 PCD_CLEAR_TX_DTOG(USBx, ep->num);
2244
2245 if (ep->type != EP_TYPE_ISOC)
2246 {
2247 /* Configure NAK status for the Endpoint */
2248 PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_NAK);
2249 }
2250 else
2251 {
2252 /* Configure TX Endpoint to disabled state */
2253 PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_DIS);
2254 }
2255
2256 PCD_SET_EP_RX_STATUS(USBx, ep->num, USB_EP_RX_DIS);
2257 }
2258 }
2259 #endif /* (USE_USB_DOUBLE_BUFFER == 1U) */
2260
2261 return ret;
2262 }
2263
2264 /**
2265 * @brief De-activate and de-initialize an endpoint
2266 * @param USBx Selected device
2267 * @param ep pointer to endpoint structure
2268 * @retval HAL status
2269 */
USB_DeactivateEndpoint(USB_TypeDef * USBx,USB_EPTypeDef * ep)2270 HAL_StatusTypeDef USB_DeactivateEndpoint(USB_TypeDef *USBx, USB_EPTypeDef *ep)
2271 {
2272 if (ep->doublebuffer == 0U)
2273 {
2274 if (ep->is_in != 0U)
2275 {
2276 PCD_CLEAR_TX_DTOG(USBx, ep->num);
2277
2278 /* Configure DISABLE status for the Endpoint */
2279 PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_DIS);
2280 }
2281
2282 else
2283 {
2284 PCD_CLEAR_RX_DTOG(USBx, ep->num);
2285
2286 /* Configure DISABLE status for the Endpoint */
2287 PCD_SET_EP_RX_STATUS(USBx, ep->num, USB_EP_RX_DIS);
2288 }
2289 }
2290 #if (USE_USB_DOUBLE_BUFFER == 1U)
2291 /* Double Buffer */
2292 else
2293 {
2294 if (ep->is_in == 0U)
2295 {
2296 /* Clear the data toggle bits for the endpoint IN/OUT*/
2297 PCD_CLEAR_RX_DTOG(USBx, ep->num);
2298 PCD_CLEAR_TX_DTOG(USBx, ep->num);
2299
2300 /* Reset value of the data toggle bits for the endpoint out*/
2301 PCD_TX_DTOG(USBx, ep->num);
2302
2303 PCD_SET_EP_RX_STATUS(USBx, ep->num, USB_EP_RX_DIS);
2304 PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_DIS);
2305 }
2306 else
2307 {
2308 /* Clear the data toggle bits for the endpoint IN/OUT*/
2309 PCD_CLEAR_RX_DTOG(USBx, ep->num);
2310 PCD_CLEAR_TX_DTOG(USBx, ep->num);
2311 PCD_RX_DTOG(USBx, ep->num);
2312
2313 /* Configure DISABLE status for the Endpoint*/
2314 PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_DIS);
2315 PCD_SET_EP_RX_STATUS(USBx, ep->num, USB_EP_RX_DIS);
2316 }
2317 }
2318 #endif /* (USE_USB_DOUBLE_BUFFER == 1U) */
2319
2320 return HAL_OK;
2321 }
2322
2323 /**
2324 * @brief USB_EPStartXfer setup and starts a transfer over an EP
2325 * @param USBx Selected device
2326 * @param ep pointer to endpoint structure
2327 * @retval HAL status
2328 */
USB_EPStartXfer(USB_TypeDef * USBx,USB_EPTypeDef * ep)2329 HAL_StatusTypeDef USB_EPStartXfer(USB_TypeDef *USBx, USB_EPTypeDef *ep)
2330 {
2331 uint32_t len;
2332 #if (USE_USB_DOUBLE_BUFFER == 1U)
2333 uint16_t pmabuffer;
2334 uint16_t wEPVal;
2335 #endif /* (USE_USB_DOUBLE_BUFFER == 1U) */
2336
2337 /* IN endpoint */
2338 if (ep->is_in == 1U)
2339 {
2340 /*Multi packet transfer*/
2341 if (ep->xfer_len > ep->maxpacket)
2342 {
2343 len = ep->maxpacket;
2344 }
2345 else
2346 {
2347 len = ep->xfer_len;
2348 }
2349
2350 /* configure and validate Tx endpoint */
2351 if (ep->doublebuffer == 0U)
2352 {
2353 USB_WritePMA(USBx, ep->xfer_buff, ep->pmaadress, (uint16_t)len);
2354 PCD_SET_EP_TX_CNT(USBx, ep->num, len);
2355 }
2356 #if (USE_USB_DOUBLE_BUFFER == 1U)
2357 else
2358 {
2359 /* double buffer bulk management */
2360 if (ep->type == EP_TYPE_BULK)
2361 {
2362 if (ep->xfer_len_db > ep->maxpacket)
2363 {
2364 /* enable double buffer */
2365 PCD_SET_BULK_EP_DBUF(USBx, ep->num);
2366
2367 /* each Time to write in PMA xfer_len_db will */
2368 ep->xfer_len_db -= len;
2369
2370 /* Fill the two first buffer in the Buffer0 & Buffer1 */
2371 if ((PCD_GET_ENDPOINT(USBx, ep->num) & USB_EP_DTOG_TX) != 0U)
2372 {
2373 /* Set the Double buffer counter for pmabuffer1 */
2374 PCD_SET_EP_DBUF1_CNT(USBx, ep->num, ep->is_in, len);
2375 pmabuffer = ep->pmaaddr1;
2376
2377 /* Write the user buffer to USB PMA */
2378 USB_WritePMA(USBx, ep->xfer_buff, pmabuffer, (uint16_t)len);
2379 ep->xfer_buff += len;
2380
2381 if (ep->xfer_len_db > ep->maxpacket)
2382 {
2383 ep->xfer_len_db -= len;
2384 }
2385 else
2386 {
2387 len = ep->xfer_len_db;
2388 ep->xfer_len_db = 0U;
2389 }
2390
2391 /* Set the Double buffer counter for pmabuffer0 */
2392 PCD_SET_EP_DBUF0_CNT(USBx, ep->num, ep->is_in, len);
2393 pmabuffer = ep->pmaaddr0;
2394
2395 /* Write the user buffer to USB PMA */
2396 USB_WritePMA(USBx, ep->xfer_buff, pmabuffer, (uint16_t)len);
2397 }
2398 else
2399 {
2400 /* Set the Double buffer counter for pmabuffer0 */
2401 PCD_SET_EP_DBUF0_CNT(USBx, ep->num, ep->is_in, len);
2402 pmabuffer = ep->pmaaddr0;
2403
2404 /* Write the user buffer to USB PMA */
2405 USB_WritePMA(USBx, ep->xfer_buff, pmabuffer, (uint16_t)len);
2406 ep->xfer_buff += len;
2407
2408 if (ep->xfer_len_db > ep->maxpacket)
2409 {
2410 ep->xfer_len_db -= len;
2411 }
2412 else
2413 {
2414 len = ep->xfer_len_db;
2415 ep->xfer_len_db = 0U;
2416 }
2417
2418 /* Set the Double buffer counter for pmabuffer1 */
2419 PCD_SET_EP_DBUF1_CNT(USBx, ep->num, ep->is_in, len);
2420 pmabuffer = ep->pmaaddr1;
2421
2422 /* Write the user buffer to USB PMA */
2423 USB_WritePMA(USBx, ep->xfer_buff, pmabuffer, (uint16_t)len);
2424 }
2425 }
2426 /* auto Switch to single buffer mode when transfer <Mps no need to manage in double buffer */
2427 else
2428 {
2429 len = ep->xfer_len_db;
2430
2431 /* disable double buffer mode for Bulk endpoint */
2432 PCD_CLEAR_BULK_EP_DBUF(USBx, ep->num);
2433
2434 /* Set Tx count with nbre of byte to be transmitted */
2435 PCD_SET_EP_TX_CNT(USBx, ep->num, len);
2436 pmabuffer = ep->pmaaddr0;
2437
2438 /* Write the user buffer to USB PMA */
2439 USB_WritePMA(USBx, ep->xfer_buff, pmabuffer, (uint16_t)len);
2440 }
2441 }
2442 else /* manage isochronous double buffer IN mode */
2443 {
2444 /* each Time to write in PMA xfer_len_db will */
2445 ep->xfer_len_db -= len;
2446
2447 /* Fill the data buffer */
2448 if ((PCD_GET_ENDPOINT(USBx, ep->num) & USB_EP_DTOG_TX) != 0U)
2449 {
2450 /* Set the Double buffer counter for pmabuffer1 */
2451 PCD_SET_EP_DBUF1_CNT(USBx, ep->num, ep->is_in, len);
2452 pmabuffer = ep->pmaaddr1;
2453
2454 /* Write the user buffer to USB PMA */
2455 USB_WritePMA(USBx, ep->xfer_buff, pmabuffer, (uint16_t)len);
2456 }
2457 else
2458 {
2459 /* Set the Double buffer counter for pmabuffer0 */
2460 PCD_SET_EP_DBUF0_CNT(USBx, ep->num, ep->is_in, len);
2461 pmabuffer = ep->pmaaddr0;
2462
2463 /* Write the user buffer to USB PMA */
2464 USB_WritePMA(USBx, ep->xfer_buff, pmabuffer, (uint16_t)len);
2465 }
2466 }
2467 }
2468 #endif /* (USE_USB_DOUBLE_BUFFER == 1U) */
2469
2470 PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_VALID);
2471 }
2472 else /* OUT endpoint */
2473 {
2474 if (ep->doublebuffer == 0U)
2475 {
2476 /* Multi packet transfer */
2477 if (ep->xfer_len > ep->maxpacket)
2478 {
2479 len = ep->maxpacket;
2480 ep->xfer_len -= len;
2481 }
2482 else
2483 {
2484 len = ep->xfer_len;
2485 ep->xfer_len = 0U;
2486 }
2487 /* configure and validate Rx endpoint */
2488 PCD_SET_EP_RX_CNT(USBx, ep->num, len);
2489 }
2490 #if (USE_USB_DOUBLE_BUFFER == 1U)
2491 else
2492 {
2493 /* First Transfer Coming From HAL_PCD_EP_Receive & From ISR */
2494 /* Set the Double buffer counter */
2495 if (ep->type == EP_TYPE_BULK)
2496 {
2497 PCD_SET_EP_DBUF_CNT(USBx, ep->num, ep->is_in, ep->maxpacket);
2498
2499 /* Coming from ISR */
2500 if (ep->xfer_count != 0U)
2501 {
2502 /* update last value to check if there is blocking state */
2503 wEPVal = PCD_GET_ENDPOINT(USBx, ep->num);
2504
2505 /*Blocking State */
2506 if ((((wEPVal & USB_EP_DTOG_RX) != 0U) && ((wEPVal & USB_EP_DTOG_TX) != 0U)) ||
2507 (((wEPVal & USB_EP_DTOG_RX) == 0U) && ((wEPVal & USB_EP_DTOG_TX) == 0U)))
2508 {
2509 PCD_FREE_USER_BUFFER(USBx, ep->num, 0U);
2510 }
2511 }
2512 }
2513 /* iso out double */
2514 else if (ep->type == EP_TYPE_ISOC)
2515 {
2516 /* Multi packet transfer */
2517 if (ep->xfer_len > ep->maxpacket)
2518 {
2519 len = ep->maxpacket;
2520 ep->xfer_len -= len;
2521 }
2522 else
2523 {
2524 len = ep->xfer_len;
2525 ep->xfer_len = 0U;
2526 }
2527 PCD_SET_EP_DBUF_CNT(USBx, ep->num, ep->is_in, len);
2528 }
2529 else
2530 {
2531 return HAL_ERROR;
2532 }
2533 }
2534 #endif /* (USE_USB_DOUBLE_BUFFER == 1U) */
2535
2536 PCD_SET_EP_RX_STATUS(USBx, ep->num, USB_EP_RX_VALID);
2537 }
2538
2539 return HAL_OK;
2540 }
2541
2542
2543 /**
2544 * @brief USB_EPSetStall set a stall condition over an EP
2545 * @param USBx Selected device
2546 * @param ep pointer to endpoint structure
2547 * @retval HAL status
2548 */
USB_EPSetStall(USB_TypeDef * USBx,USB_EPTypeDef * ep)2549 HAL_StatusTypeDef USB_EPSetStall(USB_TypeDef *USBx, USB_EPTypeDef *ep)
2550 {
2551 if (ep->is_in != 0U)
2552 {
2553 PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_STALL);
2554 }
2555 else
2556 {
2557 PCD_SET_EP_RX_STATUS(USBx, ep->num, USB_EP_RX_STALL);
2558 }
2559
2560 return HAL_OK;
2561 }
2562
2563 /**
2564 * @brief USB_EPClearStall Clear a stall condition over an EP
2565 * @param USBx Selected device
2566 * @param ep pointer to endpoint structure
2567 * @retval HAL status
2568 */
USB_EPClearStall(USB_TypeDef * USBx,USB_EPTypeDef * ep)2569 HAL_StatusTypeDef USB_EPClearStall(USB_TypeDef *USBx, USB_EPTypeDef *ep)
2570 {
2571 if (ep->doublebuffer == 0U)
2572 {
2573 if (ep->is_in != 0U)
2574 {
2575 PCD_CLEAR_TX_DTOG(USBx, ep->num);
2576
2577 if (ep->type != EP_TYPE_ISOC)
2578 {
2579 /* Configure NAK status for the Endpoint */
2580 PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_NAK);
2581 }
2582 }
2583 else
2584 {
2585 PCD_CLEAR_RX_DTOG(USBx, ep->num);
2586
2587 /* Configure VALID status for the Endpoint */
2588 PCD_SET_EP_RX_STATUS(USBx, ep->num, USB_EP_RX_VALID);
2589 }
2590 }
2591
2592 return HAL_OK;
2593 }
2594
2595 /**
2596 * @brief USB_EPStoptXfer Stop transfer on an EP
2597 * @param USBx usb device instance
2598 * @param ep pointer to endpoint structure
2599 * @retval HAL status
2600 */
USB_EPStopXfer(USB_TypeDef * USBx,USB_EPTypeDef * ep)2601 HAL_StatusTypeDef USB_EPStopXfer(USB_TypeDef *USBx, USB_EPTypeDef *ep)
2602 {
2603 /* IN endpoint */
2604 if (ep->is_in == 1U)
2605 {
2606 if (ep->doublebuffer == 0U)
2607 {
2608 if (ep->type != EP_TYPE_ISOC)
2609 {
2610 /* Configure NAK status for the Endpoint */
2611 PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_NAK);
2612 }
2613 else
2614 {
2615 /* Configure TX Endpoint to disabled state */
2616 PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_DIS);
2617 }
2618 }
2619 }
2620 else /* OUT endpoint */
2621 {
2622 if (ep->doublebuffer == 0U)
2623 {
2624 if (ep->type != EP_TYPE_ISOC)
2625 {
2626 /* Configure NAK status for the Endpoint */
2627 PCD_SET_EP_RX_STATUS(USBx, ep->num, USB_EP_RX_NAK);
2628 }
2629 else
2630 {
2631 /* Configure RX Endpoint to disabled state */
2632 PCD_SET_EP_RX_STATUS(USBx, ep->num, USB_EP_RX_DIS);
2633 }
2634 }
2635 }
2636
2637 return HAL_OK;
2638 }
2639 #endif /* defined (HAL_PCD_MODULE_ENABLED) */
2640
2641 /**
2642 * @brief USB_StopDevice Stop the usb device mode
2643 * @param USBx Selected device
2644 * @retval HAL status
2645 */
USB_StopDevice(USB_TypeDef * USBx)2646 HAL_StatusTypeDef USB_StopDevice(USB_TypeDef *USBx)
2647 {
2648 /* disable all interrupts and force USB reset */
2649 USBx->CNTR = (uint16_t)USB_CNTR_FRES;
2650
2651 /* clear interrupt status register */
2652 USBx->ISTR = 0U;
2653
2654 /* switch-off device */
2655 USBx->CNTR = (uint16_t)(USB_CNTR_FRES | USB_CNTR_PDWN);
2656
2657 return HAL_OK;
2658 }
2659
2660 /**
2661 * @brief USB_SetDevAddress Stop the usb device mode
2662 * @param USBx Selected device
2663 * @param address new device address to be assigned
2664 * This parameter can be a value from 0 to 255
2665 * @retval HAL status
2666 */
USB_SetDevAddress(USB_TypeDef * USBx,uint8_t address)2667 HAL_StatusTypeDef USB_SetDevAddress(USB_TypeDef *USBx, uint8_t address)
2668 {
2669 if (address == 0U)
2670 {
2671 /* set device address and enable function */
2672 USBx->DADDR = (uint16_t)USB_DADDR_EF;
2673 }
2674
2675 return HAL_OK;
2676 }
2677
2678 /**
2679 * @brief USB_DevConnect Connect the USB device by enabling the pull-up/pull-down
2680 * @param USBx Selected device
2681 * @retval HAL status
2682 */
USB_DevConnect(USB_TypeDef * USBx)2683 HAL_StatusTypeDef USB_DevConnect(USB_TypeDef *USBx)
2684 {
2685 /* Enabling DP Pull-UP bit to Connect internal PU resistor on USB DP line */
2686 USBx->BCDR |= (uint16_t)USB_BCDR_DPPU;
2687
2688 return HAL_OK;
2689 }
2690
2691 /**
2692 * @brief USB_DevDisconnect Disconnect the USB device by disabling the pull-up/pull-down
2693 * @param USBx Selected device
2694 * @retval HAL status
2695 */
USB_DevDisconnect(USB_TypeDef * USBx)2696 HAL_StatusTypeDef USB_DevDisconnect(USB_TypeDef *USBx)
2697 {
2698 /* Disable DP Pull-Up bit to disconnect the Internal PU resistor on USB DP line */
2699 USBx->BCDR &= (uint16_t)(~(USB_BCDR_DPPU));
2700
2701 return HAL_OK;
2702 }
2703
2704 /**
2705 * @brief USB_ReadInterrupts return the global USB interrupt status
2706 * @param USBx Selected device
2707 * @retval HAL status
2708 */
USB_ReadInterrupts(USB_TypeDef * USBx)2709 uint32_t USB_ReadInterrupts(USB_TypeDef *USBx)
2710 {
2711 uint32_t tmpreg;
2712
2713 tmpreg = USBx->ISTR;
2714 return tmpreg;
2715 }
2716
2717 /**
2718 * @brief USB_ReadDevAllOutEpInterrupt return the USB device OUT endpoints interrupt status
2719 * @param USBx Selected device
2720 * @retval HAL status
2721 */
USB_ReadDevAllOutEpInterrupt(USB_TypeDef * USBx)2722 uint32_t USB_ReadDevAllOutEpInterrupt(USB_TypeDef *USBx)
2723 {
2724 /* Prevent unused argument(s) compilation warning */
2725 UNUSED(USBx);
2726 /* NOTE : - This function is not required by USB Device FS peripheral, it is used
2727 only by USB OTG FS peripheral.
2728 - This function is added to ensure compatibility across platforms.
2729 */
2730 return (0);
2731 }
2732
2733 /**
2734 * @brief USB_ReadDevAllInEpInterrupt return the USB device IN endpoints interrupt status
2735 * @param USBx Selected device
2736 * @retval HAL status
2737 */
USB_ReadDevAllInEpInterrupt(USB_TypeDef * USBx)2738 uint32_t USB_ReadDevAllInEpInterrupt(USB_TypeDef *USBx)
2739 {
2740 /* Prevent unused argument(s) compilation warning */
2741 UNUSED(USBx);
2742 /* NOTE : - This function is not required by USB Device FS peripheral, it is used
2743 only by USB OTG FS peripheral.
2744 - This function is added to ensure compatibility across platforms.
2745 */
2746 return (0);
2747 }
2748
2749 /**
2750 * @brief Returns Device OUT EP Interrupt register
2751 * @param USBx Selected device
2752 * @param epnum endpoint number
2753 * This parameter can be a value from 0 to 15
2754 * @retval Device OUT EP Interrupt register
2755 */
USB_ReadDevOutEPInterrupt(USB_TypeDef * USBx,uint8_t epnum)2756 uint32_t USB_ReadDevOutEPInterrupt(USB_TypeDef *USBx, uint8_t epnum)
2757 {
2758 /* Prevent unused argument(s) compilation warning */
2759 UNUSED(USBx);
2760 UNUSED(epnum);
2761 /* NOTE : - This function is not required by USB Device FS peripheral, it is used
2762 only by USB OTG FS peripheral.
2763 - This function is added to ensure compatibility across platforms.
2764 */
2765 return (0);
2766 }
2767
2768 /**
2769 * @brief Returns Device IN EP Interrupt register
2770 * @param USBx Selected device
2771 * @param epnum endpoint number
2772 * This parameter can be a value from 0 to 15
2773 * @retval Device IN EP Interrupt register
2774 */
USB_ReadDevInEPInterrupt(USB_TypeDef * USBx,uint8_t epnum)2775 uint32_t USB_ReadDevInEPInterrupt(USB_TypeDef *USBx, uint8_t epnum)
2776 {
2777 /* Prevent unused argument(s) compilation warning */
2778 UNUSED(USBx);
2779 UNUSED(epnum);
2780 /* NOTE : - This function is not required by USB Device FS peripheral, it is used
2781 only by USB OTG FS peripheral.
2782 - This function is added to ensure compatibility across platforms.
2783 */
2784 return (0);
2785 }
2786
2787 /**
2788 * @brief USB_ClearInterrupts: clear a USB interrupt
2789 * @param USBx Selected device
2790 * @param interrupt flag
2791 * @retval None
2792 */
USB_ClearInterrupts(USB_TypeDef * USBx,uint32_t interrupt)2793 void USB_ClearInterrupts(USB_TypeDef *USBx, uint32_t interrupt)
2794 {
2795 /* Prevent unused argument(s) compilation warning */
2796 UNUSED(USBx);
2797 UNUSED(interrupt);
2798 /* NOTE : - This function is not required by USB Device FS peripheral, it is used
2799 only by USB OTG FS peripheral.
2800 - This function is added to ensure compatibility across platforms.
2801 */
2802 }
2803
2804 /**
2805 * @brief Prepare the EP0 to start the first control setup
2806 * @param USBx Selected device
2807 * @param psetup pointer to setup packet
2808 * @retval HAL status
2809 */
USB_EP0_OutStart(USB_TypeDef * USBx,uint8_t * psetup)2810 HAL_StatusTypeDef USB_EP0_OutStart(USB_TypeDef *USBx, uint8_t *psetup)
2811 {
2812 /* Prevent unused argument(s) compilation warning */
2813 UNUSED(USBx);
2814 UNUSED(psetup);
2815 /* NOTE : - This function is not required by USB Device FS peripheral, it is used
2816 only by USB OTG FS peripheral.
2817 - This function is added to ensure compatibility across platforms.
2818 */
2819 return HAL_OK;
2820 }
2821
2822 /**
2823 * @brief USB_ActivateRemoteWakeup : active remote wakeup signalling
2824 * @param USBx Selected device
2825 * @retval HAL status
2826 */
USB_ActivateRemoteWakeup(USB_TypeDef * USBx)2827 HAL_StatusTypeDef USB_ActivateRemoteWakeup(USB_TypeDef *USBx)
2828 {
2829 USBx->CNTR |= (uint16_t)USB_CNTR_RESUME;
2830
2831 return HAL_OK;
2832 }
2833
2834 /**
2835 * @brief USB_DeActivateRemoteWakeup de-active remote wakeup signalling
2836 * @param USBx Selected device
2837 * @retval HAL status
2838 */
USB_DeActivateRemoteWakeup(USB_TypeDef * USBx)2839 HAL_StatusTypeDef USB_DeActivateRemoteWakeup(USB_TypeDef *USBx)
2840 {
2841 USBx->CNTR &= (uint16_t)(~USB_CNTR_RESUME);
2842
2843 return HAL_OK;
2844 }
2845
2846 /**
2847 * @brief Copy a buffer from user memory area to packet memory area (PMA)
2848 * @param USBx USB peripheral instance register address.
2849 * @param pbUsrBuf pointer to user memory area.
2850 * @param wPMABufAddr address into PMA.
2851 * @param wNBytes no. of bytes to be copied.
2852 * @retval None
2853 */
USB_WritePMA(USB_TypeDef * USBx,uint8_t * pbUsrBuf,uint16_t wPMABufAddr,uint16_t wNBytes)2854 void USB_WritePMA(USB_TypeDef *USBx, uint8_t *pbUsrBuf, uint16_t wPMABufAddr, uint16_t wNBytes)
2855 {
2856 uint32_t n = ((uint32_t)wNBytes + 1U) >> 1;
2857 uint32_t BaseAddr = (uint32_t)USBx;
2858 uint32_t count;
2859 uint16_t WrVal;
2860 __IO uint16_t *pdwVal;
2861 uint8_t *pBuf = pbUsrBuf;
2862
2863 pdwVal = (__IO uint16_t *)(BaseAddr + 0x400U + ((uint32_t)wPMABufAddr * PMA_ACCESS));
2864
2865 for (count = n; count != 0U; count--)
2866 {
2867 WrVal = pBuf[0];
2868 WrVal |= (uint16_t)pBuf[1] << 8;
2869 *pdwVal = (WrVal & 0xFFFFU);
2870 pdwVal++;
2871
2872 #if PMA_ACCESS > 1U
2873 pdwVal++;
2874 #endif /* PMA_ACCESS */
2875
2876 pBuf++;
2877 pBuf++;
2878 }
2879 }
2880
2881 /**
2882 * @brief Copy data from packet memory area (PMA) to user memory buffer
2883 * @param USBx USB peripheral instance register address.
2884 * @param pbUsrBuf pointer to user memory area.
2885 * @param wPMABufAddr address into PMA.
2886 * @param wNBytes no. of bytes to be copied.
2887 * @retval None
2888 */
USB_ReadPMA(USB_TypeDef * USBx,uint8_t * pbUsrBuf,uint16_t wPMABufAddr,uint16_t wNBytes)2889 void USB_ReadPMA(USB_TypeDef *USBx, uint8_t *pbUsrBuf, uint16_t wPMABufAddr, uint16_t wNBytes)
2890 {
2891 uint32_t n = (uint32_t)wNBytes >> 1;
2892 uint32_t BaseAddr = (uint32_t)USBx;
2893 uint32_t count;
2894 uint32_t RdVal;
2895 __IO uint16_t *pdwVal;
2896 uint8_t *pBuf = pbUsrBuf;
2897
2898 pdwVal = (__IO uint16_t *)(BaseAddr + 0x400U + ((uint32_t)wPMABufAddr * PMA_ACCESS));
2899
2900 for (count = n; count != 0U; count--)
2901 {
2902 RdVal = *(__IO uint16_t *)pdwVal;
2903 pdwVal++;
2904 *pBuf = (uint8_t)((RdVal >> 0) & 0xFFU);
2905 pBuf++;
2906 *pBuf = (uint8_t)((RdVal >> 8) & 0xFFU);
2907 pBuf++;
2908
2909 #if PMA_ACCESS > 1U
2910 pdwVal++;
2911 #endif /* PMA_ACCESS */
2912 }
2913
2914 if ((wNBytes % 2U) != 0U)
2915 {
2916 RdVal = *pdwVal;
2917 *pBuf = (uint8_t)((RdVal >> 0) & 0xFFU);
2918 }
2919 }
2920 #endif /* defined (USB) */
2921
2922 /**
2923 * @}
2924 */
2925
2926 /**
2927 * @}
2928 */
2929 #endif /* defined (USB) || defined (USB_OTG_FS) */
2930 #endif /* defined (HAL_PCD_MODULE_ENABLED) || defined (HAL_HCD_MODULE_ENABLED) */
2931
2932 /**
2933 * @}
2934 */
2935