source: asp3_wo_tecs/trunk/arch/arm_m_gcc/stm32f4xx_stm32cube/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_hcd.c@ 303

Last change on this file since 303 was 303, checked in by ertl-honda, 7 years ago

nucleo_f401re依存部の追加

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