Mercurial > public > ostc4
comparison Common/Drivers/STM32F4xx_HAL_DRIVER_v120/Src/stm32f4xx_hal_hcd.c @ 38:5f11787b4f42
include in ostc4 repository
author | heinrichsweikamp |
---|---|
date | Sat, 28 Apr 2018 11:52:34 +0200 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
37:ccc45c0e1ea2 | 38:5f11787b4f42 |
---|---|
1 /** | |
2 ****************************************************************************** | |
3 * @file stm32f4xx_hal_hcd.c | |
4 * @author MCD Application Team | |
5 * @version V1.2.0 | |
6 * @date 26-December-2014 | |
7 * @brief HCD 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 (#)Declare a HCD_HandleTypeDef handle structure, for example: | |
21 HCD_HandleTypeDef hhcd; | |
22 | |
23 (#)Fill parameters of Init structure in HCD handle | |
24 | |
25 (#)Call HAL_HCD_Init() API to initialize the HCD peripheral (Core, Host core, ...) | |
26 | |
27 (#)Initialize the HCD low level resources through the HAL_HCD_MspInit() API: | |
28 (##) Enable the HCD/USB Low Level interface clock using the following macros | |
29 (+++) __OTGFS-OTG_CLK_ENABLE() or __OTGHS-OTG_CLK_ENABLE() | |
30 (+++) __OTGHSULPI_CLK_ENABLE() For High Speed Mode | |
31 | |
32 (##) Initialize the related GPIO clocks | |
33 (##) Configure HCD pin-out | |
34 (##) Configure HCD NVIC interrupt | |
35 | |
36 (#)Associate the Upper USB Host stack to the HAL HCD Driver: | |
37 (##) hhcd.pData = phost; | |
38 | |
39 (#)Enable HCD transmission and reception: | |
40 (##) HAL_HCD_Start(); | |
41 | |
42 @endverbatim | |
43 ****************************************************************************** | |
44 * @attention | |
45 * | |
46 * <h2><center>© COPYRIGHT(c) 2014 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 /** @addtogroup HCD | |
81 * @{ | |
82 */ | |
83 | |
84 #ifdef HAL_HCD_MODULE_ENABLED | |
85 | |
86 /* Private typedef -----------------------------------------------------------*/ | |
87 /* Private define ------------------------------------------------------------*/ | |
88 /* Private macro -------------------------------------------------------------*/ | |
89 /* Private variables ---------------------------------------------------------*/ | |
90 /* Private function ----------------------------------------------------------*/ | |
91 /** @addtogroup HCD_Private_Functions | |
92 * @{ | |
93 */ | |
94 static void HCD_HC_IN_IRQHandler(HCD_HandleTypeDef *hhcd, uint8_t chnum); | |
95 static void HCD_HC_OUT_IRQHandler(HCD_HandleTypeDef *hhcd, uint8_t chnum); | |
96 static void HCD_RXQLVL_IRQHandler(HCD_HandleTypeDef *hhcd); | |
97 static void HCD_Port_IRQHandler(HCD_HandleTypeDef *hhcd); | |
98 /** | |
99 * @} | |
100 */ | |
101 | |
102 /* Exported functions --------------------------------------------------------*/ | |
103 /** @addtogroup HCD_Exported_Functions | |
104 * @{ | |
105 */ | |
106 | |
107 /** @addtogroup HCD_Exported_Functions_Group1 | |
108 * @brief Initialization and de-initialization functions | |
109 * | |
110 @verbatim | |
111 =============================================================================== | |
112 ##### Initialization and de-initialization functions ##### | |
113 =============================================================================== | |
114 [..] This section provides functions allowing to: | |
115 | |
116 @endverbatim | |
117 * @{ | |
118 */ | |
119 | |
120 /** | |
121 * @brief Initialize the host driver | |
122 * @param hhcd: HCD handle | |
123 * @retval HAL status | |
124 */ | |
125 HAL_StatusTypeDef HAL_HCD_Init(HCD_HandleTypeDef *hhcd) | |
126 { | |
127 /* Check the HCD handle allocation */ | |
128 if(hhcd == NULL) | |
129 { | |
130 return HAL_ERROR; | |
131 } | |
132 | |
133 /* Check the parameters */ | |
134 assert_param(IS_HCD_ALL_INSTANCE(hhcd->Instance)); | |
135 | |
136 hhcd->State = HAL_HCD_STATE_BUSY; | |
137 | |
138 /* Init the low level hardware : GPIO, CLOCK, NVIC... */ | |
139 HAL_HCD_MspInit(hhcd); | |
140 | |
141 /* Disable the Interrupts */ | |
142 __HAL_HCD_DISABLE(hhcd); | |
143 | |
144 /* Init the Core (common init.) */ | |
145 USB_CoreInit(hhcd->Instance, hhcd->Init); | |
146 | |
147 /* Force Host Mode*/ | |
148 USB_SetCurrentMode(hhcd->Instance , USB_OTG_HOST_MODE); | |
149 | |
150 /* Init Host */ | |
151 USB_HostInit(hhcd->Instance, hhcd->Init); | |
152 | |
153 hhcd->State= HAL_HCD_STATE_READY; | |
154 | |
155 return HAL_OK; | |
156 } | |
157 | |
158 /** | |
159 * @brief Initialize a host channel | |
160 * @param hhcd: HCD handle | |
161 * @param ch_num: Channel number. | |
162 * This parameter can be a value from 1 to 15 | |
163 * @param epnum: Endpoint number. | |
164 * This parameter can be a value from 1 to 15 | |
165 * @param dev_address : Current device address | |
166 * This parameter can be a value from 0 to 255 | |
167 * @param speed: Current device speed. | |
168 * This parameter can be one of these values: | |
169 * HCD_SPEED_HIGH: High speed mode, | |
170 * HCD_SPEED_FULL: Full speed mode, | |
171 * HCD_SPEED_LOW: Low speed mode | |
172 * @param ep_type: Endpoint Type. | |
173 * This parameter can be one of these values: | |
174 * EP_TYPE_CTRL: Control type, | |
175 * EP_TYPE_ISOC: Isochronous type, | |
176 * EP_TYPE_BULK: Bulk type, | |
177 * EP_TYPE_INTR: Interrupt type | |
178 * @param mps: Max Packet Size. | |
179 * This parameter can be a value from 0 to32K | |
180 * @retval HAL status | |
181 */ | |
182 HAL_StatusTypeDef HAL_HCD_HC_Init(HCD_HandleTypeDef *hhcd, | |
183 uint8_t ch_num, | |
184 uint8_t epnum, | |
185 uint8_t dev_address, | |
186 uint8_t speed, | |
187 uint8_t ep_type, | |
188 uint16_t mps) | |
189 { | |
190 HAL_StatusTypeDef status = HAL_OK; | |
191 | |
192 __HAL_LOCK(hhcd); | |
193 | |
194 hhcd->hc[ch_num].dev_addr = dev_address; | |
195 hhcd->hc[ch_num].max_packet = mps; | |
196 hhcd->hc[ch_num].ch_num = ch_num; | |
197 hhcd->hc[ch_num].ep_type = ep_type; | |
198 hhcd->hc[ch_num].ep_num = epnum & 0x7F; | |
199 hhcd->hc[ch_num].ep_is_in = ((epnum & 0x80) == 0x80); | |
200 hhcd->hc[ch_num].speed = speed; | |
201 | |
202 status = USB_HC_Init(hhcd->Instance, | |
203 ch_num, | |
204 epnum, | |
205 dev_address, | |
206 speed, | |
207 ep_type, | |
208 mps); | |
209 __HAL_UNLOCK(hhcd); | |
210 | |
211 return status; | |
212 } | |
213 | |
214 /** | |
215 * @brief Halt a host channel | |
216 * @param hhcd: HCD handle | |
217 * @param ch_num: Channel number. | |
218 * This parameter can be a value from 1 to 15 | |
219 * @retval HAL status | |
220 */ | |
221 HAL_StatusTypeDef HAL_HCD_HC_Halt(HCD_HandleTypeDef *hhcd, uint8_t ch_num) | |
222 { | |
223 HAL_StatusTypeDef status = HAL_OK; | |
224 | |
225 __HAL_LOCK(hhcd); | |
226 USB_HC_Halt(hhcd->Instance, ch_num); | |
227 __HAL_UNLOCK(hhcd); | |
228 | |
229 return status; | |
230 } | |
231 | |
232 /** | |
233 * @brief DeInitialize the host driver | |
234 * @param hhcd: HCD handle | |
235 * @retval HAL status | |
236 */ | |
237 HAL_StatusTypeDef HAL_HCD_DeInit(HCD_HandleTypeDef *hhcd) | |
238 { | |
239 /* Check the HCD handle allocation */ | |
240 if(hhcd == NULL) | |
241 { | |
242 return HAL_ERROR; | |
243 } | |
244 | |
245 hhcd->State = HAL_HCD_STATE_BUSY; | |
246 | |
247 /* DeInit the low level hardware */ | |
248 HAL_HCD_MspDeInit(hhcd); | |
249 | |
250 __HAL_HCD_DISABLE(hhcd); | |
251 | |
252 hhcd->State = HAL_HCD_STATE_RESET; | |
253 | |
254 return HAL_OK; | |
255 } | |
256 | |
257 /** | |
258 * @brief Initializes the HCD MSP. | |
259 * @param hhcd: HCD handle | |
260 * @retval None | |
261 */ | |
262 __weak void HAL_HCD_MspInit(HCD_HandleTypeDef *hhcd) | |
263 { | |
264 /* NOTE : This function Should not be modified, when the callback is needed, | |
265 the HAL_PCD_MspInit could be implemented in the user file | |
266 */ | |
267 } | |
268 | |
269 /** | |
270 * @brief DeInitializes HCD MSP. | |
271 * @param hhcd: HCD handle | |
272 * @retval None | |
273 */ | |
274 __weak void HAL_HCD_MspDeInit(HCD_HandleTypeDef *hhcd) | |
275 { | |
276 /* NOTE : This function Should not be modified, when the callback is needed, | |
277 the HAL_PCD_MspDeInit could be implemented in the user file | |
278 */ | |
279 } | |
280 | |
281 /** | |
282 * @} | |
283 */ | |
284 | |
285 /** @addtogroup HCD_Exported_Functions_Group2 | |
286 * @brief HCD IO operation functions | |
287 * | |
288 @verbatim | |
289 =============================================================================== | |
290 ##### IO operation functions ##### | |
291 =============================================================================== | |
292 This subsection provides a set of functions allowing to manage the USB Host Data | |
293 Transfer | |
294 | |
295 @endverbatim | |
296 * @{ | |
297 */ | |
298 | |
299 /** | |
300 * @brief Submit a new URB for processing | |
301 * @param hhcd: HCD handle | |
302 * @param ch_num: Channel number. | |
303 * This parameter can be a value from 1 to 15 | |
304 * @param direction: Channel number. | |
305 * This parameter can be one of these values: | |
306 * 0 : Output / 1 : Input | |
307 * @param ep_type: Endpoint Type. | |
308 * This parameter can be one of these values: | |
309 * EP_TYPE_CTRL: Control type/ | |
310 * EP_TYPE_ISOC: Isochronous type/ | |
311 * EP_TYPE_BULK: Bulk type/ | |
312 * EP_TYPE_INTR: Interrupt type/ | |
313 * @param token: Endpoint Type. | |
314 * This parameter can be one of these values: | |
315 * 0: HC_PID_SETUP / 1: HC_PID_DATA1 | |
316 * @param pbuff: pointer to URB data | |
317 * @param length: Length of URB data | |
318 * @param do_ping: activate do ping protocol (for high speed only). | |
319 * This parameter can be one of these values: | |
320 * 0 : do ping inactive / 1 : do ping active | |
321 * @retval HAL status | |
322 */ | |
323 HAL_StatusTypeDef HAL_HCD_HC_SubmitRequest(HCD_HandleTypeDef *hhcd, | |
324 uint8_t ch_num, | |
325 uint8_t direction, | |
326 uint8_t ep_type, | |
327 uint8_t token, | |
328 uint8_t* pbuff, | |
329 uint16_t length, | |
330 uint8_t do_ping) | |
331 { | |
332 hhcd->hc[ch_num].ep_is_in = direction; | |
333 hhcd->hc[ch_num].ep_type = ep_type; | |
334 | |
335 if(token == 0) | |
336 { | |
337 hhcd->hc[ch_num].data_pid = HC_PID_SETUP; | |
338 } | |
339 else | |
340 { | |
341 hhcd->hc[ch_num].data_pid = HC_PID_DATA1; | |
342 } | |
343 | |
344 /* Manage Data Toggle */ | |
345 switch(ep_type) | |
346 { | |
347 case EP_TYPE_CTRL: | |
348 if((token == 1) && (direction == 0)) /*send data */ | |
349 { | |
350 if ( length == 0 ) | |
351 { /* For Status OUT stage, Length==0, Status Out PID = 1 */ | |
352 hhcd->hc[ch_num].toggle_out = 1; | |
353 } | |
354 | |
355 /* Set the Data Toggle bit as per the Flag */ | |
356 if ( hhcd->hc[ch_num].toggle_out == 0) | |
357 { /* Put the PID 0 */ | |
358 hhcd->hc[ch_num].data_pid = HC_PID_DATA0; | |
359 } | |
360 else | |
361 { /* Put the PID 1 */ | |
362 hhcd->hc[ch_num].data_pid = HC_PID_DATA1; | |
363 } | |
364 if(hhcd->hc[ch_num].urb_state != URB_NOTREADY) | |
365 { | |
366 hhcd->hc[ch_num].do_ping = do_ping; | |
367 } | |
368 } | |
369 break; | |
370 | |
371 case EP_TYPE_BULK: | |
372 if(direction == 0) | |
373 { | |
374 /* Set the Data Toggle bit as per the Flag */ | |
375 if ( hhcd->hc[ch_num].toggle_out == 0) | |
376 { /* Put the PID 0 */ | |
377 hhcd->hc[ch_num].data_pid = HC_PID_DATA0; | |
378 } | |
379 else | |
380 { /* Put the PID 1 */ | |
381 hhcd->hc[ch_num].data_pid = HC_PID_DATA1; | |
382 } | |
383 if(hhcd->hc[ch_num].urb_state != URB_NOTREADY) | |
384 { | |
385 hhcd->hc[ch_num].do_ping = do_ping; | |
386 } | |
387 } | |
388 else | |
389 { | |
390 if( hhcd->hc[ch_num].toggle_in == 0) | |
391 { | |
392 hhcd->hc[ch_num].data_pid = HC_PID_DATA0; | |
393 } | |
394 else | |
395 { | |
396 hhcd->hc[ch_num].data_pid = HC_PID_DATA1; | |
397 } | |
398 } | |
399 | |
400 break; | |
401 case EP_TYPE_INTR: | |
402 if(direction == 0) | |
403 { | |
404 /* Set the Data Toggle bit as per the Flag */ | |
405 if ( hhcd->hc[ch_num].toggle_out == 0) | |
406 { /* Put the PID 0 */ | |
407 hhcd->hc[ch_num].data_pid = HC_PID_DATA0; | |
408 } | |
409 else | |
410 { /* Put the PID 1 */ | |
411 hhcd->hc[ch_num].data_pid = HC_PID_DATA1; | |
412 } | |
413 } | |
414 else | |
415 { | |
416 if( hhcd->hc[ch_num].toggle_in == 0) | |
417 { | |
418 hhcd->hc[ch_num].data_pid = HC_PID_DATA0; | |
419 } | |
420 else | |
421 { | |
422 hhcd->hc[ch_num].data_pid = HC_PID_DATA1; | |
423 } | |
424 } | |
425 break; | |
426 | |
427 case EP_TYPE_ISOC: | |
428 hhcd->hc[ch_num].data_pid = HC_PID_DATA0; | |
429 break; | |
430 } | |
431 | |
432 hhcd->hc[ch_num].xfer_buff = pbuff; | |
433 hhcd->hc[ch_num].xfer_len = length; | |
434 hhcd->hc[ch_num].urb_state = URB_IDLE; | |
435 hhcd->hc[ch_num].xfer_count = 0; | |
436 hhcd->hc[ch_num].ch_num = ch_num; | |
437 hhcd->hc[ch_num].state = HC_IDLE; | |
438 | |
439 return USB_HC_StartXfer(hhcd->Instance, &(hhcd->hc[ch_num]), hhcd->Init.dma_enable); | |
440 } | |
441 | |
442 /** | |
443 * @brief This function handles HCD interrupt request. | |
444 * @param hhcd: HCD handle | |
445 * @retval None | |
446 */ | |
447 void HAL_HCD_IRQHandler(HCD_HandleTypeDef *hhcd) | |
448 { | |
449 USB_OTG_GlobalTypeDef *USBx = hhcd->Instance; | |
450 uint32_t i = 0 , interrupt = 0; | |
451 | |
452 /* Ensure that we are in device mode */ | |
453 if (USB_GetMode(hhcd->Instance) == USB_OTG_MODE_HOST) | |
454 { | |
455 /* Avoid spurious interrupt */ | |
456 if(__HAL_HCD_IS_INVALID_INTERRUPT(hhcd)) | |
457 { | |
458 return; | |
459 } | |
460 | |
461 if(__HAL_HCD_GET_FLAG(hhcd, USB_OTG_GINTSTS_PXFR_INCOMPISOOUT)) | |
462 { | |
463 /* Incorrect mode, acknowledge the interrupt */ | |
464 __HAL_HCD_CLEAR_FLAG(hhcd, USB_OTG_GINTSTS_PXFR_INCOMPISOOUT); | |
465 } | |
466 | |
467 if(__HAL_HCD_GET_FLAG(hhcd, USB_OTG_GINTSTS_IISOIXFR)) | |
468 { | |
469 /* Incorrect mode, acknowledge the interrupt */ | |
470 __HAL_HCD_CLEAR_FLAG(hhcd, USB_OTG_GINTSTS_IISOIXFR); | |
471 } | |
472 | |
473 if(__HAL_HCD_GET_FLAG(hhcd, USB_OTG_GINTSTS_PTXFE)) | |
474 { | |
475 /* Incorrect mode, acknowledge the interrupt */ | |
476 __HAL_HCD_CLEAR_FLAG(hhcd, USB_OTG_GINTSTS_PTXFE); | |
477 } | |
478 | |
479 if(__HAL_HCD_GET_FLAG(hhcd, USB_OTG_GINTSTS_MMIS)) | |
480 { | |
481 /* Incorrect mode, acknowledge the interrupt */ | |
482 __HAL_HCD_CLEAR_FLAG(hhcd, USB_OTG_GINTSTS_MMIS); | |
483 } | |
484 | |
485 /* Handle Host Disconnect Interrupts */ | |
486 if(__HAL_HCD_GET_FLAG(hhcd, USB_OTG_GINTSTS_DISCINT)) | |
487 { | |
488 | |
489 /* Cleanup HPRT */ | |
490 USBx_HPRT0 &= ~(USB_OTG_HPRT_PENA | USB_OTG_HPRT_PCDET |\ | |
491 USB_OTG_HPRT_PENCHNG | USB_OTG_HPRT_POCCHNG ); | |
492 | |
493 /* Handle Host Port Interrupts */ | |
494 HAL_HCD_Disconnect_Callback(hhcd); | |
495 USB_InitFSLSPClkSel(hhcd->Instance ,HCFG_48_MHZ ); | |
496 __HAL_HCD_CLEAR_FLAG(hhcd, USB_OTG_GINTSTS_DISCINT); | |
497 } | |
498 | |
499 /* Handle Host Port Interrupts */ | |
500 if(__HAL_HCD_GET_FLAG(hhcd, USB_OTG_GINTSTS_HPRTINT)) | |
501 { | |
502 HCD_Port_IRQHandler (hhcd); | |
503 } | |
504 | |
505 /* Handle Host SOF Interrupts */ | |
506 if(__HAL_HCD_GET_FLAG(hhcd, USB_OTG_GINTSTS_SOF)) | |
507 { | |
508 HAL_HCD_SOF_Callback(hhcd); | |
509 __HAL_HCD_CLEAR_FLAG(hhcd, USB_OTG_GINTSTS_SOF); | |
510 } | |
511 | |
512 /* Handle Host channel Interrupts */ | |
513 if(__HAL_HCD_GET_FLAG(hhcd, USB_OTG_GINTSTS_HCINT)) | |
514 { | |
515 interrupt = USB_HC_ReadInterrupt(hhcd->Instance); | |
516 for (i = 0; i < hhcd->Init.Host_channels; i++) | |
517 { | |
518 if (interrupt & (1 << i)) | |
519 { | |
520 if ((USBx_HC(i)->HCCHAR) & USB_OTG_HCCHAR_EPDIR) | |
521 { | |
522 HCD_HC_IN_IRQHandler(hhcd, i); | |
523 } | |
524 else | |
525 { | |
526 HCD_HC_OUT_IRQHandler (hhcd, i); | |
527 } | |
528 } | |
529 } | |
530 __HAL_HCD_CLEAR_FLAG(hhcd, USB_OTG_GINTSTS_HCINT); | |
531 } | |
532 | |
533 /* Handle Rx Queue Level Interrupts */ | |
534 if(__HAL_HCD_GET_FLAG(hhcd, USB_OTG_GINTSTS_RXFLVL)) | |
535 { | |
536 USB_MASK_INTERRUPT(hhcd->Instance, USB_OTG_GINTSTS_RXFLVL); | |
537 | |
538 HCD_RXQLVL_IRQHandler (hhcd); | |
539 | |
540 USB_UNMASK_INTERRUPT(hhcd->Instance, USB_OTG_GINTSTS_RXFLVL); | |
541 } | |
542 } | |
543 } | |
544 | |
545 /** | |
546 * @brief SOF callback. | |
547 * @param hhcd: HCD handle | |
548 * @retval None | |
549 */ | |
550 __weak void HAL_HCD_SOF_Callback(HCD_HandleTypeDef *hhcd) | |
551 { | |
552 /* NOTE : This function Should not be modified, when the callback is needed, | |
553 the HAL_HCD_SOF_Callback could be implemented in the user file | |
554 */ | |
555 } | |
556 | |
557 /** | |
558 * @brief Connexion Event callback. | |
559 * @param hhcd: HCD handle | |
560 * @retval None | |
561 */ | |
562 __weak void HAL_HCD_Connect_Callback(HCD_HandleTypeDef *hhcd) | |
563 { | |
564 /* NOTE : This function Should not be modified, when the callback is needed, | |
565 the HAL_HCD_Connect_Callback could be implemented in the user file | |
566 */ | |
567 } | |
568 | |
569 /** | |
570 * @brief Disconnexion Event callback. | |
571 * @param hhcd: HCD handle | |
572 * @retval None | |
573 */ | |
574 __weak void HAL_HCD_Disconnect_Callback(HCD_HandleTypeDef *hhcd) | |
575 { | |
576 /* NOTE : This function Should not be modified, when the callback is needed, | |
577 the HAL_HCD_Disconnect_Callback could be implemented in the user file | |
578 */ | |
579 } | |
580 | |
581 /** | |
582 * @brief Notify URB state change callback. | |
583 * @param hhcd: HCD handle | |
584 * @param chnum: Channel number. | |
585 * This parameter can be a value from 1 to 15 | |
586 * @param urb_state: | |
587 * This parameter can be one of these values: | |
588 * URB_IDLE/ | |
589 * URB_DONE/ | |
590 * URB_NOTREADY/ | |
591 * URB_NYET/ | |
592 * URB_ERROR/ | |
593 * URB_STALL/ | |
594 * @retval None | |
595 */ | |
596 __weak void HAL_HCD_HC_NotifyURBChange_Callback(HCD_HandleTypeDef *hhcd, uint8_t chnum, HCD_URBStateTypeDef urb_state) | |
597 { | |
598 /* NOTE : This function Should not be modified, when the callback is needed, | |
599 the HAL_HCD_HC_NotifyURBChange_Callback could be implemented in the user file | |
600 */ | |
601 } | |
602 | |
603 /** | |
604 * @} | |
605 */ | |
606 | |
607 /** @addtogroup HCD_Exported_Functions_Group3 | |
608 * @brief Peripheral State functions | |
609 * | |
610 @verbatim | |
611 =============================================================================== | |
612 ##### Peripheral Control functions ##### | |
613 =============================================================================== | |
614 [..] | |
615 This subsection provides a set of functions allowing to control the HCD data | |
616 transfers. | |
617 | |
618 @endverbatim | |
619 * @{ | |
620 */ | |
621 | |
622 /** | |
623 * @brief Start the host driver | |
624 * @param hhcd: HCD handle | |
625 * @retval HAL status | |
626 */ | |
627 HAL_StatusTypeDef HAL_HCD_Start(HCD_HandleTypeDef *hhcd) | |
628 { | |
629 __HAL_LOCK(hhcd); | |
630 __HAL_HCD_ENABLE(hhcd); | |
631 USB_DriveVbus(hhcd->Instance, 1); | |
632 __HAL_UNLOCK(hhcd); | |
633 return HAL_OK; | |
634 } | |
635 | |
636 /** | |
637 * @brief Stop the host driver | |
638 * @param hhcd: HCD handle | |
639 * @retval HAL status | |
640 */ | |
641 | |
642 HAL_StatusTypeDef HAL_HCD_Stop(HCD_HandleTypeDef *hhcd) | |
643 { | |
644 __HAL_LOCK(hhcd); | |
645 USB_StopHost(hhcd->Instance); | |
646 __HAL_UNLOCK(hhcd); | |
647 return HAL_OK; | |
648 } | |
649 | |
650 /** | |
651 * @brief Reset the host port | |
652 * @param hhcd: HCD handle | |
653 * @retval HAL status | |
654 */ | |
655 HAL_StatusTypeDef HAL_HCD_ResetPort(HCD_HandleTypeDef *hhcd) | |
656 { | |
657 return (USB_ResetPort(hhcd->Instance)); | |
658 } | |
659 | |
660 /** | |
661 * @} | |
662 */ | |
663 | |
664 /** @addtogroup HCD_Exported_Functions_Group4 | |
665 * @brief Peripheral State functions | |
666 * | |
667 @verbatim | |
668 =============================================================================== | |
669 ##### Peripheral State functions ##### | |
670 =============================================================================== | |
671 [..] | |
672 This subsection permits to get in run-time the status of the peripheral | |
673 and the data flow. | |
674 | |
675 @endverbatim | |
676 * @{ | |
677 */ | |
678 | |
679 /** | |
680 * @brief Return the HCD state | |
681 * @param hhcd: HCD handle | |
682 * @retval HAL state | |
683 */ | |
684 HCD_StateTypeDef HAL_HCD_GetState(HCD_HandleTypeDef *hhcd) | |
685 { | |
686 return hhcd->State; | |
687 } | |
688 | |
689 /** | |
690 * @brief Return URB state for a channel | |
691 * @param hhcd: HCD handle | |
692 * @param chnum: Channel number. | |
693 * This parameter can be a value from 1 to 15 | |
694 * @retval URB state. | |
695 * This parameter can be one of these values: | |
696 * URB_IDLE/ | |
697 * URB_DONE/ | |
698 * URB_NOTREADY/ | |
699 * URB_NYET/ | |
700 * URB_ERROR/ | |
701 * URB_STALL/ | |
702 */ | |
703 HCD_URBStateTypeDef HAL_HCD_HC_GetURBState(HCD_HandleTypeDef *hhcd, uint8_t chnum) | |
704 { | |
705 return hhcd->hc[chnum].urb_state; | |
706 } | |
707 | |
708 | |
709 /** | |
710 * @brief Return the last host transfer size | |
711 * @param hhcd: HCD handle | |
712 * @param chnum: Channel number. | |
713 * This parameter can be a value from 1 to 15 | |
714 * @retval last transfer size in byte | |
715 */ | |
716 uint32_t HAL_HCD_HC_GetXferCount(HCD_HandleTypeDef *hhcd, uint8_t chnum) | |
717 { | |
718 return hhcd->hc[chnum].xfer_count; | |
719 } | |
720 | |
721 /** | |
722 * @brief Return the Host Channel state | |
723 * @param hhcd: HCD handle | |
724 * @param chnum: Channel number. | |
725 * This parameter can be a value from 1 to 15 | |
726 * @retval Host channel state | |
727 * This parameter can be one of the these values: | |
728 * HC_IDLE/ | |
729 * HC_XFRC/ | |
730 * HC_HALTED/ | |
731 * HC_NYET/ | |
732 * HC_NAK/ | |
733 * HC_STALL/ | |
734 * HC_XACTERR/ | |
735 * HC_BBLERR/ | |
736 * HC_DATATGLERR/ | |
737 */ | |
738 HCD_HCStateTypeDef HAL_HCD_HC_GetState(HCD_HandleTypeDef *hhcd, uint8_t chnum) | |
739 { | |
740 return hhcd->hc[chnum].state; | |
741 } | |
742 | |
743 /** | |
744 * @brief Return the current Host frame number | |
745 * @param hhcd: HCD handle | |
746 * @retval Current Host frame number | |
747 */ | |
748 uint32_t HAL_HCD_GetCurrentFrame(HCD_HandleTypeDef *hhcd) | |
749 { | |
750 return (USB_GetCurrentFrame(hhcd->Instance)); | |
751 } | |
752 | |
753 /** | |
754 * @brief Return the Host enumeration speed | |
755 * @param hhcd: HCD handle | |
756 * @retval Enumeration speed | |
757 */ | |
758 uint32_t HAL_HCD_GetCurrentSpeed(HCD_HandleTypeDef *hhcd) | |
759 { | |
760 return (USB_GetHostSpeed(hhcd->Instance)); | |
761 } | |
762 /** | |
763 * @} | |
764 */ | |
765 | |
766 /** | |
767 * @} | |
768 */ | |
769 | |
770 /** @addtogroup HCD_Private_Functions | |
771 * @{ | |
772 */ | |
773 /** | |
774 * @brief This function handles Host Channel IN interrupt requests. | |
775 * @param hhcd: HCD handle | |
776 * @param chnum: Channel number. | |
777 * This parameter can be a value from 1 to 15 | |
778 * @retval None | |
779 */ | |
780 static void HCD_HC_IN_IRQHandler(HCD_HandleTypeDef *hhcd, uint8_t chnum) | |
781 { | |
782 USB_OTG_GlobalTypeDef *USBx = hhcd->Instance; | |
783 | |
784 if ((USBx_HC(chnum)->HCINT) & USB_OTG_HCINT_AHBERR) | |
785 { | |
786 __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_AHBERR); | |
787 __HAL_HCD_UNMASK_HALT_HC_INT(chnum); | |
788 } | |
789 else if ((USBx_HC(chnum)->HCINT) & USB_OTG_HCINT_ACK) | |
790 { | |
791 __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_ACK); | |
792 } | |
793 | |
794 else if ((USBx_HC(chnum)->HCINT) & USB_OTG_HCINT_STALL) | |
795 { | |
796 __HAL_HCD_UNMASK_HALT_HC_INT(chnum); | |
797 hhcd->hc[chnum].state = HC_STALL; | |
798 __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_NAK); | |
799 __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_STALL); | |
800 USB_HC_Halt(hhcd->Instance, chnum); | |
801 } | |
802 else if ((USBx_HC(chnum)->HCINT) & USB_OTG_HCINT_DTERR) | |
803 { | |
804 __HAL_HCD_UNMASK_HALT_HC_INT(chnum); | |
805 USB_HC_Halt(hhcd->Instance, chnum); | |
806 __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_NAK); | |
807 hhcd->hc[chnum].state = HC_DATATGLERR; | |
808 __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_DTERR); | |
809 } | |
810 | |
811 if ((USBx_HC(chnum)->HCINT) & USB_OTG_HCINT_FRMOR) | |
812 { | |
813 __HAL_HCD_UNMASK_HALT_HC_INT(chnum); | |
814 USB_HC_Halt(hhcd->Instance, chnum); | |
815 __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_FRMOR); | |
816 } | |
817 | |
818 else if ((USBx_HC(chnum)->HCINT) & USB_OTG_HCINT_XFRC) | |
819 { | |
820 | |
821 if (hhcd->Init.dma_enable) | |
822 { | |
823 hhcd->hc[chnum].xfer_count = hhcd->hc[chnum].xfer_len - \ | |
824 (USBx_HC(chnum)->HCTSIZ & USB_OTG_HCTSIZ_XFRSIZ); | |
825 } | |
826 | |
827 hhcd->hc[chnum].state = HC_XFRC; | |
828 hhcd->hc[chnum].ErrCnt = 0; | |
829 __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_XFRC); | |
830 | |
831 | |
832 if ((hhcd->hc[chnum].ep_type == EP_TYPE_CTRL)|| | |
833 (hhcd->hc[chnum].ep_type == EP_TYPE_BULK)) | |
834 { | |
835 __HAL_HCD_UNMASK_HALT_HC_INT(chnum); | |
836 USB_HC_Halt(hhcd->Instance, chnum); | |
837 __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_NAK); | |
838 | |
839 } | |
840 else if(hhcd->hc[chnum].ep_type == EP_TYPE_INTR) | |
841 { | |
842 USBx_HC(chnum)->HCCHAR |= USB_OTG_HCCHAR_ODDFRM; | |
843 hhcd->hc[chnum].urb_state = URB_DONE; | |
844 HAL_HCD_HC_NotifyURBChange_Callback(hhcd, chnum, hhcd->hc[chnum].urb_state); | |
845 } | |
846 hhcd->hc[chnum].toggle_in ^= 1; | |
847 | |
848 } | |
849 else if ((USBx_HC(chnum)->HCINT) & USB_OTG_HCINT_CHH) | |
850 { | |
851 __HAL_HCD_MASK_HALT_HC_INT(chnum); | |
852 | |
853 if(hhcd->hc[chnum].state == HC_XFRC) | |
854 { | |
855 hhcd->hc[chnum].urb_state = URB_DONE; | |
856 } | |
857 | |
858 else if (hhcd->hc[chnum].state == HC_STALL) | |
859 { | |
860 hhcd->hc[chnum].urb_state = URB_STALL; | |
861 } | |
862 | |
863 else if((hhcd->hc[chnum].state == HC_XACTERR) || | |
864 (hhcd->hc[chnum].state == HC_DATATGLERR)) | |
865 { | |
866 if(hhcd->hc[chnum].ErrCnt++ > 3) | |
867 { | |
868 hhcd->hc[chnum].ErrCnt = 0; | |
869 hhcd->hc[chnum].urb_state = URB_ERROR; | |
870 } | |
871 else | |
872 { | |
873 hhcd->hc[chnum].urb_state = URB_NOTREADY; | |
874 } | |
875 | |
876 /* re-activate the channel */ | |
877 USBx_HC(chnum)->HCCHAR &= ~USB_OTG_HCCHAR_CHDIS; | |
878 USBx_HC(chnum)->HCCHAR |= USB_OTG_HCCHAR_CHENA; | |
879 } | |
880 __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_CHH); | |
881 HAL_HCD_HC_NotifyURBChange_Callback(hhcd, chnum, hhcd->hc[chnum].urb_state); | |
882 } | |
883 | |
884 else if ((USBx_HC(chnum)->HCINT) & USB_OTG_HCINT_TXERR) | |
885 { | |
886 __HAL_HCD_UNMASK_HALT_HC_INT(chnum); | |
887 hhcd->hc[chnum].ErrCnt++; | |
888 hhcd->hc[chnum].state = HC_XACTERR; | |
889 USB_HC_Halt(hhcd->Instance, chnum); | |
890 __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_TXERR); | |
891 } | |
892 else if ((USBx_HC(chnum)->HCINT) & USB_OTG_HCINT_NAK) | |
893 { | |
894 if(hhcd->hc[chnum].ep_type == EP_TYPE_INTR) | |
895 { | |
896 __HAL_HCD_UNMASK_HALT_HC_INT(chnum); | |
897 USB_HC_Halt(hhcd->Instance, chnum); | |
898 } | |
899 else if ((hhcd->hc[chnum].ep_type == EP_TYPE_CTRL)|| | |
900 (hhcd->hc[chnum].ep_type == EP_TYPE_BULK)) | |
901 { | |
902 /* re-activate the channel */ | |
903 USBx_HC(chnum)->HCCHAR &= ~USB_OTG_HCCHAR_CHDIS; | |
904 USBx_HC(chnum)->HCCHAR |= USB_OTG_HCCHAR_CHENA; | |
905 | |
906 } | |
907 hhcd->hc[chnum].state = HC_NAK; | |
908 __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_NAK); | |
909 } | |
910 } | |
911 | |
912 /** | |
913 * @brief This function handles Host Channel OUT interrupt requests. | |
914 * @param hhcd: HCD handle | |
915 * @param chnum: Channel number. | |
916 * This parameter can be a value from 1 to 15 | |
917 * @retval None | |
918 */ | |
919 static void HCD_HC_OUT_IRQHandler (HCD_HandleTypeDef *hhcd, uint8_t chnum) | |
920 { | |
921 USB_OTG_GlobalTypeDef *USBx = hhcd->Instance; | |
922 | |
923 if ((USBx_HC(chnum)->HCINT) & USB_OTG_HCINT_AHBERR) | |
924 { | |
925 __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_AHBERR); | |
926 __HAL_HCD_UNMASK_HALT_HC_INT(chnum); | |
927 } | |
928 else if ((USBx_HC(chnum)->HCINT) & USB_OTG_HCINT_ACK) | |
929 { | |
930 __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_ACK); | |
931 | |
932 if( hhcd->hc[chnum].do_ping == 1) | |
933 { | |
934 hhcd->hc[chnum].state = HC_NYET; | |
935 __HAL_HCD_UNMASK_HALT_HC_INT(chnum); | |
936 USB_HC_Halt(hhcd->Instance, chnum); | |
937 hhcd->hc[chnum].urb_state = URB_NOTREADY; | |
938 } | |
939 } | |
940 | |
941 else if ((USBx_HC(chnum)->HCINT) & USB_OTG_HCINT_NYET) | |
942 { | |
943 hhcd->hc[chnum].state = HC_NYET; | |
944 hhcd->hc[chnum].ErrCnt= 0; | |
945 __HAL_HCD_UNMASK_HALT_HC_INT(chnum); | |
946 USB_HC_Halt(hhcd->Instance, chnum); | |
947 __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_NYET); | |
948 | |
949 } | |
950 | |
951 else if ((USBx_HC(chnum)->HCINT) & USB_OTG_HCINT_FRMOR) | |
952 { | |
953 __HAL_HCD_UNMASK_HALT_HC_INT(chnum); | |
954 USB_HC_Halt(hhcd->Instance, chnum); | |
955 __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_FRMOR); | |
956 } | |
957 | |
958 else if ((USBx_HC(chnum)->HCINT) & USB_OTG_HCINT_XFRC) | |
959 { | |
960 hhcd->hc[chnum].ErrCnt = 0; | |
961 __HAL_HCD_UNMASK_HALT_HC_INT(chnum); | |
962 USB_HC_Halt(hhcd->Instance, chnum); | |
963 __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_XFRC); | |
964 hhcd->hc[chnum].state = HC_XFRC; | |
965 | |
966 } | |
967 | |
968 else if ((USBx_HC(chnum)->HCINT) & USB_OTG_HCINT_STALL) | |
969 { | |
970 __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_STALL); | |
971 __HAL_HCD_UNMASK_HALT_HC_INT(chnum); | |
972 USB_HC_Halt(hhcd->Instance, chnum); | |
973 hhcd->hc[chnum].state = HC_STALL; | |
974 } | |
975 | |
976 else if ((USBx_HC(chnum)->HCINT) & USB_OTG_HCINT_NAK) | |
977 { | |
978 hhcd->hc[chnum].ErrCnt = 0; | |
979 __HAL_HCD_UNMASK_HALT_HC_INT(chnum); | |
980 USB_HC_Halt(hhcd->Instance, chnum); | |
981 hhcd->hc[chnum].state = HC_NAK; | |
982 __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_NAK); | |
983 } | |
984 | |
985 else if ((USBx_HC(chnum)->HCINT) & USB_OTG_HCINT_TXERR) | |
986 { | |
987 __HAL_HCD_UNMASK_HALT_HC_INT(chnum); | |
988 USB_HC_Halt(hhcd->Instance, chnum); | |
989 hhcd->hc[chnum].state = HC_XACTERR; | |
990 __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_TXERR); | |
991 } | |
992 | |
993 else if ((USBx_HC(chnum)->HCINT) & USB_OTG_HCINT_DTERR) | |
994 { | |
995 __HAL_HCD_UNMASK_HALT_HC_INT(chnum); | |
996 USB_HC_Halt(hhcd->Instance, chnum); | |
997 __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_NAK); | |
998 __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_DTERR); | |
999 hhcd->hc[chnum].state = HC_DATATGLERR; | |
1000 } | |
1001 | |
1002 | |
1003 else if ((USBx_HC(chnum)->HCINT) & USB_OTG_HCINT_CHH) | |
1004 { | |
1005 __HAL_HCD_MASK_HALT_HC_INT(chnum); | |
1006 | |
1007 if(hhcd->hc[chnum].state == HC_XFRC) | |
1008 { | |
1009 hhcd->hc[chnum].urb_state = URB_DONE; | |
1010 if (hhcd->hc[chnum].ep_type == EP_TYPE_BULK) | |
1011 { | |
1012 hhcd->hc[chnum].toggle_out ^= 1; | |
1013 } | |
1014 } | |
1015 else if (hhcd->hc[chnum].state == HC_NAK) | |
1016 { | |
1017 hhcd->hc[chnum].urb_state = URB_NOTREADY; | |
1018 } | |
1019 | |
1020 else if (hhcd->hc[chnum].state == HC_NYET) | |
1021 { | |
1022 hhcd->hc[chnum].urb_state = URB_NOTREADY; | |
1023 hhcd->hc[chnum].do_ping = 0; | |
1024 } | |
1025 | |
1026 else if (hhcd->hc[chnum].state == HC_STALL) | |
1027 { | |
1028 hhcd->hc[chnum].urb_state = URB_STALL; | |
1029 } | |
1030 | |
1031 else if((hhcd->hc[chnum].state == HC_XACTERR) || | |
1032 (hhcd->hc[chnum].state == HC_DATATGLERR)) | |
1033 { | |
1034 if(hhcd->hc[chnum].ErrCnt++ > 3) | |
1035 { | |
1036 hhcd->hc[chnum].ErrCnt = 0; | |
1037 hhcd->hc[chnum].urb_state = URB_ERROR; | |
1038 } | |
1039 else | |
1040 { | |
1041 hhcd->hc[chnum].urb_state = URB_NOTREADY; | |
1042 } | |
1043 | |
1044 /* re-activate the channel */ | |
1045 USBx_HC(chnum)->HCCHAR &= ~USB_OTG_HCCHAR_CHDIS; | |
1046 USBx_HC(chnum)->HCCHAR |= USB_OTG_HCCHAR_CHENA; | |
1047 } | |
1048 | |
1049 __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_CHH); | |
1050 HAL_HCD_HC_NotifyURBChange_Callback(hhcd, chnum, hhcd->hc[chnum].urb_state); | |
1051 } | |
1052 } | |
1053 | |
1054 /** | |
1055 * @brief This function handles Rx Queue Level interrupt requests. | |
1056 * @param hhcd: HCD handle | |
1057 * @retval None | |
1058 */ | |
1059 static void HCD_RXQLVL_IRQHandler(HCD_HandleTypeDef *hhcd) | |
1060 { | |
1061 USB_OTG_GlobalTypeDef *USBx = hhcd->Instance; | |
1062 uint8_t channelnum = 0; | |
1063 uint32_t pktsts; | |
1064 uint32_t pktcnt; | |
1065 uint32_t temp = 0; | |
1066 | |
1067 temp = hhcd->Instance->GRXSTSP; | |
1068 channelnum = temp & USB_OTG_GRXSTSP_EPNUM; | |
1069 pktsts = (temp & USB_OTG_GRXSTSP_PKTSTS) >> 17; | |
1070 pktcnt = (temp & USB_OTG_GRXSTSP_BCNT) >> 4; | |
1071 | |
1072 switch (pktsts) | |
1073 { | |
1074 case GRXSTS_PKTSTS_IN: | |
1075 /* Read the data into the host buffer. */ | |
1076 if ((pktcnt > 0) && (hhcd->hc[channelnum].xfer_buff != (void *)0)) | |
1077 { | |
1078 | |
1079 USB_ReadPacket(hhcd->Instance, hhcd->hc[channelnum].xfer_buff, pktcnt); | |
1080 | |
1081 /*manage multiple Xfer */ | |
1082 hhcd->hc[channelnum].xfer_buff += pktcnt; | |
1083 hhcd->hc[channelnum].xfer_count += pktcnt; | |
1084 | |
1085 if((USBx_HC(channelnum)->HCTSIZ & USB_OTG_HCTSIZ_PKTCNT) > 0) | |
1086 { | |
1087 /* re-activate the channel when more packets are expected */ | |
1088 USBx_HC(channelnum)->HCCHAR &= ~USB_OTG_HCCHAR_CHDIS; | |
1089 USBx_HC(channelnum)->HCCHAR |= USB_OTG_HCCHAR_CHENA; | |
1090 hhcd->hc[channelnum].toggle_in ^= 1; | |
1091 } | |
1092 } | |
1093 break; | |
1094 | |
1095 case GRXSTS_PKTSTS_DATA_TOGGLE_ERR: | |
1096 break; | |
1097 case GRXSTS_PKTSTS_IN_XFER_COMP: | |
1098 case GRXSTS_PKTSTS_CH_HALTED: | |
1099 default: | |
1100 break; | |
1101 } | |
1102 } | |
1103 | |
1104 /** | |
1105 * @brief This function handles Host Port interrupt requests. | |
1106 * @param hhcd: HCD handle | |
1107 * @retval None | |
1108 */ | |
1109 static void HCD_Port_IRQHandler (HCD_HandleTypeDef *hhcd) | |
1110 { | |
1111 USB_OTG_GlobalTypeDef *USBx = hhcd->Instance; | |
1112 __IO uint32_t hprt0, hprt0_dup; | |
1113 | |
1114 /* Handle Host Port Interrupts */ | |
1115 hprt0 = USBx_HPRT0; | |
1116 hprt0_dup = USBx_HPRT0; | |
1117 | |
1118 hprt0_dup &= ~(USB_OTG_HPRT_PENA | USB_OTG_HPRT_PCDET |\ | |
1119 USB_OTG_HPRT_PENCHNG | USB_OTG_HPRT_POCCHNG ); | |
1120 | |
1121 /* Check whether Port Connect Detected */ | |
1122 if((hprt0 & USB_OTG_HPRT_PCDET) == USB_OTG_HPRT_PCDET) | |
1123 { | |
1124 if((hprt0 & USB_OTG_HPRT_PCSTS) == USB_OTG_HPRT_PCSTS) | |
1125 { | |
1126 USB_MASK_INTERRUPT(hhcd->Instance, USB_OTG_GINTSTS_DISCINT); | |
1127 HAL_HCD_Connect_Callback(hhcd); | |
1128 } | |
1129 hprt0_dup |= USB_OTG_HPRT_PCDET; | |
1130 | |
1131 } | |
1132 | |
1133 /* Check whether Port Enable Changed */ | |
1134 if((hprt0 & USB_OTG_HPRT_PENCHNG) == USB_OTG_HPRT_PENCHNG) | |
1135 { | |
1136 hprt0_dup |= USB_OTG_HPRT_PENCHNG; | |
1137 | |
1138 if((hprt0 & USB_OTG_HPRT_PENA) == USB_OTG_HPRT_PENA) | |
1139 { | |
1140 if(hhcd->Init.phy_itface == USB_OTG_EMBEDDED_PHY) | |
1141 { | |
1142 if ((hprt0 & USB_OTG_HPRT_PSPD) == (HPRT0_PRTSPD_LOW_SPEED << 17)) | |
1143 { | |
1144 USB_InitFSLSPClkSel(hhcd->Instance ,HCFG_6_MHZ ); | |
1145 } | |
1146 else | |
1147 { | |
1148 USB_InitFSLSPClkSel(hhcd->Instance ,HCFG_48_MHZ ); | |
1149 } | |
1150 } | |
1151 else | |
1152 { | |
1153 if(hhcd->Init.speed == HCD_SPEED_FULL) | |
1154 { | |
1155 USBx_HOST->HFIR = (uint32_t)60000; | |
1156 } | |
1157 } | |
1158 HAL_HCD_Connect_Callback(hhcd); | |
1159 | |
1160 if(hhcd->Init.speed == HCD_SPEED_HIGH) | |
1161 { | |
1162 USB_UNMASK_INTERRUPT(hhcd->Instance, USB_OTG_GINTSTS_DISCINT); | |
1163 } | |
1164 } | |
1165 else | |
1166 { | |
1167 /* Cleanup HPRT */ | |
1168 USBx_HPRT0 &= ~(USB_OTG_HPRT_PENA | USB_OTG_HPRT_PCDET |\ | |
1169 USB_OTG_HPRT_PENCHNG | USB_OTG_HPRT_POCCHNG ); | |
1170 | |
1171 USB_UNMASK_INTERRUPT(hhcd->Instance, USB_OTG_GINTSTS_DISCINT); | |
1172 } | |
1173 } | |
1174 | |
1175 /* Check for an overcurrent */ | |
1176 if((hprt0 & USB_OTG_HPRT_POCCHNG) == USB_OTG_HPRT_POCCHNG) | |
1177 { | |
1178 hprt0_dup |= USB_OTG_HPRT_POCCHNG; | |
1179 } | |
1180 | |
1181 /* Clear Port Interrupts */ | |
1182 USBx_HPRT0 = hprt0_dup; | |
1183 } | |
1184 | |
1185 /** | |
1186 * @} | |
1187 */ | |
1188 | |
1189 #endif /* HAL_HCD_MODULE_ENABLED */ | |
1190 /** | |
1191 * @} | |
1192 */ | |
1193 | |
1194 /** | |
1195 * @} | |
1196 */ | |
1197 | |
1198 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ |