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