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