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