2021-12-13 21:39:13 -08:00
|
|
|
/**
|
|
|
|
**************************************************************************
|
|
|
|
* @file usbh_core.c
|
2022-05-04 23:48:39 -07:00
|
|
|
* @version v2.0.8
|
|
|
|
* @date 2022-04-25
|
2021-12-13 21:39:13 -08:00
|
|
|
* @brief usb host driver
|
|
|
|
**************************************************************************
|
|
|
|
* Copyright notice & Disclaimer
|
|
|
|
*
|
2022-04-11 04:50:25 -07:00
|
|
|
* The software Board Support Package (BSP) that is made available to
|
|
|
|
* download from Artery official website is the copyrighted work of Artery.
|
|
|
|
* Artery authorizes customers to use, copy, and distribute the BSP
|
|
|
|
* software and its related documentation for the purpose of design and
|
|
|
|
* development in conjunction with Artery microcontrollers. Use of the
|
2021-12-13 21:39:13 -08:00
|
|
|
* software is governed by this copyright notice and the following disclaimer.
|
|
|
|
*
|
|
|
|
* THIS SOFTWARE IS PROVIDED ON "AS IS" BASIS WITHOUT WARRANTIES,
|
|
|
|
* GUARANTEES OR REPRESENTATIONS OF ANY KIND. ARTERY EXPRESSLY DISCLAIMS,
|
|
|
|
* TO THE FULLEST EXTENT PERMITTED BY LAW, ALL EXPRESS, IMPLIED OR
|
|
|
|
* STATUTORY OR OTHER WARRANTIES, GUARANTEES OR REPRESENTATIONS,
|
|
|
|
* INCLUDING BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY,
|
|
|
|
* FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT.
|
|
|
|
*
|
|
|
|
**************************************************************************
|
|
|
|
*/
|
|
|
|
#include "usbh_core.h"
|
|
|
|
#include "usb_core.h"
|
|
|
|
#include "usbh_ctrl.h"
|
|
|
|
#include "usb_conf.h"
|
|
|
|
|
|
|
|
/** @addtogroup AT32F435_437_middlewares_usbh_drivers
|
|
|
|
* @{
|
|
|
|
*/
|
2022-04-11 04:50:25 -07:00
|
|
|
|
2021-12-13 21:39:13 -08:00
|
|
|
/** @defgroup USBH_drivers_core
|
|
|
|
* @brief usb host drivers core
|
|
|
|
* @{
|
2022-04-11 04:50:25 -07:00
|
|
|
*/
|
2021-12-13 21:39:13 -08:00
|
|
|
|
|
|
|
/** @defgroup USBH_core_private_functions
|
|
|
|
* @{
|
|
|
|
*/
|
2022-04-11 04:50:25 -07:00
|
|
|
|
2021-12-13 21:39:13 -08:00
|
|
|
static void usbh_attached(usbh_core_type *uhost);
|
|
|
|
static void usbh_enumeration(usbh_core_type *uhost);
|
|
|
|
static void usbh_class_request(usbh_core_type *uhost);
|
|
|
|
static void usbh_class(usbh_core_type *uhost);
|
|
|
|
static void usbh_suspend(usbh_core_type *uhost);
|
|
|
|
static void usbh_wakeup(usbh_core_type *uhost);
|
|
|
|
static void usbh_disconnect(usbh_core_type *uhost);
|
|
|
|
/**
|
|
|
|
* @brief usb host free channel
|
|
|
|
* @param uhost: to the structure of usbh_core_type
|
2022-04-11 04:50:25 -07:00
|
|
|
* @param index: channle number
|
2021-12-13 21:39:13 -08:00
|
|
|
* @retval none
|
|
|
|
*/
|
|
|
|
void usbh_free_channel(usbh_core_type *uhost, uint8_t index)
|
|
|
|
{
|
|
|
|
if(index < USB_HOST_CHANNEL_NUM)
|
|
|
|
{
|
|
|
|
/* free host channel */
|
|
|
|
uhost->channel[index] = 0x0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief get usb host free channel
|
|
|
|
* @param uhost: to the structure of usbh_core_type
|
|
|
|
* @retval channel index
|
|
|
|
*/
|
|
|
|
uint16_t usbh_get_free_channel(usbh_core_type *uhost)
|
|
|
|
{
|
|
|
|
uint16_t i_index = 0;
|
|
|
|
for(i_index = 0; i_index < USB_HOST_CHANNEL_NUM; i_index ++)
|
|
|
|
{
|
|
|
|
/* find unuse channel */
|
|
|
|
if((uhost->channel[i_index] & HCH_USED) == 0)
|
|
|
|
{
|
|
|
|
/* return channel index */
|
|
|
|
return i_index;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return HCH_ERROR;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief usb host set toggle
|
|
|
|
* @param uhost: to the structure of usbh_core_type
|
|
|
|
* @param hc_num: channel number
|
|
|
|
* @param toggle: toggle value
|
|
|
|
* @retval status: usb_sts_type status
|
|
|
|
*/
|
|
|
|
usb_sts_type usbh_set_toggle(usbh_core_type *uhost, uint8_t hc_num, uint8_t toggle)
|
|
|
|
{
|
|
|
|
if(uhost->hch[hc_num].dir)
|
|
|
|
{
|
|
|
|
/* direction in */
|
|
|
|
uhost->hch[hc_num].toggle_in = toggle;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* direction out */
|
|
|
|
uhost->hch[hc_num].toggle_out = toggle;
|
|
|
|
}
|
|
|
|
return USB_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief usb host in out request
|
|
|
|
* @param uhost: to the structure of usbh_core_type
|
|
|
|
* @param hc_num: channel number
|
|
|
|
* @retval status: usb_sts_type status
|
|
|
|
*/
|
|
|
|
usb_sts_type usbh_in_out_request(usbh_core_type *uhost, uint8_t hc_num)
|
|
|
|
{
|
|
|
|
usb_sts_type status = USB_OK;
|
|
|
|
uint32_t n_packet = 0;
|
|
|
|
uint32_t num_words = 0;
|
|
|
|
uint32_t tmp;
|
|
|
|
otg_global_type *usbx = uhost->usb_reg;
|
|
|
|
otg_hchannel_type *ch = USB_CHL(uhost->usb_reg, hc_num);
|
2022-04-11 04:50:25 -07:00
|
|
|
|
2021-12-13 21:39:13 -08:00
|
|
|
/* set usb request block to idle */
|
|
|
|
uhost->urb_state[hc_num] = URB_IDLE;
|
2022-04-11 04:50:25 -07:00
|
|
|
uhost->hch[hc_num].state = HCH_IDLE;
|
|
|
|
|
2021-12-13 21:39:13 -08:00
|
|
|
/* set usb channel transmit count to zero */
|
|
|
|
uhost->hch[hc_num].trans_count = 0;
|
2022-04-11 04:50:25 -07:00
|
|
|
|
2021-12-13 21:39:13 -08:00
|
|
|
/* check transmit data len */
|
|
|
|
if(uhost->hch[hc_num].trans_len > 0)
|
|
|
|
{
|
|
|
|
/* count how many packet need to send */
|
|
|
|
n_packet = (uhost->hch[hc_num].trans_len + \
|
|
|
|
uhost->hch[hc_num].maxpacket - 1) / \
|
|
|
|
uhost->hch[hc_num].maxpacket;
|
2022-04-11 04:50:25 -07:00
|
|
|
|
2021-12-13 21:39:13 -08:00
|
|
|
/* packet count max 256 */
|
|
|
|
if(n_packet > 256)
|
|
|
|
{
|
|
|
|
n_packet = 256;
|
|
|
|
uhost->hch[hc_num].trans_len = n_packet * uhost->hch[hc_num].maxpacket;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* zero data len */
|
|
|
|
n_packet = 1;
|
|
|
|
}
|
2022-04-11 04:50:25 -07:00
|
|
|
|
2021-12-13 21:39:13 -08:00
|
|
|
/* direction is in */
|
|
|
|
if(uhost->hch[hc_num].dir)
|
|
|
|
{
|
|
|
|
uhost->hch[hc_num].trans_len = n_packet * uhost->hch[hc_num].maxpacket;
|
|
|
|
}
|
2022-04-11 04:50:25 -07:00
|
|
|
|
2021-12-13 21:39:13 -08:00
|
|
|
/* set transfer information to channel register */
|
|
|
|
ch->hctsiz = (uhost->hch[hc_num].trans_len & USB_OTG_HCTSIZ_XFERSIZE) |
|
|
|
|
((n_packet << 19) & USB_OTG_HCTSIZ_PKTCNT) |
|
|
|
|
((uhost->hch[hc_num].data_pid << 29) & USB_OTG_HCTSIZ_PID);
|
2022-04-11 04:50:25 -07:00
|
|
|
|
2021-12-13 21:39:13 -08:00
|
|
|
/* set odd frame */
|
|
|
|
ch->hcchar_bit.oddfrm = !(OTG_HOST(uhost->usb_reg)->hfnum & 0x1);
|
2022-04-11 04:50:25 -07:00
|
|
|
|
2021-12-13 21:39:13 -08:00
|
|
|
/* clear channel disable bit and enable channel */
|
|
|
|
tmp = ch->hcchar;
|
|
|
|
tmp &= ~(USB_OTG_HCCHAR_CHDIS);
|
|
|
|
tmp |= USB_OTG_HCCHAR_CHENA;
|
|
|
|
ch->hcchar = tmp;
|
2022-04-11 04:50:25 -07:00
|
|
|
|
2021-12-13 21:39:13 -08:00
|
|
|
/* channel direction is out and transfer len > 0 */
|
2022-04-11 04:50:25 -07:00
|
|
|
if((uhost->hch[hc_num].dir == 0) &&
|
2021-12-13 21:39:13 -08:00
|
|
|
(uhost->hch[hc_num].trans_len > 0 ))
|
|
|
|
{
|
|
|
|
switch(uhost->hch[hc_num].ept_type)
|
|
|
|
{
|
|
|
|
case EPT_CONTROL_TYPE:
|
|
|
|
case EPT_BULK_TYPE:
|
|
|
|
num_words = (uhost->hch[hc_num].trans_len + 3) / 4;
|
2022-04-11 04:50:25 -07:00
|
|
|
|
|
|
|
/* non-periodic transfer */
|
2021-12-13 21:39:13 -08:00
|
|
|
if(num_words > usbx->gnptxsts_bit.nptxfspcavail)
|
|
|
|
{
|
|
|
|
usbx->gintmsk_bit.nptxfempmsk = 1;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case EPT_ISO_TYPE:
|
|
|
|
case EPT_INT_TYPE:
|
|
|
|
num_words = (uhost->hch[hc_num].trans_len + 3) / 4;
|
2022-04-11 04:50:25 -07:00
|
|
|
|
|
|
|
/* periodic transfer */
|
2021-12-13 21:39:13 -08:00
|
|
|
if(num_words > OTG_HOST(usbx)->hptxsts_bit.ptxfspcavil)
|
|
|
|
{
|
2022-04-11 04:50:25 -07:00
|
|
|
usbx->gintmsk_bit.ptxfempmsk = 1;
|
2021-12-13 21:39:13 -08:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
/* write data to fifo */
|
2022-04-11 04:50:25 -07:00
|
|
|
usb_write_packet(usbx, uhost->hch[hc_num].trans_buf,
|
2021-12-13 21:39:13 -08:00
|
|
|
hc_num, uhost->hch[hc_num].trans_len);
|
|
|
|
}
|
2022-04-11 04:50:25 -07:00
|
|
|
|
2021-12-13 21:39:13 -08:00
|
|
|
return status;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief usb host interrupt receive request
|
|
|
|
* @param uhost: to the structure of usbh_core_type
|
|
|
|
* @param hc_num: channel number
|
|
|
|
* @param buffer: receive buffer
|
|
|
|
* @param length: receive length
|
|
|
|
* @retval status: usb_sts_type status
|
|
|
|
*/
|
|
|
|
usb_sts_type usbh_interrupt_recv(usbh_core_type *uhost, uint8_t hc_num,
|
|
|
|
uint8_t *buffer, uint16_t length)
|
|
|
|
{
|
|
|
|
/* set direction is in */
|
|
|
|
uhost->hch[hc_num].dir = 1;
|
2022-04-11 04:50:25 -07:00
|
|
|
|
2021-12-13 21:39:13 -08:00
|
|
|
/* set transfer buffer */
|
|
|
|
uhost->hch[hc_num].trans_buf = buffer;
|
2022-04-11 04:50:25 -07:00
|
|
|
|
2021-12-13 21:39:13 -08:00
|
|
|
/* set transfer len*/
|
|
|
|
uhost->hch[hc_num].trans_len = length;
|
2022-04-11 04:50:25 -07:00
|
|
|
|
2021-12-13 21:39:13 -08:00
|
|
|
if(uhost->hch[hc_num].toggle_in == 0)
|
|
|
|
{
|
|
|
|
/* pid: data0 */
|
|
|
|
uhost->hch[hc_num].data_pid = HCH_PID_DATA0;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* pid: data1 */
|
|
|
|
uhost->hch[hc_num].data_pid = HCH_PID_DATA1;
|
|
|
|
}
|
2022-04-11 04:50:25 -07:00
|
|
|
|
2021-12-13 21:39:13 -08:00
|
|
|
return usbh_in_out_request(uhost, hc_num);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief usb host interrupt send request
|
|
|
|
* @param uhost: to the structure of usbh_core_type
|
|
|
|
* @param hc_num: channel number
|
|
|
|
* @param buffer: send buffer
|
|
|
|
* @param length: send length
|
|
|
|
* @retval status: usb_sts_type status
|
|
|
|
*/
|
|
|
|
usb_sts_type usbh_interrupt_send(usbh_core_type *uhost, uint8_t hc_num,
|
|
|
|
uint8_t *buffer, uint16_t length)
|
|
|
|
{
|
|
|
|
/* set direction is out */
|
|
|
|
uhost->hch[hc_num].dir = 0;
|
2022-04-11 04:50:25 -07:00
|
|
|
|
2021-12-13 21:39:13 -08:00
|
|
|
/* set transfer buffer */
|
|
|
|
uhost->hch[hc_num].trans_buf = buffer;
|
2022-04-11 04:50:25 -07:00
|
|
|
|
2021-12-13 21:39:13 -08:00
|
|
|
/* set transfer len*/
|
|
|
|
uhost->hch[hc_num].trans_len = length;
|
2022-04-11 04:50:25 -07:00
|
|
|
|
2021-12-13 21:39:13 -08:00
|
|
|
if(uhost->hch[hc_num].toggle_out == 0)
|
|
|
|
{
|
|
|
|
/* pid: data0 */
|
|
|
|
uhost->hch[hc_num].data_pid = HCH_PID_DATA0;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* pid: data1 */
|
|
|
|
uhost->hch[hc_num].data_pid = HCH_PID_DATA1;
|
|
|
|
}
|
2022-04-11 04:50:25 -07:00
|
|
|
|
2021-12-13 21:39:13 -08:00
|
|
|
return usbh_in_out_request(uhost, hc_num);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief usb host bulk receive request
|
|
|
|
* @param uhost: to the structure of usbh_core_type
|
|
|
|
* @param hc_num: channel number
|
|
|
|
* @param buffer: receive buffer
|
|
|
|
* @param length: receive length
|
|
|
|
* @retval status: usb_sts_type status
|
|
|
|
*/
|
|
|
|
usb_sts_type usbh_bulk_recv(usbh_core_type *uhost, uint8_t hc_num,
|
|
|
|
uint8_t *buffer, uint16_t length)
|
|
|
|
{
|
|
|
|
/* set direction is in */
|
|
|
|
uhost->hch[hc_num].dir = 1;
|
2022-04-11 04:50:25 -07:00
|
|
|
|
2021-12-13 21:39:13 -08:00
|
|
|
/* set transfer buffer */
|
|
|
|
uhost->hch[hc_num].trans_buf = buffer;
|
2022-04-11 04:50:25 -07:00
|
|
|
|
2021-12-13 21:39:13 -08:00
|
|
|
/* set transfer len*/
|
|
|
|
uhost->hch[hc_num].trans_len = length;
|
2022-04-11 04:50:25 -07:00
|
|
|
|
2021-12-13 21:39:13 -08:00
|
|
|
if(uhost->hch[hc_num].toggle_in == 0)
|
|
|
|
{
|
|
|
|
/* pid: data0 */
|
|
|
|
uhost->hch[hc_num].data_pid = HCH_PID_DATA0;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* pid: data1 */
|
|
|
|
uhost->hch[hc_num].data_pid = HCH_PID_DATA1;
|
|
|
|
}
|
2022-04-11 04:50:25 -07:00
|
|
|
|
2021-12-13 21:39:13 -08:00
|
|
|
return usbh_in_out_request(uhost, hc_num);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief usb host bulk send request
|
|
|
|
* @param uhost: to the structure of usbh_core_type
|
|
|
|
* @param hc_num: channel number
|
|
|
|
* @param buffer: receive buffer
|
|
|
|
* @param length: receive length
|
|
|
|
* @retval status: usb_sts_type status
|
|
|
|
*/
|
|
|
|
usb_sts_type usbh_bulk_send(usbh_core_type *uhost, uint8_t hc_num,
|
|
|
|
uint8_t *buffer, uint16_t length)
|
|
|
|
{
|
|
|
|
/* set direction is out */
|
|
|
|
uhost->hch[hc_num].dir = 0;
|
2022-04-11 04:50:25 -07:00
|
|
|
|
2021-12-13 21:39:13 -08:00
|
|
|
/* set transfer buffer */
|
|
|
|
uhost->hch[hc_num].trans_buf = buffer;
|
2022-04-11 04:50:25 -07:00
|
|
|
|
2021-12-13 21:39:13 -08:00
|
|
|
/* set transfer len*/
|
|
|
|
uhost->hch[hc_num].trans_len = length;
|
2022-04-11 04:50:25 -07:00
|
|
|
|
2021-12-13 21:39:13 -08:00
|
|
|
if(uhost->hch[hc_num].toggle_out == 0)
|
|
|
|
{
|
|
|
|
/* pid: data0 */
|
|
|
|
uhost->hch[hc_num].data_pid = HCH_PID_DATA0;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* pid: data1 */
|
|
|
|
uhost->hch[hc_num].data_pid = HCH_PID_DATA1;
|
|
|
|
}
|
2022-04-11 04:50:25 -07:00
|
|
|
|
2021-12-13 21:39:13 -08:00
|
|
|
return usbh_in_out_request(uhost, hc_num);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief usb host iso send request
|
|
|
|
* @param uhost: to the structure of usbh_core_type
|
|
|
|
* @param hc_num: channel number
|
|
|
|
* @param buffer: send buffer
|
|
|
|
* @param length: send length
|
|
|
|
* @retval status: usb_sts_type status
|
|
|
|
*/
|
|
|
|
usb_sts_type usbh_isoc_send(usbh_core_type *uhost, uint8_t hc_num,
|
|
|
|
uint8_t *buffer, uint16_t length)
|
|
|
|
{
|
|
|
|
/* set direction is out */
|
|
|
|
uhost->hch[hc_num].dir = 0;
|
2022-04-11 04:50:25 -07:00
|
|
|
|
2021-12-13 21:39:13 -08:00
|
|
|
/* set transfer buffer */
|
|
|
|
uhost->hch[hc_num].trans_buf = buffer;
|
2022-04-11 04:50:25 -07:00
|
|
|
|
2021-12-13 21:39:13 -08:00
|
|
|
/* set transfer len*/
|
|
|
|
uhost->hch[hc_num].trans_len = length;
|
2022-04-11 04:50:25 -07:00
|
|
|
|
2021-12-13 21:39:13 -08:00
|
|
|
/* pid: data0 */
|
|
|
|
uhost->hch[hc_num].data_pid = HCH_PID_DATA0;
|
2022-04-11 04:50:25 -07:00
|
|
|
|
2021-12-13 21:39:13 -08:00
|
|
|
return usbh_in_out_request(uhost, hc_num);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief usb host iso receive request
|
|
|
|
* @param uhost: to the structure of usbh_core_type
|
|
|
|
* @param hc_num: channel number
|
|
|
|
* @param buffer: receive buffer
|
|
|
|
* @param length: receive length
|
|
|
|
* @retval status: usb_sts_type status
|
|
|
|
*/
|
|
|
|
usb_sts_type usbh_isoc_recv(usbh_core_type *uhost, uint8_t hc_num,
|
|
|
|
uint8_t *buffer, uint16_t length)
|
|
|
|
{
|
|
|
|
/* set direction is in */
|
|
|
|
uhost->hch[hc_num].dir = 1;
|
2022-04-11 04:50:25 -07:00
|
|
|
|
2021-12-13 21:39:13 -08:00
|
|
|
/* set transfer buffer */
|
|
|
|
uhost->hch[hc_num].trans_buf = buffer;
|
2022-04-11 04:50:25 -07:00
|
|
|
|
2021-12-13 21:39:13 -08:00
|
|
|
/* set transfer len*/
|
|
|
|
uhost->hch[hc_num].trans_len = length;
|
2022-04-11 04:50:25 -07:00
|
|
|
|
2021-12-13 21:39:13 -08:00
|
|
|
/* pid: data0 */
|
|
|
|
uhost->hch[hc_num].data_pid = HCH_PID_DATA0;
|
2022-04-11 04:50:25 -07:00
|
|
|
|
2021-12-13 21:39:13 -08:00
|
|
|
return usbh_in_out_request(uhost, hc_num);
|
|
|
|
}
|
2022-04-11 04:50:25 -07:00
|
|
|
|
2021-12-13 21:39:13 -08:00
|
|
|
/**
|
|
|
|
* @brief usb host cfg default init
|
|
|
|
* @param uhost: to the structure of usbh_core_type
|
|
|
|
* @retval status: usb_sts_type status
|
|
|
|
*/
|
|
|
|
usb_sts_type usbh_cfg_default_init(usbh_core_type *uhost)
|
|
|
|
{
|
|
|
|
/* set global state to idle */
|
|
|
|
uhost->global_state = USBH_IDLE;
|
2022-04-11 04:50:25 -07:00
|
|
|
|
2021-12-13 21:39:13 -08:00
|
|
|
/* enumeration state to get description */
|
|
|
|
uhost->enum_state = ENUM_GET_MIN_DESC;
|
2022-04-11 04:50:25 -07:00
|
|
|
|
2021-12-13 21:39:13 -08:00
|
|
|
/* request state send */
|
|
|
|
uhost->req_state = CMD_SEND;
|
2022-04-11 04:50:25 -07:00
|
|
|
|
2021-12-13 21:39:13 -08:00
|
|
|
/* control transfer state is idle*/
|
|
|
|
uhost->ctrl.state = CONTROL_IDLE;
|
2022-04-11 04:50:25 -07:00
|
|
|
|
2021-12-13 21:39:13 -08:00
|
|
|
/* defaut endpoint 0 max size is 8byte */
|
|
|
|
uhost->ctrl.ept0_size = 8;
|
2022-04-11 04:50:25 -07:00
|
|
|
|
2021-12-13 21:39:13 -08:00
|
|
|
/* default device address is 0 */
|
|
|
|
uhost->dev.address = 0;
|
2022-04-11 04:50:25 -07:00
|
|
|
|
2021-12-13 21:39:13 -08:00
|
|
|
/* default speed is full speed */
|
|
|
|
uhost->dev.speed = USB_FULL_SPEED_CORE_ID;
|
2022-04-11 04:50:25 -07:00
|
|
|
|
2022-03-03 03:49:19 -08:00
|
|
|
uhost->timer = 0;
|
2022-04-11 04:50:25 -07:00
|
|
|
|
2022-03-03 03:49:19 -08:00
|
|
|
uhost->ctrl.err_cnt = 0;
|
2022-04-11 04:50:25 -07:00
|
|
|
|
2021-12-13 21:39:13 -08:00
|
|
|
/* free all channel */
|
|
|
|
usbh_free_channel(uhost, uhost->ctrl.hch_in);
|
|
|
|
usbh_free_channel(uhost, uhost->ctrl.hch_out);
|
|
|
|
return USB_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief usb host enter suspend
|
|
|
|
* @param uhost: to the structure of usbh_core_type
|
|
|
|
* @retval none
|
|
|
|
*/
|
|
|
|
void usbh_enter_suspend(usbh_core_type *uhost)
|
|
|
|
{
|
|
|
|
otg_host_type *host = OTG_HOST(uhost->usb_reg);
|
|
|
|
uint32_t hprt_val = host->hprt;
|
2022-04-11 04:50:25 -07:00
|
|
|
|
|
|
|
hprt_val &= ~(USB_OTG_HPRT_PRTENA | USB_OTG_HPRT_PRTENCHNG |
|
2021-12-13 21:39:13 -08:00
|
|
|
USB_OTG_HPRT_PRTOVRCACT | USB_OTG_HPRT_PRTCONDET);
|
2022-04-11 04:50:25 -07:00
|
|
|
|
2021-12-13 21:39:13 -08:00
|
|
|
/* set port suspend */
|
|
|
|
host->hprt = hprt_val | USB_OTG_HPRT_PRTSUSP;
|
2022-04-11 04:50:25 -07:00
|
|
|
|
2021-12-13 21:39:13 -08:00
|
|
|
/* stop phy clock */
|
|
|
|
usb_stop_phy_clk(uhost->usb_reg);
|
2022-04-11 04:50:25 -07:00
|
|
|
|
2021-12-13 21:39:13 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief usb host resume
|
|
|
|
* @param uhost: to the structure of usbh_core_type
|
|
|
|
* @retval none
|
|
|
|
*/
|
|
|
|
void usbh_resume(usbh_core_type *uhost)
|
|
|
|
{
|
|
|
|
otg_host_type *host = OTG_HOST(uhost->usb_reg);
|
|
|
|
uint32_t temp = host->hprt;
|
2022-04-11 04:50:25 -07:00
|
|
|
|
2021-12-13 21:39:13 -08:00
|
|
|
/* open phy clock */
|
|
|
|
usb_open_phy_clk(uhost->usb_reg);
|
2022-04-11 04:50:25 -07:00
|
|
|
|
2021-12-13 21:39:13 -08:00
|
|
|
/* clear port suspend and set port resume*/
|
2022-04-11 04:50:25 -07:00
|
|
|
temp &= ~(USB_OTG_HPRT_PRTENA | USB_OTG_HPRT_PRTENCHNG |
|
2021-12-13 21:39:13 -08:00
|
|
|
USB_OTG_HPRT_PRTOVRCACT | USB_OTG_HPRT_PRTCONDET
|
|
|
|
| USB_OTG_HPRT_PRTSUSP);
|
|
|
|
host->hprt = temp | USB_OTG_HPRT_PRTRES;
|
2022-04-11 04:50:25 -07:00
|
|
|
|
2021-12-13 21:39:13 -08:00
|
|
|
/* delay 20 ms */
|
|
|
|
usb_delay_ms(20);
|
2022-04-11 04:50:25 -07:00
|
|
|
|
2021-12-13 21:39:13 -08:00
|
|
|
/*clear port resume */
|
|
|
|
temp = host->hprt;
|
2022-04-11 04:50:25 -07:00
|
|
|
temp &= ~(USB_OTG_HPRT_PRTENA | USB_OTG_HPRT_PRTENCHNG |
|
2021-12-13 21:39:13 -08:00
|
|
|
USB_OTG_HPRT_PRTOVRCACT | USB_OTG_HPRT_PRTCONDET
|
|
|
|
| USB_OTG_HPRT_PRTRES);
|
|
|
|
host->hprt = temp;
|
|
|
|
usb_delay_ms(5);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief usb host core initialize
|
|
|
|
* @param uhost: to the structure of usbh_core_type
|
|
|
|
* @param usb_reg: usb otgfs peripheral global register
|
|
|
|
* this parameter can be one of the following values:
|
|
|
|
* OTG1_GLOBAL , OTG2_GLOBAL
|
|
|
|
* @param class_handler: usb host class handler type pointer
|
|
|
|
* @param user_handler: usb host user handler type pointer
|
|
|
|
* @param core_id: usb core select id
|
|
|
|
* @retval status: usb_sts_type status
|
|
|
|
*/
|
|
|
|
usb_sts_type usbh_core_init(usbh_core_type *uhost,
|
|
|
|
usb_reg_type *usb_reg,
|
|
|
|
usbh_class_handler_type *class_handler,
|
|
|
|
usbh_user_handler_type *user_handler,
|
|
|
|
uint8_t core_id)
|
|
|
|
{
|
|
|
|
usb_sts_type status = USB_OK;
|
|
|
|
uint32_t i_index;
|
|
|
|
otg_global_type *usbx = usb_reg;
|
|
|
|
otg_host_type *host = OTG_HOST(usbx);
|
|
|
|
uhost->usb_reg = usb_reg;
|
2022-04-11 04:50:25 -07:00
|
|
|
|
2021-12-13 21:39:13 -08:00
|
|
|
/* host class handler */
|
|
|
|
uhost->class_handler = class_handler;
|
|
|
|
uhost->user_handler = user_handler;
|
2022-04-11 04:50:25 -07:00
|
|
|
|
2021-12-13 21:39:13 -08:00
|
|
|
/* host user handler */
|
|
|
|
uhost->user_handler->user_init();
|
2022-04-11 04:50:25 -07:00
|
|
|
|
2022-01-21 00:05:17 -08:00
|
|
|
uhost->timer = 0;
|
2022-04-11 04:50:25 -07:00
|
|
|
|
2021-12-13 21:39:13 -08:00
|
|
|
/* usb host cfg default init */
|
|
|
|
usbh_cfg_default_init(uhost);
|
2022-04-11 04:50:25 -07:00
|
|
|
|
2021-12-13 21:39:13 -08:00
|
|
|
/* clear host config to default value */
|
|
|
|
for(i_index = 0; i_index < USB_HOST_CHANNEL_NUM; i_index ++)
|
|
|
|
{
|
|
|
|
uhost->err_cnt[i_index] = 0;
|
|
|
|
uhost->xfer_cnt[i_index] = 0;
|
|
|
|
uhost->hch_state[i_index] = HCH_IDLE;
|
2022-04-11 04:50:25 -07:00
|
|
|
uhost->hch[0].maxpacket = 8;
|
2021-12-13 21:39:13 -08:00
|
|
|
}
|
2022-04-11 04:50:25 -07:00
|
|
|
|
2021-12-13 21:39:13 -08:00
|
|
|
/* no device connect */
|
|
|
|
uhost->conn_sts = 0;
|
2022-04-11 04:50:25 -07:00
|
|
|
|
2021-12-13 21:39:13 -08:00
|
|
|
/* disable usb interrupt */
|
|
|
|
usb_interrupt_disable(usbx);
|
2022-04-11 04:50:25 -07:00
|
|
|
|
2021-12-13 21:39:13 -08:00
|
|
|
/* usb global init */
|
|
|
|
usb_global_init(usbx);
|
2022-04-11 04:50:25 -07:00
|
|
|
|
2021-12-13 21:39:13 -08:00
|
|
|
/* set usb host mode */
|
|
|
|
usb_global_set_mode(usbx, OTG_HOST_MODE);
|
2022-04-11 04:50:25 -07:00
|
|
|
|
2021-12-13 21:39:13 -08:00
|
|
|
/* open usb phy clock*/
|
|
|
|
usb_open_phy_clk(usbx);
|
2022-04-11 04:50:25 -07:00
|
|
|
|
2021-12-13 21:39:13 -08:00
|
|
|
/* clock select */
|
|
|
|
usbh_fsls_clksel(usbx, USB_HCFG_CLK_48M);
|
2022-04-11 04:50:25 -07:00
|
|
|
|
2021-12-13 21:39:13 -08:00
|
|
|
/* set support ls and fs device */
|
|
|
|
host->hcfg_bit.fslssupp = 0;
|
2022-04-11 04:50:25 -07:00
|
|
|
|
2021-12-13 21:39:13 -08:00
|
|
|
if(usbx == OTG1_GLOBAL)
|
|
|
|
{
|
2022-04-11 04:50:25 -07:00
|
|
|
/* set receive fifo size */
|
|
|
|
usbx->grxfsiz = USBH_RX_FIFO_SIZE;
|
|
|
|
|
2021-12-13 21:39:13 -08:00
|
|
|
/* set non-periodic transmit fifo start address and depth */
|
|
|
|
usbx->gnptxfsiz_ept0tx_bit.nptxfstaddr = USBH_RX_FIFO_SIZE;
|
|
|
|
usbx->gnptxfsiz_ept0tx_bit.nptxfdep = USBH_NP_TX_FIFO_SIZE;
|
2022-04-11 04:50:25 -07:00
|
|
|
|
2021-12-13 21:39:13 -08:00
|
|
|
/* set periodic transmit fifo start address and depth */
|
|
|
|
usbx->hptxfsiz_bit.ptxfstaddr = USBH_RX_FIFO_SIZE + USBH_NP_TX_FIFO_SIZE;
|
|
|
|
usbx->hptxfsiz_bit.ptxfsize = USBH_P_TX_FIFO_SIZE;
|
|
|
|
}
|
|
|
|
#ifdef OTG2_GLOBAL
|
|
|
|
if(usbx == OTG2_GLOBAL)
|
|
|
|
{
|
2022-04-11 04:50:25 -07:00
|
|
|
/* set receive fifo size */
|
|
|
|
usbx->grxfsiz = USBH2_RX_FIFO_SIZE;
|
|
|
|
|
2021-12-13 21:39:13 -08:00
|
|
|
/* set non-periodic transmit fifo start address and depth */
|
|
|
|
usbx->gnptxfsiz_ept0tx_bit.nptxfstaddr = USBH2_RX_FIFO_SIZE;
|
|
|
|
usbx->gnptxfsiz_ept0tx_bit.nptxfdep = USBH2_NP_TX_FIFO_SIZE;
|
2022-04-11 04:50:25 -07:00
|
|
|
|
2021-12-13 21:39:13 -08:00
|
|
|
/* set periodic transmit fifo start address and depth */
|
|
|
|
usbx->hptxfsiz_bit.ptxfstaddr = USBH2_RX_FIFO_SIZE + USBH2_NP_TX_FIFO_SIZE;
|
|
|
|
usbx->hptxfsiz_bit.ptxfsize = USBH2_P_TX_FIFO_SIZE;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
/* flush tx fifo */
|
|
|
|
usb_flush_tx_fifo(usbx, 16);
|
2022-04-11 04:50:25 -07:00
|
|
|
|
2021-12-13 21:39:13 -08:00
|
|
|
/* flush rx fifo */
|
|
|
|
usb_flush_rx_fifo(usbx);
|
2022-04-11 04:50:25 -07:00
|
|
|
|
2021-12-13 21:39:13 -08:00
|
|
|
/* clear host channel interrut mask and status */
|
|
|
|
for(i_index = 0; i_index < USB_HOST_CHANNEL_NUM; i_index ++)
|
|
|
|
{
|
|
|
|
USB_CHL(usbx, i_index)->hcintmsk = 0;
|
|
|
|
USB_CHL(usbx, i_index)->hcint = 0xFFFFFFFF;
|
|
|
|
}
|
2022-04-11 04:50:25 -07:00
|
|
|
|
2021-12-13 21:39:13 -08:00
|
|
|
/* power on to this port */
|
|
|
|
usb_port_power_on(usbx, TRUE);
|
2022-04-11 04:50:25 -07:00
|
|
|
|
2021-12-13 21:39:13 -08:00
|
|
|
/* clear global interrupt mask and status */
|
|
|
|
usbx->gintmsk = 0;
|
|
|
|
usbx->gintsts = 0xBFFFFFFF;
|
2022-04-11 04:50:25 -07:00
|
|
|
|
2021-12-13 21:39:13 -08:00
|
|
|
/* set global interrut mask */
|
2022-04-11 04:50:25 -07:00
|
|
|
usbx->gintmsk = USB_OTG_SOF_INT | USB_OTG_RXFLVL_INT |
|
|
|
|
USB_OTG_USBSUSP_INT | USB_OTG_PRT_INT |
|
|
|
|
USB_OTG_HCH_INT | USB_OTG_INCOMISOIN_INT |
|
|
|
|
USB_OTG_INCOMPIP_INCOMPISOOUT_INT | USB_OTG_WKUP_INT |
|
2021-12-13 21:39:13 -08:00
|
|
|
USB_OTG_DISCON_INT;
|
2022-04-11 04:50:25 -07:00
|
|
|
|
2021-12-13 21:39:13 -08:00
|
|
|
/* enable usb global interrupt */
|
|
|
|
usb_interrupt_enable(usbx);
|
2022-04-11 04:50:25 -07:00
|
|
|
|
2021-12-13 21:39:13 -08:00
|
|
|
/* active vbus */
|
|
|
|
usbh_active_vbus(uhost, TRUE);
|
|
|
|
return status;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief usb host open channel
|
|
|
|
* @param uhost: to the structure of usbh_core_type
|
|
|
|
* @param chn: host channel number
|
|
|
|
* @param ept_num: devvice endpoint number
|
|
|
|
* @param dev_address: device address
|
|
|
|
* @param type: channel transfer type
|
2022-04-11 04:50:25 -07:00
|
|
|
* this parameter can be one of the following values:
|
2021-12-13 21:39:13 -08:00
|
|
|
* - EPT_CONTROL_TYPE
|
|
|
|
* - EPT_BULK_TYPE
|
|
|
|
* - EPT_INT_TYPE
|
|
|
|
* - EPT_ISO_TYPE
|
|
|
|
* @param maxpacket: support max packe size for this channel
|
|
|
|
* @param speed: device speed
|
2022-04-11 04:50:25 -07:00
|
|
|
* this parameter can be one of the following values:
|
2021-12-13 21:39:13 -08:00
|
|
|
* - USB_PRTSPD_FULL_SPEED
|
|
|
|
* - USB_PRTSPD_LOW_SPEED
|
|
|
|
* @param ept_addr: endpoint address
|
|
|
|
* @retval usb_sts_type
|
|
|
|
*/
|
|
|
|
void usbh_hc_open(usbh_core_type *uhost,
|
|
|
|
uint8_t chn,
|
2022-04-11 04:50:25 -07:00
|
|
|
uint8_t ept_num,
|
2021-12-13 21:39:13 -08:00
|
|
|
uint8_t dev_address,
|
2022-04-11 04:50:25 -07:00
|
|
|
uint8_t type,
|
|
|
|
uint16_t maxpacket,
|
2021-12-13 21:39:13 -08:00
|
|
|
uint8_t speed)
|
|
|
|
{
|
|
|
|
/* device address */
|
|
|
|
uhost->hch[chn].address = dev_address;
|
2022-04-11 04:50:25 -07:00
|
|
|
|
2021-12-13 21:39:13 -08:00
|
|
|
/* device speed */
|
|
|
|
uhost->hch[chn].speed = speed;
|
2022-04-11 04:50:25 -07:00
|
|
|
|
2021-12-13 21:39:13 -08:00
|
|
|
/* endpoint transfer type */
|
|
|
|
uhost->hch[chn].ept_type = type;
|
2022-04-11 04:50:25 -07:00
|
|
|
|
2021-12-13 21:39:13 -08:00
|
|
|
/* endpoint support maxpacket */
|
|
|
|
uhost->hch[chn].maxpacket = maxpacket;
|
2022-04-11 04:50:25 -07:00
|
|
|
|
2021-12-13 21:39:13 -08:00
|
|
|
/* endpoint direction in or out */
|
|
|
|
uhost->hch[chn].dir = (ept_num & 0x80)?1:0;;
|
2022-04-11 04:50:25 -07:00
|
|
|
|
2021-12-13 21:39:13 -08:00
|
|
|
/* host channel number */
|
|
|
|
uhost->hch[chn].ch_num = chn;
|
2022-04-11 04:50:25 -07:00
|
|
|
|
2021-12-13 21:39:13 -08:00
|
|
|
/* device endpoint number */
|
|
|
|
uhost->hch[chn].ept_num = ept_num;
|
2022-04-11 04:50:25 -07:00
|
|
|
|
2021-12-13 21:39:13 -08:00
|
|
|
/* enable channel */
|
|
|
|
usb_hc_enable(uhost->usb_reg, chn,
|
|
|
|
ept_num, dev_address,
|
|
|
|
type, maxpacket, speed
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief disable host channel
|
|
|
|
* @param usbx: to select the otgfs peripheral.
|
|
|
|
* this parameter can be one of the following values:
|
2022-04-11 04:50:25 -07:00
|
|
|
* - OTG1_GLOBAL
|
2021-12-13 21:39:13 -08:00
|
|
|
* - OTG2_GLOBAL
|
|
|
|
* @param chn: channel number
|
2022-04-11 04:50:25 -07:00
|
|
|
* @retval none
|
2021-12-13 21:39:13 -08:00
|
|
|
*/
|
|
|
|
void usbh_ch_disable(usbh_core_type *uhost, uint8_t chn)
|
|
|
|
{
|
|
|
|
usb_hch_halt(uhost->usb_reg, chn);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief usb host alloc channel
|
|
|
|
* @param uhost: to the structure of usbh_core_type
|
|
|
|
* @param ept_addr: endpoint address
|
|
|
|
* @retval usb_sts_type
|
|
|
|
*/
|
|
|
|
uint16_t usbh_alloc_channel(usbh_core_type *uhost, uint8_t ept_addr)
|
|
|
|
{
|
|
|
|
/* get one free channel */
|
|
|
|
uint16_t ch_num = usbh_get_free_channel(uhost);
|
2022-04-11 04:50:25 -07:00
|
|
|
|
2021-12-13 21:39:13 -08:00
|
|
|
if(ch_num == HCH_ERROR)
|
|
|
|
return USB_FAIL;
|
2022-04-11 04:50:25 -07:00
|
|
|
|
2021-12-13 21:39:13 -08:00
|
|
|
/* set channel to used */
|
|
|
|
uhost->channel[ch_num] = HCH_USED | ept_addr;
|
|
|
|
return ch_num;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief usb host get urb status
|
|
|
|
* @param uhost: to the structure of usbh_core_type
|
|
|
|
* @param ch_num: channel number
|
|
|
|
* @retval urb_sts_type: urb status
|
|
|
|
*/
|
|
|
|
urb_sts_type usbh_get_urb_status(usbh_core_type *uhost, uint8_t ch_num)
|
|
|
|
{
|
|
|
|
return uhost->urb_state[ch_num];
|
|
|
|
}
|
|
|
|
/**
|
2022-04-11 04:50:25 -07:00
|
|
|
* @brief usb wait control setup complete
|
2021-12-13 21:39:13 -08:00
|
|
|
* @param uhost: to the structure of usbh_core_type
|
|
|
|
* @param next_ctrl_state: next ctrl state when setup complete
|
|
|
|
* @param next_enum_state: next enum state when setup complete
|
|
|
|
* @retval status: usb_sts_type status
|
|
|
|
*/
|
|
|
|
usb_sts_type usbh_ctrl_result_check(usbh_core_type *uhost, ctrl_ept0_sts_type next_ctrl_state, uint8_t next_enum_state)
|
|
|
|
{
|
|
|
|
usb_sts_type status;
|
2022-04-11 04:50:25 -07:00
|
|
|
|
2021-12-13 21:39:13 -08:00
|
|
|
/* control transfer loop */
|
|
|
|
status = usbh_ctrl_transfer_loop(uhost);
|
2022-04-11 04:50:25 -07:00
|
|
|
|
2021-12-13 21:39:13 -08:00
|
|
|
if(status == USB_OK)
|
|
|
|
{
|
|
|
|
uhost->ctrl.state = next_ctrl_state;
|
|
|
|
uhost->enum_state = next_enum_state;
|
|
|
|
uhost->req_state = CMD_SEND;
|
|
|
|
}
|
|
|
|
else if(status == USB_ERROR)
|
|
|
|
{
|
|
|
|
uhost->ctrl.state = CONTROL_IDLE;
|
|
|
|
uhost->req_state = CMD_SEND;
|
|
|
|
}
|
|
|
|
else if(status == USB_NOT_SUPPORT)
|
|
|
|
{
|
|
|
|
uhost->ctrl.state = next_ctrl_state;
|
|
|
|
uhost->enum_state = next_enum_state;
|
|
|
|
uhost->req_state = CMD_SEND;
|
|
|
|
}
|
|
|
|
return status;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2022-04-11 04:50:25 -07:00
|
|
|
* @brief auto alloc address (1...20)
|
2021-12-13 21:39:13 -08:00
|
|
|
* @param none
|
2022-03-03 03:49:19 -08:00
|
|
|
* @retval address (1...20)
|
2021-12-13 21:39:13 -08:00
|
|
|
*/
|
|
|
|
uint8_t usbh_alloc_address(void)
|
|
|
|
{
|
2022-03-03 03:49:19 -08:00
|
|
|
static uint8_t address = 1;
|
|
|
|
if(address == 20)
|
|
|
|
address = 1;
|
|
|
|
return address ++;
|
2021-12-13 21:39:13 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief usb host enumeration handler
|
|
|
|
* @param uhost: to the structure of usbh_core_type
|
|
|
|
* @retval status: usb_sts_type status
|
|
|
|
*/
|
|
|
|
usb_sts_type usbh_enum_handler(usbh_core_type *uhost)
|
|
|
|
{
|
|
|
|
usb_sts_type status = USB_WAIT;
|
|
|
|
switch(uhost->enum_state)
|
|
|
|
{
|
|
|
|
case ENUM_IDLE:
|
|
|
|
break;
|
|
|
|
case ENUM_GET_MIN_DESC:
|
|
|
|
/* get description */
|
|
|
|
if(uhost->ctrl.state == CONTROL_IDLE)
|
|
|
|
{
|
|
|
|
usbh_get_device_descriptor(uhost, 8);
|
|
|
|
}
|
|
|
|
if(usbh_ctrl_result_check(uhost, CONTROL_IDLE, ENUM_GET_FULL_DESC) == USB_OK)
|
|
|
|
{
|
|
|
|
usbh_parse_dev_desc(uhost, uhost->rx_buffer, 8);
|
2022-04-11 04:50:25 -07:00
|
|
|
|
2021-12-13 21:39:13 -08:00
|
|
|
/* set new control endpoint maxpacket size */
|
|
|
|
uhost->ctrl.ept0_size = (uhost->dev).dev_desc.bMaxPacketSize0;
|
2022-04-11 04:50:25 -07:00
|
|
|
|
2021-12-13 21:39:13 -08:00
|
|
|
/* enable channel */
|
|
|
|
usbh_hc_open(uhost, uhost->ctrl.hch_in,0x80,
|
|
|
|
uhost->dev.address, EPT_CONTROL_TYPE,
|
2022-04-11 04:50:25 -07:00
|
|
|
uhost->ctrl.ept0_size,
|
2021-12-13 21:39:13 -08:00
|
|
|
uhost->dev.speed);
|
2022-04-11 04:50:25 -07:00
|
|
|
|
2021-12-13 21:39:13 -08:00
|
|
|
/* enable channel */
|
|
|
|
usbh_hc_open(uhost, uhost->ctrl.hch_out,0x00,
|
|
|
|
uhost->dev.address, EPT_CONTROL_TYPE,
|
2022-04-11 04:50:25 -07:00
|
|
|
uhost->ctrl.ept0_size,
|
2021-12-13 21:39:13 -08:00
|
|
|
uhost->dev.speed);
|
|
|
|
}
|
|
|
|
break;
|
2022-04-11 04:50:25 -07:00
|
|
|
|
2021-12-13 21:39:13 -08:00
|
|
|
case ENUM_GET_FULL_DESC:
|
|
|
|
/* get description */
|
|
|
|
if(uhost->ctrl.state == CONTROL_IDLE)
|
|
|
|
{
|
|
|
|
usbh_get_device_descriptor(uhost, 18);
|
|
|
|
}
|
|
|
|
if(usbh_ctrl_result_check(uhost, CONTROL_IDLE, ENUM_SET_ADDR) == USB_OK)
|
|
|
|
{
|
|
|
|
usbh_parse_dev_desc(uhost, uhost->rx_buffer, 18);
|
|
|
|
USBH_DEBUG("VID: %xh", uhost->dev.dev_desc.idVendor);
|
|
|
|
USBH_DEBUG("PID: %xh", uhost->dev.dev_desc.idProduct);
|
|
|
|
}
|
|
|
|
break;
|
2022-04-11 04:50:25 -07:00
|
|
|
|
2021-12-13 21:39:13 -08:00
|
|
|
case ENUM_SET_ADDR:
|
|
|
|
/* set device address */
|
|
|
|
if(uhost->ctrl.state == CONTROL_IDLE)
|
|
|
|
{
|
|
|
|
uhost->dev.address = usbh_alloc_address();
|
|
|
|
USBH_DEBUG("Set Address: %d", uhost->dev.address);
|
2022-04-11 04:50:25 -07:00
|
|
|
usbh_set_address(uhost, uhost->dev.address);
|
2021-12-13 21:39:13 -08:00
|
|
|
}
|
|
|
|
if (usbh_ctrl_result_check(uhost, CONTROL_IDLE, ENUM_GET_CFG) == USB_OK)
|
|
|
|
{
|
|
|
|
/* enable channel */
|
|
|
|
usbh_hc_open(uhost, uhost->ctrl.hch_in,0x80,
|
|
|
|
uhost->dev.address, EPT_CONTROL_TYPE,
|
2022-04-11 04:50:25 -07:00
|
|
|
uhost->ctrl.ept0_size,
|
2021-12-13 21:39:13 -08:00
|
|
|
uhost->dev.speed);
|
2022-04-11 04:50:25 -07:00
|
|
|
|
2021-12-13 21:39:13 -08:00
|
|
|
/* enable channel */
|
|
|
|
usbh_hc_open(uhost, uhost->ctrl.hch_out,0x00,
|
|
|
|
uhost->dev.address, EPT_CONTROL_TYPE,
|
2022-04-11 04:50:25 -07:00
|
|
|
uhost->ctrl.ept0_size,
|
2021-12-13 21:39:13 -08:00
|
|
|
uhost->dev.speed);
|
|
|
|
}
|
|
|
|
break;
|
2022-04-11 04:50:25 -07:00
|
|
|
|
2021-12-13 21:39:13 -08:00
|
|
|
case ENUM_GET_CFG:
|
|
|
|
/* get device confiuration */
|
|
|
|
if(uhost->ctrl.state == CONTROL_IDLE)
|
|
|
|
{
|
|
|
|
usbh_get_configure_descriptor(uhost, 9);
|
|
|
|
}
|
2022-04-11 04:50:25 -07:00
|
|
|
|
2021-12-13 21:39:13 -08:00
|
|
|
if(usbh_ctrl_result_check(uhost, CONTROL_IDLE, ENUM_GET_FULL_CFG) == USB_OK)
|
|
|
|
{
|
|
|
|
usbh_parse_configure_desc(uhost, uhost->rx_buffer, 9);
|
|
|
|
}
|
|
|
|
break;
|
2022-04-11 04:50:25 -07:00
|
|
|
|
2021-12-13 21:39:13 -08:00
|
|
|
case ENUM_GET_FULL_CFG:
|
|
|
|
/* get device confiuration */
|
|
|
|
if(uhost->ctrl.state == CONTROL_IDLE)
|
|
|
|
{
|
|
|
|
usbh_get_configure_descriptor(uhost, uhost->dev.cfg_desc.cfg.wTotalLength);
|
|
|
|
}
|
2022-04-11 04:50:25 -07:00
|
|
|
|
2021-12-13 21:39:13 -08:00
|
|
|
if(usbh_ctrl_result_check(uhost, CONTROL_IDLE, ENUM_GET_MFC_STRING) == USB_OK)
|
|
|
|
{
|
|
|
|
usbh_parse_configure_desc(uhost, uhost->rx_buffer, uhost->dev.cfg_desc.cfg.wTotalLength);
|
|
|
|
}
|
|
|
|
break;
|
2022-04-11 04:50:25 -07:00
|
|
|
|
2021-12-13 21:39:13 -08:00
|
|
|
case ENUM_GET_MFC_STRING:
|
|
|
|
/* get device mfc string */
|
|
|
|
if(uhost->ctrl.state == CONTROL_IDLE)
|
|
|
|
{
|
2022-04-11 04:50:25 -07:00
|
|
|
usbh_get_sting_descriptor(uhost, uhost->dev.dev_desc.iManufacturer,
|
2021-12-13 21:39:13 -08:00
|
|
|
uhost->rx_buffer, 0xFF);
|
|
|
|
}
|
2022-04-11 04:50:25 -07:00
|
|
|
|
2021-12-13 21:39:13 -08:00
|
|
|
if(usbh_ctrl_result_check(uhost, CONTROL_IDLE, ENUM_GET_PRODUCT_STRING) == USB_OK)
|
|
|
|
{
|
|
|
|
usbh_parse_string_desc(uhost->rx_buffer, uhost->rx_buffer, 0xFF);
|
|
|
|
uhost->user_handler->user_mfc_string(uhost->rx_buffer);
|
|
|
|
}
|
|
|
|
break;
|
2022-04-11 04:50:25 -07:00
|
|
|
|
2021-12-13 21:39:13 -08:00
|
|
|
case ENUM_GET_PRODUCT_STRING:
|
|
|
|
/* get device product string */
|
|
|
|
if(uhost->ctrl.state == CONTROL_IDLE)
|
|
|
|
{
|
2022-04-11 04:50:25 -07:00
|
|
|
usbh_get_sting_descriptor(uhost, uhost->dev.dev_desc.iProduct,
|
2021-12-13 21:39:13 -08:00
|
|
|
uhost->rx_buffer, 0xFF);
|
|
|
|
}
|
2022-04-11 04:50:25 -07:00
|
|
|
|
2021-12-13 21:39:13 -08:00
|
|
|
if(usbh_ctrl_result_check(uhost, CONTROL_IDLE, ENUM_GET_SERIALNUM_STRING) == USB_OK)
|
|
|
|
{
|
|
|
|
usbh_parse_string_desc(uhost->rx_buffer, uhost->rx_buffer, 0xFF);
|
|
|
|
uhost->user_handler->user_product_string(uhost->rx_buffer);
|
|
|
|
}
|
|
|
|
break;
|
2022-04-11 04:50:25 -07:00
|
|
|
|
2021-12-13 21:39:13 -08:00
|
|
|
case ENUM_GET_SERIALNUM_STRING:
|
|
|
|
/* get device serial string */
|
|
|
|
if(uhost->ctrl.state == CONTROL_IDLE)
|
|
|
|
{
|
2022-04-11 04:50:25 -07:00
|
|
|
usbh_get_sting_descriptor(uhost, uhost->dev.dev_desc.iSerialNumber,
|
2021-12-13 21:39:13 -08:00
|
|
|
uhost->rx_buffer, 0xFF);
|
|
|
|
}
|
2022-04-11 04:50:25 -07:00
|
|
|
|
2021-12-13 21:39:13 -08:00
|
|
|
if(usbh_ctrl_result_check(uhost, CONTROL_IDLE, ENUM_SET_CONFIG) == USB_OK)
|
|
|
|
{
|
|
|
|
usbh_parse_string_desc(uhost->rx_buffer, uhost->rx_buffer, 0xFF);
|
|
|
|
uhost->user_handler->user_serial_string(uhost->rx_buffer);
|
|
|
|
}
|
|
|
|
break;
|
2022-04-11 04:50:25 -07:00
|
|
|
|
2021-12-13 21:39:13 -08:00
|
|
|
case ENUM_SET_CONFIG:
|
|
|
|
/* set device config */
|
|
|
|
if(uhost->ctrl.state == CONTROL_IDLE)
|
|
|
|
{
|
|
|
|
usbh_set_configuration(uhost, uhost->dev.cfg_desc.cfg.bConfigurationValue);
|
|
|
|
}
|
|
|
|
usbh_ctrl_result_check(uhost, CONTROL_IDLE, ENUM_COMPLETE);
|
2022-04-11 04:50:25 -07:00
|
|
|
|
2021-12-13 21:39:13 -08:00
|
|
|
break;
|
2022-04-11 04:50:25 -07:00
|
|
|
|
2021-12-13 21:39:13 -08:00
|
|
|
case ENUM_COMPLETE:
|
|
|
|
/* enum complete */
|
|
|
|
status = USB_OK;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
return status;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief active vbus.
|
|
|
|
* @param uhost: to the structure of usbh_core_type
|
|
|
|
* @param state: vbus state
|
|
|
|
* @retval none
|
|
|
|
*/
|
|
|
|
void usbh_active_vbus(usbh_core_type *uhost, confirm_state state)
|
|
|
|
{
|
|
|
|
uhost->user_handler->user_active_vbus(uhost, state);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief reset usb port
|
|
|
|
* @param usbx: to the structure of otg_global_type
|
2022-04-11 04:50:25 -07:00
|
|
|
* @retval none
|
2021-12-13 21:39:13 -08:00
|
|
|
*/
|
|
|
|
void usbh_reset_port(usbh_core_type *uhost)
|
|
|
|
{
|
|
|
|
otg_host_type *usb_host = OTG_HOST(uhost->usb_reg);
|
|
|
|
uint32_t hprt_val = usb_host->hprt;
|
2022-04-11 04:50:25 -07:00
|
|
|
|
|
|
|
hprt_val &= ~(USB_OTG_HPRT_PRTENA | USB_OTG_HPRT_PRTENCHNG |
|
2021-12-13 21:39:13 -08:00
|
|
|
USB_OTG_HPRT_PRTOVRCACT | USB_OTG_HPRT_PRTCONDET);
|
2022-04-11 04:50:25 -07:00
|
|
|
|
2021-12-13 21:39:13 -08:00
|
|
|
/* set port reset */
|
|
|
|
usb_host->hprt = hprt_val | USB_OTG_HPRT_PRTRST;
|
2022-04-11 04:50:25 -07:00
|
|
|
|
2022-01-21 00:05:17 -08:00
|
|
|
usb_delay_ms(100);
|
2022-04-11 04:50:25 -07:00
|
|
|
|
2021-12-13 21:39:13 -08:00
|
|
|
/* clear port reset */
|
|
|
|
usb_host->hprt = hprt_val & (~USB_OTG_HPRT_PRTRST);
|
2022-04-11 04:50:25 -07:00
|
|
|
|
2022-01-21 00:05:17 -08:00
|
|
|
usb_delay_ms(20);
|
2022-04-11 04:50:25 -07:00
|
|
|
|
2021-12-13 21:39:13 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief usb host attached
|
|
|
|
* @param uhost: to the structure of usbh_core_type
|
|
|
|
* @retval none
|
|
|
|
*/
|
|
|
|
static void usbh_attached(usbh_core_type *uhost)
|
|
|
|
{
|
|
|
|
/* get free channel */
|
|
|
|
uhost->ctrl.hch_in = usbh_alloc_channel(uhost, 0x80);
|
|
|
|
uhost->ctrl.hch_out = usbh_alloc_channel(uhost, 0x00);
|
2022-04-11 04:50:25 -07:00
|
|
|
|
2021-12-13 21:39:13 -08:00
|
|
|
/* user reset callback handler */
|
|
|
|
uhost->user_handler->user_reset();
|
2022-04-11 04:50:25 -07:00
|
|
|
|
2021-12-13 21:39:13 -08:00
|
|
|
/* get device speed */
|
|
|
|
uhost->dev.speed = OTG_HOST(uhost->usb_reg)->hprt_bit.prtspd;
|
|
|
|
uhost->global_state = USBH_ENUMERATION;
|
|
|
|
uhost->user_handler->user_speed(uhost->dev.speed);
|
2022-04-11 04:50:25 -07:00
|
|
|
|
2021-12-13 21:39:13 -08:00
|
|
|
/* enable channel */
|
|
|
|
usbh_hc_open(uhost, uhost->ctrl.hch_in,0x80,
|
|
|
|
uhost->dev.address, EPT_CONTROL_TYPE,
|
2022-04-11 04:50:25 -07:00
|
|
|
uhost->ctrl.ept0_size,
|
2021-12-13 21:39:13 -08:00
|
|
|
uhost->dev.speed);
|
2022-04-11 04:50:25 -07:00
|
|
|
|
2021-12-13 21:39:13 -08:00
|
|
|
/* enable channel */
|
|
|
|
usbh_hc_open(uhost, uhost->ctrl.hch_out,0x00,
|
|
|
|
uhost->dev.address, EPT_CONTROL_TYPE,
|
2022-04-11 04:50:25 -07:00
|
|
|
uhost->ctrl.ept0_size,
|
2021-12-13 21:39:13 -08:00
|
|
|
uhost->dev.speed);
|
2022-04-11 04:50:25 -07:00
|
|
|
|
2022-01-21 00:05:17 -08:00
|
|
|
usb_flush_tx_fifo(uhost->usb_reg, 0x10);
|
|
|
|
usb_flush_rx_fifo(uhost->usb_reg);
|
2022-04-11 04:50:25 -07:00
|
|
|
|
|
|
|
/* user attached callback */
|
2021-12-13 21:39:13 -08:00
|
|
|
uhost->user_handler->user_attached();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief usb host enumeration
|
|
|
|
* @param uhost: to the structure of usbh_core_type
|
|
|
|
* @retval none
|
|
|
|
*/
|
|
|
|
static void usbh_enumeration(usbh_core_type *uhost)
|
|
|
|
{
|
|
|
|
/* enumeration process */
|
|
|
|
if(usbh_enum_handler(uhost) == USB_OK)
|
|
|
|
{
|
|
|
|
/* user enumeration done callback */
|
|
|
|
uhost->user_handler->user_enumeration_done();
|
|
|
|
uhost->global_state = USBH_USER_HANDLER;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief usb host class request
|
|
|
|
* @param uhost: to the structure of usbh_core_type
|
|
|
|
* @retval none
|
|
|
|
*/
|
|
|
|
static void usbh_class_request(usbh_core_type *uhost)
|
|
|
|
{
|
|
|
|
usb_sts_type status;
|
2022-04-11 04:50:25 -07:00
|
|
|
|
2021-12-13 21:39:13 -08:00
|
|
|
/* class request callback */
|
|
|
|
status = uhost->class_handler->request_handler((void *)uhost);
|
|
|
|
if(status == USB_OK)
|
|
|
|
{
|
|
|
|
uhost->global_state = USBH_CLASS;
|
|
|
|
}
|
2022-01-21 00:05:17 -08:00
|
|
|
else if(status == USB_ERROR || status == USB_FAIL)
|
2021-12-13 21:39:13 -08:00
|
|
|
{
|
|
|
|
uhost->global_state = USBH_ERROR_STATE;
|
|
|
|
}
|
|
|
|
else if(status == USB_NOT_SUPPORT)
|
|
|
|
{
|
|
|
|
uhost->global_state = USBH_ERROR_STATE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief usb host class handler
|
|
|
|
* @param uhost: to the structure of usbh_core_type
|
|
|
|
* @retval none
|
|
|
|
*/
|
|
|
|
static void usbh_class(usbh_core_type *uhost)
|
|
|
|
{
|
|
|
|
/* process handler */
|
|
|
|
if(uhost->class_handler->process_handler((void *)uhost) == USB_OK)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief usb host suspend
|
|
|
|
* @param uhost: to the structure of usbh_core_type
|
|
|
|
* @retval none
|
|
|
|
*/
|
|
|
|
static void usbh_suspend(usbh_core_type *uhost)
|
|
|
|
{
|
|
|
|
/* set device feature */
|
|
|
|
if(uhost->ctrl.state == CONTROL_IDLE)
|
|
|
|
{
|
|
|
|
usbh_set_feature(uhost, 0x01, 0);
|
|
|
|
}
|
|
|
|
if(usbh_ctrl_result_check(uhost, CONTROL_IDLE, ENUM_IDLE) == USB_OK)
|
|
|
|
{
|
|
|
|
/* enter suspend mode */
|
|
|
|
usb_delay_ms(3);
|
|
|
|
usbh_enter_suspend(uhost);
|
|
|
|
uhost->global_state = USBH_SUSPENDED;
|
2022-04-11 04:50:25 -07:00
|
|
|
|
2021-12-13 21:39:13 -08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief usb host wakeup
|
|
|
|
* @param uhost: to the structure of usbh_core_type
|
|
|
|
* @retval none
|
|
|
|
*/
|
|
|
|
static void usbh_wakeup(usbh_core_type *uhost)
|
|
|
|
{
|
|
|
|
/* clear device feature */
|
|
|
|
if(uhost->ctrl.state == CONTROL_IDLE)
|
|
|
|
{
|
|
|
|
/* usb host resume */
|
|
|
|
usbh_resume(uhost);
|
|
|
|
usbh_clear_dev_feature(uhost, 0x01, 0);
|
|
|
|
}
|
|
|
|
if(usbh_ctrl_result_check(uhost, CONTROL_IDLE, ENUM_IDLE) == USB_OK)
|
|
|
|
{
|
|
|
|
uhost->global_state = USBH_CLASS_REQUEST;
|
|
|
|
USBH_DEBUG("Remote Wakeup");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief usb host disconnect
|
|
|
|
* @param uhost: to the structure of usbh_core_type
|
|
|
|
* @retval none
|
|
|
|
*/
|
|
|
|
static void usbh_disconnect(usbh_core_type *uhost)
|
|
|
|
{
|
|
|
|
uint8_t i_index = 0;
|
2022-04-11 04:50:25 -07:00
|
|
|
|
2021-12-13 21:39:13 -08:00
|
|
|
/* set host to default state */
|
|
|
|
usbh_cfg_default_init(uhost);
|
2022-04-11 04:50:25 -07:00
|
|
|
|
2021-12-13 21:39:13 -08:00
|
|
|
/* free host channel */
|
|
|
|
for(i_index = 0; i_index < USB_HOST_CHANNEL_NUM; i_index ++)
|
|
|
|
{
|
|
|
|
usbh_free_channel(uhost, i_index);
|
|
|
|
}
|
2022-04-11 04:50:25 -07:00
|
|
|
|
2021-12-13 21:39:13 -08:00
|
|
|
/* call class reset handler */
|
|
|
|
if(uhost->class_handler->reset_handler != NULL)
|
|
|
|
{
|
|
|
|
uhost->class_handler->reset_handler(uhost);
|
|
|
|
}
|
2022-04-11 04:50:25 -07:00
|
|
|
|
2021-12-13 21:39:13 -08:00
|
|
|
/* set global state to idle */
|
|
|
|
uhost->global_state = USBH_IDLE;
|
2022-04-11 04:50:25 -07:00
|
|
|
|
2021-12-13 21:39:13 -08:00
|
|
|
/*call user disconnect function */
|
|
|
|
uhost->user_handler->user_disconnect();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief usb host enum loop handler
|
|
|
|
* @param uhost: to the structure of usbh_core_type
|
|
|
|
* @retval none
|
|
|
|
*/
|
|
|
|
usb_sts_type usbh_loop_handler(usbh_core_type *uhost)
|
|
|
|
{
|
|
|
|
usb_sts_type status = USB_FAIL;
|
2022-04-11 04:50:25 -07:00
|
|
|
|
|
|
|
if(uhost->conn_sts == 0 &&
|
|
|
|
uhost->global_state != USBH_IDLE &&
|
2022-01-21 00:05:17 -08:00
|
|
|
uhost->global_state != USBH_DISCONNECT)
|
|
|
|
{
|
|
|
|
uhost->global_state = USBH_IDLE;
|
|
|
|
}
|
2021-12-13 21:39:13 -08:00
|
|
|
switch(uhost->global_state)
|
|
|
|
{
|
|
|
|
case USBH_IDLE:
|
|
|
|
if(uhost->conn_sts == 1)
|
|
|
|
{
|
|
|
|
uhost->global_state = USBH_PORT_EN;
|
2022-04-11 04:50:25 -07:00
|
|
|
|
2022-01-21 00:05:17 -08:00
|
|
|
/* wait stable */
|
|
|
|
usb_delay_ms(200);
|
2022-04-11 04:50:25 -07:00
|
|
|
|
2021-12-13 21:39:13 -08:00
|
|
|
/* port reset */
|
|
|
|
usbh_reset_port(uhost);
|
2022-04-11 04:50:25 -07:00
|
|
|
|
2021-12-13 21:39:13 -08:00
|
|
|
/* user reset */
|
|
|
|
uhost->user_handler->user_reset();
|
|
|
|
}
|
|
|
|
break;
|
2022-04-11 04:50:25 -07:00
|
|
|
|
2021-12-13 21:39:13 -08:00
|
|
|
case USBH_PORT_EN:
|
|
|
|
if(uhost->port_enable)
|
|
|
|
{
|
|
|
|
uhost->global_state = USBH_ATTACHED;
|
2022-03-03 03:49:19 -08:00
|
|
|
usb_delay_ms(50);
|
2021-12-13 21:39:13 -08:00
|
|
|
}
|
|
|
|
break;
|
2022-04-11 04:50:25 -07:00
|
|
|
|
2021-12-13 21:39:13 -08:00
|
|
|
case USBH_ATTACHED:
|
|
|
|
usbh_attached(uhost);
|
|
|
|
break;
|
2022-04-11 04:50:25 -07:00
|
|
|
|
2021-12-13 21:39:13 -08:00
|
|
|
case USBH_ENUMERATION:
|
|
|
|
usbh_enumeration(uhost);
|
|
|
|
break;
|
2022-04-11 04:50:25 -07:00
|
|
|
|
2021-12-13 21:39:13 -08:00
|
|
|
case USBH_USER_HANDLER:
|
|
|
|
uhost->global_state = USBH_CLASS_REQUEST;
|
|
|
|
if( uhost->class_handler->init_handler(uhost) == USB_NOT_SUPPORT)
|
|
|
|
{
|
|
|
|
uhost->global_state = USBH_UNSUPPORT;
|
|
|
|
}
|
|
|
|
break;
|
2022-04-11 04:50:25 -07:00
|
|
|
|
2021-12-13 21:39:13 -08:00
|
|
|
case USBH_CLASS_REQUEST:
|
|
|
|
usbh_class_request(uhost);
|
|
|
|
break;
|
2022-04-11 04:50:25 -07:00
|
|
|
|
2021-12-13 21:39:13 -08:00
|
|
|
case USBH_CLASS:
|
|
|
|
usbh_class(uhost);
|
|
|
|
break;
|
2022-04-11 04:50:25 -07:00
|
|
|
|
2021-12-13 21:39:13 -08:00
|
|
|
case USBH_SUSPEND:
|
|
|
|
usbh_suspend(uhost);
|
|
|
|
break;
|
2022-04-11 04:50:25 -07:00
|
|
|
|
2021-12-13 21:39:13 -08:00
|
|
|
case USBH_SUSPENDED:
|
|
|
|
break;
|
2022-04-11 04:50:25 -07:00
|
|
|
|
2021-12-13 21:39:13 -08:00
|
|
|
case USBH_WAKEUP:
|
|
|
|
usbh_wakeup(uhost);
|
|
|
|
break;
|
2022-04-11 04:50:25 -07:00
|
|
|
|
2021-12-13 21:39:13 -08:00
|
|
|
case USBH_DISCONNECT:
|
|
|
|
usbh_disconnect(uhost);
|
|
|
|
break;
|
2022-04-11 04:50:25 -07:00
|
|
|
|
2021-12-13 21:39:13 -08:00
|
|
|
case USBH_ERROR_STATE:
|
|
|
|
usbh_cfg_default_init(uhost);
|
|
|
|
uhost->class_handler->reset_handler(uhost);
|
|
|
|
uhost->user_handler->user_reset();
|
|
|
|
break;
|
|
|
|
case USBH_UNSUPPORT:
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
2022-04-11 04:50:25 -07:00
|
|
|
|
2021-12-13 21:39:13 -08:00
|
|
|
return status;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @}
|
2022-04-11 04:50:25 -07:00
|
|
|
*/
|
2021-12-13 21:39:13 -08:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @}
|
|
|
|
*/
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @}
|
|
|
|
*/
|