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