Mercurial > public > ostc4
comparison Common/Drivers/STM32F4xx_HAL_DRIVER_v120/Src/stm32f4xx_hal_pcd.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_hal_pcd.c | |
4 * @author MCD Application Team | |
5 * @version V1.2.0 | |
6 * @date 26-December-2014 | |
7 * @brief PCD HAL module driver. | |
8 * This file provides firmware functions to manage the following | |
9 * functionalities of the USB Peripheral Controller: | |
10 * + Initialization and de-initialization functions | |
11 * + IO operation functions | |
12 * + Peripheral Control functions | |
13 * + Peripheral State functions | |
14 * | |
15 @verbatim | |
16 ============================================================================== | |
17 ##### How to use this driver ##### | |
18 ============================================================================== | |
19 [..] | |
20 The PCD HAL driver can be used as follows: | |
21 | |
22 (#) Declare a PCD_HandleTypeDef handle structure, for example: | |
23 PCD_HandleTypeDef hpcd; | |
24 | |
25 (#) Fill parameters of Init structure in HCD handle | |
26 | |
27 (#) Call HAL_PCD_Init() API to initialize the HCD peripheral (Core, Device core, ...) | |
28 | |
29 (#) Initialize the PCD low level resources through the HAL_PCD_MspInit() API: | |
30 (##) Enable the PCD/USB Low Level interface clock using | |
31 (+++) __OTGFS-OTG_CLK_ENABLE()/__OTGHS-OTG_CLK_ENABLE(); | |
32 (+++) __OTGHSULPI_CLK_ENABLE(); (For High Speed Mode) | |
33 | |
34 (##) Initialize the related GPIO clocks | |
35 (##) Configure PCD pin-out | |
36 (##) Configure PCD NVIC interrupt | |
37 | |
38 (#)Associate the Upper USB device stack to the HAL PCD Driver: | |
39 (##) hpcd.pData = pdev; | |
40 | |
41 (#)Enable HCD transmission and reception: | |
42 (##) HAL_PCD_Start(); | |
43 | |
44 @endverbatim | |
45 ****************************************************************************** | |
46 * @attention | |
47 * | |
48 * <h2><center>© COPYRIGHT(c) 2014 STMicroelectronics</center></h2> | |
49 * | |
50 * Redistribution and use in source and binary forms, with or without modification, | |
51 * are permitted provided that the following conditions are met: | |
52 * 1. Redistributions of source code must retain the above copyright notice, | |
53 * this list of conditions and the following disclaimer. | |
54 * 2. Redistributions in binary form must reproduce the above copyright notice, | |
55 * this list of conditions and the following disclaimer in the documentation | |
56 * and/or other materials provided with the distribution. | |
57 * 3. Neither the name of STMicroelectronics nor the names of its contributors | |
58 * may be used to endorse or promote products derived from this software | |
59 * without specific prior written permission. | |
60 * | |
61 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | |
62 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |
63 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | |
64 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE | |
65 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | |
66 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR | |
67 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER | |
68 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, | |
69 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | |
70 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
71 * | |
72 ****************************************************************************** | |
73 */ | |
74 | |
75 /* Includes ------------------------------------------------------------------*/ | |
76 #include "stm32f4xx_hal.h" | |
77 | |
78 /** @addtogroup STM32F4xx_HAL_Driver | |
79 * @{ | |
80 */ | |
81 | |
82 /** @defgroup PCD PCD | |
83 * @brief PCD HAL module driver | |
84 * @{ | |
85 */ | |
86 | |
87 #ifdef HAL_PCD_MODULE_ENABLED | |
88 | |
89 /* Private types -------------------------------------------------------------*/ | |
90 /* Private variables ---------------------------------------------------------*/ | |
91 /* Private constants ---------------------------------------------------------*/ | |
92 /* Private macros ------------------------------------------------------------*/ | |
93 /** @defgroup PCD_Private_Macros PCD Private Macros | |
94 * @{ | |
95 */ | |
96 #define PCD_MIN(a, b) (((a) < (b)) ? (a) : (b)) | |
97 #define PCD_MAX(a, b) (((a) > (b)) ? (a) : (b)) | |
98 /** | |
99 * @} | |
100 */ | |
101 | |
102 /* Private functions prototypes ----------------------------------------------*/ | |
103 /** @defgroup PCD_Private_Functions PCD Private Functions | |
104 * @{ | |
105 */ | |
106 static HAL_StatusTypeDef PCD_WriteEmptyTxFifo(PCD_HandleTypeDef *hpcd, uint32_t epnum); | |
107 /** | |
108 * @} | |
109 */ | |
110 | |
111 /* Exported functions --------------------------------------------------------*/ | |
112 /** @defgroup PCD_Exported_Functions PCD Exported Functions | |
113 * @{ | |
114 */ | |
115 | |
116 /** @defgroup PCD_Exported_Functions_Group1 Initialization and de-initialization functions | |
117 * @brief Initialization and Configuration functions | |
118 * | |
119 @verbatim | |
120 =============================================================================== | |
121 ##### Initialization and de-initialization functions ##### | |
122 =============================================================================== | |
123 [..] This section provides functions allowing to: | |
124 | |
125 @endverbatim | |
126 * @{ | |
127 */ | |
128 | |
129 /** | |
130 * @brief Initializes the PCD according to the specified | |
131 * parameters in the PCD_InitTypeDef and create the associated handle. | |
132 * @param hpcd: PCD handle | |
133 * @retval HAL status | |
134 */ | |
135 HAL_StatusTypeDef HAL_PCD_Init(PCD_HandleTypeDef *hpcd) | |
136 { | |
137 uint32_t i = 0; | |
138 | |
139 /* Check the PCD handle allocation */ | |
140 if(hpcd == NULL) | |
141 { | |
142 return HAL_ERROR; | |
143 } | |
144 | |
145 /* Check the parameters */ | |
146 assert_param(IS_PCD_ALL_INSTANCE(hpcd->Instance)); | |
147 | |
148 hpcd->State = HAL_PCD_STATE_BUSY; | |
149 | |
150 /* Init the low level hardware : GPIO, CLOCK, NVIC... */ | |
151 HAL_PCD_MspInit(hpcd); | |
152 | |
153 /* Disable the Interrupts */ | |
154 __HAL_PCD_DISABLE(hpcd); | |
155 | |
156 /*Init the Core (common init.) */ | |
157 USB_CoreInit(hpcd->Instance, hpcd->Init); | |
158 | |
159 /* Force Device Mode*/ | |
160 USB_SetCurrentMode(hpcd->Instance , USB_OTG_DEVICE_MODE); | |
161 | |
162 /* Init endpoints structures */ | |
163 for (i = 0; i < 15 ; i++) | |
164 { | |
165 /* Init ep structure */ | |
166 hpcd->IN_ep[i].is_in = 1; | |
167 hpcd->IN_ep[i].num = i; | |
168 hpcd->IN_ep[i].tx_fifo_num = i; | |
169 /* Control until ep is activated */ | |
170 hpcd->IN_ep[i].type = EP_TYPE_CTRL; | |
171 hpcd->IN_ep[i].maxpacket = 0; | |
172 hpcd->IN_ep[i].xfer_buff = 0; | |
173 hpcd->IN_ep[i].xfer_len = 0; | |
174 } | |
175 | |
176 for (i = 0; i < 15 ; i++) | |
177 { | |
178 hpcd->OUT_ep[i].is_in = 0; | |
179 hpcd->OUT_ep[i].num = i; | |
180 hpcd->IN_ep[i].tx_fifo_num = i; | |
181 /* Control until ep is activated */ | |
182 hpcd->OUT_ep[i].type = EP_TYPE_CTRL; | |
183 hpcd->OUT_ep[i].maxpacket = 0; | |
184 hpcd->OUT_ep[i].xfer_buff = 0; | |
185 hpcd->OUT_ep[i].xfer_len = 0; | |
186 | |
187 hpcd->Instance->DIEPTXF[i] = 0; | |
188 } | |
189 | |
190 /* Init Device */ | |
191 USB_DevInit(hpcd->Instance, hpcd->Init); | |
192 | |
193 hpcd->State= HAL_PCD_STATE_READY; | |
194 | |
195 USB_DevDisconnect (hpcd->Instance); | |
196 return HAL_OK; | |
197 } | |
198 | |
199 /** | |
200 * @brief DeInitializes the PCD peripheral | |
201 * @param hpcd: PCD handle | |
202 * @retval HAL status | |
203 */ | |
204 HAL_StatusTypeDef HAL_PCD_DeInit(PCD_HandleTypeDef *hpcd) | |
205 { | |
206 /* Check the PCD handle allocation */ | |
207 if(hpcd == NULL) | |
208 { | |
209 return HAL_ERROR; | |
210 } | |
211 | |
212 hpcd->State = HAL_PCD_STATE_BUSY; | |
213 | |
214 /* Stop Device */ | |
215 HAL_PCD_Stop(hpcd); | |
216 | |
217 /* DeInit the low level hardware */ | |
218 HAL_PCD_MspDeInit(hpcd); | |
219 | |
220 hpcd->State = HAL_PCD_STATE_RESET; | |
221 | |
222 return HAL_OK; | |
223 } | |
224 | |
225 /** | |
226 * @brief Initializes the PCD MSP. | |
227 * @param hpcd: PCD handle | |
228 * @retval None | |
229 */ | |
230 __weak void HAL_PCD_MspInit(PCD_HandleTypeDef *hpcd) | |
231 { | |
232 /* NOTE : This function Should not be modified, when the callback is needed, | |
233 the HAL_PCD_MspInit could be implemented in the user file | |
234 */ | |
235 } | |
236 | |
237 /** | |
238 * @brief DeInitializes PCD MSP. | |
239 * @param hpcd: PCD handle | |
240 * @retval None | |
241 */ | |
242 __weak void HAL_PCD_MspDeInit(PCD_HandleTypeDef *hpcd) | |
243 { | |
244 /* NOTE : This function Should not be modified, when the callback is needed, | |
245 the HAL_PCD_MspDeInit could be implemented in the user file | |
246 */ | |
247 } | |
248 | |
249 /** | |
250 * @} | |
251 */ | |
252 | |
253 /** @defgroup PCD_Exported_Functions_Group2 IO operation functions | |
254 * @brief Data transfers functions | |
255 * | |
256 @verbatim | |
257 =============================================================================== | |
258 ##### IO operation functions ##### | |
259 =============================================================================== | |
260 [..] | |
261 This subsection provides a set of functions allowing to manage the PCD data | |
262 transfers. | |
263 | |
264 @endverbatim | |
265 * @{ | |
266 */ | |
267 | |
268 /** | |
269 * @brief Start The USB OTG Device. | |
270 * @param hpcd: PCD handle | |
271 * @retval HAL status | |
272 */ | |
273 HAL_StatusTypeDef HAL_PCD_Start(PCD_HandleTypeDef *hpcd) | |
274 { | |
275 __HAL_LOCK(hpcd); | |
276 USB_DevConnect (hpcd->Instance); | |
277 __HAL_PCD_ENABLE(hpcd); | |
278 __HAL_UNLOCK(hpcd); | |
279 return HAL_OK; | |
280 } | |
281 | |
282 /** | |
283 * @brief Stop The USB OTG Device. | |
284 * @param hpcd: PCD handle | |
285 * @retval HAL status | |
286 */ | |
287 HAL_StatusTypeDef HAL_PCD_Stop(PCD_HandleTypeDef *hpcd) | |
288 { | |
289 __HAL_LOCK(hpcd); | |
290 __HAL_PCD_DISABLE(hpcd); | |
291 USB_StopDevice(hpcd->Instance); | |
292 USB_DevDisconnect(hpcd->Instance); | |
293 __HAL_UNLOCK(hpcd); | |
294 return HAL_OK; | |
295 } | |
296 | |
297 /** | |
298 * @brief This function handles PCD interrupt request. | |
299 * @param hpcd: PCD handle | |
300 * @retval HAL status | |
301 */ | |
302 void HAL_PCD_IRQHandler(PCD_HandleTypeDef *hpcd) | |
303 { | |
304 USB_OTG_GlobalTypeDef *USBx = hpcd->Instance; | |
305 uint32_t i = 0, ep_intr = 0, epint = 0, epnum = 0; | |
306 uint32_t fifoemptymsk = 0, temp = 0; | |
307 USB_OTG_EPTypeDef *ep; | |
308 | |
309 /* ensure that we are in device mode */ | |
310 if (USB_GetMode(hpcd->Instance) == USB_OTG_MODE_DEVICE) | |
311 { | |
312 /* avoid spurious interrupt */ | |
313 if(__HAL_PCD_IS_INVALID_INTERRUPT(hpcd)) | |
314 { | |
315 return; | |
316 } | |
317 | |
318 if(__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_MMIS)) | |
319 { | |
320 /* incorrect mode, acknowledge the interrupt */ | |
321 __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_MMIS); | |
322 } | |
323 | |
324 if(__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_OEPINT)) | |
325 { | |
326 epnum = 0; | |
327 | |
328 /* Read in the device interrupt bits */ | |
329 ep_intr = USB_ReadDevAllOutEpInterrupt(hpcd->Instance); | |
330 | |
331 while ( ep_intr ) | |
332 { | |
333 if (ep_intr & 0x1) | |
334 { | |
335 epint = USB_ReadDevOutEPInterrupt(hpcd->Instance, epnum); | |
336 | |
337 if(( epint & USB_OTG_DOEPINT_XFRC) == USB_OTG_DOEPINT_XFRC) | |
338 { | |
339 CLEAR_OUT_EP_INTR(epnum, USB_OTG_DOEPINT_XFRC); | |
340 | |
341 if(hpcd->Init.dma_enable == 1) | |
342 { | |
343 hpcd->OUT_ep[epnum].xfer_count = hpcd->OUT_ep[epnum].maxpacket- (USBx_OUTEP(epnum)->DOEPTSIZ & USB_OTG_DOEPTSIZ_XFRSIZ); | |
344 hpcd->OUT_ep[epnum].xfer_buff += hpcd->OUT_ep[epnum].maxpacket; | |
345 } | |
346 | |
347 HAL_PCD_DataOutStageCallback(hpcd, epnum); | |
348 if(hpcd->Init.dma_enable == 1) | |
349 { | |
350 if((epnum == 0) && (hpcd->OUT_ep[epnum].xfer_len == 0)) | |
351 { | |
352 /* this is ZLP, so prepare EP0 for next setup */ | |
353 USB_EP0_OutStart(hpcd->Instance, 1, (uint8_t *)hpcd->Setup); | |
354 } | |
355 } | |
356 } | |
357 | |
358 if(( epint & USB_OTG_DOEPINT_STUP) == USB_OTG_DOEPINT_STUP) | |
359 { | |
360 /* Inform the upper layer that a setup packet is available */ | |
361 HAL_PCD_SetupStageCallback(hpcd); | |
362 CLEAR_OUT_EP_INTR(epnum, USB_OTG_DOEPINT_STUP); | |
363 } | |
364 | |
365 if(( epint & USB_OTG_DOEPINT_OTEPDIS) == USB_OTG_DOEPINT_OTEPDIS) | |
366 { | |
367 CLEAR_OUT_EP_INTR(epnum, USB_OTG_DOEPINT_OTEPDIS); | |
368 } | |
369 } | |
370 epnum++; | |
371 ep_intr >>= 1; | |
372 } | |
373 } | |
374 | |
375 if(__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_IEPINT)) | |
376 { | |
377 /* Read in the device interrupt bits */ | |
378 ep_intr = USB_ReadDevAllInEpInterrupt(hpcd->Instance); | |
379 | |
380 epnum = 0; | |
381 | |
382 while ( ep_intr ) | |
383 { | |
384 if (ep_intr & 0x1) /* In ITR */ | |
385 { | |
386 epint = USB_ReadDevInEPInterrupt(hpcd->Instance, epnum); | |
387 | |
388 if(( epint & USB_OTG_DIEPINT_XFRC) == USB_OTG_DIEPINT_XFRC) | |
389 { | |
390 fifoemptymsk = 0x1 << epnum; | |
391 USBx_DEVICE->DIEPEMPMSK &= ~fifoemptymsk; | |
392 | |
393 CLEAR_IN_EP_INTR(epnum, USB_OTG_DIEPINT_XFRC); | |
394 | |
395 if (hpcd->Init.dma_enable == 1) | |
396 { | |
397 hpcd->IN_ep[epnum].xfer_buff += hpcd->IN_ep[epnum].maxpacket; | |
398 } | |
399 | |
400 HAL_PCD_DataInStageCallback(hpcd, epnum); | |
401 | |
402 if (hpcd->Init.dma_enable == 1) | |
403 { | |
404 /* this is ZLP, so prepare EP0 for next setup */ | |
405 if((epnum == 0) && (hpcd->IN_ep[epnum].xfer_len == 0)) | |
406 { | |
407 /* prepare to rx more setup packets */ | |
408 USB_EP0_OutStart(hpcd->Instance, 1, (uint8_t *)hpcd->Setup); | |
409 } | |
410 } | |
411 } | |
412 if(( epint & USB_OTG_DIEPINT_TOC) == USB_OTG_DIEPINT_TOC) | |
413 { | |
414 CLEAR_IN_EP_INTR(epnum, USB_OTG_DIEPINT_TOC); | |
415 } | |
416 if(( epint & USB_OTG_DIEPINT_ITTXFE) == USB_OTG_DIEPINT_ITTXFE) | |
417 { | |
418 CLEAR_IN_EP_INTR(epnum, USB_OTG_DIEPINT_ITTXFE); | |
419 } | |
420 if(( epint & USB_OTG_DIEPINT_INEPNE) == USB_OTG_DIEPINT_INEPNE) | |
421 { | |
422 CLEAR_IN_EP_INTR(epnum, USB_OTG_DIEPINT_INEPNE); | |
423 } | |
424 if(( epint & USB_OTG_DIEPINT_EPDISD) == USB_OTG_DIEPINT_EPDISD) | |
425 { | |
426 CLEAR_IN_EP_INTR(epnum, USB_OTG_DIEPINT_EPDISD); | |
427 } | |
428 if(( epint & USB_OTG_DIEPINT_TXFE) == USB_OTG_DIEPINT_TXFE) | |
429 { | |
430 PCD_WriteEmptyTxFifo(hpcd , epnum); | |
431 } | |
432 } | |
433 epnum++; | |
434 ep_intr >>= 1; | |
435 } | |
436 } | |
437 | |
438 /* Handle Resume Interrupt */ | |
439 if(__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_WKUINT)) | |
440 { | |
441 /* Clear the Remote Wake-up Signaling */ | |
442 USBx_DEVICE->DCTL &= ~USB_OTG_DCTL_RWUSIG; | |
443 | |
444 HAL_PCD_ResumeCallback(hpcd); | |
445 | |
446 __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_WKUINT); | |
447 } | |
448 | |
449 /* Handle Suspend Interrupt */ | |
450 if(__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_USBSUSP)) | |
451 { | |
452 | |
453 if((USBx_DEVICE->DSTS & USB_OTG_DSTS_SUSPSTS) == USB_OTG_DSTS_SUSPSTS) | |
454 { | |
455 | |
456 HAL_PCD_SuspendCallback(hpcd); | |
457 } | |
458 __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_USBSUSP); | |
459 } | |
460 | |
461 /* Handle Reset Interrupt */ | |
462 if(__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_USBRST)) | |
463 { | |
464 USBx_DEVICE->DCTL &= ~USB_OTG_DCTL_RWUSIG; | |
465 USB_FlushTxFifo(hpcd->Instance , 0 ); | |
466 | |
467 for (i = 0; i < hpcd->Init.dev_endpoints ; i++) | |
468 { | |
469 USBx_INEP(i)->DIEPINT = 0xFF; | |
470 USBx_OUTEP(i)->DOEPINT = 0xFF; | |
471 } | |
472 USBx_DEVICE->DAINT = 0xFFFFFFFF; | |
473 USBx_DEVICE->DAINTMSK |= 0x10001; | |
474 | |
475 if(hpcd->Init.use_dedicated_ep1) | |
476 { | |
477 USBx_DEVICE->DOUTEP1MSK |= (USB_OTG_DOEPMSK_STUPM | USB_OTG_DOEPMSK_XFRCM | USB_OTG_DOEPMSK_EPDM); | |
478 USBx_DEVICE->DINEP1MSK |= (USB_OTG_DIEPMSK_TOM | USB_OTG_DIEPMSK_XFRCM | USB_OTG_DIEPMSK_EPDM); | |
479 } | |
480 else | |
481 { | |
482 USBx_DEVICE->DOEPMSK |= (USB_OTG_DOEPMSK_STUPM | USB_OTG_DOEPMSK_XFRCM | USB_OTG_DOEPMSK_EPDM); | |
483 USBx_DEVICE->DIEPMSK |= (USB_OTG_DIEPMSK_TOM | USB_OTG_DIEPMSK_XFRCM | USB_OTG_DIEPMSK_EPDM); | |
484 } | |
485 | |
486 /* Set Default Address to 0 */ | |
487 USBx_DEVICE->DCFG &= ~USB_OTG_DCFG_DAD; | |
488 | |
489 /* setup EP0 to receive SETUP packets */ | |
490 USB_EP0_OutStart(hpcd->Instance, hpcd->Init.dma_enable, (uint8_t *)hpcd->Setup); | |
491 | |
492 __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_USBRST); | |
493 } | |
494 | |
495 /* Handle Enumeration done Interrupt */ | |
496 if(__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_ENUMDNE)) | |
497 { | |
498 USB_ActivateSetup(hpcd->Instance); | |
499 hpcd->Instance->GUSBCFG &= ~USB_OTG_GUSBCFG_TRDT; | |
500 | |
501 if ( USB_GetDevSpeed(hpcd->Instance) == USB_OTG_SPEED_HIGH) | |
502 { | |
503 hpcd->Init.speed = USB_OTG_SPEED_HIGH; | |
504 hpcd->Init.ep0_mps = USB_OTG_HS_MAX_PACKET_SIZE ; | |
505 hpcd->Instance->GUSBCFG |= (USB_OTG_GUSBCFG_TRDT_0 | USB_OTG_GUSBCFG_TRDT_3); | |
506 } | |
507 else | |
508 { | |
509 hpcd->Init.speed = USB_OTG_SPEED_FULL; | |
510 hpcd->Init.ep0_mps = USB_OTG_FS_MAX_PACKET_SIZE ; | |
511 hpcd->Instance->GUSBCFG |= (USB_OTG_GUSBCFG_TRDT_0 | USB_OTG_GUSBCFG_TRDT_2); | |
512 } | |
513 | |
514 HAL_PCD_ResetCallback(hpcd); | |
515 | |
516 __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_ENUMDNE); | |
517 } | |
518 | |
519 /* Handle RxQLevel Interrupt */ | |
520 if(__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_RXFLVL)) | |
521 { | |
522 USB_MASK_INTERRUPT(hpcd->Instance, USB_OTG_GINTSTS_RXFLVL); | |
523 temp = USBx->GRXSTSP; | |
524 ep = &hpcd->OUT_ep[temp & USB_OTG_GRXSTSP_EPNUM]; | |
525 | |
526 if(((temp & USB_OTG_GRXSTSP_PKTSTS) >> 17) == STS_DATA_UPDT) | |
527 { | |
528 if((temp & USB_OTG_GRXSTSP_BCNT) != 0) | |
529 { | |
530 USB_ReadPacket(USBx, ep->xfer_buff, (temp & USB_OTG_GRXSTSP_BCNT) >> 4); | |
531 ep->xfer_buff += (temp & USB_OTG_GRXSTSP_BCNT) >> 4; | |
532 ep->xfer_count += (temp & USB_OTG_GRXSTSP_BCNT) >> 4; | |
533 } | |
534 } | |
535 else if (((temp & USB_OTG_GRXSTSP_PKTSTS) >> 17) == STS_SETUP_UPDT) | |
536 { | |
537 USB_ReadPacket(USBx, (uint8_t *)hpcd->Setup, 8); | |
538 ep->xfer_count += (temp & USB_OTG_GRXSTSP_BCNT) >> 4; | |
539 } | |
540 USB_UNMASK_INTERRUPT(hpcd->Instance, USB_OTG_GINTSTS_RXFLVL); | |
541 } | |
542 | |
543 /* Handle SOF Interrupt */ | |
544 if(__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_SOF)) | |
545 { | |
546 HAL_PCD_SOFCallback(hpcd); | |
547 __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_SOF); | |
548 } | |
549 | |
550 /* Handle Incomplete ISO IN Interrupt */ | |
551 if(__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_IISOIXFR)) | |
552 { | |
553 HAL_PCD_ISOINIncompleteCallback(hpcd, epnum); | |
554 __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_IISOIXFR); | |
555 } | |
556 | |
557 /* Handle Incomplete ISO OUT Interrupt */ | |
558 if(__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_PXFR_INCOMPISOOUT)) | |
559 { | |
560 HAL_PCD_ISOOUTIncompleteCallback(hpcd, epnum); | |
561 __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_PXFR_INCOMPISOOUT); | |
562 } | |
563 | |
564 /* Handle Connection event Interrupt */ | |
565 if(__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_SRQINT)) | |
566 { | |
567 HAL_PCD_ConnectCallback(hpcd); | |
568 __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_SRQINT); | |
569 } | |
570 | |
571 /* Handle Disconnection event Interrupt */ | |
572 if(__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_OTGINT)) | |
573 { | |
574 temp = hpcd->Instance->GOTGINT; | |
575 | |
576 if((temp & USB_OTG_GOTGINT_SEDET) == USB_OTG_GOTGINT_SEDET) | |
577 { | |
578 HAL_PCD_DisconnectCallback(hpcd); | |
579 } | |
580 hpcd->Instance->GOTGINT |= temp; | |
581 } | |
582 } | |
583 } | |
584 | |
585 /** | |
586 * @brief Data OUT stage callbacks | |
587 * @param hpcd: PCD handle | |
588 * @param epnum: endpoint number | |
589 * @retval None | |
590 */ | |
591 __weak void HAL_PCD_DataOutStageCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum) | |
592 { | |
593 /* NOTE : This function Should not be modified, when the callback is needed, | |
594 the HAL_PCD_DataOutStageCallback could be implemented in the user file | |
595 */ | |
596 } | |
597 | |
598 /** | |
599 * @brief Data IN stage callbacks | |
600 * @param hpcd: PCD handle | |
601 * @param epnum: endpoint number | |
602 * @retval None | |
603 */ | |
604 __weak void HAL_PCD_DataInStageCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum) | |
605 { | |
606 /* NOTE : This function Should not be modified, when the callback is needed, | |
607 the HAL_PCD_DataOutStageCallback could be implemented in the user file | |
608 */ | |
609 } | |
610 /** | |
611 * @brief Setup stage callback | |
612 * @param hpcd: PCD handle | |
613 * @retval None | |
614 */ | |
615 __weak void HAL_PCD_SetupStageCallback(PCD_HandleTypeDef *hpcd) | |
616 { | |
617 /* NOTE : This function Should not be modified, when the callback is needed, | |
618 the HAL_PCD_DataOutStageCallback could be implemented in the user file | |
619 */ | |
620 } | |
621 | |
622 /** | |
623 * @brief USB Start Of Frame callbacks | |
624 * @param hpcd: PCD handle | |
625 * @retval None | |
626 */ | |
627 __weak void HAL_PCD_SOFCallback(PCD_HandleTypeDef *hpcd) | |
628 { | |
629 /* NOTE : This function Should not be modified, when the callback is needed, | |
630 the HAL_PCD_DataOutStageCallback could be implemented in the user file | |
631 */ | |
632 } | |
633 | |
634 /** | |
635 * @brief USB Reset callbacks | |
636 * @param hpcd: PCD handle | |
637 * @retval None | |
638 */ | |
639 __weak void HAL_PCD_ResetCallback(PCD_HandleTypeDef *hpcd) | |
640 { | |
641 /* NOTE : This function Should not be modified, when the callback is needed, | |
642 the HAL_PCD_DataOutStageCallback could be implemented in the user file | |
643 */ | |
644 } | |
645 | |
646 | |
647 /** | |
648 * @brief Suspend event callbacks | |
649 * @param hpcd: PCD handle | |
650 * @retval None | |
651 */ | |
652 __weak void HAL_PCD_SuspendCallback(PCD_HandleTypeDef *hpcd) | |
653 { | |
654 /* NOTE : This function Should not be modified, when the callback is needed, | |
655 the HAL_PCD_DataOutStageCallback could be implemented in the user file | |
656 */ | |
657 } | |
658 | |
659 /** | |
660 * @brief Resume event callbacks | |
661 * @param hpcd: PCD handle | |
662 * @retval None | |
663 */ | |
664 __weak void HAL_PCD_ResumeCallback(PCD_HandleTypeDef *hpcd) | |
665 { | |
666 /* NOTE : This function Should not be modified, when the callback is needed, | |
667 the HAL_PCD_DataOutStageCallback could be implemented in the user file | |
668 */ | |
669 } | |
670 | |
671 /** | |
672 * @brief Incomplete ISO OUT callbacks | |
673 * @param hpcd: PCD handle | |
674 * @param epnum: endpoint number | |
675 * @retval None | |
676 */ | |
677 __weak void HAL_PCD_ISOOUTIncompleteCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum) | |
678 { | |
679 /* NOTE : This function Should not be modified, when the callback is needed, | |
680 the HAL_PCD_DataOutStageCallback could be implemented in the user file | |
681 */ | |
682 } | |
683 | |
684 /** | |
685 * @brief Incomplete ISO IN callbacks | |
686 * @param hpcd: PCD handle | |
687 * @param epnum: endpoint number | |
688 * @retval None | |
689 */ | |
690 __weak void HAL_PCD_ISOINIncompleteCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum) | |
691 { | |
692 /* NOTE : This function Should not be modified, when the callback is needed, | |
693 the HAL_PCD_DataOutStageCallback could be implemented in the user file | |
694 */ | |
695 } | |
696 | |
697 /** | |
698 * @brief Connection event callbacks | |
699 * @param hpcd: PCD handle | |
700 * @retval None | |
701 */ | |
702 __weak void HAL_PCD_ConnectCallback(PCD_HandleTypeDef *hpcd) | |
703 { | |
704 /* NOTE : This function Should not be modified, when the callback is needed, | |
705 the HAL_PCD_DataOutStageCallback could be implemented in the user file | |
706 */ | |
707 } | |
708 | |
709 /** | |
710 * @brief Disconnection event callbacks | |
711 * @param hpcd: PCD handle | |
712 * @retval None | |
713 */ | |
714 __weak void HAL_PCD_DisconnectCallback(PCD_HandleTypeDef *hpcd) | |
715 { | |
716 /* NOTE : This function Should not be modified, when the callback is needed, | |
717 the HAL_PCD_DataOutStageCallback could be implemented in the user file | |
718 */ | |
719 } | |
720 | |
721 /** | |
722 * @} | |
723 */ | |
724 | |
725 /** @defgroup PCD_Exported_Functions_Group3 Peripheral Control functions | |
726 * @brief management functions | |
727 * | |
728 @verbatim | |
729 =============================================================================== | |
730 ##### Peripheral Control functions ##### | |
731 =============================================================================== | |
732 [..] | |
733 This subsection provides a set of functions allowing to control the PCD data | |
734 transfers. | |
735 | |
736 @endverbatim | |
737 * @{ | |
738 */ | |
739 | |
740 /** | |
741 * @brief Connect the USB device | |
742 * @param hpcd: PCD handle | |
743 * @retval HAL status | |
744 */ | |
745 HAL_StatusTypeDef HAL_PCD_DevConnect(PCD_HandleTypeDef *hpcd) | |
746 { | |
747 __HAL_LOCK(hpcd); | |
748 USB_DevConnect(hpcd->Instance); | |
749 __HAL_UNLOCK(hpcd); | |
750 return HAL_OK; | |
751 } | |
752 | |
753 /** | |
754 * @brief Disconnect the USB device | |
755 * @param hpcd: PCD handle | |
756 * @retval HAL status | |
757 */ | |
758 HAL_StatusTypeDef HAL_PCD_DevDisconnect(PCD_HandleTypeDef *hpcd) | |
759 { | |
760 __HAL_LOCK(hpcd); | |
761 USB_DevDisconnect(hpcd->Instance); | |
762 __HAL_UNLOCK(hpcd); | |
763 return HAL_OK; | |
764 } | |
765 | |
766 /** | |
767 * @brief Set the USB Device address | |
768 * @param hpcd: PCD handle | |
769 * @param address: new device address | |
770 * @retval HAL status | |
771 */ | |
772 HAL_StatusTypeDef HAL_PCD_SetAddress(PCD_HandleTypeDef *hpcd, uint8_t address) | |
773 { | |
774 __HAL_LOCK(hpcd); | |
775 USB_SetDevAddress(hpcd->Instance, address); | |
776 __HAL_UNLOCK(hpcd); | |
777 return HAL_OK; | |
778 } | |
779 /** | |
780 * @brief Open and configure an endpoint | |
781 * @param hpcd: PCD handle | |
782 * @param ep_addr: endpoint address | |
783 * @param ep_mps: endpoint max packet size | |
784 * @param ep_type: endpoint type | |
785 * @retval HAL status | |
786 */ | |
787 HAL_StatusTypeDef HAL_PCD_EP_Open(PCD_HandleTypeDef *hpcd, uint8_t ep_addr, uint16_t ep_mps, uint8_t ep_type) | |
788 { | |
789 HAL_StatusTypeDef ret = HAL_OK; | |
790 USB_OTG_EPTypeDef *ep; | |
791 | |
792 if ((ep_addr & 0x80) == 0x80) | |
793 { | |
794 ep = &hpcd->IN_ep[ep_addr & 0x7F]; | |
795 } | |
796 else | |
797 { | |
798 ep = &hpcd->OUT_ep[ep_addr & 0x7F]; | |
799 } | |
800 ep->num = ep_addr & 0x7F; | |
801 | |
802 ep->is_in = (0x80 & ep_addr) != 0; | |
803 ep->maxpacket = ep_mps; | |
804 ep->type = ep_type; | |
805 if (ep->is_in) | |
806 { | |
807 /* Assign a Tx FIFO */ | |
808 ep->tx_fifo_num = ep->num; | |
809 } | |
810 /* Set initial data PID. */ | |
811 if (ep_type == EP_TYPE_BULK ) | |
812 { | |
813 ep->data_pid_start = 0; | |
814 } | |
815 | |
816 __HAL_LOCK(hpcd); | |
817 USB_ActivateEndpoint(hpcd->Instance , ep); | |
818 __HAL_UNLOCK(hpcd); | |
819 return ret; | |
820 } | |
821 | |
822 | |
823 /** | |
824 * @brief Deactivate an endpoint | |
825 * @param hpcd: PCD handle | |
826 * @param ep_addr: endpoint address | |
827 * @retval HAL status | |
828 */ | |
829 HAL_StatusTypeDef HAL_PCD_EP_Close(PCD_HandleTypeDef *hpcd, uint8_t ep_addr) | |
830 { | |
831 USB_OTG_EPTypeDef *ep; | |
832 | |
833 if ((ep_addr & 0x80) == 0x80) | |
834 { | |
835 ep = &hpcd->IN_ep[ep_addr & 0x7F]; | |
836 } | |
837 else | |
838 { | |
839 ep = &hpcd->OUT_ep[ep_addr & 0x7F]; | |
840 } | |
841 ep->num = ep_addr & 0x7F; | |
842 | |
843 ep->is_in = (0x80 & ep_addr) != 0; | |
844 | |
845 __HAL_LOCK(hpcd); | |
846 USB_DeactivateEndpoint(hpcd->Instance , ep); | |
847 __HAL_UNLOCK(hpcd); | |
848 return HAL_OK; | |
849 } | |
850 | |
851 | |
852 /** | |
853 * @brief Receive an amount of data | |
854 * @param hpcd: PCD handle | |
855 * @param ep_addr: endpoint address | |
856 * @param pBuf: pointer to the reception buffer | |
857 * @param len: amount of data to be received | |
858 * @retval HAL status | |
859 */ | |
860 HAL_StatusTypeDef HAL_PCD_EP_Receive(PCD_HandleTypeDef *hpcd, uint8_t ep_addr, uint8_t *pBuf, uint32_t len) | |
861 { | |
862 USB_OTG_EPTypeDef *ep; | |
863 | |
864 ep = &hpcd->OUT_ep[ep_addr & 0x7F]; | |
865 | |
866 /*setup and start the Xfer */ | |
867 ep->xfer_buff = pBuf; | |
868 ep->xfer_len = len; | |
869 ep->xfer_count = 0; | |
870 ep->is_in = 0; | |
871 ep->num = ep_addr & 0x7F; | |
872 | |
873 if (hpcd->Init.dma_enable == 1) | |
874 { | |
875 ep->dma_addr = (uint32_t)pBuf; | |
876 } | |
877 | |
878 __HAL_LOCK(hpcd); | |
879 | |
880 if ((ep_addr & 0x7F) == 0 ) | |
881 { | |
882 USB_EP0StartXfer(hpcd->Instance , ep, hpcd->Init.dma_enable); | |
883 } | |
884 else | |
885 { | |
886 USB_EPStartXfer(hpcd->Instance , ep, hpcd->Init.dma_enable); | |
887 } | |
888 __HAL_UNLOCK(hpcd); | |
889 | |
890 return HAL_OK; | |
891 } | |
892 | |
893 /** | |
894 * @brief Get Received Data Size | |
895 * @param hpcd: PCD handle | |
896 * @param ep_addr: endpoint address | |
897 * @retval Data Size | |
898 */ | |
899 uint16_t HAL_PCD_EP_GetRxCount(PCD_HandleTypeDef *hpcd, uint8_t ep_addr) | |
900 { | |
901 return hpcd->OUT_ep[ep_addr & 0x7F].xfer_count; | |
902 } | |
903 /** | |
904 * @brief Send an amount of data | |
905 * @param hpcd: PCD handle | |
906 * @param ep_addr: endpoint address | |
907 * @param pBuf: pointer to the transmission buffer | |
908 * @param len: amount of data to be sent | |
909 * @retval HAL status | |
910 */ | |
911 HAL_StatusTypeDef HAL_PCD_EP_Transmit(PCD_HandleTypeDef *hpcd, uint8_t ep_addr, uint8_t *pBuf, uint32_t len) | |
912 { | |
913 USB_OTG_EPTypeDef *ep; | |
914 | |
915 ep = &hpcd->IN_ep[ep_addr & 0x7F]; | |
916 | |
917 /*setup and start the Xfer */ | |
918 ep->xfer_buff = pBuf; | |
919 ep->xfer_len = len; | |
920 ep->xfer_count = 0; | |
921 ep->is_in = 1; | |
922 ep->num = ep_addr & 0x7F; | |
923 | |
924 if (hpcd->Init.dma_enable == 1) | |
925 { | |
926 ep->dma_addr = (uint32_t)pBuf; | |
927 } | |
928 | |
929 __HAL_LOCK(hpcd); | |
930 | |
931 if ((ep_addr & 0x7F) == 0 ) | |
932 { | |
933 USB_EP0StartXfer(hpcd->Instance , ep, hpcd->Init.dma_enable); | |
934 } | |
935 else | |
936 { | |
937 USB_EPStartXfer(hpcd->Instance , ep, hpcd->Init.dma_enable); | |
938 } | |
939 | |
940 __HAL_UNLOCK(hpcd); | |
941 | |
942 return HAL_OK; | |
943 } | |
944 | |
945 /** | |
946 * @brief Set a STALL condition over an endpoint | |
947 * @param hpcd: PCD handle | |
948 * @param ep_addr: endpoint address | |
949 * @retval HAL status | |
950 */ | |
951 HAL_StatusTypeDef HAL_PCD_EP_SetStall(PCD_HandleTypeDef *hpcd, uint8_t ep_addr) | |
952 { | |
953 USB_OTG_EPTypeDef *ep; | |
954 | |
955 if ((0x80 & ep_addr) == 0x80) | |
956 { | |
957 ep = &hpcd->IN_ep[ep_addr & 0x7F]; | |
958 } | |
959 else | |
960 { | |
961 ep = &hpcd->OUT_ep[ep_addr]; | |
962 } | |
963 | |
964 ep->is_stall = 1; | |
965 ep->num = ep_addr & 0x7F; | |
966 ep->is_in = ((ep_addr & 0x80) == 0x80); | |
967 | |
968 | |
969 __HAL_LOCK(hpcd); | |
970 USB_EPSetStall(hpcd->Instance , ep); | |
971 if((ep_addr & 0x7F) == 0) | |
972 { | |
973 USB_EP0_OutStart(hpcd->Instance, hpcd->Init.dma_enable, (uint8_t *)hpcd->Setup); | |
974 } | |
975 __HAL_UNLOCK(hpcd); | |
976 | |
977 return HAL_OK; | |
978 } | |
979 | |
980 /** | |
981 * @brief Clear a STALL condition over in an endpoint | |
982 * @param hpcd: PCD handle | |
983 * @param ep_addr: endpoint address | |
984 * @retval HAL status | |
985 */ | |
986 HAL_StatusTypeDef HAL_PCD_EP_ClrStall(PCD_HandleTypeDef *hpcd, uint8_t ep_addr) | |
987 { | |
988 USB_OTG_EPTypeDef *ep; | |
989 | |
990 if ((0x80 & ep_addr) == 0x80) | |
991 { | |
992 ep = &hpcd->IN_ep[ep_addr & 0x7F]; | |
993 } | |
994 else | |
995 { | |
996 ep = &hpcd->OUT_ep[ep_addr]; | |
997 } | |
998 | |
999 ep->is_stall = 0; | |
1000 ep->num = ep_addr & 0x7F; | |
1001 ep->is_in = ((ep_addr & 0x80) == 0x80); | |
1002 | |
1003 __HAL_LOCK(hpcd); | |
1004 USB_EPClearStall(hpcd->Instance , ep); | |
1005 __HAL_UNLOCK(hpcd); | |
1006 | |
1007 return HAL_OK; | |
1008 } | |
1009 | |
1010 /** | |
1011 * @brief Flush an endpoint | |
1012 * @param hpcd: PCD handle | |
1013 * @param ep_addr: endpoint address | |
1014 * @retval HAL status | |
1015 */ | |
1016 HAL_StatusTypeDef HAL_PCD_EP_Flush(PCD_HandleTypeDef *hpcd, uint8_t ep_addr) | |
1017 { | |
1018 __HAL_LOCK(hpcd); | |
1019 | |
1020 if ((ep_addr & 0x80) == 0x80) | |
1021 { | |
1022 USB_FlushTxFifo(hpcd->Instance, ep_addr & 0x7F); | |
1023 } | |
1024 else | |
1025 { | |
1026 USB_FlushRxFifo(hpcd->Instance); | |
1027 } | |
1028 | |
1029 __HAL_UNLOCK(hpcd); | |
1030 | |
1031 return HAL_OK; | |
1032 } | |
1033 | |
1034 /** | |
1035 * @brief HAL_PCD_ActivateRemoteWakeup : active remote wake-up signalling | |
1036 * @param hpcd: PCD handle | |
1037 * @retval HAL status | |
1038 */ | |
1039 HAL_StatusTypeDef HAL_PCD_ActivateRemoteWakeup(PCD_HandleTypeDef *hpcd) | |
1040 { | |
1041 USB_OTG_GlobalTypeDef *USBx = hpcd->Instance; | |
1042 | |
1043 if((USBx_DEVICE->DSTS & USB_OTG_DSTS_SUSPSTS) == USB_OTG_DSTS_SUSPSTS) | |
1044 { | |
1045 /* active Remote wake-up signaling */ | |
1046 USBx_DEVICE->DCTL |= USB_OTG_DCTL_RWUSIG; | |
1047 } | |
1048 return HAL_OK; | |
1049 } | |
1050 | |
1051 /** | |
1052 * @brief HAL_PCD_DeActivateRemoteWakeup : de-active remote wake-up signalling | |
1053 * @param hpcd: PCD handle | |
1054 * @retval HAL status | |
1055 */ | |
1056 HAL_StatusTypeDef HAL_PCD_DeActivateRemoteWakeup(PCD_HandleTypeDef *hpcd) | |
1057 { | |
1058 USB_OTG_GlobalTypeDef *USBx = hpcd->Instance; | |
1059 | |
1060 /* Active Remote wake-up signaling */ | |
1061 USBx_DEVICE->DCTL &= ~(USB_OTG_DCTL_RWUSIG); | |
1062 return HAL_OK; | |
1063 } | |
1064 /** | |
1065 * @} | |
1066 */ | |
1067 | |
1068 /** @defgroup PCD_Exported_Functions_Group4 Peripheral State functions | |
1069 * @brief Peripheral State functions | |
1070 * | |
1071 @verbatim | |
1072 =============================================================================== | |
1073 ##### Peripheral State functions ##### | |
1074 =============================================================================== | |
1075 [..] | |
1076 This subsection permits to get in run-time the status of the peripheral | |
1077 and the data flow. | |
1078 | |
1079 @endverbatim | |
1080 * @{ | |
1081 */ | |
1082 | |
1083 /** | |
1084 * @brief Return the PCD state | |
1085 * @param hpcd: PCD handle | |
1086 * @retval HAL state | |
1087 */ | |
1088 PCD_StateTypeDef HAL_PCD_GetState(PCD_HandleTypeDef *hpcd) | |
1089 { | |
1090 return hpcd->State; | |
1091 } | |
1092 /** | |
1093 * @} | |
1094 */ | |
1095 | |
1096 /** | |
1097 * @} | |
1098 */ | |
1099 | |
1100 /* Private functions ---------------------------------------------------------*/ | |
1101 /** @addtogroup PCD_Private_Functions | |
1102 * @{ | |
1103 */ | |
1104 | |
1105 /** | |
1106 * @brief DCD_WriteEmptyTxFifo | |
1107 * check FIFO for the next packet to be loaded | |
1108 * @param hpcd: PCD handle | |
1109 * @param epnum : endpoint number | |
1110 * @retval HAL status | |
1111 */ | |
1112 static HAL_StatusTypeDef PCD_WriteEmptyTxFifo(PCD_HandleTypeDef *hpcd, uint32_t epnum) | |
1113 { | |
1114 USB_OTG_GlobalTypeDef *USBx = hpcd->Instance; | |
1115 USB_OTG_EPTypeDef *ep; | |
1116 int32_t len = 0; | |
1117 uint32_t len32b; | |
1118 uint32_t fifoemptymsk = 0; | |
1119 | |
1120 ep = &hpcd->IN_ep[epnum]; | |
1121 len = ep->xfer_len - ep->xfer_count; | |
1122 | |
1123 if (len > ep->maxpacket) | |
1124 { | |
1125 len = ep->maxpacket; | |
1126 } | |
1127 | |
1128 | |
1129 len32b = (len + 3) / 4; | |
1130 | |
1131 while ( (USBx_INEP(epnum)->DTXFSTS & USB_OTG_DTXFSTS_INEPTFSAV) > len32b && | |
1132 ep->xfer_count < ep->xfer_len && | |
1133 ep->xfer_len != 0) | |
1134 { | |
1135 /* Write the FIFO */ | |
1136 len = ep->xfer_len - ep->xfer_count; | |
1137 | |
1138 if (len > ep->maxpacket) | |
1139 { | |
1140 len = ep->maxpacket; | |
1141 } | |
1142 len32b = (len + 3) / 4; | |
1143 | |
1144 USB_WritePacket(USBx, ep->xfer_buff, epnum, len, hpcd->Init.dma_enable); | |
1145 | |
1146 ep->xfer_buff += len; | |
1147 ep->xfer_count += len; | |
1148 } | |
1149 | |
1150 if(len <= 0) | |
1151 { | |
1152 fifoemptymsk = 0x1 << epnum; | |
1153 USBx_DEVICE->DIEPEMPMSK &= ~fifoemptymsk; | |
1154 | |
1155 } | |
1156 | |
1157 return HAL_OK; | |
1158 } | |
1159 | |
1160 /** | |
1161 * @} | |
1162 */ | |
1163 | |
1164 #endif /* HAL_PCD_MODULE_ENABLED */ | |
1165 /** | |
1166 * @} | |
1167 */ | |
1168 | |
1169 /** | |
1170 * @} | |
1171 */ | |
1172 | |
1173 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ |