xref: /btstack/port/stm32-f4discovery-usb/USB_HOST/Target/usbh_conf.c (revision a8f7f3fcbcd51f8d2e92aca076b6a9f812db358c)
1 /* USER CODE BEGIN Header */
2 /**
3   ******************************************************************************
4   * @file           : Target/usbh_conf.c
5   * @version        : v1.0_Cube
6   * @brief          : This file implements the board support package for the USB host library
7   ******************************************************************************
8   * @attention
9   *
10   * <h2><center>&copy; Copyright (c) 2021 STMicroelectronics.
11   * All rights reserved.</center></h2>
12   *
13   * This software component is licensed by ST under Ultimate Liberty license
14   * SLA0044, the "License"; You may not use this file except in compliance with
15   * the License. You may obtain a copy of the License at:
16   *                             www.st.com/SLA0044
17   *
18   ******************************************************************************
19   */
20 /* USER CODE END Header */
21 
22 /* Includes ------------------------------------------------------------------*/
23 #include "usbh_core.h"
24 #include "usbh_platform.h"
25 
26 /* USER CODE BEGIN Includes */
27 
28 /* USER CODE END Includes */
29 
30 /* Private typedef -----------------------------------------------------------*/
31 /* Private define ------------------------------------------------------------*/
32 /* Private macro -------------------------------------------------------------*/
33 
34 /* USER CODE BEGIN PV */
35 /* Private variables ---------------------------------------------------------*/
36 
37 /* USER CODE END PV */
38 
39 HCD_HandleTypeDef hhcd_USB_OTG_FS;
40 void Error_Handler(void);
41 
42 /* USER CODE BEGIN 0 */
43 
44 /* USER CODE END 0 */
45 
46 /* USER CODE BEGIN PFP */
47 /* Private function prototypes -----------------------------------------------*/
48 USBH_StatusTypeDef USBH_Get_USB_Status(HAL_StatusTypeDef hal_status);
49 
50 /* USER CODE END PFP */
51 
52 /* Private functions ---------------------------------------------------------*/
53 
54 /* USER CODE BEGIN 1 */
55 
56 /* USER CODE END 1 */
57 
58 /*******************************************************************************
59                        LL Driver Callbacks (HCD -> USB Host Library)
60 *******************************************************************************/
61 /* MSP Init */
62 
HAL_HCD_MspInit(HCD_HandleTypeDef * hcdHandle)63 void HAL_HCD_MspInit(HCD_HandleTypeDef* hcdHandle)
64 {
65   GPIO_InitTypeDef GPIO_InitStruct = {0};
66   if(hcdHandle->Instance==USB_OTG_FS)
67   {
68   /* USER CODE BEGIN USB_OTG_FS_MspInit 0 */
69 
70   /* USER CODE END USB_OTG_FS_MspInit 0 */
71 
72     __HAL_RCC_GPIOA_CLK_ENABLE();
73     /**USB_OTG_FS GPIO Configuration
74     PA9     ------> USB_OTG_FS_VBUS
75     PA10     ------> USB_OTG_FS_ID
76     PA11     ------> USB_OTG_FS_DM
77     PA12     ------> USB_OTG_FS_DP
78     */
79     GPIO_InitStruct.Pin = VBUS_FS_Pin;
80     GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
81     GPIO_InitStruct.Pull = GPIO_NOPULL;
82     HAL_GPIO_Init(VBUS_FS_GPIO_Port, &GPIO_InitStruct);
83 
84     GPIO_InitStruct.Pin = OTG_FS_ID_Pin|OTG_FS_DM_Pin|OTG_FS_DP_Pin;
85     GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
86     GPIO_InitStruct.Pull = GPIO_NOPULL;
87     GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
88     GPIO_InitStruct.Alternate = GPIO_AF10_OTG_FS;
89     HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
90 
91     /* Peripheral clock enable */
92     __HAL_RCC_USB_OTG_FS_CLK_ENABLE();
93 
94     /* Peripheral interrupt init */
95     HAL_NVIC_SetPriority(OTG_FS_IRQn, 0, 0);
96     HAL_NVIC_EnableIRQ(OTG_FS_IRQn);
97   /* USER CODE BEGIN USB_OTG_FS_MspInit 1 */
98 
99   /* USER CODE END USB_OTG_FS_MspInit 1 */
100   }
101 }
102 
HAL_HCD_MspDeInit(HCD_HandleTypeDef * hcdHandle)103 void HAL_HCD_MspDeInit(HCD_HandleTypeDef* hcdHandle)
104 {
105   if(hcdHandle->Instance==USB_OTG_FS)
106   {
107   /* USER CODE BEGIN USB_OTG_FS_MspDeInit 0 */
108 
109   /* USER CODE END USB_OTG_FS_MspDeInit 0 */
110     /* Peripheral clock disable */
111     __HAL_RCC_USB_OTG_FS_CLK_DISABLE();
112 
113     /**USB_OTG_FS GPIO Configuration
114     PA9     ------> USB_OTG_FS_VBUS
115     PA10     ------> USB_OTG_FS_ID
116     PA11     ------> USB_OTG_FS_DM
117     PA12     ------> USB_OTG_FS_DP
118     */
119     HAL_GPIO_DeInit(GPIOA, VBUS_FS_Pin|OTG_FS_ID_Pin|OTG_FS_DM_Pin|OTG_FS_DP_Pin);
120 
121     /* Peripheral interrupt Deinit*/
122     HAL_NVIC_DisableIRQ(OTG_FS_IRQn);
123 
124   /* USER CODE BEGIN USB_OTG_FS_MspDeInit 1 */
125 
126   /* USER CODE END USB_OTG_FS_MspDeInit 1 */
127   }
128 }
129 
130 /**
131   * @brief  SOF callback.
132   * @param  hhcd: HCD handle
133   * @retval None
134   */
HAL_HCD_SOF_Callback(HCD_HandleTypeDef * hhcd)135 void HAL_HCD_SOF_Callback(HCD_HandleTypeDef *hhcd)
136 {
137   USBH_LL_IncTimer(hhcd->pData);
138 }
139 
140 /**
141   * @brief  SOF callback.
142   * @param  hhcd: HCD handle
143   * @retval None
144   */
HAL_HCD_Connect_Callback(HCD_HandleTypeDef * hhcd)145 void HAL_HCD_Connect_Callback(HCD_HandleTypeDef *hhcd)
146 {
147   USBH_LL_Connect(hhcd->pData);
148 }
149 
150 /**
151   * @brief  SOF callback.
152   * @param  hhcd: HCD handle
153   * @retval None
154   */
HAL_HCD_Disconnect_Callback(HCD_HandleTypeDef * hhcd)155 void HAL_HCD_Disconnect_Callback(HCD_HandleTypeDef *hhcd)
156 {
157   USBH_LL_Disconnect(hhcd->pData);
158 }
159 
160 /**
161   * @brief  Notify URB state change callback.
162   * @param  hhcd: HCD handle
163   * @param  chnum: channel number
164   * @param  urb_state: state
165   * @retval None
166   */
HAL_HCD_HC_NotifyURBChange_Callback(HCD_HandleTypeDef * hhcd,uint8_t chnum,HCD_URBStateTypeDef urb_state)167 void HAL_HCD_HC_NotifyURBChange_Callback(HCD_HandleTypeDef *hhcd, uint8_t chnum, HCD_URBStateTypeDef urb_state)
168 {
169   /* To be used with OS to sync URB state with the global state machine */
170 #if (USBH_USE_OS == 1)
171   USBH_LL_NotifyURBChange(hhcd->pData);
172 #endif
173 }
174 /**
175 * @brief  Port Port Enabled callback.
176   * @param  hhcd: HCD handle
177   * @retval None
178   */
HAL_HCD_PortEnabled_Callback(HCD_HandleTypeDef * hhcd)179 void HAL_HCD_PortEnabled_Callback(HCD_HandleTypeDef *hhcd)
180 {
181   USBH_LL_PortEnabled(hhcd->pData);
182 }
183 
184 /**
185   * @brief  Port Port Disabled callback.
186   * @param  hhcd: HCD handle
187   * @retval None
188   */
HAL_HCD_PortDisabled_Callback(HCD_HandleTypeDef * hhcd)189 void HAL_HCD_PortDisabled_Callback(HCD_HandleTypeDef *hhcd)
190 {
191   USBH_LL_PortDisabled(hhcd->pData);
192 }
193 
194 /*******************************************************************************
195                        LL Driver Interface (USB Host Library --> HCD)
196 *******************************************************************************/
197 
198 /**
199   * @brief  Initialize the low level portion of the host driver.
200   * @param  phost: Host handle
201   * @retval USBH status
202   */
USBH_LL_Init(USBH_HandleTypeDef * phost)203 USBH_StatusTypeDef USBH_LL_Init(USBH_HandleTypeDef *phost)
204 {
205   /* Init USB_IP */
206   if (phost->id == HOST_FS) {
207   /* Link the driver to the stack. */
208   hhcd_USB_OTG_FS.pData = phost;
209   phost->pData = &hhcd_USB_OTG_FS;
210 
211   hhcd_USB_OTG_FS.Instance = USB_OTG_FS;
212   hhcd_USB_OTG_FS.Init.Host_channels = 8;
213   hhcd_USB_OTG_FS.Init.speed = HCD_SPEED_FULL;
214   hhcd_USB_OTG_FS.Init.dma_enable = DISABLE;
215   hhcd_USB_OTG_FS.Init.phy_itface = HCD_PHY_EMBEDDED;
216   hhcd_USB_OTG_FS.Init.Sof_enable = DISABLE;
217   if (HAL_HCD_Init(&hhcd_USB_OTG_FS) != HAL_OK)
218   {
219     Error_Handler( );
220   }
221 
222   USBH_LL_SetTimer(phost, HAL_HCD_GetCurrentFrame(&hhcd_USB_OTG_FS));
223   }
224   return USBH_OK;
225 }
226 
227 /**
228   * @brief  De-Initialize the low level portion of the host driver.
229   * @param  phost: Host handle
230   * @retval USBH status
231   */
USBH_LL_DeInit(USBH_HandleTypeDef * phost)232 USBH_StatusTypeDef USBH_LL_DeInit(USBH_HandleTypeDef *phost)
233 {
234   HAL_StatusTypeDef hal_status = HAL_OK;
235   USBH_StatusTypeDef usb_status = USBH_OK;
236 
237   hal_status = HAL_HCD_DeInit(phost->pData);
238 
239   usb_status = USBH_Get_USB_Status(hal_status);
240 
241   return usb_status;
242 }
243 
244 /**
245   * @brief  Start the low level portion of the host driver.
246   * @param  phost: Host handle
247   * @retval USBH status
248   */
USBH_LL_Start(USBH_HandleTypeDef * phost)249 USBH_StatusTypeDef USBH_LL_Start(USBH_HandleTypeDef *phost)
250 {
251   HAL_StatusTypeDef hal_status = HAL_OK;
252   USBH_StatusTypeDef usb_status = USBH_OK;
253 
254   hal_status = HAL_HCD_Start(phost->pData);
255 
256   usb_status = USBH_Get_USB_Status(hal_status);
257 
258   return usb_status;
259 }
260 
261 /**
262   * @brief  Stop the low level portion of the host driver.
263   * @param  phost: Host handle
264   * @retval USBH status
265   */
USBH_LL_Stop(USBH_HandleTypeDef * phost)266 USBH_StatusTypeDef USBH_LL_Stop(USBH_HandleTypeDef *phost)
267 {
268   HAL_StatusTypeDef hal_status = HAL_OK;
269   USBH_StatusTypeDef usb_status = USBH_OK;
270 
271   hal_status = HAL_HCD_Stop(phost->pData);
272 
273   usb_status = USBH_Get_USB_Status(hal_status);
274 
275   return usb_status;
276 }
277 
278 /**
279   * @brief  Return the USB host speed from the low level driver.
280   * @param  phost: Host handle
281   * @retval USBH speeds
282   */
USBH_LL_GetSpeed(USBH_HandleTypeDef * phost)283 USBH_SpeedTypeDef USBH_LL_GetSpeed(USBH_HandleTypeDef *phost)
284 {
285   USBH_SpeedTypeDef speed = USBH_SPEED_FULL;
286 
287   switch (HAL_HCD_GetCurrentSpeed(phost->pData))
288   {
289   case 0 :
290     speed = USBH_SPEED_HIGH;
291     break;
292 
293   case 1 :
294     speed = USBH_SPEED_FULL;
295     break;
296 
297   case 2 :
298     speed = USBH_SPEED_LOW;
299     break;
300 
301   default:
302    speed = USBH_SPEED_FULL;
303     break;
304   }
305   return  speed;
306 }
307 
308 /**
309   * @brief  Reset the Host port of the low level driver.
310   * @param  phost: Host handle
311   * @retval USBH status
312   */
USBH_LL_ResetPort(USBH_HandleTypeDef * phost)313 USBH_StatusTypeDef USBH_LL_ResetPort(USBH_HandleTypeDef *phost)
314 {
315   HAL_StatusTypeDef hal_status = HAL_OK;
316   USBH_StatusTypeDef usb_status = USBH_OK;
317 
318   hal_status = HAL_HCD_ResetPort(phost->pData);
319 
320   usb_status = USBH_Get_USB_Status(hal_status);
321 
322   return usb_status;
323 }
324 
325 /**
326   * @brief  Return the last transfered packet size.
327   * @param  phost: Host handle
328   * @param  pipe: Pipe index
329   * @retval Packet size
330   */
USBH_LL_GetLastXferSize(USBH_HandleTypeDef * phost,uint8_t pipe)331 uint32_t USBH_LL_GetLastXferSize(USBH_HandleTypeDef *phost, uint8_t pipe)
332 {
333   return HAL_HCD_HC_GetXferCount(phost->pData, pipe);
334 }
335 
336 /**
337   * @brief  Open a pipe of the low level driver.
338   * @param  phost: Host handle
339   * @param  pipe_num: Pipe index
340   * @param  epnum: Endpoint number
341   * @param  dev_address: Device USB address
342   * @param  speed: Device Speed
343   * @param  ep_type: Endpoint type
344   * @param  mps: Endpoint max packet size
345   * @retval USBH status
346   */
USBH_LL_OpenPipe(USBH_HandleTypeDef * phost,uint8_t pipe_num,uint8_t epnum,uint8_t dev_address,uint8_t speed,uint8_t ep_type,uint16_t mps)347 USBH_StatusTypeDef USBH_LL_OpenPipe(USBH_HandleTypeDef *phost, uint8_t pipe_num, uint8_t epnum,
348                                     uint8_t dev_address, uint8_t speed, uint8_t ep_type, uint16_t mps)
349 {
350   HAL_StatusTypeDef hal_status = HAL_OK;
351   USBH_StatusTypeDef usb_status = USBH_OK;
352 
353   hal_status = HAL_HCD_HC_Init(phost->pData, pipe_num, epnum,
354                                dev_address, speed, ep_type, mps);
355 
356   usb_status = USBH_Get_USB_Status(hal_status);
357 
358   return usb_status;
359 }
360 
361 /**
362   * @brief  Close a pipe of the low level driver.
363   * @param  phost: Host handle
364   * @param  pipe: Pipe index
365   * @retval USBH status
366   */
USBH_LL_ClosePipe(USBH_HandleTypeDef * phost,uint8_t pipe)367 USBH_StatusTypeDef USBH_LL_ClosePipe(USBH_HandleTypeDef *phost, uint8_t pipe)
368 {
369   HAL_StatusTypeDef hal_status = HAL_OK;
370   USBH_StatusTypeDef usb_status = USBH_OK;
371 
372   hal_status = HAL_HCD_HC_Halt(phost->pData, pipe);
373 
374   usb_status = USBH_Get_USB_Status(hal_status);
375 
376   return usb_status;
377 }
378 
379 /**
380   * @brief  Submit a new URB to the low level driver.
381   * @param  phost: Host handle
382   * @param  pipe: Pipe index
383   *         This parameter can be a value from 1 to 15
384   * @param  direction : Channel number
385   *          This parameter can be one of the these values:
386   *           0 : Output
387   *           1 : Input
388   * @param  ep_type : Endpoint Type
389   *          This parameter can be one of the these values:
390   *            @arg EP_TYPE_CTRL: Control type
391   *            @arg EP_TYPE_ISOC: Isochrounous type
392   *            @arg EP_TYPE_BULK: Bulk type
393   *            @arg EP_TYPE_INTR: Interrupt type
394   * @param  token : Endpoint Type
395   *          This parameter can be one of the these values:
396   *            @arg 0: PID_SETUP
397   *            @arg 1: PID_DATA
398   * @param  pbuff : pointer to URB data
399   * @param  length : Length of URB data
400   * @param  do_ping : activate do ping protocol (for high speed only)
401   *          This parameter can be one of the these values:
402   *           0 : do ping inactive
403   *           1 : do ping active
404   * @retval Status
405   */
USBH_LL_SubmitURB(USBH_HandleTypeDef * phost,uint8_t pipe,uint8_t direction,uint8_t ep_type,uint8_t token,uint8_t * pbuff,uint16_t length,uint8_t do_ping)406 USBH_StatusTypeDef USBH_LL_SubmitURB(USBH_HandleTypeDef *phost, uint8_t pipe, uint8_t direction,
407                                      uint8_t ep_type, uint8_t token, uint8_t *pbuff, uint16_t length,
408                                      uint8_t do_ping)
409 {
410   HAL_StatusTypeDef hal_status = HAL_OK;
411   USBH_StatusTypeDef usb_status = USBH_OK;
412 
413   hal_status = HAL_HCD_HC_SubmitRequest(phost->pData, pipe, direction ,
414                                         ep_type, token, pbuff, length,
415                                         do_ping);
416   usb_status =  USBH_Get_USB_Status(hal_status);
417 
418   return usb_status;
419 }
420 
421 /**
422   * @brief  Get a URB state from the low level driver.
423   * @param  phost: Host handle
424   * @param  pipe: Pipe index
425   *         This parameter can be a value from 1 to 15
426   * @retval URB state
427   *          This parameter can be one of the these values:
428   *            @arg URB_IDLE
429   *            @arg URB_DONE
430   *            @arg URB_NOTREADY
431   *            @arg URB_NYET
432   *            @arg URB_ERROR
433   *            @arg URB_STALL
434   */
USBH_LL_GetURBState(USBH_HandleTypeDef * phost,uint8_t pipe)435 USBH_URBStateTypeDef USBH_LL_GetURBState(USBH_HandleTypeDef *phost, uint8_t pipe)
436 {
437   return (USBH_URBStateTypeDef)HAL_HCD_HC_GetURBState (phost->pData, pipe);
438 }
439 
440 /**
441   * @brief  Drive VBUS.
442   * @param  phost: Host handle
443   * @param  state : VBUS state
444   *          This parameter can be one of the these values:
445   *           0 : VBUS Inactive
446   *           1 : VBUS Active
447   * @retval Status
448   */
USBH_LL_DriverVBUS(USBH_HandleTypeDef * phost,uint8_t state)449 USBH_StatusTypeDef USBH_LL_DriverVBUS(USBH_HandleTypeDef *phost, uint8_t state)
450 {
451   if (phost->id == HOST_FS) {
452     MX_DriverVbusFS(state);
453   }
454 
455   /* USER CODE BEGIN 0 */
456 
457   /* USER CODE END 0*/
458 
459   HAL_Delay(200);
460   return USBH_OK;
461 }
462 
463 /**
464   * @brief  Set toggle for a pipe.
465   * @param  phost: Host handle
466   * @param  pipe: Pipe index
467   * @param  toggle: toggle (0/1)
468   * @retval Status
469   */
USBH_LL_SetToggle(USBH_HandleTypeDef * phost,uint8_t pipe,uint8_t toggle)470 USBH_StatusTypeDef USBH_LL_SetToggle(USBH_HandleTypeDef *phost, uint8_t pipe, uint8_t toggle)
471 {
472   HCD_HandleTypeDef *pHandle;
473   pHandle = phost->pData;
474 
475   if(pHandle->hc[pipe].ep_is_in)
476   {
477     pHandle->hc[pipe].toggle_in = toggle;
478   }
479   else
480   {
481     pHandle->hc[pipe].toggle_out = toggle;
482   }
483 
484   return USBH_OK;
485 }
486 
487 /**
488   * @brief  Return the current toggle of a pipe.
489   * @param  phost: Host handle
490   * @param  pipe: Pipe index
491   * @retval toggle (0/1)
492   */
USBH_LL_GetToggle(USBH_HandleTypeDef * phost,uint8_t pipe)493 uint8_t USBH_LL_GetToggle(USBH_HandleTypeDef *phost, uint8_t pipe)
494 {
495   uint8_t toggle = 0;
496   HCD_HandleTypeDef *pHandle;
497   pHandle = phost->pData;
498 
499   if(pHandle->hc[pipe].ep_is_in)
500   {
501     toggle = pHandle->hc[pipe].toggle_in;
502   }
503   else
504   {
505     toggle = pHandle->hc[pipe].toggle_out;
506   }
507   return toggle;
508 }
509 
510 /**
511   * @brief  Delay routine for the USB Host Library
512   * @param  Delay: Delay in ms
513   * @retval None
514   */
USBH_Delay(uint32_t Delay)515 void USBH_Delay(uint32_t Delay)
516 {
517   HAL_Delay(Delay);
518 }
519 
520 /**
521   * @brief  Retuns the USB status depending on the HAL status:
522   * @param  hal_status: HAL status
523   * @retval USB status
524   */
USBH_Get_USB_Status(HAL_StatusTypeDef hal_status)525 USBH_StatusTypeDef USBH_Get_USB_Status(HAL_StatusTypeDef hal_status)
526 {
527   USBH_StatusTypeDef usb_status = USBH_OK;
528 
529   switch (hal_status)
530   {
531     case HAL_OK :
532       usb_status = USBH_OK;
533     break;
534     case HAL_ERROR :
535       usb_status = USBH_FAIL;
536     break;
537     case HAL_BUSY :
538       usb_status = USBH_BUSY;
539     break;
540     case HAL_TIMEOUT :
541       usb_status = USBH_FAIL;
542     break;
543     default :
544       usb_status = USBH_FAIL;
545     break;
546   }
547   return usb_status;
548 }
549 
550 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
551