fc54bc3338b710a88bd0741d063d47540186c135
[mTask.git] / int / com / lib / STM32F7xx_HAL_Driver / Src / stm32f7xx_hal_pcd.c
1 /**
2 ******************************************************************************
3 * @file stm32f7xx_hal_pcd.c
4 * @author MCD Application Team
5 * @version V1.1.0
6 * @date 22-April-2016
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 PCD 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 (+++) __HAL_RCC_USB_OTG_FS_CLK_ENABLE();
32 (+++) __HAL_RCC_USB_OTG_HS_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 PCD transmission and reception:
42 (##) HAL_PCD_Start();
43
44 @endverbatim
45 ******************************************************************************
46 * @attention
47 *
48 * <h2><center>&copy; COPYRIGHT(c) 2016 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 "stm32f7xx_hal.h"
77
78 /** @addtogroup STM32F7xx_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 /* Activate LPM */
196 if (hpcd->Init.lpm_enable == 1)
197 {
198 HAL_PCDEx_ActivateLPM(hpcd);
199 }
200
201 USB_DevDisconnect (hpcd->Instance);
202 return HAL_OK;
203 }
204
205 /**
206 * @brief DeInitializes the PCD peripheral.
207 * @param hpcd: PCD handle
208 * @retval HAL status
209 */
210 HAL_StatusTypeDef HAL_PCD_DeInit(PCD_HandleTypeDef *hpcd)
211 {
212 /* Check the PCD handle allocation */
213 if(hpcd == NULL)
214 {
215 return HAL_ERROR;
216 }
217
218 hpcd->State = HAL_PCD_STATE_BUSY;
219
220 /* Stop Device */
221 HAL_PCD_Stop(hpcd);
222
223 /* DeInit the low level hardware */
224 HAL_PCD_MspDeInit(hpcd);
225
226 hpcd->State = HAL_PCD_STATE_RESET;
227
228 return HAL_OK;
229 }
230
231 /**
232 * @brief Initializes the PCD MSP.
233 * @param hpcd: PCD handle
234 * @retval None
235 */
236 __weak void HAL_PCD_MspInit(PCD_HandleTypeDef *hpcd)
237 {
238 /* Prevent unused argument(s) compilation warning */
239 UNUSED(hpcd);
240
241 /* NOTE : This function Should not be modified, when the callback is needed,
242 the HAL_PCD_MspInit could be implemented in the user file
243 */
244 }
245
246 /**
247 * @brief DeInitializes PCD MSP.
248 * @param hpcd: PCD handle
249 * @retval None
250 */
251 __weak void HAL_PCD_MspDeInit(PCD_HandleTypeDef *hpcd)
252 {
253 /* Prevent unused argument(s) compilation warning */
254 UNUSED(hpcd);
255
256 /* NOTE : This function Should not be modified, when the callback is needed,
257 the HAL_PCD_MspDeInit could be implemented in the user file
258 */
259 }
260
261 /**
262 * @}
263 */
264
265 /** @defgroup PCD_Exported_Functions_Group2 Input and Output operation functions
266 * @brief Data transfers functions
267 *
268 @verbatim
269 ===============================================================================
270 ##### IO operation functions #####
271 ===============================================================================
272 [..]
273 This subsection provides a set of functions allowing to manage the PCD data
274 transfers.
275
276 @endverbatim
277 * @{
278 */
279
280 /**
281 * @brief Start The USB OTG Device.
282 * @param hpcd: PCD handle
283 * @retval HAL status
284 */
285 HAL_StatusTypeDef HAL_PCD_Start(PCD_HandleTypeDef *hpcd)
286 {
287 __HAL_LOCK(hpcd);
288 USB_DevConnect (hpcd->Instance);
289 __HAL_PCD_ENABLE(hpcd);
290 __HAL_UNLOCK(hpcd);
291 return HAL_OK;
292 }
293
294 /**
295 * @brief Stop The USB OTG Device.
296 * @param hpcd: PCD handle
297 * @retval HAL status
298 */
299 HAL_StatusTypeDef HAL_PCD_Stop(PCD_HandleTypeDef *hpcd)
300 {
301 __HAL_LOCK(hpcd);
302 __HAL_PCD_DISABLE(hpcd);
303 USB_StopDevice(hpcd->Instance);
304 USB_DevDisconnect (hpcd->Instance);
305 __HAL_UNLOCK(hpcd);
306 return HAL_OK;
307 }
308
309 /**
310 * @brief Handle PCD interrupt request.
311 * @param hpcd: PCD handle
312 * @retval HAL status
313 */
314 void HAL_PCD_IRQHandler(PCD_HandleTypeDef *hpcd)
315 {
316 USB_OTG_GlobalTypeDef *USBx = hpcd->Instance;
317 uint32_t i = 0, ep_intr = 0, epint = 0, epnum = 0;
318 uint32_t fifoemptymsk = 0, temp = 0;
319 USB_OTG_EPTypeDef *ep = NULL;
320 uint32_t hclk = 200000000;
321
322 /* ensure that we are in device mode */
323 if (USB_GetMode(hpcd->Instance) == USB_OTG_MODE_DEVICE)
324 {
325 /* avoid spurious interrupt */
326 if(__HAL_PCD_IS_INVALID_INTERRUPT(hpcd))
327 {
328 return;
329 }
330
331 if(__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_MMIS))
332 {
333 /* incorrect mode, acknowledge the interrupt */
334 __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_MMIS);
335 }
336
337 if(__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_OEPINT))
338 {
339 epnum = 0;
340
341 /* Read in the device interrupt bits */
342 ep_intr = USB_ReadDevAllOutEpInterrupt(hpcd->Instance);
343
344 while ( ep_intr )
345 {
346 if (ep_intr & 0x1)
347 {
348 epint = USB_ReadDevOutEPInterrupt(hpcd->Instance, epnum);
349
350 if(( epint & USB_OTG_DOEPINT_XFRC) == USB_OTG_DOEPINT_XFRC)
351 {
352 CLEAR_OUT_EP_INTR(epnum, USB_OTG_DOEPINT_XFRC);
353
354 if(hpcd->Init.dma_enable == 1)
355 {
356 hpcd->OUT_ep[epnum].xfer_count = hpcd->OUT_ep[epnum].maxpacket- (USBx_OUTEP(epnum)->DOEPTSIZ & USB_OTG_DOEPTSIZ_XFRSIZ);
357 hpcd->OUT_ep[epnum].xfer_buff += hpcd->OUT_ep[epnum].maxpacket;
358 }
359
360 HAL_PCD_DataOutStageCallback(hpcd, epnum);
361 if(hpcd->Init.dma_enable == 1)
362 {
363 if((epnum == 0) && (hpcd->OUT_ep[epnum].xfer_len == 0))
364 {
365 /* this is ZLP, so prepare EP0 for next setup */
366 USB_EP0_OutStart(hpcd->Instance, 1, (uint8_t *)hpcd->Setup);
367 }
368 }
369 }
370
371 if(( epint & USB_OTG_DOEPINT_STUP) == USB_OTG_DOEPINT_STUP)
372 {
373 /* Inform the upper layer that a setup packet is available */
374 HAL_PCD_SetupStageCallback(hpcd);
375 CLEAR_OUT_EP_INTR(epnum, USB_OTG_DOEPINT_STUP);
376 }
377
378 if(( epint & USB_OTG_DOEPINT_OTEPDIS) == USB_OTG_DOEPINT_OTEPDIS)
379 {
380 CLEAR_OUT_EP_INTR(epnum, USB_OTG_DOEPINT_OTEPDIS);
381 }
382 /* Clear Status Phase Received interrupt */
383 if(( epint & USB_OTG_DOEPINT_OTEPSPR) == USB_OTG_DOEPINT_OTEPSPR)
384 {
385 CLEAR_OUT_EP_INTR(epnum, USB_OTG_DOEPINT_OTEPSPR);
386 }
387 }
388 epnum++;
389 ep_intr >>= 1;
390 }
391 }
392
393 if(__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_IEPINT))
394 {
395 /* Read in the device interrupt bits */
396 ep_intr = USB_ReadDevAllInEpInterrupt(hpcd->Instance);
397
398 epnum = 0;
399
400 while ( ep_intr )
401 {
402 if (ep_intr & 0x1) /* In ITR */
403 {
404 epint = USB_ReadDevInEPInterrupt(hpcd->Instance, epnum);
405
406 if(( epint & USB_OTG_DIEPINT_XFRC) == USB_OTG_DIEPINT_XFRC)
407 {
408 fifoemptymsk = 0x1 << epnum;
409 USBx_DEVICE->DIEPEMPMSK &= ~fifoemptymsk;
410
411 CLEAR_IN_EP_INTR(epnum, USB_OTG_DIEPINT_XFRC);
412
413 if (hpcd->Init.dma_enable == 1)
414 {
415 hpcd->IN_ep[epnum].xfer_buff += hpcd->IN_ep[epnum].maxpacket;
416 }
417
418 HAL_PCD_DataInStageCallback(hpcd, epnum);
419
420 if (hpcd->Init.dma_enable == 1)
421 {
422 /* this is ZLP, so prepare EP0 for next setup */
423 if((epnum == 0) && (hpcd->IN_ep[epnum].xfer_len == 0))
424 {
425 /* prepare to rx more setup packets */
426 USB_EP0_OutStart(hpcd->Instance, 1, (uint8_t *)hpcd->Setup);
427 }
428 }
429 }
430 if(( epint & USB_OTG_DIEPINT_TOC) == USB_OTG_DIEPINT_TOC)
431 {
432 CLEAR_IN_EP_INTR(epnum, USB_OTG_DIEPINT_TOC);
433 }
434 if(( epint & USB_OTG_DIEPINT_ITTXFE) == USB_OTG_DIEPINT_ITTXFE)
435 {
436 CLEAR_IN_EP_INTR(epnum, USB_OTG_DIEPINT_ITTXFE);
437 }
438 if(( epint & USB_OTG_DIEPINT_INEPNE) == USB_OTG_DIEPINT_INEPNE)
439 {
440 CLEAR_IN_EP_INTR(epnum, USB_OTG_DIEPINT_INEPNE);
441 }
442 if(( epint & USB_OTG_DIEPINT_EPDISD) == USB_OTG_DIEPINT_EPDISD)
443 {
444 CLEAR_IN_EP_INTR(epnum, USB_OTG_DIEPINT_EPDISD);
445 }
446 if(( epint & USB_OTG_DIEPINT_TXFE) == USB_OTG_DIEPINT_TXFE)
447 {
448 PCD_WriteEmptyTxFifo(hpcd , epnum);
449 }
450 }
451 epnum++;
452 ep_intr >>= 1;
453 }
454 }
455
456 /* Handle Resume Interrupt */
457 if(__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_WKUINT))
458 {
459 /* Clear the Remote Wake-up Signaling */
460 USBx_DEVICE->DCTL &= ~USB_OTG_DCTL_RWUSIG;
461
462 if(hpcd->LPM_State == LPM_L1)
463 {
464 hpcd->LPM_State = LPM_L0;
465 HAL_PCDEx_LPM_Callback(hpcd, PCD_LPM_L0_ACTIVE);
466 }
467 else
468 {
469 HAL_PCD_ResumeCallback(hpcd);
470 }
471 __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_WKUINT);
472 }
473
474 /* Handle Suspend Interrupt */
475 if(__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_USBSUSP))
476 {
477 if((USBx_DEVICE->DSTS & USB_OTG_DSTS_SUSPSTS) == USB_OTG_DSTS_SUSPSTS)
478 {
479
480 HAL_PCD_SuspendCallback(hpcd);
481 }
482 __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_USBSUSP);
483 }
484
485 /* Handle LPM Interrupt */
486 if(__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_LPMINT))
487 {
488 __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_LPMINT);
489 if( hpcd->LPM_State == LPM_L0)
490 {
491 hpcd->LPM_State = LPM_L1;
492 hpcd->BESL = (hpcd->Instance->GLPMCFG & USB_OTG_GLPMCFG_BESL) >>2 ;
493 HAL_PCDEx_LPM_Callback(hpcd, PCD_LPM_L1_ACTIVE);
494 }
495 else
496 {
497 HAL_PCD_SuspendCallback(hpcd);
498 }
499 }
500
501 /* Handle Reset Interrupt */
502 if(__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_USBRST))
503 {
504 USBx_DEVICE->DCTL &= ~USB_OTG_DCTL_RWUSIG;
505 USB_FlushTxFifo(hpcd->Instance , 0 );
506
507 for (i = 0; i < hpcd->Init.dev_endpoints ; i++)
508 {
509 USBx_INEP(i)->DIEPINT = 0xFF;
510 USBx_OUTEP(i)->DOEPINT = 0xFF;
511 }
512 USBx_DEVICE->DAINT = 0xFFFFFFFF;
513 USBx_DEVICE->DAINTMSK |= 0x10001;
514
515 if(hpcd->Init.use_dedicated_ep1)
516 {
517 USBx_DEVICE->DOUTEP1MSK |= (USB_OTG_DOEPMSK_STUPM | USB_OTG_DOEPMSK_XFRCM | USB_OTG_DOEPMSK_EPDM);
518 USBx_DEVICE->DINEP1MSK |= (USB_OTG_DIEPMSK_TOM | USB_OTG_DIEPMSK_XFRCM | USB_OTG_DIEPMSK_EPDM);
519 }
520 else
521 {
522 USBx_DEVICE->DOEPMSK |= (USB_OTG_DOEPMSK_STUPM | USB_OTG_DOEPMSK_XFRCM | USB_OTG_DOEPMSK_EPDM | USB_OTG_DOEPMSK_OTEPSPRM);
523 USBx_DEVICE->DIEPMSK |= (USB_OTG_DIEPMSK_TOM | USB_OTG_DIEPMSK_XFRCM | USB_OTG_DIEPMSK_EPDM);
524 }
525
526 /* Set Default Address to 0 */
527 USBx_DEVICE->DCFG &= ~USB_OTG_DCFG_DAD;
528
529 /* setup EP0 to receive SETUP packets */
530 USB_EP0_OutStart(hpcd->Instance, hpcd->Init.dma_enable, (uint8_t *)hpcd->Setup);
531
532 __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_USBRST);
533 }
534
535 /* Handle Enumeration done Interrupt */
536 if(__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_ENUMDNE))
537 {
538 USB_ActivateSetup(hpcd->Instance);
539 hpcd->Instance->GUSBCFG &= ~USB_OTG_GUSBCFG_TRDT;
540
541 if ( USB_GetDevSpeed(hpcd->Instance) == USB_OTG_SPEED_HIGH)
542 {
543 hpcd->Init.speed = USB_OTG_SPEED_HIGH;
544 hpcd->Init.ep0_mps = USB_OTG_HS_MAX_PACKET_SIZE ;
545 hpcd->Instance->GUSBCFG |= (uint32_t)((USBD_HS_TRDT_VALUE << 10) & USB_OTG_GUSBCFG_TRDT);
546 }
547 else
548 {
549 hpcd->Init.speed = USB_OTG_SPEED_FULL;
550 hpcd->Init.ep0_mps = USB_OTG_FS_MAX_PACKET_SIZE ;
551
552 /* The USBTRD is configured according to the tables below, depending on AHB frequency
553 used by application. In the low AHB frequency range it is used to stretch enough the USB response
554 time to IN tokens, the USB turnaround time, so to compensate for the longer AHB read access
555 latency to the Data FIFO */
556
557 /* Get hclk frequency value */
558 hclk = HAL_RCC_GetHCLKFreq();
559
560 if((hclk >= 14200000)&&(hclk < 15000000))
561 {
562 /* hclk Clock Range between 14.2-15 MHz */
563 hpcd->Instance->GUSBCFG |= (uint32_t)((0xF << 10) & USB_OTG_GUSBCFG_TRDT);
564 }
565
566 else if((hclk >= 15000000)&&(hclk < 16000000))
567 {
568 /* hclk Clock Range between 15-16 MHz */
569 hpcd->Instance->GUSBCFG |= (uint32_t)((0xE << 10) & USB_OTG_GUSBCFG_TRDT);
570 }
571
572 else if((hclk >= 16000000)&&(hclk < 17200000))
573 {
574 /* hclk Clock Range between 16-17.2 MHz */
575 hpcd->Instance->GUSBCFG |= (uint32_t)((0xD << 10) & USB_OTG_GUSBCFG_TRDT);
576 }
577
578 else if((hclk >= 17200000)&&(hclk < 18500000))
579 {
580 /* hclk Clock Range between 17.2-18.5 MHz */
581 hpcd->Instance->GUSBCFG |= (uint32_t)((0xC << 10) & USB_OTG_GUSBCFG_TRDT);
582 }
583
584 else if((hclk >= 18500000)&&(hclk < 20000000))
585 {
586 /* hclk Clock Range between 18.5-20 MHz */
587 hpcd->Instance->GUSBCFG |= (uint32_t)((0xB << 10) & USB_OTG_GUSBCFG_TRDT);
588 }
589
590 else if((hclk >= 20000000)&&(hclk < 21800000))
591 {
592 /* hclk Clock Range between 20-21.8 MHz */
593 hpcd->Instance->GUSBCFG |= (uint32_t)((0xA << 10) & USB_OTG_GUSBCFG_TRDT);
594 }
595
596 else if((hclk >= 21800000)&&(hclk < 24000000))
597 {
598 /* hclk Clock Range between 21.8-24 MHz */
599 hpcd->Instance->GUSBCFG |= (uint32_t)((0x9 << 10) & USB_OTG_GUSBCFG_TRDT);
600 }
601
602 else if((hclk >= 24000000)&&(hclk < 27700000))
603 {
604 /* hclk Clock Range between 24-27.7 MHz */
605 hpcd->Instance->GUSBCFG |= (uint32_t)((0x8 << 10) & USB_OTG_GUSBCFG_TRDT);
606 }
607
608 else if((hclk >= 27700000)&&(hclk < 32000000))
609 {
610 /* hclk Clock Range between 27.7-32 MHz */
611 hpcd->Instance->GUSBCFG |= (uint32_t)((0x7 << 10) & USB_OTG_GUSBCFG_TRDT);
612 }
613
614 else /* if(hclk >= 32000000) */
615 {
616 /* hclk Clock Range between 32-200 MHz */
617 hpcd->Instance->GUSBCFG |= (uint32_t)((0x6 << 10) & USB_OTG_GUSBCFG_TRDT);
618 }
619 }
620
621 HAL_PCD_ResetCallback(hpcd);
622
623 __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_ENUMDNE);
624 }
625
626 /* Handle RxQLevel Interrupt */
627 if(__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_RXFLVL))
628 {
629 USB_MASK_INTERRUPT(hpcd->Instance, USB_OTG_GINTSTS_RXFLVL);
630 temp = USBx->GRXSTSP;
631 ep = &hpcd->OUT_ep[temp & USB_OTG_GRXSTSP_EPNUM];
632
633 if(((temp & USB_OTG_GRXSTSP_PKTSTS) >> 17) == STS_DATA_UPDT)
634 {
635 if((temp & USB_OTG_GRXSTSP_BCNT) != 0)
636 {
637 USB_ReadPacket(USBx, ep->xfer_buff, (temp & USB_OTG_GRXSTSP_BCNT) >> 4);
638 ep->xfer_buff += (temp & USB_OTG_GRXSTSP_BCNT) >> 4;
639 ep->xfer_count += (temp & USB_OTG_GRXSTSP_BCNT) >> 4;
640 }
641 }
642 else if (((temp & USB_OTG_GRXSTSP_PKTSTS) >> 17) == STS_SETUP_UPDT)
643 {
644 USB_ReadPacket(USBx, (uint8_t *)hpcd->Setup, 8);
645 ep->xfer_count += (temp & USB_OTG_GRXSTSP_BCNT) >> 4;
646 }
647 USB_UNMASK_INTERRUPT(hpcd->Instance, USB_OTG_GINTSTS_RXFLVL);
648 }
649
650 /* Handle SOF Interrupt */
651 if(__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_SOF))
652 {
653 HAL_PCD_SOFCallback(hpcd);
654 __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_SOF);
655 }
656
657 /* Handle Incomplete ISO IN Interrupt */
658 if(__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_IISOIXFR))
659 {
660 HAL_PCD_ISOINIncompleteCallback(hpcd, epnum);
661 __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_IISOIXFR);
662 }
663
664 /* Handle Incomplete ISO OUT Interrupt */
665 if(__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_PXFR_INCOMPISOOUT))
666 {
667 HAL_PCD_ISOOUTIncompleteCallback(hpcd, epnum);
668 __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_PXFR_INCOMPISOOUT);
669 }
670
671 /* Handle Connection event Interrupt */
672 if(__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_SRQINT))
673 {
674 HAL_PCD_ConnectCallback(hpcd);
675 __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_SRQINT);
676 }
677
678 /* Handle Disconnection event Interrupt */
679 if(__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_OTGINT))
680 {
681 temp = hpcd->Instance->GOTGINT;
682
683 if((temp & USB_OTG_GOTGINT_SEDET) == USB_OTG_GOTGINT_SEDET)
684 {
685 HAL_PCD_DisconnectCallback(hpcd);
686 }
687 hpcd->Instance->GOTGINT |= temp;
688 }
689 }
690 }
691
692 /**
693 * @brief Data OUT stage callback.
694 * @param hpcd: PCD handle
695 * @param epnum: endpoint number
696 * @retval None
697 */
698 __weak void HAL_PCD_DataOutStageCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum)
699 {
700 /* Prevent unused argument(s) compilation warning */
701 UNUSED(hpcd);
702 UNUSED(epnum);
703 /* NOTE : This function Should not be modified, when the callback is needed,
704 the HAL_PCD_DataOutStageCallback could be implemented in the user file
705 */
706 }
707
708 /**
709 * @brief Data IN stage callback.
710 * @param hpcd: PCD handle
711 * @param epnum: endpoint number
712 * @retval None
713 */
714 __weak void HAL_PCD_DataInStageCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum)
715 {
716 /* Prevent unused argument(s) compilation warning */
717 UNUSED(hpcd);
718 UNUSED(epnum);
719 /* NOTE : This function Should not be modified, when the callback is needed,
720 the HAL_PCD_DataInStageCallback could be implemented in the user file
721 */
722 }
723 /**
724 * @brief Setup stage callback.
725 * @param hpcd: PCD handle
726 * @retval None
727 */
728 __weak void HAL_PCD_SetupStageCallback(PCD_HandleTypeDef *hpcd)
729 {
730 /* Prevent unused argument(s) compilation warning */
731 UNUSED(hpcd);
732
733 /* NOTE : This function Should not be modified, when the callback is needed,
734 the HAL_PCD_SetupStageCallback could be implemented in the user file
735 */
736 }
737
738 /**
739 * @brief USB Start Of Frame callback.
740 * @param hpcd: PCD handle
741 * @retval None
742 */
743 __weak void HAL_PCD_SOFCallback(PCD_HandleTypeDef *hpcd)
744 {
745 /* Prevent unused argument(s) compilation warning */
746 UNUSED(hpcd);
747
748 /* NOTE : This function Should not be modified, when the callback is needed,
749 the HAL_PCD_SOFCallback could be implemented in the user file
750 */
751 }
752
753 /**
754 * @brief USB Reset callback.
755 * @param hpcd: PCD handle
756 * @retval None
757 */
758 __weak void HAL_PCD_ResetCallback(PCD_HandleTypeDef *hpcd)
759 {
760 /* Prevent unused argument(s) compilation warning */
761 UNUSED(hpcd);
762
763 /* NOTE : This function Should not be modified, when the callback is needed,
764 the HAL_PCD_ResetCallback could be implemented in the user file
765 */
766 }
767
768 /**
769 * @brief Suspend event callback.
770 * @param hpcd: PCD handle
771 * @retval None
772 */
773 __weak void HAL_PCD_SuspendCallback(PCD_HandleTypeDef *hpcd)
774 {
775 /* Prevent unused argument(s) compilation warning */
776 UNUSED(hpcd);
777
778 /* NOTE : This function Should not be modified, when the callback is needed,
779 the HAL_PCD_SuspendCallback could be implemented in the user file
780 */
781 }
782
783 /**
784 * @brief Resume event callback.
785 * @param hpcd: PCD handle
786 * @retval None
787 */
788 __weak void HAL_PCD_ResumeCallback(PCD_HandleTypeDef *hpcd)
789 {
790 /* Prevent unused argument(s) compilation warning */
791 UNUSED(hpcd);
792
793 /* NOTE : This function Should not be modified, when the callback is needed,
794 the HAL_PCD_ResumeCallback could be implemented in the user file
795 */
796 }
797
798 /**
799 * @brief Incomplete ISO OUT callback.
800 * @param hpcd: PCD handle
801 * @param epnum: endpoint number
802 * @retval None
803 */
804 __weak void HAL_PCD_ISOOUTIncompleteCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum)
805 {
806 /* Prevent unused argument(s) compilation warning */
807 UNUSED(hpcd);
808 UNUSED(epnum);
809 /* NOTE : This function Should not be modified, when the callback is needed,
810 the HAL_PCD_ISOOUTIncompleteCallback could be implemented in the user file
811 */
812 }
813
814 /**
815 * @brief Incomplete ISO IN callback.
816 * @param hpcd: PCD handle
817 * @param epnum: endpoint number
818 * @retval None
819 */
820 __weak void HAL_PCD_ISOINIncompleteCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum)
821 {
822 /* Prevent unused argument(s) compilation warning */
823 UNUSED(hpcd);
824 UNUSED(epnum);
825 /* NOTE : This function Should not be modified, when the callback is needed,
826 the HAL_PCD_ISOINIncompleteCallback could be implemented in the user file
827 */
828 }
829
830 /**
831 * @brief Connection event callback.
832 * @param hpcd: PCD handle
833 * @retval None
834 */
835 __weak void HAL_PCD_ConnectCallback(PCD_HandleTypeDef *hpcd)
836 {
837 /* Prevent unused argument(s) compilation warning */
838 UNUSED(hpcd);
839
840 /* NOTE : This function Should not be modified, when the callback is needed,
841 the HAL_PCD_ConnectCallback could be implemented in the user file
842 */
843 }
844
845 /**
846 * @brief Disconnection event callback.
847 * @param hpcd: PCD handle
848 * @retval None
849 */
850 __weak void HAL_PCD_DisconnectCallback(PCD_HandleTypeDef *hpcd)
851 {
852 /* Prevent unused argument(s) compilation warning */
853 UNUSED(hpcd);
854
855 /* NOTE : This function Should not be modified, when the callback is needed,
856 the HAL_PCD_DisconnectCallback could be implemented in the user file
857 */
858 }
859
860 /**
861 * @}
862 */
863
864 /** @defgroup PCD_Exported_Functions_Group3 Peripheral Control functions
865 * @brief management functions
866 *
867 @verbatim
868 ===============================================================================
869 ##### Peripheral Control functions #####
870 ===============================================================================
871 [..]
872 This subsection provides a set of functions allowing to control the PCD data
873 transfers.
874
875 @endverbatim
876 * @{
877 */
878
879 /**
880 * @brief Connect the USB device.
881 * @param hpcd: PCD handle
882 * @retval HAL status
883 */
884 HAL_StatusTypeDef HAL_PCD_DevConnect(PCD_HandleTypeDef *hpcd)
885 {
886 __HAL_LOCK(hpcd);
887 USB_DevConnect(hpcd->Instance);
888 __HAL_UNLOCK(hpcd);
889 return HAL_OK;
890 }
891
892 /**
893 * @brief Disconnect the USB device.
894 * @param hpcd: PCD handle
895 * @retval HAL status
896 */
897 HAL_StatusTypeDef HAL_PCD_DevDisconnect(PCD_HandleTypeDef *hpcd)
898 {
899 __HAL_LOCK(hpcd);
900 USB_DevDisconnect(hpcd->Instance);
901 __HAL_UNLOCK(hpcd);
902 return HAL_OK;
903 }
904
905 /**
906 * @brief Set the USB Device address.
907 * @param hpcd: PCD handle
908 * @param address: new device address
909 * @retval HAL status
910 */
911 HAL_StatusTypeDef HAL_PCD_SetAddress(PCD_HandleTypeDef *hpcd, uint8_t address)
912 {
913 __HAL_LOCK(hpcd);
914 USB_SetDevAddress(hpcd->Instance, address);
915 __HAL_UNLOCK(hpcd);
916 return HAL_OK;
917 }
918 /**
919 * @brief Open and configure an endpoint.
920 * @param hpcd: PCD handle
921 * @param ep_addr: endpoint address
922 * @param ep_mps: endpoint max packet size
923 * @param ep_type: endpoint type
924 * @retval HAL status
925 */
926 HAL_StatusTypeDef HAL_PCD_EP_Open(PCD_HandleTypeDef *hpcd, uint8_t ep_addr, uint16_t ep_mps, uint8_t ep_type)
927 {
928 HAL_StatusTypeDef ret = HAL_OK;
929 USB_OTG_EPTypeDef *ep;
930
931 if ((ep_addr & 0x80) == 0x80)
932 {
933 ep = &hpcd->IN_ep[ep_addr & 0x7F];
934 }
935 else
936 {
937 ep = &hpcd->OUT_ep[ep_addr & 0x7F];
938 }
939 ep->num = ep_addr & 0x7F;
940
941 ep->is_in = (0x80 & ep_addr) != 0;
942 ep->maxpacket = ep_mps;
943 ep->type = ep_type;
944 if (ep->is_in)
945 {
946 /* Assign a Tx FIFO */
947 ep->tx_fifo_num = ep->num;
948 }
949 /* Set initial data PID. */
950 if (ep_type == EP_TYPE_BULK )
951 {
952 ep->data_pid_start = 0;
953 }
954
955 __HAL_LOCK(hpcd);
956 USB_ActivateEndpoint(hpcd->Instance , ep);
957 __HAL_UNLOCK(hpcd);
958 return ret;
959 }
960
961
962 /**
963 * @brief Deactivate an endpoint.
964 * @param hpcd: PCD handle
965 * @param ep_addr: endpoint address
966 * @retval HAL status
967 */
968 HAL_StatusTypeDef HAL_PCD_EP_Close(PCD_HandleTypeDef *hpcd, uint8_t ep_addr)
969 {
970 USB_OTG_EPTypeDef *ep;
971
972 if ((ep_addr & 0x80) == 0x80)
973 {
974 ep = &hpcd->IN_ep[ep_addr & 0x7F];
975 }
976 else
977 {
978 ep = &hpcd->OUT_ep[ep_addr & 0x7F];
979 }
980 ep->num = ep_addr & 0x7F;
981
982 ep->is_in = (0x80 & ep_addr) != 0;
983
984 __HAL_LOCK(hpcd);
985 USB_DeactivateEndpoint(hpcd->Instance , ep);
986 __HAL_UNLOCK(hpcd);
987 return HAL_OK;
988 }
989
990
991 /**
992 * @brief Receive an amount of data.
993 * @param hpcd: PCD handle
994 * @param ep_addr: endpoint address
995 * @param pBuf: pointer to the reception buffer
996 * @param len: amount of data to be received
997 * @retval HAL status
998 */
999 HAL_StatusTypeDef HAL_PCD_EP_Receive(PCD_HandleTypeDef *hpcd, uint8_t ep_addr, uint8_t *pBuf, uint32_t len)
1000 {
1001 USB_OTG_EPTypeDef *ep;
1002
1003 ep = &hpcd->OUT_ep[ep_addr & 0x7F];
1004
1005 /*setup and start the Xfer */
1006 ep->xfer_buff = pBuf;
1007 ep->xfer_len = len;
1008 ep->xfer_count = 0;
1009 ep->is_in = 0;
1010 ep->num = ep_addr & 0x7F;
1011
1012 if (hpcd->Init.dma_enable == 1)
1013 {
1014 ep->dma_addr = (uint32_t)pBuf;
1015 }
1016
1017 __HAL_LOCK(hpcd);
1018
1019 if ((ep_addr & 0x7F) == 0 )
1020 {
1021 USB_EP0StartXfer(hpcd->Instance , ep, hpcd->Init.dma_enable);
1022 }
1023 else
1024 {
1025 USB_EPStartXfer(hpcd->Instance , ep, hpcd->Init.dma_enable);
1026 }
1027 __HAL_UNLOCK(hpcd);
1028
1029 return HAL_OK;
1030 }
1031
1032 /**
1033 * @brief Get Received Data Size.
1034 * @param hpcd: PCD handle
1035 * @param ep_addr: endpoint address
1036 * @retval Data Size
1037 */
1038 uint16_t HAL_PCD_EP_GetRxCount(PCD_HandleTypeDef *hpcd, uint8_t ep_addr)
1039 {
1040 return hpcd->OUT_ep[ep_addr & 0x7F].xfer_count;
1041 }
1042 /**
1043 * @brief Send an amount of data.
1044 * @param hpcd: PCD handle
1045 * @param ep_addr: endpoint address
1046 * @param pBuf: pointer to the transmission buffer
1047 * @param len: amount of data to be sent
1048 * @retval HAL status
1049 */
1050 HAL_StatusTypeDef HAL_PCD_EP_Transmit(PCD_HandleTypeDef *hpcd, uint8_t ep_addr, uint8_t *pBuf, uint32_t len)
1051 {
1052 USB_OTG_EPTypeDef *ep;
1053
1054 ep = &hpcd->IN_ep[ep_addr & 0x7F];
1055
1056 /*setup and start the Xfer */
1057 ep->xfer_buff = pBuf;
1058 ep->xfer_len = len;
1059 ep->xfer_count = 0;
1060 ep->is_in = 1;
1061 ep->num = ep_addr & 0x7F;
1062
1063 if (hpcd->Init.dma_enable == 1)
1064 {
1065 ep->dma_addr = (uint32_t)pBuf;
1066 }
1067
1068 __HAL_LOCK(hpcd);
1069
1070 if ((ep_addr & 0x7F) == 0 )
1071 {
1072 USB_EP0StartXfer(hpcd->Instance , ep, hpcd->Init.dma_enable);
1073 }
1074 else
1075 {
1076 USB_EPStartXfer(hpcd->Instance , ep, hpcd->Init.dma_enable);
1077 }
1078
1079 __HAL_UNLOCK(hpcd);
1080
1081 return HAL_OK;
1082 }
1083
1084 /**
1085 * @brief Set a STALL condition over an endpoint.
1086 * @param hpcd: PCD handle
1087 * @param ep_addr: endpoint address
1088 * @retval HAL status
1089 */
1090 HAL_StatusTypeDef HAL_PCD_EP_SetStall(PCD_HandleTypeDef *hpcd, uint8_t ep_addr)
1091 {
1092 USB_OTG_EPTypeDef *ep;
1093
1094 if ((0x80 & ep_addr) == 0x80)
1095 {
1096 ep = &hpcd->IN_ep[ep_addr & 0x7F];
1097 }
1098 else
1099 {
1100 ep = &hpcd->OUT_ep[ep_addr];
1101 }
1102
1103 ep->is_stall = 1;
1104 ep->num = ep_addr & 0x7F;
1105 ep->is_in = ((ep_addr & 0x80) == 0x80);
1106
1107
1108 __HAL_LOCK(hpcd);
1109 USB_EPSetStall(hpcd->Instance , ep);
1110 if((ep_addr & 0x7F) == 0)
1111 {
1112 USB_EP0_OutStart(hpcd->Instance, hpcd->Init.dma_enable, (uint8_t *)hpcd->Setup);
1113 }
1114 __HAL_UNLOCK(hpcd);
1115
1116 return HAL_OK;
1117 }
1118
1119 /**
1120 * @brief Clear a STALL condition over in an endpoint.
1121 * @param hpcd: PCD handle
1122 * @param ep_addr: endpoint address
1123 * @retval HAL status
1124 */
1125 HAL_StatusTypeDef HAL_PCD_EP_ClrStall(PCD_HandleTypeDef *hpcd, uint8_t ep_addr)
1126 {
1127 USB_OTG_EPTypeDef *ep;
1128
1129 if ((0x80 & ep_addr) == 0x80)
1130 {
1131 ep = &hpcd->IN_ep[ep_addr & 0x7F];
1132 }
1133 else
1134 {
1135 ep = &hpcd->OUT_ep[ep_addr];
1136 }
1137
1138 ep->is_stall = 0;
1139 ep->num = ep_addr & 0x7F;
1140 ep->is_in = ((ep_addr & 0x80) == 0x80);
1141
1142 __HAL_LOCK(hpcd);
1143 USB_EPClearStall(hpcd->Instance , ep);
1144 __HAL_UNLOCK(hpcd);
1145
1146 return HAL_OK;
1147 }
1148
1149 /**
1150 * @brief Flush an endpoint.
1151 * @param hpcd: PCD handle
1152 * @param ep_addr: endpoint address
1153 * @retval HAL status
1154 */
1155 HAL_StatusTypeDef HAL_PCD_EP_Flush(PCD_HandleTypeDef *hpcd, uint8_t ep_addr)
1156 {
1157 __HAL_LOCK(hpcd);
1158
1159 if ((ep_addr & 0x80) == 0x80)
1160 {
1161 USB_FlushTxFifo(hpcd->Instance, ep_addr & 0x7F);
1162 }
1163 else
1164 {
1165 USB_FlushRxFifo(hpcd->Instance);
1166 }
1167
1168 __HAL_UNLOCK(hpcd);
1169
1170 return HAL_OK;
1171 }
1172
1173 /**
1174 * @brief Activate remote wakeup signalling.
1175 * @param hpcd: PCD handle
1176 * @retval HAL status
1177 */
1178 HAL_StatusTypeDef HAL_PCD_ActivateRemoteWakeup(PCD_HandleTypeDef *hpcd)
1179 {
1180 USB_OTG_GlobalTypeDef *USBx = hpcd->Instance;
1181
1182 if((USBx_DEVICE->DSTS & USB_OTG_DSTS_SUSPSTS) == USB_OTG_DSTS_SUSPSTS)
1183 {
1184 /* Activate Remote wakeup signaling */
1185 USBx_DEVICE->DCTL |= USB_OTG_DCTL_RWUSIG;
1186 }
1187 return HAL_OK;
1188 }
1189
1190 /**
1191 * @brief De-activate remote wakeup signalling.
1192 * @param hpcd: PCD handle
1193 * @retval HAL status
1194 */
1195 HAL_StatusTypeDef HAL_PCD_DeActivateRemoteWakeup(PCD_HandleTypeDef *hpcd)
1196 {
1197 USB_OTG_GlobalTypeDef *USBx = hpcd->Instance;
1198
1199 /* De-activate Remote wakeup signaling */
1200 USBx_DEVICE->DCTL &= ~(USB_OTG_DCTL_RWUSIG);
1201 return HAL_OK;
1202 }
1203 /**
1204 * @}
1205 */
1206
1207 /** @defgroup PCD_Exported_Functions_Group4 Peripheral State functions
1208 * @brief Peripheral State functions
1209 *
1210 @verbatim
1211 ===============================================================================
1212 ##### Peripheral State functions #####
1213 ===============================================================================
1214 [..]
1215 This subsection permits to get in run-time the status of the peripheral
1216 and the data flow.
1217
1218 @endverbatim
1219 * @{
1220 */
1221
1222 /**
1223 * @brief Return the PCD handle state.
1224 * @param hpcd: PCD handle
1225 * @retval HAL state
1226 */
1227 PCD_StateTypeDef HAL_PCD_GetState(PCD_HandleTypeDef *hpcd)
1228 {
1229 return hpcd->State;
1230 }
1231 /**
1232 * @}
1233 */
1234
1235 /**
1236 * @}
1237 */
1238
1239 /* Private functions ---------------------------------------------------------*/
1240 /** @addtogroup PCD_Private_Functions
1241 * @{
1242 */
1243
1244 /**
1245 * @brief Check FIFO for the next packet to be loaded.
1246 * @param hpcd: PCD handle
1247 * @param epnum : endpoint number
1248 * @retval HAL status
1249 */
1250 static HAL_StatusTypeDef PCD_WriteEmptyTxFifo(PCD_HandleTypeDef *hpcd, uint32_t epnum)
1251 {
1252 USB_OTG_GlobalTypeDef *USBx = hpcd->Instance;
1253 USB_OTG_EPTypeDef *ep;
1254 int32_t len = 0;
1255 uint32_t len32b;
1256 uint32_t fifoemptymsk = 0;
1257
1258 ep = &hpcd->IN_ep[epnum];
1259 len = ep->xfer_len - ep->xfer_count;
1260
1261 if (len > ep->maxpacket)
1262 {
1263 len = ep->maxpacket;
1264 }
1265
1266
1267 len32b = (len + 3) / 4;
1268
1269 while ( (USBx_INEP(epnum)->DTXFSTS & USB_OTG_DTXFSTS_INEPTFSAV) > len32b &&
1270 ep->xfer_count < ep->xfer_len &&
1271 ep->xfer_len != 0)
1272 {
1273 /* Write the FIFO */
1274 len = ep->xfer_len - ep->xfer_count;
1275
1276 if (len > ep->maxpacket)
1277 {
1278 len = ep->maxpacket;
1279 }
1280 len32b = (len + 3) / 4;
1281
1282 USB_WritePacket(USBx, ep->xfer_buff, epnum, len, hpcd->Init.dma_enable);
1283
1284 ep->xfer_buff += len;
1285 ep->xfer_count += len;
1286 }
1287
1288 if(len <= 0)
1289 {
1290 fifoemptymsk = 0x1 << epnum;
1291 USBx_DEVICE->DIEPEMPMSK &= ~fifoemptymsk;
1292
1293 }
1294
1295 return HAL_OK;
1296 }
1297
1298 /**
1299 * @}
1300 */
1301
1302 #endif /* HAL_PCD_MODULE_ENABLED */
1303 /**
1304 * @}
1305 */
1306
1307 /**
1308 * @}
1309 */
1310
1311 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/