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