38
|
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****/
|