summaryrefslogtreecommitdiff
path: root/src/device
diff options
context:
space:
mode:
authorHa Thach <[email protected]>2024-04-08 23:48:52 +0700
committerGitHub <[email protected]>2024-04-08 23:48:52 +0700
commit42decf28f1bf7512a4c3e7402c9daf83ee241191 (patch)
tree1a3ed93956a7d51d592d6ba4de6215725ec43c4c /src/device
parentd33fe38a6257bcdd60f51a57c9fd19ce2ad1f202 (diff)
parentbe25a3fc20339c27803e68cb1363f89ffe7a7c67 (diff)
Merge pull request #1835 from MasterQ32/otg_bringup
Implements deinit functions for host/device mode switch
Diffstat (limited to 'src/device')
-rw-r--r--src/device/dcd.h3
-rw-r--r--src/device/usbd.c196
-rw-r--r--src/device/usbd.h5
-rw-r--r--src/device/usbd_pvt.h1
4 files changed, 132 insertions, 73 deletions
diff --git a/src/device/dcd.h b/src/device/dcd.h
index 69c26bcf4..d4f105aa3 100644
--- a/src/device/dcd.h
+++ b/src/device/dcd.h
@@ -122,6 +122,9 @@ void dcd_dcache_clean_invalidate(void const* addr, uint32_t data_size) TU_ATTR_W
// Initialize controller to device mode
void dcd_init(uint8_t rhport);
+// Deinitialize controller, unset device mode.
+bool dcd_deinit(uint8_t rhport);
+
// Interrupt Handler
void dcd_int_handler(uint8_t rhport);
diff --git a/src/device/usbd.c b/src/device/usbd.c
index 8f98862c6..96982c30b 100644
--- a/src/device/usbd.c
+++ b/src/device/usbd.c
@@ -43,8 +43,13 @@
#endif
//--------------------------------------------------------------------+
-// Callback weak stubs (called if application does not provide)
+// Weak stubs: invoked if no strong implementation is available
//--------------------------------------------------------------------+
+TU_ATTR_WEAK bool dcd_deinit(uint8_t rhport) {
+ (void) rhport;
+ return false;
+}
+
TU_ATTR_WEAK void tud_event_hook_cb(uint8_t rhport, uint32_t eventid, bool in_isr) {
(void)rhport;
(void)eventid;
@@ -96,6 +101,7 @@ tu_static usbd_class_driver_t const _usbd_driver[] = {
{
DRIVER_NAME("CDC")
.init = cdcd_init,
+ .deinit = cdcd_deinit,
.reset = cdcd_reset,
.open = cdcd_open,
.control_xfer_cb = cdcd_control_xfer_cb,
@@ -108,6 +114,7 @@ tu_static usbd_class_driver_t const _usbd_driver[] = {
{
DRIVER_NAME("MSC")
.init = mscd_init,
+ .deinit = NULL,
.reset = mscd_reset,
.open = mscd_open,
.control_xfer_cb = mscd_control_xfer_cb,
@@ -118,121 +125,131 @@ tu_static usbd_class_driver_t const _usbd_driver[] = {
#if CFG_TUD_HID
{
- DRIVER_NAME("HID")
- .init = hidd_init,
- .reset = hidd_reset,
- .open = hidd_open,
- .control_xfer_cb = hidd_control_xfer_cb,
- .xfer_cb = hidd_xfer_cb,
- .sof = NULL
+ DRIVER_NAME("HID")
+ .init = hidd_init,
+ .deinit = hidd_deinit,
+ .reset = hidd_reset,
+ .open = hidd_open,
+ .control_xfer_cb = hidd_control_xfer_cb,
+ .xfer_cb = hidd_xfer_cb,
+ .sof = NULL
},
#endif
#if CFG_TUD_AUDIO
{
- DRIVER_NAME("AUDIO")
- .init = audiod_init,
- .reset = audiod_reset,
- .open = audiod_open,
- .control_xfer_cb = audiod_control_xfer_cb,
- .xfer_cb = audiod_xfer_cb,
- .sof = audiod_sof_isr
+ DRIVER_NAME("AUDIO")
+ .init = audiod_init,
+ .deinit = audiod_deinit,
+ .reset = audiod_reset,
+ .open = audiod_open,
+ .control_xfer_cb = audiod_control_xfer_cb,
+ .xfer_cb = audiod_xfer_cb,
+ .sof = audiod_sof_isr
},
#endif
#if CFG_TUD_VIDEO
{
- DRIVER_NAME("VIDEO")
- .init = videod_init,
- .reset = videod_reset,
- .open = videod_open,
- .control_xfer_cb = videod_control_xfer_cb,
- .xfer_cb = videod_xfer_cb,
- .sof = NULL
+ DRIVER_NAME("VIDEO")
+ .init = videod_init,
+ .deinit = videod_deinit,
+ .reset = videod_reset,
+ .open = videod_open,
+ .control_xfer_cb = videod_control_xfer_cb,
+ .xfer_cb = videod_xfer_cb,
+ .sof = NULL
},
#endif
#if CFG_TUD_MIDI
{
- DRIVER_NAME("MIDI")
- .init = midid_init,
- .open = midid_open,
- .reset = midid_reset,
- .control_xfer_cb = midid_control_xfer_cb,
- .xfer_cb = midid_xfer_cb,
- .sof = NULL
+ DRIVER_NAME("MIDI")
+ .init = midid_init,
+ .deinit = midid_deinit,
+ .open = midid_open,
+ .reset = midid_reset,
+ .control_xfer_cb = midid_control_xfer_cb,
+ .xfer_cb = midid_xfer_cb,
+ .sof = NULL
},
#endif
#if CFG_TUD_VENDOR
{
- DRIVER_NAME("VENDOR")
- .init = vendord_init,
- .reset = vendord_reset,
- .open = vendord_open,
- .control_xfer_cb = tud_vendor_control_xfer_cb,
- .xfer_cb = vendord_xfer_cb,
- .sof = NULL
+ DRIVER_NAME("VENDOR")
+ .init = vendord_init,
+ .deinit = vendord_deinit,
+ .reset = vendord_reset,
+ .open = vendord_open,
+ .control_xfer_cb = tud_vendor_control_xfer_cb,
+ .xfer_cb = vendord_xfer_cb,
+ .sof = NULL
},
#endif
#if CFG_TUD_USBTMC
{
- DRIVER_NAME("TMC")
- .init = usbtmcd_init_cb,
- .reset = usbtmcd_reset_cb,
- .open = usbtmcd_open_cb,
- .control_xfer_cb = usbtmcd_control_xfer_cb,
- .xfer_cb = usbtmcd_xfer_cb,
- .sof = NULL
+ DRIVER_NAME("TMC")
+ .init = usbtmcd_init_cb,
+ .deinit = usbtmcd_deinit,
+ .reset = usbtmcd_reset_cb,
+ .open = usbtmcd_open_cb,
+ .control_xfer_cb = usbtmcd_control_xfer_cb,
+ .xfer_cb = usbtmcd_xfer_cb,
+ .sof = NULL
},
#endif
#if CFG_TUD_DFU_RUNTIME
{
- DRIVER_NAME("DFU-RUNTIME")
- .init = dfu_rtd_init,
- .reset = dfu_rtd_reset,
- .open = dfu_rtd_open,
- .control_xfer_cb = dfu_rtd_control_xfer_cb,
- .xfer_cb = NULL,
- .sof = NULL
+ DRIVER_NAME("DFU-RUNTIME")
+ .init = dfu_rtd_init,
+ .deinit = dfu_rtd_deinit,
+ .reset = dfu_rtd_reset,
+ .open = dfu_rtd_open,
+ .control_xfer_cb = dfu_rtd_control_xfer_cb,
+ .xfer_cb = NULL,
+ .sof = NULL
},
#endif
#if CFG_TUD_DFU
{
- DRIVER_NAME("DFU")
- .init = dfu_moded_init,
- .reset = dfu_moded_reset,
- .open = dfu_moded_open,
- .control_xfer_cb = dfu_moded_control_xfer_cb,
- .xfer_cb = NULL,
- .sof = NULL
+ DRIVER_NAME("DFU")
+ .init = dfu_moded_init,
+ .deinit = dfu_moded_deinit,
+ .reset = dfu_moded_reset,
+ .open = dfu_moded_open,
+ .control_xfer_cb = dfu_moded_control_xfer_cb,
+ .xfer_cb = NULL,
+ .sof = NULL
},
#endif
#if CFG_TUD_ECM_RNDIS || CFG_TUD_NCM
{
- DRIVER_NAME("NET")
- .init = netd_init,
- .reset = netd_reset,
- .open = netd_open,
- .control_xfer_cb = netd_control_xfer_cb,
- .xfer_cb = netd_xfer_cb,
- .sof = NULL,
+ DRIVER_NAME("NET")
+ .init = netd_init,
+ .deinit = netd_deinit,
+ .reset = netd_reset,
+ .open = netd_open,
+ .control_xfer_cb = netd_control_xfer_cb,
+ .xfer_cb = netd_xfer_cb,
+ .sof = NULL,
},
#endif
#if CFG_TUD_BTH
{
- DRIVER_NAME("BTH")
- .init = btd_init,
- .reset = btd_reset,
- .open = btd_open,
- .control_xfer_cb = btd_control_xfer_cb,
- .xfer_cb = btd_xfer_cb,
- .sof = NULL
+ DRIVER_NAME("BTH")
+ .init = btd_init,
+ .deinit = btd_deinit,
+ .reset = btd_reset,
+ .open = btd_open,
+ .control_xfer_cb = btd_control_xfer_cb,
+ .xfer_cb = btd_xfer_cb,
+ .sof = NULL
},
#endif
};
@@ -402,7 +419,7 @@ bool tud_init(uint8_t rhport) {
// Init class drivers
for (uint8_t i = 0; i < TOTAL_DRIVER_COUNT; i++) {
usbd_class_driver_t const* driver = get_driver(i);
- TU_ASSERT(driver);
+ TU_ASSERT(driver && driver->init);
TU_LOG_USBD("%s init\r\n", driver->name);
driver->init();
}
@@ -416,6 +433,41 @@ bool tud_init(uint8_t rhport) {
return true;
}
+bool tud_deinit(uint8_t rhport) {
+ // skip if not initialized
+ if (!tud_inited()) return true;
+
+ TU_LOG_USBD("USBD deinit on controller %u\r\n", rhport);
+
+ // Deinit device controller driver
+ dcd_int_disable(rhport);
+ dcd_disconnect(rhport);
+ dcd_deinit(rhport);
+
+ // Deinit class drivers
+ for (uint8_t i = 0; i < TOTAL_DRIVER_COUNT; i++) {
+ usbd_class_driver_t const* driver = get_driver(i);
+ if(driver && driver->deinit) {
+ TU_LOG_USBD("%s deinit\r\n", driver->name);
+ driver->deinit();
+ }
+ }
+
+ // Deinit device queue & task
+ osal_queue_delete(_usbd_q);
+ _usbd_q = NULL;
+
+#if OSAL_MUTEX_REQUIRED
+ // TODO make sure there is no task waiting on this mutex
+ osal_mutex_delete(_usbd_mutex);
+ _usbd_mutex = NULL;
+#endif
+
+ _usbd_rhport = RHPORT_INVALID;
+
+ return true;
+}
+
static void configuration_reset(uint8_t rhport) {
for (uint8_t i = 0; i < TOTAL_DRIVER_COUNT; i++) {
usbd_class_driver_t const* driver = get_driver(i);
diff --git a/src/device/usbd.h b/src/device/usbd.h
index 2e3987b99..0197628e2 100644
--- a/src/device/usbd.h
+++ b/src/device/usbd.h
@@ -37,9 +37,12 @@ extern "C" {
// Application API
//--------------------------------------------------------------------+
-// Init device stack
+// Init device stack on roothub port
bool tud_init (uint8_t rhport);
+// Deinit device stack on roothub port
+bool tud_deinit(uint8_t rhport);
+
// Check if device stack is already initialized
bool tud_inited(void);
diff --git a/src/device/usbd_pvt.h b/src/device/usbd_pvt.h
index 9039bc9d6..47752f32c 100644
--- a/src/device/usbd_pvt.h
+++ b/src/device/usbd_pvt.h
@@ -45,6 +45,7 @@ typedef struct {
#endif
void (* init ) (void);
+ bool (* deinit ) (void);
void (* reset ) (uint8_t rhport);
uint16_t (* open ) (uint8_t rhport, tusb_desc_interface_t const * desc_intf, uint16_t max_len);
bool (* control_xfer_cb ) (uint8_t rhport, uint8_t stage, tusb_control_request_t const * request);