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