2 ******************************************************************************
3 * @file stm32f4xx_hal_pcd.c
4 * @author MCD Application Team
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
16 ==============================================================================
17 ##### How to use this driver #####
18 ==============================================================================
20 The PCD HAL driver can be used as follows:
22 (#) Declare a PCD_HandleTypeDef handle structure, for example:
23 PCD_HandleTypeDef hpcd;
25 (#) Fill parameters of Init structure in HCD handle
27 (#) Call HAL_PCD_Init() API to initialize the HCD peripheral (Core, Device core, ...)
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)
34 (##) Initialize the related GPIO clocks
35 (##) Configure PCD pin-out
36 (##) Configure PCD NVIC interrupt
38 (#)Associate the Upper USB device stack to the HAL PCD Driver:
39 (##) hpcd.pData = pdev;
41 (#)Enable HCD transmission and reception:
45 ******************************************************************************
48 * <h2><center>© COPYRIGHT(c) 2014 STMicroelectronics</center></h2>
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.
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.
72 ******************************************************************************
75 /* Includes ------------------------------------------------------------------*/
76 #include "stm32f4xx_hal.h"
78 /** @addtogroup STM32F4xx_HAL_Driver
83 * @brief PCD HAL module driver
87 #ifdef HAL_PCD_MODULE_ENABLED
89 /* Private typedef -----------------------------------------------------------*/
90 /* Private define ------------------------------------------------------------*/
91 /* Private macro -------------------------------------------------------------*/
92 #define PCD_MIN(a, b) (((a) < (b)) ? (a) : (b))
93 #define PCD_MAX(a, b) (((a) > (b)) ? (a) : (b))
94 /* Private variables ---------------------------------------------------------*/
95 /* Private function prototypes -----------------------------------------------*/
96 static HAL_StatusTypeDef
PCD_WriteEmptyTxFifo(PCD_HandleTypeDef
*hpcd
, uint32_t epnum
);
97 /* Private functions ---------------------------------------------------------*/
99 /** @defgroup PCD_Private_Functions
103 /** @defgroup PCD_Group1 Initialization and de-initialization functions
104 * @brief Initialization and Configuration functions
107 ===============================================================================
108 ##### Initialization and de-initialization functions #####
109 ===============================================================================
110 [..] This section provides functions allowing to:
117 * @brief Initializes the PCD according to the specified
118 * parameters in the PCD_InitTypeDef and create the associated handle.
119 * @param hpcd: PCD handle
122 HAL_StatusTypeDef
HAL_PCD_Init(PCD_HandleTypeDef
*hpcd
)
126 /* Check the PCD handle allocation */
132 /* Check the parameters */
133 assert_param(IS_PCD_ALL_INSTANCE(hpcd
->Instance
));
135 hpcd
->State
= HAL_PCD_STATE_BUSY
;
137 /* Init the low level hardware : GPIO, CLOCK, NVIC... */
138 HAL_PCD_MspInit(hpcd
);
140 /* Disable the Interrupts */
141 __HAL_PCD_DISABLE(hpcd
);
143 /*Init the Core (common init.) */
144 USB_CoreInit(hpcd
->Instance
, hpcd
->Init
);
146 /* Force Device Mode*/
147 USB_SetCurrentMode(hpcd
->Instance
, USB_OTG_DEVICE_MODE
);
149 /* Init endpoints structures */
150 for (i
= 0; i
< 15 ; i
++)
152 /* Init ep structure */
153 hpcd
->IN_ep
[i
].is_in
= 1;
154 hpcd
->IN_ep
[i
].num
= i
;
155 hpcd
->IN_ep
[i
].tx_fifo_num
= i
;
156 /* Control until ep is actvated */
157 hpcd
->IN_ep
[i
].type
= EP_TYPE_CTRL
;
158 hpcd
->IN_ep
[i
].maxpacket
= 0;
159 hpcd
->IN_ep
[i
].xfer_buff
= 0;
160 hpcd
->IN_ep
[i
].xfer_len
= 0;
163 for (i
= 0; i
< 15 ; i
++)
165 hpcd
->OUT_ep
[i
].is_in
= 0;
166 hpcd
->OUT_ep
[i
].num
= i
;
167 hpcd
->IN_ep
[i
].tx_fifo_num
= i
;
168 /* Control until ep is activated */
169 hpcd
->OUT_ep
[i
].type
= EP_TYPE_CTRL
;
170 hpcd
->OUT_ep
[i
].maxpacket
= 0;
171 hpcd
->OUT_ep
[i
].xfer_buff
= 0;
172 hpcd
->OUT_ep
[i
].xfer_len
= 0;
174 hpcd
->Instance
->DIEPTXF
[i
] = 0;
178 USB_DevInit(hpcd
->Instance
, hpcd
->Init
);
180 hpcd
->State
= HAL_PCD_STATE_READY
;
182 USB_DevDisconnect (hpcd
->Instance
);
187 * @brief DeInitializes the PCD peripheral
188 * @param hpcd: PCD handle
191 HAL_StatusTypeDef
HAL_PCD_DeInit(PCD_HandleTypeDef
*hpcd
)
193 /* Check the PCD handle allocation */
199 hpcd
->State
= HAL_PCD_STATE_BUSY
;
204 /* DeInit the low level hardware */
205 HAL_PCD_MspDeInit(hpcd
);
207 hpcd
->State
= HAL_PCD_STATE_RESET
;
213 * @brief Initializes the PCD MSP.
214 * @param hpcd: PCD handle
217 __weak
void HAL_PCD_MspInit(PCD_HandleTypeDef
*hpcd
)
219 /* NOTE : This function Should not be modified, when the callback is needed,
220 the HAL_PCD_MspInit could be implenetd in the user file
225 * @brief DeInitializes PCD MSP.
226 * @param hpcd: PCD handle
229 __weak
void HAL_PCD_MspDeInit(PCD_HandleTypeDef
*hpcd
)
231 /* NOTE : This function Should not be modified, when the callback is needed,
232 the HAL_PCD_MspDeInit could be implenetd in the user file
240 /** @defgroup PCD_Group2 IO operation functions
241 * @brief Data transfers functions
244 ===============================================================================
245 ##### IO operation functions #####
246 ===============================================================================
248 This subsection provides a set of functions allowing to manage the PCD data
256 * @brief Start The USB OTG Device.
257 * @param hpcd: PCD handle
260 HAL_StatusTypeDef
HAL_PCD_Start(PCD_HandleTypeDef
*hpcd
)
263 USB_DevConnect (hpcd
->Instance
);
264 __HAL_PCD_ENABLE(hpcd
);
270 * @brief Stop The USB OTG Device.
271 * @param hpcd: PCD handle
274 HAL_StatusTypeDef
HAL_PCD_Stop(PCD_HandleTypeDef
*hpcd
)
277 __HAL_PCD_DISABLE(hpcd
);
278 USB_StopDevice(hpcd
->Instance
);
279 USB_DevDisconnect (hpcd
->Instance
);
285 * @brief This function handles PCD interrupt request.
286 * @param hpcd: PCD handle
289 void HAL_PCD_IRQHandler(PCD_HandleTypeDef
*hpcd
)
291 USB_OTG_GlobalTypeDef
*USBx
= hpcd
->Instance
;
292 uint32_t i
= 0, ep_intr
= 0, epint
= 0, epnum
= 0;
293 uint32_t fifoemptymsk
= 0, temp
= 0;
294 USB_OTG_EPTypeDef
*ep
;
296 /* ensure that we are in device mode */
297 if (USB_GetMode(hpcd
->Instance
) == USB_OTG_MODE_DEVICE
)
299 /* avoid spurious interrupt */
300 if(__HAL_PCD_IS_INVALID_INTERRUPT(hpcd
))
305 if(__HAL_PCD_GET_FLAG(hpcd
, USB_OTG_GINTSTS_MMIS
))
307 /* incorrect mode, acknowledge the interrupt */
308 __HAL_PCD_CLEAR_FLAG(hpcd
, USB_OTG_GINTSTS_MMIS
);
311 if(__HAL_PCD_GET_FLAG(hpcd
, USB_OTG_GINTSTS_OEPINT
))
315 /* Read in the device interrupt bits */
316 ep_intr
= USB_ReadDevAllOutEpInterrupt(hpcd
->Instance
);
322 epint
= USB_ReadDevOutEPInterrupt(hpcd
->Instance
, epnum
);
324 if(( epint
& USB_OTG_DOEPINT_XFRC
) == USB_OTG_DOEPINT_XFRC
)
326 CLEAR_OUT_EP_INTR(epnum
, USB_OTG_DOEPINT_XFRC
);
328 if(hpcd
->Init
.dma_enable
== 1)
330 hpcd
->OUT_ep
[epnum
].xfer_count
= hpcd
->OUT_ep
[epnum
].maxpacket
- (USBx_OUTEP(epnum
)->DOEPTSIZ
& USB_OTG_DOEPTSIZ_XFRSIZ
);
331 hpcd
->OUT_ep
[epnum
].xfer_buff
+= hpcd
->OUT_ep
[epnum
].maxpacket
;
334 HAL_PCD_DataOutStageCallback(hpcd
, epnum
);
335 if(hpcd
->Init
.dma_enable
== 1)
337 if((epnum
== 0) && (hpcd
->OUT_ep
[epnum
].xfer_len
== 0))
339 /* this is ZLP, so prepare EP0 for next setup */
340 USB_EP0_OutStart(hpcd
->Instance
, 1, (uint8_t *)hpcd
->Setup
);
345 if(( epint
& USB_OTG_DOEPINT_STUP
) == USB_OTG_DOEPINT_STUP
)
347 /* Inform the upper layer that a setup packet is available */
348 HAL_PCD_SetupStageCallback(hpcd
);
349 CLEAR_OUT_EP_INTR(epnum
, USB_OTG_DOEPINT_STUP
);
352 if(( epint
& USB_OTG_DOEPINT_OTEPDIS
) == USB_OTG_DOEPINT_OTEPDIS
)
354 CLEAR_OUT_EP_INTR(epnum
, USB_OTG_DOEPINT_OTEPDIS
);
362 if(__HAL_PCD_GET_FLAG(hpcd
, USB_OTG_GINTSTS_IEPINT
))
364 /* Read in the device interrupt bits */
365 ep_intr
= USB_ReadDevAllInEpInterrupt(hpcd
->Instance
);
371 if (ep_intr
& 0x1) /* In ITR */
373 epint
= USB_ReadDevInEPInterrupt(hpcd
->Instance
, epnum
);
375 if(( epint
& USB_OTG_DIEPINT_XFRC
) == USB_OTG_DIEPINT_XFRC
)
377 fifoemptymsk
= 0x1 << epnum
;
378 USBx_DEVICE
->DIEPEMPMSK
&= ~fifoemptymsk
;
380 CLEAR_IN_EP_INTR(epnum
, USB_OTG_DIEPINT_XFRC
);
382 if (hpcd
->Init
.dma_enable
== 1)
384 hpcd
->IN_ep
[epnum
].xfer_buff
+= hpcd
->IN_ep
[epnum
].maxpacket
;
387 HAL_PCD_DataInStageCallback(hpcd
, epnum
);
389 if (hpcd
->Init
.dma_enable
== 1)
391 /* this is ZLP, so prepare EP0 for next setup */
392 if((epnum
== 0) && (hpcd
->IN_ep
[epnum
].xfer_len
== 0))
394 /* prepare to rx more setup packets */
395 USB_EP0_OutStart(hpcd
->Instance
, 1, (uint8_t *)hpcd
->Setup
);
399 if(( epint
& USB_OTG_DIEPINT_TOC
) == USB_OTG_DIEPINT_TOC
)
401 CLEAR_IN_EP_INTR(epnum
, USB_OTG_DIEPINT_TOC
);
403 if(( epint
& USB_OTG_DIEPINT_ITTXFE
) == USB_OTG_DIEPINT_ITTXFE
)
405 CLEAR_IN_EP_INTR(epnum
, USB_OTG_DIEPINT_ITTXFE
);
407 if(( epint
& USB_OTG_DIEPINT_INEPNE
) == USB_OTG_DIEPINT_INEPNE
)
409 CLEAR_IN_EP_INTR(epnum
, USB_OTG_DIEPINT_INEPNE
);
411 if(( epint
& USB_OTG_DIEPINT_EPDISD
) == USB_OTG_DIEPINT_EPDISD
)
413 CLEAR_IN_EP_INTR(epnum
, USB_OTG_DIEPINT_EPDISD
);
415 if(( epint
& USB_OTG_DIEPINT_TXFE
) == USB_OTG_DIEPINT_TXFE
)
417 PCD_WriteEmptyTxFifo(hpcd
, epnum
);
425 /* Handle Resume Interrupt */
426 if(__HAL_PCD_GET_FLAG(hpcd
, USB_OTG_GINTSTS_WKUINT
))
428 /* Clear the Remote Wake-up Signaling */
429 USBx_DEVICE
->DCTL
&= ~USB_OTG_DCTL_RWUSIG
;
431 HAL_PCD_ResumeCallback(hpcd
);
433 __HAL_PCD_CLEAR_FLAG(hpcd
, USB_OTG_GINTSTS_WKUINT
);
436 /* Handle Suspend Interrupt */
437 if(__HAL_PCD_GET_FLAG(hpcd
, USB_OTG_GINTSTS_USBSUSP
))
440 if((USBx_DEVICE
->DSTS
& USB_OTG_DSTS_SUSPSTS
) == USB_OTG_DSTS_SUSPSTS
)
443 HAL_PCD_SuspendCallback(hpcd
);
445 __HAL_PCD_CLEAR_FLAG(hpcd
, USB_OTG_GINTSTS_USBSUSP
);
450 /* Handle Reset Interrupt */
451 if(__HAL_PCD_GET_FLAG(hpcd
, USB_OTG_GINTSTS_USBRST
))
453 USBx_DEVICE
->DCTL
&= ~USB_OTG_DCTL_RWUSIG
;
454 USB_FlushTxFifo(hpcd
->Instance
, 0 );
456 for (i
= 0; i
< hpcd
->Init
.dev_endpoints
; i
++)
458 USBx_INEP(i
)->DIEPINT
= 0xFF;
459 USBx_OUTEP(i
)->DOEPINT
= 0xFF;
461 USBx_DEVICE
->DAINT
= 0xFFFFFFFF;
462 USBx_DEVICE
->DAINTMSK
|= 0x10001;
464 if(hpcd
->Init
.use_dedicated_ep1
)
466 USBx_DEVICE
->DOUTEP1MSK
|= (USB_OTG_DOEPMSK_STUPM
| USB_OTG_DOEPMSK_XFRCM
| USB_OTG_DOEPMSK_EPDM
);
467 USBx_DEVICE
->DINEP1MSK
|= (USB_OTG_DIEPMSK_TOM
| USB_OTG_DIEPMSK_XFRCM
| USB_OTG_DIEPMSK_EPDM
);
471 USBx_DEVICE
->DOEPMSK
|= (USB_OTG_DOEPMSK_STUPM
| USB_OTG_DOEPMSK_XFRCM
| USB_OTG_DOEPMSK_EPDM
);
472 USBx_DEVICE
->DIEPMSK
|= (USB_OTG_DIEPMSK_TOM
| USB_OTG_DIEPMSK_XFRCM
| USB_OTG_DIEPMSK_EPDM
);
475 /* Set Default Address to 0 */
476 USBx_DEVICE
->DCFG
&= ~USB_OTG_DCFG_DAD
;
478 /* setup EP0 to receive SETUP packets */
479 USB_EP0_OutStart(hpcd
->Instance
, hpcd
->Init
.dma_enable
, (uint8_t *)hpcd
->Setup
);
481 __HAL_PCD_CLEAR_FLAG(hpcd
, USB_OTG_GINTSTS_USBRST
);
484 /* Handle Enumeration done Interrupt */
485 if(__HAL_PCD_GET_FLAG(hpcd
, USB_OTG_GINTSTS_ENUMDNE
))
487 USB_ActivateSetup(hpcd
->Instance
);
488 hpcd
->Instance
->GUSBCFG
&= ~USB_OTG_GUSBCFG_TRDT
;
490 if ( USB_GetDevSpeed(hpcd
->Instance
) == USB_OTG_SPEED_HIGH
)
492 hpcd
->Init
.speed
= USB_OTG_SPEED_HIGH
;
493 hpcd
->Init
.ep0_mps
= USB_OTG_HS_MAX_PACKET_SIZE
;
494 hpcd
->Instance
->GUSBCFG
|= (USB_OTG_GUSBCFG_TRDT_0
| USB_OTG_GUSBCFG_TRDT_3
);
498 hpcd
->Init
.speed
= USB_OTG_SPEED_FULL
;
499 hpcd
->Init
.ep0_mps
= USB_OTG_FS_MAX_PACKET_SIZE
;
500 hpcd
->Instance
->GUSBCFG
|= (USB_OTG_GUSBCFG_TRDT_0
| USB_OTG_GUSBCFG_TRDT_2
);
503 HAL_PCD_ResetCallback(hpcd
);
505 __HAL_PCD_CLEAR_FLAG(hpcd
, USB_OTG_GINTSTS_ENUMDNE
);
509 /* Handle RxQLevel Interrupt */
510 if(__HAL_PCD_GET_FLAG(hpcd
, USB_OTG_GINTSTS_RXFLVL
))
512 USB_MASK_INTERRUPT(hpcd
->Instance
, USB_OTG_GINTSTS_RXFLVL
);
513 temp
= USBx
->GRXSTSP
;
514 ep
= &hpcd
->OUT_ep
[temp
& USB_OTG_GRXSTSP_EPNUM
];
516 if(((temp
& USB_OTG_GRXSTSP_PKTSTS
) >> 17) == STS_DATA_UPDT
)
518 if((temp
& USB_OTG_GRXSTSP_BCNT
) != 0)
520 USB_ReadPacket(USBx
, ep
->xfer_buff
, (temp
& USB_OTG_GRXSTSP_BCNT
) >> 4);
521 ep
->xfer_buff
+= (temp
& USB_OTG_GRXSTSP_BCNT
) >> 4;
522 ep
->xfer_count
+= (temp
& USB_OTG_GRXSTSP_BCNT
) >> 4;
525 else if (((temp
& USB_OTG_GRXSTSP_PKTSTS
) >> 17) == STS_SETUP_UPDT
)
527 USB_ReadPacket(USBx
, (uint8_t *)hpcd
->Setup
, 8);
528 ep
->xfer_count
+= (temp
& USB_OTG_GRXSTSP_BCNT
) >> 4;
530 USB_UNMASK_INTERRUPT(hpcd
->Instance
, USB_OTG_GINTSTS_RXFLVL
);
533 /* Handle SOF Interrupt */
534 if(__HAL_PCD_GET_FLAG(hpcd
, USB_OTG_GINTSTS_SOF
))
536 HAL_PCD_SOFCallback(hpcd
);
537 __HAL_PCD_CLEAR_FLAG(hpcd
, USB_OTG_GINTSTS_SOF
);
540 /* Handle Incomplete ISO IN Interrupt */
541 if(__HAL_PCD_GET_FLAG(hpcd
, USB_OTG_GINTSTS_IISOIXFR
))
543 HAL_PCD_ISOINIncompleteCallback(hpcd
, epnum
);
544 __HAL_PCD_CLEAR_FLAG(hpcd
, USB_OTG_GINTSTS_IISOIXFR
);
547 /* Handle Incomplete ISO OUT Interrupt */
548 if(__HAL_PCD_GET_FLAG(hpcd
, USB_OTG_GINTSTS_PXFR_INCOMPISOOUT
))
550 HAL_PCD_ISOOUTIncompleteCallback(hpcd
, epnum
);
551 __HAL_PCD_CLEAR_FLAG(hpcd
, USB_OTG_GINTSTS_PXFR_INCOMPISOOUT
);
554 /* Handle Connection event Interrupt */
555 if(__HAL_PCD_GET_FLAG(hpcd
, USB_OTG_GINTSTS_SRQINT
))
557 HAL_PCD_ConnectCallback(hpcd
);
558 __HAL_PCD_CLEAR_FLAG(hpcd
, USB_OTG_GINTSTS_SRQINT
);
561 /* Handle Disconnection event Interrupt */
562 if(__HAL_PCD_GET_FLAG(hpcd
, USB_OTG_GINTSTS_OTGINT
))
564 temp
= hpcd
->Instance
->GOTGINT
;
566 if((temp
& USB_OTG_GOTGINT_SEDET
) == USB_OTG_GOTGINT_SEDET
)
568 HAL_PCD_DisconnectCallback(hpcd
);
570 hpcd
->Instance
->GOTGINT
|= temp
;
576 * @brief Data out stage callbacks
577 * @param hpcd: PCD handle
580 __weak
void HAL_PCD_DataOutStageCallback(PCD_HandleTypeDef
*hpcd
, uint8_t epnum
)
582 /* NOTE : This function Should not be modified, when the callback is needed,
583 the HAL_PCD_DataOutStageCallback could be implenetd in the user file
588 * @brief Data IN stage callbacks
589 * @param hpcd: PCD handle
592 __weak
void HAL_PCD_DataInStageCallback(PCD_HandleTypeDef
*hpcd
, uint8_t epnum
)
594 /* NOTE : This function Should not be modified, when the callback is needed,
595 the HAL_PCD_DataOutStageCallback could be implenetd in the user file
599 * @brief Setup stage callback
600 * @param hpcd: PCD handle
603 __weak
void HAL_PCD_SetupStageCallback(PCD_HandleTypeDef
*hpcd
)
605 /* NOTE : This function Should not be modified, when the callback is needed,
606 the HAL_PCD_DataOutStageCallback could be implenetd in the user file
611 * @brief USB Start Of Frame callbacks
612 * @param hpcd: PCD handle
615 __weak
void HAL_PCD_SOFCallback(PCD_HandleTypeDef
*hpcd
)
617 /* NOTE : This function Should not be modified, when the callback is needed,
618 the HAL_PCD_DataOutStageCallback could be implenetd in the user file
623 * @brief USB Reset callbacks
624 * @param hpcd: PCD handle
627 __weak
void HAL_PCD_ResetCallback(PCD_HandleTypeDef
*hpcd
)
629 /* NOTE : This function Should not be modified, when the callback is needed,
630 the HAL_PCD_DataOutStageCallback could be implenetd in the user file
636 * @brief Suspend event callbacks
637 * @param hpcd: PCD handle
640 __weak
void HAL_PCD_SuspendCallback(PCD_HandleTypeDef
*hpcd
)
642 /* NOTE : This function Should not be modified, when the callback is needed,
643 the HAL_PCD_DataOutStageCallback could be implenetd in the user file
648 * @brief Resume event callbacks
649 * @param hpcd: PCD handle
652 __weak
void HAL_PCD_ResumeCallback(PCD_HandleTypeDef
*hpcd
)
654 /* NOTE : This function Should not be modified, when the callback is needed,
655 the HAL_PCD_DataOutStageCallback could be implenetd in the user file
660 * @brief Incomplete ISO OUT callbacks
661 * @param hpcd: PCD handle
664 __weak
void HAL_PCD_ISOOUTIncompleteCallback(PCD_HandleTypeDef
*hpcd
, uint8_t epnum
)
666 /* NOTE : This function Should not be modified, when the callback is needed,
667 the HAL_PCD_DataOutStageCallback could be implenetd in the user file
672 * @brief Incomplete ISO IN callbacks
673 * @param hpcd: PCD handle
676 __weak
void HAL_PCD_ISOINIncompleteCallback(PCD_HandleTypeDef
*hpcd
, uint8_t epnum
)
678 /* NOTE : This function Should not be modified, when the callback is needed,
679 the HAL_PCD_DataOutStageCallback could be implenetd in the user file
684 * @brief Connection event callbacks
685 * @param hpcd: PCD handle
688 __weak
void HAL_PCD_ConnectCallback(PCD_HandleTypeDef
*hpcd
)
690 /* NOTE : This function Should not be modified, when the callback is needed,
691 the HAL_PCD_DataOutStageCallback could be implenetd in the user file
696 * @brief Disconnection event callbacks
697 * @param hpcd: PCD handle
700 __weak
void HAL_PCD_DisconnectCallback(PCD_HandleTypeDef
*hpcd
)
702 /* NOTE : This function Should not be modified, when the callback is needed,
703 the HAL_PCD_DataOutStageCallback could be implenetd in the user file
711 /** @defgroup PCD_Group3 Peripheral Control functions
712 * @brief management functions
715 ===============================================================================
716 ##### Peripheral Control functions #####
717 ===============================================================================
719 This subsection provides a set of functions allowing to control the PCD data
727 * @brief Send an amount of data in blocking mode
728 * @param hpcd: PCD handle
731 HAL_StatusTypeDef
HAL_PCD_DevConnect(PCD_HandleTypeDef
*hpcd
)
734 USB_DevConnect(hpcd
->Instance
);
740 * @brief Send an amount of data in blocking mode
741 * @param hpcd: PCD handle
744 HAL_StatusTypeDef
HAL_PCD_DevDisconnect(PCD_HandleTypeDef
*hpcd
)
747 USB_DevDisconnect(hpcd
->Instance
);
753 * @brief Set the USB Device address
754 * @param hpcd: PCD handle
755 * @param address: new device address
758 HAL_StatusTypeDef
HAL_PCD_SetAddress(PCD_HandleTypeDef
*hpcd
, uint8_t address
)
761 USB_SetDevAddress(hpcd
->Instance
, address
);
766 * @brief Open and configure an endpoint
767 * @param hpcd: PCD handle
768 * @param ep_addr: endpoint address
769 * @param ep_mps: endpoint max packert size
770 * @param ep_type: endpoint type
773 HAL_StatusTypeDef
HAL_PCD_EP_Open(PCD_HandleTypeDef
*hpcd
, uint8_t ep_addr
, uint16_t ep_mps
, uint8_t ep_type
)
775 HAL_StatusTypeDef ret
= HAL_OK
;
776 USB_OTG_EPTypeDef
*ep
;
778 if ((ep_addr
& 0x80) == 0x80)
780 ep
= &hpcd
->IN_ep
[ep_addr
& 0x7F];
784 ep
= &hpcd
->OUT_ep
[ep_addr
& 0x7F];
786 ep
->num
= ep_addr
& 0x7F;
788 ep
->is_in
= (0x80 & ep_addr
) != 0;
789 ep
->maxpacket
= ep_mps
;
793 /* Assign a Tx FIFO */
794 ep
->tx_fifo_num
= ep
->num
;
796 /* Set initial data PID. */
797 if (ep_type
== EP_TYPE_BULK
)
799 ep
->data_pid_start
= 0;
803 USB_ActivateEndpoint(hpcd
->Instance
, ep
);
810 * @brief Deactivate an endpoint
811 * @param hpcd: PCD handle
812 * @param ep_addr: endpoint address
815 HAL_StatusTypeDef
HAL_PCD_EP_Close(PCD_HandleTypeDef
*hpcd
, uint8_t ep_addr
)
817 USB_OTG_EPTypeDef
*ep
;
819 if ((ep_addr
& 0x80) == 0x80)
821 ep
= &hpcd
->IN_ep
[ep_addr
& 0x7F];
825 ep
= &hpcd
->OUT_ep
[ep_addr
& 0x7F];
827 ep
->num
= ep_addr
& 0x7F;
829 ep
->is_in
= (0x80 & ep_addr
) != 0;
832 USB_DeactivateEndpoint(hpcd
->Instance
, ep
);
839 * @brief Receive an amount of data
840 * @param hpcd: PCD handle
841 * @param ep_addr: endpoint address
842 * @param pBuf: pointer to the reception buffer
843 * @param len: amount of data to be received
846 HAL_StatusTypeDef
HAL_PCD_EP_Receive(PCD_HandleTypeDef
*hpcd
, uint8_t ep_addr
, uint8_t *pBuf
, uint32_t len
)
849 USB_OTG_EPTypeDef
*ep
;
851 ep
= &hpcd
->OUT_ep
[ep_addr
& 0x7F];
853 /*setup and start the Xfer */
854 ep
->xfer_buff
= pBuf
;
858 ep
->num
= ep_addr
& 0x7F;
860 if (hpcd
->Init
.dma_enable
== 1)
862 ep
->dma_addr
= (uint32_t)pBuf
;
867 if ((ep_addr
& 0x7F) == 0 )
869 USB_EP0StartXfer(hpcd
->Instance
, ep
, hpcd
->Init
.dma_enable
);
873 USB_EPStartXfer(hpcd
->Instance
, ep
, hpcd
->Init
.dma_enable
);
881 * @brief Get Received Data Size
882 * @param hpcd: PCD handle
883 * @param ep_addr: endpoint address
886 uint16_t HAL_PCD_EP_GetRxCount(PCD_HandleTypeDef
*hpcd
, uint8_t ep_addr
)
888 return hpcd
->OUT_ep
[ep_addr
& 0x7F].xfer_count
;
891 * @brief Send an amount of data
892 * @param hpcd: PCD handle
893 * @param ep_addr: endpoint address
894 * @param pBuf: pointer to the transmission buffer
895 * @param len: amount of data to be sent
898 HAL_StatusTypeDef
HAL_PCD_EP_Transmit(PCD_HandleTypeDef
*hpcd
, uint8_t ep_addr
, uint8_t *pBuf
, uint32_t len
)
900 USB_OTG_EPTypeDef
*ep
;
902 ep
= &hpcd
->IN_ep
[ep_addr
& 0x7F];
904 /*setup and start the Xfer */
905 ep
->xfer_buff
= pBuf
;
909 ep
->num
= ep_addr
& 0x7F;
911 if (hpcd
->Init
.dma_enable
== 1)
913 ep
->dma_addr
= (uint32_t)pBuf
;
918 if ((ep_addr
& 0x7F) == 0 )
920 USB_EP0StartXfer(hpcd
->Instance
, ep
, hpcd
->Init
.dma_enable
);
924 USB_EPStartXfer(hpcd
->Instance
, ep
, hpcd
->Init
.dma_enable
);
933 * @brief Set a STALL condition over an endpoint
934 * @param hpcd: PCD handle
935 * @param ep_addr: endpoint address
938 HAL_StatusTypeDef
HAL_PCD_EP_SetStall(PCD_HandleTypeDef
*hpcd
, uint8_t ep_addr
)
940 USB_OTG_EPTypeDef
*ep
;
942 if ((0x80 & ep_addr
) == 0x80)
944 ep
= &hpcd
->IN_ep
[ep_addr
& 0x7F];
948 ep
= &hpcd
->OUT_ep
[ep_addr
];
952 ep
->num
= ep_addr
& 0x7F;
953 ep
->is_in
= ((ep_addr
& 0x80) == 0x80);
957 USB_EPSetStall(hpcd
->Instance
, ep
);
958 if((ep_addr
& 0x7F) == 0)
960 USB_EP0_OutStart(hpcd
->Instance
, hpcd
->Init
.dma_enable
, (uint8_t *)hpcd
->Setup
);
968 * @brief Clear a STALL condition over in an endpoint
969 * @param hpcd: PCD handle
970 * @param ep_addr: endpoint address
973 HAL_StatusTypeDef
HAL_PCD_EP_ClrStall(PCD_HandleTypeDef
*hpcd
, uint8_t ep_addr
)
975 USB_OTG_EPTypeDef
*ep
;
977 if ((0x80 & ep_addr
) == 0x80)
979 ep
= &hpcd
->IN_ep
[ep_addr
& 0x7F];
983 ep
= &hpcd
->OUT_ep
[ep_addr
];
987 ep
->num
= ep_addr
& 0x7F;
988 ep
->is_in
= ((ep_addr
& 0x80) == 0x80);
991 USB_EPClearStall(hpcd
->Instance
, ep
);
998 * @brief Flush an endpoint
999 * @param hpcd: PCD handle
1000 * @param ep_addr: endpoint address
1001 * @retval HAL status
1003 HAL_StatusTypeDef
HAL_PCD_EP_Flush(PCD_HandleTypeDef
*hpcd
, uint8_t ep_addr
)
1007 if ((ep_addr
& 0x80) == 0x80)
1009 USB_FlushTxFifo(hpcd
->Instance
, ep_addr
& 0x7F);
1013 USB_FlushRxFifo(hpcd
->Instance
);
1022 * @brief HAL_PCD_ActiveRemoteWakeup : active remote wakeup signalling
1023 * @param hpcd: PCD handle
1024 * @retval HAL status
1026 HAL_StatusTypeDef
HAL_PCD_ActiveRemoteWakeup(PCD_HandleTypeDef
*hpcd
)
1028 USB_OTG_GlobalTypeDef
*USBx
= hpcd
->Instance
;
1030 if((USBx_DEVICE
->DSTS
& USB_OTG_DSTS_SUSPSTS
) == USB_OTG_DSTS_SUSPSTS
)
1032 /* active Remote wakeup signaling */
1033 USBx_DEVICE
->DCTL
|= USB_OTG_DCTL_RWUSIG
;
1039 * @brief HAL_PCD_DeActiveRemoteWakeup : de-active remote wakeup signalling
1040 * @param hpcd: PCD handle
1041 * @retval HAL status
1043 HAL_StatusTypeDef
HAL_PCD_DeActiveRemoteWakeup(PCD_HandleTypeDef
*hpcd
)
1045 USB_OTG_GlobalTypeDef
*USBx
= hpcd
->Instance
;
1047 /* active Remote wakeup signaling */
1048 USBx_DEVICE
->DCTL
&= ~(USB_OTG_DCTL_RWUSIG
);
1055 /** @defgroup PCD_Group4 Peripheral State functions
1056 * @brief Peripheral State functions
1059 ===============================================================================
1060 ##### Peripheral State functions #####
1061 ===============================================================================
1063 This subsection permits to get in run-time the status of the peripheral
1071 * @brief Return the PCD state
1072 * @param hpcd: PCD handle
1075 PCD_StateTypeDef
HAL_PCD_GetState(PCD_HandleTypeDef
*hpcd
)
1084 * @brief DCD_WriteEmptyTxFifo
1085 * check FIFO for the next packet to be loaded
1086 * @param hpcd: PCD handle
1087 * @retval HAL status
1089 static HAL_StatusTypeDef
PCD_WriteEmptyTxFifo(PCD_HandleTypeDef
*hpcd
, uint32_t epnum
)
1091 USB_OTG_GlobalTypeDef
*USBx
= hpcd
->Instance
;
1092 USB_OTG_EPTypeDef
*ep
;
1095 uint32_t fifoemptymsk
= 0;
1097 ep
= &hpcd
->IN_ep
[epnum
];
1098 len
= ep
->xfer_len
- ep
->xfer_count
;
1100 if (len
> ep
->maxpacket
)
1102 len
= ep
->maxpacket
;
1106 len32b
= (len
+ 3) / 4;
1108 while ( (USBx_INEP(epnum
)->DTXFSTS
& USB_OTG_DTXFSTS_INEPTFSAV
) > len32b
&&
1109 ep
->xfer_count
< ep
->xfer_len
&&
1112 /* Write the FIFO */
1113 len
= ep
->xfer_len
- ep
->xfer_count
;
1115 if (len
> ep
->maxpacket
)
1117 len
= ep
->maxpacket
;
1119 len32b
= (len
+ 3) / 4;
1121 USB_WritePacket(USBx
, ep
->xfer_buff
, epnum
, len
, hpcd
->Init
.dma_enable
);
1123 ep
->xfer_buff
+= len
;
1124 ep
->xfer_count
+= len
;
1129 fifoemptymsk
= 0x1 << epnum
;
1130 USBx_DEVICE
->DIEPEMPMSK
&= ~fifoemptymsk
;
1141 #endif /* HAL_PCD_MODULE_ENABLED */
1150 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/