1 /**
2 ******************************************************************************
3 * @file stm32f7xx_ll_usb.c
4 * @author MCD Application Team
5 * @version V1.0.1
6 * @date 25-June-2015
7 * @brief USB Low Layer HAL module driver.
8 *
9 * This file provides firmware functions to manage the following
10 * functionalities of the USB Peripheral Controller:
11 * + Initialization/de-initialization functions
12 * + I/O operation functions
13 * + Peripheral Control functions
14 * + Peripheral State functions
15 *
16 @verbatim
17 ==============================================================================
18 ##### How to use this driver #####
19 ==============================================================================
20 [..]
21 (#) Fill parameters of Init structure in USB_OTG_CfgTypeDef structure.
22
23 (#) Call USB_CoreInit() API to initialize the USB Core peripheral.
24
25 (#) The upper HAL HCD/PCD driver will call the right routines for its internal processes.
26
27 @endverbatim
28 ******************************************************************************
29 * @attention
30 *
31 * <h2><center>© COPYRIGHT(c) 2015 STMicroelectronics</center></h2>
32 *
33 * Redistribution and use in source and binary forms, with or without modification,
34 * are permitted provided that the following conditions are met:
35 * 1. Redistributions of source code must retain the above copyright notice,
36 * this list of conditions and the following disclaimer.
37 * 2. Redistributions in binary form must reproduce the above copyright notice,
38 * this list of conditions and the following disclaimer in the documentation
39 * and/or other materials provided with the distribution.
40 * 3. Neither the name of STMicroelectronics nor the names of its contributors
41 * may be used to endorse or promote products derived from this software
42 * without specific prior written permission.
43 *
44 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
45 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
46 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
47 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
48 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
49 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
50 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
51 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
52 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
53 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
54 *
55 ******************************************************************************
56 */
57
58 /* Includes ------------------------------------------------------------------*/
59 #include "stm32f7xx_hal.h"
60
61 /** @addtogroup STM32F7xx_LL_USB_DRIVER
62 * @{
63 */
64
65 #if defined (HAL_PCD_MODULE_ENABLED) || defined (HAL_HCD_MODULE_ENABLED)
66
67 /* Private typedef -----------------------------------------------------------*/
68 /* Private define ------------------------------------------------------------*/
69 /* Private macro -------------------------------------------------------------*/
70 /* Private variables ---------------------------------------------------------*/
71 /* Private function prototypes -----------------------------------------------*/
72 /* Private functions ---------------------------------------------------------*/
73 static HAL_StatusTypeDef USB_CoreReset(USB_OTG_GlobalTypeDef *USBx);
74
75 /** @defgroup PCD_Private_Functions
76 * @{
77 */
78
79 /** @defgroup LL_USB_Group1 Initialization/de-initialization functions
80 * @brief Initialization and Configuration functions
81 *
82 @verbatim
83 ===============================================================================
84 ##### Initialization/de-initialization functions #####
85 ===============================================================================
86 [..] This section provides functions allowing to:
87
88 @endverbatim
89 * @{
90 */
91
92 /**
93 * @brief Initializes the USB Core
94 * @param USBx: USB Instance
95 * @param cfg : pointer to a USB_OTG_CfgTypeDef structure that contains
96 * the configuration information for the specified USBx peripheral.
97 * @retval HAL status
98 */
USB_CoreInit(USB_OTG_GlobalTypeDef * USBx,USB_OTG_CfgTypeDef cfg)99 HAL_StatusTypeDef USB_CoreInit(USB_OTG_GlobalTypeDef *USBx, USB_OTG_CfgTypeDef cfg)
100 {
101 if (cfg.phy_itface == USB_OTG_ULPI_PHY) {
102
103 USBx->GCCFG &= ~(USB_OTG_GCCFG_PWRDWN);
104
105 /* Init The ULPI Interface */
106 USBx->GUSBCFG &= ~(USB_OTG_GUSBCFG_TSDPS | USB_OTG_GUSBCFG_ULPIFSLS | USB_OTG_GUSBCFG_PHYSEL);
107
108 /* Select vbus source */
109 USBx->GUSBCFG &= ~(USB_OTG_GUSBCFG_ULPIEVBUSD | USB_OTG_GUSBCFG_ULPIEVBUSI);
110 if (cfg.use_external_vbus == 1) {
111 USBx->GUSBCFG |= USB_OTG_GUSBCFG_ULPIEVBUSD;
112 }
113 /* Reset after a PHY select */
114 USB_CoreReset(USBx);
115 } else { /* FS interface (embedded Phy) */
116
117 /* Select FS Embedded PHY */
118 USBx->GUSBCFG |= USB_OTG_GUSBCFG_PHYSEL;
119
120 /* Reset after a PHY select and set Host mode */
121 USB_CoreReset(USBx);
122
123 /* Deactivate the power down*/
124 USBx->GCCFG = USB_OTG_GCCFG_PWRDWN;
125 }
126
127 if (cfg.dma_enable == ENABLE) {
128 USBx->GAHBCFG |= (USB_OTG_GAHBCFG_HBSTLEN_1 | USB_OTG_GAHBCFG_HBSTLEN_2);
129 USBx->GAHBCFG |= USB_OTG_GAHBCFG_DMAEN;
130 }
131
132 return HAL_OK;
133 }
134
135 /**
136 * @brief USB_EnableGlobalInt
137 * Enables the controller's Global Int in the AHB Config reg
138 * @param USBx : Selected device
139 * @retval HAL status
140 */
USB_EnableGlobalInt(USB_OTG_GlobalTypeDef * USBx)141 HAL_StatusTypeDef USB_EnableGlobalInt(USB_OTG_GlobalTypeDef *USBx)
142 {
143 USBx->GAHBCFG |= USB_OTG_GAHBCFG_GINT;
144 return HAL_OK;
145 }
146
147
148 /**
149 * @brief USB_DisableGlobalInt
150 * Disable the controller's Global Int in the AHB Config reg
151 * @param USBx : Selected device
152 * @retval HAL status
153 */
USB_DisableGlobalInt(USB_OTG_GlobalTypeDef * USBx)154 HAL_StatusTypeDef USB_DisableGlobalInt(USB_OTG_GlobalTypeDef *USBx)
155 {
156 USBx->GAHBCFG &= ~USB_OTG_GAHBCFG_GINT;
157 return HAL_OK;
158 }
159
160 /**
161 * @brief USB_SetCurrentMode : Set functional mode
162 * @param USBx : Selected device
163 * @param mode : current core mode
164 * This parameter can be one of the these values:
165 * @arg USB_OTG_DEVICE_MODE: Peripheral mode
166 * @arg USB_OTG_HOST_MODE: Host mode
167 * @arg USB_OTG_DRD_MODE: Dual Role Device mode
168 * @retval HAL status
169 */
USB_SetCurrentMode(USB_OTG_GlobalTypeDef * USBx,USB_OTG_ModeTypeDef mode)170 HAL_StatusTypeDef USB_SetCurrentMode(USB_OTG_GlobalTypeDef *USBx , USB_OTG_ModeTypeDef mode)
171 {
172 USBx->GUSBCFG &= ~(USB_OTG_GUSBCFG_FHMOD | USB_OTG_GUSBCFG_FDMOD);
173
174 if ( mode == USB_OTG_HOST_MODE) {
175 USBx->GUSBCFG |= USB_OTG_GUSBCFG_FHMOD;
176 } else if ( mode == USB_OTG_DEVICE_MODE) {
177 USBx->GUSBCFG |= USB_OTG_GUSBCFG_FDMOD;
178 }
179 HAL_Delay(50);
180
181 return HAL_OK;
182 }
183
184 /**
185 * @brief USB_DevInit : Initializes the USB_OTG controller registers
186 * for device mode
187 * @param USBx : Selected device
188 * @param cfg : pointer to a USB_OTG_CfgTypeDef structure that contains
189 * the configuration information for the specified USBx peripheral.
190 * @retval HAL status
191 */
USB_DevInit(USB_OTG_GlobalTypeDef * USBx,USB_OTG_CfgTypeDef cfg)192 HAL_StatusTypeDef USB_DevInit (USB_OTG_GlobalTypeDef *USBx, USB_OTG_CfgTypeDef cfg)
193 {
194 uint32_t i = 0;
195
196 /*Activate VBUS Sensing B */
197 USBx->GCCFG |= USB_OTG_GCCFG_VBDEN;
198
199 if (cfg.vbus_sensing_enable == 0) {
200 /*Desactivate VBUS Sensing B */
201 USBx->GCCFG &= ~ USB_OTG_GCCFG_VBDEN;
202
203 /* B-peripheral session valid override enable*/
204 USBx->GOTGCTL |= USB_OTG_GOTGCTL_BVALOEN;
205 USBx->GOTGCTL |= USB_OTG_GOTGCTL_BVALOVAL;
206 }
207
208 /* Restart the Phy Clock */
209 USBx_PCGCCTL = 0;
210
211 /* Device mode configuration */
212 USBx_DEVICE->DCFG |= DCFG_FRAME_INTERVAL_80;
213
214 if (cfg.phy_itface == USB_OTG_ULPI_PHY) {
215 if (cfg.speed == USB_OTG_SPEED_HIGH) {
216 /* Set High speed phy */
217 USB_SetDevSpeed (USBx , USB_OTG_SPEED_HIGH);
218 } else {
219 /* set High speed phy in Full speed mode */
220 USB_SetDevSpeed (USBx , USB_OTG_SPEED_HIGH_IN_FULL);
221 }
222 } else {
223 /* Set Full speed phy */
224 USB_SetDevSpeed (USBx , USB_OTG_SPEED_FULL);
225 }
226
227 /* Flush the FIFOs */
228 USB_FlushTxFifo(USBx , 0x10); /* all Tx FIFOs */
229 USB_FlushRxFifo(USBx);
230
231
232 /* Clear all pending Device Interrupts */
233 USBx_DEVICE->DIEPMSK = 0;
234 USBx_DEVICE->DOEPMSK = 0;
235 USBx_DEVICE->DAINT = 0xFFFFFFFF;
236 USBx_DEVICE->DAINTMSK = 0;
237
238 for (i = 0; i < cfg.dev_endpoints; i++) {
239 if ((USBx_INEP(i)->DIEPCTL & USB_OTG_DIEPCTL_EPENA) == USB_OTG_DIEPCTL_EPENA) {
240 USBx_INEP(i)->DIEPCTL = (USB_OTG_DIEPCTL_EPDIS | USB_OTG_DIEPCTL_SNAK);
241 } else {
242 USBx_INEP(i)->DIEPCTL = 0;
243 }
244
245 USBx_INEP(i)->DIEPTSIZ = 0;
246 USBx_INEP(i)->DIEPINT = 0xFF;
247 }
248
249 for (i = 0; i < cfg.dev_endpoints; i++) {
250 if ((USBx_OUTEP(i)->DOEPCTL & USB_OTG_DOEPCTL_EPENA) == USB_OTG_DOEPCTL_EPENA) {
251 USBx_OUTEP(i)->DOEPCTL = (USB_OTG_DOEPCTL_EPDIS | USB_OTG_DOEPCTL_SNAK);
252 } else {
253 USBx_OUTEP(i)->DOEPCTL = 0;
254 }
255
256 USBx_OUTEP(i)->DOEPTSIZ = 0;
257 USBx_OUTEP(i)->DOEPINT = 0xFF;
258 }
259
260 USBx_DEVICE->DIEPMSK &= ~(USB_OTG_DIEPMSK_TXFURM);
261
262 if (cfg.dma_enable == 1) {
263 /*Set threshold parameters */
264 USBx_DEVICE->DTHRCTL = (USB_OTG_DTHRCTL_TXTHRLEN_6 | USB_OTG_DTHRCTL_RXTHRLEN_6);
265 USBx_DEVICE->DTHRCTL |= (USB_OTG_DTHRCTL_RXTHREN | USB_OTG_DTHRCTL_ISOTHREN | USB_OTG_DTHRCTL_NONISOTHREN);
266
267 i= USBx_DEVICE->DTHRCTL;
268 }
269
270 /* Disable all interrupts. */
271 USBx->GINTMSK = 0;
272
273 /* Clear any pending interrupts */
274 USBx->GINTSTS = 0xBFFFFFFF;
275
276 /* Enable the common interrupts */
277 if (cfg.dma_enable == DISABLE) {
278 USBx->GINTMSK |= USB_OTG_GINTMSK_RXFLVLM;
279 }
280
281 /* Enable interrupts matching to the Device mode ONLY */
282 USBx->GINTMSK |= (USB_OTG_GINTMSK_USBSUSPM | USB_OTG_GINTMSK_USBRST |\
283 USB_OTG_GINTMSK_ENUMDNEM | USB_OTG_GINTMSK_IEPINT |\
284 USB_OTG_GINTMSK_OEPINT | USB_OTG_GINTMSK_IISOIXFRM|\
285 USB_OTG_GINTMSK_PXFRM_IISOOXFRM | USB_OTG_GINTMSK_WUIM);
286
287 if (cfg.Sof_enable) {
288 USBx->GINTMSK |= USB_OTG_GINTMSK_SOFM;
289 }
290
291 if (cfg.vbus_sensing_enable == ENABLE) {
292 USBx->GINTMSK |= (USB_OTG_GINTMSK_SRQIM | USB_OTG_GINTMSK_OTGINT);
293 }
294
295 return HAL_OK;
296 }
297
298
299 /**
300 * @brief USB_OTG_FlushTxFifo : Flush a Tx FIFO
301 * @param USBx : Selected device
302 * @param num : FIFO number
303 * This parameter can be a value from 1 to 15
304 15 means Flush all Tx FIFOs
305 * @retval HAL status
306 */
USB_FlushTxFifo(USB_OTG_GlobalTypeDef * USBx,uint32_t num)307 HAL_StatusTypeDef USB_FlushTxFifo (USB_OTG_GlobalTypeDef *USBx, uint32_t num )
308 {
309 uint32_t count = 0;
310
311 USBx->GRSTCTL = ( USB_OTG_GRSTCTL_TXFFLSH |(uint32_t)( num << 6));
312
313 do {
314 if (++count > 200000) {
315 return HAL_TIMEOUT;
316 }
317 } while ((USBx->GRSTCTL & USB_OTG_GRSTCTL_TXFFLSH) == USB_OTG_GRSTCTL_TXFFLSH);
318
319 return HAL_OK;
320 }
321
322
323 /**
324 * @brief USB_FlushRxFifo : Flush Rx FIFO
325 * @param USBx : Selected device
326 * @retval HAL status
327 */
USB_FlushRxFifo(USB_OTG_GlobalTypeDef * USBx)328 HAL_StatusTypeDef USB_FlushRxFifo(USB_OTG_GlobalTypeDef *USBx)
329 {
330 uint32_t count = 0;
331
332 USBx->GRSTCTL = USB_OTG_GRSTCTL_RXFFLSH;
333
334 do {
335 if (++count > 200000) {
336 return HAL_TIMEOUT;
337 }
338 } while ((USBx->GRSTCTL & USB_OTG_GRSTCTL_RXFFLSH) == USB_OTG_GRSTCTL_RXFFLSH);
339
340 return HAL_OK;
341 }
342
343 /**
344 * @brief USB_SetDevSpeed :Initializes the DevSpd field of DCFG register
345 * depending the PHY type and the enumeration speed of the device.
346 * @param USBx : Selected device
347 * @param speed : device speed
348 * This parameter can be one of the these values:
349 * @arg USB_OTG_SPEED_HIGH: High speed mode
350 * @arg USB_OTG_SPEED_HIGH_IN_FULL: High speed core in Full Speed mode
351 * @arg USB_OTG_SPEED_FULL: Full speed mode
352 * @arg USB_OTG_SPEED_LOW: Low speed mode
353 * @retval Hal status
354 */
USB_SetDevSpeed(USB_OTG_GlobalTypeDef * USBx,uint8_t speed)355 HAL_StatusTypeDef USB_SetDevSpeed(USB_OTG_GlobalTypeDef *USBx , uint8_t speed)
356 {
357 USBx_DEVICE->DCFG |= speed;
358 return HAL_OK;
359 }
360
361 /**
362 * @brief USB_GetDevSpeed :Return the Dev Speed
363 * @param USBx : Selected device
364 * @retval speed : device speed
365 * This parameter can be one of the these values:
366 * @arg USB_OTG_SPEED_HIGH: High speed mode
367 * @arg USB_OTG_SPEED_FULL: Full speed mode
368 * @arg USB_OTG_SPEED_LOW: Low speed mode
369 */
USB_GetDevSpeed(USB_OTG_GlobalTypeDef * USBx)370 uint8_t USB_GetDevSpeed(USB_OTG_GlobalTypeDef *USBx)
371 {
372 uint8_t speed = 0;
373
374 if ((USBx_DEVICE->DSTS & USB_OTG_DSTS_ENUMSPD) == DSTS_ENUMSPD_HS_PHY_30MHZ_OR_60MHZ) {
375 speed = USB_OTG_SPEED_HIGH;
376 } else if (((USBx_DEVICE->DSTS & USB_OTG_DSTS_ENUMSPD) == DSTS_ENUMSPD_FS_PHY_30MHZ_OR_60MHZ)||
377 ((USBx_DEVICE->DSTS & USB_OTG_DSTS_ENUMSPD) == DSTS_ENUMSPD_FS_PHY_48MHZ)) {
378 speed = USB_OTG_SPEED_FULL;
379 } else if ((USBx_DEVICE->DSTS & USB_OTG_DSTS_ENUMSPD) == DSTS_ENUMSPD_LS_PHY_6MHZ) {
380 speed = USB_OTG_SPEED_LOW;
381 }
382
383 return speed;
384 }
385
386 /**
387 * @brief Activate and configure an endpoint
388 * @param USBx : Selected device
389 * @param ep: pointer to endpoint structure
390 * @retval HAL status
391 */
USB_ActivateEndpoint(USB_OTG_GlobalTypeDef * USBx,USB_OTG_EPTypeDef * ep)392 HAL_StatusTypeDef USB_ActivateEndpoint(USB_OTG_GlobalTypeDef *USBx, USB_OTG_EPTypeDef *ep)
393 {
394 if (ep->is_in == 1) {
395 USBx_DEVICE->DAINTMSK |= USB_OTG_DAINTMSK_IEPM & ((1 << (ep->num)));
396
397 if (((USBx_INEP(ep->num)->DIEPCTL) & USB_OTG_DIEPCTL_USBAEP) == 0) {
398 USBx_INEP(ep->num)->DIEPCTL |= ((ep->maxpacket & USB_OTG_DIEPCTL_MPSIZ ) | (ep->type << 18 ) |\
399 ((ep->num) << 22 ) | (USB_OTG_DIEPCTL_SD0PID_SEVNFRM) | (USB_OTG_DIEPCTL_USBAEP));
400 }
401
402 } else {
403 USBx_DEVICE->DAINTMSK |= USB_OTG_DAINTMSK_OEPM & ((1 << (ep->num)) << 16);
404
405 if (((USBx_OUTEP(ep->num)->DOEPCTL) & USB_OTG_DOEPCTL_USBAEP) == 0) {
406 USBx_OUTEP(ep->num)->DOEPCTL |= ((ep->maxpacket & USB_OTG_DOEPCTL_MPSIZ ) | (ep->type << 18 ) |\
407 (USB_OTG_DIEPCTL_SD0PID_SEVNFRM)| (USB_OTG_DOEPCTL_USBAEP) |\
408 (USB_OTG_DOEPCTL_SNAK)); // TKG add to default receive eps as NAK until queued
409 }
410 }
411 return HAL_OK;
412 }
413 /**
414 * @brief Activate and configure a dedicated endpoint
415 * @param USBx : Selected device
416 * @param ep: pointer to endpoint structure
417 * @retval HAL status
418 */
USB_ActivateDedicatedEndpoint(USB_OTG_GlobalTypeDef * USBx,USB_OTG_EPTypeDef * ep)419 HAL_StatusTypeDef USB_ActivateDedicatedEndpoint(USB_OTG_GlobalTypeDef *USBx, USB_OTG_EPTypeDef *ep)
420 {
421 static __IO uint32_t debug = 0;
422
423 /* Read DEPCTLn register */
424 if (ep->is_in == 1) {
425 if (((USBx_INEP(ep->num)->DIEPCTL) & USB_OTG_DIEPCTL_USBAEP) == 0) {
426 USBx_INEP(ep->num)->DIEPCTL |= ((ep->maxpacket & USB_OTG_DIEPCTL_MPSIZ ) | (ep->type << 18 ) |\
427 ((ep->num) << 22 ) | (USB_OTG_DIEPCTL_SD0PID_SEVNFRM) | (USB_OTG_DIEPCTL_USBAEP));
428 }
429
430
431 debug |= ((ep->maxpacket & USB_OTG_DIEPCTL_MPSIZ ) | (ep->type << 18 ) |\
432 ((ep->num) << 22 ) | (USB_OTG_DIEPCTL_SD0PID_SEVNFRM) | (USB_OTG_DIEPCTL_USBAEP));
433
434 USBx_DEVICE->DEACHMSK |= USB_OTG_DAINTMSK_IEPM & ((1 << (ep->num)));
435 } else {
436 if (((USBx_OUTEP(ep->num)->DOEPCTL) & USB_OTG_DOEPCTL_USBAEP) == 0) {
437 USBx_OUTEP(ep->num)->DOEPCTL |= ((ep->maxpacket & USB_OTG_DOEPCTL_MPSIZ ) | (ep->type << 18 ) |\
438 ((ep->num) << 22 ) | (USB_OTG_DOEPCTL_USBAEP));
439
440 debug = (uint32_t)(((uint32_t )USBx) + USB_OTG_OUT_ENDPOINT_BASE + (0)*USB_OTG_EP_REG_SIZE);
441 debug = (uint32_t )&USBx_OUTEP(ep->num)->DOEPCTL;
442 debug |= ((ep->maxpacket & USB_OTG_DOEPCTL_MPSIZ ) | (ep->type << 18 ) |\
443 ((ep->num) << 22 ) | (USB_OTG_DOEPCTL_USBAEP));
444 }
445
446 USBx_DEVICE->DEACHMSK |= USB_OTG_DAINTMSK_OEPM & ((1 << (ep->num)) << 16);
447 }
448
449 return HAL_OK;
450 }
451 /**
452 * @brief De-activate and de-initialize an endpoint
453 * @param USBx : Selected device
454 * @param ep: pointer to endpoint structure
455 * @retval HAL status
456 */
USB_DeactivateEndpoint(USB_OTG_GlobalTypeDef * USBx,USB_OTG_EPTypeDef * ep)457 HAL_StatusTypeDef USB_DeactivateEndpoint(USB_OTG_GlobalTypeDef *USBx, USB_OTG_EPTypeDef *ep)
458 {
459 /* Read DEPCTLn register */
460 if (ep->is_in == 1) {
461 USBx_DEVICE->DEACHMSK &= ~(USB_OTG_DAINTMSK_IEPM & ((1 << (ep->num))));
462 USBx_DEVICE->DAINTMSK &= ~(USB_OTG_DAINTMSK_IEPM & ((1 << (ep->num))));
463 USBx_INEP(ep->num)->DIEPCTL &= ~ USB_OTG_DIEPCTL_USBAEP;
464 } else {
465
466 USBx_DEVICE->DEACHMSK &= ~(USB_OTG_DAINTMSK_OEPM & ((1 << (ep->num)) << 16));
467 USBx_DEVICE->DAINTMSK &= ~(USB_OTG_DAINTMSK_OEPM & ((1 << (ep->num)) << 16));
468 USBx_OUTEP(ep->num)->DOEPCTL &= ~USB_OTG_DOEPCTL_USBAEP;
469 }
470 return HAL_OK;
471 }
472
473 /**
474 * @brief De-activate and de-initialize a dedicated endpoint
475 * @param USBx : Selected device
476 * @param ep: pointer to endpoint structure
477 * @retval HAL status
478 */
USB_DeactivateDedicatedEndpoint(USB_OTG_GlobalTypeDef * USBx,USB_OTG_EPTypeDef * ep)479 HAL_StatusTypeDef USB_DeactivateDedicatedEndpoint(USB_OTG_GlobalTypeDef *USBx, USB_OTG_EPTypeDef *ep)
480 {
481 /* Read DEPCTLn register */
482 if (ep->is_in == 1) {
483 USBx_INEP(ep->num)->DIEPCTL &= ~ USB_OTG_DIEPCTL_USBAEP;
484 USBx_DEVICE->DAINTMSK &= ~(USB_OTG_DAINTMSK_IEPM & ((1 << (ep->num))));
485 } else {
486 USBx_OUTEP(ep->num)->DOEPCTL &= ~USB_OTG_DOEPCTL_USBAEP;
487 USBx_DEVICE->DAINTMSK &= ~(USB_OTG_DAINTMSK_OEPM & ((1 << (ep->num)) << 16));
488 }
489 return HAL_OK;
490 }
491
492 /**
493 * @brief USB_EPStartXfer : setup and starts a transfer over an EP
494 * @param USBx : Selected device
495 * @param ep: pointer to endpoint structure
496 * @param dma: USB dma enabled or disabled
497 * This parameter can be one of the these values:
498 * 0 : DMA feature not used
499 * 1 : DMA feature used
500 * @retval HAL status
501 */
USB_EPStartXfer(USB_OTG_GlobalTypeDef * USBx,USB_OTG_EPTypeDef * ep,uint8_t dma)502 HAL_StatusTypeDef USB_EPStartXfer(USB_OTG_GlobalTypeDef *USBx , USB_OTG_EPTypeDef *ep, uint8_t dma)
503 {
504 uint16_t pktcnt = 0;
505
506 /* IN endpoint */
507 if (ep->is_in == 1) {
508 /* Zero Length Packet? */
509 if (ep->xfer_len == 0) {
510 USBx_INEP(ep->num)->DIEPTSIZ &= ~(USB_OTG_DIEPTSIZ_PKTCNT);
511 USBx_INEP(ep->num)->DIEPTSIZ |= (USB_OTG_DIEPTSIZ_PKTCNT & (1 << 19)) ;
512 USBx_INEP(ep->num)->DIEPTSIZ &= ~(USB_OTG_DIEPTSIZ_XFRSIZ);
513 } else {
514 /* Program the transfer size and packet count
515 * as follows: xfersize = N * maxpacket +
516 * short_packet pktcnt = N + (short_packet
517 * exist ? 1 : 0)
518 */
519 USBx_INEP(ep->num)->DIEPTSIZ &= ~(USB_OTG_DIEPTSIZ_XFRSIZ);
520 USBx_INEP(ep->num)->DIEPTSIZ &= ~(USB_OTG_DIEPTSIZ_PKTCNT);
521 USBx_INEP(ep->num)->DIEPTSIZ |= (USB_OTG_DIEPTSIZ_PKTCNT & (((ep->xfer_len + ep->maxpacket -1)/ ep->maxpacket) << 19)) ;
522 USBx_INEP(ep->num)->DIEPTSIZ |= (USB_OTG_DIEPTSIZ_XFRSIZ & ep->xfer_len);
523
524 if (ep->type == EP_TYPE_ISOC) {
525 USBx_INEP(ep->num)->DIEPTSIZ &= ~(USB_OTG_DIEPTSIZ_MULCNT);
526 USBx_INEP(ep->num)->DIEPTSIZ |= (USB_OTG_DIEPTSIZ_MULCNT & (1 << 29));
527 }
528 }
529
530 if (dma == 1) {
531 USBx_INEP(ep->num)->DIEPDMA = (uint32_t)(ep->dma_addr);
532 } else {
533 if (ep->type != EP_TYPE_ISOC) {
534 /* Enable the Tx FIFO Empty Interrupt for this EP */
535 if (ep->xfer_len > 0) {
536 USBx_DEVICE->DIEPEMPMSK |= 1 << ep->num;
537 }
538 }
539 }
540
541 if (ep->type == EP_TYPE_ISOC) {
542 if ((USBx_DEVICE->DSTS & ( 1 << 8 )) == 0) {
543 USBx_INEP(ep->num)->DIEPCTL |= USB_OTG_DIEPCTL_SODDFRM;
544 } else {
545 USBx_INEP(ep->num)->DIEPCTL |= USB_OTG_DIEPCTL_SD0PID_SEVNFRM;
546 }
547 }
548
549 /* EP enable, IN data in FIFO */
550 USBx_INEP(ep->num)->DIEPCTL |= (USB_OTG_DIEPCTL_CNAK | USB_OTG_DIEPCTL_EPENA);
551
552 if (ep->type == EP_TYPE_ISOC) {
553 USB_WritePacket(USBx, ep->xfer_buff, ep->num, ep->xfer_len, dma);
554 }
555 } else { /* OUT endpoint */
556 /* Program the transfer size and packet count as follows:
557 * pktcnt = N
558 * xfersize = N * maxpacket
559 */
560 USBx_OUTEP(ep->num)->DOEPTSIZ &= ~(USB_OTG_DOEPTSIZ_XFRSIZ);
561 USBx_OUTEP(ep->num)->DOEPTSIZ &= ~(USB_OTG_DOEPTSIZ_PKTCNT);
562
563 if (ep->xfer_len == 0) {
564 USBx_OUTEP(ep->num)->DOEPTSIZ |= (USB_OTG_DOEPTSIZ_XFRSIZ & ep->maxpacket);
565 USBx_OUTEP(ep->num)->DOEPTSIZ |= (USB_OTG_DOEPTSIZ_PKTCNT & (1 << 19)) ;
566 } else {
567 pktcnt = (ep->xfer_len + ep->maxpacket -1)/ ep->maxpacket;
568 USBx_OUTEP(ep->num)->DOEPTSIZ |= (USB_OTG_DOEPTSIZ_PKTCNT & (pktcnt << 19));
569 USBx_OUTEP(ep->num)->DOEPTSIZ |= (USB_OTG_DOEPTSIZ_XFRSIZ & (ep->maxpacket * pktcnt));
570 }
571
572 if (dma == 1) {
573 USBx_OUTEP(ep->num)->DOEPDMA = (uint32_t)ep->xfer_buff;
574 }
575
576 if (ep->type == EP_TYPE_ISOC) {
577 if ((USBx_DEVICE->DSTS & ( 1 << 8 )) == 0) {
578 USBx_OUTEP(ep->num)->DOEPCTL |= USB_OTG_DOEPCTL_SODDFRM;
579 } else {
580 USBx_OUTEP(ep->num)->DOEPCTL |= USB_OTG_DOEPCTL_SD0PID_SEVNFRM;
581 }
582 }
583 /* EP enable */
584 USBx_OUTEP(ep->num)->DOEPCTL |= (USB_OTG_DOEPCTL_CNAK | USB_OTG_DOEPCTL_EPENA);
585 }
586 return HAL_OK;
587 }
588
589 /**
590 * @brief USB_EP0StartXfer : setup and starts a transfer over the EP 0
591 * @param USBx : Selected device
592 * @param ep: pointer to endpoint structure
593 * @param dma: USB dma enabled or disabled
594 * This parameter can be one of the these values:
595 * 0 : DMA feature not used
596 * 1 : DMA feature used
597 * @retval HAL status
598 */
USB_EP0StartXfer(USB_OTG_GlobalTypeDef * USBx,USB_OTG_EPTypeDef * ep,uint8_t dma)599 HAL_StatusTypeDef USB_EP0StartXfer(USB_OTG_GlobalTypeDef *USBx , USB_OTG_EPTypeDef *ep, uint8_t dma)
600 {
601 /* IN endpoint */
602 if (ep->is_in == 1) {
603 /* Zero Length Packet? */
604 if (ep->xfer_len == 0) {
605 USBx_INEP(ep->num)->DIEPTSIZ &= ~(USB_OTG_DIEPTSIZ_PKTCNT);
606 USBx_INEP(ep->num)->DIEPTSIZ |= (USB_OTG_DIEPTSIZ_PKTCNT & (1 << 19)) ;
607 USBx_INEP(ep->num)->DIEPTSIZ &= ~(USB_OTG_DIEPTSIZ_XFRSIZ);
608 } else {
609 /* Program the transfer size and packet count
610 * as follows: xfersize = N * maxpacket +
611 * short_packet pktcnt = N + (short_packet
612 * exist ? 1 : 0)
613 */
614 USBx_INEP(ep->num)->DIEPTSIZ &= ~(USB_OTG_DIEPTSIZ_XFRSIZ);
615 USBx_INEP(ep->num)->DIEPTSIZ &= ~(USB_OTG_DIEPTSIZ_PKTCNT);
616
617 if (ep->xfer_len > ep->maxpacket) {
618 ep->xfer_len = ep->maxpacket;
619 }
620 USBx_INEP(ep->num)->DIEPTSIZ |= (USB_OTG_DIEPTSIZ_PKTCNT & (1 << 19)) ;
621 USBx_INEP(ep->num)->DIEPTSIZ |= (USB_OTG_DIEPTSIZ_XFRSIZ & ep->xfer_len);
622
623 }
624
625 if (dma == 1) {
626 USBx_INEP(ep->num)->DIEPDMA = (uint32_t)(ep->dma_addr);
627 } else {
628 /* Enable the Tx FIFO Empty Interrupt for this EP */
629 if (ep->xfer_len > 0) {
630 USBx_DEVICE->DIEPEMPMSK |= 1 << (ep->num);
631 }
632 }
633
634 /* EP enable, IN data in FIFO */
635 USBx_INEP(ep->num)->DIEPCTL |= (USB_OTG_DIEPCTL_CNAK | USB_OTG_DIEPCTL_EPENA);
636 } else { /* OUT endpoint */
637 /* Program the transfer size and packet count as follows:
638 * pktcnt = N
639 * xfersize = N * maxpacket
640 */
641 USBx_OUTEP(ep->num)->DOEPTSIZ &= ~(USB_OTG_DOEPTSIZ_XFRSIZ);
642 USBx_OUTEP(ep->num)->DOEPTSIZ &= ~(USB_OTG_DOEPTSIZ_PKTCNT);
643
644 if (ep->xfer_len > 0) {
645 ep->xfer_len = ep->maxpacket;
646 }
647
648 USBx_OUTEP(ep->num)->DOEPTSIZ |= (USB_OTG_DOEPTSIZ_PKTCNT & (1 << 19));
649 USBx_OUTEP(ep->num)->DOEPTSIZ |= (USB_OTG_DOEPTSIZ_XFRSIZ & (ep->maxpacket));
650
651
652 if (dma == 1) {
653 USBx_OUTEP(ep->num)->DOEPDMA = (uint32_t)(ep->xfer_buff);
654 }
655
656 /* EP enable */
657 USBx_OUTEP(ep->num)->DOEPCTL |= (USB_OTG_DOEPCTL_CNAK | USB_OTG_DOEPCTL_EPENA);
658 }
659 return HAL_OK;
660 }
661
662 /**
663 * @brief USB_WritePacket : Writes a packet into the Tx FIFO associated
664 * with the EP/channel
665 * @param USBx : Selected device
666 * @param src : pointer to source buffer
667 * @param ch_ep_num : endpoint or host channel number
668 * @param len : Number of bytes to write
669 * @param dma: USB dma enabled or disabled
670 * This parameter can be one of the these values:
671 * 0 : DMA feature not used
672 * 1 : DMA feature used
673 * @retval HAL status
674 */
USB_WritePacket(USB_OTG_GlobalTypeDef * USBx,uint8_t * src,uint8_t ch_ep_num,uint16_t len,uint8_t dma)675 HAL_StatusTypeDef USB_WritePacket(USB_OTG_GlobalTypeDef *USBx, uint8_t *src, uint8_t ch_ep_num, uint16_t len, uint8_t dma)
676 {
677 uint32_t count32b= 0 , i= 0;
678
679 if (dma == 0) {
680 count32b = (len + 3) / 4;
681 for (i = 0; i < count32b; i++, src += 4) {
682 USBx_DFIFO(ch_ep_num) = *((__packed uint32_t *)src);
683 }
684 }
685 return HAL_OK;
686 }
687
688 /**
689 * @brief USB_ReadPacket : read a packet from the Tx FIFO associated
690 * with the EP/channel
691 * @param USBx : Selected device
692 * @param src : source pointer
693 * @param ch_ep_num : endpoint or host channel number
694 * @param len : Number of bytes to read
695 * @param dma: USB dma enabled or disabled
696 * This parameter can be one of the these values:
697 * 0 : DMA feature not used
698 * 1 : DMA feature used
699 * @retval pointer to destination buffer
700 */
USB_ReadPacket(USB_OTG_GlobalTypeDef * USBx,uint8_t * dest,uint16_t len)701 void *USB_ReadPacket(USB_OTG_GlobalTypeDef *USBx, uint8_t *dest, uint16_t len)
702 {
703 uint32_t i=0;
704 uint32_t count32b = (len + 3) / 4;
705
706 for ( i = 0; i < count32b; i++, dest += 4 ) {
707 *(__packed uint32_t *)dest = USBx_DFIFO(0);
708
709 }
710 return ((void *)dest);
711 }
712
713 /**
714 * @brief USB_EPSetStall : set a stall condition over an EP
715 * @param USBx : Selected device
716 * @param ep: pointer to endpoint structure
717 * @retval HAL status
718 */
USB_EPSetStall(USB_OTG_GlobalTypeDef * USBx,USB_OTG_EPTypeDef * ep)719 HAL_StatusTypeDef USB_EPSetStall(USB_OTG_GlobalTypeDef *USBx , USB_OTG_EPTypeDef *ep)
720 {
721 if (ep->is_in == 1) {
722 if (((USBx_INEP(ep->num)->DIEPCTL) & USB_OTG_DIEPCTL_EPENA) == 0) {
723 USBx_INEP(ep->num)->DIEPCTL &= ~(USB_OTG_DIEPCTL_EPDIS);
724 }
725 USBx_INEP(ep->num)->DIEPCTL |= USB_OTG_DIEPCTL_STALL;
726 } else {
727 if (((USBx_OUTEP(ep->num)->DOEPCTL) & USB_OTG_DOEPCTL_EPENA) == 0) {
728 USBx_OUTEP(ep->num)->DOEPCTL &= ~(USB_OTG_DOEPCTL_EPDIS);
729 }
730 USBx_OUTEP(ep->num)->DOEPCTL |= USB_OTG_DOEPCTL_STALL;
731 }
732 return HAL_OK;
733 }
734
735
736 /**
737 * @brief USB_EPClearStall : Clear a stall condition over an EP
738 * @param USBx : Selected device
739 * @param ep: pointer to endpoint structure
740 * @retval HAL status
741 */
USB_EPClearStall(USB_OTG_GlobalTypeDef * USBx,USB_OTG_EPTypeDef * ep)742 HAL_StatusTypeDef USB_EPClearStall(USB_OTG_GlobalTypeDef *USBx, USB_OTG_EPTypeDef *ep)
743 {
744 if (ep->is_in == 1) {
745 USBx_INEP(ep->num)->DIEPCTL &= ~USB_OTG_DIEPCTL_STALL;
746 if (ep->type == EP_TYPE_INTR || ep->type == EP_TYPE_BULK) {
747 USBx_INEP(ep->num)->DIEPCTL |= USB_OTG_DIEPCTL_SD0PID_SEVNFRM; /* DATA0 */
748 }
749 } else {
750 USBx_OUTEP(ep->num)->DOEPCTL &= ~USB_OTG_DOEPCTL_STALL;
751 if (ep->type == EP_TYPE_INTR || ep->type == EP_TYPE_BULK) {
752 USBx_OUTEP(ep->num)->DOEPCTL |= USB_OTG_DOEPCTL_SD0PID_SEVNFRM; /* DATA0 */
753 }
754 }
755 return HAL_OK;
756 }
757
758 /**
759 * @brief USB_StopDevice : Stop the usb device mode
760 * @param USBx : Selected device
761 * @retval HAL status
762 */
USB_StopDevice(USB_OTG_GlobalTypeDef * USBx)763 HAL_StatusTypeDef USB_StopDevice(USB_OTG_GlobalTypeDef *USBx)
764 {
765 uint32_t i;
766
767 /* Clear Pending interrupt */
768 for (i = 0; i < 15 ; i++) {
769 USBx_INEP(i)->DIEPINT = 0xFF;
770 USBx_OUTEP(i)->DOEPINT = 0xFF;
771 }
772 USBx_DEVICE->DAINT = 0xFFFFFFFF;
773
774 /* Clear interrupt masks */
775 USBx_DEVICE->DIEPMSK = 0;
776 USBx_DEVICE->DOEPMSK = 0;
777 USBx_DEVICE->DAINTMSK = 0;
778
779 /* Flush the FIFO */
780 USB_FlushRxFifo(USBx);
781 USB_FlushTxFifo(USBx , 0x10 );
782
783 return HAL_OK;
784 }
785
786 /**
787 * @brief USB_SetDevAddress : Stop the usb device mode
788 * @param USBx : Selected device
789 * @param address : new device address to be assigned
790 * This parameter can be a value from 0 to 255
791 * @retval HAL status
792 */
USB_SetDevAddress(USB_OTG_GlobalTypeDef * USBx,uint8_t address)793 HAL_StatusTypeDef USB_SetDevAddress (USB_OTG_GlobalTypeDef *USBx, uint8_t address)
794 {
795 USBx_DEVICE->DCFG &= ~ (USB_OTG_DCFG_DAD);
796 USBx_DEVICE->DCFG |= (address << 4) & USB_OTG_DCFG_DAD ;
797
798 return HAL_OK;
799 }
800
801 /**
802 * @brief USB_DevConnect : Connect the USB device by enabling the pull-up/pull-down
803 * @param USBx : Selected device
804 * @retval HAL status
805 */
USB_DevConnect(USB_OTG_GlobalTypeDef * USBx)806 HAL_StatusTypeDef USB_DevConnect (USB_OTG_GlobalTypeDef *USBx)
807 {
808 USBx_DEVICE->DCTL &= ~USB_OTG_DCTL_SDIS ;
809 HAL_Delay(3);
810
811 return HAL_OK;
812 }
813
814 /**
815 * @brief USB_DevDisconnect : Disconnect the USB device by disabling the pull-up/pull-down
816 * @param USBx : Selected device
817 * @retval HAL status
818 */
USB_DevDisconnect(USB_OTG_GlobalTypeDef * USBx)819 HAL_StatusTypeDef USB_DevDisconnect (USB_OTG_GlobalTypeDef *USBx)
820 {
821 USBx_DEVICE->DCTL |= USB_OTG_DCTL_SDIS ;
822 HAL_Delay(3);
823
824 return HAL_OK;
825 }
826
827 /**
828 * @brief USB_ReadInterrupts: return the global USB interrupt status
829 * @param USBx : Selected device
830 * @retval HAL status
831 */
USB_ReadInterrupts(USB_OTG_GlobalTypeDef * USBx)832 uint32_t USB_ReadInterrupts (USB_OTG_GlobalTypeDef *USBx)
833 {
834 uint32_t v = 0;
835
836 v = USBx->GINTSTS;
837 v &= USBx->GINTMSK;
838 return v;
839 }
840
841 /**
842 * @brief USB_ReadDevAllOutEpInterrupt: return the USB device OUT endpoints interrupt status
843 * @param USBx : Selected device
844 * @retval HAL status
845 */
USB_ReadDevAllOutEpInterrupt(USB_OTG_GlobalTypeDef * USBx)846 uint32_t USB_ReadDevAllOutEpInterrupt (USB_OTG_GlobalTypeDef *USBx)
847 {
848 uint32_t v;
849 v = USBx_DEVICE->DAINT;
850 v &= USBx_DEVICE->DAINTMSK;
851 return ((v & 0xffff0000) >> 16);
852 }
853
854 /**
855 * @brief USB_ReadDevAllInEpInterrupt: return the USB device IN endpoints interrupt status
856 * @param USBx : Selected device
857 * @retval HAL status
858 */
USB_ReadDevAllInEpInterrupt(USB_OTG_GlobalTypeDef * USBx)859 uint32_t USB_ReadDevAllInEpInterrupt (USB_OTG_GlobalTypeDef *USBx)
860 {
861 uint32_t v;
862 v = USBx_DEVICE->DAINT;
863 v &= USBx_DEVICE->DAINTMSK;
864 return ((v & 0xFFFF));
865 }
866
867 /**
868 * @brief Returns Device OUT EP Interrupt register
869 * @param USBx : Selected device
870 * @param epnum : endpoint number
871 * This parameter can be a value from 0 to 15
872 * @retval Device OUT EP Interrupt register
873 */
USB_ReadDevOutEPInterrupt(USB_OTG_GlobalTypeDef * USBx,uint8_t epnum)874 uint32_t USB_ReadDevOutEPInterrupt (USB_OTG_GlobalTypeDef *USBx , uint8_t epnum)
875 {
876 uint32_t v;
877 v = USBx_OUTEP(epnum)->DOEPINT;
878 v &= USBx_DEVICE->DOEPMSK;
879 return v;
880 }
881
882 /**
883 * @brief Returns Device IN EP Interrupt register
884 * @param USBx : Selected device
885 * @param epnum : endpoint number
886 * This parameter can be a value from 0 to 15
887 * @retval Device IN EP Interrupt register
888 */
USB_ReadDevInEPInterrupt(USB_OTG_GlobalTypeDef * USBx,uint8_t epnum)889 uint32_t USB_ReadDevInEPInterrupt (USB_OTG_GlobalTypeDef *USBx , uint8_t epnum)
890 {
891 uint32_t v, msk, emp;
892
893 msk = USBx_DEVICE->DIEPMSK;
894 emp = USBx_DEVICE->DIEPEMPMSK;
895 msk |= ((emp >> epnum) & 0x1) << 7;
896 v = USBx_INEP(epnum)->DIEPINT & msk;
897 return v;
898 }
899
900 /**
901 * @brief USB_ClearInterrupts: clear a USB interrupt
902 * @param USBx : Selected device
903 * @param interrupt : interrupt flag
904 * @retval None
905 */
USB_ClearInterrupts(USB_OTG_GlobalTypeDef * USBx,uint32_t interrupt)906 void USB_ClearInterrupts (USB_OTG_GlobalTypeDef *USBx, uint32_t interrupt)
907 {
908 USBx->GINTSTS |= interrupt;
909 }
910
911 /**
912 * @brief Returns USB core mode
913 * @param USBx : Selected device
914 * @retval return core mode : Host or Device
915 * This parameter can be one of the these values:
916 * 0 : Host
917 * 1 : Device
918 */
USB_GetMode(USB_OTG_GlobalTypeDef * USBx)919 uint32_t USB_GetMode(USB_OTG_GlobalTypeDef *USBx)
920 {
921 return ((USBx->GINTSTS ) & 0x1);
922 }
923
924
925 /**
926 * @brief Activate EP0 for Setup transactions
927 * @param USBx : Selected device
928 * @retval HAL status
929 */
USB_ActivateSetup(USB_OTG_GlobalTypeDef * USBx)930 HAL_StatusTypeDef USB_ActivateSetup (USB_OTG_GlobalTypeDef *USBx)
931 {
932 /* Set the MPS of the IN EP based on the enumeration speed */
933 USBx_INEP(0)->DIEPCTL &= ~USB_OTG_DIEPCTL_MPSIZ;
934
935 if ((USBx_DEVICE->DSTS & USB_OTG_DSTS_ENUMSPD) == DSTS_ENUMSPD_LS_PHY_6MHZ) {
936 USBx_INEP(0)->DIEPCTL |= 3;
937 }
938 USBx_DEVICE->DCTL |= USB_OTG_DCTL_CGINAK;
939
940 return HAL_OK;
941 }
942
943
944 /**
945 * @brief Prepare the EP0 to start the first control setup
946 * @param USBx : Selected device
947 * @param dma: USB dma enabled or disabled
948 * This parameter can be one of the these values:
949 * 0 : DMA feature not used
950 * 1 : DMA feature used
951 * @param psetup : pointer to setup packet
952 * @retval HAL status
953 */
USB_EP0_OutStart(USB_OTG_GlobalTypeDef * USBx,uint8_t dma,uint8_t * psetup)954 HAL_StatusTypeDef USB_EP0_OutStart(USB_OTG_GlobalTypeDef *USBx, uint8_t dma, uint8_t *psetup)
955 {
956 USBx_OUTEP(0)->DOEPTSIZ = 0;
957 USBx_OUTEP(0)->DOEPTSIZ |= (USB_OTG_DOEPTSIZ_PKTCNT & (1 << 19)) ;
958 USBx_OUTEP(0)->DOEPTSIZ |= (3 * 8);
959 USBx_OUTEP(0)->DOEPTSIZ |= USB_OTG_DOEPTSIZ_STUPCNT;
960
961 if (dma == 1) {
962 USBx_OUTEP(0)->DOEPDMA = (uint32_t)psetup;
963 /* EP enable */
964 USBx_OUTEP(0)->DOEPCTL = 0x80008000;
965 }
966
967 return HAL_OK;
968 }
969
970
971 /**
972 * @brief Reset the USB Core (needed after USB clock settings change)
973 * @param USBx : Selected device
974 * @retval HAL status
975 */
USB_CoreReset(USB_OTG_GlobalTypeDef * USBx)976 static HAL_StatusTypeDef USB_CoreReset(USB_OTG_GlobalTypeDef *USBx)
977 {
978 uint32_t count = 0;
979
980 /* Wait for AHB master IDLE state. */
981 do {
982 if (++count > 200000) {
983 return HAL_TIMEOUT;
984 }
985 } while ((USBx->GRSTCTL & USB_OTG_GRSTCTL_AHBIDL) == 0);
986
987 /* Core Soft Reset */
988 count = 0;
989 USBx->GRSTCTL |= USB_OTG_GRSTCTL_CSRST;
990
991 do {
992 if (++count > 200000) {
993 return HAL_TIMEOUT;
994 }
995 } while ((USBx->GRSTCTL & USB_OTG_GRSTCTL_CSRST) == USB_OTG_GRSTCTL_CSRST);
996
997 return HAL_OK;
998 }
999
1000
1001 /**
1002 * @brief USB_HostInit : Initializes the USB OTG controller registers
1003 * for Host mode
1004 * @param USBx : Selected device
1005 * @param cfg : pointer to a USB_OTG_CfgTypeDef structure that contains
1006 * the configuration information for the specified USBx peripheral.
1007 * @retval HAL status
1008 */
USB_HostInit(USB_OTG_GlobalTypeDef * USBx,USB_OTG_CfgTypeDef cfg)1009 HAL_StatusTypeDef USB_HostInit (USB_OTG_GlobalTypeDef *USBx, USB_OTG_CfgTypeDef cfg)
1010 {
1011 uint32_t i;
1012
1013 /* Restart the Phy Clock */
1014 USBx_PCGCCTL = 0;
1015
1016 /*Activate VBUS Sensing B */
1017 USBx->GCCFG |= USB_OTG_GCCFG_VBDEN;
1018
1019 /* Disable the FS/LS support mode only */
1020 if ((cfg.speed == USB_OTG_SPEED_FULL)&&
1021 (USBx != USB_OTG_FS)) {
1022 USBx_HOST->HCFG |= USB_OTG_HCFG_FSLSS;
1023 } else {
1024 USBx_HOST->HCFG &= ~(USB_OTG_HCFG_FSLSS);
1025 }
1026
1027 /* Make sure the FIFOs are flushed. */
1028 USB_FlushTxFifo(USBx, 0x10 ); /* all Tx FIFOs */
1029 USB_FlushRxFifo(USBx);
1030
1031 /* Clear all pending HC Interrupts */
1032 for (i = 0; i < cfg.Host_channels; i++) {
1033 USBx_HC(i)->HCINT = 0xFFFFFFFF;
1034 USBx_HC(i)->HCINTMSK = 0;
1035 }
1036
1037 /* Enable VBUS driving */
1038 USB_DriveVbus(USBx, 1);
1039
1040 HAL_Delay(200);
1041
1042 /* Disable all interrupts. */
1043 USBx->GINTMSK = 0;
1044
1045 /* Clear any pending interrupts */
1046 USBx->GINTSTS = 0xFFFFFFFF;
1047
1048
1049 if (USBx == USB_OTG_FS) {
1050 /* set Rx FIFO size */
1051 USBx->GRXFSIZ = (uint32_t )0x80;
1052 USBx->DIEPTXF0_HNPTXFSIZ = (uint32_t )(((0x60 << 16)& USB_OTG_NPTXFD) | 0x80);
1053 USBx->HPTXFSIZ = (uint32_t )(((0x40 << 16)& USB_OTG_HPTXFSIZ_PTXFD) | 0xE0);
1054
1055 }
1056
1057 else {
1058 /* set Rx FIFO size */
1059 USBx->GRXFSIZ = (uint32_t )0x200;
1060 USBx->DIEPTXF0_HNPTXFSIZ = (uint32_t )(((0x100 << 16)& USB_OTG_NPTXFD) | 0x200);
1061 USBx->HPTXFSIZ = (uint32_t )(((0xE0 << 16)& USB_OTG_HPTXFSIZ_PTXFD) | 0x300);
1062 }
1063
1064 /* Enable the common interrupts */
1065 if (cfg.dma_enable == DISABLE) {
1066 USBx->GINTMSK |= USB_OTG_GINTMSK_RXFLVLM;
1067 }
1068
1069 /* Enable interrupts matching to the Host mode ONLY */
1070 USBx->GINTMSK |= (USB_OTG_GINTMSK_PRTIM | USB_OTG_GINTMSK_HCIM |\
1071 USB_OTG_GINTMSK_SOFM |USB_OTG_GINTSTS_DISCINT|\
1072 USB_OTG_GINTMSK_PXFRM_IISOOXFRM | USB_OTG_GINTMSK_WUIM);
1073
1074 return HAL_OK;
1075 }
1076
1077 /**
1078 * @brief USB_InitFSLSPClkSel : Initializes the FSLSPClkSel field of the
1079 * HCFG register on the PHY type and set the right frame interval
1080 * @param USBx : Selected device
1081 * @param freq : clock frequency
1082 * This parameter can be one of the these values:
1083 * HCFG_48_MHZ : Full Speed 48 MHz Clock
1084 * HCFG_6_MHZ : Low Speed 6 MHz Clock
1085 * @retval HAL status
1086 */
USB_InitFSLSPClkSel(USB_OTG_GlobalTypeDef * USBx,uint8_t freq)1087 HAL_StatusTypeDef USB_InitFSLSPClkSel(USB_OTG_GlobalTypeDef *USBx , uint8_t freq)
1088 {
1089 USBx_HOST->HCFG &= ~(USB_OTG_HCFG_FSLSPCS);
1090 USBx_HOST->HCFG |= (freq & USB_OTG_HCFG_FSLSPCS);
1091
1092 if (freq == HCFG_48_MHZ) {
1093 USBx_HOST->HFIR = (uint32_t)48000;
1094 } else if (freq == HCFG_6_MHZ) {
1095 USBx_HOST->HFIR = (uint32_t)6000;
1096 }
1097 return HAL_OK;
1098 }
1099
1100 /**
1101 * @brief USB_OTG_ResetPort : Reset Host Port
1102 * @param USBx : Selected device
1103 * @retval HAL status
1104 * @note : (1)The application must wait at least 10 ms
1105 * before clearing the reset bit.
1106 */
USB_ResetPort(USB_OTG_GlobalTypeDef * USBx)1107 HAL_StatusTypeDef USB_ResetPort(USB_OTG_GlobalTypeDef *USBx)
1108 {
1109 __IO uint32_t hprt0;
1110
1111 hprt0 = USBx_HPRT0;
1112
1113 hprt0 &= ~(USB_OTG_HPRT_PENA | USB_OTG_HPRT_PCDET |\
1114 USB_OTG_HPRT_PENCHNG | USB_OTG_HPRT_POCCHNG );
1115
1116 USBx_HPRT0 = (USB_OTG_HPRT_PRST | hprt0);
1117 HAL_Delay (10); /* See Note #1 */
1118 USBx_HPRT0 = ((~USB_OTG_HPRT_PRST) & hprt0);
1119 return HAL_OK;
1120 }
1121
1122 /**
1123 * @brief USB_DriveVbus : activate or de-activate vbus
1124 * @param state : VBUS state
1125 * This parameter can be one of the these values:
1126 * 0 : VBUS Active
1127 * 1 : VBUS Inactive
1128 * @retval HAL status
1129 */
USB_DriveVbus(USB_OTG_GlobalTypeDef * USBx,uint8_t state)1130 HAL_StatusTypeDef USB_DriveVbus (USB_OTG_GlobalTypeDef *USBx, uint8_t state)
1131 {
1132 __IO uint32_t hprt0;
1133
1134 hprt0 = USBx_HPRT0;
1135 hprt0 &= ~(USB_OTG_HPRT_PENA | USB_OTG_HPRT_PCDET |\
1136 USB_OTG_HPRT_PENCHNG | USB_OTG_HPRT_POCCHNG );
1137
1138 if (((hprt0 & USB_OTG_HPRT_PPWR) == 0 ) && (state == 1 )) {
1139 USBx_HPRT0 = (USB_OTG_HPRT_PPWR | hprt0);
1140 }
1141 if (((hprt0 & USB_OTG_HPRT_PPWR) == USB_OTG_HPRT_PPWR) && (state == 0 )) {
1142 USBx_HPRT0 = ((~USB_OTG_HPRT_PPWR) & hprt0);
1143 }
1144 return HAL_OK;
1145 }
1146
1147 /**
1148 * @brief Return Host Core speed
1149 * @param USBx : Selected device
1150 * @retval speed : Host speed
1151 * This parameter can be one of the these values:
1152 * @arg USB_OTG_SPEED_HIGH: High speed mode
1153 * @arg USB_OTG_SPEED_FULL: Full speed mode
1154 * @arg USB_OTG_SPEED_LOW: Low speed mode
1155 */
USB_GetHostSpeed(USB_OTG_GlobalTypeDef * USBx)1156 uint32_t USB_GetHostSpeed (USB_OTG_GlobalTypeDef *USBx)
1157 {
1158 __IO uint32_t hprt0;
1159
1160 hprt0 = USBx_HPRT0;
1161 return ((hprt0 & USB_OTG_HPRT_PSPD) >> 17);
1162 }
1163
1164 /**
1165 * @brief Return Host Current Frame number
1166 * @param USBx : Selected device
1167 * @retval current frame number
1168 */
USB_GetCurrentFrame(USB_OTG_GlobalTypeDef * USBx)1169 uint32_t USB_GetCurrentFrame (USB_OTG_GlobalTypeDef *USBx)
1170 {
1171 return (USBx_HOST->HFNUM & USB_OTG_HFNUM_FRNUM);
1172 }
1173
1174 /**
1175 * @brief Initialize a host channel
1176 * @param USBx : Selected device
1177 * @param ch_num : Channel number
1178 * This parameter can be a value from 1 to 15
1179 * @param epnum : Endpoint number
1180 * This parameter can be a value from 1 to 15
1181 * @param dev_address : Current device address
1182 * This parameter can be a value from 0 to 255
1183 * @param speed : Current device speed
1184 * This parameter can be one of the these values:
1185 * @arg USB_OTG_SPEED_HIGH: High speed mode
1186 * @arg USB_OTG_SPEED_FULL: Full speed mode
1187 * @arg USB_OTG_SPEED_LOW: Low speed mode
1188 * @param ep_type : Endpoint Type
1189 * This parameter can be one of the these values:
1190 * @arg EP_TYPE_CTRL: Control type
1191 * @arg EP_TYPE_ISOC: Isochronous type
1192 * @arg EP_TYPE_BULK: Bulk type
1193 * @arg EP_TYPE_INTR: Interrupt type
1194 * @param mps : Max Packet Size
1195 * This parameter can be a value from 0 to32K
1196 * @retval HAL state
1197 */
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)1198 HAL_StatusTypeDef USB_HC_Init(USB_OTG_GlobalTypeDef *USBx,
1199 uint8_t ch_num,
1200 uint8_t epnum,
1201 uint8_t dev_address,
1202 uint8_t speed,
1203 uint8_t ep_type,
1204 uint16_t mps)
1205 {
1206
1207 /* Clear old interrupt conditions for this host channel. */
1208 USBx_HC(ch_num)->HCINT = 0xFFFFFFFF;
1209
1210 /* Enable channel interrupts required for this transfer. */
1211 switch (ep_type) {
1212 case EP_TYPE_CTRL:
1213 case EP_TYPE_BULK:
1214
1215 USBx_HC(ch_num)->HCINTMSK = USB_OTG_HCINTMSK_XFRCM |\
1216 USB_OTG_HCINTMSK_STALLM |\
1217 USB_OTG_HCINTMSK_TXERRM |\
1218 USB_OTG_HCINTMSK_DTERRM |\
1219 USB_OTG_HCINTMSK_AHBERR |\
1220 USB_OTG_HCINTMSK_NAKM ;
1221
1222 if (epnum & 0x80) {
1223 USBx_HC(ch_num)->HCINTMSK |= USB_OTG_HCINTMSK_BBERRM;
1224 } else {
1225 if (USBx != USB_OTG_FS) {
1226 USBx_HC(ch_num)->HCINTMSK |= (USB_OTG_HCINTMSK_NYET | USB_OTG_HCINTMSK_ACKM);
1227 }
1228 }
1229 break;
1230 case EP_TYPE_INTR:
1231
1232 USBx_HC(ch_num)->HCINTMSK = USB_OTG_HCINTMSK_XFRCM |\
1233 USB_OTG_HCINTMSK_STALLM |\
1234 USB_OTG_HCINTMSK_TXERRM |\
1235 USB_OTG_HCINTMSK_DTERRM |\
1236 USB_OTG_HCINTMSK_NAKM |\
1237 USB_OTG_HCINTMSK_AHBERR |\
1238 USB_OTG_HCINTMSK_FRMORM ;
1239
1240 if (epnum & 0x80) {
1241 USBx_HC(ch_num)->HCINTMSK |= USB_OTG_HCINTMSK_BBERRM;
1242 }
1243
1244 break;
1245 case EP_TYPE_ISOC:
1246
1247 USBx_HC(ch_num)->HCINTMSK = USB_OTG_HCINTMSK_XFRCM |\
1248 USB_OTG_HCINTMSK_ACKM |\
1249 USB_OTG_HCINTMSK_AHBERR |\
1250 USB_OTG_HCINTMSK_FRMORM ;
1251
1252 if (epnum & 0x80) {
1253 USBx_HC(ch_num)->HCINTMSK |= (USB_OTG_HCINTMSK_TXERRM | USB_OTG_HCINTMSK_BBERRM);
1254 }
1255 break;
1256 }
1257
1258 /* Enable the top level host channel interrupt. */
1259 USBx_HOST->HAINTMSK |= (1 << ch_num);
1260
1261 /* Make sure host channel interrupts are enabled. */
1262 USBx->GINTMSK |= USB_OTG_GINTMSK_HCIM;
1263
1264 /* Program the HCCHAR register */
1265 USBx_HC(ch_num)->HCCHAR = (((dev_address << 22) & USB_OTG_HCCHAR_DAD) |\
1266 (((epnum & 0x7F)<< 11) & USB_OTG_HCCHAR_EPNUM)|\
1267 ((((epnum & 0x80) == 0x80)<< 15) & USB_OTG_HCCHAR_EPDIR)|\
1268 (((speed == HPRT0_PRTSPD_LOW_SPEED)<< 17) & USB_OTG_HCCHAR_LSDEV)|\
1269 ((ep_type << 18) & USB_OTG_HCCHAR_EPTYP)|\
1270 (mps & USB_OTG_HCCHAR_MPSIZ));
1271
1272 if (ep_type == EP_TYPE_INTR) {
1273 USBx_HC(ch_num)->HCCHAR |= USB_OTG_HCCHAR_ODDFRM ;
1274 }
1275
1276 return HAL_OK;
1277 }
1278
1279 /**
1280 * @brief Start a transfer over a host channel
1281 * @param USBx : Selected device
1282 * @param hc : pointer to host channel structure
1283 * @param dma: USB dma enabled or disabled
1284 * This parameter can be one of the these values:
1285 * 0 : DMA feature not used
1286 * 1 : DMA feature used
1287 * @retval HAL state
1288 */
1289 #if defined (__CC_ARM) /*!< ARM Compiler */
1290 #pragma O0
1291 #elif defined (__GNUC__) /*!< GNU Compiler */
1292 #pragma GCC optimize ("O0")
1293 #endif /* __CC_ARM */
USB_HC_StartXfer(USB_OTG_GlobalTypeDef * USBx,USB_OTG_HCTypeDef * hc,uint8_t dma)1294 HAL_StatusTypeDef USB_HC_StartXfer(USB_OTG_GlobalTypeDef *USBx, USB_OTG_HCTypeDef *hc, uint8_t dma)
1295 {
1296 uint8_t is_oddframe = 0;
1297 uint16_t len_words = 0;
1298 uint16_t num_packets = 0;
1299 uint16_t max_hc_pkt_count = 256;
1300 uint32_t tmpreg = 0;
1301
1302 if ((USBx != USB_OTG_FS) && (hc->speed == USB_OTG_SPEED_HIGH)) {
1303 if ((dma == 0) && (hc->do_ping == 1)) {
1304 USB_DoPing(USBx, hc->ch_num);
1305 return HAL_OK;
1306 } else if (dma == 1) {
1307 USBx_HC(hc->ch_num)->HCINTMSK &= ~(USB_OTG_HCINTMSK_NYET | USB_OTG_HCINTMSK_ACKM);
1308 hc->do_ping = 0;
1309 }
1310 }
1311
1312 /* Compute the expected number of packets associated to the transfer */
1313 if (hc->xfer_len > 0) {
1314 num_packets = (hc->xfer_len + hc->max_packet - 1) / hc->max_packet;
1315
1316 if (num_packets > max_hc_pkt_count) {
1317 num_packets = max_hc_pkt_count;
1318 hc->xfer_len = num_packets * hc->max_packet;
1319 }
1320 } else {
1321 num_packets = 1;
1322 }
1323 if (hc->ep_is_in) {
1324 hc->xfer_len = num_packets * hc->max_packet;
1325 }
1326
1327
1328
1329 /* Initialize the HCTSIZn register */
1330 USBx_HC(hc->ch_num)->HCTSIZ = (((hc->xfer_len) & USB_OTG_HCTSIZ_XFRSIZ)) |\
1331 ((num_packets << 19) & USB_OTG_HCTSIZ_PKTCNT) |\
1332 (((hc->data_pid) << 29) & USB_OTG_HCTSIZ_DPID);
1333
1334 if (dma) {
1335 /* xfer_buff MUST be 32-bits aligned */
1336 USBx_HC(hc->ch_num)->HCDMA = (uint32_t)hc->xfer_buff;
1337 }
1338
1339 is_oddframe = (USBx_HOST->HFNUM & 0x01) ? 0 : 1;
1340 USBx_HC(hc->ch_num)->HCCHAR &= ~USB_OTG_HCCHAR_ODDFRM;
1341 USBx_HC(hc->ch_num)->HCCHAR |= (is_oddframe << 29);
1342
1343 /* Set host channel enable */
1344 tmpreg = USBx_HC(hc->ch_num)->HCCHAR;
1345 tmpreg &= ~USB_OTG_HCCHAR_CHDIS;
1346 tmpreg |= USB_OTG_HCCHAR_CHENA;
1347 USBx_HC(hc->ch_num)->HCCHAR = tmpreg;
1348
1349 if (dma == 0) { /* Slave mode */
1350 if ((hc->ep_is_in == 0) && (hc->xfer_len > 0)) {
1351 switch (hc->ep_type) {
1352 /* Non periodic transfer */
1353 case EP_TYPE_CTRL:
1354 case EP_TYPE_BULK:
1355
1356 len_words = (hc->xfer_len + 3) / 4;
1357
1358 /* check if there is enough space in FIFO space */
1359 if (len_words > (USBx->HNPTXSTS & 0xFFFF)) {
1360 /* need to process data in nptxfempty interrupt */
1361 USBx->GINTMSK |= USB_OTG_GINTMSK_NPTXFEM;
1362 }
1363 break;
1364 /* Periodic transfer */
1365 case EP_TYPE_INTR:
1366 case EP_TYPE_ISOC:
1367 len_words = (hc->xfer_len + 3) / 4;
1368 /* check if there is enough space in FIFO space */
1369 if (len_words > (USBx_HOST->HPTXSTS & 0xFFFF)) { /* split the transfer */
1370 /* need to process data in ptxfempty interrupt */
1371 USBx->GINTMSK |= USB_OTG_GINTMSK_PTXFEM;
1372 }
1373 break;
1374
1375 default:
1376 break;
1377 }
1378
1379 /* Write packet into the Tx FIFO. */
1380 USB_WritePacket(USBx, hc->xfer_buff, hc->ch_num, hc->xfer_len, 0);
1381 }
1382 }
1383
1384 return HAL_OK;
1385 }
1386
1387 /**
1388 * @brief Read all host channel interrupts status
1389 * @param USBx : Selected device
1390 * @retval HAL state
1391 */
USB_HC_ReadInterrupt(USB_OTG_GlobalTypeDef * USBx)1392 uint32_t USB_HC_ReadInterrupt (USB_OTG_GlobalTypeDef *USBx)
1393 {
1394 return ((USBx_HOST->HAINT) & 0xFFFF);
1395 }
1396
1397 /**
1398 * @brief Halt a host channel
1399 * @param USBx : Selected device
1400 * @param hc_num : Host Channel number
1401 * This parameter can be a value from 1 to 15
1402 * @retval HAL state
1403 */
USB_HC_Halt(USB_OTG_GlobalTypeDef * USBx,uint8_t hc_num)1404 HAL_StatusTypeDef USB_HC_Halt(USB_OTG_GlobalTypeDef *USBx , uint8_t hc_num)
1405 {
1406 uint32_t count = 0;
1407
1408 /* Check for space in the request queue to issue the halt. */
1409 if (((USBx_HC(hc_num)->HCCHAR) & (HCCHAR_CTRL << 18)) || ((USBx_HC(hc_num)->HCCHAR) & (HCCHAR_BULK << 18))) {
1410 USBx_HC(hc_num)->HCCHAR |= USB_OTG_HCCHAR_CHDIS;
1411
1412 if ((USBx->HNPTXSTS & 0xFFFF) == 0) {
1413 USBx_HC(hc_num)->HCCHAR &= ~USB_OTG_HCCHAR_CHENA;
1414 USBx_HC(hc_num)->HCCHAR |= USB_OTG_HCCHAR_CHENA;
1415 USBx_HC(hc_num)->HCCHAR &= ~USB_OTG_HCCHAR_EPDIR;
1416 do {
1417 if (++count > 1000) {
1418 break;
1419 }
1420 } while ((USBx_HC(hc_num)->HCCHAR & USB_OTG_HCCHAR_CHENA) == USB_OTG_HCCHAR_CHENA);
1421 } else {
1422 USBx_HC(hc_num)->HCCHAR |= USB_OTG_HCCHAR_CHENA;
1423 }
1424 } else {
1425 USBx_HC(hc_num)->HCCHAR |= USB_OTG_HCCHAR_CHDIS;
1426
1427 if ((USBx_HOST->HPTXSTS & 0xFFFF) == 0) {
1428 USBx_HC(hc_num)->HCCHAR &= ~USB_OTG_HCCHAR_CHENA;
1429 USBx_HC(hc_num)->HCCHAR |= USB_OTG_HCCHAR_CHENA;
1430 USBx_HC(hc_num)->HCCHAR &= ~USB_OTG_HCCHAR_EPDIR;
1431 do {
1432 if (++count > 1000) {
1433 break;
1434 }
1435 } while ((USBx_HC(hc_num)->HCCHAR & USB_OTG_HCCHAR_CHENA) == USB_OTG_HCCHAR_CHENA);
1436 } else {
1437 USBx_HC(hc_num)->HCCHAR |= USB_OTG_HCCHAR_CHENA;
1438 }
1439 }
1440
1441 return HAL_OK;
1442 }
1443
1444 /**
1445 * @brief Initiate Do Ping protocol
1446 * @param USBx : Selected device
1447 * @param hc_num : Host Channel number
1448 * This parameter can be a value from 1 to 15
1449 * @retval HAL state
1450 */
USB_DoPing(USB_OTG_GlobalTypeDef * USBx,uint8_t ch_num)1451 HAL_StatusTypeDef USB_DoPing(USB_OTG_GlobalTypeDef *USBx , uint8_t ch_num)
1452 {
1453 uint8_t num_packets = 1;
1454 uint32_t tmpreg = 0;
1455
1456 USBx_HC(ch_num)->HCTSIZ = ((num_packets << 19) & USB_OTG_HCTSIZ_PKTCNT) |\
1457 USB_OTG_HCTSIZ_DOPING;
1458
1459 /* Set host channel enable */
1460 tmpreg = USBx_HC(ch_num)->HCCHAR;
1461 tmpreg &= ~USB_OTG_HCCHAR_CHDIS;
1462 tmpreg |= USB_OTG_HCCHAR_CHENA;
1463 USBx_HC(ch_num)->HCCHAR = tmpreg;
1464
1465 return HAL_OK;
1466 }
1467
1468 /**
1469 * @brief Stop Host Core
1470 * @param USBx : Selected device
1471 * @retval HAL state
1472 */
USB_StopHost(USB_OTG_GlobalTypeDef * USBx)1473 HAL_StatusTypeDef USB_StopHost(USB_OTG_GlobalTypeDef *USBx)
1474 {
1475 uint8_t i;
1476 uint32_t count = 0;
1477 uint32_t value;
1478
1479 USB_DisableGlobalInt(USBx);
1480
1481 /* Flush FIFO */
1482 USB_FlushTxFifo(USBx, 0x10);
1483 USB_FlushRxFifo(USBx);
1484
1485 /* Flush out any leftover queued requests. */
1486 for (i = 0; i <= 15; i++) {
1487
1488 value = USBx_HC(i)->HCCHAR ;
1489 value |= USB_OTG_HCCHAR_CHDIS;
1490 value &= ~USB_OTG_HCCHAR_CHENA;
1491 value &= ~USB_OTG_HCCHAR_EPDIR;
1492 USBx_HC(i)->HCCHAR = value;
1493 }
1494
1495 /* Halt all channels to put them into a known state. */
1496 for (i = 0; i <= 15; i++) {
1497
1498 value = USBx_HC(i)->HCCHAR ;
1499
1500 value |= USB_OTG_HCCHAR_CHDIS;
1501 value |= USB_OTG_HCCHAR_CHENA;
1502 value &= ~USB_OTG_HCCHAR_EPDIR;
1503
1504 USBx_HC(i)->HCCHAR = value;
1505 do {
1506 if (++count > 1000) {
1507 break;
1508 }
1509 } while ((USBx_HC(i)->HCCHAR & USB_OTG_HCCHAR_CHENA) == USB_OTG_HCCHAR_CHENA);
1510 }
1511
1512 /* Clear any pending Host interrupts */
1513 USBx_HOST->HAINT = 0xFFFFFFFF;
1514 USBx->GINTSTS = 0xFFFFFFFF;
1515 USB_EnableGlobalInt(USBx);
1516 return HAL_OK;
1517 }
1518 /**
1519 * @}
1520 */
1521
1522 #endif /* defined (HAL_PCD_MODULE_ENABLED) || defined (HAL_HCD_MODULE_ENABLED) */
1523
1524 /**
1525 * @}
1526 */
1527
1528 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
1529