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