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