add usbh_deinitialize api
This commit is contained in:
@@ -647,6 +647,8 @@ static void usbh_hub_thread(void *argument)
|
||||
|
||||
static void usbh_roothub_register(void)
|
||||
{
|
||||
usb_slist_init(&hub_class_head);
|
||||
|
||||
memset(&roothub, 0, sizeof(struct usbh_hub));
|
||||
|
||||
roothub.connected = true;
|
||||
@@ -680,6 +682,36 @@ int usbh_hub_initialize(void)
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int usbh_hub_deinitialize(void)
|
||||
{
|
||||
usb_slist_t *i;
|
||||
struct usbh_hubport *hport;
|
||||
size_t flags;
|
||||
|
||||
flags = usb_osal_enter_critical_section();
|
||||
|
||||
usb_slist_for_each(i, &hub_class_head)
|
||||
{
|
||||
struct usbh_hub *hub = usb_slist_entry(i, struct usbh_hub, list);
|
||||
|
||||
for (uint8_t port = 0; port < hub->hub_desc.bNbrPorts; port++) {
|
||||
hport = &hub->child[port];
|
||||
|
||||
usbh_hubport_release(hport);
|
||||
}
|
||||
}
|
||||
|
||||
usb_hc_deinit();
|
||||
|
||||
usb_osal_leave_critical_section(flags);
|
||||
|
||||
usb_osal_mq_delete(hub_mq);
|
||||
usb_osal_thread_delete(hub_thread);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if CONFIG_USBHOST_MAX_EXTHUBS > 0
|
||||
const struct usbh_class_driver hub_class_driver = {
|
||||
.driver_name = "hub",
|
||||
|
||||
@@ -23,7 +23,10 @@ int usbh_hub_set_feature(struct usbh_hub *hub, uint8_t port, uint8_t feature);
|
||||
int usbh_hub_clear_feature(struct usbh_hub *hub, uint8_t port, uint8_t feature);
|
||||
|
||||
void usbh_roothub_thread_wakeup(uint8_t port);
|
||||
|
||||
int usbh_hub_initialize(void);
|
||||
int usbh_hub_deinitialize(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -61,6 +61,13 @@ struct usbh_urb {
|
||||
*/
|
||||
int usb_hc_init(void);
|
||||
|
||||
/**
|
||||
* @brief usb host controller hardware deinit.
|
||||
*
|
||||
* @return On success will return 0, and others indicate fail.
|
||||
*/
|
||||
int usb_hc_deinit(void);
|
||||
|
||||
/**
|
||||
* @brief Get frame number.
|
||||
*
|
||||
|
||||
@@ -35,6 +35,7 @@ int usb_osal_mutex_take(usb_osal_mutex_t mutex);
|
||||
int usb_osal_mutex_give(usb_osal_mutex_t mutex);
|
||||
|
||||
usb_osal_mq_t usb_osal_mq_create(uint32_t max_msgs);
|
||||
void usb_osal_mq_delete(usb_osal_mq_t mq);
|
||||
int usb_osal_mq_send(usb_osal_mq_t mq, uintptr_t addr);
|
||||
int usb_osal_mq_recv(usb_osal_mq_t mq, uintptr_t *addr, uint32_t timeout);
|
||||
|
||||
|
||||
@@ -666,6 +666,11 @@ int usbh_initialize(void)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int usbh_deinitialize(void)
|
||||
{
|
||||
return usbh_hub_deinitialize();
|
||||
}
|
||||
|
||||
int usbh_control_transfer(struct usbh_hubport *hport, struct usb_setup_packet *setup, uint8_t *buffer)
|
||||
{
|
||||
struct usbh_urb *urb;
|
||||
|
||||
@@ -226,6 +226,7 @@ int usbh_get_string_desc(struct usbh_hubport *hport, uint8_t index, uint8_t *out
|
||||
int usbh_set_interface(struct usbh_hubport *hport, uint8_t intf, uint8_t altsetting);
|
||||
|
||||
int usbh_initialize(void);
|
||||
int usbh_deinitialize(void);
|
||||
void *usbh_find_class_instance(const char *devname);
|
||||
|
||||
int lsusb(int argc, char **argv);
|
||||
|
||||
@@ -89,6 +89,11 @@ usb_osal_mq_t usb_osal_mq_create(uint32_t max_msgs)
|
||||
return (usb_osal_mq_t)xQueueCreate(max_msgs, sizeof(uintptr_t));
|
||||
}
|
||||
|
||||
void usb_osal_mq_delete(usb_osal_mq_t mq)
|
||||
{
|
||||
vQueueDelete((QueueHandle_t)mq);
|
||||
}
|
||||
|
||||
int usb_osal_mq_send(usb_osal_mq_t mq, uintptr_t addr)
|
||||
{
|
||||
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
|
||||
|
||||
@@ -91,6 +91,11 @@ usb_osal_mq_t usb_osal_mq_create(uint32_t max_msgs)
|
||||
return (usb_osal_mq_t)rt_mq_create("usbh_mq", sizeof(uintptr_t), max_msgs, RT_IPC_FLAG_FIFO);
|
||||
}
|
||||
|
||||
void usb_osal_mq_delete(usb_osal_mq_t mq)
|
||||
{
|
||||
rt_mq_delete((rt_mq_t)mq);
|
||||
}
|
||||
|
||||
int usb_osal_mq_send(usb_osal_mq_t mq, uintptr_t addr)
|
||||
{
|
||||
return rt_mq_send((rt_mq_t)mq, &addr, sizeof(uintptr_t));
|
||||
|
||||
@@ -89,6 +89,11 @@ usb_osal_mq_t usb_osal_mq_create(uint32_t max_msgs)
|
||||
return (usb_osal_mq_t)queue;
|
||||
}
|
||||
|
||||
void usb_osal_mq_delete(usb_osal_mq_t mq)
|
||||
{
|
||||
aos_queue_free((aos_queue_t)mq);
|
||||
}
|
||||
|
||||
int usb_osal_mq_send(usb_osal_mq_t mq, uintptr_t addr)
|
||||
{
|
||||
return aos_queue_send((aos_queue_t *)&mq, &addr, sizeof(uintptr_t));
|
||||
|
||||
@@ -525,6 +525,57 @@ int usb_hc_init(void)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int usb_hc_deinit(void)
|
||||
{
|
||||
volatile uint32_t count = 0U;
|
||||
uint32_t value;
|
||||
|
||||
USB_OTG_GLB->GAHBCFG &= ~USB_OTG_GAHBCFG_GINT;
|
||||
|
||||
dwc2_flush_txfifo(0x10U);
|
||||
dwc2_flush_rxfifo();
|
||||
|
||||
/* Flush out any leftover queued requests. */
|
||||
for (uint32_t i = 0U; i <= 15U; i++) {
|
||||
value = USB_OTG_HC(i)->HCCHAR;
|
||||
value |= USB_OTG_HCCHAR_CHDIS;
|
||||
value &= ~USB_OTG_HCCHAR_CHENA;
|
||||
value &= ~USB_OTG_HCCHAR_EPDIR;
|
||||
USB_OTG_HC(i)->HCCHAR = value;
|
||||
}
|
||||
|
||||
/* Halt all channels to put them into a known state. */
|
||||
for (uint32_t i = 0U; i <= 15U; i++) {
|
||||
value = USB_OTG_HC(i)->HCCHAR;
|
||||
value |= USB_OTG_HCCHAR_CHDIS;
|
||||
value |= USB_OTG_HCCHAR_CHENA;
|
||||
value &= ~USB_OTG_HCCHAR_EPDIR;
|
||||
USB_OTG_HC(i)->HCCHAR = value;
|
||||
|
||||
do {
|
||||
if (++count > 1000U) {
|
||||
return -USB_ERR_TIMEOUT;
|
||||
}
|
||||
} while ((USB_OTG_HC(i)->HCCHAR & USB_OTG_HCCHAR_CHENA) == USB_OTG_HCCHAR_CHENA);
|
||||
}
|
||||
|
||||
/* Disable all interrupts. */
|
||||
USB_OTG_GLB->GINTMSK = 0U;
|
||||
|
||||
/* Clear any pending Host interrupts */
|
||||
USB_OTG_HOST->HAINT = 0xFFFFFFFFU;
|
||||
USB_OTG_GLB->GINTSTS = 0xFFFFFFFFU;
|
||||
|
||||
dwc2_drivebus(0);
|
||||
usb_osal_msleep(200);
|
||||
|
||||
for (uint8_t chidx = 0; chidx < CONFIG_USBHOST_PIPE_NUM; chidx++) {
|
||||
usb_osal_sem_delete(g_dwc2_hcd.chan_pool[chidx].waitsem);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint16_t usbh_get_frame_number(void)
|
||||
{
|
||||
return (USB_OTG_HOST->HFNUM & USB_OTG_HFNUM_FRNUM);
|
||||
|
||||
@@ -906,6 +906,51 @@ int usb_hc_init(void)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int usb_hc_deinit(void)
|
||||
{
|
||||
struct ehci_qh_hw *qh;
|
||||
|
||||
volatile uint32_t timeout = 0;
|
||||
uint32_t regval;
|
||||
|
||||
EHCI_HCOR->usbintr = 0;
|
||||
|
||||
regval = EHCI_HCOR->usbcmd;
|
||||
regval &= ~EHCI_USBCMD_ASEN;
|
||||
regval &= ~EHCI_USBCMD_PSEN;
|
||||
regval &= ~EHCI_USBCMD_RUN;
|
||||
EHCI_HCOR->usbcmd = regval;
|
||||
|
||||
while ((EHCI_HCOR->usbsts & (EHCI_USBSTS_PSS | EHCI_USBSTS_ASS))) {
|
||||
usb_osal_msleep(1);
|
||||
timeout++;
|
||||
if (timeout > 100) {
|
||||
return -USB_ERR_TIMEOUT;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef CONFIG_USB_EHCI_PORT_POWER
|
||||
for (uint8_t port = 0; port < CONFIG_USBHOST_MAX_RHPORTS; port++) {
|
||||
regval = EHCI_HCOR->portsc[port];
|
||||
regval &= ~EHCI_PORTSC_PP;
|
||||
EHCI_HCOR->portsc[port] = regval;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_USB_EHCI_CONFIGFLAG
|
||||
EHCI_HCOR->configflag = 0;
|
||||
#endif
|
||||
|
||||
EHCI_HCOR->usbsts = EHCI_HCOR->usbsts;
|
||||
|
||||
for (uint8_t index = 0; index < CONFIG_USB_EHCI_QH_NUM; index++) {
|
||||
qh = &ehci_qh_pool[index];
|
||||
usb_osal_sem_delete(qh->waitsem);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint16_t usbh_get_frame_number(void)
|
||||
{
|
||||
return (((EHCI_HCOR->frindex & EHCI_FRINDEX_MASK) >> 3) & 0x3ff);
|
||||
@@ -1199,6 +1244,9 @@ int usbh_kill_urb(struct usbh_urb *urb)
|
||||
} else {
|
||||
#ifdef CONFIG_USB_EHCI_ISO
|
||||
ehci_remove_itd_urb(urb);
|
||||
EHCI_HCOR->usbcmd |= (EHCI_USBCMD_PSEN | EHCI_USBCMD_ASEN);
|
||||
usb_osal_leave_critical_section(flags);
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -470,6 +470,22 @@ int usb_hc_init(void)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int usb_hc_deinit(void)
|
||||
{
|
||||
HWREGB(USB_BASE + MUSB_IE_OFFSET) = 0;
|
||||
HWREGH(USB_BASE + MUSB_TXIE_OFFSET) = 0;
|
||||
HWREGH(USB_BASE + MUSB_RXIE_OFFSET) = 0;
|
||||
|
||||
HWREGB(USB_BASE + MUSB_POWER_OFFSET) &= ~USB_POWER_HSENAB;
|
||||
HWREGB(USB_BASE + MUSB_DEVCTL_OFFSET) &= ~USB_DEVCTL_SESSION;
|
||||
|
||||
for (uint8_t i = 0; i < CONFIG_USBHOST_PIPE_NUM; i++) {
|
||||
usb_osal_sem_delete(g_musb_hcd.pipe_pool[i].waitsem);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int usbh_roothub_control(struct usb_setup_packet *setup, uint8_t *buf)
|
||||
{
|
||||
uint8_t nports;
|
||||
|
||||
Reference in New Issue
Block a user