Merge pull request #1835 from MasterQ32/otg_bringup

Implements deinit functions for host/device mode switch
This commit is contained in:
Ha Thach 2024-04-08 23:48:52 +07:00 committed by GitHub
commit 42decf28f1
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
33 changed files with 312 additions and 102 deletions

View File

@ -1389,6 +1389,10 @@ void audiod_init(void)
}
}
bool audiod_deinit(void) {
return false; // TODO not implemented yet
}
void audiod_reset(uint8_t rhport)
{
(void) rhport;

View File

@ -685,6 +685,7 @@ static inline bool tud_audio_fb_set(uint32_t feedback)
// Internal Class Driver API
//--------------------------------------------------------------------+
void audiod_init (void);
bool audiod_deinit (void);
void audiod_reset (uint8_t rhport);
uint16_t audiod_open (uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint16_t max_len);
bool audiod_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t const * request);

View File

@ -91,11 +91,14 @@ bool tud_bt_acl_data_send(void *event, uint16_t event_len)
//--------------------------------------------------------------------+
// USBD Driver API
//--------------------------------------------------------------------+
void btd_init(void)
{
void btd_init(void) {
tu_memclr(&_btd_itf, sizeof(_btd_itf));
}
bool btd_deinit(void) {
return true;
}
void btd_reset(uint8_t rhport)
{
(void)rhport;

View File

@ -104,6 +104,7 @@ bool tud_bt_acl_data_send(void *acl_data, uint16_t data_len);
// Internal Class Driver API
//--------------------------------------------------------------------+
void btd_init (void);
bool btd_deinit (void);
void btd_reset (uint8_t rhport);
uint16_t btd_open (uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint16_t max_len);
bool btd_control_xfer_cb (uint8_t rhport, uint8_t stage, tusb_control_request_t const *request);

View File

@ -253,11 +253,39 @@ void cdcd_init(void)
// In this way, the most current data is prioritized.
tu_fifo_config(&p_cdc->tx_ff, p_cdc->tx_ff_buf, TU_ARRAY_SIZE(p_cdc->tx_ff_buf), 1, true);
tu_fifo_config_mutex(&p_cdc->rx_ff, NULL, osal_mutex_create(&p_cdc->rx_ff_mutex));
tu_fifo_config_mutex(&p_cdc->tx_ff, osal_mutex_create(&p_cdc->tx_ff_mutex), NULL);
#if OSAL_MUTEX_REQUIRED
osal_mutex_t mutex_rd = osal_mutex_create(&p_cdc->rx_ff_mutex);
osal_mutex_t mutex_wr = osal_mutex_create(&p_cdc->tx_ff_mutex);
TU_ASSERT(mutex_rd != NULL && mutex_wr != NULL, );
tu_fifo_config_mutex(&p_cdc->rx_ff, NULL, mutex_rd);
tu_fifo_config_mutex(&p_cdc->tx_ff, mutex_wr, NULL);
#endif
}
}
bool cdcd_deinit(void) {
#if OSAL_MUTEX_REQUIRED
for(uint8_t i=0; i<CFG_TUD_CDC; i++) {
cdcd_interface_t* p_cdc = &_cdcd_itf[i];
osal_mutex_t mutex_rd = p_cdc->rx_ff.mutex_rd;
osal_mutex_t mutex_wr = p_cdc->tx_ff.mutex_wr;
if (mutex_rd) {
osal_mutex_delete(mutex_rd);
tu_fifo_config_mutex(&p_cdc->rx_ff, NULL, NULL);
}
if (mutex_wr) {
osal_mutex_delete(mutex_wr);
tu_fifo_config_mutex(&p_cdc->tx_ff, NULL, NULL);
}
}
#endif
return true;
}
void cdcd_reset(uint8_t rhport)
{
(void) rhport;

View File

@ -247,6 +247,7 @@ static inline bool tud_cdc_write_clear(void)
// INTERNAL USBD-CLASS DRIVER API
//--------------------------------------------------------------------+
void cdcd_init (void);
bool cdcd_deinit (void);
void cdcd_reset (uint8_t rhport);
uint16_t cdcd_open (uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint16_t max_len);
bool cdcd_control_xfer_cb (uint8_t rhport, uint8_t stage, tusb_control_request_t const * request);

View File

@ -160,11 +160,14 @@ void dfu_moded_reset(uint8_t rhport)
reset_state();
}
void dfu_moded_init(void)
{
void dfu_moded_init(void) {
dfu_moded_reset(0);
}
bool dfu_moded_deinit(void) {
return true;
}
uint16_t dfu_moded_open(uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint16_t max_len)
{
(void) rhport;

View File

@ -86,6 +86,7 @@ TU_ATTR_WEAK void tud_dfu_abort_cb(uint8_t alt);
// Internal Class Driver API
//--------------------------------------------------------------------+
void dfu_moded_init(void);
bool dfu_moded_deinit(void);
void dfu_moded_reset(uint8_t rhport);
uint16_t dfu_moded_open(uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint16_t max_len);
bool dfu_moded_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t const * request);

View File

@ -51,8 +51,11 @@
//--------------------------------------------------------------------+
// USBD Driver API
//--------------------------------------------------------------------+
void dfu_rtd_init(void)
{
void dfu_rtd_init(void) {
}
bool dfu_rtd_deinit(void) {
return true;
}
void dfu_rtd_reset(uint8_t rhport)

View File

@ -43,6 +43,7 @@ void tud_dfu_runtime_reboot_to_dfu_cb(void);
// Internal Class Driver API
//--------------------------------------------------------------------+
void dfu_rtd_init(void);
bool dfu_rtd_deinit(void);
void dfu_rtd_reset(uint8_t rhport);
uint16_t dfu_rtd_open(uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint16_t max_len);
bool dfu_rtd_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t const * request);

View File

@ -179,11 +179,14 @@ bool tud_hid_n_gamepad_report(uint8_t instance, uint8_t report_id,
//--------------------------------------------------------------------+
// USBD-CLASS API
//--------------------------------------------------------------------+
void hidd_init(void)
{
void hidd_init(void) {
hidd_reset(0);
}
bool hidd_deinit(void) {
return true;
}
void hidd_reset(uint8_t rhport)
{
(void) rhport;

View File

@ -465,6 +465,7 @@ static inline bool tud_hid_gamepad_report(uint8_t report_id, int8_t x, int8_t y
// Internal Class Driver API
//--------------------------------------------------------------------+
void hidd_init (void);
bool hidd_deinit (void);
void hidd_reset (uint8_t rhport);
uint16_t hidd_open (uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint16_t max_len);
bool hidd_control_xfer_cb (uint8_t rhport, uint8_t stage, tusb_control_request_t const * request);

View File

@ -373,12 +373,10 @@ bool tud_midi_n_packet_write (uint8_t itf, uint8_t const packet[4])
//--------------------------------------------------------------------+
// USBD Driver API
//--------------------------------------------------------------------+
void midid_init(void)
{
void midid_init(void) {
tu_memclr(_midid_itf, sizeof(_midid_itf));
for(uint8_t i=0; i<CFG_TUD_MIDI; i++)
{
for (uint8_t i = 0; i < CFG_TUD_MIDI; i++) {
midid_interface_t* midi = &_midid_itf[i];
// config fifo
@ -386,12 +384,38 @@ void midid_init(void)
tu_fifo_config(&midi->tx_ff, midi->tx_ff_buf, CFG_TUD_MIDI_TX_BUFSIZE, 1, false); // OBVS.
#if CFG_FIFO_MUTEX
tu_fifo_config_mutex(&midi->rx_ff, NULL, osal_mutex_create(&midi->rx_ff_mutex));
tu_fifo_config_mutex(&midi->tx_ff, osal_mutex_create(&midi->tx_ff_mutex), NULL);
osal_mutex_t mutex_rd = osal_mutex_create(&midi->rx_ff_mutex);
osal_mutex_t mutex_wr = osal_mutex_create(&midi->tx_ff_mutex);
TU_ASSERT(mutex_wr != NULL && mutex_wr != NULL, );
tu_fifo_config_mutex(&midi->rx_ff, NULL, mutex_rd);
tu_fifo_config_mutex(&midi->tx_ff, mutex_wr, NULL);
#endif
}
}
bool midid_deinit(void) {
#if CFG_FIFO_MUTEX
for(uint8_t i=0; i<CFG_TUD_MIDI; i++) {
midid_interface_t* midi = &_midid_itf[i];
osal_mutex_t mutex_rd = midi->rx_ff.mutex_rd;
osal_mutex_t mutex_wr = midi->tx_ff.mutex_wr;
if (mutex_rd) {
osal_mutex_delete(mutex_rd);
tu_fifo_config_mutex(&midi->rx_ff, NULL, NULL);
}
if (mutex_wr) {
osal_mutex_delete(mutex_wr);
tu_fifo_config_mutex(&midi->tx_ff, NULL, NULL);
}
}
#endif
return true;
}
void midid_reset(uint8_t rhport)
{
(void) rhport;

View File

@ -158,6 +158,7 @@ static inline bool tud_midi_packet_write (uint8_t const packet[4])
// Internal Class Driver API
//--------------------------------------------------------------------+
void midid_init (void);
bool midid_deinit (void);
void midid_reset (uint8_t rhport);
uint16_t midid_open (uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint16_t max_len);
bool midid_control_xfer_cb (uint8_t rhport, uint8_t stage, tusb_control_request_t const * request);

View File

@ -251,11 +251,15 @@ static inline void set_sense_medium_not_present(uint8_t lun)
//--------------------------------------------------------------------+
// USBD Driver API
//--------------------------------------------------------------------+
void mscd_init(void)
{
void mscd_init(void) {
tu_memclr(&_mscd_itf, sizeof(mscd_interface_t));
}
bool mscd_deinit(void) {
// nothing to do
return true;
}
void mscd_reset(uint8_t rhport)
{
(void) rhport;

View File

@ -150,6 +150,7 @@ TU_ATTR_WEAK bool tud_msc_is_writable_cb(uint8_t lun);
// Internal Class Driver API
//--------------------------------------------------------------------+
void mscd_init (void);
bool mscd_deinit (void);
void mscd_reset (uint8_t rhport);
uint16_t mscd_open (uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint16_t max_len);
bool mscd_control_xfer_cb (uint8_t rhport, uint8_t stage, tusb_control_request_t const * p_request);

View File

@ -132,11 +132,14 @@ void netd_report(uint8_t *buf, uint16_t len)
//--------------------------------------------------------------------+
// USBD Driver API
//--------------------------------------------------------------------+
void netd_init(void)
{
void netd_init(void) {
tu_memclr(&_netd_itf, sizeof(_netd_itf));
}
bool netd_deinit(void) {
return true;
}
void netd_reset(uint8_t rhport)
{
(void) rhport;

View File

@ -260,6 +260,10 @@ void netd_init(void)
ncm_prepare_for_tx();
}
bool netd_deinit(void) {
return true;
}
void netd_reset(uint8_t rhport)
{
(void) rhport;

View File

@ -105,6 +105,7 @@ void tud_network_link_state_cb(bool state);
// INTERNAL USBD-CLASS DRIVER API
//--------------------------------------------------------------------+
void netd_init (void);
bool netd_deinit (void);
void netd_reset (uint8_t rhport);
uint16_t netd_open (uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint16_t max_len);
bool netd_control_xfer_cb (uint8_t rhport, uint8_t stage, tusb_control_request_t const * request);

View File

@ -260,6 +260,13 @@ void usbtmcd_init_cb(void)
usbtmcLock = osal_mutex_create(&usbtmcLockBuffer);
}
bool usbtmcd_deinit(void) {
#if OSAL_MUTEX_REQUIRED
osal_mutex_delete(usbtmcLock);
#endif
return true;
}
uint16_t usbtmcd_open_cb(uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint16_t max_len)
{
(void)rhport;

View File

@ -98,11 +98,12 @@ bool tud_usbtmc_start_bus_read(void);
/* "callbacks" from USB device core */
void usbtmcd_init_cb(void);
bool usbtmcd_deinit(void);
uint16_t usbtmcd_open_cb(uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint16_t max_len);
void usbtmcd_reset_cb(uint8_t rhport);
bool usbtmcd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes);
bool usbtmcd_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t const * request);
void usbtmcd_init_cb(void);
/************************************************************
* USBTMC Descriptor Templates

View File

@ -169,23 +169,49 @@ uint32_t tud_vendor_n_write_available (uint8_t itf)
//--------------------------------------------------------------------+
// USBD Driver API
//--------------------------------------------------------------------+
void vendord_init(void)
{
void vendord_init(void) {
tu_memclr(_vendord_itf, sizeof(_vendord_itf));
for(uint8_t i=0; i<CFG_TUD_VENDOR; i++)
{
for(uint8_t i=0; i<CFG_TUD_VENDOR; i++) {
vendord_interface_t* p_itf = &_vendord_itf[i];
// config fifo
tu_fifo_config(&p_itf->rx_ff, p_itf->rx_ff_buf, CFG_TUD_VENDOR_RX_BUFSIZE, 1, false);
tu_fifo_config(&p_itf->tx_ff, p_itf->tx_ff_buf, CFG_TUD_VENDOR_TX_BUFSIZE, 1, false);
tu_fifo_config_mutex(&p_itf->rx_ff, NULL, osal_mutex_create(&p_itf->rx_ff_mutex));
tu_fifo_config_mutex(&p_itf->tx_ff, osal_mutex_create(&p_itf->tx_ff_mutex), NULL);
#if OSAL_MUTEX_REQUIRED
osal_mutex_t mutex_rd = osal_mutex_create(&p_itf->rx_ff_mutex);
osal_mutex_t mutex_wr = osal_mutex_create(&p_itf->tx_ff_mutex);
TU_ASSERT(mutex_rd && mutex_wr,);
tu_fifo_config_mutex(&p_itf->rx_ff, NULL, mutex_rd);
tu_fifo_config_mutex(&p_itf->tx_ff, mutex_wr, NULL);
#endif
}
}
bool vendord_deinit(void) {
#if OSAL_MUTEX_REQUIRED
for(uint8_t i=0; i<CFG_TUD_VENDOR; i++) {
vendord_interface_t* p_itf = &_vendord_itf[i];
osal_mutex_t mutex_rd = p_itf->rx_ff.mutex_rd;
osal_mutex_t mutex_wr = p_itf->tx_ff.mutex_wr;
if (mutex_rd) {
osal_mutex_delete(mutex_rd);
tu_fifo_config_mutex(&p_itf->rx_ff, NULL, NULL);
}
if (mutex_wr) {
osal_mutex_delete(mutex_wr);
tu_fifo_config_mutex(&p_itf->tx_ff, NULL, NULL);
}
}
#endif
return true;
}
void vendord_reset(uint8_t rhport)
{
(void) rhport;

View File

@ -139,6 +139,7 @@ static inline uint32_t tud_vendor_write_available (void)
// Internal Class Driver API
//--------------------------------------------------------------------+
void vendord_init(void);
bool vendord_deinit(void);
void vendord_reset(uint8_t rhport);
uint16_t vendord_open(uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint16_t max_len);
bool vendord_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t event, uint32_t xferred_bytes);

View File

@ -1236,6 +1236,10 @@ void videod_init(void) {
}
}
bool videod_deinit(void) {
return true;
}
void videod_reset(uint8_t rhport) {
(void) rhport;
for (uint_fast8_t i = 0; i < CFG_TUD_VIDEO; ++i) {

View File

@ -85,6 +85,7 @@ TU_ATTR_WEAK int tud_video_commit_cb(uint_fast8_t ctl_idx, uint_fast8_t stm_idx,
// INTERNAL USBD-CLASS DRIVER API
//--------------------------------------------------------------------+
void videod_init (void);
bool videod_deinit (void);
void videod_reset (uint8_t rhport);
uint16_t videod_open (uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint16_t max_len);
bool videod_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t const * request);

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -425,7 +425,7 @@ bool tuh_deinit(uint8_t rhport) {
// Class drivers
for (uint8_t drv_id = 0; drv_id < TOTAL_DRIVER_COUNT; drv_id++) {
usbh_class_driver_t const* driver = get_driver(drv_id);
if (driver) {
if (driver && driver->deinit) {
TU_LOG_USBH("%s deinit\r\n", driver->name);
driver->deinit();
}

View File

@ -407,6 +407,19 @@ void dcd_init(uint8_t rhport) {
dcd_connect(rhport);
}
bool dcd_deinit(uint8_t rhport) {
(void) rhport;
reset_non_control_endpoints();
irq_remove_handler(USBCTRL_IRQ, dcd_rp2040_irq);
// reset usb hardware into initial state
reset_block(RESETS_RESET_USBCTRL_BITS);
unreset_block_wait(RESETS_RESET_USBCTRL_BITS);
return true;
}
void dcd_int_enable(__unused uint8_t rhport) {
assert(rhport == 0);
irq_set_enabled(USBCTRL_IRQ, true);

View File

@ -409,6 +409,16 @@ bool hcd_init(uint8_t rhport)
return true;
}
bool hcd_deinit(uint8_t rhport) {
(void) rhport;
irq_remove_handler(USBCTRL_IRQ, hcd_rp2040_irq);
reset_block(RESETS_RESET_USBCTRL_BITS);
unreset_block_wait(RESETS_RESET_USBCTRL_BITS);
return true;
}
void hcd_port_reset(uint8_t rhport)
{
(void) rhport;

View File

@ -34,7 +34,7 @@
#define TUSB_VERSION_MAJOR 0
#define TUSB_VERSION_MINOR 16
#define TUSB_VERSION_REVISION 0
#define TUSB_VERSION_BUILD 2
#define TUSB_VERSION_BUILD 3
#define TUSB_VERSION_NUMBER (TUSB_VERSION_MAJOR << 24 | TUSB_VERSION_MINOR << 16 | TUSB_VERSION_REVISION << 8 | TUSB_VERSION_BUILD)
#define TUSB_VERSION_STRING TU_STRING(TUSB_VERSION_MAJOR) "." TU_STRING(TUSB_VERSION_MINOR) "." TU_STRING(TUSB_VERSION_REVISION)