From 3fdd2a40b2103089e47609a05577fc84b786ec4f Mon Sep 17 00:00:00 2001 From: Aladdin Bakosh Date: Fri, 2 Jun 2023 15:04:53 +0200 Subject: osal_none: make it possible to override the task delay function --- src/host/usbh.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/host') diff --git a/src/host/usbh.c b/src/host/usbh.c index 184bda23b..1418cfb79 100644 --- a/src/host/usbh.c +++ b/src/host/usbh.c @@ -256,7 +256,7 @@ static bool usbh_control_xfer_cb (uint8_t daddr, uint8_t ep_addr, xfer_result_t #if CFG_TUSB_OS == OPT_OS_NONE // TODO rework time-related function later -void osal_task_delay(uint32_t msec) +TU_ATTR_WEAK void osal_task_delay(uint32_t msec) { const uint32_t start = hcd_frame_number(_usbh_controller); while ( ( hcd_frame_number(_usbh_controller) - start ) < msec ) {} -- cgit v1.3.1 From dc74e634f93962512229ba7d4e14467c16125c0d Mon Sep 17 00:00:00 2001 From: hathach Date: Tue, 25 Jul 2023 12:35:40 +0700 Subject: fix unaligned hub status_change --- src/host/hub.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/host') diff --git a/src/host/hub.c b/src/host/hub.c index 182bd6ce8..16dd534d2 100644 --- a/src/host/hub.c +++ b/src/host/hub.c @@ -45,8 +45,8 @@ typedef struct uint8_t itf_num; uint8_t ep_in; uint8_t port_count; - uint8_t status_change; // data from status change interrupt endpoint + CFG_TUH_MEM_ALIGN uint8_t status_change; CFG_TUH_MEM_ALIGN hub_port_status_response_t port_status; CFG_TUH_MEM_ALIGN hub_status_response_t hub_status; } hub_interface_t; -- cgit v1.3.1 From c37a9571741cef0dcf0cd5a77e202ae741a2dd42 Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 26 Jul 2023 19:56:48 +0700 Subject: correct hcd_edpt_clear_stall() API signature --- src/host/hcd.h | 2 +- src/portable/mentor/musb/hcd_musb.c | 4 ++-- src/portable/nxp/khci/hcd_khci.c | 4 ++-- src/portable/ohci/ohci.c | 4 ++-- src/portable/raspberrypi/pio_usb/hcd_pio_usb.c | 4 ++-- src/portable/raspberrypi/rp2040/hcd_rp2040.c | 4 ++-- src/portable/renesas/rusb2/hcd_rusb2.c | 4 ++-- 7 files changed, 13 insertions(+), 13 deletions(-) (limited to 'src/host') diff --git a/src/host/hcd.h b/src/host/hcd.h index 50f1dcdcc..898e0c6a4 100644 --- a/src/host/hcd.h +++ b/src/host/hcd.h @@ -179,7 +179,7 @@ bool hcd_edpt_abort_xfer(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr); bool hcd_setup_send(uint8_t rhport, uint8_t dev_addr, uint8_t const setup_packet[8]); // clear stall, data toggle is also reset to DATA0 -bool hcd_edpt_clear_stall(uint8_t daddr, uint8_t ep_addr); +bool hcd_edpt_clear_stall(uint8_t rhport, uint8_t daddr, uint8_t ep_addr); //--------------------------------------------------------------------+ // USBH implemented API diff --git a/src/portable/mentor/musb/hcd_musb.c b/src/portable/mentor/musb/hcd_musb.c index 5be67a186..5d1fba6d9 100644 --- a/src/portable/mentor/musb/hcd_musb.c +++ b/src/portable/mentor/musb/hcd_musb.c @@ -831,8 +831,8 @@ bool hcd_edpt_abort_xfer(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr) { } // clear stall, data toggle is also reset to DATA0 -bool hcd_edpt_clear_stall(uint8_t dev_addr, uint8_t ep_addr) -{ +bool hcd_edpt_clear_stall(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr) { + (void) rhport; unsigned const pipenum = find_pipe(dev_addr, ep_addr); if (!pipenum) return false; hw_endpoint_t volatile *regs = edpt_regs(pipenum - 1); diff --git a/src/portable/nxp/khci/hcd_khci.c b/src/portable/nxp/khci/hcd_khci.c index 6784049c5..928564e26 100644 --- a/src/portable/nxp/khci/hcd_khci.c +++ b/src/portable/nxp/khci/hcd_khci.c @@ -570,8 +570,8 @@ bool hcd_edpt_abort_xfer(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr) { return false; } -bool hcd_edpt_clear_stall(uint8_t dev_addr, uint8_t ep_addr) -{ +bool hcd_edpt_clear_stall(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr) { + (void) rhport; if (!tu_edpt_number(ep_addr)) return true; int num = find_pipe(dev_addr, ep_addr); if (num < 0) return false; diff --git a/src/portable/ohci/ohci.c b/src/portable/ohci/ohci.c index 9f3af4781..413e72037 100644 --- a/src/portable/ohci/ohci.c +++ b/src/portable/ohci/ohci.c @@ -556,8 +556,8 @@ bool hcd_edpt_abort_xfer(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr) { return false; } -bool hcd_edpt_clear_stall(uint8_t dev_addr, uint8_t ep_addr) -{ +bool hcd_edpt_clear_stall(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr) { + (void) rhport; ohci_ed_t * const p_ed = ed_from_addr(dev_addr, ep_addr); p_ed->is_stalled = 0; diff --git a/src/portable/raspberrypi/pio_usb/hcd_pio_usb.c b/src/portable/raspberrypi/pio_usb/hcd_pio_usb.c index bb41ad638..45a3e80ef 100644 --- a/src/portable/raspberrypi/pio_usb/hcd_pio_usb.c +++ b/src/portable/raspberrypi/pio_usb/hcd_pio_usb.c @@ -163,8 +163,8 @@ bool hcd_setup_send(uint8_t rhport, uint8_t dev_addr, uint8_t const setup_packet // return busy; //} -bool hcd_edpt_clear_stall(uint8_t dev_addr, uint8_t ep_addr) -{ +bool hcd_edpt_clear_stall(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr) { + (void) rhport; (void) dev_addr; (void) ep_addr; diff --git a/src/portable/raspberrypi/rp2040/hcd_rp2040.c b/src/portable/raspberrypi/rp2040/hcd_rp2040.c index 5091fa907..6db8e2a0a 100644 --- a/src/portable/raspberrypi/rp2040/hcd_rp2040.c +++ b/src/portable/raspberrypi/rp2040/hcd_rp2040.c @@ -625,8 +625,8 @@ bool hcd_setup_send(uint8_t rhport, uint8_t dev_addr, uint8_t const setup_packet return true; } -bool hcd_edpt_clear_stall(uint8_t dev_addr, uint8_t ep_addr) -{ +bool hcd_edpt_clear_stall(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr) { + (void) rhport; (void) dev_addr; (void) ep_addr; diff --git a/src/portable/renesas/rusb2/hcd_rusb2.c b/src/portable/renesas/rusb2/hcd_rusb2.c index 0a75d0b47..292d40da8 100644 --- a/src/portable/renesas/rusb2/hcd_rusb2.c +++ b/src/portable/renesas/rusb2/hcd_rusb2.c @@ -718,8 +718,8 @@ bool hcd_edpt_abort_xfer(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr) { return false; } -bool hcd_edpt_clear_stall(uint8_t dev_addr, uint8_t ep_addr) -{ +bool hcd_edpt_clear_stall(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr) { + (void) rhport; uint16_t volatile *ctr = addr_to_pipectr(dev_addr, ep_addr); TU_ASSERT(ctr); -- cgit v1.3.1 From 10575c1b380136ce9381393c33e982cea7ef4731 Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 26 Jul 2023 20:48:18 +0700 Subject: mising ehci --- src/host/hcd.h | 2 +- src/portable/ehci/ehci.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'src/host') diff --git a/src/host/hcd.h b/src/host/hcd.h index 898e0c6a4..d77dd6e2f 100644 --- a/src/host/hcd.h +++ b/src/host/hcd.h @@ -179,7 +179,7 @@ bool hcd_edpt_abort_xfer(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr); bool hcd_setup_send(uint8_t rhport, uint8_t dev_addr, uint8_t const setup_packet[8]); // clear stall, data toggle is also reset to DATA0 -bool hcd_edpt_clear_stall(uint8_t rhport, uint8_t daddr, uint8_t ep_addr); +bool hcd_edpt_clear_stall(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr); //--------------------------------------------------------------------+ // USBH implemented API diff --git a/src/portable/ehci/ehci.c b/src/portable/ehci/ehci.c index 241393a39..979069cfa 100644 --- a/src/portable/ehci/ehci.c +++ b/src/portable/ehci/ehci.c @@ -502,8 +502,8 @@ bool hcd_edpt_abort_xfer(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr) { return still_active; // true if removed an active transfer } -bool hcd_edpt_clear_stall(uint8_t daddr, uint8_t ep_addr) -{ +bool hcd_edpt_clear_stall(uint8_t rhport, uint8_t daddr, uint8_t ep_addr) { + (void) rhport; ehci_qhd_t *qhd = qhd_get_from_addr(daddr, ep_addr); qhd->qtd_overlay.halted = 0; hcd_dcache_clean_invalidate(qhd, sizeof(ehci_qhd_t)); -- cgit v1.3.1 From 979bf32266d379ec493ad31001b815d6a597b91e Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 2 Aug 2023 15:34:18 +0700 Subject: default class driver log level to CFG_TUH/TUD_LOG_LEVEL allow application to selectively disable usbd/usbh or driver log --- src/class/cdc/cdc_device.c | 15 +++++++++++---- src/class/cdc/cdc_host.c | 9 ++++++--- src/class/dfu/dfu_device.c | 11 +++++++++-- src/class/dfu/dfu_rt_device.c | 13 ++++++++++--- src/class/hid/hid_host.c | 8 +++++--- src/class/msc/msc_device.c | 2 +- src/class/msc/msc_host.c | 19 +++++++++++-------- src/class/net/ncm_device.c | 11 +++++++++-- src/class/video/video_device.c | 23 +++++++++++++++-------- src/host/usbh.c | 7 ------- src/host/usbh_classdriver.h | 7 +++++++ 11 files changed, 84 insertions(+), 41 deletions(-) (limited to 'src/host') diff --git a/src/class/cdc/cdc_device.c b/src/class/cdc/cdc_device.c index f658df4d0..70d9c2e24 100644 --- a/src/class/cdc/cdc_device.c +++ b/src/class/cdc/cdc_device.c @@ -33,6 +33,13 @@ #include "cdc_device.h" +// Level where CFG_TUSB_DEBUG must be at least for this driver is logged +#ifndef CFG_TUD_CDC_LOG_LEVEL + #define CFG_TUD_CDC_LOG_LEVEL CFG_TUD_LOG_LEVEL +#endif + +#define TU_LOG_DRV(...) TU_LOG(CFG_TUD_CDC_LOG_LEVEL, __VA_ARGS__) + //--------------------------------------------------------------------+ // MACRO CONSTANT TYPEDEF //--------------------------------------------------------------------+ @@ -353,7 +360,7 @@ bool cdcd_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t case CDC_REQUEST_SET_LINE_CODING: if (stage == CONTROL_STAGE_SETUP) { - TU_LOG2(" Set Line Coding\r\n"); + TU_LOG_DRV(" Set Line Coding\r\n"); tud_control_xfer(rhport, request, &p_cdc->line_coding, sizeof(cdc_line_coding_t)); } else if ( stage == CONTROL_STAGE_ACK) @@ -365,7 +372,7 @@ bool cdcd_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t case CDC_REQUEST_GET_LINE_CODING: if (stage == CONTROL_STAGE_SETUP) { - TU_LOG2(" Get Line Coding\r\n"); + TU_LOG_DRV(" Get Line Coding\r\n"); tud_control_xfer(rhport, request, &p_cdc->line_coding, sizeof(cdc_line_coding_t)); } break; @@ -390,7 +397,7 @@ bool cdcd_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t // Disable fifo overwriting if DTR bit is set tu_fifo_set_overwritable(&p_cdc->tx_ff, !dtr); - TU_LOG2(" Set Control Line State: DTR = %d, RTS = %d\r\n", dtr, rts); + TU_LOG_DRV(" Set Control Line State: DTR = %d, RTS = %d\r\n", dtr, rts); // Invoke callback if ( tud_cdc_line_state_cb ) tud_cdc_line_state_cb(itf, dtr, rts); @@ -403,7 +410,7 @@ bool cdcd_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t } else if (stage == CONTROL_STAGE_ACK) { - TU_LOG2(" Send Break\r\n"); + TU_LOG_DRV(" Send Break\r\n"); if ( tud_cdc_send_break_cb ) tud_cdc_send_break_cb(itf, request->wValue); } break; diff --git a/src/class/cdc/cdc_host.c b/src/class/cdc/cdc_host.c index ce9f27c33..7f9ed18b3 100644 --- a/src/class/cdc/cdc_host.c +++ b/src/class/cdc/cdc_host.c @@ -33,9 +33,12 @@ #include "cdc_host.h" -// Debug level, TUSB_CFG_DEBUG must be at least this level for debug message -#define CDCH_DEBUG 2 -#define TU_LOG_DRV(...) TU_LOG(CDCH_DEBUG, __VA_ARGS__) +// Level where CFG_TUSB_DEBUG must be at least for this driver is logged +#ifndef CFG_TUH_CDC_LOG_LEVEL + #define CFG_TUH_CDC_LOG_LEVEL CFG_TUH_LOG_LEVEL +#endif + +#define TU_LOG_DRV(...) TU_LOG(CFG_TUH_CDC_LOG_LEVEL, __VA_ARGS__) //--------------------------------------------------------------------+ // Host CDC Interface diff --git a/src/class/dfu/dfu_device.c b/src/class/dfu/dfu_device.c index bffdb8376..3e7c13dea 100644 --- a/src/class/dfu/dfu_device.c +++ b/src/class/dfu/dfu_device.c @@ -37,6 +37,13 @@ // MACRO CONSTANT TYPEDEF //--------------------------------------------------------------------+ +// Level where CFG_TUSB_DEBUG must be at least for this driver is logged +#ifndef CFG_TUD_DFU_LOG_LEVEL + #define CFG_TUD_DFU_LOG_LEVEL CFG_TUD_LOG_LEVEL +#endif + +#define TU_LOG_DRV(...) TU_LOG(CFG_TUD_DFU_LOG_LEVEL, __VA_ARGS__) + //--------------------------------------------------------------------+ // INTERNAL OBJECT & FUNCTION DECLARATION //--------------------------------------------------------------------+ @@ -205,7 +212,7 @@ bool dfu_moded_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_reque { TU_VERIFY(request->bmRequestType_bit.recipient == TUSB_REQ_RCPT_INTERFACE); - TU_LOG2(" DFU State : %s, Status: %s\r\n", tu_lookup_find(&_dfu_state_table, _dfu_ctx.state), tu_lookup_find(&_dfu_status_table, _dfu_ctx.status)); + TU_LOG_DRV(" DFU State : %s, Status: %s\r\n", tu_lookup_find(&_dfu_state_table, _dfu_ctx.state), tu_lookup_find(&_dfu_status_table, _dfu_ctx.status)); if ( request->bmRequestType_bit.type == TUSB_REQ_TYPE_STANDARD ) { @@ -235,7 +242,7 @@ bool dfu_moded_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_reque } else if ( request->bmRequestType_bit.type == TUSB_REQ_TYPE_CLASS ) { - TU_LOG2(" DFU Request: %s\r\n", tu_lookup_find(&_dfu_request_table, request->bRequest)); + TU_LOG_DRV(" DFU Request: %s\r\n", tu_lookup_find(&_dfu_request_table, request->bRequest)); // Class request switch ( request->bRequest ) diff --git a/src/class/dfu/dfu_rt_device.c b/src/class/dfu/dfu_rt_device.c index 7b77b3f8f..a940d8d62 100644 --- a/src/class/dfu/dfu_rt_device.c +++ b/src/class/dfu/dfu_rt_device.c @@ -37,6 +37,13 @@ // MACRO CONSTANT TYPEDEF //--------------------------------------------------------------------+ +// Level where CFG_TUSB_DEBUG must be at least for this driver is logged +#ifndef CFG_TUD_DFU_RUNTIME_LOG_LEVEL + #define CFG_TUD_DFU_RUNTIME_LOG_LEVEL CFG_TUD_LOG_LEVEL +#endif + +#define TU_LOG_DRV(...) TU_LOG(CFG_TUD_DFU_RUNTIME_LOG_LEVEL, __VA_ARGS__) + //--------------------------------------------------------------------+ // INTERNAL OBJECT & FUNCTION DECLARATION //--------------------------------------------------------------------+ @@ -99,7 +106,7 @@ bool dfu_rtd_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request { case DFU_REQUEST_DETACH: { - TU_LOG2(" DFU RT Request: DETACH\r\n"); + TU_LOG_DRV(" DFU RT Request: DETACH\r\n"); tud_control_status(rhport, request); tud_dfu_runtime_reboot_to_dfu_cb(); } @@ -107,7 +114,7 @@ bool dfu_rtd_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request case DFU_REQUEST_GETSTATUS: { - TU_LOG2(" DFU RT Request: GETSTATUS\r\n"); + TU_LOG_DRV(" DFU RT Request: GETSTATUS\r\n"); dfu_status_response_t resp; // Status = OK, Poll timeout is ignored during RT, State = APP_IDLE, IString = 0 TU_VERIFY(tu_memset_s(&resp, sizeof(resp), 0x00, sizeof(resp))==0); @@ -117,7 +124,7 @@ bool dfu_rtd_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request default: { - TU_LOG2(" DFU RT Unexpected Request: %d\r\n", request->bRequest); + TU_LOG_DRV(" DFU RT Unexpected Request: %d\r\n", request->bRequest); return false; // stall unsupported request } } diff --git a/src/class/hid/hid_host.c b/src/class/hid/hid_host.c index 6abe298e5..4253170d4 100644 --- a/src/class/hid/hid_host.c +++ b/src/class/hid/hid_host.c @@ -33,10 +33,12 @@ #include "hid_host.h" -// Debug level, TUSB_CFG_DEBUG must be at least this level for debug message -#define HIDH_DEBUG 2 -#define TU_LOG_DRV(...) TU_LOG(HIDH_DEBUG, __VA_ARGS__) +// Level where CFG_TUSB_DEBUG must be at least for this driver is logged +#ifndef CFG_TUH_HID_LOG_LEVEL + #define CFG_TUH_HID_LOG_LEVEL CFG_TUH_LOG_LEVEL +#endif +#define TU_LOG_DRV(...) TU_LOG(CFG_TUH_HID_LOG_LEVEL, __VA_ARGS__) //--------------------------------------------------------------------+ // MACRO CONSTANT TYPEDEF //--------------------------------------------------------------------+ diff --git a/src/class/msc/msc_device.c b/src/class/msc/msc_device.c index a602e9672..2589dcd2c 100644 --- a/src/class/msc/msc_device.c +++ b/src/class/msc/msc_device.c @@ -36,7 +36,7 @@ // Level where CFG_TUSB_DEBUG must be at least for this driver is logged #ifndef CFG_TUD_MSC_LOG_LEVEL - #define CFG_TUD_MSC_LOG_LEVEL 2 + #define CFG_TUD_MSC_LOG_LEVEL CFG_TUD_LOG_LEVEL #endif #define TU_LOG_DRV(...) TU_LOG(CFG_TUD_MSC_LOG_LEVEL, __VA_ARGS__) diff --git a/src/class/msc/msc_host.c b/src/class/msc/msc_host.c index d32c0adb0..a65208d69 100644 --- a/src/class/msc/msc_host.c +++ b/src/class/msc/msc_host.c @@ -33,9 +33,12 @@ #include "msc_host.h" -// Debug level, TUSB_CFG_DEBUG must be at least this level for debug message -#define MSCH_DEBUG 2 -#define TU_LOG_MSCH(...) TU_LOG(MSCH_DEBUG, __VA_ARGS__) +// Level where CFG_TUSB_DEBUG must be at least for this driver is logged +#ifndef CFG_TUH_MSC_LOG_LEVEL + #define CFG_TUH_MSC_LOG_LEVEL CFG_TUH_LOG_LEVEL +#endif + +#define TU_LOG_DRV(...) TU_LOG(CFG_TUH_MSC_LOG_LEVEL, __VA_ARGS__) //--------------------------------------------------------------------+ // MACRO CONSTANT TYPEDEF @@ -308,7 +311,7 @@ void msch_close(uint8_t dev_addr) msch_interface_t* p_msc = get_itf(dev_addr); TU_VERIFY(p_msc->configured, ); - TU_LOG_MSCH(" MSCh close addr = %d\r\n", dev_addr); + TU_LOG_DRV(" MSCh close addr = %d\r\n", dev_addr); // invoke Application Callback if (p_msc->mounted) { @@ -426,7 +429,7 @@ bool msch_set_config(uint8_t dev_addr, uint8_t itf_num) p_msc->configured = true; //------------- Get Max Lun -------------// - TU_LOG_MSCH("MSC Get Max Lun\r\n"); + TU_LOG_DRV("MSC Get Max Lun\r\n"); tusb_control_request_t const request = { .bmRequestType_bit = @@ -465,7 +468,7 @@ static void config_get_maxlun_complete (tuh_xfer_t* xfer) p_msc->max_lun++; // MAX LUN is minus 1 by specs // TODO multiple LUN support - TU_LOG_MSCH("SCSI Test Unit Ready\r\n"); + TU_LOG_DRV("SCSI Test Unit Ready\r\n"); uint8_t const lun = 0; tuh_msc_test_unit_ready(daddr, lun, config_test_unit_ready_complete, 0); } @@ -478,14 +481,14 @@ static bool config_test_unit_ready_complete(uint8_t dev_addr, tuh_msc_complete_d if (csw->status == 0) { // Unit is ready, read its capacity - TU_LOG_MSCH("SCSI Read Capacity\r\n"); + TU_LOG_DRV("SCSI Read Capacity\r\n"); tuh_msc_read_capacity(dev_addr, cbw->lun, (scsi_read_capacity10_resp_t*) ((void*) _msch_buffer), config_read_capacity_complete, 0); }else { // Note: During enumeration, some device fails Test Unit Ready and require a few retries // with Request Sense to start working !! // TODO limit number of retries - TU_LOG_MSCH("SCSI Request Sense\r\n"); + TU_LOG_DRV("SCSI Request Sense\r\n"); TU_ASSERT(tuh_msc_request_sense(dev_addr, cbw->lun, _msch_buffer, config_request_sense_complete, 0)); } diff --git a/src/class/net/ncm_device.c b/src/class/net/ncm_device.c index 611dc3348..226c42c4e 100644 --- a/src/class/net/ncm_device.c +++ b/src/class/net/ncm_device.c @@ -34,6 +34,13 @@ #include "device/usbd_pvt.h" #include "net_device.h" +// Level where CFG_TUSB_DEBUG must be at least for this driver is logged +#ifndef CFG_TUD_NCM_LOG_LEVEL + #define CFG_TUD_NCM_LOG_LEVEL CFG_TUD_LOG_LEVEL +#endif + +#define TU_LOG_DRV(...) TU_LOG(CFG_TUD_NCM_LOG_LEVEL, __VA_ARGS__) + //--------------------------------------------------------------------+ // MACRO CONSTANT TYPEDEF //--------------------------------------------------------------------+ @@ -473,13 +480,13 @@ bool tud_network_can_xmit(uint16_t size) TU_VERIFY(ncm_interface.itf_data_alt == 1); if (ncm_interface.datagram_count >= ncm_interface.max_datagrams_per_ntb) { - TU_LOG2("NTB full [by count]\r\n"); + TU_LOG_DRV("NTB full [by count]\r\n"); return false; } size_t next_datagram_offset = ncm_interface.next_datagram_offset; if (next_datagram_offset + size > ncm_interface.ntb_in_size) { - TU_LOG2("ntb full [by size]\r\n"); + TU_LOG_DRV("ntb full [by size]\r\n"); return false; } diff --git a/src/class/video/video_device.c b/src/class/video/video_device.c index e6fadf41b..abc43ccff 100644 --- a/src/class/video/video_device.c +++ b/src/class/video/video_device.c @@ -34,6 +34,13 @@ #include "video_device.h" +// Level where CFG_TUSB_DEBUG must be at least for this driver is logged +#ifndef CFG_TUD_VIDEO_LOG_LEVEL + #define CFG_TUD_VIDEO_LOG_LEVEL CFG_TUD_LOG_LEVEL +#endif + +#define TU_LOG_DRV(...) TU_LOG(CFG_TUD_VIDEO_LOG_LEVEL, __VA_ARGS__) + //--------------------------------------------------------------------+ // MACRO CONSTANT TYPEDEF //--------------------------------------------------------------------+ @@ -609,17 +616,17 @@ static bool _close_vc_itf(uint8_t rhport, videod_interface_t *self) * @param[in] altnum The target alternate setting number. */ static bool _open_vc_itf(uint8_t rhport, videod_interface_t *self, uint_fast8_t altnum) { - TU_LOG2(" open VC %d\n", altnum); + TU_LOG_DRV(" open VC %d\n", altnum); uint8_t const *beg = self->beg; uint8_t const *end = beg + self->len; /* The first descriptor is a video control interface descriptor. */ uint8_t const *cur = _find_desc_itf(beg, end, _desc_itfnum(beg), altnum); - TU_LOG2(" cur %d\n", cur - beg); + TU_LOG_DRV(" cur %d\n", cur - beg); TU_VERIFY(cur < end); tusb_desc_vc_itf_t const *vc = (tusb_desc_vc_itf_t const *)cur; - TU_LOG2(" bInCollection %d\n", vc->ctl.bInCollection); + TU_LOG_DRV(" bInCollection %d\n", vc->ctl.bInCollection); /* Support for up to 2 streaming interfaces only. */ TU_ASSERT(vc->ctl.bInCollection <= CFG_TUD_VIDEO_STREAMING); @@ -628,7 +635,7 @@ static bool _open_vc_itf(uint8_t rhport, videod_interface_t *self, uint_fast8_t /* Advance to the next descriptor after the class-specific VC interface header descriptor. */ cur += vc->std.bLength + vc->ctl.bLength; - TU_LOG2(" bNumEndpoints %d\n", vc->std.bNumEndpoints); + TU_LOG_DRV(" bNumEndpoints %d\n", vc->std.bNumEndpoints); /* Open the notification endpoint if it exist. */ if (vc->std.bNumEndpoints) { /* Support for 1 endpoint only. */ @@ -662,7 +669,7 @@ static bool _init_vs_configuration(videod_streaming_interface_t *stm) static bool _open_vs_itf(uint8_t rhport, videod_streaming_interface_t *stm, uint_fast8_t altnum) { uint_fast8_t i; - TU_LOG2(" reopen VS %d\n", altnum); + TU_LOG_DRV(" reopen VS %d\n", altnum); uint8_t const *desc = _videod_itf[stm->index_vc].beg; /* Close endpoints of previous settings. */ @@ -672,7 +679,7 @@ static bool _open_vs_itf(uint8_t rhport, videod_streaming_interface_t *stm, uint uint8_t ep_adr = _desc_ep_addr(desc + ofs_ep); usbd_edpt_close(rhport, ep_adr); stm->desc.ep[i] = 0; - TU_LOG2(" close EP%02x\n", ep_adr); + TU_LOG_DRV(" close EP%02x\n", ep_adr); } /* clear transfer management information */ @@ -709,12 +716,12 @@ static bool _open_vs_itf(uint8_t rhport, videod_streaming_interface_t *stm, uint } TU_ASSERT(usbd_edpt_open(rhport, ep)); stm->desc.ep[i] = (uint16_t) (cur - desc); - TU_LOG2(" open EP%02x\n", _desc_ep_addr(cur)); + TU_LOG_DRV(" open EP%02x\n", _desc_ep_addr(cur)); } if (altnum) { stm->state = VS_STATE_STREAMING; } - TU_LOG2(" done\n"); + TU_LOG_DRV(" done\n"); return true; } diff --git a/src/host/usbh.c b/src/host/usbh.c index c8eb91be3..49f8c78f1 100644 --- a/src/host/usbh.c +++ b/src/host/usbh.c @@ -45,13 +45,6 @@ #define CFG_TUH_INTERFACE_MAX 8 #endif -// Level where CFG_TUSB_DEBUG must be at least for USBH is logged -#ifndef CFG_TUH_LOG_LEVEL - #define CFG_TUH_LOG_LEVEL 2 -#endif - -#define TU_LOG_USBH(...) TU_LOG(CFG_TUH_LOG_LEVEL, __VA_ARGS__) - //--------------------------------------------------------------------+ // USBH-HCD common data structure //--------------------------------------------------------------------+ diff --git a/src/host/usbh_classdriver.h b/src/host/usbh_classdriver.h index be9811641..308b4418a 100644 --- a/src/host/usbh_classdriver.h +++ b/src/host/usbh_classdriver.h @@ -35,6 +35,13 @@ extern "C" { #endif +// Level where CFG_TUSB_DEBUG must be at least for USBH is logged +#ifndef CFG_TUH_LOG_LEVEL + #define CFG_TUH_LOG_LEVEL 2 +#endif + +#define TU_LOG_USBH(...) TU_LOG(CFG_TUH_LOG_LEVEL, __VA_ARGS__) + enum { USBH_EPSIZE_BULK_MAX = (TUH_OPT_HIGH_SPEED ? TUSB_EPSIZE_BULK_HS : TUSB_EPSIZE_BULK_FS) }; -- cgit v1.3.1 From 1f95a417f271e627ec981be3d211eed8c37cb052 Mon Sep 17 00:00:00 2001 From: hathach Date: Mon, 7 Aug 2023 18:22:28 +0700 Subject: Add tuh_rhport_is_active() and tuh_rhport_reset_bus() - also improve ehci bus reset - seperate bus reset delay and contact debouncing delay in enumeration --- src/host/hcd.h | 5 +- src/host/hub.c | 2 +- src/host/usbh.c | 118 +++++++++++++++++--------------- src/host/usbh.h | 39 ++++++----- src/portable/chipidea/ci_hs/hcd_ci_hs.c | 43 ++++++------ src/portable/ehci/ehci.c | 24 +++++-- 6 files changed, 128 insertions(+), 103 deletions(-) (limited to 'src/host') diff --git a/src/host/hcd.h b/src/host/hcd.h index d77dd6e2f..9bcc1c6df 100644 --- a/src/host/hcd.h +++ b/src/host/hcd.h @@ -149,10 +149,11 @@ uint32_t hcd_frame_number(uint8_t rhport); // Get the current connect status of roothub port bool hcd_port_connect_status(uint8_t rhport); -// Reset USB bus on the port +// Reset USB bus on the port. Return immediately, bus reset sequence may not be complete. +// Some port would require hcd_port_reset_end() to be invoked after 10ms to complete the reset sequence. void hcd_port_reset(uint8_t rhport); -// TODO implement later +// Complete bus reset sequence, may be required by some controllers void hcd_port_reset_end(uint8_t rhport); // Get port link speed diff --git a/src/host/hub.c b/src/host/hub.c index 16dd534d2..ec30eb96a 100644 --- a/src/host/hub.c +++ b/src/host/hub.c @@ -330,7 +330,7 @@ static void connection_port_reset_complete (tuh_xfer_t* xfer); bool hub_xfer_cb(uint8_t dev_addr, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes) { (void) xferred_bytes; // TODO can be more than 1 for hub with lots of ports (void) ep_addr; - TU_ASSERT(result == XFER_RESULT_SUCCESS); + TU_VERIFY(result == XFER_RESULT_SUCCESS); hub_interface_t* p_hub = get_itf(dev_addr); diff --git a/src/host/usbh.c b/src/host/usbh.c index 49f8c78f1..cc7e38b45 100644 --- a/src/host/usbh.c +++ b/src/host/usbh.c @@ -181,9 +181,6 @@ static usbh_class_driver_t const usbh_class_drivers[] = }; enum { USBH_CLASS_DRIVER_COUNT = TU_ARRAY_SIZE(usbh_class_drivers) }; - -enum { RESET_DELAY = 500 }; // 200 USB specs say only 50ms but many devices require much longer - enum { CONFIG_NUM = 1 }; // default to use configuration 1 @@ -251,40 +248,27 @@ static bool usbh_control_xfer_cb (uint8_t daddr, uint8_t ep_addr, xfer_result_t #if CFG_TUSB_OS == OPT_OS_NONE // TODO rework time-related function later -TU_ATTR_WEAK void osal_task_delay(uint32_t msec) -{ +// weak and overridable +TU_ATTR_WEAK void osal_task_delay(uint32_t msec) { const uint32_t start = hcd_frame_number(_usbh_controller); while ( ( hcd_frame_number(_usbh_controller) - start ) < msec ) {} } #endif //--------------------------------------------------------------------+ -// PUBLIC API (Parameter Verification is required) +// Device API //--------------------------------------------------------------------+ -bool tuh_configure(uint8_t rhport, uint32_t cfg_id, const void* cfg_param) -{ - if (hcd_configure) - { - return hcd_configure(rhport, cfg_id, cfg_param); - }else - { - return false; - } -} - -bool tuh_mounted(uint8_t dev_addr) -{ - usbh_device_t* dev = get_device(dev_addr); +bool tuh_mounted(uint8_t dev_addr) { + usbh_device_t *dev = get_device(dev_addr); TU_VERIFY(dev); return dev->configured; } -bool tuh_vid_pid_get(uint8_t dev_addr, uint16_t* vid, uint16_t* pid) -{ +bool tuh_vid_pid_get(uint8_t dev_addr, uint16_t *vid, uint16_t *pid) { *vid = *pid = 0; - usbh_device_t const* dev = get_device(dev_addr); + usbh_device_t const *dev = get_device(dev_addr); TU_VERIFY(dev && dev->addressed && dev->vid != 0); *vid = dev->vid; @@ -293,26 +277,48 @@ bool tuh_vid_pid_get(uint8_t dev_addr, uint16_t* vid, uint16_t* pid) return true; } -tusb_speed_t tuh_speed_get (uint8_t dev_addr) -{ - usbh_device_t* dev = get_device(dev_addr); +tusb_speed_t tuh_speed_get(uint8_t dev_addr) { + usbh_device_t *dev = get_device(dev_addr); return (tusb_speed_t) (dev ? get_device(dev_addr)->speed : _dev0.speed); } -static void clear_device(usbh_device_t* dev) -{ +bool tuh_rhport_is_active(uint8_t rhport) { + return _usbh_controller == rhport; +} + +bool tuh_rhport_reset_bus(uint8_t rhport, bool active) { + TU_VERIFY(tuh_rhport_is_active(rhport)); + if ( active ) { + hcd_port_reset(rhport); + } else { + hcd_port_reset_end(rhport); + } + return true; +} + +//--------------------------------------------------------------------+ +// PUBLIC API (Parameter Verification is required) +//--------------------------------------------------------------------+ + +bool tuh_configure(uint8_t rhport, uint32_t cfg_id, const void *cfg_param) { + if ( hcd_configure ) { + return hcd_configure(rhport, cfg_id, cfg_param); + } else { + return false; + } +} + +static void clear_device(usbh_device_t* dev) { tu_memclr(dev, sizeof(usbh_device_t)); memset(dev->itf2drv, TUSB_INDEX_INVALID_8, sizeof(dev->itf2drv)); // invalid mapping memset(dev->ep2drv , TUSB_INDEX_INVALID_8, sizeof(dev->ep2drv )); // invalid mapping } -bool tuh_inited(void) -{ +bool tuh_inited(void) { return _usbh_controller != TUSB_INDEX_INVALID_8; } -bool tuh_init(uint8_t controller_id) -{ +bool tuh_init(uint8_t controller_id) { // skip if already initialized if ( tuh_inited() ) return true; @@ -359,8 +365,7 @@ bool tuh_init(uint8_t controller_id) return true; } -bool tuh_task_event_ready(void) -{ +bool tuh_task_event_ready(void) { // Skip if stack is not initialized if ( !tuh_inited() ) return false; @@ -385,8 +390,7 @@ bool tuh_task_event_ready(void) } @endcode */ -void tuh_task_ext(uint32_t timeout_ms, bool in_isr) -{ +void tuh_task_ext(uint32_t timeout_ms, bool in_isr) { (void) in_isr; // not implemented yet // Skip if stack is not initialized @@ -403,8 +407,7 @@ void tuh_task_ext(uint32_t timeout_ms, bool in_isr) case HCD_EVENT_DEVICE_ATTACH: // due to the shared _usbh_ctrl_buf, we must complete enumerating // one device before enumerating another one. - if ( _dev0.enumerating ) - { + if ( _dev0.enumerating ) { TU_LOG_USBH("[%u:] USBH Defer Attach until current enumeration complete\r\n", event.rhport); bool is_empty = osal_queue_empty(_usbh_q); @@ -414,8 +417,7 @@ void tuh_task_ext(uint32_t timeout_ms, bool in_isr) // Exit if this is the only event in the queue, otherwise we may loop forever return; } - }else - { + }else { TU_LOG_USBH("[%u:] USBH DEVICE ATTACH\r\n", event.rhport); _dev0.enumerating = 1; enum_new_device(&event); @@ -428,8 +430,7 @@ void tuh_task_ext(uint32_t timeout_ms, bool in_isr) #if CFG_TUH_HUB // TODO remove - if ( event.connection.hub_addr != 0) - { + if ( event.connection.hub_addr != 0) { // done with hub, waiting for next data on status pipe (void) hub_edpt_status_xfer( event.connection.hub_addr ); } @@ -1230,6 +1231,12 @@ static void process_removing_device(uint8_t rhport, uint8_t hub_addr, uint8_t hu // one device before enumerating another one. //--------------------------------------------------------------------+ +enum { + ENUM_RESET_DELAY = 50, // USB specs: 10 to 50ms + ENUM_CONTACT_DEBOUNCING_DELAY = 450, // when plug/unplug a device, physical connection can be bouncing and may + // generate a series of attach/detach event. This delay wait for stable connection +}; + enum { ENUM_IDLE, ENUM_RESET_1, // 1st reset when attached @@ -1311,7 +1318,7 @@ static void process_enumeration(tuh_xfer_t* xfer) break; case ENUM_HUB_GET_STATUS_2: - osal_task_delay(RESET_DELAY); + osal_task_delay(ENUM_RESET_DELAY); TU_ASSERT( hub_port_get_status(_dev0.hub_addr, _dev0.hub_port, _usbh_ctrl_buf, process_enumeration, ENUM_HUB_CLEAR_RESET_2), ); break; @@ -1468,12 +1475,14 @@ static bool enum_new_device(hcd_event_t* event) if (_dev0.hub_addr == 0) { // connected/disconnected directly with roothub - // wait until device is stable TODO non blocking hcd_port_reset(_dev0.rhport); - osal_task_delay(RESET_DELAY); // TODO may not work for no-OS on MCU that require reset_end() since - // sof of controller may not running while resetting + osal_task_delay(ENUM_RESET_DELAY); // TODO may not work for no-OS on MCU that require reset_end() since + // sof of controller may not running while resetting hcd_port_reset_end( _dev0.rhport); + // wait until device connection is stable TODO non blocking + osal_task_delay(ENUM_CONTACT_DEBOUNCING_DELAY); + // device unplugged while delaying if ( !hcd_port_connect_status(_dev0.rhport) ) { enum_full_complete(); @@ -1489,6 +1498,7 @@ static bool enum_new_device(hcd_event_t* event) xfer.result = XFER_RESULT_SUCCESS; xfer.user_data = ENUM_ADDR0_DEVICE_DESC; + process_enumeration(&xfer); } @@ -1496,8 +1506,8 @@ static bool enum_new_device(hcd_event_t* event) else { // connected/disconnected via external hub - // wait until device is stable - osal_task_delay(RESET_DELAY); + // wait until device connection is stable TODO non blocking + osal_task_delay(ENUM_CONTACT_DEBOUNCING_DELAY); // ENUM_HUB_GET_STATUS //TU_ASSERT( hub_port_get_status(_dev0.hub_addr, _dev0.hub_port, _usbh_ctrl_buf, enum_hub_get_status0_complete, 0) ); @@ -1508,23 +1518,19 @@ static bool enum_new_device(hcd_event_t* event) return true; } -static uint8_t get_new_address(bool is_hub) -{ +static uint8_t get_new_address(bool is_hub) { uint8_t start; uint8_t end; - if ( is_hub ) - { + if ( is_hub ) { start = CFG_TUH_DEVICE_MAX; end = start + CFG_TUH_HUB; - }else - { + }else { start = 0; end = start + CFG_TUH_DEVICE_MAX; } - for (uint8_t idx = start; idx < end; idx++) - { + for (uint8_t idx = start; idx < end; idx++) { if (!_usbh_devices[idx].connected) return (idx+1); } diff --git a/src/host/usbh.h b/src/host/usbh.h index 0d56f40c9..684e8240e 100644 --- a/src/host/usbh.h +++ b/src/host/usbh.h @@ -47,8 +47,7 @@ typedef void (*tuh_xfer_cb_t)(tuh_xfer_t* xfer); // it is advised to initialize it using member name // Note2: not all field is available/meaningful in callback, // some info is not saved by usbh to save SRAM -struct tuh_xfer_s -{ +struct tuh_xfer_s { uint8_t daddr; uint8_t ep_addr; uint8_t TU_RESERVED; // reserved @@ -56,8 +55,7 @@ struct tuh_xfer_s uint32_t actual_len; // excluding setup packet - union - { + union { tusb_control_request_t const* setup; // setup packet pointer if control transfer uint32_t buflen; // expected length if not control transfer (not available in callback) }; @@ -70,15 +68,13 @@ struct tuh_xfer_s }; // Subject to change -typedef struct -{ +typedef struct { uint8_t daddr; tusb_desc_interface_t desc; } tuh_itf_info_t; // ConfigID for tuh_config() -enum -{ +enum { TUH_CFGID_RPI_PIO_USB_CONFIGURATION = OPT_MCU_RP2040 << 8 // cfg_param: pio_usb_configuration_t }; @@ -105,12 +101,12 @@ TU_ATTR_WEAK void tuh_umount_cb(uint8_t daddr); // Should be called before tuh_init() // - cfg_id : configure ID (TBD) // - cfg_param: configure data, structure depends on the ID -bool tuh_configure(uint8_t controller_id, uint32_t cfg_id, const void* cfg_param); +bool tuh_configure(uint8_t rhport, uint32_t cfg_id, const void* cfg_param); // Init host stack -bool tuh_init(uint8_t controller_id); +bool tuh_init(uint8_t rhport); -// Check if host stack is already initialized +// Check if host stack is already initialized with any roothub ports bool tuh_inited(void); // Task function should be called in main/rtos loop, extended version of tuh_task() @@ -120,8 +116,7 @@ void tuh_task_ext(uint32_t timeout_ms, bool in_isr); // Task function should be called in main/rtos loop TU_ATTR_ALWAYS_INLINE static inline -void tuh_task(void) -{ +void tuh_task(void) { tuh_task_ext(UINT32_MAX, false); } @@ -135,8 +130,20 @@ extern void hcd_int_handler(uint8_t rhport); // Interrupt handler, name alias to HCD #define tuh_int_handler hcd_int_handler +// Check if roothub port is initialized and active as a host +bool tuh_rhport_is_active(uint8_t rhport); + +// Assert/de-assert Bus Reset signal to roothub port. USB specs: it should last 10-50ms +bool tuh_rhport_reset_bus(uint8_t rhport, bool active); + +//--------------------------------------------------------------------+ +// Device API +//--------------------------------------------------------------------+ + +// Get VID/PID of device bool tuh_vid_pid_get(uint8_t daddr, uint16_t* vid, uint16_t* pid); +// Get speed of device tusb_speed_t tuh_speed_get(uint8_t daddr); // Check if device is connected and configured @@ -144,8 +151,7 @@ bool tuh_mounted(uint8_t daddr); // Check if device is suspended TU_ATTR_ALWAYS_INLINE static inline -bool tuh_suspended(uint8_t daddr) -{ +bool tuh_suspended(uint8_t daddr) { // TODO implement suspend & resume on host (void) daddr; return false; @@ -153,8 +159,7 @@ bool tuh_suspended(uint8_t daddr) // Check if device is ready to communicate with TU_ATTR_ALWAYS_INLINE static inline -bool tuh_ready(uint8_t daddr) -{ +bool tuh_ready(uint8_t daddr) { return tuh_mounted(daddr) && !tuh_suspended(daddr); } diff --git a/src/portable/chipidea/ci_hs/hcd_ci_hs.c b/src/portable/chipidea/ci_hs/hcd_ci_hs.c index 6ee91e18e..462cbd301 100644 --- a/src/portable/chipidea/ci_hs/hcd_ci_hs.c +++ b/src/portable/chipidea/ci_hs/hcd_ci_hs.c @@ -39,24 +39,27 @@ #include "ci_hs_type.h" #if CFG_TUSB_MCU == OPT_MCU_MIMXRT1XXX - #include "ci_hs_imxrt.h" - bool hcd_dcache_clean(void const* addr, uint32_t data_size) { - return imxrt_dcache_clean(addr, data_size); - } +#include "ci_hs_imxrt.h" - bool hcd_dcache_invalidate(void const* addr, uint32_t data_size) { - return imxrt_dcache_invalidate(addr, data_size); - } +bool hcd_dcache_clean(void const* addr, uint32_t data_size) { + return imxrt_dcache_clean(addr, data_size); +} + +bool hcd_dcache_invalidate(void const* addr, uint32_t data_size) { + return imxrt_dcache_invalidate(addr, data_size); +} - bool hcd_dcache_clean_invalidate(void const* addr, uint32_t data_size) { - return imxrt_dcache_clean_invalidate(addr, data_size); - } +bool hcd_dcache_clean_invalidate(void const* addr, uint32_t data_size) { + return imxrt_dcache_clean_invalidate(addr, data_size); +} #elif TU_CHECK_MCU(OPT_MCU_LPC18XX, OPT_MCU_LPC43XX) - #include "ci_hs_lpc18_43.h" + +#include "ci_hs_lpc18_43.h" + #else - #error "Unsupported MCUs" +#error "Unsupported MCUs" #endif //--------------------------------------------------------------------+ @@ -67,25 +70,25 @@ // Controller API //--------------------------------------------------------------------+ -bool hcd_init(uint8_t rhport) -{ - ci_hs_regs_t* hcd_reg = CI_HS_REG(rhport); +bool hcd_init(uint8_t rhport) { + ci_hs_regs_t *hcd_reg = CI_HS_REG(rhport); // Reset controller hcd_reg->USBCMD |= USBCMD_RESET; - while( hcd_reg->USBCMD & USBCMD_RESET ) {} + while ( hcd_reg->USBCMD & USBCMD_RESET ) {} // Set mode to device, must be set immediately after reset #if CFG_TUSB_MCU == OPT_MCU_LPC18XX || CFG_TUSB_MCU == OPT_MCU_LPC43XX // LPC18XX/43XX need to set VBUS Power Select to HIGH // RHPORT1 is fullspeed only (need external PHY for Highspeed) hcd_reg->USBMODE = USBMODE_CM_HOST | USBMODE_VBUS_POWER_SELECT; - if (rhport == 1) hcd_reg->PORTSC1 |= PORTSC1_FORCE_FULL_SPEED; + if ( rhport == 1 ) hcd_reg->PORTSC1 |= PORTSC1_FORCE_FULL_SPEED; #else hcd_reg->USBMODE = USBMODE_CM_HOST; #endif // FIXME force full speed, still have issue with Highspeed enumeration + // probably due to physical connection bouncing when plug/unplug // 1. Have issue when plug/unplug devices, maybe the port is not reset properly // 2. Also does not seems to detect disconnection hcd_reg->PORTSC1 |= PORTSC1_FORCE_FULL_SPEED; @@ -93,13 +96,11 @@ bool hcd_init(uint8_t rhport) return ehci_init(rhport, (uint32_t) &hcd_reg->CAPLENGTH, (uint32_t) &hcd_reg->USBCMD); } -void hcd_int_enable(uint8_t rhport) -{ +void hcd_int_enable(uint8_t rhport) { CI_HCD_INT_ENABLE(rhport); } -void hcd_int_disable(uint8_t rhport) -{ +void hcd_int_disable(uint8_t rhport) { CI_HCD_INT_DISABLE(rhport); } diff --git a/src/portable/ehci/ehci.c b/src/portable/ehci/ehci.c index 9be24c888..79811985c 100644 --- a/src/portable/ehci/ehci.c +++ b/src/portable/ehci/ehci.c @@ -188,6 +188,11 @@ void hcd_port_reset(uint8_t rhport) ehci_registers_t* regs = ehci_data.regs; + // skip if already in reset + if (regs->portsc_bm.port_reset) { + return; + } + // mask out Write-1-to-Clear bits uint32_t portsc = regs->portsc & ~EHCI_PORTSC_MASK_W1C; @@ -202,16 +207,18 @@ void hcd_port_reset(uint8_t rhport) void hcd_port_reset_end(uint8_t rhport) { (void) rhport; - -#if 0 // TODO check if this is necessary ehci_registers_t* regs = ehci_data.regs; + // skip if reset is already complete + if (!regs->portsc_bm.port_reset) { + return; + } + // mask out all change bits since they are Write 1 to clear - uint32_t portsc = regs->portsc & ~EHCI_PORTSC_MASK_CHANGE_ALL; - portsc &= ~(EHCI_PORTSC_MASK_PORT_RESET); + uint32_t portsc = regs->portsc & ~EHCI_PORTSC_MASK_W1C; + portsc &= ~EHCI_PORTSC_MASK_PORT_RESET; regs->portsc = portsc; -#endif } bool hcd_port_connect_status(uint8_t rhport) @@ -426,6 +433,11 @@ bool hcd_setup_send(uint8_t rhport, uint8_t dev_addr, uint8_t const setup_packet hcd_dcache_clean(setup_packet, 8); + // Control endpoint never be stalled. Skip reset Data Toggle since it is fixed per stage + if (qhd->qtd_overlay.halted) { + qhd->qtd_overlay.halted = false; + } + // attach TD to QHD -> start transferring qhd_attach_qtd(qhd, td); @@ -662,7 +674,7 @@ void hcd_int_handler(uint8_t rhport) if (int_status & EHCI_INT_MASK_PORT_CHANGE) { // Including: Force port resume, over-current change, enable/disable change and connect status change. uint32_t const port_status = regs->portsc & EHCI_PORTSC_MASK_W1C; - print_portsc(regs); + // print_portsc(regs); if (regs->portsc_bm.connect_status_change) { port_connect_status_change_isr(rhport); -- cgit v1.3.1 From 9d942967414d7b95f3a132c284ef83f386a0c467 Mon Sep 17 00:00:00 2001 From: rppicomidi Date: Mon, 14 Aug 2023 15:38:48 -0700 Subject: fix issue 2188: support usbh_app_driver_get_cb() --- README.rst | 2 ++ src/host/usbh.c | 86 ++++++++++++++++++++++++++++++++------------- src/host/usbh_classdriver.h | 8 +++++ 3 files changed, 72 insertions(+), 24 deletions(-) (limited to 'src/host') diff --git a/README.rst b/README.rst index 78e8d87b0..d72cdb149 100644 --- a/README.rst +++ b/README.rst @@ -89,6 +89,8 @@ Host Stack - Mass Storage Class (MSC) - Hub with multiple-level support +Similar to the Device Stack, if you have a special requirement, `usbh_app_driver_get_cb()` can be used to write your own class driver without modifying the stack. + TypeC PD Stack ============== diff --git a/src/host/usbh.c b/src/host/usbh.c index cc7e38b45..af8142be3 100644 --- a/src/host/usbh.c +++ b/src/host/usbh.c @@ -180,7 +180,7 @@ static usbh_class_driver_t const usbh_class_drivers[] = #endif }; -enum { USBH_CLASS_DRIVER_COUNT = TU_ARRAY_SIZE(usbh_class_drivers) }; +enum { USBH_BUILTIN_DRIVER_COUNT = TU_ARRAY_SIZE(usbh_class_drivers) }; enum { CONFIG_NUM = 1 }; // default to use configuration 1 @@ -246,6 +246,21 @@ static void process_removing_device(uint8_t rhport, uint8_t hub_addr, uint8_t hu static bool usbh_edpt_control_open(uint8_t dev_addr, uint8_t max_packet_size); static bool usbh_control_xfer_cb (uint8_t daddr, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes); +// Additional class drivers implemented by application +tu_static usbh_class_driver_t const * _app_driver = NULL; +tu_static uint8_t _app_driver_count = 0; +tu_static uint8_t _total_driver_count = USBH_BUILTIN_DRIVER_COUNT; + +static usbh_class_driver_t const * usbh_get_driver(uint8_t drv_id) +{ + usbh_class_driver_t const * driver = NULL; + if ( drv_id < _app_driver_count ) + driver = &_app_driver[drv_id]; + else if ( drv_id < _total_driver_count ) + driver = &usbh_class_drivers[drv_id - _app_driver_count]; + return driver; +} + #if CFG_TUSB_OS == OPT_OS_NONE // TODO rework time-related function later // weak and overridable @@ -339,6 +354,12 @@ bool tuh_init(uint8_t controller_id) { _usbh_mutex = osal_mutex_create(&_usbh_mutexdef); TU_ASSERT(_usbh_mutex); #endif + // Get application driver if available + if ( usbh_app_driver_get_cb ) + { + _app_driver = usbh_app_driver_get_cb(&_app_driver_count); + _total_driver_count = USBH_BUILTIN_DRIVER_COUNT + _app_driver_count; + } // Device tu_memclr(&_dev0, sizeof(_dev0)); @@ -351,10 +372,14 @@ bool tuh_init(uint8_t controller_id) { } // Class drivers - for (uint8_t drv_id = 0; drv_id < USBH_CLASS_DRIVER_COUNT; drv_id++) + for (uint8_t drv_id = 0; drv_id < _total_driver_count; drv_id++) { - TU_LOG_USBH("%s init\r\n", usbh_class_drivers[drv_id].name); - usbh_class_drivers[drv_id].init(); + usbh_class_driver_t const * driver = usbh_get_driver(drv_id); + if ( driver ) + { + TU_LOG_USBH("%s init\r\n", driver->name); + driver->init(); + } } _usbh_controller = controller_id;; @@ -482,12 +507,16 @@ void tuh_task_ext(uint32_t timeout_ms, bool in_isr) { }else #endif { - uint8_t const drv_id = dev->ep2drv[epnum][ep_dir]; - if ( drv_id < USBH_CLASS_DRIVER_COUNT ) { - TU_LOG_USBH("%s xfer callback\r\n", usbh_class_drivers[drv_id].name); - usbh_class_drivers[drv_id].xfer_cb(event.dev_addr, ep_addr, (xfer_result_t) event.xfer_complete.result, + uint8_t drv_id = dev->ep2drv[epnum][ep_dir]; + usbh_class_driver_t const * driver = usbh_get_driver(drv_id); + if ( driver ) + { + TU_LOG_USBH("%s xfer callback\r\n", driver->name); + driver->xfer_cb(event.dev_addr, ep_addr, (xfer_result_t) event.xfer_complete.result, event.xfer_complete.len); - } else { + } + else + { // no driver/callback responsible for this transfer TU_ASSERT(false,); } @@ -1183,17 +1212,20 @@ static void process_removing_device(uint8_t rhport, uint8_t hub_addr, uint8_t hu uint8_t nop_count = 0; #endif - for (uint8_t dev_id = 0; dev_id < TOTAL_DEVICES; dev_id++) { + for (uint8_t dev_id = 0; dev_id < TOTAL_DEVICES; dev_id++) + { usbh_device_t *dev = &_usbh_devices[dev_id]; uint8_t const daddr = dev_id + 1; // hub_addr = 0 means roothub, hub_port = 0 means all devices of downstream hub if (dev->rhport == rhport && dev->connected && (hub_addr == 0 || dev->hub_addr == hub_addr) && - (hub_port == 0 || dev->hub_port == hub_port)) { + (hub_port == 0 || dev->hub_port == hub_port)) + { TU_LOG_USBH("Device unplugged address = %u\r\n", daddr); - if (is_hub_addr(daddr)) { + if (is_hub_addr(daddr)) + { TU_LOG(CFG_TUH_LOG_LEVEL, " is a HUB device %u\r\n", daddr); // Submit removed event If the device itself is a hub (un-rolled recursive) @@ -1211,10 +1243,14 @@ static void process_removing_device(uint8_t rhport, uint8_t hub_addr, uint8_t hu } // Close class driver - for (uint8_t drv_id = 0; drv_id < USBH_CLASS_DRIVER_COUNT; drv_id++) { - usbh_class_drivers[drv_id].close(daddr); + for (uint8_t drv_id = 0; drv_id < _total_driver_count; drv_id++) + { + usbh_class_driver_t const * driver = usbh_get_driver(drv_id); + if ( driver ) + { + driver->close(daddr); + } } - hcd_device_close(rhport, daddr); clear_device(dev); // abort on-going control xfer if any @@ -1643,11 +1679,12 @@ static bool _parse_configuration_descriptor(uint8_t dev_addr, tusb_desc_configur TU_ASSERT(drv_len >= sizeof(tusb_desc_interface_t)); // Find driver for this interface - for (uint8_t drv_id = 0; drv_id < USBH_CLASS_DRIVER_COUNT; drv_id++) + uint8_t drv_id = 0; + for (; drv_id < _total_driver_count; drv_id++) { - usbh_class_driver_t const * driver = &usbh_class_drivers[drv_id]; + usbh_class_driver_t const * driver = usbh_get_driver(drv_id); - if ( driver->open(dev->rhport, dev_addr, desc_itf, drv_len) ) + if (driver && driver->open(dev->rhport, dev_addr, desc_itf, drv_len) ) { // open successfully TU_LOG_USBH(" %s opened\r\n", driver->name); @@ -1668,11 +1705,12 @@ static bool _parse_configuration_descriptor(uint8_t dev_addr, tusb_desc_configur break; // exit driver find loop } - if( drv_id >= USBH_CLASS_DRIVER_COUNT ) - { - TU_LOG(CFG_TUH_LOG_LEVEL, "Interface %u: class = %u subclass = %u protocol = %u is not supported\r\n", - desc_itf->bInterfaceNumber, desc_itf->bInterfaceClass, desc_itf->bInterfaceSubClass, desc_itf->bInterfaceProtocol); - } + } + + if( drv_id >= _total_driver_count ) + { + TU_LOG(CFG_TUH_LOG_LEVEL, "Interface %u: class = %u subclass = %u protocol = %u is not supported\r\n", + desc_itf->bInterfaceNumber, desc_itf->bInterfaceClass, desc_itf->bInterfaceSubClass, desc_itf->bInterfaceProtocol); } // next Interface or IAD descriptor @@ -1694,7 +1732,7 @@ void usbh_driver_set_config_complete(uint8_t dev_addr, uint8_t itf_num) uint8_t const drv_id = dev->itf2drv[itf_num]; if (drv_id != TUSB_INDEX_INVALID_8) { - usbh_class_driver_t const * driver = &usbh_class_drivers[drv_id]; + usbh_class_driver_t const * driver = usbh_get_driver(drv_id); TU_LOG_USBH("%s set config: itf = %u\r\n", driver->name, itf_num); driver->set_config(dev_addr, itf_num); break; diff --git a/src/host/usbh_classdriver.h b/src/host/usbh_classdriver.h index 308b4418a..7443b2d90 100644 --- a/src/host/usbh_classdriver.h +++ b/src/host/usbh_classdriver.h @@ -96,6 +96,14 @@ bool usbh_edpt_release(uint8_t dev_addr, uint8_t ep_addr); // Check if endpoint transferring is complete bool usbh_edpt_busy(uint8_t dev_addr, uint8_t ep_addr); +//--------------------------------------------------------------------+ +// USBH application additional driver API +//--------------------------------------------------------------------+ +// Invoked when initializing host stack to get additional class drivers. +// Can optionally implemented by application to extend/overwrite class driver support. +// Note: The drivers array must be accessible at all time when stack is active +usbh_class_driver_t const* usbh_app_driver_get_cb(uint8_t* driver_count) TU_ATTR_WEAK; + #ifdef __cplusplus } #endif -- cgit v1.3.1 From 1b33a315365184a74a8b5bbce5fdbdfc4dfe6f69 Mon Sep 17 00:00:00 2001 From: hathach Date: Tue, 15 Aug 2023 22:51:21 +0700 Subject: more minor clean up - also rename usbh_classdriver.h to usbh_pvt.h to consitent with usbd --- src/class/cdc/cdc_host.c | 2 +- src/class/hid/hid_host.c | 2 +- src/class/msc/msc_host.c | 2 +- src/device/usbd.c | 31 +++++-------- src/device/usbd_pvt.h | 2 +- src/host/hub.c | 2 +- src/host/usbh.c | 84 ++++++++++++++++----------------- src/host/usbh_classdriver.h | 111 -------------------------------------------- src/host/usbh_pvt.h | 108 ++++++++++++++++++++++++++++++++++++++++++ src/tusb.c | 2 +- 10 files changed, 164 insertions(+), 182 deletions(-) delete mode 100644 src/host/usbh_classdriver.h create mode 100644 src/host/usbh_pvt.h (limited to 'src/host') diff --git a/src/class/cdc/cdc_host.c b/src/class/cdc/cdc_host.c index 40ebd331d..53e15710e 100644 --- a/src/class/cdc/cdc_host.c +++ b/src/class/cdc/cdc_host.c @@ -29,7 +29,7 @@ #if (CFG_TUH_ENABLED && CFG_TUH_CDC) #include "host/usbh.h" -#include "host/usbh_classdriver.h" +#include "host/usbh_pvt.h" #include "cdc_host.h" diff --git a/src/class/hid/hid_host.c b/src/class/hid/hid_host.c index 4253170d4..a3551c85a 100644 --- a/src/class/hid/hid_host.c +++ b/src/class/hid/hid_host.c @@ -29,7 +29,7 @@ #if (CFG_TUH_ENABLED && CFG_TUH_HID) #include "host/usbh.h" -#include "host/usbh_classdriver.h" +#include "host/usbh_pvt.h" #include "hid_host.h" diff --git a/src/class/msc/msc_host.c b/src/class/msc/msc_host.c index 90a58d3d0..da264142c 100644 --- a/src/class/msc/msc_host.c +++ b/src/class/msc/msc_host.c @@ -29,7 +29,7 @@ #if CFG_TUH_ENABLED && CFG_TUH_MSC #include "host/usbh.h" -#include "host/usbh_classdriver.h" +#include "host/usbh_pvt.h" #include "msc_host.h" diff --git a/src/device/usbd.c b/src/device/usbd.c index 156b92ce1..f0d9fba52 100644 --- a/src/device/usbd.c +++ b/src/device/usbd.c @@ -238,34 +238,25 @@ enum { BUILTIN_DRIVER_COUNT = TU_ARRAY_SIZE(_usbd_driver) }; tu_static usbd_class_driver_t const * _app_driver = NULL; tu_static uint8_t _app_driver_count = 0; +#define TOTAL_DRIVER_COUNT (_app_driver_count + BUILTIN_DRIVER_COUNT) + // virtually joins built-in and application drivers together. // Application is positioned first to allow overwriting built-in ones. static inline usbd_class_driver_t const * get_driver(uint8_t drvid) { - // Application drivers - if ( usbd_app_driver_get_cb ) - { - if ( drvid < _app_driver_count ) return &_app_driver[drvid]; - drvid -= _app_driver_count; - } - - // when there is no built-in drivers BUILTIN_DRIVER_COUNT = 0 will cause -Wtype-limits warning -#ifdef __GNUC__ -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wtype-limits" -#endif - - // Built-in drivers - if (drvid < BUILTIN_DRIVER_COUNT) return &_usbd_driver[drvid]; + usbd_class_driver_t const * driver = NULL; -#ifdef __GNUC__ -#pragma GCC diagnostic pop -#endif + if ( drvid < _app_driver_count ) { + // Application drivers + driver = &_app_driver[drvid]; + } else if ( drvid < TOTAL_DRIVER_COUNT && BUILTIN_DRIVER_COUNT > 0 ){ + driver = &_usbd_driver[drvid - _app_driver_count]; + } - return NULL; + return driver; } -#define TOTAL_DRIVER_COUNT (_app_driver_count + BUILTIN_DRIVER_COUNT) + //--------------------------------------------------------------------+ // DCD Event diff --git a/src/device/usbd_pvt.h b/src/device/usbd_pvt.h index 940b2858b..16585167f 100644 --- a/src/device/usbd_pvt.h +++ b/src/device/usbd_pvt.h @@ -59,7 +59,7 @@ typedef struct } usbd_class_driver_t; // Invoked when initializing device stack to get additional class drivers. -// Can optionally implemented by application to extend/overwrite class driver support. +// Can be implemented by application to extend/overwrite class driver support. // Note: The drivers array must be accessible at all time when stack is active usbd_class_driver_t const* usbd_app_driver_get_cb(uint8_t* driver_count) TU_ATTR_WEAK; diff --git a/src/host/hub.c b/src/host/hub.c index ec30eb96a..32f5e0ac7 100644 --- a/src/host/hub.c +++ b/src/host/hub.c @@ -30,7 +30,7 @@ #include "hcd.h" #include "usbh.h" -#include "usbh_classdriver.h" +#include "usbh_pvt.h" #include "hub.h" // Debug level, TUSB_CFG_DEBUG must be at least this level for debug message diff --git a/src/host/usbh.c b/src/host/usbh.c index af8142be3..739157b56 100644 --- a/src/host/usbh.c +++ b/src/host/usbh.c @@ -30,7 +30,7 @@ #include "host/hcd.h" #include "tusb.h" -#include "host/usbh_classdriver.h" +#include "host/usbh_pvt.h" #include "hub.h" //--------------------------------------------------------------------+ @@ -183,6 +183,23 @@ static usbh_class_driver_t const usbh_class_drivers[] = enum { USBH_BUILTIN_DRIVER_COUNT = TU_ARRAY_SIZE(usbh_class_drivers) }; enum { CONFIG_NUM = 1 }; // default to use configuration 1 +// Additional class drivers implemented by application +tu_static usbh_class_driver_t const * _app_driver = NULL; +tu_static uint8_t _app_driver_count = 0; + +#define TOTAL_DRIVER_COUNT (_app_driver_count + USBH_BUILTIN_DRIVER_COUNT) + +static inline usbh_class_driver_t const *get_driver(uint8_t drv_id) { + usbh_class_driver_t const *driver = NULL; + + if ( drv_id < _app_driver_count ) { + driver = &_app_driver[drv_id]; + } else if ( drv_id < TOTAL_DRIVER_COUNT && USBH_BUILTIN_DRIVER_COUNT > 0) { + driver = &usbh_class_drivers[drv_id - _app_driver_count]; + } + + return driver; +} //--------------------------------------------------------------------+ // INTERNAL OBJECT & FUNCTION DECLARATION @@ -246,21 +263,6 @@ static void process_removing_device(uint8_t rhport, uint8_t hub_addr, uint8_t hu static bool usbh_edpt_control_open(uint8_t dev_addr, uint8_t max_packet_size); static bool usbh_control_xfer_cb (uint8_t daddr, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes); -// Additional class drivers implemented by application -tu_static usbh_class_driver_t const * _app_driver = NULL; -tu_static uint8_t _app_driver_count = 0; -tu_static uint8_t _total_driver_count = USBH_BUILTIN_DRIVER_COUNT; - -static usbh_class_driver_t const * usbh_get_driver(uint8_t drv_id) -{ - usbh_class_driver_t const * driver = NULL; - if ( drv_id < _app_driver_count ) - driver = &_app_driver[drv_id]; - else if ( drv_id < _total_driver_count ) - driver = &usbh_class_drivers[drv_id - _app_driver_count]; - return driver; -} - #if CFG_TUSB_OS == OPT_OS_NONE // TODO rework time-related function later // weak and overridable @@ -354,11 +356,10 @@ bool tuh_init(uint8_t controller_id) { _usbh_mutex = osal_mutex_create(&_usbh_mutexdef); TU_ASSERT(_usbh_mutex); #endif + // Get application driver if available - if ( usbh_app_driver_get_cb ) - { + if ( usbh_app_driver_get_cb ) { _app_driver = usbh_app_driver_get_cb(&_app_driver_count); - _total_driver_count = USBH_BUILTIN_DRIVER_COUNT + _app_driver_count; } // Device @@ -372,9 +373,9 @@ bool tuh_init(uint8_t controller_id) { } // Class drivers - for (uint8_t drv_id = 0; drv_id < _total_driver_count; drv_id++) + for (uint8_t drv_id = 0; drv_id < TOTAL_DRIVER_COUNT; drv_id++) { - usbh_class_driver_t const * driver = usbh_get_driver(drv_id); + usbh_class_driver_t const * driver = get_driver(drv_id); if ( driver ) { TU_LOG_USBH("%s init\r\n", driver->name); @@ -508,12 +509,12 @@ void tuh_task_ext(uint32_t timeout_ms, bool in_isr) { #endif { uint8_t drv_id = dev->ep2drv[epnum][ep_dir]; - usbh_class_driver_t const * driver = usbh_get_driver(drv_id); + usbh_class_driver_t const * driver = get_driver(drv_id); if ( driver ) { TU_LOG_USBH("%s xfer callback\r\n", driver->name); driver->xfer_cb(event.dev_addr, ep_addr, (xfer_result_t) event.xfer_complete.result, - event.xfer_complete.len); + event.xfer_complete.len); } else { @@ -1220,12 +1221,10 @@ static void process_removing_device(uint8_t rhport, uint8_t hub_addr, uint8_t hu // hub_addr = 0 means roothub, hub_port = 0 means all devices of downstream hub if (dev->rhport == rhport && dev->connected && (hub_addr == 0 || dev->hub_addr == hub_addr) && - (hub_port == 0 || dev->hub_port == hub_port)) - { + (hub_port == 0 || dev->hub_port == hub_port)) { TU_LOG_USBH("Device unplugged address = %u\r\n", daddr); - if (is_hub_addr(daddr)) - { + if (is_hub_addr(daddr)) { TU_LOG(CFG_TUH_LOG_LEVEL, " is a HUB device %u\r\n", daddr); // Submit removed event If the device itself is a hub (un-rolled recursive) @@ -1243,14 +1242,11 @@ static void process_removing_device(uint8_t rhport, uint8_t hub_addr, uint8_t hu } // Close class driver - for (uint8_t drv_id = 0; drv_id < _total_driver_count; drv_id++) - { - usbh_class_driver_t const * driver = usbh_get_driver(drv_id); - if ( driver ) - { - driver->close(daddr); - } + 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 ) driver->close(daddr); } + hcd_device_close(rhport, daddr); clear_device(dev); // abort on-going control xfer if any @@ -1679,10 +1675,9 @@ static bool _parse_configuration_descriptor(uint8_t dev_addr, tusb_desc_configur TU_ASSERT(drv_len >= sizeof(tusb_desc_interface_t)); // Find driver for this interface - uint8_t drv_id = 0; - for (; drv_id < _total_driver_count; drv_id++) + for (uint8_t drv_id = 0; drv_id < TOTAL_DRIVER_COUNT; drv_id++) { - usbh_class_driver_t const * driver = usbh_get_driver(drv_id); + usbh_class_driver_t const * driver = get_driver(drv_id); if (driver && driver->open(dev->rhport, dev_addr, desc_itf, drv_len) ) { @@ -1705,12 +1700,11 @@ static bool _parse_configuration_descriptor(uint8_t dev_addr, tusb_desc_configur break; // exit driver find loop } - } - - if( drv_id >= _total_driver_count ) - { - TU_LOG(CFG_TUH_LOG_LEVEL, "Interface %u: class = %u subclass = %u protocol = %u is not supported\r\n", - desc_itf->bInterfaceNumber, desc_itf->bInterfaceClass, desc_itf->bInterfaceSubClass, desc_itf->bInterfaceProtocol); + if ( drv_id == TOTAL_DRIVER_COUNT - 1 ) + { + TU_LOG(CFG_TUH_LOG_LEVEL, "[%u:%u] Interface %u: class = %u subclass = %u protocol = %u is not supported\r\n", + dev->rhport, dev_addr, desc_itf->bInterfaceNumber, desc_itf->bInterfaceClass, desc_itf->bInterfaceSubClass, desc_itf->bInterfaceProtocol); + } } // next Interface or IAD descriptor @@ -1730,9 +1724,9 @@ void usbh_driver_set_config_complete(uint8_t dev_addr, uint8_t itf_num) // IAD binding interface such as CDCs should return itf_num + 1 when complete // with usbh_driver_set_config_complete() uint8_t const drv_id = dev->itf2drv[itf_num]; - if (drv_id != TUSB_INDEX_INVALID_8) + usbh_class_driver_t const * driver = get_driver(drv_id); + if (driver) { - usbh_class_driver_t const * driver = usbh_get_driver(drv_id); TU_LOG_USBH("%s set config: itf = %u\r\n", driver->name, itf_num); driver->set_config(dev_addr, itf_num); break; diff --git a/src/host/usbh_classdriver.h b/src/host/usbh_classdriver.h deleted file mode 100644 index 7443b2d90..000000000 --- a/src/host/usbh_classdriver.h +++ /dev/null @@ -1,111 +0,0 @@ -/* - * The MIT License (MIT) - * - * Copyright (c) 2021, Ha Thach (tinyusb.org) - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - * This file is part of the TinyUSB stack. - */ - -#ifndef _TUSB_USBH_CLASSDRIVER_H_ -#define _TUSB_USBH_CLASSDRIVER_H_ - -#include "osal/osal.h" -#include "common/tusb_fifo.h" -#include "common/tusb_private.h" - -#ifdef __cplusplus - extern "C" { -#endif - -// Level where CFG_TUSB_DEBUG must be at least for USBH is logged -#ifndef CFG_TUH_LOG_LEVEL - #define CFG_TUH_LOG_LEVEL 2 -#endif - -#define TU_LOG_USBH(...) TU_LOG(CFG_TUH_LOG_LEVEL, __VA_ARGS__) - -enum { - USBH_EPSIZE_BULK_MAX = (TUH_OPT_HIGH_SPEED ? TUSB_EPSIZE_BULK_HS : TUSB_EPSIZE_BULK_FS) -}; - -//--------------------------------------------------------------------+ -// Class Driver API -//--------------------------------------------------------------------+ - -typedef struct { - #if CFG_TUSB_DEBUG >= 2 - char const* name; - #endif - - void (* const init )(void); - bool (* const open )(uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const * itf_desc, uint16_t max_len); - bool (* const set_config )(uint8_t dev_addr, uint8_t itf_num); - bool (* const xfer_cb )(uint8_t dev_addr, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes); - void (* const close )(uint8_t dev_addr); -} usbh_class_driver_t; - -// Call by class driver to tell USBH that it has complete the enumeration -void usbh_driver_set_config_complete(uint8_t dev_addr, uint8_t itf_num); - -uint8_t usbh_get_rhport(uint8_t dev_addr); - -uint8_t* usbh_get_enum_buf(void); - -void usbh_int_set(bool enabled); - -//--------------------------------------------------------------------+ -// USBH Endpoint API -//--------------------------------------------------------------------+ - -// Submit a usb transfer with callback support, require CFG_TUH_API_EDPT_XFER -bool usbh_edpt_xfer_with_callback(uint8_t dev_addr, uint8_t ep_addr, uint8_t * buffer, uint16_t total_bytes, - tuh_xfer_cb_t complete_cb, uintptr_t user_data); - -TU_ATTR_ALWAYS_INLINE -static inline bool usbh_edpt_xfer(uint8_t dev_addr, uint8_t ep_addr, uint8_t * buffer, uint16_t total_bytes) -{ - return usbh_edpt_xfer_with_callback(dev_addr, ep_addr, buffer, total_bytes, NULL, 0); -} - - -// Claim an endpoint before submitting a transfer. -// If caller does not make any transfer, it must release endpoint for others. -bool usbh_edpt_claim(uint8_t dev_addr, uint8_t ep_addr); - -// Release claimed endpoint without submitting a transfer -bool usbh_edpt_release(uint8_t dev_addr, uint8_t ep_addr); - -// Check if endpoint transferring is complete -bool usbh_edpt_busy(uint8_t dev_addr, uint8_t ep_addr); - -//--------------------------------------------------------------------+ -// USBH application additional driver API -//--------------------------------------------------------------------+ -// Invoked when initializing host stack to get additional class drivers. -// Can optionally implemented by application to extend/overwrite class driver support. -// Note: The drivers array must be accessible at all time when stack is active -usbh_class_driver_t const* usbh_app_driver_get_cb(uint8_t* driver_count) TU_ATTR_WEAK; - -#ifdef __cplusplus - } -#endif - -#endif diff --git a/src/host/usbh_pvt.h b/src/host/usbh_pvt.h new file mode 100644 index 000000000..0b58a91bc --- /dev/null +++ b/src/host/usbh_pvt.h @@ -0,0 +1,108 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2021, Ha Thach (tinyusb.org) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + +#ifndef _TUSB_USBH_CLASSDRIVER_H_ +#define _TUSB_USBH_CLASSDRIVER_H_ + +#include "osal/osal.h" +#include "common/tusb_fifo.h" +#include "common/tusb_private.h" + +#ifdef __cplusplus + extern "C" { +#endif + +// Level where CFG_TUSB_DEBUG must be at least for USBH is logged +#ifndef CFG_TUH_LOG_LEVEL + #define CFG_TUH_LOG_LEVEL 2 +#endif + +#define TU_LOG_USBH(...) TU_LOG(CFG_TUH_LOG_LEVEL, __VA_ARGS__) + +enum { + USBH_EPSIZE_BULK_MAX = (TUH_OPT_HIGH_SPEED ? TUSB_EPSIZE_BULK_HS : TUSB_EPSIZE_BULK_FS) +}; + +//--------------------------------------------------------------------+ +// Class Driver API +//--------------------------------------------------------------------+ + +typedef struct { + #if CFG_TUSB_DEBUG >= 2 + char const* name; + #endif + + void (* const init )(void); + bool (* const open )(uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const * itf_desc, uint16_t max_len); + bool (* const set_config )(uint8_t dev_addr, uint8_t itf_num); + bool (* const xfer_cb )(uint8_t dev_addr, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes); + void (* const close )(uint8_t dev_addr); +} usbh_class_driver_t; + +// Invoked when initializing host stack to get additional class drivers. +// Can be implemented by application to extend/overwrite class driver support. +// Note: The drivers array must be accessible at all time when stack is active +usbh_class_driver_t const* usbh_app_driver_get_cb(uint8_t* driver_count) TU_ATTR_WEAK; + +// Call by class driver to tell USBH that it has complete the enumeration +void usbh_driver_set_config_complete(uint8_t dev_addr, uint8_t itf_num); + +uint8_t usbh_get_rhport(uint8_t dev_addr); + +uint8_t* usbh_get_enum_buf(void); + +void usbh_int_set(bool enabled); + +//--------------------------------------------------------------------+ +// USBH Endpoint API +//--------------------------------------------------------------------+ + +// Submit a usb transfer with callback support, require CFG_TUH_API_EDPT_XFER +bool usbh_edpt_xfer_with_callback(uint8_t dev_addr, uint8_t ep_addr, uint8_t * buffer, uint16_t total_bytes, + tuh_xfer_cb_t complete_cb, uintptr_t user_data); + +TU_ATTR_ALWAYS_INLINE +static inline bool usbh_edpt_xfer(uint8_t dev_addr, uint8_t ep_addr, uint8_t * buffer, uint16_t total_bytes) +{ + return usbh_edpt_xfer_with_callback(dev_addr, ep_addr, buffer, total_bytes, NULL, 0); +} + + +// Claim an endpoint before submitting a transfer. +// If caller does not make any transfer, it must release endpoint for others. +bool usbh_edpt_claim(uint8_t dev_addr, uint8_t ep_addr); + +// Release claimed endpoint without submitting a transfer +bool usbh_edpt_release(uint8_t dev_addr, uint8_t ep_addr); + +// Check if endpoint transferring is complete +bool usbh_edpt_busy(uint8_t dev_addr, uint8_t ep_addr); + +#ifdef __cplusplus + } +#endif + +#endif diff --git a/src/tusb.c b/src/tusb.c index 465b608b0..7b0a669a0 100644 --- a/src/tusb.c +++ b/src/tusb.c @@ -36,7 +36,7 @@ #endif #if CFG_TUH_ENABLED -#include "host/usbh_classdriver.h" +#include "host/usbh_pvt.h" #endif //--------------------------------------------------------------------+ -- cgit v1.3.1 From 67a374d932cbe14bf1651bdd6fea82c2e2ecfa10 Mon Sep 17 00:00:00 2001 From: hathach Date: Tue, 15 Aug 2023 22:57:05 +0700 Subject: more rename --- src/host/usbh.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src/host') diff --git a/src/host/usbh.c b/src/host/usbh.c index 739157b56..7cdcbda5e 100644 --- a/src/host/usbh.c +++ b/src/host/usbh.c @@ -180,21 +180,21 @@ static usbh_class_driver_t const usbh_class_drivers[] = #endif }; -enum { USBH_BUILTIN_DRIVER_COUNT = TU_ARRAY_SIZE(usbh_class_drivers) }; +enum { BUILTIN_DRIVER_COUNT = TU_ARRAY_SIZE(usbh_class_drivers) }; enum { CONFIG_NUM = 1 }; // default to use configuration 1 // Additional class drivers implemented by application tu_static usbh_class_driver_t const * _app_driver = NULL; tu_static uint8_t _app_driver_count = 0; -#define TOTAL_DRIVER_COUNT (_app_driver_count + USBH_BUILTIN_DRIVER_COUNT) +#define TOTAL_DRIVER_COUNT (_app_driver_count + BUILTIN_DRIVER_COUNT) static inline usbh_class_driver_t const *get_driver(uint8_t drv_id) { usbh_class_driver_t const *driver = NULL; if ( drv_id < _app_driver_count ) { driver = &_app_driver[drv_id]; - } else if ( drv_id < TOTAL_DRIVER_COUNT && USBH_BUILTIN_DRIVER_COUNT > 0) { + } else if ( drv_id < TOTAL_DRIVER_COUNT && BUILTIN_DRIVER_COUNT > 0) { driver = &usbh_class_drivers[drv_id - _app_driver_count]; } -- cgit v1.3.1 From 0109ffbdcb22a358ecbc1476fbfb4e370e5bb4cc Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 16 Aug 2023 14:31:14 +0700 Subject: fix abort transfer does not release endpoint, also reset state if it is control transfer --- src/host/usbh.c | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) (limited to 'src/host') diff --git a/src/host/usbh.c b/src/host/usbh.c index 7cdcbda5e..5423df669 100644 --- a/src/host/usbh.c +++ b/src/host/usbh.c @@ -738,19 +738,27 @@ bool tuh_edpt_abort_xfer(uint8_t daddr, uint8_t ep_addr) { usbh_device_t* dev = get_device(daddr); TU_VERIFY(dev); + TU_LOG_USBH("[%u] Aborted transfer on EP %02X\r\n", daddr, ep_addr); + uint8_t const epnum = tu_edpt_number(ep_addr); uint8_t const dir = tu_edpt_dir(ep_addr); - // skip if not busy - TU_VERIFY(dev->ep_status[epnum][dir].busy); - - bool const ret = hcd_edpt_abort_xfer(dev->rhport, daddr, ep_addr); - if (ret) { - // mark as ready if transfer is aborted + if ( epnum == 0 ) { + // control transfer: only 1 control at a time, check if we are aborting the current one + TU_VERIFY(daddr == _ctrl_xfer.daddr && _ctrl_xfer.stage != CONTROL_STAGE_IDLE); + TU_VERIFY(hcd_edpt_abort_xfer(dev->rhport, daddr, ep_addr)); + // reset control transfer state to idle + _set_control_xfer_stage(CONTROL_STAGE_IDLE); + } else { + // non-control skip if not busy + TU_VERIFY(dev->ep_status[epnum][dir].busy); + TU_VERIFY(hcd_edpt_abort_xfer(dev->rhport, daddr, ep_addr)); + // mark as ready and release endpoint if transfer is aborted dev->ep_status[epnum][dir].busy = false; + usbh_edpt_release(daddr, ep_addr); } - return ret; + return true; } //--------------------------------------------------------------------+ -- cgit v1.3.1 From 9257a0f562a1cb939a902e7c41de5032b0f7de19 Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 18 Aug 2023 12:48:12 +0700 Subject: - update nrf52 bsp for cmake - add empty tuh_int_handler/tud_int_handler if corresponidng stack not enabled - add hcd_template.c --- hw/bsp/nrf/boards/adafruit_clue/board.cmake | 5 + hw/bsp/nrf/boards/arduino_nano33_ble/board.cmake | 5 + .../boards/circuitplayground_bluefruit/board.cmake | 5 + .../boards/feather_nrf52840_express/board.cmake | 6 + .../nrf/boards/feather_nrf52840_sense/board.cmake | 5 + hw/bsp/nrf/boards/itsybitsy_nrf52840/board.cmake | 5 + hw/bsp/nrf/boards/nrf52840_mdk_dongle/board.cmake | 5 + hw/bsp/nrf/boards/pca10056/board.cmake | 3 - hw/bsp/nrf/boards/pca10059/board.cmake | 5 + hw/bsp/nrf/boards/pca10095/board.cmake | 4 - hw/bsp/nrf/boards/pca10100/board.cmake | 5 + hw/bsp/nrf/boards/raytac_mdbt50q_rx/board.cmake | 5 + hw/bsp/nrf/family.cmake | 14 +- src/device/usbd.h | 6 +- src/host/hcd.h | 12 +- src/portable/template/dcd_template.c | 4 +- src/portable/template/hcd_template.c | 162 +++++++++++++++++++++ src/tusb.h | 9 +- 18 files changed, 241 insertions(+), 24 deletions(-) create mode 100644 hw/bsp/nrf/boards/adafruit_clue/board.cmake create mode 100644 hw/bsp/nrf/boards/arduino_nano33_ble/board.cmake create mode 100644 hw/bsp/nrf/boards/circuitplayground_bluefruit/board.cmake create mode 100644 hw/bsp/nrf/boards/feather_nrf52840_express/board.cmake create mode 100644 hw/bsp/nrf/boards/feather_nrf52840_sense/board.cmake create mode 100644 hw/bsp/nrf/boards/itsybitsy_nrf52840/board.cmake create mode 100644 hw/bsp/nrf/boards/nrf52840_mdk_dongle/board.cmake create mode 100644 hw/bsp/nrf/boards/pca10059/board.cmake create mode 100644 hw/bsp/nrf/boards/pca10100/board.cmake create mode 100644 hw/bsp/nrf/boards/raytac_mdbt50q_rx/board.cmake create mode 100644 src/portable/template/hcd_template.c (limited to 'src/host') diff --git a/hw/bsp/nrf/boards/adafruit_clue/board.cmake b/hw/bsp/nrf/boards/adafruit_clue/board.cmake new file mode 100644 index 000000000..eb97e5c55 --- /dev/null +++ b/hw/bsp/nrf/boards/adafruit_clue/board.cmake @@ -0,0 +1,5 @@ +set(MCU_VARIANT nrf52840) +set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/../../linker/nrf52840_s140_v6.ld) + +function(update_board TARGET) +endfunction() diff --git a/hw/bsp/nrf/boards/arduino_nano33_ble/board.cmake b/hw/bsp/nrf/boards/arduino_nano33_ble/board.cmake new file mode 100644 index 000000000..93647063a --- /dev/null +++ b/hw/bsp/nrf/boards/arduino_nano33_ble/board.cmake @@ -0,0 +1,5 @@ +set(MCU_VARIANT nrf52840) +set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/arduino_nano33_ble.ld) + +function(update_board TARGET) +endfunction() diff --git a/hw/bsp/nrf/boards/circuitplayground_bluefruit/board.cmake b/hw/bsp/nrf/boards/circuitplayground_bluefruit/board.cmake new file mode 100644 index 000000000..eb97e5c55 --- /dev/null +++ b/hw/bsp/nrf/boards/circuitplayground_bluefruit/board.cmake @@ -0,0 +1,5 @@ +set(MCU_VARIANT nrf52840) +set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/../../linker/nrf52840_s140_v6.ld) + +function(update_board TARGET) +endfunction() diff --git a/hw/bsp/nrf/boards/feather_nrf52840_express/board.cmake b/hw/bsp/nrf/boards/feather_nrf52840_express/board.cmake new file mode 100644 index 000000000..0acbecf7a --- /dev/null +++ b/hw/bsp/nrf/boards/feather_nrf52840_express/board.cmake @@ -0,0 +1,6 @@ +set(MCU_VARIANT nrf52840) +set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/../../linker/nrf52840_s140_v6.ld) +# set(LD_FILE_GNU ${NRFX_DIR}/mdk/nrf52840_xxaa.ld) + +function(update_board TARGET) +endfunction() diff --git a/hw/bsp/nrf/boards/feather_nrf52840_sense/board.cmake b/hw/bsp/nrf/boards/feather_nrf52840_sense/board.cmake new file mode 100644 index 000000000..eb97e5c55 --- /dev/null +++ b/hw/bsp/nrf/boards/feather_nrf52840_sense/board.cmake @@ -0,0 +1,5 @@ +set(MCU_VARIANT nrf52840) +set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/../../linker/nrf52840_s140_v6.ld) + +function(update_board TARGET) +endfunction() diff --git a/hw/bsp/nrf/boards/itsybitsy_nrf52840/board.cmake b/hw/bsp/nrf/boards/itsybitsy_nrf52840/board.cmake new file mode 100644 index 000000000..eb97e5c55 --- /dev/null +++ b/hw/bsp/nrf/boards/itsybitsy_nrf52840/board.cmake @@ -0,0 +1,5 @@ +set(MCU_VARIANT nrf52840) +set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/../../linker/nrf52840_s140_v6.ld) + +function(update_board TARGET) +endfunction() diff --git a/hw/bsp/nrf/boards/nrf52840_mdk_dongle/board.cmake b/hw/bsp/nrf/boards/nrf52840_mdk_dongle/board.cmake new file mode 100644 index 000000000..ffa5932c1 --- /dev/null +++ b/hw/bsp/nrf/boards/nrf52840_mdk_dongle/board.cmake @@ -0,0 +1,5 @@ +set(MCU_VARIANT nrf52840) +set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/nrf52840_mdk_dongle.ld) + +function(update_board TARGET) +endfunction() diff --git a/hw/bsp/nrf/boards/pca10056/board.cmake b/hw/bsp/nrf/boards/pca10056/board.cmake index b4fe39fc0..693d7beed 100644 --- a/hw/bsp/nrf/boards/pca10056/board.cmake +++ b/hw/bsp/nrf/boards/pca10056/board.cmake @@ -2,7 +2,4 @@ set(MCU_VARIANT nrf52840) set(LD_FILE_GNU ${NRFX_DIR}/mdk/nrf52840_xxaa.ld) function(update_board TARGET) - target_compile_definitions(${TARGET} PUBLIC - NRF52840_XXAA - ) endfunction() diff --git a/hw/bsp/nrf/boards/pca10059/board.cmake b/hw/bsp/nrf/boards/pca10059/board.cmake new file mode 100644 index 000000000..c79eb5964 --- /dev/null +++ b/hw/bsp/nrf/boards/pca10059/board.cmake @@ -0,0 +1,5 @@ +set(MCU_VARIANT nrf52840) +set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/pca10059.ld) + +function(update_board TARGET) +endfunction() diff --git a/hw/bsp/nrf/boards/pca10095/board.cmake b/hw/bsp/nrf/boards/pca10095/board.cmake index 1e72243c9..ca5399a3a 100644 --- a/hw/bsp/nrf/boards/pca10095/board.cmake +++ b/hw/bsp/nrf/boards/pca10095/board.cmake @@ -2,10 +2,6 @@ set(MCU_VARIANT nrf5340_application) set(LD_FILE_GNU ${NRFX_DIR}/mdk/nrf5340_xxaa_application.ld) function(update_board TARGET) - target_compile_definitions(${TARGET} PUBLIC - NRF5340_XXAA - NRF5340_XXAA_APPLICATION - ) target_sources(${TARGET} PRIVATE ${NRFX_DIR}/drivers/src/nrfx_usbreg.c ) diff --git a/hw/bsp/nrf/boards/pca10100/board.cmake b/hw/bsp/nrf/boards/pca10100/board.cmake new file mode 100644 index 000000000..c30026815 --- /dev/null +++ b/hw/bsp/nrf/boards/pca10100/board.cmake @@ -0,0 +1,5 @@ +set(MCU_VARIANT nrf52833) +set(LD_FILE_GNU ${NRFX_DIR}/mdk/nrf52833_xxaa.ld) + +function(update_board TARGET) +endfunction() diff --git a/hw/bsp/nrf/boards/raytac_mdbt50q_rx/board.cmake b/hw/bsp/nrf/boards/raytac_mdbt50q_rx/board.cmake new file mode 100644 index 000000000..693d7beed --- /dev/null +++ b/hw/bsp/nrf/boards/raytac_mdbt50q_rx/board.cmake @@ -0,0 +1,5 @@ +set(MCU_VARIANT nrf52840) +set(LD_FILE_GNU ${NRFX_DIR}/mdk/nrf52840_xxaa.ld) + +function(update_board TARGET) +endfunction() diff --git a/hw/bsp/nrf/family.cmake b/hw/bsp/nrf/family.cmake index 2b13249f4..6c24d3658 100644 --- a/hw/bsp/nrf/family.cmake +++ b/hw/bsp/nrf/family.cmake @@ -33,13 +33,20 @@ function(add_board_target BOARD_TARGET) add_library(${BOARD_TARGET} STATIC # driver ${NRFX_DIR}/drivers/src/nrfx_power.c + ${NRFX_DIR}/drivers/src/nrfx_spim.c ${NRFX_DIR}/drivers/src/nrfx_uarte.c # mcu ${NRFX_DIR}/mdk/system_${MCU_VARIANT}.c ) - target_compile_definitions(${BOARD_TARGET} PUBLIC - CONFIG_GPIO_AS_PINRESET - ) + target_compile_definitions(${BOARD_TARGET} PUBLIC CONFIG_GPIO_AS_PINRESET) + + if (MCU_VARIANT STREQUAL "nrf52840") + target_compile_definitions(${BOARD_TARGET} PUBLIC NRF52840_XXAA) + elseif (MCU_VARIANT STREQUAL "nrf52833") + target_compile_definitions(${BOARD_TARGET} PUBLIC NRF52833_XXAA) + elseif (MCU_VARIANT STREQUAL "nrf5340_application") + target_compile_definitions(${BOARD_TARGET} PUBLIC NRF5340_XXAA NRF5340_XXAA_APPLICATION) + endif () if (TRACE_ETM STREQUAL "1") # ENABLE_TRACE will cause system_nrf5x.c to set up ETM trace @@ -115,6 +122,7 @@ function(family_configure_example TARGET RTOS) family_add_tinyusb(${TARGET} OPT_MCU_NRF5X ${RTOS}) target_sources(${TARGET}-tinyusb PUBLIC ${TOP}/src/portable/nordic/nrf5x/dcd_nrf5x.c + #${TOP}/src/portable/analog/max3421e/hcd_max3421e.c ) target_link_libraries(${TARGET}-tinyusb PUBLIC board_${BOARD}) diff --git a/src/device/usbd.h b/src/device/usbd.h index b11c1a09d..782f538fd 100644 --- a/src/device/usbd.h +++ b/src/device/usbd.h @@ -50,8 +50,7 @@ void tud_task_ext(uint32_t timeout_ms, bool in_isr); // Task function should be called in main/rtos loop TU_ATTR_ALWAYS_INLINE static inline -void tud_task (void) -{ +void tud_task (void) { tud_task_ext(UINT32_MAX, false); } @@ -80,8 +79,7 @@ bool tud_suspended(void); // Check if device is ready to transfer TU_ATTR_ALWAYS_INLINE static inline -bool tud_ready(void) -{ +bool tud_ready(void) { return tud_mounted() && !tud_suspended(); } diff --git a/src/host/hcd.h b/src/host/hcd.h index 9bcc1c6df..1b5038ef4 100644 --- a/src/host/hcd.h +++ b/src/host/hcd.h @@ -198,8 +198,7 @@ extern void hcd_event_handler(hcd_event_t const* event, bool in_isr); // Helper to send device attach event TU_ATTR_ALWAYS_INLINE static inline -void hcd_event_device_attach(uint8_t rhport, bool in_isr) -{ +void hcd_event_device_attach(uint8_t rhport, bool in_isr) { hcd_event_t event; event.rhport = rhport; event.event_id = HCD_EVENT_DEVICE_ATTACH; @@ -211,8 +210,7 @@ void hcd_event_device_attach(uint8_t rhport, bool in_isr) // Helper to send device removal event TU_ATTR_ALWAYS_INLINE static inline -void hcd_event_device_remove(uint8_t rhport, bool in_isr) -{ +void hcd_event_device_remove(uint8_t rhport, bool in_isr) { hcd_event_t event; event.rhport = rhport; event.event_id = HCD_EVENT_DEVICE_REMOVE; @@ -224,10 +222,8 @@ void hcd_event_device_remove(uint8_t rhport, bool in_isr) // Helper to send USB transfer event TU_ATTR_ALWAYS_INLINE static inline -void hcd_event_xfer_complete(uint8_t dev_addr, uint8_t ep_addr, uint32_t xferred_bytes, xfer_result_t result, bool in_isr) -{ - hcd_event_t event = - { +void hcd_event_xfer_complete(uint8_t dev_addr, uint8_t ep_addr, uint32_t xferred_bytes, xfer_result_t result, bool in_isr) { + hcd_event_t event = { .rhport = 0, // TODO correct rhport .event_id = HCD_EVENT_XFER_COMPLETE, .dev_addr = dev_addr, diff --git a/src/portable/template/dcd_template.c b/src/portable/template/dcd_template.c index 590dd9fcf..12d610bd6 100644 --- a/src/portable/template/dcd_template.c +++ b/src/portable/template/dcd_template.c @@ -26,7 +26,7 @@ #include "tusb_option.h" -#if CFG_TUSB_MCU == OPT_MCU_NONE +#if CFG_TUD_ENABLED && CFG_TUSB_MCU == OPT_MCU_NONE #include "device/dcd.h" @@ -141,4 +141,6 @@ void dcd_edpt_clear_stall (uint8_t rhport, uint8_t ep_addr) (void) ep_addr; } + + #endif diff --git a/src/portable/template/hcd_template.c b/src/portable/template/hcd_template.c new file mode 100644 index 000000000..3e3b91558 --- /dev/null +++ b/src/portable/template/hcd_template.c @@ -0,0 +1,162 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2023 Ha Thach (tinyusb.org) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + +#include "tusb_option.h" + +#if CFG_TUH_ENABLED && CFG_TUSB_MCU == OPT_MCU_NONE + +#include "host/hcd.h" + +//--------------------------------------------------------------------+ +// Controller API +//--------------------------------------------------------------------+ + +// optional hcd configuration, called by tuh_configure() +bool hcd_configure(uint8_t rhport, uint32_t cfg_id, const void* cfg_param) { + (void) rhport; + (void) cfg_id; + (void) cfg_param; + + return false; +} + +// Initialize controller to host mode +bool hcd_init(uint8_t rhport) { + (void) rhport; + + return false; +} + +// Interrupt Handler +void hcd_int_handler(uint8_t rhport) { + (void) rhport; +} + +// Enable USB interrupt +void hcd_int_enable (uint8_t rhport) { + (void) rhport; +} + +// Disable USB interrupt +void hcd_int_disable(uint8_t rhport) { + (void) rhport; +} + +// Get frame number (1ms) +uint32_t hcd_frame_number(uint8_t rhport) { + (void) rhport; + + return 0; +} + +//--------------------------------------------------------------------+ +// Port API +//--------------------------------------------------------------------+ + +// Get the current connect status of roothub port +bool hcd_port_connect_status(uint8_t rhport) { + (void) rhport; + + return false; +} + +// Reset USB bus on the port. Return immediately, bus reset sequence may not be complete. +// Some port would require hcd_port_reset_end() to be invoked after 10ms to complete the reset sequence. +void hcd_port_reset(uint8_t rhport) { + (void) rhport; +} + +// Complete bus reset sequence, may be required by some controllers +void hcd_port_reset_end(uint8_t rhport) { + (void) rhport; +} + +// Get port link speed +tusb_speed_t hcd_port_speed_get(uint8_t rhport) { + (void) rhport; + + return TUSB_SPEED_FULL; +} + +// HCD closes all opened endpoints belong to this device +void hcd_device_close(uint8_t rhport, uint8_t dev_addr) { + (void) rhport; + (void) dev_addr; +} + +//--------------------------------------------------------------------+ +// Endpoints API +//--------------------------------------------------------------------+ + +// Open an endpoint +bool hcd_edpt_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_endpoint_t const * ep_desc) { + (void) rhport; + (void) dev_addr; + (void) ep_desc; + + return false; +} + +// Submit a transfer, when complete hcd_event_xfer_complete() must be invoked +bool hcd_edpt_xfer(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr, uint8_t * buffer, uint16_t buflen) { + (void) rhport; + (void) dev_addr; + (void) ep_addr; + (void) buffer; + (void) buflen; + + return false; +} + +// Abort a queued transfer. Note: it can only abort transfer that has not been started +// Return true if a queued transfer is aborted, false if there is no transfer to abort +bool hcd_edpt_abort_xfer(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr) { + (void) rhport; + (void) dev_addr; + (void) ep_addr; + + return false; +} + +// Submit a special transfer to send 8-byte Setup Packet, when complete hcd_event_xfer_complete() must be invoked +bool hcd_setup_send(uint8_t rhport, uint8_t dev_addr, uint8_t const setup_packet[8]) { + (void) rhport; + (void) dev_addr; + (void) setup_packet; + + return false; +} + +// clear stall, data toggle is also reset to DATA0 +bool hcd_edpt_clear_stall(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr) { + (void) rhport; + (void) dev_addr; + (void) ep_addr; + + return false; +} + +#endif diff --git a/src/tusb.h b/src/tusb.h index 37a521fa8..d6534ca28 100644 --- a/src/tusb.h +++ b/src/tusb.h @@ -64,7 +64,10 @@ #if CFG_TUH_VENDOR #include "class/vendor/vendor_host.h" #endif - +#else + #ifndef tuh_int_handler + #define tuh_int_handler(_x) + #endif #endif //------------- DEVICE -------------// @@ -118,6 +121,10 @@ #if CFG_TUD_BTH #include "class/bth/bth_device.h" #endif +#else + #ifndef tud_int_handler + #define tud_int_handler(_x) + #endif #endif -- cgit v1.3.1 From 274578ff46c31b231b3553dc9a20895646313130 Mon Sep 17 00:00:00 2001 From: hathach Date: Tue, 22 Aug 2023 23:17:12 +0700 Subject: able to send setup packet --- hw/bsp/nrf/boards/feather_nrf52840_express/board.h | 8 +- hw/bsp/nrf/family.c | 36 ++++- src/host/hcd.h | 2 +- src/host/usbh.c | 32 ++-- src/portable/analog/max3421e/hcd_max3421e.c | 173 ++++++++++++++++----- 5 files changed, 179 insertions(+), 72 deletions(-) (limited to 'src/host') diff --git a/hw/bsp/nrf/boards/feather_nrf52840_express/board.h b/hw/bsp/nrf/boards/feather_nrf52840_express/board.h index 7f042142e..e6e7590ac 100644 --- a/hw/bsp/nrf/boards/feather_nrf52840_express/board.h +++ b/hw/bsp/nrf/boards/feather_nrf52840_express/board.h @@ -46,10 +46,10 @@ #define UART_TX_PIN 25 // SPI for USB host shield -#define SPI_SCK_PIN 14 -#define SPI_MOSI_PIN 13 -#define SPI_MISO_PIN 15 -#define SPI_CS_PIN 27 +#define MAX3421E_SCK_PIN 14 +#define MAX3421E_MOSI_PIN 13 +#define MAX3421E_MISO_PIN 15 +#define MAX3421E_CS_PIN 27 #define MAX3241E_INTR_PIN 26 #ifdef __cplusplus diff --git a/hw/bsp/nrf/family.c b/hw/bsp/nrf/family.c index e58ee845b..862f67bc7 100644 --- a/hw/bsp/nrf/family.c +++ b/hw/bsp/nrf/family.c @@ -96,22 +96,38 @@ TU_ATTR_UNUSED static void power_event_handler(nrfx_power_usb_evt_t event) { #if CFG_TUH_ENABLED && defined(CFG_TUH_MAX3421E) && CFG_TUH_MAX3421E static nrfx_spim_t _spi = NRFX_SPIM_INSTANCE(0); -void max2342e_int_handler(nrfx_gpiote_pin_t pin, nrf_gpiote_polarity_t action) { +void max3421e_int_handler(nrfx_gpiote_pin_t pin, nrf_gpiote_polarity_t action) { if ( !(pin == MAX3241E_INTR_PIN && action == NRF_GPIOTE_POLARITY_HITOLO) ) return; tuh_int_handler(1); } +static inline void max3421e_cs_assert(bool active) { + nrf_gpio_pin_write(MAX3421E_CS_PIN, active ? 0 : 1); +} + +//--------------------------------------------------------------------+ // API: SPI transfer with MAX3421E, must be implemented by application -bool tuh_max3421e_spi_xfer_api(uint8_t rhport, uint8_t const * tx_buf, size_t tx_len, uint8_t * rx_buf, size_t rx_len) { +//--------------------------------------------------------------------+ + +bool tuh_max3421e_spi_xfer_api(uint8_t rhport, uint8_t const * tx_buf, size_t tx_len, + uint8_t * rx_buf, size_t rx_len, bool keep_cs) { (void) rhport; + + max3421e_cs_assert(true); + nrfx_spim_xfer_desc_t xfer = { .p_tx_buffer = tx_buf, .tx_length = tx_len, .p_rx_buffer = rx_buf, .rx_length = rx_len, }; - return nrfx_spim_xfer(&_spi, &xfer, 0) == NRFX_SUCCESS; + + bool ret = (nrfx_spim_xfer(&_spi, &xfer, 0) == NRFX_SUCCESS); + + if ( !keep_cs ) max3421e_cs_assert(false); + + return ret; } #endif @@ -203,12 +219,16 @@ void board_init(void) { #endif #if CFG_TUH_ENABLED && defined(CFG_TUH_MAX3421E) && CFG_TUH_MAX3421E + // manually manage CS + nrf_gpio_cfg_output(MAX3421E_CS_PIN); + max3421e_cs_assert(false); + // USB host using max3421e usb controller via SPI nrfx_spim_config_t cfg = { - .sck_pin = SPI_SCK_PIN, - .mosi_pin = SPI_MOSI_PIN, - .miso_pin = SPI_MISO_PIN, - .ss_pin = SPI_CS_PIN, + .sck_pin = MAX3421E_SCK_PIN, + .mosi_pin = MAX3421E_MOSI_PIN, + .miso_pin = MAX3421E_MISO_PIN, + .ss_pin = NRFX_SPIM_PIN_NOT_USED, .ss_active_high = false, .irq_priority = 3, .orc = 0xFF, @@ -226,7 +246,7 @@ void board_init(void) { nrfx_gpiote_in_config_t in_config = NRFX_GPIOTE_CONFIG_IN_SENSE_HITOLO(true); in_config.pull = NRF_GPIO_PIN_PULLUP; - nrfx_gpiote_in_init(MAX3241E_INTR_PIN, &in_config, max2342e_int_handler); + nrfx_gpiote_in_init(MAX3241E_INTR_PIN, &in_config, max3421e_int_handler); nrfx_gpiote_in_event_enable(MAX3241E_INTR_PIN, true); #endif diff --git a/src/host/hcd.h b/src/host/hcd.h index 1b5038ef4..079877b79 100644 --- a/src/host/hcd.h +++ b/src/host/hcd.h @@ -177,7 +177,7 @@ bool hcd_edpt_xfer(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr, uint8_t * bool hcd_edpt_abort_xfer(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr); // Submit a special transfer to send 8-byte Setup Packet, when complete hcd_event_xfer_complete() must be invoked -bool hcd_setup_send(uint8_t rhport, uint8_t dev_addr, uint8_t const setup_packet[8]); +bool hcd_setup_send(uint8_t rhport, uint8_t daddr, uint8_t const setup_packet[8]); // clear stall, data toggle is also reset to DATA0 bool hcd_edpt_clear_stall(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr); diff --git a/src/host/usbh.c b/src/host/usbh.c index 5423df669..7a09f5b6e 100644 --- a/src/host/usbh.c +++ b/src/host/usbh.c @@ -552,8 +552,7 @@ static void _control_blocking_complete_cb(tuh_xfer_t* xfer) } // TODO timeout_ms is not supported yet -bool tuh_control_xfer (tuh_xfer_t* xfer) -{ +bool tuh_control_xfer (tuh_xfer_t* xfer) { // EP0 with setup packet TU_VERIFY(xfer->ep_addr == 0 && xfer->setup); @@ -565,8 +564,7 @@ bool tuh_control_xfer (tuh_xfer_t* xfer) (void) osal_mutex_lock(_usbh_mutex, OSAL_TIMEOUT_WAIT_FOREVER); bool const is_idle = (_ctrl_xfer.stage == CONTROL_STAGE_IDLE); - if (is_idle) - { + if (is_idle) { _ctrl_xfer.stage = CONTROL_STAGE_SETUP; _ctrl_xfer.daddr = daddr; _ctrl_xfer.actual_len = 0; @@ -588,11 +586,9 @@ bool tuh_control_xfer (tuh_xfer_t* xfer) TU_LOG_PTR(CFG_TUH_LOG_LEVEL, xfer->setup); TU_LOG_USBH("\r\n"); - if (xfer->complete_cb) - { + if (xfer->complete_cb) { TU_ASSERT( hcd_setup_send(rhport, daddr, (uint8_t const*) &_ctrl_xfer.request) ); - }else - { + }else { // blocking if complete callback is not provided // change callback to internal blocking, and result as user argument volatile xfer_result_t result = XFER_RESULT_INVALID; @@ -656,15 +652,13 @@ static void _xfer_complete(uint8_t daddr, xfer_result_t result) } } -static bool usbh_control_xfer_cb (uint8_t dev_addr, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes) -{ +static bool usbh_control_xfer_cb (uint8_t dev_addr, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes) { (void) ep_addr; const uint8_t rhport = usbh_get_rhport(dev_addr); tusb_control_request_t const * request = &_ctrl_xfer.request; - if (XFER_RESULT_SUCCESS != result) - { + if (XFER_RESULT_SUCCESS != result) { TU_LOG1("[%u:%u] Control %s, xferred_bytes = %lu\r\n", rhport, dev_addr, result == XFER_RESULT_STALLED ? "STALLED" : "FAILED", xferred_bytes); #if CFG_TUSB_DEBUG == 1 TU_LOG1_PTR(request); @@ -673,13 +667,10 @@ static bool usbh_control_xfer_cb (uint8_t dev_addr, uint8_t ep_addr, xfer_result // terminate transfer if any stage failed _xfer_complete(dev_addr, result); - }else - { - switch(_ctrl_xfer.stage) - { + }else { + switch(_ctrl_xfer.stage) { case CONTROL_STAGE_SETUP: - if (request->wLength) - { + if (request->wLength) { // DATA stage: initial data toggle is always 1 _set_control_xfer_stage(CONTROL_STAGE_DATA); TU_ASSERT( hcd_edpt_xfer(rhport, dev_addr, tu_edpt_addr(0, request->bmRequestType_bit.direction), _ctrl_xfer.buffer, request->wLength) ); @@ -688,8 +679,7 @@ static bool usbh_control_xfer_cb (uint8_t dev_addr, uint8_t ep_addr, xfer_result TU_ATTR_FALLTHROUGH; case CONTROL_STAGE_DATA: - if (request->wLength) - { + if (request->wLength) { TU_LOG_USBH("[%u:%u] Control data:\r\n", rhport, dev_addr); TU_LOG_MEM(CFG_TUH_LOG_LEVEL, _ctrl_xfer.buffer, xferred_bytes, 2); } @@ -1538,9 +1528,7 @@ static bool enum_new_device(hcd_event_t* event) xfer.result = XFER_RESULT_SUCCESS; xfer.user_data = ENUM_ADDR0_DEVICE_DESC; - process_enumeration(&xfer); - } #if CFG_TUH_HUB else diff --git a/src/portable/analog/max3421e/hcd_max3421e.c b/src/portable/analog/max3421e/hcd_max3421e.c index 870c616a9..c9596f695 100644 --- a/src/portable/analog/max3421e/hcd_max3421e.c +++ b/src/portable/analog/max3421e/hcd_max3421e.c @@ -136,30 +136,64 @@ enum { HRSL_JSTATUS = 1u << 7, }; +enum { + HRSL_SUCCESS = 0, + HRSL_BUSY, + HRSL_BAD_REQ, + HRSL_UNDEF, + HRSL_NAK, + HRSL_STALL, + HRSL_TOG_ERR, + HRSL_WRONG_PID, + HRSL_BAD_BYTECOUNT, + HRSL_PID_ERR, + HRSL_PKT_ERR, + HRSL_CRC_ERR, + HRSL_K_ERR, + HRSL_J_ERR, + HRSL_TIMEOUT, + HRSL_BABBLE, +}; + + //--------------------------------------------------------------------+ // //--------------------------------------------------------------------+ typedef struct { + // cached register uint8_t mode; + uint8_t peraddr; + uint8_t hxfr; volatile uint16_t frame_count; + + struct { + uint16_t packet_size; + uint16_t total_len; + uint8_t xfer_type; + }ep[8][2]; } max2341e_data_t; static max2341e_data_t _hcd_data; //--------------------------------------------------------------------+ -// +// API: SPI transfer with MAX3421E, must be implemented by application //--------------------------------------------------------------------+ -// API: SPI transfer with MAX3421E, must be implemented by application -bool tuh_max3421e_spi_xfer_api(uint8_t rhport, uint8_t const * tx_buf, size_t tx_len, uint8_t * rx_buf, size_t rx_len); +bool tuh_max3421e_spi_xfer_api(uint8_t rhport, uint8_t const * tx_buf, size_t tx_len, + uint8_t * rx_buf, size_t rx_len, bool keep_cs); +//void tuh_max3421e_int_enable(uint8_t rhport, bool enabled); + +//--------------------------------------------------------------------+ +// +//--------------------------------------------------------------------+ // return HIRQ register since we are in full-duplex mode static uint8_t reg_write(uint8_t reg, uint8_t data) { uint8_t tx_buf[2] = {reg | CMDBYTE_WRITE, data}; uint8_t rx_buf[2] = {0, 0}; - tuh_max3421e_spi_xfer_api(0, tx_buf, 2, rx_buf, 2); + tuh_max3421e_spi_xfer_api(0, tx_buf, 2, rx_buf, 2, false); TU_LOG2("HIRQ: %02X\r\n", rx_buf[0]); return rx_buf[0]; } @@ -167,7 +201,7 @@ static uint8_t reg_write(uint8_t reg, uint8_t data) { static uint8_t reg_read(uint8_t reg) { uint8_t tx_buf[2] = {reg, 0}; uint8_t rx_buf[2] = {0, 0}; - return tuh_max3421e_spi_xfer_api(0, tx_buf, 2, rx_buf, 2) ? rx_buf[1] : 0; + return tuh_max3421e_spi_xfer_api(0, tx_buf, 2, rx_buf, 2, false) ? rx_buf[1] : 0; } static inline uint8_t mode_write(uint8_t data) { @@ -175,6 +209,24 @@ static inline uint8_t mode_write(uint8_t data) { return reg_write(MODE_ADDR, data); } +static inline uint8_t peraddr_write(uint8_t data) { + if ( _hcd_data.peraddr == data ) return 0; // no need to change address + + _hcd_data.peraddr = data; + return reg_write(PERADDR_ADDR, data); +} + +static inline uint8_t hxfr_write(uint8_t data) { + _hcd_data.hxfr = data; + return reg_write(HXFR_ADDR, data); +} + +static void fifo_write(uint8_t reg, uint8_t const * buffer, uint16_t len) { + uint8_t tx_buf[1] = {reg | CMDBYTE_WRITE}; + tuh_max3421e_spi_xfer_api(0, tx_buf, 1, NULL, 0, true); + tuh_max3421e_spi_xfer_api(0, buffer, len, NULL, 0, false); +} + //--------------------------------------------------------------------+ // Controller API @@ -252,7 +304,7 @@ bool hcd_init(uint8_t rhport) { mode_write(MODE_DPPULLDN | MODE_DMPULLDN | MODE_HOST); // Enable Connection IRQ - reg_write(HIEN_ADDR, HIRQ_CONDET_IRQ | HIRQ_FRAME_IRQ); + reg_write(HIEN_ADDR, HIRQ_CONDET_IRQ | HIRQ_FRAME_IRQ | HIRQ_HXFRDN_IRQ); #if 0 // Note: if device is already connected, CONDET IRQ may not be triggered. @@ -271,33 +323,6 @@ bool hcd_init(uint8_t rhport) { return true; } -// Interrupt Handler -void hcd_int_handler(uint8_t rhport) { - (void) rhport; - - uint8_t hirq = reg_read(HIRQ_ADDR); - TU_LOG3_HEX(hirq); - - if (hirq & HIRQ_CONDET_IRQ) { - tusb_speed_t speed = handle_connect_irq(rhport); - - if (speed == TUSB_SPEED_INVALID) { - hcd_event_device_remove(rhport, true); - }else { - hcd_event_device_attach(rhport, true); - } - } - - if (hirq & HIRQ_FRAME_IRQ) { - _hcd_data.frame_count++; - } - - // clear all interrupt - if ( hirq ) { - reg_write(HIRQ_ADDR, hirq); - } -} - // Enable USB interrupt void hcd_int_enable (uint8_t rhport) { (void) rhport; @@ -359,7 +384,12 @@ bool hcd_edpt_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_endpoint_t const (void) dev_addr; (void) ep_desc; - return false; + uint8_t ep_num = tu_edpt_number(ep_desc->bEndpointAddress); + uint8_t ep_dir = tu_edpt_dir(ep_desc->bEndpointAddress); + + _hcd_data.ep[ep_num][ep_dir].packet_size = tu_edpt_packet_size(ep_desc); + + return true; } // Submit a transfer, when complete hcd_event_xfer_complete() must be invoked @@ -384,12 +414,18 @@ bool hcd_edpt_abort_xfer(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr) { } // Submit a special transfer to send 8-byte Setup Packet, when complete hcd_event_xfer_complete() must be invoked -bool hcd_setup_send(uint8_t rhport, uint8_t dev_addr, uint8_t const setup_packet[8]) { +bool hcd_setup_send(uint8_t rhport, uint8_t daddr, uint8_t const setup_packet[8]) { (void) rhport; - (void) dev_addr; + (void) daddr; (void) setup_packet; - return false; + _hcd_data.ep[0][0].total_len = 8; + + peraddr_write(daddr); + fifo_write(SUDFIFO_ADDR, setup_packet, 8); + hxfr_write(HXFR_SETUP); + + return true; } // clear stall, data toggle is also reset to DATA0 @@ -401,4 +437,67 @@ bool hcd_edpt_clear_stall(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr) { return false; } +// Interrupt Handler +void hcd_int_handler(uint8_t rhport) { + uint8_t hirq = reg_read(HIRQ_ADDR); + TU_LOG3_HEX(hirq); + + if (hirq & HIRQ_CONDET_IRQ) { + tusb_speed_t speed = handle_connect_irq(rhport); + + if (speed == TUSB_SPEED_INVALID) { + hcd_event_device_remove(rhport, true); + }else { + hcd_event_device_attach(rhport, true); + } + } + + if (hirq & HIRQ_FRAME_IRQ) { + _hcd_data.frame_count++; + } + + if (hirq & HIRQ_HXFRDN_IRQ) { + uint8_t const hrsl = reg_read(HRSL_ADDR); + uint8_t const result = hrsl & HRSL_RESULT_MASK; + uint8_t xfer_result; + + TU_LOG3("HRSL: %02X\r\n", hrsl); + switch(result) { + case HRSL_SUCCESS: + xfer_result = XFER_RESULT_SUCCESS; + break; + + case HRSL_STALL: + xfer_result = XFER_RESULT_STALLED; + break; + + default: + xfer_result = XFER_RESULT_FAILED; + break; + } + + uint8_t ep_dir = 0; + uint8_t ep_num = _hcd_data.hxfr & HXFR_EPNUM_MASK; + uint8_t const xfer_type = _hcd_data.hxfr & 0xf0; + + if ( xfer_type & HXFR_SETUP ) { + // SETUP transfer + ep_dir = 0; + }else if ( !(xfer_type & HXFR_OUT_NIN) ) { + // IN transfer + ep_dir = 1; + } + + uint8_t const ep_addr = tu_edpt_addr(ep_num, ep_dir); + uint16_t xferred_len = _hcd_data.ep[ep_num][ep_dir].total_len; + + hcd_event_xfer_complete(_hcd_data.peraddr, ep_addr, xferred_len, xfer_result, true); + } + + // clear all interrupt + if ( hirq ) { + reg_write(HIRQ_ADDR, hirq); + } +} + #endif -- cgit v1.3.1 From e3f3179924f7c84c4bb3e69234720f9afc178727 Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 23 Aug 2023 15:08:12 +0700 Subject: able to get 8 byte descriptor, but read(RCVBC) always return 0 - rename max3421e to max3421 - fix incorrect bitmask for HCTL, fix initial device connect - fix bus reset cause connect IRQ --- hw/bsp/nrf/family.c | 24 +- hw/bsp/nrf/family.cmake | 2 +- src/host/hcd.h | 2 +- src/portable/analog/max3421/hcd_max3421.c | 613 ++++++++++++++++++++++++++++ src/portable/analog/max3421e/hcd_max3421e.c | 503 ----------------------- 5 files changed, 624 insertions(+), 520 deletions(-) create mode 100644 src/portable/analog/max3421/hcd_max3421.c delete mode 100644 src/portable/analog/max3421e/hcd_max3421e.c (limited to 'src/host') diff --git a/hw/bsp/nrf/family.c b/hw/bsp/nrf/family.c index 862f67bc7..45a5166a7 100644 --- a/hw/bsp/nrf/family.c +++ b/hw/bsp/nrf/family.c @@ -93,7 +93,7 @@ TU_ATTR_UNUSED static void power_event_handler(nrfx_power_usb_evt_t event) { } //------------- Host using MAX2341E -------------// -#if CFG_TUH_ENABLED && defined(CFG_TUH_MAX3421E) && CFG_TUH_MAX3421E +#if CFG_TUH_ENABLED && defined(CFG_TUH_MAX3421) && CFG_TUH_MAX3421 static nrfx_spim_t _spi = NRFX_SPIM_INSTANCE(0); void max3421e_int_handler(nrfx_gpiote_pin_t pin, nrf_gpiote_polarity_t action) { @@ -102,19 +102,17 @@ void max3421e_int_handler(nrfx_gpiote_pin_t pin, nrf_gpiote_polarity_t action) { tuh_int_handler(1); } -static inline void max3421e_cs_assert(bool active) { - nrf_gpio_pin_write(MAX3421E_CS_PIN, active ? 0 : 1); -} - //--------------------------------------------------------------------+ // API: SPI transfer with MAX3421E, must be implemented by application //--------------------------------------------------------------------+ -bool tuh_max3421e_spi_xfer_api(uint8_t rhport, uint8_t const * tx_buf, size_t tx_len, - uint8_t * rx_buf, size_t rx_len, bool keep_cs) { +void tuh_max3421_spi_cs_api(uint8_t rhport, bool active) { (void) rhport; + nrf_gpio_pin_write(MAX3421E_CS_PIN, active ? 0 : 1); +} - max3421e_cs_assert(true); +bool tuh_max3421_spi_xfer_api(uint8_t rhport, uint8_t const * tx_buf, size_t tx_len, uint8_t * rx_buf, size_t rx_len) { + (void) rhport; nrfx_spim_xfer_desc_t xfer = { .p_tx_buffer = tx_buf, @@ -123,11 +121,7 @@ bool tuh_max3421e_spi_xfer_api(uint8_t rhport, uint8_t const * tx_buf, size_t tx .rx_length = rx_len, }; - bool ret = (nrfx_spim_xfer(&_spi, &xfer, 0) == NRFX_SUCCESS); - - if ( !keep_cs ) max3421e_cs_assert(false); - - return ret; + return (nrfx_spim_xfer(&_spi, &xfer, 0) == NRFX_SUCCESS); } #endif @@ -218,10 +212,10 @@ void board_init(void) { if ( usb_reg & OUTPUTRDY_Msk ) tusb_hal_nrf_power_event(USB_EVT_READY); #endif -#if CFG_TUH_ENABLED && defined(CFG_TUH_MAX3421E) && CFG_TUH_MAX3421E +#if CFG_TUH_ENABLED && defined(CFG_TUH_MAX3421) && CFG_TUH_MAX3421 // manually manage CS nrf_gpio_cfg_output(MAX3421E_CS_PIN); - max3421e_cs_assert(false); + tuh_max3421_spi_cs_api(0, false); // USB host using max3421e usb controller via SPI nrfx_spim_config_t cfg = { diff --git a/hw/bsp/nrf/family.cmake b/hw/bsp/nrf/family.cmake index 8bf7bcb52..ff6b882ce 100644 --- a/hw/bsp/nrf/family.cmake +++ b/hw/bsp/nrf/family.cmake @@ -124,7 +124,7 @@ function(family_configure_example TARGET RTOS) family_add_tinyusb(${TARGET} OPT_MCU_NRF5X ${RTOS}) target_sources(${TARGET}-tinyusb PUBLIC ${TOP}/src/portable/nordic/nrf5x/dcd_nrf5x.c - ${TOP}/src/portable/analog/max3421e/hcd_max3421e.c + ${TOP}/src/portable/analog/max3421/hcd_max3421.c ) target_link_libraries(${TARGET}-tinyusb PUBLIC board_${BOARD}) diff --git a/src/host/hcd.h b/src/host/hcd.h index 079877b79..1f01a1a2f 100644 --- a/src/host/hcd.h +++ b/src/host/hcd.h @@ -170,7 +170,7 @@ void hcd_device_close(uint8_t rhport, uint8_t dev_addr); bool hcd_edpt_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_endpoint_t const * ep_desc); // Submit a transfer, when complete hcd_event_xfer_complete() must be invoked -bool hcd_edpt_xfer(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr, uint8_t * buffer, uint16_t buflen); +bool hcd_edpt_xfer(uint8_t rhport, uint8_t daddr, uint8_t ep_addr, uint8_t * buffer, uint16_t buflen); // Abort a queued transfer. Note: it can only abort transfer that has not been started // Return true if a queued transfer is aborted, false if there is no transfer to abort diff --git a/src/portable/analog/max3421/hcd_max3421.c b/src/portable/analog/max3421/hcd_max3421.c new file mode 100644 index 000000000..edcb6ca6f --- /dev/null +++ b/src/portable/analog/max3421/hcd_max3421.c @@ -0,0 +1,613 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2023 Ha Thach (tinyusb.org) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + +#include "tusb_option.h" + +#if CFG_TUH_ENABLED && defined(CFG_TUH_MAX3421) && CFG_TUH_MAX3421 + +#include "host/hcd.h" + +//--------------------------------------------------------------------+ +// +//--------------------------------------------------------------------+ + +// Command format is +// Reg [7:3] | 0 [2] | Dir [1] | Ack [0] + +enum { + CMDBYTE_WRITE = 0x02, +}; + +enum { + RCVVFIFO_ADDR = 1u << 3, // 0x08 + SNDFIFO_ADDR = 2u << 3, // 0x10 + SUDFIFO_ADDR = 4u << 3, // 0x20 + RCVBC_ADDR = 6u << 3, // 0x30 + SNDBC_ADDR = 7u << 3, // 0x38 + USBIRQ_ADDR = 13u << 3, // 0x68 + USBIEN_ADDR = 14u << 3, // 0x70 + USBCTL_ADDR = 15u << 3, // 0x78 + CPUCTL_ADDR = 16u << 3, // 0x80 + PINCTL_ADDR = 17u << 3, // 0x88 + REVISION_ADDR = 18u << 3, // 0x90 + HIRQ_ADDR = 25u << 3, // 0xC8 + HIEN_ADDR = 26u << 3, // 0xD0 + MODE_ADDR = 27u << 3, // 0xD8 + PERADDR_ADDR = 28u << 3, // 0xE0 + HCTL_ADDR = 29u << 3, // 0xE8 + HXFR_ADDR = 30u << 3, // 0xF0 + HRSL_ADDR = 31u << 3, // 0xF8 +}; + +enum { + USBIRQ_OSCOK_IRQ = 1u << 0, + USBIRQ_NOVBUS_IRQ = 1u << 5, + USBIRQ_VBUS_IRQ = 1u << 6, +}; + +enum { + USBCTL_PWRDOWN = 1u << 4, + USBCTL_CHIPRES = 1u << 5, +}; + +enum { + CPUCTL_IE = 1u << 0, + CPUCTL_PULSEWID0 = 1u << 6, + CPUCTL_PULSEWID1 = 1u << 7, +}; + +enum { + PINCTL_GPXA = 1u << 0, + PINCTL_GPXB = 1u << 1, + PINCTL_POSINT = 1u << 2, + PINCTL_INTLEVEL = 1u << 3, + PINCTL_FDUPSPI = 1u << 4, +}; + +enum { + HIRQ_BUSEVENT_IRQ = 1u << 0, + HIRQ_RWU_IRQ = 1u << 1, + HIRQ_RCVDAV_IRQ = 1u << 2, + HIRQ_SNDBAV_IRQ = 1u << 3, + HIRQ_SUSDN_IRQ = 1u << 4, + HIRQ_CONDET_IRQ = 1u << 5, + HIRQ_FRAME_IRQ = 1u << 6, + HIRQ_HXFRDN_IRQ = 1u << 7, +}; + +enum { + MODE_HOST = 1u << 0, + MODE_LOWSPEED = 1u << 1, + MODE_HUBPRE = 1u << 2, + MODE_SOFKAENAB = 1u << 3, + MODE_SEPIRQ = 1u << 4, + MODE_DELAYISO = 1u << 5, + MODE_DMPULLDN = 1u << 6, + MODE_DPPULLDN = 1u << 7, +}; + +enum { + HCTL_BUSRST = 1u << 0, + HCTL_FRMRST = 1u << 1, + HCTL_SAMPLEBUS = 1u << 2, + HCTL_SIGRSM = 1u << 3, + HCTL_RCVTOG0 = 1u << 4, + HCTL_RCVTOG1 = 1u << 5, + HCTL_SNDTOG0 = 1u << 6, + HCTL_SNDTOG1 = 1u << 7, +}; + +enum { + HXFR_EPNUM_MASK = 0x0f, + HXFR_SETUP = 1u << 4, + HXFR_OUT_NIN = 1u << 5, + HXFR_ISO = 1u << 6, + HXFR_HS = 1u << 7, +}; + +enum { + HRSL_RESULT_MASK = 0x0f, + HRSL_RCVTOGRD = 1u << 4, + HRSL_SNDTOGRD = 1u << 5, + HRSL_KSTATUS = 1u << 6, + HRSL_JSTATUS = 1u << 7, +}; + +enum { + HRSL_SUCCESS = 0, + HRSL_BUSY, + HRSL_BAD_REQ, + HRSL_UNDEF, + HRSL_NAK, + HRSL_STALL, + HRSL_TOG_ERR, + HRSL_WRONG_PID, + HRSL_BAD_BYTECOUNT, + HRSL_PID_ERR, + HRSL_PKT_ERR, + HRSL_CRC_ERR, + HRSL_K_ERR, + HRSL_J_ERR, + HRSL_TIMEOUT, + HRSL_BABBLE, +}; + +enum { + DEFAULT_HIEN = HIRQ_CONDET_IRQ | HIRQ_FRAME_IRQ | HIRQ_HXFRDN_IRQ +}; + +//--------------------------------------------------------------------+ +// +//--------------------------------------------------------------------+ + +typedef struct { + uint8_t xfer_type; + uint8_t data_toggle; + uint16_t packet_size; + + uint16_t total_len; + uint16_t xferred_len; + uint8_t* buf; +} hcd_ep_t; + +typedef struct { + bool inited; + + // cached register + uint8_t sndbc; + uint8_t mode; + uint8_t peraddr; + uint8_t hxfr; + + volatile uint16_t frame_count; + + hcd_ep_t ep[8][2]; +} max2341_data_t; + +static max2341_data_t _hcd_data; + +//--------------------------------------------------------------------+ +// API: SPI transfer with MAX3421E, must be implemented by application +//--------------------------------------------------------------------+ + +void tuh_max3421_spi_cs_api(uint8_t rhport, bool active); +bool tuh_max3421_spi_xfer_api(uint8_t rhport, uint8_t const * tx_buf, size_t tx_len, uint8_t * rx_buf, size_t rx_len); + +//void tuh_max3421e_int_enable(uint8_t rhport, bool enabled); + +//--------------------------------------------------------------------+ +// +//--------------------------------------------------------------------+ + +static void fifo_write(uint8_t reg, uint8_t const * buffer, uint16_t len) { + reg |= CMDBYTE_WRITE; + + tuh_max3421_spi_cs_api(0, true); + + tuh_max3421_spi_xfer_api(0, ®, 1, NULL, 0); + tuh_max3421_spi_xfer_api(0, buffer, len, NULL, 0); + + tuh_max3421_spi_cs_api(0, false); +} + +// return HIRQ register since we are in full-duplex mode +static uint8_t reg_write(uint8_t reg, uint8_t data) { + uint8_t tx_buf[2] = {reg | CMDBYTE_WRITE, data}; + uint8_t rx_buf[2] = {0, 0}; + + tuh_max3421_spi_cs_api(0, true); + tuh_max3421_spi_xfer_api(0, tx_buf, 2, rx_buf, 2); + tuh_max3421_spi_cs_api(0, false); + + TU_LOG2("HIRQ: %02X\r\n", rx_buf[0]); + return rx_buf[0]; +} + +static uint8_t reg_read(uint8_t reg) { + uint8_t tx_buf[2] = {reg, 0}; + uint8_t rx_buf[2] = {0, 0}; + + tuh_max3421_spi_cs_api(0, true); + bool ret = tuh_max3421_spi_xfer_api(0, tx_buf, 2, rx_buf, 2); + tuh_max3421_spi_cs_api(0, false); + + return ret ? rx_buf[1] : 0; +} + +static inline uint8_t mode_write(uint8_t data) { + _hcd_data.mode = data; + return reg_write(MODE_ADDR, data); +} + +static inline uint8_t peraddr_write(uint8_t data) { + if ( _hcd_data.peraddr == data ) return 0; // no need to change address + + _hcd_data.peraddr = data; + return reg_write(PERADDR_ADDR, data); +} + +static inline uint8_t hxfr_write(uint8_t data) { + _hcd_data.hxfr = data; + return reg_write(HXFR_ADDR, data); +} + +static inline uint8_t sndbc_write(uint8_t data) { + _hcd_data.sndbc = data; + return reg_write(SNDBC_ADDR, data); +} + + +//--------------------------------------------------------------------+ +// Controller API +//--------------------------------------------------------------------+ + +// optional hcd configuration, called by tuh_configure() +bool hcd_configure(uint8_t rhport, uint32_t cfg_id, const void* cfg_param) { + (void) rhport; + (void) cfg_id; + (void) cfg_param; + + return false; +} + +tusb_speed_t handle_connect_irq(uint8_t rhport) { + (void) rhport; + + uint8_t const hrsl = reg_read(HRSL_ADDR); + uint8_t const jk = hrsl & (HRSL_JSTATUS | HRSL_KSTATUS); + + tusb_speed_t speed; + uint8_t new_mode = MODE_DPPULLDN | MODE_DMPULLDN | MODE_HOST; + + switch(jk) { + case 0x00: + // SEO is disconnected + speed = TUSB_SPEED_INVALID; + break; + + case (HRSL_JSTATUS | HRSL_KSTATUS): + // SE1 is illegal + speed = TUSB_SPEED_INVALID; + break; + + default: { + // Low speed if (LS = 1 and J-state) or (LS = 0 and K-State) + uint8_t const mode = reg_read(MODE_ADDR); + uint8_t const ls_bit = mode & MODE_LOWSPEED; + + if ( (ls_bit && (jk == HRSL_JSTATUS)) || (!ls_bit && (jk == HRSL_KSTATUS)) ) { + speed = TUSB_SPEED_LOW; + new_mode |= MODE_LOWSPEED; + } else { + speed = TUSB_SPEED_FULL; + } + + new_mode |= MODE_SOFKAENAB; // enable SOF since there is new device + + break; + } + } + + mode_write(new_mode); + TU_LOG2_INT(speed); + return speed; +} + +// Initialize controller to host mode +bool hcd_init(uint8_t rhport) { + (void) rhport; + + tu_memclr(&_hcd_data, sizeof(_hcd_data)); + + // full duplex, interrupt negative edge + reg_write(PINCTL_ADDR, PINCTL_FDUPSPI); + + // reset + reg_write(USBCTL_ADDR, USBCTL_CHIPRES); + reg_write(USBCTL_ADDR, 0); + while( !(reg_read(USBIRQ_ADDR) & USBIRQ_OSCOK_IRQ) ) { + // wait for oscillator to stabilize + } + + // Mode: Host and DP/DM pull down + mode_write(MODE_DPPULLDN | MODE_DMPULLDN | MODE_HOST); + + // bus reset, this will trigger CONDET IRQ if device is already connected + reg_write(HCTL_ADDR, HCTL_BUSRST); + + // clear all previously pending IRQ + reg_write(HIRQ_ADDR, 0xff); + + _hcd_data.inited = true; + + // Enable Connection IRQ + reg_write(HIEN_ADDR, DEFAULT_HIEN); + + // Enable Interrupt pin + reg_write(CPUCTL_ADDR, CPUCTL_IE); + + return true; +} + +// Enable USB interrupt +void hcd_int_enable (uint8_t rhport) { + (void) rhport; +} + +// Disable USB interrupt +void hcd_int_disable(uint8_t rhport) { + (void) rhport; +} + +// Get frame number (1ms) +uint32_t hcd_frame_number(uint8_t rhport) { + (void) rhport; + return (uint32_t ) _hcd_data.frame_count; +} + +//--------------------------------------------------------------------+ +// Port API +//--------------------------------------------------------------------+ + +// Get the current connect status of roothub port +bool hcd_port_connect_status(uint8_t rhport) { + (void) rhport; + return (_hcd_data.mode & MODE_SOFKAENAB) ? true : false; +} + +// Reset USB bus on the port. Return immediately, bus reset sequence may not be complete. +// Some port would require hcd_port_reset_end() to be invoked after 10ms to complete the reset sequence. +void hcd_port_reset(uint8_t rhport) { + (void) rhport; + // Bus reset will also trigger CONDET IRQ, disable it + uint8_t hien = DEFAULT_HIEN & ~HIRQ_CONDET_IRQ; + reg_write(HIEN_ADDR, hien); + + reg_write(HCTL_ADDR, HCTL_BUSRST); +} + +// Complete bus reset sequence, may be required by some controllers +void hcd_port_reset_end(uint8_t rhport) { + (void) rhport; + reg_write(HCTL_ADDR, 0); + + // Bus reset will also trigger CONDET IRQ, clear and re-enable it after reset + reg_write(HIRQ_ADDR, HIRQ_CONDET_IRQ); + reg_write(HIEN_ADDR, DEFAULT_HIEN); +} + +// Get port link speed +tusb_speed_t hcd_port_speed_get(uint8_t rhport) { + (void) rhport; + return (_hcd_data.mode & MODE_LOWSPEED) ? TUSB_SPEED_LOW : TUSB_SPEED_FULL; +} + +// HCD closes all opened endpoints belong to this device +void hcd_device_close(uint8_t rhport, uint8_t dev_addr) { + (void) rhport; + (void) dev_addr; +} + +//--------------------------------------------------------------------+ +// Endpoints API +//--------------------------------------------------------------------+ + +// Open an endpoint +bool hcd_edpt_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_endpoint_t const * ep_desc) { + (void) rhport; + (void) dev_addr; + (void) ep_desc; + + uint8_t ep_num = tu_edpt_number(ep_desc->bEndpointAddress); + uint8_t ep_dir = tu_edpt_dir(ep_desc->bEndpointAddress); + + _hcd_data.ep[ep_num][ep_dir].packet_size = tu_edpt_packet_size(ep_desc); + + return true; +} + +// Submit a transfer, when complete hcd_event_xfer_complete() must be invoked +bool hcd_edpt_xfer(uint8_t rhport, uint8_t daddr, uint8_t ep_addr, uint8_t * buffer, uint16_t buflen) { + (void) rhport; + + uint8_t const ep_num = tu_edpt_number(ep_addr); + uint8_t const ep_dir = tu_edpt_dir(ep_addr); + + hcd_ep_t* ep = &_hcd_data.ep[ep_num][ep_dir]; + + ep->buf = buffer; + ep->total_len = buflen; + ep->xferred_len = 0; + + uint8_t hirq = peraddr_write(daddr); + + uint8_t hctl = 0; + uint8_t hxfr = ep_num; + if ( ep_num == 0 ) { + ep->data_toggle = 1; + if ( buffer == NULL || buflen == 0 ) { + // ZLP for ACK stage + hxfr |= HXFR_HS; + } + } else if ( ep->xfer_type == TUSB_XFER_ISOCHRONOUS ) { + hxfr |= HXFR_ISO; + } + + if ( 0 == ep_dir ) { + // Page 12: Programming BULK-OUT Transfers + TU_ASSERT(hirq & HIRQ_RCVDAV_IRQ); + + uint8_t const xact_len = (uint8_t) tu_min16(buflen, ep->packet_size); + fifo_write(SNDFIFO_ADDR, buffer, xact_len); + reg_write(SNDBC_ADDR, xact_len); + + hctl = (ep->data_toggle ? HCTL_SNDTOG1 : HCTL_SNDTOG0); + hxfr |= HXFR_OUT_NIN; + } else { + // Page 13: Programming BULK-IN Transfers + hctl = (ep->data_toggle ? HCTL_RCVTOG1 : HCTL_RCVTOG0); + } + + reg_write(HCTL_ADDR, hctl); + hxfr_write(hxfr); + + return true; +} + +// Abort a queued transfer. Note: it can only abort transfer that has not been started +// Return true if a queued transfer is aborted, false if there is no transfer to abort +bool hcd_edpt_abort_xfer(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr) { + (void) rhport; + (void) dev_addr; + (void) ep_addr; + + return false; +} + +// Submit a special transfer to send 8-byte Setup Packet, when complete hcd_event_xfer_complete() must be invoked +bool hcd_setup_send(uint8_t rhport, uint8_t daddr, uint8_t const setup_packet[8]) { + (void) rhport; + + hcd_ep_t* ep = &_hcd_data.ep[0][0]; + ep->total_len = 8; + ep->xferred_len = 0; + + peraddr_write(daddr); + fifo_write(SUDFIFO_ADDR, setup_packet, 8); + hxfr_write(HXFR_SETUP); + + return true; +} + +// clear stall, data toggle is also reset to DATA0 +bool hcd_edpt_clear_stall(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr) { + (void) rhport; + (void) dev_addr; + (void) ep_addr; + + return false; +} + +static void handle_xfer_done(uint8_t rhport) { + (void) rhport; + + uint8_t const hrsl = reg_read(HRSL_ADDR); + uint8_t const result = hrsl & HRSL_RESULT_MASK; + uint8_t xfer_result; + + TU_LOG3("HRSL: %02X\r\n", hrsl); + switch(result) { + case HRSL_SUCCESS: + xfer_result = XFER_RESULT_SUCCESS; + break; + + case HRSL_STALL: + xfer_result = XFER_RESULT_STALLED; + break; + + case HRSL_BAD_REQ: + // occurred when initialized without any pending transfer. Skip for now + return; + + default: + xfer_result = XFER_RESULT_FAILED; + break; + } + + uint8_t ep_dir = 0; + uint8_t ep_num = _hcd_data.hxfr & HXFR_EPNUM_MASK; + uint8_t const xfer_type = _hcd_data.hxfr & 0xf0; + + hcd_ep_t * ep; + + if ( (xfer_type & HXFR_SETUP) || (xfer_type & HXFR_OUT_NIN) ) { + // SETUP or OUT transfer + ep_dir = 0; + ep = &_hcd_data.ep[ep_num][ep_dir]; + + uint8_t const xact_len = (xfer_type & HXFR_SETUP) ? 8 : _hcd_data.sndbc; + ep->xferred_len += xact_len; + + if ( xact_len < ep->packet_size || ep->xferred_len >= ep->total_len ) { + hcd_event_xfer_complete(_hcd_data.peraddr, ep_num, ep->xferred_len, xfer_result, true); + }else { + // more to transfer + } + } else { + // IN transfer + ep_dir = 1; + ep = &_hcd_data.ep[ep_num][ep_dir]; + uint8_t const xact_len = reg_read(RCVBC_ADDR); + ep->xferred_len += xact_len; + + // short packet or all bytes transferred + if ( xact_len < ep->packet_size || ep->xferred_len >= ep->total_len ) { + hcd_event_xfer_complete(_hcd_data.peraddr, TUSB_DIR_IN_MASK | ep_num, ep->xferred_len, xfer_result, true); + }else { + // more to transfer + } + } +} + +// Interrupt Handler +void hcd_int_handler(uint8_t rhport) { + // not initialized, do nothing + if ( !_hcd_data.inited ) return; + + uint8_t hirq = reg_read(HIRQ_ADDR); + TU_LOG3_HEX(hirq); + + if (hirq & HIRQ_FRAME_IRQ) { + _hcd_data.frame_count++; + } + + if (hirq & HIRQ_CONDET_IRQ) { + tusb_speed_t speed = handle_connect_irq(rhport); + + if (speed == TUSB_SPEED_INVALID) { + hcd_event_device_remove(rhport, true); + }else { + hcd_event_device_attach(rhport, true); + } + } + + if (hirq & HIRQ_HXFRDN_IRQ) { + handle_xfer_done(rhport); + } + + if ( hirq & HIRQ_RCVDAV_IRQ ) { + TU_LOG3("RCVDAV\r\n"); + TU_LOG3_INT(reg_read(RCVBC_ADDR)); + } + + // clear all interrupt execept SNDBAV_IRQ + hirq &= ~HIRQ_SNDBAV_IRQ; + if ( hirq ) { + reg_write(HIRQ_ADDR, hirq); + } +} + +#endif diff --git a/src/portable/analog/max3421e/hcd_max3421e.c b/src/portable/analog/max3421e/hcd_max3421e.c deleted file mode 100644 index c9596f695..000000000 --- a/src/portable/analog/max3421e/hcd_max3421e.c +++ /dev/null @@ -1,503 +0,0 @@ -/* - * The MIT License (MIT) - * - * Copyright (c) 2023 Ha Thach (tinyusb.org) - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - * This file is part of the TinyUSB stack. - */ - -#include "tusb_option.h" - -#if CFG_TUH_ENABLED && defined(CFG_TUH_MAX3421E) && CFG_TUH_MAX3421E - -#include "host/hcd.h" - -//--------------------------------------------------------------------+ -// -//--------------------------------------------------------------------+ - -// Command format is -// Reg [7:3] | 0 [2] | Dir [1] | Ack [0] - -enum { - CMDBYTE_WRITE = 0x02, -}; - -enum { - RCVVFIFO_ADDR = 1u << 3, // 0x08 - SNDFIFO_ADDR = 2u << 3, // 0x10 - SUDFIFO_ADDR = 4u << 3, // 0x20 - RCVBC_ADDR = 6u << 3, // 0x30 - SNDBC_ADDR = 7u << 3, // 0x38 - USBIRQ_ADDR = 13u << 3, // 0x68 - USBIEN_ADDR = 14u << 3, // 0x70 - USBCTL_ADDR = 15u << 3, // 0x78 - CPUCTL_ADDR = 16u << 3, // 0x80 - PINCTL_ADDR = 17u << 3, // 0x88 - REVISION_ADDR = 18u << 3, // 0x90 - HIRQ_ADDR = 25u << 3, // 0xC8 - HIEN_ADDR = 26u << 3, // 0xD0 - MODE_ADDR = 27u << 3, // 0xD8 - PERADDR_ADDR = 28u << 3, // 0xE0 - HCTL_ADDR = 29u << 3, // 0xE8 - HXFR_ADDR = 30u << 3, // 0xF0 - HRSL_ADDR = 31u << 3, // 0xF8 -}; - -enum { - USBIRQ_OSCOK_IRQ = 1u << 0, - USBIRQ_NOVBUS_IRQ = 1u << 5, - USBIRQ_VBUS_IRQ = 1u << 6, -}; - -enum { - USBCTL_PWRDOWN = 1u << 4, - USBCTL_CHIPRES = 1u << 5, -}; - -enum { - CPUCTL_IE = 1u << 0, - CPUCTL_PULSEWID0 = 1u << 6, - CPUCTL_PULSEWID1 = 1u << 7, -}; - -enum { - PINCTL_GPXA = 1u << 0, - PINCTL_GPXB = 1u << 1, - PINCTL_POSINT = 1u << 2, - PINCTL_INTLEVEL = 1u << 3, - PINCTL_FDUPSPI = 1u << 4, -}; - -enum { - HIRQ_BUSEVENT_IRQ = 1u << 0, - HIRQ_RWU_IRQ = 1u << 1, - HIRQ_RCVDAV_IRQ = 1u << 2, - HIRQ_SNDBAV_IRQ = 1u << 3, - HIRQ_SUSDN_IRQ = 1u << 4, - HIRQ_CONDET_IRQ = 1u << 5, - HIRQ_FRAME_IRQ = 1u << 6, - HIRQ_HXFRDN_IRQ = 1u << 7, -}; - -enum { - MODE_HOST = 1u << 0, - MODE_LOWSPEED = 1u << 1, - MODE_HUBPRE = 1u << 2, - MODE_SOFKAENAB = 1u << 3, - MODE_SEPIRQ = 1u << 4, - MODE_DELAYISO = 1u << 5, - MODE_DMPULLDN = 1u << 6, - MODE_DPPULLDN = 1u << 7, -}; - -enum { - HCTL_BUSRST = 1u << 1, - HCTL_FRMRST = 1u << 2, - HCTL_SAMPLEBUS = 1u << 3, - HCTL_SIGRSM = 1u << 4, - HCTL_RCVTOG0 = 1u << 5, - HCTL_RCVTOG1 = 1u << 6, - HCTL_SNDTOG0 = 1u << 7, - HCTL_SNDTOG1 = 1u << 8, -}; - -enum { - HXFR_EPNUM_MASK = 0x0f, - HXFR_SETUP = 1u << 4, - HXFR_OUT_NIN = 1u << 5, - HXFR_ISO = 1u << 6, - HXFR_HS = 1u << 7, -}; - -enum { - HRSL_RESULT_MASK = 0x0f, - HRSL_RCVTOGRD = 1u << 4, - HRSL_SNDTOGRD = 1u << 5, - HRSL_KSTATUS = 1u << 6, - HRSL_JSTATUS = 1u << 7, -}; - -enum { - HRSL_SUCCESS = 0, - HRSL_BUSY, - HRSL_BAD_REQ, - HRSL_UNDEF, - HRSL_NAK, - HRSL_STALL, - HRSL_TOG_ERR, - HRSL_WRONG_PID, - HRSL_BAD_BYTECOUNT, - HRSL_PID_ERR, - HRSL_PKT_ERR, - HRSL_CRC_ERR, - HRSL_K_ERR, - HRSL_J_ERR, - HRSL_TIMEOUT, - HRSL_BABBLE, -}; - - -//--------------------------------------------------------------------+ -// -//--------------------------------------------------------------------+ - -typedef struct { - // cached register - uint8_t mode; - uint8_t peraddr; - uint8_t hxfr; - - volatile uint16_t frame_count; - - struct { - uint16_t packet_size; - uint16_t total_len; - uint8_t xfer_type; - }ep[8][2]; -} max2341e_data_t; - -static max2341e_data_t _hcd_data; - -//--------------------------------------------------------------------+ -// API: SPI transfer with MAX3421E, must be implemented by application -//--------------------------------------------------------------------+ - -bool tuh_max3421e_spi_xfer_api(uint8_t rhport, uint8_t const * tx_buf, size_t tx_len, - uint8_t * rx_buf, size_t rx_len, bool keep_cs); -//void tuh_max3421e_int_enable(uint8_t rhport, bool enabled); - -//--------------------------------------------------------------------+ -// -//--------------------------------------------------------------------+ - -// return HIRQ register since we are in full-duplex mode -static uint8_t reg_write(uint8_t reg, uint8_t data) { - uint8_t tx_buf[2] = {reg | CMDBYTE_WRITE, data}; - uint8_t rx_buf[2] = {0, 0}; - tuh_max3421e_spi_xfer_api(0, tx_buf, 2, rx_buf, 2, false); - TU_LOG2("HIRQ: %02X\r\n", rx_buf[0]); - return rx_buf[0]; -} - -static uint8_t reg_read(uint8_t reg) { - uint8_t tx_buf[2] = {reg, 0}; - uint8_t rx_buf[2] = {0, 0}; - return tuh_max3421e_spi_xfer_api(0, tx_buf, 2, rx_buf, 2, false) ? rx_buf[1] : 0; -} - -static inline uint8_t mode_write(uint8_t data) { - _hcd_data.mode = data; - return reg_write(MODE_ADDR, data); -} - -static inline uint8_t peraddr_write(uint8_t data) { - if ( _hcd_data.peraddr == data ) return 0; // no need to change address - - _hcd_data.peraddr = data; - return reg_write(PERADDR_ADDR, data); -} - -static inline uint8_t hxfr_write(uint8_t data) { - _hcd_data.hxfr = data; - return reg_write(HXFR_ADDR, data); -} - -static void fifo_write(uint8_t reg, uint8_t const * buffer, uint16_t len) { - uint8_t tx_buf[1] = {reg | CMDBYTE_WRITE}; - tuh_max3421e_spi_xfer_api(0, tx_buf, 1, NULL, 0, true); - tuh_max3421e_spi_xfer_api(0, buffer, len, NULL, 0, false); -} - - -//--------------------------------------------------------------------+ -// Controller API -//--------------------------------------------------------------------+ - -// optional hcd configuration, called by tuh_configure() -bool hcd_configure(uint8_t rhport, uint32_t cfg_id, const void* cfg_param) { - (void) rhport; - (void) cfg_id; - (void) cfg_param; - - return false; -} - -tusb_speed_t handle_connect_irq(uint8_t rhport) { - (void) rhport; - - uint8_t const hrsl = reg_read(HRSL_ADDR); - uint8_t const jk = hrsl & (HRSL_JSTATUS | HRSL_KSTATUS); - - tusb_speed_t speed; - uint8_t new_mode = MODE_DPPULLDN | MODE_DMPULLDN | MODE_HOST; - - switch(jk) { - case 0x00: - // SEO is disconnected - speed = TUSB_SPEED_INVALID; - break; - - case (HRSL_JSTATUS | HRSL_KSTATUS): - // SE1 is illegal - speed = TUSB_SPEED_INVALID; - break; - - default: { - // Low speed if (LS = 1 and J-state) or (LS = 0 and K-State) - uint8_t const mode = reg_read(MODE_ADDR); - uint8_t const ls_bit = mode & MODE_LOWSPEED; - - if ( (ls_bit && (jk == HRSL_JSTATUS)) || (!ls_bit && (jk == HRSL_KSTATUS)) ) { - speed = TUSB_SPEED_LOW; - new_mode |= MODE_LOWSPEED; - } else { - speed = TUSB_SPEED_FULL; - } - - new_mode |= MODE_SOFKAENAB; // enable SOF since there is new device - - break; - } - } - - mode_write(new_mode); - TU_LOG2_INT(speed); - return speed; -} - -// Initialize controller to host mode -bool hcd_init(uint8_t rhport) { - (void) rhport; - - tu_memclr(&_hcd_data, sizeof(_hcd_data)); - - // full duplex, interrupt level (should be configurable) - reg_write(PINCTL_ADDR, PINCTL_FDUPSPI | PINCTL_INTLEVEL); - - // reset - reg_write(USBCTL_ADDR, USBCTL_CHIPRES); - reg_write(USBCTL_ADDR, 0); - while( !(reg_read(USBIRQ_ADDR) & USBIRQ_OSCOK_IRQ) ) { - // wait for oscillator to stabilize - } - - // Mode: Host and DP/DM pull down - mode_write(MODE_DPPULLDN | MODE_DMPULLDN | MODE_HOST); - - // Enable Connection IRQ - reg_write(HIEN_ADDR, HIRQ_CONDET_IRQ | HIRQ_FRAME_IRQ | HIRQ_HXFRDN_IRQ); - - #if 0 - // Note: if device is already connected, CONDET IRQ may not be triggered. - // We need to detect it by sampling bus signal. FIXME not working - reg_write(HCTL_ADDR, HCTL_SAMPLEBUS); - while ( reg_read(HCTL_ADDR) & HCTL_SAMPLEBUS ) {} - - if ( TUSB_SPEED_INVALID != handle_connect_irq(rhport) ) { - reg_write(HIRQ_ADDR, HIRQ_CONDET_IRQ); // clear connect irq - } - #endif - - // Enable Interrupt pin - reg_write(CPUCTL_ADDR, CPUCTL_IE); - - return true; -} - -// Enable USB interrupt -void hcd_int_enable (uint8_t rhport) { - (void) rhport; -} - -// Disable USB interrupt -void hcd_int_disable(uint8_t rhport) { - (void) rhport; -} - -// Get frame number (1ms) -uint32_t hcd_frame_number(uint8_t rhport) { - (void) rhport; - return (uint32_t ) _hcd_data.frame_count; -} - -//--------------------------------------------------------------------+ -// Port API -//--------------------------------------------------------------------+ - -// Get the current connect status of roothub port -bool hcd_port_connect_status(uint8_t rhport) { - (void) rhport; - return (_hcd_data.mode & MODE_SOFKAENAB) ? true : false; -} - -// Reset USB bus on the port. Return immediately, bus reset sequence may not be complete. -// Some port would require hcd_port_reset_end() to be invoked after 10ms to complete the reset sequence. -void hcd_port_reset(uint8_t rhport) { - (void) rhport; - reg_write(HCTL_ADDR, HCTL_BUSRST); -} - -// Complete bus reset sequence, may be required by some controllers -void hcd_port_reset_end(uint8_t rhport) { - (void) rhport; - reg_write(HCTL_ADDR, 0); -} - -// Get port link speed -tusb_speed_t hcd_port_speed_get(uint8_t rhport) { - (void) rhport; - return (_hcd_data.mode & MODE_LOWSPEED) ? TUSB_SPEED_LOW : TUSB_SPEED_FULL; -} - -// HCD closes all opened endpoints belong to this device -void hcd_device_close(uint8_t rhport, uint8_t dev_addr) { - (void) rhport; - (void) dev_addr; -} - -//--------------------------------------------------------------------+ -// Endpoints API -//--------------------------------------------------------------------+ - -// Open an endpoint -bool hcd_edpt_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_endpoint_t const * ep_desc) { - (void) rhport; - (void) dev_addr; - (void) ep_desc; - - uint8_t ep_num = tu_edpt_number(ep_desc->bEndpointAddress); - uint8_t ep_dir = tu_edpt_dir(ep_desc->bEndpointAddress); - - _hcd_data.ep[ep_num][ep_dir].packet_size = tu_edpt_packet_size(ep_desc); - - return true; -} - -// Submit a transfer, when complete hcd_event_xfer_complete() must be invoked -bool hcd_edpt_xfer(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr, uint8_t * buffer, uint16_t buflen) { - (void) rhport; - (void) dev_addr; - (void) ep_addr; - (void) buffer; - (void) buflen; - - return false; -} - -// Abort a queued transfer. Note: it can only abort transfer that has not been started -// Return true if a queued transfer is aborted, false if there is no transfer to abort -bool hcd_edpt_abort_xfer(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr) { - (void) rhport; - (void) dev_addr; - (void) ep_addr; - - return false; -} - -// Submit a special transfer to send 8-byte Setup Packet, when complete hcd_event_xfer_complete() must be invoked -bool hcd_setup_send(uint8_t rhport, uint8_t daddr, uint8_t const setup_packet[8]) { - (void) rhport; - (void) daddr; - (void) setup_packet; - - _hcd_data.ep[0][0].total_len = 8; - - peraddr_write(daddr); - fifo_write(SUDFIFO_ADDR, setup_packet, 8); - hxfr_write(HXFR_SETUP); - - return true; -} - -// clear stall, data toggle is also reset to DATA0 -bool hcd_edpt_clear_stall(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr) { - (void) rhport; - (void) dev_addr; - (void) ep_addr; - - return false; -} - -// Interrupt Handler -void hcd_int_handler(uint8_t rhport) { - uint8_t hirq = reg_read(HIRQ_ADDR); - TU_LOG3_HEX(hirq); - - if (hirq & HIRQ_CONDET_IRQ) { - tusb_speed_t speed = handle_connect_irq(rhport); - - if (speed == TUSB_SPEED_INVALID) { - hcd_event_device_remove(rhport, true); - }else { - hcd_event_device_attach(rhport, true); - } - } - - if (hirq & HIRQ_FRAME_IRQ) { - _hcd_data.frame_count++; - } - - if (hirq & HIRQ_HXFRDN_IRQ) { - uint8_t const hrsl = reg_read(HRSL_ADDR); - uint8_t const result = hrsl & HRSL_RESULT_MASK; - uint8_t xfer_result; - - TU_LOG3("HRSL: %02X\r\n", hrsl); - switch(result) { - case HRSL_SUCCESS: - xfer_result = XFER_RESULT_SUCCESS; - break; - - case HRSL_STALL: - xfer_result = XFER_RESULT_STALLED; - break; - - default: - xfer_result = XFER_RESULT_FAILED; - break; - } - - uint8_t ep_dir = 0; - uint8_t ep_num = _hcd_data.hxfr & HXFR_EPNUM_MASK; - uint8_t const xfer_type = _hcd_data.hxfr & 0xf0; - - if ( xfer_type & HXFR_SETUP ) { - // SETUP transfer - ep_dir = 0; - }else if ( !(xfer_type & HXFR_OUT_NIN) ) { - // IN transfer - ep_dir = 1; - } - - uint8_t const ep_addr = tu_edpt_addr(ep_num, ep_dir); - uint16_t xferred_len = _hcd_data.ep[ep_num][ep_dir].total_len; - - hcd_event_xfer_complete(_hcd_data.peraddr, ep_addr, xferred_len, xfer_result, true); - } - - // clear all interrupt - if ( hirq ) { - reg_write(HIRQ_ADDR, hirq); - } -} - -#endif -- cgit v1.3.1 From 502b1bdda62f0f207d9a51daf134574e455f3aa2 Mon Sep 17 00:00:00 2001 From: hathach Date: Sun, 27 Aug 2023 23:45:34 +0700 Subject: more update to transaction --- examples/host/cdc_msc_hid/src/tusb_config.h | 9 ++-- examples/host/msc_file_explorer/src/tusb_config.h | 10 +++-- src/common/tusb_mcu.h | 12 ++++++ src/host/hcd.h | 4 +- src/host/usbh.c | 1 + src/portable/analog/max3421/hcd_max3421.c | 51 +++++++++++++++-------- 6 files changed, 62 insertions(+), 25 deletions(-) (limited to 'src/host') diff --git a/examples/host/cdc_msc_hid/src/tusb_config.h b/examples/host/cdc_msc_hid/src/tusb_config.h index abb75f068..7d621d466 100644 --- a/examples/host/cdc_msc_hid/src/tusb_config.h +++ b/examples/host/cdc_msc_hid/src/tusb_config.h @@ -35,9 +35,12 @@ //--------------------------------------------------------------------+ #if CFG_TUSB_MCU == OPT_MCU_RP2040 -// change to 1 if using pico-pio-usb as host controller for raspberry rp2040 -#define CFG_TUH_RPI_PIO_USB 0 -#define BOARD_TUH_RHPORT CFG_TUH_RPI_PIO_USB + // change to 1 if using pico-pio-usb as host controller for raspberry rp2040 + #define CFG_TUH_RPI_PIO_USB 0 + #define BOARD_TUH_RHPORT CFG_TUH_RPI_PIO_USB +#elif CFG_TUSB_MCU == OPT_MCU_NRF5X + // Use external USB controller (via SPI) MAX3421E (aka usb host shield) + #define CFG_TUH_MAX3421 1 #endif // RHPort number used for host can be defined by board.mk, default to port 0 diff --git a/examples/host/msc_file_explorer/src/tusb_config.h b/examples/host/msc_file_explorer/src/tusb_config.h index 1e0d067bf..bb2fd4cf5 100644 --- a/examples/host/msc_file_explorer/src/tusb_config.h +++ b/examples/host/msc_file_explorer/src/tusb_config.h @@ -35,11 +35,15 @@ //--------------------------------------------------------------------+ #if CFG_TUSB_MCU == OPT_MCU_RP2040 -// change to 1 if using pico-pio-usb as host controller for raspberry rp2040 -#define CFG_TUH_RPI_PIO_USB 0 -#define BOARD_TUH_RHPORT CFG_TUH_RPI_PIO_USB + // change to 1 if using pico-pio-usb as host controller for raspberry rp2040 + #define CFG_TUH_RPI_PIO_USB 0 + #define BOARD_TUH_RHPORT CFG_TUH_RPI_PIO_US +#elif CFG_TUSB_MCU == OPT_MCU_NRF5X + // Use external USB controller (via SPI) MAX3421E (aka usb host shield) + #define CFG_TUH_MAX3421 1 #endif + // RHPort number used for host can be defined by board.mk, default to port 0 #ifndef BOARD_TUH_RHPORT #define BOARD_TUH_RHPORT 0 diff --git a/src/common/tusb_mcu.h b/src/common/tusb_mcu.h index 35f94efbc..21939df7c 100644 --- a/src/common/tusb_mcu.h +++ b/src/common/tusb_mcu.h @@ -385,6 +385,18 @@ #define TUP_RHPORT_HIGHSPEED 1 #endif + +//--------------------------------------------------------------------+ +// External USB controller +//--------------------------------------------------------------------+ + +#if defined(CFG_TUH_MAX3421) & CFG_TUH_MAX3421 + #ifndef CFG_TUH_MAX3421_ENDPOINT_TOTAL + #define CFG_TUH_MAX3421_ENDPOINT_TOTAL (8 + 4*(CFG_TUH_DEVICE_MAX-1)) + #endif +#endif + + //--------------------------------------------------------------------+ // Default Values //--------------------------------------------------------------------+ diff --git a/src/host/hcd.h b/src/host/hcd.h index 1f01a1a2f..e25b20ea3 100644 --- a/src/host/hcd.h +++ b/src/host/hcd.h @@ -39,7 +39,7 @@ // Configuration //--------------------------------------------------------------------+ -// Max number of endpoints per device +// Max number of endpoints pair per device // TODO optimize memory usage #ifndef CFG_TUH_ENDPOINT_MAX #define CFG_TUH_ENDPOINT_MAX 16 @@ -167,7 +167,7 @@ void hcd_device_close(uint8_t rhport, uint8_t dev_addr); //--------------------------------------------------------------------+ // Open an endpoint -bool hcd_edpt_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_endpoint_t const * ep_desc); +bool hcd_edpt_open(uint8_t rhport, uint8_t daddr, tusb_desc_endpoint_t const * ep_desc); // Submit a transfer, when complete hcd_event_xfer_complete() must be invoked bool hcd_edpt_xfer(uint8_t rhport, uint8_t daddr, uint8_t ep_addr, uint8_t * buffer, uint16_t buflen); diff --git a/src/host/usbh.c b/src/host/usbh.c index 7a09f5b6e..12a7f5839 100644 --- a/src/host/usbh.c +++ b/src/host/usbh.c @@ -919,6 +919,7 @@ TU_ATTR_FAST_FUNC void hcd_event_handler(hcd_event_t const* event, bool in_isr) switch (event->event_id) { // case HCD_EVENT_DEVICE_REMOVE: +// // FIXME device remove from a hub need an HCD API for hcd to free up endpoint // // mark device as removing to prevent further xfer before the event is processed in usbh task // break; diff --git a/src/portable/analog/max3421/hcd_max3421.c b/src/portable/analog/max3421/hcd_max3421.c index e546f99ce..574cca788 100644 --- a/src/portable/analog/max3421/hcd_max3421.c +++ b/src/portable/analog/max3421/hcd_max3421.c @@ -582,6 +582,7 @@ void xact_out(uint8_t rhport, max3421_ep_t *ep, bool switch_ep, bool in_isr) { } uint8_t const xact_len = (uint8_t) tu_min16(ep->total_len - ep->xferred_len, ep->packet_size); + TU_ASSERT(_hcd_data.hirq & HIRQ_SNDBAV_IRQ, ); fifo_write(rhport, SNDFIFO_ADDR, ep->buf, xact_len, in_isr); sndbc_write(rhport, xact_len, in_isr); @@ -602,6 +603,28 @@ void xact_in(uint8_t rhport, max3421_ep_t *ep, bool switch_ep, bool in_isr) { hxfr_write(rhport, hxfr, in_isr); } +TU_ATTR_ALWAYS_INLINE static inline void xact_inout(uint8_t rhport, max3421_ep_t *ep, bool switch_ep, bool in_isr) { + if (ep->ep_dir) { + xact_in(rhport, ep, switch_ep, in_isr); + }else { + xact_out(rhport, ep, switch_ep, in_isr); + } +} + +void xfer_complete_isr(uint8_t rhport, max3421_ep_t *ep, xfer_result_t result, uint8_t data_toggle) { + (void) rhport; + (void) result; + ep->xfer_pending = 0; + ep->data_toggle = data_toggle; + //uint8_t const ep_addr = tu_edpt_addr(ep->ep_num, ep->ep_dir); + //hcd_event_xfer_complete(rhport, ep_addr, ep->xferred_len, result, true); + +// max3421_ep_t *next_ep = find_next_pending_ep(ep); +// if (next_ep) { +// xact_inout(rhport, next_ep, true, true); +// } +} + // Submit a transfer, when complete hcd_event_xfer_complete() must be invoked bool hcd_edpt_xfer(uint8_t rhport, uint8_t daddr, uint8_t ep_addr, uint8_t * buffer, uint16_t buflen) { (void) rhport; @@ -612,6 +635,9 @@ bool hcd_edpt_xfer(uint8_t rhport, uint8_t daddr, uint8_t ep_addr, uint8_t * buf max3421_ep_t* ep = find_opened_ep(daddr, ep_num, ep_dir); TU_ASSERT(ep); + // control transfer can switch direction + ep->ep_dir = ep_dir; + ep->buf = buffer; ep->total_len = buflen; ep->xferred_len = 0; @@ -636,12 +662,7 @@ bool hcd_edpt_xfer(uint8_t rhport, uint8_t daddr, uint8_t ep_addr, uint8_t * buf } } - if ( 0 == ep_dir ) { - TU_ASSERT(_hcd_data.hirq & HIRQ_SNDBAV_IRQ); - xact_out(rhport, ep, true, false); - } else { - xact_in(rhport, ep, true, false); - } + xact_inout(rhport, ep, true, false); } return true; @@ -662,6 +683,7 @@ bool hcd_setup_send(uint8_t rhport, uint8_t daddr, uint8_t const setup_packet[8] (void) rhport; max3421_ep_t* ep = find_opened_ep(daddr, 0, 0); + ep->ep_dir = 0; ep->total_len = 8; ep->xferred_len = 0; @@ -715,18 +737,13 @@ static void handle_xfer_done(uint8_t rhport) { }else { // NAK on non-control, find next pending to switch max3421_ep_t *next_ep = find_next_pending_ep(ep); - TU_ASSERT(next_ep, ); if (ep == next_ep) { // only one pending, retry immediately hxfr_write(rhport, _hcd_data.hxfr, true); - }else { + }else if (next_ep) { // switch to next pending TODO could have issue with double buffered if not clear previously out data - if ( ep_dir ) { - xact_in(rhport, next_ep, true, true); - } else { - xact_out(rhport, next_ep, true, true); - } + xact_inout(rhport, next_ep, true, true); } } return; @@ -744,8 +761,8 @@ static void handle_xfer_done(uint8_t rhport) { // short packet or all bytes transferred if ( ep->xfer_complete ) { - // save data toggle - ep->data_toggle = (hrsl & HRSL_RCVTOGRD) ? 1 : 0; + uint8_t const dt = (hrsl & HRSL_RCVTOGRD) ? 1 : 0; // save data toggle + xfer_complete_isr(rhport, ep, xfer_result, dt); hcd_event_xfer_complete(_hcd_data.peraddr, TUSB_DIR_IN_MASK | ep_num, ep->xferred_len, xfer_result, true); }else { // more to transfer @@ -767,8 +784,8 @@ static void handle_xfer_done(uint8_t rhport) { ep->buf += xact_len; if (xact_len < ep->packet_size || ep->xferred_len >= ep->total_len) { - // save data toggle - ep->data_toggle = (hrsl & HRSL_SNDTOGRD) ? 1 : 0; + uint8_t const dt = (hrsl & HRSL_SNDTOGRD) ? 1 : 0; // save data toggle + xfer_complete_isr(rhport, ep, xfer_result, dt); hcd_event_xfer_complete(_hcd_data.peraddr, ep_num, ep->xferred_len, xfer_result, true); } else { xact_out(rhport, ep, false, true); -- cgit v1.3.1 From 3b7d5aa0421f3d3a7ac199de0138dc40141fbddd Mon Sep 17 00:00:00 2001 From: hathach Date: Thu, 31 Aug 2023 16:52:09 +0700 Subject: improve connection & disconnection detection. But there is still issue when CONDETIRQ occurs but we are disabled interrupt (for osal queue access). --- hw/bsp/board.c | 26 ++++------ hw/bsp/nrf/family.c | 49 ++++++++---------- src/host/usbh.c | 2 +- src/portable/analog/max3421/hcd_max3421.c | 85 ++++++++++++++----------------- 4 files changed, 72 insertions(+), 90 deletions(-) (limited to 'src/host') diff --git a/hw/bsp/board.c b/hw/bsp/board.c index 417630a03..562792625 100644 --- a/hw/bsp/board.c +++ b/hw/bsp/board.c @@ -44,17 +44,16 @@ // If using SES IDE, use the Syscalls/SEGGER_RTT_Syscalls_SES.c instead #if !(defined __SES_ARM) && !(defined __SES_RISCV) && !(defined __CROSSWORKS_ARM) + #include "SEGGER_RTT.h" -TU_ATTR_USED int sys_write (int fhdl, const void *buf, size_t count) -{ +TU_ATTR_USED int sys_write(int fhdl, const void *buf, size_t count) { (void) fhdl; - SEGGER_RTT_Write(0, (const char*) buf, (int) count); + SEGGER_RTT_Write(0, (const char *) buf, (int) count); return count; } -TU_ATTR_USED int sys_read (int fhdl, char *buf, size_t count) -{ +TU_ATTR_USED int sys_read(int fhdl, char *buf, size_t count) { (void) fhdl; int rd = (int) SEGGER_RTT_Read(0, buf, count); return (rd > 0) ? rd : -1; @@ -67,8 +66,7 @@ TU_ATTR_USED int sys_read (int fhdl, char *buf, size_t count) #include "board_mcu.h" -TU_ATTR_USED int sys_write (int fhdl, const void *buf, size_t count) -{ +TU_ATTR_USED int sys_write (int fhdl, const void *buf, size_t count) { (void) fhdl; uint8_t const* buf8 = (uint8_t const*) buf; @@ -79,8 +77,7 @@ TU_ATTR_USED int sys_write (int fhdl, const void *buf, size_t count) return (int) count; } -TU_ATTR_USED int sys_read (int fhdl, char *buf, size_t count) -{ +TU_ATTR_USED int sys_read (int fhdl, char *buf, size_t count) { (void) fhdl; (void) buf; (void) count; @@ -90,14 +87,12 @@ TU_ATTR_USED int sys_read (int fhdl, char *buf, size_t count) #else // Default logging with on-board UART -TU_ATTR_USED int sys_write (int fhdl, const void *buf, size_t count) -{ +TU_ATTR_USED int sys_write (int fhdl, const void *buf, size_t count) { (void) fhdl; return board_uart_write(buf, (int) count); } -TU_ATTR_USED int sys_read (int fhdl, char *buf, size_t count) -{ +TU_ATTR_USED int sys_read (int fhdl, char *buf, size_t count) { (void) fhdl; int rd = board_uart_read((uint8_t*) buf, (int) count); return (rd > 0) ? rd : -1; @@ -105,8 +100,7 @@ TU_ATTR_USED int sys_read (int fhdl, char *buf, size_t count) #endif -int board_getchar(void) -{ +int board_getchar(void) { char c; - return ( sys_read(0, &c, 1) > 0 ) ? (int) c : (-1); + return (sys_read(0, &c, 1) > 0) ? (int) c : (-1); } diff --git a/hw/bsp/nrf/family.c b/hw/bsp/nrf/family.c index 2b4260083..7358458ce 100644 --- a/hw/bsp/nrf/family.c +++ b/hw/bsp/nrf/family.c @@ -98,7 +98,7 @@ TU_ATTR_UNUSED static void power_event_handler(nrfx_power_usb_evt_t event) { static nrfx_spim_t _spi = NRFX_SPIM_INSTANCE(1); void max3421e_int_handler(nrfx_gpiote_pin_t pin, nrf_gpiote_polarity_t action) { - if ( !(pin == MAX3241E_INTR_PIN && action == NRF_GPIOTE_POLARITY_HITOLO) ) return; + if (!(pin == MAX3241E_INTR_PIN && action == NRF_GPIOTE_POLARITY_HITOLO)) return; tuh_int_handler(1); } @@ -111,7 +111,7 @@ void tuh_max3421e_int_api(uint8_t rhport, bool enabled) { if (enabled) { nrfx_gpiote_trigger_enable(MAX3241E_INTR_PIN, true); - }else { + } else { nrfx_gpiote_trigger_disable(MAX3241E_INTR_PIN); } } @@ -121,7 +121,7 @@ void tuh_max3421_spi_cs_api(uint8_t rhport, bool active) { nrf_gpio_pin_write(MAX3421E_CS_PIN, active ? 0 : 1); } -bool tuh_max3421_spi_xfer_api(uint8_t rhport, uint8_t const * tx_buf, size_t tx_len, uint8_t * rx_buf, size_t rx_len) { +bool tuh_max3421_spi_xfer_api(uint8_t rhport, uint8_t const *tx_buf, size_t tx_len, uint8_t *rx_buf, size_t rx_len) { (void) rhport; nrfx_spim_xfer_desc_t xfer = { @@ -157,21 +157,21 @@ void board_init(void) { nrf_gpio_cfg_input(BUTTON_PIN, NRF_GPIO_PIN_PULLUP); // 1ms tick timer - SysTick_Config(SystemCoreClock/1000); + SysTick_Config(SystemCoreClock / 1000); // UART nrfx_uarte_config_t uart_cfg = { - .pseltxd = UART_TX_PIN, - .pselrxd = UART_RX_PIN, - .pselcts = NRF_UARTE_PSEL_DISCONNECTED, - .pselrts = NRF_UARTE_PSEL_DISCONNECTED, - .p_context = NULL, - .baudrate = NRF_UARTE_BAUDRATE_115200, // CFG_BOARD_UART_BAUDRATE - .interrupt_priority = 7, - .hal_cfg = { - .hwfc = NRF_UARTE_HWFC_DISABLED, - .parity = NRF_UARTE_PARITY_EXCLUDED, - } + .pseltxd = UART_TX_PIN, + .pselrxd = UART_RX_PIN, + .pselcts = NRF_UARTE_PSEL_DISCONNECTED, + .pselrts = NRF_UARTE_PSEL_DISCONNECTED, + .p_context = NULL, + .baudrate = NRF_UARTE_BAUDRATE_115200, // CFG_BOARD_UART_BAUDRATE + .interrupt_priority = 7, + .hal_cfg = { + .hwfc = NRF_UARTE_HWFC_DISABLED, + .parity = NRF_UARTE_PARITY_EXCLUDED, + } }; nrfx_uarte_init(&_uart_id, &uart_cfg, NULL); //uart_handler); @@ -211,11 +211,11 @@ void board_init(void) { // USB power may already be ready at this time -> no event generated // We need to invoke the handler based on the status initially - #ifdef NRF5340_XXAA +#ifdef NRF5340_XXAA usb_reg = NRF_USBREGULATOR->USBREGSTATUS; - #else +#else usb_reg = NRF_POWER->USBREGSTATUS; - #endif +#endif } if ( usb_reg & VBUSDETECT_Msk ) tusb_hal_nrf_power_event(USB_EVT_DETECTED); @@ -308,8 +308,7 @@ uint32_t board_millis(void) { #ifdef SOFTDEVICE_PRESENT // process SOC event from SD -uint32_t proc_soc(void) -{ +uint32_t proc_soc(void) { uint32_t soc_evt; uint32_t err = sd_evt_get(&soc_evt); @@ -326,18 +325,14 @@ uint32_t proc_soc(void) return err; } -uint32_t proc_ble(void) -{ +uint32_t proc_ble(void) { // do nothing with ble return NRF_ERROR_NOT_FOUND; } -void SD_EVT_IRQHandler(void) -{ +void SD_EVT_IRQHandler(void) { // process BLE and SOC until there is no more events - while( (NRF_ERROR_NOT_FOUND != proc_ble()) || (NRF_ERROR_NOT_FOUND != proc_soc()) ) - { - + while( (NRF_ERROR_NOT_FOUND != proc_ble()) || (NRF_ERROR_NOT_FOUND != proc_soc()) ) { } } diff --git a/src/host/usbh.c b/src/host/usbh.c index 12a7f5839..bacb3a719 100644 --- a/src/host/usbh.c +++ b/src/host/usbh.c @@ -852,7 +852,7 @@ bool usbh_edpt_xfer_with_callback(uint8_t dev_addr, uint8_t ep_addr, uint8_t * b ep_state->busy = 0; ep_state->claimed = 0; TU_LOG1("Failed\r\n"); - TU_BREAKPOINT(); +// TU_BREAKPOINT(); return false; } } diff --git a/src/portable/analog/max3421/hcd_max3421.c b/src/portable/analog/max3421/hcd_max3421.c index d644390da..56d3aea45 100644 --- a/src/portable/analog/max3421/hcd_max3421.c +++ b/src/portable/analog/max3421/hcd_max3421.c @@ -405,45 +405,46 @@ bool hcd_configure(uint8_t rhport, uint32_t cfg_id, const void* cfg_param) { return false; } -tusb_speed_t handle_connect_irq(uint8_t rhport) { +static void handle_connect_irq(uint8_t rhport) { uint8_t const hrsl = reg_read(rhport, HRSL_ADDR, true); uint8_t const jk = hrsl & (HRSL_JSTATUS | HRSL_KSTATUS); - tusb_speed_t speed; uint8_t new_mode = MODE_DPPULLDN | MODE_DMPULLDN | MODE_HOST; + TU_LOG2_HEX(jk); switch(jk) { - case 0x00: - // SEO is disconnected - speed = TUSB_SPEED_INVALID; - break; - - case (HRSL_JSTATUS | HRSL_KSTATUS): - // SE1 is illegal - speed = TUSB_SPEED_INVALID; + case 0x00: // SEO is disconnected + case (HRSL_JSTATUS | HRSL_KSTATUS): // SE1 is illegal + mode_write(rhport, new_mode, true); + hcd_event_device_remove(rhport, true); break; default: { - // Low speed if (LS = 1 and J-state) or (LS = 0 and K-State) - uint8_t const mode = reg_read(rhport, MODE_ADDR, true); - uint8_t const ls_bit = mode & MODE_LOWSPEED; + // Bus Reset also cause CONDET IRQ, skip if we are already connected and doing bus reset + if ((_hcd_data.hirq & HIRQ_BUSEVENT_IRQ) && (_hcd_data.mode & MODE_SOFKAENAB)) { + break; + } - if ( (ls_bit && (jk == HRSL_JSTATUS)) || (!ls_bit && (jk == HRSL_KSTATUS)) ) { - speed = TUSB_SPEED_LOW; + // Low speed if (LS = 1 and J-state) or (LS = 0 and K-State) + // However, since we are always in full speed mode, we can just check J-state + if (jk == HRSL_KSTATUS) { new_mode |= MODE_LOWSPEED; - } else { - speed = TUSB_SPEED_FULL; + TU_LOG3("Low speed\n"); + }else { + TU_LOG3("Full speed\n"); } + new_mode |= MODE_SOFKAENAB; + mode_write(rhport, new_mode, true); - new_mode |= MODE_SOFKAENAB; // enable SOF since there is new device + // FIXME multiple MAX3421 rootdevice address is not 1 + uint8_t const daddr = 1; + free_ep(daddr); + + hcd_event_device_attach(rhport, true); break; } } - - mode_write(rhport, new_mode, true); - TU_LOG2_INT(speed); - return speed; } // Initialize controller to host mode @@ -500,8 +501,9 @@ bool hcd_init(uint8_t rhport) { // Enable USB interrupt // Not actually enable GPIO interrupt, just set variable to prevent handler to process void hcd_int_enable (uint8_t rhport) { +// tuh_max3421e_int_api(rhport, true); + (void) rhport; - // tuh_max3421e_int_api(rhport, true); if (_hcd_data.intr_disable_count) { _hcd_data.intr_disable_count--; } @@ -510,8 +512,8 @@ void hcd_int_enable (uint8_t rhport) { // Disable USB interrupt // Not actually disable GPIO interrupt, just set variable to prevent handler to process void hcd_int_disable(uint8_t rhport) { - (void) rhport; //tuh_max3421e_int_api(rhport, false); + (void) rhport; _hcd_data.intr_disable_count++; } @@ -534,20 +536,12 @@ bool hcd_port_connect_status(uint8_t rhport) { // Reset USB bus on the port. Return immediately, bus reset sequence may not be complete. // Some port would require hcd_port_reset_end() to be invoked after 10ms to complete the reset sequence. void hcd_port_reset(uint8_t rhport) { - // Bus reset will also trigger CONDET IRQ, disable it - uint8_t const hien = DEFAULT_HIEN & ~HIRQ_CONDET_IRQ; - hien_write(rhport, hien, false); - reg_write(rhport, HCTL_ADDR, HCTL_BUSRST, false); } // Complete bus reset sequence, may be required by some controllers void hcd_port_reset_end(uint8_t rhport) { reg_write(rhport, HCTL_ADDR, 0, false); - - // Bus reset will also trigger CONDET IRQ, clear and re-enable it after reset - hirq_write(rhport, HIRQ_CONDET_IRQ, false); - hien_write(rhport, DEFAULT_HIEN, false); } // Get port link speed @@ -660,7 +654,7 @@ bool hcd_edpt_xfer(uint8_t rhport, uint8_t daddr, uint8_t ep_addr, uint8_t * buf uint8_t const ep_dir = tu_edpt_dir(ep_addr); max3421_ep_t* ep = find_opened_ep(daddr, ep_num, ep_dir); - TU_ASSERT(ep); + TU_VERIFY(ep); // control transfer can switch direction ep->ep_dir = ep_dir; @@ -767,8 +761,6 @@ static void handle_xfer_done(uint8_t rhport) { TU_ASSERT(ep, ); xfer_result_t xfer_result; - -// TU_LOG3("HRSL: %02X\r\n", hrsl); switch(hresult) { case HRSL_SUCCESS: xfer_result = XFER_RESULT_SUCCESS; @@ -803,6 +795,7 @@ static void handle_xfer_done(uint8_t rhport) { return; default: + TU_LOG3("HRSL: %02X\r\n", hrsl); xfer_result = XFER_RESULT_FAILED; break; } @@ -875,30 +868,30 @@ void hcd_int_handler(uint8_t rhport) { if (!hirq) return; // print_hirq(hirq); +// uint8_t hirq = reg_read(rhport, HIRQ_ADDR, true); + if (hirq & HIRQ_FRAME_IRQ) { _hcd_data.frame_count++; } + #if 1 // interrupt is disabled, only ack FRAME IRQ and skip the rest if (_hcd_data.intr_disable_count) { if (hirq & HIRQ_FRAME_IRQ) { hirq_write(rhport, HIRQ_FRAME_IRQ, true); } + + if ((hirq & HIRQ_CONDET_IRQ) && !(_hcd_data.mode & MODE_SOFKAENAB)) { + // connection when interrupt is disabled + TU_LOG3_INT(_hcd_data.intr_disable_count); + return; + } return; } + #endif if (hirq & HIRQ_CONDET_IRQ) { - tusb_speed_t speed = handle_connect_irq(rhport); - - if (speed == TUSB_SPEED_INVALID) { - hcd_event_device_remove(rhport, true); - }else { - // FIXME multiple MAX3421 rootdevice address is not 1 - uint8_t const daddr = 1; - free_ep(daddr); - - hcd_event_device_attach(rhport, true); - } + handle_connect_irq(rhport); } // queue more transfer in handle_xfer_done() can cause hirq to be set again while external IRQ may not catch and/or -- cgit v1.3.1 From 1b9108ea0dc237835e801d26cc7eef052acad987 Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 6 Sep 2023 17:11:35 +0700 Subject: minor debug clean up --- src/common/tusb_common.h | 6 ++---- src/common/tusb_debug.h | 37 ++++++++++++++----------------------- src/device/usbd.c | 2 +- src/device/usbd_pvt.h | 15 ++++++--------- src/host/usbh.c | 6 ++---- 5 files changed, 25 insertions(+), 41 deletions(-) (limited to 'src/host') diff --git a/src/common/tusb_common.h b/src/common/tusb_common.h index c303c6eaf..6fffed11c 100644 --- a/src/common/tusb_common.h +++ b/src/common/tusb_common.h @@ -122,13 +122,11 @@ TU_ATTR_ALWAYS_INLINE static inline int tu_memcpy_s(void *dest, size_t destsz, c //------------- Bytes -------------// -TU_ATTR_ALWAYS_INLINE static inline uint32_t tu_u32(uint8_t b3, uint8_t b2, uint8_t b1, uint8_t b0) -{ +TU_ATTR_ALWAYS_INLINE static inline uint32_t tu_u32(uint8_t b3, uint8_t b2, uint8_t b1, uint8_t b0) { return ( ((uint32_t) b3) << 24) | ( ((uint32_t) b2) << 16) | ( ((uint32_t) b1) << 8) | b0; } -TU_ATTR_ALWAYS_INLINE static inline uint16_t tu_u16(uint8_t high, uint8_t low) -{ +TU_ATTR_ALWAYS_INLINE static inline uint16_t tu_u16(uint8_t high, uint8_t low) { return (uint16_t) ((((uint16_t) high) << 8) | low); } diff --git a/src/common/tusb_debug.h b/src/common/tusb_debug.h index 36507041f..99176c02a 100644 --- a/src/common/tusb_debug.h +++ b/src/common/tusb_debug.h @@ -58,16 +58,14 @@ void tu_print_mem(void const *buf, uint32_t count, uint8_t indent); #define tu_printf printf #endif -static inline void tu_print_arr(uint8_t const* buf, uint32_t bufsize) -{ +static inline void tu_print_buf(uint8_t const* buf, uint32_t bufsize) { for(uint32_t i=0; i= 2 #define TU_LOG2 TU_LOG1 #define TU_LOG2_MEM TU_LOG1_MEM - #define TU_LOG2_ARR TU_LOG1_ARR - #define TU_LOG2_PTR TU_LOG1_PTR + #define TU_LOG2_BUF TU_LOG1_BUF #define TU_LOG2_INT TU_LOG1_INT #define TU_LOG2_HEX TU_LOG1_HEX #endif @@ -95,30 +91,25 @@ static inline void tu_print_arr(uint8_t const* buf, uint32_t bufsize) #if CFG_TUSB_DEBUG >= 3 #define TU_LOG3 TU_LOG1 #define TU_LOG3_MEM TU_LOG1_MEM - #define TU_LOG3_ARR TU_LOG1_ARR - #define TU_LOG3_PTR TU_LOG1_PTR + #define TU_LOG3_BUF TU_LOG1_BUF #define TU_LOG3_INT TU_LOG1_INT #define TU_LOG3_HEX TU_LOG1_HEX #endif -typedef struct -{ +typedef struct { uint32_t key; const char* data; } tu_lookup_entry_t; -typedef struct -{ +typedef struct { uint16_t count; tu_lookup_entry_t const* items; } tu_lookup_table_t; -static inline const char* tu_lookup_find(tu_lookup_table_t const* p_table, uint32_t key) -{ +static inline const char* tu_lookup_find(tu_lookup_table_t const* p_table, uint32_t key) { tu_static char not_found[11]; - for(uint16_t i=0; icount; i++) - { + for(uint16_t i=0; icount; i++) { if (p_table->items[i].key == key) return p_table->items[i].data; } @@ -133,7 +124,7 @@ static inline const char* tu_lookup_find(tu_lookup_table_t const* p_table, uint3 #ifndef TU_LOG #define TU_LOG(n, ...) #define TU_LOG_MEM(n, ...) - #define TU_LOG_PTR(n, ...) + #define TU_LOG_BUF(n, ...) #define TU_LOG_INT(n, ...) #define TU_LOG_HEX(n, ...) #define TU_LOG_LOCATION() @@ -144,14 +135,14 @@ static inline const char* tu_lookup_find(tu_lookup_table_t const* p_table, uint3 #define TU_LOG0(...) #define TU_LOG0_MEM(...) -#define TU_LOG0_PTR(...) +#define TU_LOG0_BUF(...) #define TU_LOG0_INT(...) #define TU_LOG0_HEX(...) #ifndef TU_LOG1 #define TU_LOG1(...) #define TU_LOG1_MEM(...) - #define TU_LOG1_PTR(...) + #define TU_LOG1_BUF(...) #define TU_LOG1_INT(...) #define TU_LOG1_HEX(...) #endif @@ -159,7 +150,7 @@ static inline const char* tu_lookup_find(tu_lookup_table_t const* p_table, uint3 #ifndef TU_LOG2 #define TU_LOG2(...) #define TU_LOG2_MEM(...) - #define TU_LOG2_PTR(...) + #define TU_LOG2_BUF(...) #define TU_LOG2_INT(...) #define TU_LOG2_HEX(...) #endif @@ -167,7 +158,7 @@ static inline const char* tu_lookup_find(tu_lookup_table_t const* p_table, uint3 #ifndef TU_LOG3 #define TU_LOG3(...) #define TU_LOG3_MEM(...) - #define TU_LOG3_PTR(...) + #define TU_LOG3_BUF(...) #define TU_LOG3_INT(...) #define TU_LOG3_HEX(...) #endif diff --git a/src/device/usbd.c b/src/device/usbd.c index f0d9fba52..50941c46f 100644 --- a/src/device/usbd.c +++ b/src/device/usbd.c @@ -506,7 +506,7 @@ void tud_task_ext(uint32_t timeout_ms, bool in_isr) break; case DCD_EVENT_SETUP_RECEIVED: - TU_LOG_PTR(CFG_TUD_LOG_LEVEL, &event.setup_received); + TU_LOG_BUF(CFG_TUD_LOG_LEVEL, &event.setup_received, 8); TU_LOG_USBD("\r\n"); // Mark as connected after receiving 1st setup packet. diff --git a/src/device/usbd_pvt.h b/src/device/usbd_pvt.h index 16585167f..153be7cee 100644 --- a/src/device/usbd_pvt.h +++ b/src/device/usbd_pvt.h @@ -23,8 +23,8 @@ * * This file is part of the TinyUSB stack. */ -#ifndef USBD_PVT_H_ -#define USBD_PVT_H_ +#ifndef _TUSB_USBD_PVT_H_ +#define _TUSB_USBD_PVT_H_ #include "osal/osal.h" #include "common/tusb_fifo.h" @@ -44,8 +44,7 @@ // Class Driver API //--------------------------------------------------------------------+ -typedef struct -{ +typedef struct { #if CFG_TUSB_DEBUG >= CFG_TUD_LOG_LEVEL char const* name; #endif @@ -111,8 +110,7 @@ bool usbd_edpt_iso_activate(uint8_t rhport, tusb_desc_endpoint_t const * p_endp // Check if endpoint is ready (not busy and not stalled) TU_ATTR_ALWAYS_INLINE static inline -bool usbd_edpt_ready(uint8_t rhport, uint8_t ep_addr) -{ +bool usbd_edpt_ready(uint8_t rhport, uint8_t ep_addr) { return !usbd_edpt_busy(rhport, ep_addr) && !usbd_edpt_stalled(rhport, ep_addr); } @@ -124,11 +122,10 @@ void usbd_sof_enable(uint8_t rhport, bool en); *------------------------------------------------------------------*/ bool usbd_open_edpt_pair(uint8_t rhport, uint8_t const* p_desc, uint8_t ep_count, uint8_t xfer_type, uint8_t* ep_out, uint8_t* ep_in); -void usbd_defer_func( osal_task_func_t func, void* param, bool in_isr ); - +void usbd_defer_func(osal_task_func_t func, void *param, bool in_isr); #ifdef __cplusplus } #endif -#endif /* USBD_PVT_H_ */ +#endif diff --git a/src/host/usbh.c b/src/host/usbh.c index bacb3a719..e60e680c2 100644 --- a/src/host/usbh.c +++ b/src/host/usbh.c @@ -583,7 +583,7 @@ bool tuh_control_xfer (tuh_xfer_t* xfer) { TU_LOG_USBH("[%u:%u] %s: ", rhport, daddr, (xfer->setup->bmRequestType_bit.type == TUSB_REQ_TYPE_STANDARD && xfer->setup->bRequest <= TUSB_REQ_SYNCH_FRAME) ? tu_str_std_request[xfer->setup->bRequest] : "Class Request"); - TU_LOG_PTR(CFG_TUH_LOG_LEVEL, xfer->setup); + TU_LOG_BUF(CFG_TUH_LOG_LEVEL, xfer->setup, 8); TU_LOG_USBH("\r\n"); if (xfer->complete_cb) { @@ -660,10 +660,8 @@ static bool usbh_control_xfer_cb (uint8_t dev_addr, uint8_t ep_addr, xfer_result if (XFER_RESULT_SUCCESS != result) { TU_LOG1("[%u:%u] Control %s, xferred_bytes = %lu\r\n", rhport, dev_addr, result == XFER_RESULT_STALLED ? "STALLED" : "FAILED", xferred_bytes); - #if CFG_TUSB_DEBUG == 1 - TU_LOG1_PTR(request); + TU_LOG1_BUF(request, 8); TU_LOG1("\r\n"); - #endif // terminate transfer if any stage failed _xfer_complete(dev_addr, result); -- cgit v1.3.1 From 21ab40bab2e2fee28fa595f648a17944696c3d65 Mon Sep 17 00:00:00 2001 From: hathach Date: Thu, 7 Sep 2023 12:38:18 +0700 Subject: - wrap up hcd max3421, work well with nrf52840 - also add usbh_defer_func() --- hw/bsp/nrf/family.c | 7 ++++-- src/host/usbh.c | 26 ++++++++++++---------- src/host/usbh_pvt.h | 10 ++++----- src/portable/analog/max3421/hcd_max3421.c | 36 ++----------------------------- 4 files changed, 27 insertions(+), 52 deletions(-) (limited to 'src/host') diff --git a/hw/bsp/nrf/family.c b/hw/bsp/nrf/family.c index 7358458ce..39ce179e8 100644 --- a/hw/bsp/nrf/family.c +++ b/hw/bsp/nrf/family.c @@ -109,10 +109,12 @@ void max3421e_int_handler(nrfx_gpiote_pin_t pin, nrf_gpiote_polarity_t action) { void tuh_max3421e_int_api(uint8_t rhport, bool enabled) { (void) rhport; + // use NVIC_Enable/Disable instead since nrfx_gpiote_trigger_enable/disable clear pending and can miss interrupt + // when disabled if (enabled) { - nrfx_gpiote_trigger_enable(MAX3241E_INTR_PIN, true); + NVIC_EnableIRQ(GPIOTE_IRQn); } else { - nrfx_gpiote_trigger_disable(MAX3241E_INTR_PIN); + NVIC_DisableIRQ(GPIOTE_IRQn); } } @@ -266,6 +268,7 @@ void board_init(void) { in_config.pull = NRF_GPIO_PIN_PULLUP; nrfx_gpiote_in_init(MAX3241E_INTR_PIN, &in_config, max3421e_int_handler); + nrfx_gpiote_trigger_enable(MAX3241E_INTR_PIN, true); #endif } diff --git a/src/host/usbh.c b/src/host/usbh.c index e60e680c2..e332f35cc 100644 --- a/src/host/usbh.c +++ b/src/host/usbh.c @@ -753,29 +753,33 @@ bool tuh_edpt_abort_xfer(uint8_t daddr, uint8_t ep_addr) { // USBH API For Class Driver //--------------------------------------------------------------------+ -uint8_t usbh_get_rhport(uint8_t dev_addr) -{ - usbh_device_t* dev = get_device(dev_addr); +uint8_t usbh_get_rhport(uint8_t dev_addr) { + usbh_device_t *dev = get_device(dev_addr); return dev ? dev->rhport : _dev0.rhport; } -uint8_t* usbh_get_enum_buf(void) -{ +uint8_t *usbh_get_enum_buf(void) { return _usbh_ctrl_buf; } -void usbh_int_set(bool enabled) -{ +void usbh_int_set(bool enabled) { // TODO all host controller if multiple are used since they shared the same event queue - if (enabled) - { + if (enabled) { hcd_int_enable(_usbh_controller); - }else - { + } else { hcd_int_disable(_usbh_controller); } } +void usbh_defer_func(osal_task_func_t func, void *param, bool in_isr) { + hcd_event_t event = { 0 }; + event.event_id = USBH_EVENT_FUNC_CALL; + event.func_call.func = func; + event.func_call.param = param; + + osal_queue_send(_usbh_q, &event, in_isr); +} + //--------------------------------------------------------------------+ // Endpoint API //--------------------------------------------------------------------+ diff --git a/src/host/usbh_pvt.h b/src/host/usbh_pvt.h index 0b58a91bc..2b61a77db 100644 --- a/src/host/usbh_pvt.h +++ b/src/host/usbh_pvt.h @@ -24,8 +24,8 @@ * This file is part of the TinyUSB stack. */ -#ifndef _TUSB_USBH_CLASSDRIVER_H_ -#define _TUSB_USBH_CLASSDRIVER_H_ +#ifndef _TUSB_USBH_PVT_H_ +#define _TUSB_USBH_PVT_H_ #include "osal/osal.h" #include "common/tusb_fifo.h" @@ -76,6 +76,8 @@ uint8_t* usbh_get_enum_buf(void); void usbh_int_set(bool enabled); +void usbh_defer_func(osal_task_func_t func, void *param, bool in_isr); + //--------------------------------------------------------------------+ // USBH Endpoint API //--------------------------------------------------------------------+ @@ -85,12 +87,10 @@ bool usbh_edpt_xfer_with_callback(uint8_t dev_addr, uint8_t ep_addr, uint8_t * b tuh_xfer_cb_t complete_cb, uintptr_t user_data); TU_ATTR_ALWAYS_INLINE -static inline bool usbh_edpt_xfer(uint8_t dev_addr, uint8_t ep_addr, uint8_t * buffer, uint16_t total_bytes) -{ +static inline bool usbh_edpt_xfer(uint8_t dev_addr, uint8_t ep_addr, uint8_t * buffer, uint16_t total_bytes) { return usbh_edpt_xfer_with_callback(dev_addr, ep_addr, buffer, total_bytes, NULL, 0); } - // Claim an endpoint before submitting a transfer. // If caller does not make any transfer, it must release endpoint for others. bool usbh_edpt_claim(uint8_t dev_addr, uint8_t ep_addr); diff --git a/src/portable/analog/max3421/hcd_max3421.c b/src/portable/analog/max3421/hcd_max3421.c index c61389cb9..95cf5516e 100644 --- a/src/portable/analog/max3421/hcd_max3421.c +++ b/src/portable/analog/max3421/hcd_max3421.c @@ -194,7 +194,6 @@ typedef struct { uint8_t hxfr; atomic_flag busy; // busy transferring - volatile uint8_t intr_disable_count; volatile uint16_t frame_count; max3421_ep_t ep[CFG_TUH_MAX3421_ENDPOINT_TOTAL]; // [0] is reserved for addr0 @@ -241,14 +240,6 @@ static void max3421_spi_unlock(uint8_t rhport, bool in_isr) { if (!in_isr) { tuh_max3421e_int_api(rhport, true); (void) osal_mutex_unlock(_hcd_data.spi_mutex); - - // when re-enable interrupt, we may miss INTR edge (usually via GPIO detection interrupt). - // It would be ok if we are operating since SOF will re-trigger interrupt. - // However, for CONDET_IRQ i.e host not operating therefore we need to manually handle it here. - if (_hcd_data.hirq & HIRQ_CONDET_IRQ) { - handle_connect_irq(rhport, false); - hirq_write(rhport, HIRQ_CONDET_IRQ, false); - } } } @@ -470,28 +461,13 @@ bool hcd_init(uint8_t rhport) { // Enable USB interrupt // Not actually enable GPIO interrupt, just set variable to prevent handler to process void hcd_int_enable (uint8_t rhport) { -// tuh_max3421e_int_api(rhport, true); - - (void) rhport; - if (_hcd_data.intr_disable_count) { - _hcd_data.intr_disable_count--; - } - - // when re-enable interrupt, we may miss INTR edge (usually via GPIO detection interrupt). - // It would be ok if we are operating since SOF will re-trigger interrupt. - // However, for CONDET_IRQ i.e host not operating therefore we need to manually handle it here. -// if (_hcd_data.hirq & HIRQ_CONDET_IRQ) { -// handle_connect_irq(rhport, false); -// hirq_write(rhport, HIRQ_CONDET_IRQ, false); -// } + tuh_max3421e_int_api(rhport, true); } // Disable USB interrupt // Not actually disable GPIO interrupt, just set variable to prevent handler to process void hcd_int_disable(uint8_t rhport) { - //tuh_max3421e_int_api(rhport, false); - (void) rhport; - _hcd_data.intr_disable_count++; + tuh_max3421e_int_api(rhport, false); } // Get frame number (1ms) @@ -896,14 +872,6 @@ void hcd_int_handler(uint8_t rhport) { _hcd_data.frame_count++; } - // interrupt is disabled by usbh task: only ack FRAME IRQ and skip the rest - if (_hcd_data.intr_disable_count) { - if (hirq & HIRQ_FRAME_IRQ) { - hirq_write(rhport, HIRQ_FRAME_IRQ, true); - } - return; - } - if (hirq & HIRQ_CONDET_IRQ) { handle_connect_irq(rhport, true); } -- cgit v1.3.1 From a7c136c03f0c4a057f8b49c10ed9cddcecf52879 Mon Sep 17 00:00:00 2001 From: hathach Date: Mon, 25 Sep 2023 16:53:11 +0700 Subject: adding host/cdc_msc_hid_freertos example --- .idea/cmake.xml | 19 +-- examples/device/cdc_msc_freertos/Makefile | 2 +- examples/device/cdc_msc_freertos/src/main.c | 70 ++++----- examples/host/bare_api/CMakeLists.txt | 5 + examples/host/cdc_msc_hid/CMakeLists.txt | 5 + examples/host/cdc_msc_hid_freertos/CMakeLists.txt | 36 +++++ .../host/cdc_msc_hid_freertos/src/CMakeLists.txt | 4 + examples/host/cdc_msc_hid_freertos/src/main.c | 170 +++++++++++++++++++++ .../host/cdc_msc_hid_freertos/src/tusb_config.h | 133 ++++++++++++++++ examples/host/hid_controller/CMakeLists.txt | 5 + examples/host/msc_file_explorer/CMakeLists.txt | 5 + examples/make.mk | 3 - .../boards/adafruit_metro_esp32s2/board.h | 8 + hw/bsp/espressif/boards/espressif_kaluga_1/board.h | 8 + .../boards/espressif_s2_devkitc/board.cmake | 2 + .../espressif/boards/espressif_s2_devkitc/board.h | 45 ++++++ hw/bsp/espressif/boards/family.c | 130 +++++++++++++--- .../components/tinyusb_src/CMakeLists.txt | 79 ++++++---- src/host/usbh.c | 2 +- src/portable/analog/max3421/hcd_max3421.c | 2 +- 20 files changed, 622 insertions(+), 111 deletions(-) create mode 100644 examples/host/cdc_msc_hid_freertos/CMakeLists.txt create mode 100644 examples/host/cdc_msc_hid_freertos/src/CMakeLists.txt create mode 100644 examples/host/cdc_msc_hid_freertos/src/main.c create mode 100644 examples/host/cdc_msc_hid_freertos/src/tusb_config.h create mode 100644 hw/bsp/espressif/boards/espressif_s2_devkitc/board.cmake create mode 100644 hw/bsp/espressif/boards/espressif_s2_devkitc/board.h (limited to 'src/host') diff --git a/.idea/cmake.xml b/.idea/cmake.xml index 89ec1066c..747f0fb58 100644 --- a/.idea/cmake.xml +++ b/.idea/cmake.xml @@ -2,23 +2,24 @@ - + - - - - + + + + + + + + - - - @@ -53,7 +54,7 @@ - + diff --git a/examples/device/cdc_msc_freertos/Makefile b/examples/device/cdc_msc_freertos/Makefile index 0bee668b7..3ac62a79c 100644 --- a/examples/device/cdc_msc_freertos/Makefile +++ b/examples/device/cdc_msc_freertos/Makefile @@ -10,7 +10,7 @@ INC += \ src/FreeRTOSConfig \ $(TOP)/hw \ $(TOP)/$(FREERTOS_SRC)/include \ - $(TOP)/$(FREERTOS_PORTABLE_SRC) + $(TOP)/$(FREERTOS_PORTABLE_SRC) \ # Example source EXAMPLE_SOURCE = \ diff --git a/examples/device/cdc_msc_freertos/src/main.c b/examples/device/cdc_msc_freertos/src/main.c index 0b115a595..1dadc4513 100644 --- a/examples/device/cdc_msc_freertos/src/main.c +++ b/examples/device/cdc_msc_freertos/src/main.c @@ -41,6 +41,7 @@ #define USBD_STACK_SIZE 4096 #else + #include "FreeRTOS.h" #include "semphr.h" #include "queue.h" @@ -54,7 +55,7 @@ #define CDC_STACK_SZIE configMINIMAL_STACK_SIZE //--------------------------------------------------------------------+ -// MACRO CONSTANT TYPEDEF PROTYPES +// MACRO CONSTANT TYPEDEF PROTOTYPES //--------------------------------------------------------------------+ /* Blink pattern @@ -62,7 +63,7 @@ * - 1000 ms : device mounted * - 2500 ms : device is suspended */ -enum { +enum { BLINK_NOT_MOUNTED = 250, BLINK_MOUNTED = 1000, BLINK_SUSPENDED = 2500, @@ -81,16 +82,15 @@ StaticTask_t cdc_taskdef; TimerHandle_t blinky_tm; -void led_blinky_cb(TimerHandle_t xTimer); -void usb_device_task(void* param); -void cdc_task(void* params); +static void led_blinky_cb(TimerHandle_t xTimer); +static void usb_device_task(void *param); +void cdc_task(void *params); //--------------------------------------------------------------------+ // Main //--------------------------------------------------------------------+ -int main(void) -{ +int main(void) { board_init(); #if configSUPPORT_STATIC_ALLOCATION @@ -104,8 +104,8 @@ int main(void) xTaskCreateStatic(cdc_task, "cdc", CDC_STACK_SZIE, NULL, configMAX_PRIORITIES-2, cdc_stack, &cdc_taskdef); #else blinky_tm = xTimerCreate(NULL, pdMS_TO_TICKS(BLINK_NOT_MOUNTED), true, NULL, led_blinky_cb); - xTaskCreate( usb_device_task, "usbd", USBD_STACK_SIZE, NULL, configMAX_PRIORITIES-1, NULL); - xTaskCreate( cdc_task, "cdc", CDC_STACK_SZIE, NULL, configMAX_PRIORITIES-2, NULL); + xTaskCreate(usb_device_task, "usbd", USBD_STACK_SIZE, NULL, configMAX_PRIORITIES - 1, NULL); + xTaskCreate(cdc_task, "cdc", CDC_STACK_SZIE, NULL, configMAX_PRIORITIES - 2, NULL); #endif xTimerStart(blinky_tm, 0); @@ -119,16 +119,14 @@ int main(void) } #if TU_CHECK_MCU(OPT_MCU_ESP32S2, OPT_MCU_ESP32S3) -void app_main(void) -{ +void app_main(void) { main(); } #endif // USB Device Driver task // This top level thread process all usb events and invoke callbacks -void usb_device_task(void* param) -{ +static void usb_device_task(void *param) { (void) param; // init device stack on configured roothub port @@ -141,8 +139,7 @@ void usb_device_task(void* param) } // RTOS forever loop - while (1) - { + while (1) { // put this thread to waiting state until there is new events tud_task(); @@ -156,35 +153,28 @@ void usb_device_task(void* param) //--------------------------------------------------------------------+ // Invoked when device is mounted -void tud_mount_cb(void) -{ +void tud_mount_cb(void) { xTimerChangePeriod(blinky_tm, pdMS_TO_TICKS(BLINK_MOUNTED), 0); } // Invoked when device is unmounted -void tud_umount_cb(void) -{ +void tud_umount_cb(void) { xTimerChangePeriod(blinky_tm, pdMS_TO_TICKS(BLINK_NOT_MOUNTED), 0); } // Invoked when usb bus is suspended // remote_wakeup_en : if host allow us to perform remote wakeup // Within 7ms, device must draw an average of current less than 2.5 mA from bus -void tud_suspend_cb(bool remote_wakeup_en) -{ +void tud_suspend_cb(bool remote_wakeup_en) { (void) remote_wakeup_en; xTimerChangePeriod(blinky_tm, pdMS_TO_TICKS(BLINK_SUSPENDED), 0); } // Invoked when usb bus is resumed -void tud_resume_cb(void) -{ - if (tud_mounted()) - { +void tud_resume_cb(void) { + if (tud_mounted()) { xTimerChangePeriod(blinky_tm, pdMS_TO_TICKS(BLINK_MOUNTED), 0); - } - else - { + } else { xTimerChangePeriod(blinky_tm, pdMS_TO_TICKS(BLINK_NOT_MOUNTED), 0); } } @@ -192,20 +182,17 @@ void tud_resume_cb(void) //--------------------------------------------------------------------+ // USB CDC //--------------------------------------------------------------------+ -void cdc_task(void* params) -{ +void cdc_task(void *params) { (void) params; // RTOS forever loop - while ( 1 ) - { + while (1) { // connected() check for DTR bit // Most but not all terminal client set this when making connection // if ( tud_cdc_connected() ) { // There are data available - while ( tud_cdc_available() ) - { + while (tud_cdc_available()) { uint8_t buf[64]; // read and echo back @@ -228,32 +215,27 @@ void cdc_task(void* params) } // Invoked when cdc when line state changed e.g connected/disconnected -void tud_cdc_line_state_cb(uint8_t itf, bool dtr, bool rts) -{ +void tud_cdc_line_state_cb(uint8_t itf, bool dtr, bool rts) { (void) itf; (void) rts; // TODO set some indicator - if ( dtr ) - { + if (dtr) { // Terminal connected - }else - { + } else { // Terminal disconnected } } // Invoked when CDC interface received data from host -void tud_cdc_rx_cb(uint8_t itf) -{ +void tud_cdc_rx_cb(uint8_t itf) { (void) itf; } //--------------------------------------------------------------------+ // BLINKING TASK //--------------------------------------------------------------------+ -void led_blinky_cb(TimerHandle_t xTimer) -{ +static void led_blinky_cb(TimerHandle_t xTimer) { (void) xTimer; static bool led_state = false; diff --git a/examples/host/bare_api/CMakeLists.txt b/examples/host/bare_api/CMakeLists.txt index 05398b079..76182d6fa 100644 --- a/examples/host/bare_api/CMakeLists.txt +++ b/examples/host/bare_api/CMakeLists.txt @@ -10,6 +10,11 @@ project(${PROJECT} C CXX ASM) # Checks this example is valid for the family and initializes the project family_initialize_project(${PROJECT} ${CMAKE_CURRENT_LIST_DIR}) +# Espressif has its own cmake build system +if(FAMILY STREQUAL "espressif") + return() +endif() + add_executable(${PROJECT}) # Example source diff --git a/examples/host/cdc_msc_hid/CMakeLists.txt b/examples/host/cdc_msc_hid/CMakeLists.txt index ad5751705..a7c372a34 100644 --- a/examples/host/cdc_msc_hid/CMakeLists.txt +++ b/examples/host/cdc_msc_hid/CMakeLists.txt @@ -10,6 +10,11 @@ project(${PROJECT} C CXX ASM) # Checks this example is valid for the family and initializes the project family_initialize_project(${PROJECT} ${CMAKE_CURRENT_LIST_DIR}) +# Espressif has its own cmake build system +if(FAMILY STREQUAL "espressif") + return() +endif() + add_executable(${PROJECT}) # Example source diff --git a/examples/host/cdc_msc_hid_freertos/CMakeLists.txt b/examples/host/cdc_msc_hid_freertos/CMakeLists.txt new file mode 100644 index 000000000..2e95a18e0 --- /dev/null +++ b/examples/host/cdc_msc_hid_freertos/CMakeLists.txt @@ -0,0 +1,36 @@ +cmake_minimum_required(VERSION 3.17) + +include(${CMAKE_CURRENT_SOURCE_DIR}/../../../hw/bsp/family_support.cmake) + +# gets PROJECT name for the example (e.g. -) +family_get_project_name(PROJECT ${CMAKE_CURRENT_LIST_DIR}) + +project(${PROJECT} C CXX ASM) + +# Checks this example is valid for the family and initializes the project +family_initialize_project(${PROJECT} ${CMAKE_CURRENT_LIST_DIR}) + +# Espressif has its own cmake build system +if(FAMILY STREQUAL "espressif") + return() +endif() + +add_executable(${PROJECT}) + +# Example source +target_sources(${PROJECT} PUBLIC + ${CMAKE_CURRENT_SOURCE_DIR}/src/cdc_app.c + ${CMAKE_CURRENT_SOURCE_DIR}/src/freertos_hook.c + ${CMAKE_CURRENT_SOURCE_DIR}/src/hid_app.c + ${CMAKE_CURRENT_SOURCE_DIR}/src/main.c + ${CMAKE_CURRENT_SOURCE_DIR}/src/msc_app.c + ) + +# Example include +target_include_directories(${PROJECT} PUBLIC + ${CMAKE_CURRENT_SOURCE_DIR}/src + ) + +# Configure compilation flags and libraries for the example without RTOS. +# See the corresponding function in hw/bsp/FAMILY/family.cmake for details. +family_configure_host_example(${PROJECT} freertos) diff --git a/examples/host/cdc_msc_hid_freertos/src/CMakeLists.txt b/examples/host/cdc_msc_hid_freertos/src/CMakeLists.txt new file mode 100644 index 000000000..dd7ec8e58 --- /dev/null +++ b/examples/host/cdc_msc_hid_freertos/src/CMakeLists.txt @@ -0,0 +1,4 @@ +# This file is for ESP-IDF only +idf_component_register(SRCS "hid_app.c" "main.c" + INCLUDE_DIRS "." + REQUIRES boards tinyusb_src) diff --git a/examples/host/cdc_msc_hid_freertos/src/main.c b/examples/host/cdc_msc_hid_freertos/src/main.c new file mode 100644 index 000000000..e2ddd52eb --- /dev/null +++ b/examples/host/cdc_msc_hid_freertos/src/main.c @@ -0,0 +1,170 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2019 Ha Thach (tinyusb.org) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + +#include +#include +#include + +#include "bsp/board_api.h" +#include "tusb.h" + +#if TU_CHECK_MCU(OPT_MCU_ESP32S2, OPT_MCU_ESP32S3) + // ESP-IDF need "freertos/" prefix in include path. + // CFG_TUSB_OS_INC_PATH should be defined accordingly. + #include "freertos/FreeRTOS.h" + #include "freertos/semphr.h" + #include "freertos/queue.h" + #include "freertos/task.h" + #include "freertos/timers.h" + + #define USBH_STACK_SIZE 4096 +#else + #include "FreeRTOS.h" + #include "semphr.h" + #include "queue.h" + #include "task.h" + #include "timers.h" + + // Increase stack size when debug log is enabled + #define USBH_STACK_SIZE (3*configMINIMAL_STACK_SIZE/2) * (CFG_TUSB_DEBUG ? 2 : 1) +#endif + +//--------------------------------------------------------------------+ +// MACRO CONSTANT TYPEDEF PROTOTYPES +//--------------------------------------------------------------------+ +/* Blink pattern + * - 250 ms : device not mounted + * - 1000 ms : device mounted + * - 2500 ms : device is suspended + */ +enum { + BLINK_NOT_MOUNTED = 250, + BLINK_MOUNTED = 1000, + BLINK_SUSPENDED = 2500, +}; + +// static timer & task +#if configSUPPORT_STATIC_ALLOCATION +StaticTimer_t blinky_tmdef; + +StackType_t usb_host_stack[USBH_STACK_SIZE]; +StaticTask_t usb_host_taskdef; + +//StackType_t cdc_stack[CDC_STACK_SZIE]; +//StaticTask_t cdc_taskdef; +#endif + + +TimerHandle_t blinky_tm; + +static void led_blinky_cb(TimerHandle_t xTimer); +static void usb_host_task(void* param); + +extern void cdc_app_task(void); +extern void hid_app_task(void); + +/*------------- MAIN -------------*/ +int main(void) { + board_init(); + + printf("TinyUSB Host CDC MSC HID with FreeRTOS Example\r\n"); + +#if configSUPPORT_STATIC_ALLOCATION + // soft timer for blinky + blinky_tm = xTimerCreateStatic(NULL, pdMS_TO_TICKS(BLINK_MOUNTED), true, NULL, led_blinky_cb, &blinky_tmdef); + + // Create a task for tinyusb device stack + xTaskCreateStatic(usb_host_task, "usbh", USBH_STACK_SIZE, NULL, configMAX_PRIORITIES-1, usb_host_stack, &usb_host_taskdef); + + // Create CDC task + //xTaskCreateStatic(cdc_task, "cdc", CDC_STACK_SZIE, NULL, configMAX_PRIORITIES-2, cdc_stack, &cdc_taskdef); +#else + blinky_tm = xTimerCreate(NULL, pdMS_TO_TICKS(BLINK_NOT_MOUNTED), true, NULL, led_blinky_cb); + xTaskCreate( usb_device_task, "usbd", USBH_STACK_SIZE, NULL, configMAX_PRIORITIES-1, NULL); + //xTaskCreate( cdc_task, "cdc", CDC_STACK_SZIE, NULL, configMAX_PRIORITIES-2, NULL); +#endif + + xTimerStart(blinky_tm, 0); + + // skip starting scheduler (and return) for ESP32-S2 or ESP32-S3 +#if !TU_CHECK_MCU(OPT_MCU_ESP32S2, OPT_MCU_ESP32S3) + vTaskStartScheduler(); +#endif + + return 0; +} + +#if TU_CHECK_MCU(OPT_MCU_ESP32S2, OPT_MCU_ESP32S3) +void app_main(void) { + main(); +} +#endif + +// USB Host task +// This top level thread process all usb events and invoke callbacks +static void usb_host_task(void *param) { + (void) param; + + // init host stack on configured roothub port + tuh_init(BOARD_TUH_RHPORT); + + if (board_init_after_tusb) { + board_init_after_tusb(); + } + + // RTOS forever loop + while (1) { + // put this thread to waiting state until there is new events + tuh_task(); + + // following code only run if tuh_task() process at least 1 event + } +} + +//--------------------------------------------------------------------+ +// TinyUSB Callbacks +//--------------------------------------------------------------------+ + +void tuh_mount_cb(uint8_t dev_addr) { + // application set-up + printf("A device with address %d is mounted\r\n", dev_addr); +} + +void tuh_umount_cb(uint8_t dev_addr) { + // application tear-down + printf("A device with address %d is unmounted \r\n", dev_addr); +} + + +//--------------------------------------------------------------------+ +// BLINKING TASK +//--------------------------------------------------------------------+ +static void led_blinky_cb(TimerHandle_t xTimer) { + (void) xTimer; + static bool led_state = false; + + board_led_write(led_state); + led_state = 1 - led_state; // toggle +} diff --git a/examples/host/cdc_msc_hid_freertos/src/tusb_config.h b/examples/host/cdc_msc_hid_freertos/src/tusb_config.h new file mode 100644 index 000000000..1bed9a9b3 --- /dev/null +++ b/examples/host/cdc_msc_hid_freertos/src/tusb_config.h @@ -0,0 +1,133 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2019 Ha Thach (tinyusb.org) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + +#ifndef _TUSB_CONFIG_H_ +#define _TUSB_CONFIG_H_ + +#ifdef __cplusplus + extern "C" { +#endif + +//--------------------------------------------------------------------+ +// Board Specific Configuration +//--------------------------------------------------------------------+ + +#if CFG_TUSB_MCU == OPT_MCU_RP2040 + // change to 1 if using pico-pio-usb as host controller for raspberry rp2040 + #define CFG_TUH_RPI_PIO_USB 0 + #define BOARD_TUH_RHPORT CFG_TUH_RPI_PIO_USB +#endif + +// RHPort number used for host can be defined by board.mk, default to port 0 +#ifndef BOARD_TUH_RHPORT +#define BOARD_TUH_RHPORT 0 +#endif + +// RHPort max operational speed can defined by board.mk +#ifndef BOARD_TUH_MAX_SPEED +#define BOARD_TUH_MAX_SPEED OPT_MODE_DEFAULT_SPEED +#endif + +//-------------------------------------------------------------------- +// COMMON CONFIGURATION +//-------------------------------------------------------------------- + +// defined by compiler flags for flexibility +#ifndef CFG_TUSB_MCU +#error CFG_TUSB_MCU must be defined +#endif + +#ifndef CFG_TUSB_OS +#define CFG_TUSB_OS OPT_OS_FREERTOS +#endif + +// Espressif IDF requires "freertos/" prefix in include path +#if TU_CHECK_MCU(OPT_MCU_ESP32S2, OPT_MCU_ESP32S3) +#define CFG_TUSB_OS_INC_PATH freertos/ +#endif + +#ifndef CFG_TUSB_DEBUG +#define CFG_TUSB_DEBUG 0 +#endif + +// Enable Host stack +#define CFG_TUH_ENABLED 1 + +// Default is max speed that hardware controller could support with on-chip PHY +#define CFG_TUH_MAX_SPEED BOARD_TUH_MAX_SPEED + +/* USB DMA on some MCUs can only access a specific SRAM region with restriction on alignment. + * Tinyusb use follows macros to declare transferring memory so that they can be put + * into those specific section. + * e.g + * - CFG_TUSB_MEM SECTION : __attribute__ (( section(".usb_ram") )) + * - CFG_TUSB_MEM_ALIGN : __attribute__ ((aligned(4))) + */ +#ifndef CFG_TUH_MEM_SECTION +#define CFG_TUH_MEM_SECTION +#endif + +#ifndef CFG_TUH_MEM_ALIGN +#define CFG_TUH_MEM_ALIGN __attribute__ ((aligned(4))) +#endif + +//-------------------------------------------------------------------- +// CONFIGURATION +//-------------------------------------------------------------------- + +// Size of buffer to hold descriptors and other data used for enumeration +#define CFG_TUH_ENUMERATION_BUFSIZE 256 + +#define CFG_TUH_HUB 1 // number of supported hubs +#define CFG_TUH_CDC 1 // CDC ACM +#define CFG_TUH_CDC_FTDI 1 // FTDI Serial. FTDI is not part of CDC class, only to re-use CDC driver API +#define CFG_TUH_CDC_CP210X 1 // CP210x Serial. CP210X is not part of CDC class, only to re-use CDC driver API +#define CFG_TUH_HID (3*CFG_TUH_DEVICE_MAX) // typical keyboard + mouse device can have 3-4 HID interfaces +#define CFG_TUH_MSC 1 +#define CFG_TUH_VENDOR 0 + +// max device support (excluding hub device): 1 hub typically has 4 ports +#define CFG_TUH_DEVICE_MAX (3*CFG_TUH_HUB + 1) + +//------------- HID -------------// +#define CFG_TUH_HID_EPIN_BUFSIZE 64 +#define CFG_TUH_HID_EPOUT_BUFSIZE 64 + +//------------- CDC -------------// + +// Set Line Control state on enumeration/mounted: +// DTR ( bit 0), RTS (bit 1) +#define CFG_TUH_CDC_LINE_CONTROL_ON_ENUM 0x03 + +// Set Line Coding on enumeration/mounted, value for cdc_line_coding_t +// bit rate = 115200, 1 stop bit, no parity, 8 bit data width +#define CFG_TUH_CDC_LINE_CODING_ON_ENUM { 115200, CDC_LINE_CONDING_STOP_BITS_1, CDC_LINE_CODING_PARITY_NONE, 8 } + + +#ifdef __cplusplus + } +#endif + +#endif /* _TUSB_CONFIG_H_ */ diff --git a/examples/host/hid_controller/CMakeLists.txt b/examples/host/hid_controller/CMakeLists.txt index 3fb630aaa..c1b500dd8 100644 --- a/examples/host/hid_controller/CMakeLists.txt +++ b/examples/host/hid_controller/CMakeLists.txt @@ -10,6 +10,11 @@ project(${PROJECT} C CXX ASM) # Checks this example is valid for the family and initializes the project family_initialize_project(${PROJECT} ${CMAKE_CURRENT_LIST_DIR}) +# Espressif has its own cmake build system +if(FAMILY STREQUAL "espressif") + return() +endif() + add_executable(${PROJECT}) # Example source diff --git a/examples/host/msc_file_explorer/CMakeLists.txt b/examples/host/msc_file_explorer/CMakeLists.txt index 1868b632e..1a57c7466 100644 --- a/examples/host/msc_file_explorer/CMakeLists.txt +++ b/examples/host/msc_file_explorer/CMakeLists.txt @@ -10,6 +10,11 @@ project(${PROJECT} C CXX ASM) # Checks this example is valid for the family and initializes the project family_initialize_project(${PROJECT} ${CMAKE_CURRENT_LIST_DIR}) +# Espressif has its own cmake build system +if(FAMILY STREQUAL "espressif") + return() +endif() + add_executable(${PROJECT}) # Example source diff --git a/examples/make.mk b/examples/make.mk index 8fe4a3486..448d7883d 100644 --- a/examples/make.mk +++ b/examples/make.mk @@ -26,9 +26,6 @@ ifeq '$(findstring ;,$(PATH))' ';' CMDEXE := 1 # makefile shell commands should use syntax for DOS CMD, not unix sh -# Unfortunately, SHELL may point to sh or bash, which can't accept DOS syntax. -# We can't just use sh, because while sh and/or bash shell may be available, -# many Windows environments won't have utilities like realpath used below, so... # Force DOS command shell on Windows. SHELL := cmd.exe endif diff --git a/hw/bsp/espressif/boards/adafruit_metro_esp32s2/board.h b/hw/bsp/espressif/boards/adafruit_metro_esp32s2/board.h index 2ec80ef47..44ff11aa0 100644 --- a/hw/bsp/espressif/boards/adafruit_metro_esp32s2/board.h +++ b/hw/bsp/espressif/boards/adafruit_metro_esp32s2/board.h @@ -36,6 +36,14 @@ #define BUTTON_PIN 0 #define BUTTON_STATE_ACTIVE 0 +// SPI for USB host shield +#define MAX3421_SPI_HOST SPI2_HOST +#define MAX3421_SCK_PIN 36 +#define MAX3421_MOSI_PIN 35 +#define MAX3421_MISO_PIN 37 +#define MAX3421_CS_PIN 15 +#define MAX3421_INTR_PIN 14 + #ifdef __cplusplus } #endif diff --git a/hw/bsp/espressif/boards/espressif_kaluga_1/board.h b/hw/bsp/espressif/boards/espressif_kaluga_1/board.h index 0acb9c439..613e6ae0c 100644 --- a/hw/bsp/espressif/boards/espressif_kaluga_1/board.h +++ b/hw/bsp/espressif/boards/espressif_kaluga_1/board.h @@ -37,6 +37,14 @@ #define BUTTON_PIN 0 #define BUTTON_STATE_ACTIVE 0 +// SPI for USB host shield +#define MAX3421_SPI_HOST SPI2_HOST +#define MAX3421_SCK_PIN 36 +#define MAX3421_MOSI_PIN 35 +#define MAX3421_MISO_PIN 37 +#define MAX3421_CS_PIN 15 +#define MAX3421_INTR_PIN 14 + #ifdef __cplusplus } #endif diff --git a/hw/bsp/espressif/boards/espressif_s2_devkitc/board.cmake b/hw/bsp/espressif/boards/espressif_s2_devkitc/board.cmake new file mode 100644 index 000000000..abbdf7abc --- /dev/null +++ b/hw/bsp/espressif/boards/espressif_s2_devkitc/board.cmake @@ -0,0 +1,2 @@ +# Apply board specific content here +set(IDF_TARGET "esp32s2") diff --git a/hw/bsp/espressif/boards/espressif_s2_devkitc/board.h b/hw/bsp/espressif/boards/espressif_s2_devkitc/board.h new file mode 100644 index 000000000..e068efef9 --- /dev/null +++ b/hw/bsp/espressif/boards/espressif_s2_devkitc/board.h @@ -0,0 +1,45 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2020, Ha Thach (tinyusb.org) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + +#ifndef BOARD_H_ +#define BOARD_H_ + +#ifdef __cplusplus + extern "C" { +#endif + +// Note: On the production version (v1.2) WS2812 is connected to GPIO 18, +// however earlier revision v1.1 WS2812 is connected to GPIO 17 +#define NEOPIXEL_PIN 18 + +#define BUTTON_PIN 0 +#define BUTTON_STATE_ACTIVE 0 + +#ifdef __cplusplus + } +#endif + +#endif /* BOARD_H_ */ diff --git a/hw/bsp/espressif/boards/family.c b/hw/bsp/espressif/boards/family.c index 8f857fb71..250b7001e 100644 --- a/hw/bsp/espressif/boards/family.c +++ b/hw/bsp/espressif/boards/family.c @@ -45,16 +45,19 @@ static led_strip_t *strip; #endif -//--------------------------------------------------------------------+ -// MACRO TYPEDEF CONSTANT ENUM DECLARATION -//--------------------------------------------------------------------+ +#if CFG_TUH_ENABLED && CFG_TUH_MAX3421 +#include "driver/spi_master.h" +static void max3421_init(void); +#endif static void configure_pins(usb_hal_context_t *usb); -// Initialize on-board peripherals : led, button, uart and USB -void board_init(void) -{ +//--------------------------------------------------------------------+ +// Implementation +//--------------------------------------------------------------------+ +// Initialize on-board peripherals : led, button, uart and USB +void board_init(void) { #ifdef NEOPIXEL_PIN #ifdef NEOPIXEL_POWER_PIN gpio_reset_pin(NEOPIXEL_POWER_PIN); @@ -79,23 +82,27 @@ void board_init(void) gpio_set_direction(BUTTON_PIN, GPIO_MODE_INPUT); gpio_set_pull_mode(BUTTON_PIN, BUTTON_STATE_ACTIVE ? GPIO_PULLDOWN_ONLY : GPIO_PULLUP_ONLY); +#if CFG_TUD_ENABLED // USB Controller Hal init periph_module_reset(PERIPH_USB_MODULE); periph_module_enable(PERIPH_USB_MODULE); usb_hal_context_t hal = { - .use_external_phy = false // use built-in PHY + .use_external_phy = false // use built-in PHY }; usb_hal_init(&hal); configure_pins(&hal); +#endif + +#if CFG_TUH_ENABLED && CFG_TUH_MAX3421 + max3421_init(); +#endif } -static void configure_pins(usb_hal_context_t *usb) -{ +static void configure_pins(usb_hal_context_t *usb) { /* usb_periph_iopins currently configures USB_OTG as USB Device. * Introduce additional parameters in usb_hal_context_t when adding support - * for USB Host. - */ + * for USB Host. */ for (const usb_iopin_dsc_t *iopin = usb_periph_iopins; iopin->pin != -1; ++iopin) { if ((usb->use_external_phy) || (iopin->ext_phy_only == 0)) { esp_rom_gpio_pad_select_gpio(iopin->pin); @@ -115,6 +122,7 @@ static void configure_pins(usb_hal_context_t *usb) esp_rom_gpio_pad_unhold(iopin->pin); } } + if (!usb->use_external_phy) { gpio_set_drive_capability(USBPHY_DM_NUM, GPIO_DRIVE_CAP_3); gpio_set_drive_capability(USBPHY_DP_NUM, GPIO_DRIVE_CAP_3); @@ -122,8 +130,7 @@ static void configure_pins(usb_hal_context_t *usb) } // Turn LED on or off -void board_led_write(bool state) -{ +void board_led_write(bool state) { #ifdef NEOPIXEL_PIN strip->set_pixel(strip, 0, (state ? 0x88 : 0x00), 0x00, 0x00); strip->refresh(strip, 100); @@ -132,21 +139,102 @@ void board_led_write(bool state) // Get the current state of button // a '1' means active (pressed), a '0' means inactive. -uint32_t board_button_read(void) -{ +uint32_t board_button_read(void) { return gpio_get_level(BUTTON_PIN) == BUTTON_STATE_ACTIVE; } // Get characters from UART -int board_uart_read(uint8_t* buf, int len) -{ - (void) buf; (void) len; +int board_uart_read(uint8_t *buf, int len) { + (void) buf; + (void) len; return 0; } // Send characters to UART -int board_uart_write(void const * buf, int len) -{ - (void) buf; (void) len; +int board_uart_write(void const *buf, int len) { + (void) buf; + (void) len; return 0; } + +//--------------------------------------------------------------------+ +// API: SPI transfer with MAX3421E, must be implemented by application +//--------------------------------------------------------------------+ +#if CFG_TUH_ENABLED && defined(CFG_TUH_MAX3421) && CFG_TUH_MAX3421 + +static spi_device_handle_t max3421_spi; + +static void IRAM_ATTR max3421_isr_handler(void* arg) +{ + (void) arg; + //uint32_t gpio_num = (uint32_t) arg; + //xQueueSendFromISR(gpio_evt_queue, &gpio_num, NULL); + tuh_int_handler(1); +} + +static void max3421_init(void) { + // CS pin + gpio_set_direction(MAX3421_CS_PIN, GPIO_MODE_OUTPUT); + gpio_set_level(MAX3421_CS_PIN, 1); + + // SPI + spi_bus_config_t buscfg={ + .miso_io_num = MAX3421_MISO_PIN, + .mosi_io_num = MAX3421_MOSI_PIN, + .sclk_io_num = MAX3421_SCK_PIN, + .quadwp_io_num = -1, + .quadhd_io_num = -1, + .data4_io_num = -1, + .data5_io_num = -1, + .data6_io_num = -1, + .data7_io_num = -1, + .max_transfer_sz = 128 + }; + ESP_ERROR_CHECK( spi_bus_initialize(MAX3421_SPI_HOST, &buscfg, SPI_DMA_CH_AUTO) ); + + spi_device_interface_config_t max3421_cfg = { + .command_bits = 8, + .mode = 0, + .clock_speed_hz = 4000000, // 26000000 + .spics_io_num = -1, // manual control CS + .queue_size = 1 + }; + ESP_ERROR_CHECK( spi_bus_add_device(MAX3421_SPI_HOST, &max3421_cfg, &max3421_spi) ); + + // Interrupt pin +// gpio_set_direction(MAX3421_INTR_PIN, GPIO_MODE_INPUT); +// gpio_set_intr_type(MAX3421_INTR_PIN, GPIO_INTR_NEGEDGE); +// +// gpio_install_isr_service(ESP_INTR_FLAG_EDGE); +// gpio_isr_handler_add(MAX3421_INTR_PIN, max3421_isr_handler, NULL); +} + +void tuh_max3421_int_api(uint8_t rhport, bool enabled) { + (void) rhport; + if (enabled) { + gpio_intr_enable(MAX3421_INTR_PIN); + } else { + gpio_intr_disable(MAX3421_INTR_PIN); + } +} + +void tuh_max3421_spi_cs_api(uint8_t rhport, bool active) { + (void) rhport; + gpio_set_level(MAX3421_CS_PIN, active ? 0 : 1); +} + +bool tuh_max3421_spi_xfer_api(uint8_t rhport, uint8_t const *tx_buf, size_t tx_len, uint8_t *rx_buf, size_t rx_len) { + (void) rhport; + + spi_transaction_t xact = { + .length = tx_len, + .rxlength = rx_len, + .tx_buffer = tx_buf, + .rx_buffer = rx_buf + }; + + ESP_ERROR_CHECK(spi_device_transmit(max3421_spi, &xact)); + return true; +} + +#endif diff --git a/hw/bsp/espressif/components/tinyusb_src/CMakeLists.txt b/hw/bsp/espressif/components/tinyusb_src/CMakeLists.txt index bf8e45be2..2a154a8ff 100644 --- a/hw/bsp/espressif/components/tinyusb_src/CMakeLists.txt +++ b/hw/bsp/espressif/components/tinyusb_src/CMakeLists.txt @@ -16,40 +16,57 @@ else() return() endif() -list(APPEND compile_options - "-DCFG_TUSB_MCU=${tusb_mcu}" - "-DCFG_TUSB_OS=OPT_OS_FREERTOS" - #"-DCFG_TUSB_DEBUG=1" - ) +list(APPEND compile_definitions + CFG_TUSB_MCU=${tusb_mcu} + CFG_TUSB_OS=OPT_OS_FREERTOS + ) -idf_component_get_property(freertos_component_dir freertos COMPONENT_DIR) +list(APPEND srcs + # common + ${tusb_src}/tusb.c + ${tusb_src}/common/tusb_fifo.c + # device + ${tusb_src}/device/usbd.c + ${tusb_src}/device/usbd_control.c + ${tusb_src}/class/audio/audio_device.c + ${tusb_src}/class/cdc/cdc_device.c + ${tusb_src}/class/dfu/dfu_device.c + ${tusb_src}/class/dfu/dfu_rt_device.c + ${tusb_src}/class/hid/hid_device.c + ${tusb_src}/class/midi/midi_device.c + ${tusb_src}/class/msc/msc_device.c + ${tusb_src}/class/net/ecm_rndis_device.c + ${tusb_src}/class/net/ncm_device.c + ${tusb_src}/class/usbtmc/usbtmc_device.c + ${tusb_src}/class/vendor/vendor_device.c + ${tusb_src}/class/video/video_device.c + ${tusb_src}/portable/synopsys/dwc2/dcd_dwc2.c + # host + ${tusb_src}/host/usbh.c + ${tusb_src}/host/hub.c + ${tusb_src}/class/cdc/cdc_host.c + ${tusb_src}/class/hid/hid_host.c + ${tusb_src}/class/msc/msc_host.c + ${tusb_src}/class/vendor/vendor_host.c + ) -list(APPEND includes_public - "${tusb_src}" - # The FreeRTOS API include convention in tinyusb is different from esp-idf - #"${freertos_component_dir}/include/freertos" - ) +# use max3421 as host controller +if (MAX3421_HOST STREQUAL "1") + list(APPEND srcs ${tusb_src}/portable/analog/max3421/hcd_max3421.c) + list(APPEND compile_definitions CFG_TUH_MAX3421=1) +endif () -list(APPEND srcs - "${tusb_src}/tusb.c" - "${tusb_src}/common/tusb_fifo.c" - "${tusb_src}/device/usbd.c" - "${tusb_src}/device/usbd_control.c" - "${tusb_src}/class/cdc/cdc_device.c" - "${tusb_src}/class/dfu/dfu_rt_device.c" - "${tusb_src}/class/hid/hid_device.c" - "${tusb_src}/class/midi/midi_device.c" - "${tusb_src}/class/msc/msc_device.c" - "${tusb_src}/class/net/ecm_rndis_device.c" - "${tusb_src}/class/net/ncm_device.c" - "${tusb_src}/class/usbtmc/usbtmc_device.c" - "${tusb_src}/class/vendor/vendor_device.c" - "${tusb_src}/portable/synopsys/dwc2/dcd_dwc2.c" - ) +if (DEFINED LOG) + list(APPEND compile_definitions CFG_TUSB_DEBUG=${LOG}) + if (LOG STREQUAL "4") + # no inline for debug level 4 + list(APPEND compile_definitions TU_ATTR_ALWAYS_INLINE=) + endif () +endif() idf_component_register(SRCS ${srcs} - INCLUDE_DIRS ${includes_public} - REQUIRES src - ) + INCLUDE_DIRS ${tusb_src} + REQUIRES src + ) -target_compile_options(${COMPONENT_LIB} PUBLIC ${compile_options}) +target_compile_definitions(${COMPONENT_LIB} PUBLIC ${compile_definitions}) diff --git a/src/host/usbh.c b/src/host/usbh.c index e332f35cc..dc2831da3 100644 --- a/src/host/usbh.c +++ b/src/host/usbh.c @@ -659,7 +659,7 @@ static bool usbh_control_xfer_cb (uint8_t dev_addr, uint8_t ep_addr, xfer_result tusb_control_request_t const * request = &_ctrl_xfer.request; if (XFER_RESULT_SUCCESS != result) { - TU_LOG1("[%u:%u] Control %s, xferred_bytes = %lu\r\n", rhport, dev_addr, result == XFER_RESULT_STALLED ? "STALLED" : "FAILED", xferred_bytes); + TU_LOG1("[%u:%u] Control %s, xferred_bytes = %u\r\n", rhport, dev_addr, result == XFER_RESULT_STALLED ? "STALLED" : "FAILED", xferred_bytes); TU_LOG1_BUF(request, 8); TU_LOG1("\r\n"); diff --git a/src/portable/analog/max3421/hcd_max3421.c b/src/portable/analog/max3421/hcd_max3421.c index f3f76fd58..3f6747404 100644 --- a/src/portable/analog/max3421/hcd_max3421.c +++ b/src/portable/analog/max3421/hcd_max3421.c @@ -882,7 +882,7 @@ void hcd_int_handler(uint8_t rhport) { if ( hirq & HIRQ_RCVDAV_IRQ ) { uint8_t const ep_num = _hcd_data.hxfr & HXFR_EPNUM_MASK; max3421_ep_t *ep = find_opened_ep(_hcd_data.peraddr, ep_num, 1); - uint8_t xact_len; + uint8_t xact_len = 0; // RCVDAV_IRQ can trigger 2 times (dual buffered) while ( hirq & HIRQ_RCVDAV_IRQ ) { -- cgit v1.3.1 From f6ca86c3ddeaec18f52b15f1065a5c9eea210c00 Mon Sep 17 00:00:00 2001 From: hathach Date: Tue, 26 Sep 2023 19:09:36 +0700 Subject: tested cdc_msc_hid_freertos with samd51 add -Wno-error=format for espressif wrap up cdc_msc_hid_freertos --- examples/host/cdc_msc_hid_freertos/Makefile | 32 +++ examples/host/cdc_msc_hid_freertos/only.txt | 13 + .../host/cdc_msc_hid_freertos/src/CMakeLists.txt | 4 +- examples/host/cdc_msc_hid_freertos/src/cdc_app.c | 109 +++++++++ .../host/cdc_msc_hid_freertos/src/freertos_hook.c | 111 +++++++++ examples/host/cdc_msc_hid_freertos/src/hid_app.c | 263 +++++++++++++++++++++ examples/host/cdc_msc_hid_freertos/src/main.c | 22 +- examples/host/cdc_msc_hid_freertos/src/msc_app.c | 67 ++++++ hw/bsp/espressif/boards/CMakeLists.txt | 2 + hw/bsp/espressif/boards/family.c | 39 +-- .../components/tinyusb_src/CMakeLists.txt | 1 + hw/bsp/nrf/family.c | 106 +++++---- hw/bsp/samd21/family.c | 9 +- hw/bsp/samd51/FreeRTOSConfig/FreeRTOSConfig.h | 2 +- hw/bsp/samd51/family.c | 8 +- src/host/usbh.c | 2 +- 16 files changed, 703 insertions(+), 87 deletions(-) create mode 100644 examples/host/cdc_msc_hid_freertos/Makefile create mode 100644 examples/host/cdc_msc_hid_freertos/only.txt create mode 100644 examples/host/cdc_msc_hid_freertos/src/cdc_app.c create mode 100644 examples/host/cdc_msc_hid_freertos/src/freertos_hook.c create mode 100644 examples/host/cdc_msc_hid_freertos/src/hid_app.c create mode 100644 examples/host/cdc_msc_hid_freertos/src/msc_app.c (limited to 'src/host') diff --git a/examples/host/cdc_msc_hid_freertos/Makefile b/examples/host/cdc_msc_hid_freertos/Makefile new file mode 100644 index 000000000..67bb6da55 --- /dev/null +++ b/examples/host/cdc_msc_hid_freertos/Makefile @@ -0,0 +1,32 @@ +include ../../make.mk + +FREERTOS_SRC = lib/FreeRTOS-Kernel +FREERTOS_PORTABLE_PATH= $(FREERTOS_SRC)/portable/$(if $(USE_IAR),IAR,GCC) + +INC += \ + src \ + $(TOP)/hw \ + $(TOP)/$(FREERTOS_SRC)/include \ + $(TOP)/$(FREERTOS_PORTABLE_SRC) \ + +# Example source +EXAMPLE_SOURCE = \ + src/cdc_app.c \ + src/freertos_hook.c \ + src/hid_app.c \ + src/main.c \ + src/msc_app.c \ + +SRC_C += $(addprefix $(CURRENT_PATH)/, $(EXAMPLE_SOURCE)) + +# TinyUSB Host Stack source +SRC_C += \ + src/class/cdc/cdc_host.c \ + src/class/hid/hid_host.c \ + src/class/msc/msc_host.c \ + src/host/hub.c \ + src/host/usbh.c \ + src/portable/ohci/ohci.c \ + src/portable/nxp/lpc17_40/hcd_lpc17_40.c + +include ../../rules.mk diff --git a/examples/host/cdc_msc_hid_freertos/only.txt b/examples/host/cdc_msc_hid_freertos/only.txt new file mode 100644 index 000000000..3837ac8a2 --- /dev/null +++ b/examples/host/cdc_msc_hid_freertos/only.txt @@ -0,0 +1,13 @@ +mcu:LPC175X_6X +mcu:LPC177X_8X +mcu:LPC18XX +mcu:LPC40XX +mcu:LPC43XX +mcu:MIMXRT1XXX +mcu:MIMXRT10XX +mcu:MIMXRT11XX +mcu:RP2040 +mcu:MSP432E4 +mcu:RX65X +mcu:RAXXX +mcu:MAX3421 diff --git a/examples/host/cdc_msc_hid_freertos/src/CMakeLists.txt b/examples/host/cdc_msc_hid_freertos/src/CMakeLists.txt index dd7ec8e58..6f057c106 100644 --- a/examples/host/cdc_msc_hid_freertos/src/CMakeLists.txt +++ b/examples/host/cdc_msc_hid_freertos/src/CMakeLists.txt @@ -1,4 +1,6 @@ # This file is for ESP-IDF only -idf_component_register(SRCS "hid_app.c" "main.c" +idf_component_register(SRCS "cdc_app.c" "hid_app.c" "main.c" "msc_app.c" INCLUDE_DIRS "." REQUIRES boards tinyusb_src) + +target_compile_options(${COMPONENT_LIB} PRIVATE -Wno-error=format) diff --git a/examples/host/cdc_msc_hid_freertos/src/cdc_app.c b/examples/host/cdc_msc_hid_freertos/src/cdc_app.c new file mode 100644 index 000000000..fc2b1228d --- /dev/null +++ b/examples/host/cdc_msc_hid_freertos/src/cdc_app.c @@ -0,0 +1,109 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2022, Ha Thach (tinyusb.org) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + +#include "tusb.h" +#include "bsp/board_api.h" + +//--------------------------------------------------------------------+ +// MACRO TYPEDEF CONSTANT ENUM DECLARATION +//--------------------------------------------------------------------+ + + +//------------- IMPLEMENTATION -------------// + +size_t get_console_inputs(uint8_t *buf, size_t bufsize) { + size_t count = 0; + while (count < bufsize) { + int ch = board_getchar(); + if (ch <= 0) break; + + buf[count] = (uint8_t) ch; + count++; + } + + return count; +} + +void cdc_app_task(void* param) { + (void) param; + + uint8_t buf[64 + 1]; // +1 for extra null character + uint32_t const bufsize = sizeof(buf) - 1; + + while (1) { + uint32_t count = get_console_inputs(buf, bufsize); + buf[count] = 0; + + if (count) { + // loop over all mounted interfaces + for (uint8_t idx = 0; idx < CFG_TUH_CDC; idx++) { + if (tuh_cdc_mounted(idx)) { + // console --> cdc interfaces + tuh_cdc_write(idx, buf, count); + tuh_cdc_write_flush(idx); + } + } + } + + taskYIELD(); + } +} + +// Invoked when received new data +void tuh_cdc_rx_cb(uint8_t idx) { + uint8_t buf[64 + 1]; // +1 for extra null character + uint32_t const bufsize = sizeof(buf) - 1; + + // forward cdc interfaces -> console + uint32_t count = tuh_cdc_read(idx, buf, bufsize); + buf[count] = 0; + + printf((char *) buf); +} + +void tuh_cdc_mount_cb(uint8_t idx) { + tuh_itf_info_t itf_info = { 0 }; + tuh_cdc_itf_get_info(idx, &itf_info); + + printf("CDC Interface is mounted: address = %u, itf_num = %u\r\n", itf_info.daddr, itf_info.desc.bInterfaceNumber); + +#ifdef CFG_TUH_CDC_LINE_CODING_ON_ENUM + // CFG_TUH_CDC_LINE_CODING_ON_ENUM must be defined for line coding is set by tinyusb in enumeration + // otherwise you need to call tuh_cdc_set_line_coding() first + cdc_line_coding_t line_coding = { 0 }; + if (tuh_cdc_get_local_line_coding(idx, &line_coding)) { + printf(" Baudrate: %lu, Stop Bits : %u\r\n", line_coding.bit_rate, line_coding.stop_bits); + printf(" Parity : %u, Data Width: %u\r\n", line_coding.parity, line_coding.data_bits); + } +#endif +} + +void tuh_cdc_umount_cb(uint8_t idx) { + tuh_itf_info_t itf_info = { 0 }; + tuh_cdc_itf_get_info(idx, &itf_info); + + printf("CDC Interface is unmounted: address = %u, itf_num = %u\r\n", itf_info.daddr, itf_info.desc.bInterfaceNumber); +} diff --git a/examples/host/cdc_msc_hid_freertos/src/freertos_hook.c b/examples/host/cdc_msc_hid_freertos/src/freertos_hook.c new file mode 100644 index 000000000..07d159fd5 --- /dev/null +++ b/examples/host/cdc_msc_hid_freertos/src/freertos_hook.c @@ -0,0 +1,111 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2019 Ha Thach (tinyusb.org) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + +//--------------------------------------------------------------------+ +// INCLUDE +//--------------------------------------------------------------------+ +#include "FreeRTOS.h" +#include "task.h" +#include "common/tusb_common.h" + +void vApplicationMallocFailedHook(void) { + taskDISABLE_INTERRUPTS(); + TU_ASSERT(false,); +} + +void vApplicationStackOverflowHook(xTaskHandle pxTask, char *pcTaskName) { + (void) pxTask; + (void) pcTaskName; + + taskDISABLE_INTERRUPTS(); + TU_ASSERT(false,); +} + +/* configSUPPORT_STATIC_ALLOCATION is set to 1, so the application must provide an + * implementation of vApplicationGetIdleTaskMemory() to provide the memory that is + * used by the Idle task. */ +void vApplicationGetIdleTaskMemory(StaticTask_t **ppxIdleTaskTCBBuffer, StackType_t **ppxIdleTaskStackBuffer, + uint32_t *pulIdleTaskStackSize) { + /* If the buffers to be provided to the Idle task are declared inside this + * function then they must be declared static - otherwise they will be allocated on + * the stack and so not exists after this function exits. */ + static StaticTask_t xIdleTaskTCB; + static StackType_t uxIdleTaskStack[configMINIMAL_STACK_SIZE]; + + /* Pass out a pointer to the StaticTask_t structure in which the Idle task's + state will be stored. */ + *ppxIdleTaskTCBBuffer = &xIdleTaskTCB; + + /* Pass out the array that will be used as the Idle task's stack. */ + *ppxIdleTaskStackBuffer = uxIdleTaskStack; + + /* Pass out the size of the array pointed to by *ppxIdleTaskStackBuffer. + Note that, as the array is necessarily of type StackType_t, + configMINIMAL_STACK_SIZE is specified in words, not bytes. */ + *pulIdleTaskStackSize = configMINIMAL_STACK_SIZE; +} + +/* configSUPPORT_STATIC_ALLOCATION and configUSE_TIMERS are both set to 1, so the + * application must provide an implementation of vApplicationGetTimerTaskMemory() + * to provide the memory that is used by the Timer service task. */ +void vApplicationGetTimerTaskMemory(StaticTask_t **ppxTimerTaskTCBBuffer, StackType_t **ppxTimerTaskStackBuffer, + uint32_t *pulTimerTaskStackSize) { + /* If the buffers to be provided to the Timer task are declared inside this + * function then they must be declared static - otherwise they will be allocated on + * the stack and so not exists after this function exits. */ + static StaticTask_t xTimerTaskTCB; + static StackType_t uxTimerTaskStack[configTIMER_TASK_STACK_DEPTH]; + + /* Pass out a pointer to the StaticTask_t structure in which the Timer + task's state will be stored. */ + *ppxTimerTaskTCBBuffer = &xTimerTaskTCB; + + /* Pass out the array that will be used as the Timer task's stack. */ + *ppxTimerTaskStackBuffer = uxTimerTaskStack; + + /* Pass out the size of the array pointed to by *ppxTimerTaskStackBuffer. + Note that, as the array is necessarily of type StackType_t, + configTIMER_TASK_STACK_DEPTH is specified in words, not bytes. */ + *pulTimerTaskStackSize = configTIMER_TASK_STACK_DEPTH; +} + +#if CFG_TUSB_MCU == OPT_MCU_RX63X | CFG_TUSB_MCU == OPT_MCU_RX65X +#include "iodefine.h" +void vApplicationSetupTimerInterrupt(void) +{ + /* Enable CMT0 */ + SYSTEM.PRCR.WORD = (0xA5u<<8) | TU_BIT(1); + MSTP(CMT0) = 0; + SYSTEM.PRCR.WORD = (0xA5u<<8); + + CMT0.CMCNT = 0; + CMT0.CMCOR = (unsigned short)(((configPERIPHERAL_CLOCK_HZ/configTICK_RATE_HZ)-1)/128); + CMT0.CMCR.WORD = TU_BIT(6) | 2; + IR(CMT0, CMI0) = 0; + IPR(CMT0, CMI0) = configKERNEL_INTERRUPT_PRIORITY; + IEN(CMT0, CMI0) = 1; + CMT.CMSTR0.BIT.STR0 = 1; +} +#endif diff --git a/examples/host/cdc_msc_hid_freertos/src/hid_app.c b/examples/host/cdc_msc_hid_freertos/src/hid_app.c new file mode 100644 index 000000000..a2df3b909 --- /dev/null +++ b/examples/host/cdc_msc_hid_freertos/src/hid_app.c @@ -0,0 +1,263 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2021, Ha Thach (tinyusb.org) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + +#include "bsp/board_api.h" +#include "tusb.h" + +//--------------------------------------------------------------------+ +// MACRO TYPEDEF CONSTANT ENUM DECLARATION +//--------------------------------------------------------------------+ + +// If your host terminal support ansi escape code such as TeraTerm +// it can be use to simulate mouse cursor movement within terminal +#define USE_ANSI_ESCAPE 0 + +#define MAX_REPORT 4 + +static uint8_t const keycode2ascii[128][2] = { HID_KEYCODE_TO_ASCII }; + +// Each HID instance can has multiple reports +static struct { + uint8_t report_count; + tuh_hid_report_info_t report_info[MAX_REPORT]; +} hid_info[CFG_TUH_HID]; + +static void process_kbd_report(hid_keyboard_report_t const *report); +static void process_mouse_report(hid_mouse_report_t const *report); +static void process_generic_report(uint8_t dev_addr, uint8_t instance, uint8_t const *report, uint16_t len); + +//--------------------------------------------------------------------+ +// TinyUSB Callbacks +//--------------------------------------------------------------------+ + +// Invoked when device with hid interface is mounted +// Report descriptor is also available for use. tuh_hid_parse_report_descriptor() +// can be used to parse common/simple enough descriptor. +// Note: if report descriptor length > CFG_TUH_ENUMERATION_BUFSIZE, it will be skipped +// therefore report_desc = NULL, desc_len = 0 +void tuh_hid_mount_cb(uint8_t dev_addr, uint8_t instance, uint8_t const *desc_report, uint16_t desc_len) { + printf("HID device address = %d, instance = %d is mounted\r\n", dev_addr, instance); + + // Interface protocol (hid_interface_protocol_enum_t) + const char *protocol_str[] = { "None", "Keyboard", "Mouse" }; + uint8_t const itf_protocol = tuh_hid_interface_protocol(dev_addr, instance); + + printf("HID Interface Protocol = %s\r\n", protocol_str[itf_protocol]); + + // By default host stack will use activate boot protocol on supported interface. + // Therefore for this simple example, we only need to parse generic report descriptor (with built-in parser) + if (itf_protocol == HID_ITF_PROTOCOL_NONE) { + hid_info[instance].report_count = tuh_hid_parse_report_descriptor(hid_info[instance].report_info, MAX_REPORT, + desc_report, desc_len); + printf("HID has %u reports \r\n", hid_info[instance].report_count); + } + + // request to receive report + // tuh_hid_report_received_cb() will be invoked when report is available + if (!tuh_hid_receive_report(dev_addr, instance)) { + printf("Error: cannot request to receive report\r\n"); + } +} + +// Invoked when device with hid interface is un-mounted +void tuh_hid_umount_cb(uint8_t dev_addr, uint8_t instance) { + printf("HID device address = %d, instance = %d is unmounted\r\n", dev_addr, instance); +} + +// Invoked when received report from device via interrupt endpoint +void tuh_hid_report_received_cb(uint8_t dev_addr, uint8_t instance, uint8_t const *report, uint16_t len) { + uint8_t const itf_protocol = tuh_hid_interface_protocol(dev_addr, instance); + + switch (itf_protocol) { + case HID_ITF_PROTOCOL_KEYBOARD: + TU_LOG2("HID receive boot keyboard report\r\n"); + process_kbd_report((hid_keyboard_report_t const *) report); + break; + + case HID_ITF_PROTOCOL_MOUSE: + TU_LOG2("HID receive boot mouse report\r\n"); + process_mouse_report((hid_mouse_report_t const *) report); + break; + + default: + // Generic report requires matching ReportID and contents with previous parsed report info + process_generic_report(dev_addr, instance, report, len); + break; + } + + // continue to request to receive report + if (!tuh_hid_receive_report(dev_addr, instance)) { + printf("Error: cannot request to receive report\r\n"); + } +} + +//--------------------------------------------------------------------+ +// Keyboard +//--------------------------------------------------------------------+ + +// look up new key in previous keys +static inline bool find_key_in_report(hid_keyboard_report_t const *report, uint8_t keycode) { + for (uint8_t i = 0; i < 6; i++) { + if (report->keycode[i] == keycode) return true; + } + + return false; +} + +static void process_kbd_report(hid_keyboard_report_t const *report) { + static hid_keyboard_report_t prev_report = { 0, 0, { 0 } }; // previous report to check key released + + //------------- example code ignore control (non-printable) key affects -------------// + for (uint8_t i = 0; i < 6; i++) { + if (report->keycode[i]) { + if (find_key_in_report(&prev_report, report->keycode[i])) { + // exist in previous report means the current key is holding + } else { + // not existed in previous report means the current key is pressed + bool const is_shift = report->modifier & (KEYBOARD_MODIFIER_LEFTSHIFT | KEYBOARD_MODIFIER_RIGHTSHIFT); + uint8_t ch = keycode2ascii[report->keycode[i]][is_shift ? 1 : 0]; + putchar(ch); + if (ch == '\r') putchar('\n'); // added new line for enter key + + #ifndef __ICCARM__ // TODO IAR doesn't support stream control ? + fflush(stdout); // flush right away, else nanolib will wait for newline + #endif + } + } + // TODO example skips key released + } + + prev_report = *report; +} + +//--------------------------------------------------------------------+ +// Mouse +//--------------------------------------------------------------------+ + +void cursor_movement(int8_t x, int8_t y, int8_t wheel) { +#if USE_ANSI_ESCAPE + // Move X using ansi escape + if ( x < 0) { + printf(ANSI_CURSOR_BACKWARD(%d), (-x)); // move left + }else if ( x > 0) { + printf(ANSI_CURSOR_FORWARD(%d), x); // move right + } + + // Move Y using ansi escape + if ( y < 0) { + printf(ANSI_CURSOR_UP(%d), (-y)); // move up + }else if ( y > 0) { + printf(ANSI_CURSOR_DOWN(%d), y); // move down + } + + // Scroll using ansi escape + if (wheel < 0) { + printf(ANSI_SCROLL_UP(%d), (-wheel)); // scroll up + }else if (wheel > 0) { + printf(ANSI_SCROLL_DOWN(%d), wheel); // scroll down + } + + printf("\r\n"); +#else + printf("(%d %d %d)\r\n", x, y, wheel); +#endif +} + +static void process_mouse_report(hid_mouse_report_t const *report) { + static hid_mouse_report_t prev_report = { 0 }; + + //------------- button state -------------// + uint8_t button_changed_mask = report->buttons ^ prev_report.buttons; + if (button_changed_mask & report->buttons) { + printf(" %c%c%c ", + report->buttons & MOUSE_BUTTON_LEFT ? 'L' : '-', + report->buttons & MOUSE_BUTTON_MIDDLE ? 'M' : '-', + report->buttons & MOUSE_BUTTON_RIGHT ? 'R' : '-'); + } + + //------------- cursor movement -------------// + cursor_movement(report->x, report->y, report->wheel); +} + +//--------------------------------------------------------------------+ +// Generic Report +//--------------------------------------------------------------------+ +static void process_generic_report(uint8_t dev_addr, uint8_t instance, uint8_t const *report, uint16_t len) { + (void) dev_addr; + + uint8_t const rpt_count = hid_info[instance].report_count; + tuh_hid_report_info_t *rpt_info_arr = hid_info[instance].report_info; + tuh_hid_report_info_t *rpt_info = NULL; + + if (rpt_count == 1 && rpt_info_arr[0].report_id == 0) { + // Simple report without report ID as 1st byte + rpt_info = &rpt_info_arr[0]; + } else { + // Composite report, 1st byte is report ID, data starts from 2nd byte + uint8_t const rpt_id = report[0]; + + // Find report id in the array + for (uint8_t i = 0; i < rpt_count; i++) { + if (rpt_id == rpt_info_arr[i].report_id) { + rpt_info = &rpt_info_arr[i]; + break; + } + } + + report++; + len--; + } + + if (!rpt_info) { + printf("Couldn't find report info !\r\n"); + return; + } + + // For complete list of Usage Page & Usage checkout src/class/hid/hid.h. For examples: + // - Keyboard : Desktop, Keyboard + // - Mouse : Desktop, Mouse + // - Gamepad : Desktop, Gamepad + // - Consumer Control (Media Key) : Consumer, Consumer Control + // - System Control (Power key) : Desktop, System Control + // - Generic (vendor) : 0xFFxx, xx + if (rpt_info->usage_page == HID_USAGE_PAGE_DESKTOP) { + switch (rpt_info->usage) { + case HID_USAGE_DESKTOP_KEYBOARD: + TU_LOG1("HID receive keyboard report\r\n"); + // Assume keyboard follow boot report layout + process_kbd_report((hid_keyboard_report_t const *) report); + break; + + case HID_USAGE_DESKTOP_MOUSE: + TU_LOG1("HID receive mouse report\r\n"); + // Assume mouse follow boot report layout + process_mouse_report((hid_mouse_report_t const *) report); + break; + + default: + break; + } + } +} diff --git a/examples/host/cdc_msc_hid_freertos/src/main.c b/examples/host/cdc_msc_hid_freertos/src/main.c index e2ddd52eb..d5574789f 100644 --- a/examples/host/cdc_msc_hid_freertos/src/main.c +++ b/examples/host/cdc_msc_hid_freertos/src/main.c @@ -51,6 +51,8 @@ #define USBH_STACK_SIZE (3*configMINIMAL_STACK_SIZE/2) * (CFG_TUSB_DEBUG ? 2 : 1) #endif +#define CDC_STACK_SZIE (3*configMINIMAL_STACK_SIZE/2) + //--------------------------------------------------------------------+ // MACRO CONSTANT TYPEDEF PROTOTYPES //--------------------------------------------------------------------+ @@ -72,18 +74,16 @@ StaticTimer_t blinky_tmdef; StackType_t usb_host_stack[USBH_STACK_SIZE]; StaticTask_t usb_host_taskdef; -//StackType_t cdc_stack[CDC_STACK_SZIE]; -//StaticTask_t cdc_taskdef; +StackType_t cdc_stack[CDC_STACK_SZIE]; +StaticTask_t cdc_taskdef; #endif - TimerHandle_t blinky_tm; static void led_blinky_cb(TimerHandle_t xTimer); static void usb_host_task(void* param); -extern void cdc_app_task(void); -extern void hid_app_task(void); +extern void cdc_app_task(void* param); /*------------- MAIN -------------*/ int main(void) { @@ -91,19 +91,15 @@ int main(void) { printf("TinyUSB Host CDC MSC HID with FreeRTOS Example\r\n"); + // Create soft timer for blinky, task for tinyusb stack and CDC #if configSUPPORT_STATIC_ALLOCATION - // soft timer for blinky blinky_tm = xTimerCreateStatic(NULL, pdMS_TO_TICKS(BLINK_MOUNTED), true, NULL, led_blinky_cb, &blinky_tmdef); - - // Create a task for tinyusb device stack xTaskCreateStatic(usb_host_task, "usbh", USBH_STACK_SIZE, NULL, configMAX_PRIORITIES-1, usb_host_stack, &usb_host_taskdef); - - // Create CDC task - //xTaskCreateStatic(cdc_task, "cdc", CDC_STACK_SZIE, NULL, configMAX_PRIORITIES-2, cdc_stack, &cdc_taskdef); + xTaskCreateStatic(cdc_app_task, "cdc", CDC_STACK_SZIE, NULL, configMAX_PRIORITIES-2, cdc_stack, &cdc_taskdef); #else blinky_tm = xTimerCreate(NULL, pdMS_TO_TICKS(BLINK_NOT_MOUNTED), true, NULL, led_blinky_cb); - xTaskCreate( usb_device_task, "usbd", USBH_STACK_SIZE, NULL, configMAX_PRIORITIES-1, NULL); - //xTaskCreate( cdc_task, "cdc", CDC_STACK_SZIE, NULL, configMAX_PRIORITIES-2, NULL); + xTaskCreate(usb_host_task, "usbd", USBH_STACK_SIZE, NULL, configMAX_PRIORITIES-1, NULL); + xTaskCreate(cdc_app_task, "cdc", CDC_STACK_SZIE, NULL, configMAX_PRIORITIES-2, NULL); #endif xTimerStart(blinky_tm, 0); diff --git a/examples/host/cdc_msc_hid_freertos/src/msc_app.c b/examples/host/cdc_msc_hid_freertos/src/msc_app.c new file mode 100644 index 000000000..a8d6fbfaa --- /dev/null +++ b/examples/host/cdc_msc_hid_freertos/src/msc_app.c @@ -0,0 +1,67 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2019 Ha Thach (tinyusb.org) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + +#include "tusb.h" + +#if CFG_TUH_MSC + +static scsi_inquiry_resp_t inquiry_resp; + +bool inquiry_complete_cb(uint8_t dev_addr, tuh_msc_complete_data_t const *cb_data) { + msc_cbw_t const *cbw = cb_data->cbw; + msc_csw_t const *csw = cb_data->csw; + + if (csw->status != 0) { + printf("Inquiry failed\r\n"); + return false; + } + + // Print out Vendor ID, Product ID and Rev + printf("%.8s %.16s rev %.4s\r\n", inquiry_resp.vendor_id, inquiry_resp.product_id, inquiry_resp.product_rev); + + // Get capacity of device + uint32_t const block_count = tuh_msc_get_block_count(dev_addr, cbw->lun); + uint32_t const block_size = tuh_msc_get_block_size(dev_addr, cbw->lun); + + printf("Disk Size: %lu MB\r\n", block_count / ((1024 * 1024) / block_size)); + printf("Block Count = %lu, Block Size: %lu\r\n", block_count, block_size); + + return true; +} + +//------------- IMPLEMENTATION -------------// +void tuh_msc_mount_cb(uint8_t dev_addr) { + printf("A MassStorage device is mounted\r\n"); + + uint8_t const lun = 0; + tuh_msc_inquiry(dev_addr, lun, &inquiry_resp, inquiry_complete_cb, 0); +} + +void tuh_msc_umount_cb(uint8_t dev_addr) { + (void) dev_addr; + printf("A MassStorage device is unmounted\r\n"); +} + +#endif diff --git a/hw/bsp/espressif/boards/CMakeLists.txt b/hw/bsp/espressif/boards/CMakeLists.txt index 325263c1d..8209e8747 100644 --- a/hw/bsp/espressif/boards/CMakeLists.txt +++ b/hw/bsp/espressif/boards/CMakeLists.txt @@ -4,3 +4,5 @@ idf_component_register(SRCS family.c INCLUDE_DIRS "." ${BOARD} ${hw_dir} PRIV_REQUIRES "driver" REQUIRES led_strip src tinyusb_src) + +target_compile_options(${COMPONENT_LIB} PRIVATE -Wno-error=format) diff --git a/hw/bsp/espressif/boards/family.c b/hw/bsp/espressif/boards/family.c index 250b7001e..d96d86670 100644 --- a/hw/bsp/espressif/boards/family.c +++ b/hw/bsp/espressif/boards/family.c @@ -33,6 +33,7 @@ #include "soc/usb_periph.h" #include "driver/rmt.h" +#include "driver/uart.h" #if ESP_IDF_VERSION_MAJOR > 4 #include "esp_private/periph_ctrl.h" @@ -145,9 +146,7 @@ uint32_t board_button_read(void) { // Get characters from UART int board_uart_read(uint8_t *buf, int len) { - (void) buf; - (void) len; - return 0; + return uart_read_bytes(UART_NUM_0, buf, len, 0); } // Send characters to UART @@ -157,6 +156,11 @@ int board_uart_write(void const *buf, int len) { return 0; } +int board_getchar(void) { + char c; + return (uart_read_bytes(UART_NUM_0, &c, 1, 0) > 0) ? (int) c : (-1); +} + //--------------------------------------------------------------------+ // API: SPI transfer with MAX3421E, must be implemented by application //--------------------------------------------------------------------+ @@ -164,12 +168,12 @@ int board_uart_write(void const *buf, int len) { static spi_device_handle_t max3421_spi; -static void IRAM_ATTR max3421_isr_handler(void* arg) -{ - (void) arg; - //uint32_t gpio_num = (uint32_t) arg; +static void IRAM_ATTR max3421_isr_handler(void* arg) { + (void) arg; // arg is gpio num //xQueueSendFromISR(gpio_evt_queue, &gpio_num, NULL); + gpio_set_level(13, 1); tuh_int_handler(1); + gpio_set_level(13, 0); } static void max3421_init(void) { @@ -188,12 +192,11 @@ static void max3421_init(void) { .data5_io_num = -1, .data6_io_num = -1, .data7_io_num = -1, - .max_transfer_sz = 128 + .max_transfer_sz = 1024 }; ESP_ERROR_CHECK( spi_bus_initialize(MAX3421_SPI_HOST, &buscfg, SPI_DMA_CH_AUTO) ); spi_device_interface_config_t max3421_cfg = { - .command_bits = 8, .mode = 0, .clock_speed_hz = 4000000, // 26000000 .spics_io_num = -1, // manual control CS @@ -201,12 +204,16 @@ static void max3421_init(void) { }; ESP_ERROR_CHECK( spi_bus_add_device(MAX3421_SPI_HOST, &max3421_cfg, &max3421_spi) ); + // debug + gpio_set_direction(13, GPIO_MODE_OUTPUT); + gpio_set_level(13, 0); + // Interrupt pin -// gpio_set_direction(MAX3421_INTR_PIN, GPIO_MODE_INPUT); -// gpio_set_intr_type(MAX3421_INTR_PIN, GPIO_INTR_NEGEDGE); -// -// gpio_install_isr_service(ESP_INTR_FLAG_EDGE); -// gpio_isr_handler_add(MAX3421_INTR_PIN, max3421_isr_handler, NULL); + gpio_set_direction(MAX3421_INTR_PIN, GPIO_MODE_INPUT); + gpio_set_intr_type(MAX3421_INTR_PIN, GPIO_INTR_NEGEDGE); + + gpio_install_isr_service(0); + gpio_isr_handler_add(MAX3421_INTR_PIN, max3421_isr_handler, NULL); } void tuh_max3421_int_api(uint8_t rhport, bool enabled) { @@ -227,8 +234,8 @@ bool tuh_max3421_spi_xfer_api(uint8_t rhport, uint8_t const *tx_buf, size_t tx_l (void) rhport; spi_transaction_t xact = { - .length = tx_len, - .rxlength = rx_len, + .length = tx_len << 3, // length in bits + .rxlength = rx_len << 3, // length in bits .tx_buffer = tx_buf, .rx_buffer = rx_buf }; diff --git a/hw/bsp/espressif/components/tinyusb_src/CMakeLists.txt b/hw/bsp/espressif/components/tinyusb_src/CMakeLists.txt index 2a154a8ff..abe276910 100644 --- a/hw/bsp/espressif/components/tinyusb_src/CMakeLists.txt +++ b/hw/bsp/espressif/components/tinyusb_src/CMakeLists.txt @@ -70,3 +70,4 @@ idf_component_register(SRCS ${srcs} ) target_compile_definitions(${COMPONENT_LIB} PUBLIC ${compile_definitions}) +target_compile_options(${COMPONENT_LIB} PRIVATE -Wno-error=format) diff --git a/hw/bsp/nrf/family.c b/hw/bsp/nrf/family.c index 6fcfd9476..3620bc8cc 100644 --- a/hw/bsp/nrf/family.c +++ b/hw/bsp/nrf/family.c @@ -95,13 +95,8 @@ TU_ATTR_UNUSED static void power_event_handler(nrfx_power_usb_evt_t event) { //------------- Host using MAX2341E -------------// #if CFG_TUH_ENABLED && defined(CFG_TUH_MAX3421) && CFG_TUH_MAX3421 +static void max3421_init(void); static nrfx_spim_t _spi = NRFX_SPIM_INSTANCE(1); - -void max3421_int_handler(nrfx_gpiote_pin_t pin, nrf_gpiote_polarity_t action) { - if (!(pin == MAX3421_INTR_PIN && action == NRF_GPIOTE_POLARITY_HITOLO)) return; - - tuh_int_handler(1); -} #endif @@ -191,50 +186,7 @@ void board_init(void) { #endif #if CFG_TUH_ENABLED && defined(CFG_TUH_MAX3421) && CFG_TUH_MAX3421 - // MAX3421 need 3.3v signal (may not be needed) - #if defined(UICR_REGOUT0_VOUT_Msk) && 0 - if ((NRF_UICR->REGOUT0 & UICR_REGOUT0_VOUT_Msk) != UICR_REGOUT0_VOUT_3V3) { - NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Wen << NVMC_CONFIG_WEN_Pos; - while (NRF_NVMC->READY == NVMC_READY_READY_Busy){} - - NRF_UICR->REGOUT0 = (NRF_UICR->REGOUT0 & ~UICR_REGOUT0_VOUT_Msk) | UICR_REGOUT0_VOUT_3V3; - - NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Ren << NVMC_CONFIG_WEN_Pos; - while (NRF_NVMC->READY == NVMC_READY_READY_Busy){} - - NVIC_SystemReset(); - } - #endif - - // manually manage CS - nrf_gpio_cfg_output(MAX3421_CS_PIN); - nrf_gpio_pin_write(MAX3421_CS_PIN, 1); - - // USB host using max3421e usb controller via SPI - nrfx_spim_config_t cfg = { - .sck_pin = MAX3421_SCK_PIN, - .mosi_pin = MAX3421_MOSI_PIN, - .miso_pin = MAX3421_MISO_PIN, - .ss_pin = NRFX_SPIM_PIN_NOT_USED, - .ss_active_high = false, - .irq_priority = 3, - .orc = 0xFF, - // default setting 4 Mhz, Mode 0, MSB first - .frequency = NRF_SPIM_FREQ_4M, - .mode = NRF_SPIM_MODE_0, - .bit_order = NRF_SPIM_BIT_ORDER_MSB_FIRST, - }; - - // no handler --> blocking - nrfx_spim_init(&_spi, &cfg, NULL, NULL); - - // max3421e interrupt pin - nrfx_gpiote_init(1); - nrfx_gpiote_in_config_t in_config = NRFX_GPIOTE_CONFIG_IN_SENSE_HITOLO(true); - in_config.pull = NRF_GPIO_PIN_PULLUP; - - nrfx_gpiote_in_init(MAX3421_INTR_PIN, &in_config, max3421_int_handler); - nrfx_gpiote_trigger_enable(MAX3421_INTR_PIN, true); + max3421_init(); #endif } @@ -317,6 +269,60 @@ void nrf_error_cb(uint32_t id, uint32_t pc, uint32_t info) { //--------------------------------------------------------------------+ #if CFG_TUH_ENABLED && defined(CFG_TUH_MAX3421) && CFG_TUH_MAX3421 +void max3421_int_handler(nrfx_gpiote_pin_t pin, nrf_gpiote_polarity_t action) { + if (!(pin == MAX3421_INTR_PIN && action == NRF_GPIOTE_POLARITY_HITOLO)) return; + tuh_int_handler(1); +} + +static void max3421_init(void) { + // MAX3421 need 3.3v signal (may not be needed) +// #if defined(UICR_REGOUT0_VOUT_Msk) +// if ((NRF_UICR->REGOUT0 & UICR_REGOUT0_VOUT_Msk) != UICR_REGOUT0_VOUT_3V3) { +// NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Wen << NVMC_CONFIG_WEN_Pos; +// while (NRF_NVMC->READY == NVMC_READY_READY_Busy){} +// +// NRF_UICR->REGOUT0 = (NRF_UICR->REGOUT0 & ~UICR_REGOUT0_VOUT_Msk) | UICR_REGOUT0_VOUT_3V3; +// +// NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Ren << NVMC_CONFIG_WEN_Pos; +// while (NRF_NVMC->READY == NVMC_READY_READY_Busy){} +// +// NVIC_SystemReset(); +// } +// #endif + + // manually manage CS + nrf_gpio_cfg_output(MAX3421_CS_PIN); + nrf_gpio_pin_write(MAX3421_CS_PIN, 1); + + // USB host using max3421e usb controller via SPI + nrfx_spim_config_t cfg = { + .sck_pin = MAX3421_SCK_PIN, + .mosi_pin = MAX3421_MOSI_PIN, + .miso_pin = MAX3421_MISO_PIN, + .ss_pin = NRFX_SPIM_PIN_NOT_USED, + .ss_active_high = false, + .irq_priority = 3, + .orc = 0xFF, + // default setting 4 Mhz, Mode 0, MSB first + .frequency = NRF_SPIM_FREQ_4M, + .mode = NRF_SPIM_MODE_0, + .bit_order = NRF_SPIM_BIT_ORDER_MSB_FIRST, + }; + + // no handler --> blocking + nrfx_spim_init(&_spi, &cfg, NULL, NULL); + + // max3421e interrupt pin + nrfx_gpiote_init(1); + nrfx_gpiote_in_config_t in_config = NRFX_GPIOTE_CONFIG_IN_SENSE_HITOLO(true); + in_config.pull = NRF_GPIO_PIN_PULLUP; + + NVIC_SetPriority(GPIOTE_IRQn, 2); + + nrfx_gpiote_in_init(MAX3421_INTR_PIN, &in_config, max3421_int_handler); + nrfx_gpiote_trigger_enable(MAX3421_INTR_PIN, true); +} + void tuh_max3421_int_api(uint8_t rhport, bool enabled) { (void) rhport; diff --git a/hw/bsp/samd21/family.c b/hw/bsp/samd21/family.c index 395155548..335039e2f 100644 --- a/hw/bsp/samd21/family.c +++ b/hw/bsp/samd21/family.c @@ -261,6 +261,7 @@ void SysTick_Handler(void) { uint32_t board_millis(void) { return system_ticks; } +#endif //--------------------------------------------------------------------+ // @@ -344,6 +345,11 @@ static void max3421_init(void) { EIC->CONFIG[0].reg &= ~(7 << sense_shift); EIC->CONFIG[0].reg |= 2 << sense_shift; +#if CFG_TUSB_OS == OPT_OS_FREERTOS + // If freeRTOS is used, IRQ priority is limit by max syscall ( smaller is higher ) + NVIC_SetPriority(EIC_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY); +#endif + // Enable External Interrupt EIC->INTENSET.reg = EIC_INTENSET_EXTINT(1 << MAX3421_INTR_EIC_ID); @@ -413,6 +419,3 @@ bool tuh_max3421_spi_xfer_api(uint8_t rhport, uint8_t const *tx_buf, size_t tx_l } #endif - - -#endif diff --git a/hw/bsp/samd51/FreeRTOSConfig/FreeRTOSConfig.h b/hw/bsp/samd51/FreeRTOSConfig/FreeRTOSConfig.h index e3ee529cf..32db4ad95 100644 --- a/hw/bsp/samd51/FreeRTOSConfig/FreeRTOSConfig.h +++ b/hw/bsp/samd51/FreeRTOSConfig/FreeRTOSConfig.h @@ -59,7 +59,7 @@ #define configTICK_RATE_HZ ( 1000 ) #define configMAX_PRIORITIES ( 5 ) #define configMINIMAL_STACK_SIZE ( 128 ) -#define configTOTAL_HEAP_SIZE ( configSUPPORT_DYNAMIC_ALLOCATION*4*1024 ) +#define configTOTAL_HEAP_SIZE ( configSUPPORT_DYNAMIC_ALLOCATION*6*1024 ) #define configMAX_TASK_NAME_LEN 16 #define configUSE_16_BIT_TICKS 0 #define configIDLE_SHOULD_YIELD 1 diff --git a/hw/bsp/samd51/family.c b/hw/bsp/samd51/family.c index c1b914a02..7b9de35c9 100644 --- a/hw/bsp/samd51/family.c +++ b/hw/bsp/samd51/family.c @@ -175,6 +175,7 @@ void SysTick_Handler(void) { uint32_t board_millis(void) { return system_ticks; } +#endif //--------------------------------------------------------------------+ // API: SPI transfer with MAX3421E, must be implemented by application @@ -290,6 +291,11 @@ static void max3421_init(void) { *eic_config &= ~(7 << sense_shift); *eic_config |= 2 << sense_shift; +#if CFG_TUSB_OS == OPT_OS_FREERTOS + // If freeRTOS is used, IRQ priority is limit by max syscall ( smaller is higher ) + NVIC_SetPriority(EIC_0_IRQn + MAX3421_INTR_EIC_ID, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY); +#endif + // Enable External Interrupt EIC->INTENSET.reg = EIC_INTENSET_EXTINT(1 << MAX3421_INTR_EIC_ID); @@ -360,5 +366,3 @@ bool tuh_max3421_spi_xfer_api(uint8_t rhport, uint8_t const *tx_buf, size_t tx_l } #endif - -#endif diff --git a/src/host/usbh.c b/src/host/usbh.c index dc2831da3..e332f35cc 100644 --- a/src/host/usbh.c +++ b/src/host/usbh.c @@ -659,7 +659,7 @@ static bool usbh_control_xfer_cb (uint8_t dev_addr, uint8_t ep_addr, xfer_result tusb_control_request_t const * request = &_ctrl_xfer.request; if (XFER_RESULT_SUCCESS != result) { - TU_LOG1("[%u:%u] Control %s, xferred_bytes = %u\r\n", rhport, dev_addr, result == XFER_RESULT_STALLED ? "STALLED" : "FAILED", xferred_bytes); + TU_LOG1("[%u:%u] Control %s, xferred_bytes = %lu\r\n", rhport, dev_addr, result == XFER_RESULT_STALLED ? "STALLED" : "FAILED", xferred_bytes); TU_LOG1_BUF(request, 8); TU_LOG1("\r\n"); -- cgit v1.3.1 From 2f6592de7f94851cfcca411242398c5da7b792de Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 27 Sep 2023 11:30:18 +0700 Subject: update max3421 to have hcd_int_handler_ext() --- hw/bsp/espressif/boards/family.c | 22 ++++++++++- src/host/hcd.h | 3 ++ src/portable/analog/max3421/hcd_max3421.c | 62 ++++++++++++++++--------------- 3 files changed, 55 insertions(+), 32 deletions(-) (limited to 'src/host') diff --git a/hw/bsp/espressif/boards/family.c b/hw/bsp/espressif/boards/family.c index d96d86670..a04e1e7c5 100644 --- a/hw/bsp/espressif/boards/family.c +++ b/hw/bsp/espressif/boards/family.c @@ -167,15 +167,30 @@ int board_getchar(void) { #if CFG_TUH_ENABLED && defined(CFG_TUH_MAX3421) && CFG_TUH_MAX3421 static spi_device_handle_t max3421_spi; +SemaphoreHandle_t max3421_intr_sem; static void IRAM_ATTR max3421_isr_handler(void* arg) { (void) arg; // arg is gpio num - //xQueueSendFromISR(gpio_evt_queue, &gpio_num, NULL); gpio_set_level(13, 1); - tuh_int_handler(1); + + BaseType_t xHigherPriorityTaskWoken = pdFALSE; + xSemaphoreGiveFromISR(max3421_intr_sem, &xHigherPriorityTaskWoken); + if (xHigherPriorityTaskWoken) { + portYIELD_FROM_ISR(); + } + gpio_set_level(13, 0); } +static void max3421_intr_task(void* param) { + (void) param; + + while (1) { + xSemaphoreTake(max3421_intr_sem, portMAX_DELAY); + tuh_int_handler(BOARD_TUH_RHPORT); + } +} + static void max3421_init(void) { // CS pin gpio_set_direction(MAX3421_CS_PIN, GPIO_MODE_OUTPUT); @@ -209,6 +224,9 @@ static void max3421_init(void) { gpio_set_level(13, 0); // Interrupt pin + max3421_intr_sem = xSemaphoreCreateBinary(); + xTaskCreate(max3421_intr_task, "max3421 intr", 2048, NULL, configMAX_PRIORITIES-1, NULL); + gpio_set_direction(MAX3421_INTR_PIN, GPIO_MODE_INPUT); gpio_set_intr_type(MAX3421_INTR_PIN, GPIO_INTR_NEGEDGE); diff --git a/src/host/hcd.h b/src/host/hcd.h index e25b20ea3..a2d4da85d 100644 --- a/src/host/hcd.h +++ b/src/host/hcd.h @@ -133,6 +133,9 @@ bool hcd_init(uint8_t rhport); // Interrupt Handler void hcd_int_handler(uint8_t rhport); +// Interrupt Hanndler (extended version) +void hcd_int_handler_ext(uint8_t rhport, bool in_isr); + // Enable USB interrupt void hcd_int_enable (uint8_t rhport); diff --git a/src/portable/analog/max3421/hcd_max3421.c b/src/portable/analog/max3421/hcd_max3421.c index 3f6747404..652a971ee 100644 --- a/src/portable/analog/max3421/hcd_max3421.c +++ b/src/portable/analog/max3421/hcd_max3421.c @@ -428,8 +428,8 @@ bool hcd_init(uint8_t rhport) { reg_write(rhport, PINCTL_ADDR, PINCTL_FDUPSPI, false); // V1 is 0x01, V2 is 0x12, V3 is 0x13 - // uint8_t const revision = reg_read(rhport, REVISION_ADDR, false); - // TU_LOG2_HEX(revision); + uint8_t const revision = reg_read(rhport, REVISION_ADDR, false); + TU_LOG2_HEX(revision); // reset reg_write(rhport, USBCTL_ADDR, USBCTL_CHIPRES, false); @@ -693,9 +693,7 @@ static void handle_connect_irq(uint8_t rhport, bool in_isr) { // port reset anyway, this will help to stable bus signal for next connection reg_write(rhport, HCTL_ADDR, HCTL_BUSRST, in_isr); - hcd_event_device_remove(rhport, in_isr); - reg_write(rhport, HCTL_ADDR, 0, in_isr); break; @@ -721,13 +719,12 @@ static void handle_connect_irq(uint8_t rhport, bool in_isr) { free_ep(daddr); hcd_event_device_attach(rhport, in_isr); - break; } } } -static void xfer_complete_isr(uint8_t rhport, max3421_ep_t *ep, xfer_result_t result, uint8_t hrsl) { +static void xfer_complete_isr(uint8_t rhport, max3421_ep_t *ep, xfer_result_t result, uint8_t hrsl, bool in_isr) { uint8_t const ep_addr = tu_edpt_addr(ep->ep_num, ep->ep_dir); // save data toggle @@ -738,20 +735,20 @@ static void xfer_complete_isr(uint8_t rhport, max3421_ep_t *ep, xfer_result_t re } ep->xfer_pending = 0; - hcd_event_xfer_complete(ep->daddr, ep_addr, ep->xferred_len, result, true); + hcd_event_xfer_complete(ep->daddr, ep_addr, ep->xferred_len, result, in_isr); // Find next pending endpoint max3421_ep_t *next_ep = find_next_pending_ep(ep); if (next_ep) { - xact_inout(rhport, next_ep, true, true); + xact_inout(rhport, next_ep, true, in_isr); }else { // no more pending atomic_flag_clear(&_hcd_data.busy); } } -static void handle_xfer_done(uint8_t rhport) { - uint8_t const hrsl = reg_read(rhport, HRSL_ADDR, true); +static void handle_xfer_done(uint8_t rhport, bool in_isr) { + uint8_t const hrsl = reg_read(rhport, HRSL_ADDR, in_isr); uint8_t const hresult = hrsl & HRSL_RESULT_MASK; uint8_t const ep_num = _hcd_data.hxfr & HXFR_EPNUM_MASK; @@ -774,17 +771,17 @@ static void handle_xfer_done(uint8_t rhport) { case HRSL_NAK: if (ep_num == 0) { // NAK on control, retry immediately - hxfr_write(rhport, _hcd_data.hxfr, true); + hxfr_write(rhport, _hcd_data.hxfr, in_isr); }else { // NAK on non-control, find next pending to switch max3421_ep_t *next_ep = find_next_pending_ep(ep); if (ep == next_ep) { // this endpoint is only one pending, retry immediately - hxfr_write(rhport, _hcd_data.hxfr, true); + hxfr_write(rhport, _hcd_data.hxfr, in_isr); }else if (next_ep) { // switch to next pending TODO could have issue with double buffered if not clear previously out data - xact_inout(rhport, next_ep, true, true); + xact_inout(rhport, next_ep, true, in_isr); }else { TU_ASSERT(false,); } @@ -802,7 +799,7 @@ static void handle_xfer_done(uint8_t rhport) { } if (xfer_result != XFER_RESULT_SUCCESS) { - xfer_complete_isr(rhport, ep, xfer_result, hrsl); + xfer_complete_isr(rhport, ep, xfer_result, hrsl, in_isr); return; } @@ -814,10 +811,10 @@ static void handle_xfer_done(uint8_t rhport) { // short packet or all bytes transferred if ( ep->xfer_complete ) { - xfer_complete_isr(rhport, ep, xfer_result, hrsl); + xfer_complete_isr(rhport, ep, xfer_result, hrsl, in_isr); }else { // more to transfer - hxfr_write(rhport, _hcd_data.hxfr, true); + hxfr_write(rhport, _hcd_data.hxfr, in_isr); } } else { // SETUP or OUT transfer @@ -835,10 +832,10 @@ static void handle_xfer_done(uint8_t rhport) { ep->buf += xact_len; if (xact_len < ep->packet_size || ep->xferred_len >= ep->total_len) { - xfer_complete_isr(rhport, ep, xfer_result, hrsl); + xfer_complete_isr(rhport, ep, xfer_result, hrsl, in_isr); } else { // more to transfer - xact_out(rhport, ep, false, true); + xact_out(rhport, ep, false, in_isr); } } } @@ -862,9 +859,9 @@ void print_hirq(uint8_t hirq) { #define print_hirq(hirq) #endif -// Interrupt Handler -void hcd_int_handler(uint8_t rhport) { - uint8_t hirq = reg_read(rhport, HIRQ_ADDR, true) & _hcd_data.hien; +// Interrupt handler (extended) +void hcd_int_handler_ext(uint8_t rhport, bool in_isr) { + uint8_t hirq = reg_read(rhport, HIRQ_ADDR, in_isr) & _hcd_data.hien; if (!hirq) return; // print_hirq(hirq); @@ -873,7 +870,7 @@ void hcd_int_handler(uint8_t rhport) { } if (hirq & HIRQ_CONDET_IRQ) { - handle_connect_irq(rhport, true); + handle_connect_irq(rhport, in_isr); } // queue more transfer in handle_xfer_done() can cause hirq to be set again while external IRQ may not catch and/or @@ -886,17 +883,17 @@ void hcd_int_handler(uint8_t rhport) { // RCVDAV_IRQ can trigger 2 times (dual buffered) while ( hirq & HIRQ_RCVDAV_IRQ ) { - uint8_t rcvbc = reg_read(rhport, RCVBC_ADDR, true); + uint8_t rcvbc = reg_read(rhport, RCVBC_ADDR, in_isr); xact_len = (uint8_t) tu_min16(rcvbc, ep->total_len - ep->xferred_len); if ( xact_len ) { - fifo_read(rhport, ep->buf, xact_len, true); + fifo_read(rhport, ep->buf, xact_len, in_isr); ep->buf += xact_len; ep->xferred_len += xact_len; } // ack RCVDVAV IRQ - hirq_write(rhport, HIRQ_RCVDAV_IRQ, true); - hirq = reg_read(rhport, HIRQ_ADDR, true); + hirq_write(rhport, HIRQ_RCVDAV_IRQ, in_isr); + hirq = reg_read(rhport, HIRQ_ADDR, in_isr); } if ( xact_len < ep->packet_size || ep->xferred_len >= ep->total_len ) { @@ -905,18 +902,23 @@ void hcd_int_handler(uint8_t rhport) { } if ( hirq & HIRQ_HXFRDN_IRQ ) { - hirq_write(rhport, HIRQ_HXFRDN_IRQ, true); - handle_xfer_done(rhport); + hirq_write(rhport, HIRQ_HXFRDN_IRQ, in_isr); + handle_xfer_done(rhport, in_isr); } - hirq = reg_read(rhport, HIRQ_ADDR, true); + hirq = reg_read(rhport, HIRQ_ADDR, in_isr); } // clear all interrupt except SNDBAV_IRQ (never clear by us). Note RCVDAV_IRQ, HXFRDN_IRQ already clear while processing hirq &= ~HIRQ_SNDBAV_IRQ; if ( hirq ) { - hirq_write(rhport, hirq, true); + hirq_write(rhport, hirq, in_isr); } } +// Interrupt Handler +void hcd_int_handler(uint8_t rhport) { + hcd_int_handler_ext(rhport, true); +} + #endif -- cgit v1.3.1 From 3b0ffd0f488671f1bafa4bcd9e22dd51f8bb6dee Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 27 Sep 2023 15:51:03 +0700 Subject: change hcd_int_handler(rhport, in_isr) signature: add in_isr change tuh_int_handler() to take in_isr as optional parameter (default = true) --- examples/host/bare_api/only.txt | 1 + examples/host/cdc_msc_hid/only.txt | 1 + examples/host/hid_controller/only.txt | 1 + examples/host/msc_file_explorer/only.txt | 1 + hw/bsp/imxrt/family.c | 4 +- hw/bsp/kinetis_kl/family.c | 2 +- hw/bsp/kinetis_kl/family.cmake | 75 ++++++++++---------- .../lpc17/boards/lpcxpresso1769/lpcxpresso1769.c | 2 +- hw/bsp/lpc17/boards/mbed1768/mbed1768.c | 2 +- hw/bsp/lpc18/family.c | 55 ++++++--------- hw/bsp/lpc40/family.c | 2 +- hw/bsp/lpc43/family.c | 4 +- hw/bsp/msp432e4/family.c | 2 +- hw/bsp/ngx4330/ngx4330.c | 4 +- hw/bsp/nrf/family.c | 2 +- hw/bsp/ra/family.c | 6 +- hw/bsp/rx/boards/rx65n_target/rx65n_target.c | 2 +- hw/bsp/samd21/family.c | 2 +- hw/bsp/samd51/family.c | 2 +- hw/bsp/stm32g4/family.cmake | 81 +++++++++++----------- hw/bsp/tm4c123/family.c | 2 +- src/common/tusb_common.h | 2 - src/common/tusb_timeout.h | 80 --------------------- src/common/tusb_verify.h | 52 +++++--------- src/host/hcd.h | 2 +- src/host/usbh.h | 11 ++- src/portable/analog/max3421/hcd_max3421.c | 3 +- src/portable/ehci/ehci.c | 4 +- src/portable/mentor/musb/hcd_musb.c | 4 +- src/portable/nxp/khci/hcd_khci.c | 7 +- src/portable/ohci/ohci.c | 5 +- src/portable/raspberrypi/rp2040/hcd_rp2040.c | 4 +- src/portable/renesas/rusb2/hcd_rusb2.c | 5 +- src/portable/template/hcd_template.c | 3 +- src/tusb.h | 4 +- 35 files changed, 172 insertions(+), 267 deletions(-) delete mode 100644 src/common/tusb_timeout.h (limited to 'src/host') diff --git a/examples/host/bare_api/only.txt b/examples/host/bare_api/only.txt index 3837ac8a2..fee10f9e2 100644 --- a/examples/host/bare_api/only.txt +++ b/examples/host/bare_api/only.txt @@ -1,3 +1,4 @@ +mcu:KINETIS_KL mcu:LPC175X_6X mcu:LPC177X_8X mcu:LPC18XX diff --git a/examples/host/cdc_msc_hid/only.txt b/examples/host/cdc_msc_hid/only.txt index 3837ac8a2..fee10f9e2 100644 --- a/examples/host/cdc_msc_hid/only.txt +++ b/examples/host/cdc_msc_hid/only.txt @@ -1,3 +1,4 @@ +mcu:KINETIS_KL mcu:LPC175X_6X mcu:LPC177X_8X mcu:LPC18XX diff --git a/examples/host/hid_controller/only.txt b/examples/host/hid_controller/only.txt index 3837ac8a2..fee10f9e2 100644 --- a/examples/host/hid_controller/only.txt +++ b/examples/host/hid_controller/only.txt @@ -1,3 +1,4 @@ +mcu:KINETIS_KL mcu:LPC175X_6X mcu:LPC177X_8X mcu:LPC18XX diff --git a/examples/host/msc_file_explorer/only.txt b/examples/host/msc_file_explorer/only.txt index 3837ac8a2..fee10f9e2 100644 --- a/examples/host/msc_file_explorer/only.txt +++ b/examples/host/msc_file_explorer/only.txt @@ -1,3 +1,4 @@ +mcu:KINETIS_KL mcu:LPC175X_6X mcu:LPC177X_8X mcu:LPC18XX diff --git a/hw/bsp/imxrt/family.c b/hw/bsp/imxrt/family.c index ec95a8b24..32d89f794 100644 --- a/hw/bsp/imxrt/family.c +++ b/hw/bsp/imxrt/family.c @@ -188,7 +188,7 @@ void USB_OTG1_IRQHandler(void) #endif #if PORT_SUPPORT_HOST(0) - tuh_int_handler(0); + tuh_int_handler(0, true); #endif } @@ -199,7 +199,7 @@ void USB_OTG2_IRQHandler(void) #endif #if PORT_SUPPORT_HOST(1) - tuh_int_handler(1); + tuh_int_handler(1, true); #endif } diff --git a/hw/bsp/kinetis_kl/family.c b/hw/bsp/kinetis_kl/family.c index 3e9aa83a4..c436be3e6 100644 --- a/hw/bsp/kinetis_kl/family.c +++ b/hw/bsp/kinetis_kl/family.c @@ -39,7 +39,7 @@ void USB0_IRQHandler(void) { #if CFG_TUH_ENABLED - tuh_int_handler(0); + tuh_int_handler(0, true); #endif #if CFG_TUD_ENABLED tud_int_handler(0); diff --git a/hw/bsp/kinetis_kl/family.cmake b/hw/bsp/kinetis_kl/family.cmake index 793ef1783..4151979a0 100644 --- a/hw/bsp/kinetis_kl/family.cmake +++ b/hw/bsp/kinetis_kl/family.cmake @@ -22,48 +22,47 @@ set(FAMILY_MCUS KINETIS_KL CACHE INTERNAL "") #------------------------------------ # only need to be built ONCE for all examples function(add_board_target BOARD_TARGET) - if (NOT TARGET ${BOARD_TARGET}) - add_library(${BOARD_TARGET} STATIC - ${SDK_DIR}/drivers/gpio/fsl_gpio.c - ${SDK_DIR}/drivers/lpsci/fsl_lpsci.c - ${SDK_DIR}/drivers/uart/fsl_uart.c - ${SDK_DIR}/devices/${MCU_VARIANT}/drivers/fsl_clock.c - ${SDK_DIR}/devices/${MCU_VARIANT}/system_${MCU_VARIANT}.c - ) - target_compile_definitions(${BOARD_TARGET} PUBLIC - ) - target_include_directories(${BOARD_TARGET} PUBLIC - ${CMSIS_DIR}/CMSIS/Core/Include - ${SDK_DIR}/devices/${MCU_VARIANT} - ${SDK_DIR}/devices/${MCU_VARIANT}/drivers - ${SDK_DIR}/drivers/common - ${SDK_DIR}/drivers/gpio - ${SDK_DIR}/drivers/lpsci - ${SDK_DIR}/drivers/port - ${SDK_DIR}/drivers/smc - ${SDK_DIR}/drivers/uart - ) + if (TARGET ${BOARD_TARGET}) + return() + endif () - update_board(${BOARD_TARGET}) + add_library(${BOARD_TARGET} STATIC + ${SDK_DIR}/drivers/gpio/fsl_gpio.c + ${SDK_DIR}/drivers/lpsci/fsl_lpsci.c + ${SDK_DIR}/drivers/uart/fsl_uart.c + ${SDK_DIR}/devices/${MCU_VARIANT}/drivers/fsl_clock.c + ${SDK_DIR}/devices/${MCU_VARIANT}/system_${MCU_VARIANT}.c + ) + target_compile_definitions(${BOARD_TARGET} PUBLIC + ) + target_include_directories(${BOARD_TARGET} PUBLIC + ${CMSIS_DIR}/CMSIS/Core/Include + ${SDK_DIR}/devices/${MCU_VARIANT} + ${SDK_DIR}/devices/${MCU_VARIANT}/drivers + ${SDK_DIR}/drivers/common + ${SDK_DIR}/drivers/gpio + ${SDK_DIR}/drivers/lpsci + ${SDK_DIR}/drivers/port + ${SDK_DIR}/drivers/smc + ${SDK_DIR}/drivers/uart + ) + update_board(${BOARD_TARGET}) - # LD_FILE and STARTUP_FILE can be defined in board.cmake + # LD_FILE and STARTUP_FILE can be defined in board.cmake + target_sources(${BOARD_TARGET} PUBLIC + ${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} + ) - target_sources(${BOARD_TARGET} PUBLIC - ${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} + if (CMAKE_C_COMPILER_ID STREQUAL "GNU") + target_link_options(${BOARD_TARGET} PUBLIC + "LINKER:--script=${LD_FILE_GNU}" + # nanolib + --specs=nosys.specs --specs=nano.specs + ) + elseif (CMAKE_C_COMPILER_ID STREQUAL "IAR") + target_link_options(${BOARD_TARGET} PUBLIC + "LINKER:--config=${LD_FILE_IAR}" ) - - if (CMAKE_C_COMPILER_ID STREQUAL "GNU") - target_link_options(${BOARD_TARGET} PUBLIC - "LINKER:--script=${LD_FILE_GNU}" - # nanolib - --specs=nosys.specs - --specs=nano.specs - ) - elseif (CMAKE_C_COMPILER_ID STREQUAL "IAR") - target_link_options(${BOARD_TARGET} PUBLIC - "LINKER:--config=${LD_FILE_IAR}" - ) - endif () endif () endfunction() diff --git a/hw/bsp/lpc17/boards/lpcxpresso1769/lpcxpresso1769.c b/hw/bsp/lpc17/boards/lpcxpresso1769/lpcxpresso1769.c index c7d655368..8c26b906f 100644 --- a/hw/bsp/lpc17/boards/lpcxpresso1769/lpcxpresso1769.c +++ b/hw/bsp/lpc17/boards/lpcxpresso1769/lpcxpresso1769.c @@ -37,7 +37,7 @@ void USB_IRQHandler(void) #endif #if CFG_TUH_ENABLED - tuh_int_handler(0); + tuh_int_handler(0, true); #endif } diff --git a/hw/bsp/lpc17/boards/mbed1768/mbed1768.c b/hw/bsp/lpc17/boards/mbed1768/mbed1768.c index b2c92d640..613dcb570 100644 --- a/hw/bsp/lpc17/boards/mbed1768/mbed1768.c +++ b/hw/bsp/lpc17/boards/mbed1768/mbed1768.c @@ -151,7 +151,7 @@ void USB_IRQHandler(void) #endif #if CFG_TUH_ENABLED - tuh_int_handler(0); + tuh_int_handler(0, true); #endif } diff --git a/hw/bsp/lpc18/family.c b/hw/bsp/lpc18/family.c index b11f4fe0e..e6abecb4b 100644 --- a/hw/bsp/lpc18/family.c +++ b/hw/bsp/lpc18/family.c @@ -43,25 +43,23 @@ //--------------------------------------------------------------------+ // USB Interrupt Handler //--------------------------------------------------------------------+ -void USB0_IRQHandler(void) -{ +void USB0_IRQHandler(void) { #if PORT_SUPPORT_DEVICE(0) - tud_int_handler(0); + tud_int_handler(0); #endif #if PORT_SUPPORT_HOST(0) - tuh_int_handler(0); + tuh_int_handler(0, true); #endif } -void USB1_IRQHandler(void) -{ +void USB1_IRQHandler(void) { #if PORT_SUPPORT_DEVICE(1) - tud_int_handler(1); + tud_int_handler(1); #endif #if PORT_SUPPORT_HOST(1) - tuh_int_handler(1); + tuh_int_handler(1, true); #endif } @@ -74,28 +72,26 @@ const uint32_t OscRateIn = 12000000; const uint32_t ExtRateIn = 0; // Invoked by startup code -void SystemInit(void) -{ +void SystemInit(void) { #ifdef __USE_LPCOPEN - extern void (* const g_pfnVectors[])(void); + extern void (*const g_pfnVectors[])(void); unsigned int *pSCB_VTOR = (unsigned int *) 0xE000ED08; - *pSCB_VTOR = (unsigned int) g_pfnVectors; + *pSCB_VTOR = (unsigned int) g_pfnVectors; #endif board_lpc18_pinmux(); - #ifdef TRACE_ETM +#ifdef TRACE_ETM // Trace clock is limited to 60MHz, limit CPU clock to 120MHz Chip_SetupCoreClock(CLKIN_CRYSTAL, 120000000UL, true); - #else +#else // CPU clock max to 180 Mhz Chip_SetupCoreClock(CLKIN_CRYSTAL, MAX_CLOCK_FREQ, true); - #endif +#endif } -void board_init(void) -{ +void board_init(void) { SystemCoreClockUpdate(); #if CFG_TUSB_OS == OPT_OS_NONE @@ -135,27 +131,22 @@ void board_init(void) // Board porting API //--------------------------------------------------------------------+ -void board_led_write(bool state) -{ +void board_led_write(bool state) { Chip_GPIO_SetPinState(LPC_GPIO_PORT, LED_PORT, LED_PIN, state); } -uint32_t board_button_read(void) -{ +uint32_t board_button_read(void) { // active low return Chip_GPIO_GetPinState(LPC_GPIO_PORT, BUTTON_PORT, BUTTON_PIN) ? 0 : 1; } -int board_uart_read(uint8_t* buf, int len) -{ +int board_uart_read(uint8_t *buf, int len) { return Chip_UART_Read(UART_DEV, buf, len); } -int board_uart_write(void const * buf, int len) -{ - uint8_t const* buf8 = (uint8_t const*) buf; - for(int i=0; iINTFLAG.reg = EIC_INTFLAG_EXTINT(1 << MAX3421_INTR_EIC_ID); // Call the TinyUSB interrupt handler - tuh_int_handler(1); + tuh_int_handler(1, true); } void tuh_max3421_int_api(uint8_t rhport, bool enabled) { diff --git a/hw/bsp/samd51/family.c b/hw/bsp/samd51/family.c index 2cf00c7af..268d60e48 100644 --- a/hw/bsp/samd51/family.c +++ b/hw/bsp/samd51/family.c @@ -296,7 +296,7 @@ void MAX3421_EIC_Handler(void) { EIC->INTFLAG.reg = EIC_INTFLAG_EXTINT(1 << MAX3421_INTR_EIC_ID); // Call the TinyUSB interrupt handler - tuh_int_handler(1); + tuh_int_handler(1, true); } void tuh_max3421_int_api(uint8_t rhport, bool enabled) { diff --git a/hw/bsp/stm32g4/family.cmake b/hw/bsp/stm32g4/family.cmake index 675a96c74..f8cabcbe5 100644 --- a/hw/bsp/stm32g4/family.cmake +++ b/hw/bsp/stm32g4/family.cmake @@ -26,50 +26,47 @@ set(FAMILY_MCUS STM32G4 CACHE INTERNAL "") #------------------------------------ # only need to be built ONCE for all examples function(add_board_target BOARD_TARGET) - if (NOT TARGET ${BOARD_TARGET}) - # Startup & Linker script - set(STARTUP_FILE_GNU ${ST_CMSIS}/Source/Templates/gcc/startup_${MCU_VARIANT}.s) - set(STARTUP_FILE_IAR ${ST_CMSIS}/Source/Templates/iar/startup_${MCU_VARIANT}.s) - set(LD_FILE_IAR ${ST_CMSIS}/Source/Templates/iar/linker/${MCU_VARIANT}_flash.icf) - - add_library(${BOARD_TARGET} STATIC - ${ST_CMSIS}/Source/Templates/system_${ST_PREFIX}.c - ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal.c - ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_cortex.c - ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_pwr_ex.c - ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_rcc.c - ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_rcc_ex.c - ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_gpio.c - ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_uart.c - ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_uart_ex.c - ${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} - ) - target_include_directories(${BOARD_TARGET} PUBLIC - ${CMAKE_CURRENT_FUNCTION_LIST_DIR} - ${CMSIS_5}/CMSIS/Core/Include - ${ST_CMSIS}/Include - ${ST_HAL_DRIVER}/Inc - ) - target_compile_options(${BOARD_TARGET} PUBLIC + if (TARGET ${BOARD_TARGET}) + return() + endif () + + # Startup & Linker script + set(STARTUP_FILE_GNU ${ST_CMSIS}/Source/Templates/gcc/startup_${MCU_VARIANT}.s) + set(STARTUP_FILE_IAR ${ST_CMSIS}/Source/Templates/iar/startup_${MCU_VARIANT}.s) + set(LD_FILE_IAR ${ST_CMSIS}/Source/Templates/iar/linker/${MCU_VARIANT}_flash.icf) + + add_library(${BOARD_TARGET} STATIC + ${ST_CMSIS}/Source/Templates/system_${ST_PREFIX}.c + ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal.c + ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_cortex.c + ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_pwr_ex.c + ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_rcc.c + ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_rcc_ex.c + ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_gpio.c + ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_uart.c + ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_uart_ex.c + ${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} + ) + target_include_directories(${BOARD_TARGET} PUBLIC + ${CMAKE_CURRENT_FUNCTION_LIST_DIR} + ${CMSIS_5}/CMSIS/Core/Include + ${ST_CMSIS}/Include + ${ST_HAL_DRIVER}/Inc + ) + update_board(${BOARD_TARGET}) + + if (CMAKE_C_COMPILER_ID STREQUAL "GNU") + target_link_options(${BOARD_TARGET} PUBLIC + "LINKER:--script=${LD_FILE_GNU}" + -nostartfiles + # nanolib + --specs=nosys.specs + --specs=nano.specs ) - target_compile_definitions(${BOARD_TARGET} PUBLIC + elseif (CMAKE_C_COMPILER_ID STREQUAL "IAR") + target_link_options(${BOARD_TARGET} PUBLIC + "LINKER:--config=${LD_FILE_IAR}" ) - - update_board(${BOARD_TARGET}) - - if (CMAKE_C_COMPILER_ID STREQUAL "GNU") - target_link_options(${BOARD_TARGET} PUBLIC - "LINKER:--script=${LD_FILE_GNU}" - -nostartfiles - # nanolib - --specs=nosys.specs - --specs=nano.specs - ) - elseif (CMAKE_C_COMPILER_ID STREQUAL "IAR") - target_link_options(${BOARD_TARGET} PUBLIC - "LINKER:--config=${LD_FILE_IAR}" - ) - endif () endif () endfunction() diff --git a/hw/bsp/tm4c123/family.c b/hw/bsp/tm4c123/family.c index ad5ae505f..738bc3fa0 100644 --- a/hw/bsp/tm4c123/family.c +++ b/hw/bsp/tm4c123/family.c @@ -8,7 +8,7 @@ void USB0_Handler(void) { #if CFG_TUH_ENABLED - tuh_int_handler(0); + tuh_int_handler(0, true); #endif #if CFG_TUD_ENABLED diff --git a/src/common/tusb_common.h b/src/common/tusb_common.h index 6fffed11c..caeb5f2ef 100644 --- a/src/common/tusb_common.h +++ b/src/common/tusb_common.h @@ -75,8 +75,6 @@ #include "tusb_types.h" #include "tusb_debug.h" -#include "tusb_timeout.h" // TODO remove - //--------------------------------------------------------------------+ // Optional API implemented by application if needed // TODO move to a more ovious place/file diff --git a/src/common/tusb_timeout.h b/src/common/tusb_timeout.h deleted file mode 100644 index 533e67ab8..000000000 --- a/src/common/tusb_timeout.h +++ /dev/null @@ -1,80 +0,0 @@ -/* - * The MIT License (MIT) - * - * Copyright (c) 2019 Ha Thach (tinyusb.org) - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - * This file is part of the TinyUSB stack. - */ - -/** \ingroup Group_Common Common Files - * \defgroup Group_TimeoutTimer timeout timer - * @{ */ - -#ifndef _TUSB_TIMEOUT_H_ -#define _TUSB_TIMEOUT_H_ - -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -typedef struct { - uint32_t start; - uint32_t interval; -}tu_timeout_t; - -#if 0 - -extern uint32_t tusb_hal_millis(void); - -static inline void tu_timeout_set(tu_timeout_t* tt, uint32_t msec) -{ - tt->interval = msec; - tt->start = tusb_hal_millis(); -} - -static inline bool tu_timeout_expired(tu_timeout_t* tt) -{ - return ( tusb_hal_millis() - tt->start ) >= tt->interval; -} - -// For used with periodic event to prevent drift -static inline void tu_timeout_reset(tu_timeout_t* tt) -{ - tt->start += tt->interval; -} - -static inline void tu_timeout_restart(tu_timeout_t* tt) -{ - tt->start = tusb_hal_millis(); -} - -#endif - -#ifdef __cplusplus - } -#endif - -#endif /* _TUSB_TIMEOUT_H_ */ - -/** @} */ diff --git a/src/common/tusb_verify.h b/src/common/tusb_verify.h index 12355e8be..1b5f53dfc 100644 --- a/src/common/tusb_verify.h +++ b/src/common/tusb_verify.h @@ -56,12 +56,8 @@ * #define TU_VERIFY(cond) if(cond) return false; * #define TU_VERIFY(cond,ret) if(cond) return ret; * - * #define TU_VERIFY_HDLR(cond,handler) if(cond) {handler; return false;} - * #define TU_VERIFY_HDLR(cond,ret,handler) if(cond) {handler; return ret;} - * * #define TU_ASSERT(cond) if(cond) {_MESS_FAILED(); TU_BREAKPOINT(), return false;} * #define TU_ASSERT(cond,ret) if(cond) {_MESS_FAILED(); TU_BREAKPOINT(), return ret;} - * *------------------------------------------------------------------*/ #ifdef __cplusplus @@ -97,40 +93,23 @@ #define TU_BREAKPOINT() do {} while (0) #endif -/*------------------------------------------------------------------*/ -/* Macro Generator - *------------------------------------------------------------------*/ - // Helper to implement optional parameter for TU_VERIFY Macro family #define _GET_3RD_ARG(arg1, arg2, arg3, ...) arg3 -#define _GET_4TH_ARG(arg1, arg2, arg3, arg4, ...) arg4 - -/*------------- Generator for TU_VERIFY and TU_VERIFY_HDLR -------------*/ -#define TU_VERIFY_DEFINE(_cond, _handler, _ret) do \ -{ \ - if ( !(_cond) ) { _handler; return _ret; } \ -} while(0) /*------------------------------------------------------------------*/ /* TU_VERIFY * - TU_VERIFY_1ARGS : return false if failed * - TU_VERIFY_2ARGS : return provided value if failed *------------------------------------------------------------------*/ -#define TU_VERIFY_1ARGS(_cond) TU_VERIFY_DEFINE(_cond, , false) -#define TU_VERIFY_2ARGS(_cond, _ret) TU_VERIFY_DEFINE(_cond, , _ret) +#define TU_VERIFY_DEFINE(_cond, _ret) \ + do { \ + if ( !(_cond) ) { return _ret; } \ + } while(0) -#define TU_VERIFY(...) _GET_3RD_ARG(__VA_ARGS__, TU_VERIFY_2ARGS, TU_VERIFY_1ARGS, UNUSED)(__VA_ARGS__) +#define TU_VERIFY_1ARGS(_cond) TU_VERIFY_DEFINE(_cond, false) +#define TU_VERIFY_2ARGS(_cond, _ret) TU_VERIFY_DEFINE(_cond, _ret) - -/*------------------------------------------------------------------*/ -/* TU_VERIFY WITH HANDLER - * - TU_VERIFY_HDLR_2ARGS : execute handler, return false if failed - * - TU_VERIFY_HDLR_3ARGS : execute handler, return provided error if failed - *------------------------------------------------------------------*/ -#define TU_VERIFY_HDLR_2ARGS(_cond, _handler) TU_VERIFY_DEFINE(_cond, _handler, false) -#define TU_VERIFY_HDLR_3ARGS(_cond, _handler, _ret) TU_VERIFY_DEFINE(_cond, _handler, _ret) - -#define TU_VERIFY_HDLR(...) _GET_4TH_ARG(__VA_ARGS__, TU_VERIFY_HDLR_3ARGS, TU_VERIFY_HDLR_2ARGS,UNUSED)(__VA_ARGS__) +#define TU_VERIFY(...) _GET_3RD_ARG(__VA_ARGS__, TU_VERIFY_2ARGS, TU_VERIFY_1ARGS, _dummy)(__VA_ARGS__) /*------------------------------------------------------------------*/ /* ASSERT @@ -138,19 +117,20 @@ * - 1 arg : return false if failed * - 2 arg : return error if failed *------------------------------------------------------------------*/ -#define ASSERT_1ARGS(_cond) TU_VERIFY_DEFINE(_cond, _MESS_FAILED(); TU_BREAKPOINT(), false) -#define ASSERT_2ARGS(_cond, _ret) TU_VERIFY_DEFINE(_cond, _MESS_FAILED(); TU_BREAKPOINT(), _ret) +#define TU_ASSERT_DEFINE(_cond, _ret) \ + do { \ + if ( !(_cond) ) { _MESS_FAILED(); TU_BREAKPOINT(); return _ret; } \ + } while(0) + +#define TU_ASSERT_1ARGS(_cond) TU_ASSERT_DEFINE(_cond, false) +#define TU_ASSERT_2ARGS(_cond, _ret) TU_ASSERT_DEFINE(_cond, _ret) #ifndef TU_ASSERT -#define TU_ASSERT(...) _GET_3RD_ARG(__VA_ARGS__, ASSERT_2ARGS, ASSERT_1ARGS,UNUSED)(__VA_ARGS__) +#define TU_ASSERT(...) _GET_3RD_ARG(__VA_ARGS__, TU_ASSERT_2ARGS, TU_ASSERT_1ARGS, _dummy)(__VA_ARGS__) #endif -/*------------------------------------------------------------------*/ -/* ASSERT HDLR - *------------------------------------------------------------------*/ - #ifdef __cplusplus } #endif -#endif /* TUSB_VERIFY_H_ */ +#endif diff --git a/src/host/hcd.h b/src/host/hcd.h index e25b20ea3..2bde289df 100644 --- a/src/host/hcd.h +++ b/src/host/hcd.h @@ -131,7 +131,7 @@ bool hcd_configure(uint8_t rhport, uint32_t cfg_id, const void* cfg_param) TU_AT bool hcd_init(uint8_t rhport); // Interrupt Handler -void hcd_int_handler(uint8_t rhport); +void hcd_int_handler(uint8_t rhport, bool in_isr); // Enable USB interrupt void hcd_int_enable (uint8_t rhport); diff --git a/src/host/usbh.h b/src/host/usbh.h index 684e8240e..770d70dfe 100644 --- a/src/host/usbh.h +++ b/src/host/usbh.h @@ -124,11 +124,16 @@ void tuh_task(void) { bool tuh_task_event_ready(void); #ifndef _TUSB_HCD_H_ -extern void hcd_int_handler(uint8_t rhport); +extern void hcd_int_handler(uint8_t rhport, bool in_isr); #endif -// Interrupt handler, name alias to HCD -#define tuh_int_handler hcd_int_handler +// Interrupt handler alias to HCD with in_isr as optional parameter +// - tuh_int_handler(rhport) --> hcd_int_handler(rhport, true) +// - tuh_int_handler(rhport, in_isr) --> hcd_int_handler(rhport, in_isr) +// Note: this is similar to TU_VERIFY(), _GET_3RD_ARG() is defined in tusb_verify.h +#define _tuh_int_handler_1arg(_rhport) hcd_int_handler(_rhport, true) +#define _tuh_int_hanlder_2arg(_rhport, _in_isr) hcd_int_handler(_rhport, _in_isr) +#define tuh_int_handler(...) _GET_3RD_ARG(__VA_ARGS__, _tuh_int_hanlder_2arg, _tuh_int_handler_1arg, _dummy)(__VA_ARGS__) // Check if roothub port is initialized and active as a host bool tuh_rhport_is_active(uint8_t rhport); diff --git a/src/portable/analog/max3421/hcd_max3421.c b/src/portable/analog/max3421/hcd_max3421.c index 238b518a0..d013d6179 100644 --- a/src/portable/analog/max3421/hcd_max3421.c +++ b/src/portable/analog/max3421/hcd_max3421.c @@ -863,7 +863,8 @@ void print_hirq(uint8_t hirq) { #endif // Interrupt Handler -void hcd_int_handler(uint8_t rhport) { +void hcd_int_handler(uint8_t rhport, bool in_isr) { + (void) in_isr; uint8_t hirq = reg_read(rhport, HIRQ_ADDR, true) & _hcd_data.hien; if (!hirq) return; // print_hirq(hirq); diff --git a/src/portable/ehci/ehci.c b/src/portable/ehci/ehci.c index c93c33fc0..572b9826c 100644 --- a/src/portable/ehci/ehci.c +++ b/src/portable/ehci/ehci.c @@ -656,8 +656,8 @@ void process_period_xfer_isr(uint8_t rhport, uint32_t interval_ms) } //------------- Host Controller Driver's Interrupt Handler -------------// -void hcd_int_handler(uint8_t rhport) -{ +void hcd_int_handler(uint8_t rhport, bool in_isr) { + (void) in_isr; ehci_registers_t* regs = ehci_data.regs; uint32_t const int_status = regs->status; diff --git a/src/portable/mentor/musb/hcd_musb.c b/src/portable/mentor/musb/hcd_musb.c index 02090df85..5312c2812 100644 --- a/src/portable/mentor/musb/hcd_musb.c +++ b/src/portable/mentor/musb/hcd_musb.c @@ -847,8 +847,10 @@ bool hcd_edpt_clear_stall(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr) { /*------------------------------------------------------------------- * ISR *-------------------------------------------------------------------*/ -void hcd_int_handler(uint8_t rhport) +void hcd_int_handler(uint8_t rhport, bool in_isr) { + (void) in_isr; + uint_fast8_t is, txis, rxis; is = USB0->IS; /* read and clear interrupt status */ diff --git a/src/portable/nxp/khci/hcd_khci.c b/src/portable/nxp/khci/hcd_khci.c index 55327e02d..57684b259 100644 --- a/src/portable/nxp/khci/hcd_khci.c +++ b/src/portable/nxp/khci/hcd_khci.c @@ -447,6 +447,10 @@ void hcd_port_reset(uint8_t rhport) _hcd.need_reset = false; } +void hcd_port_reset_end(uint8_t rhport) { + (void) rhport; +} + tusb_speed_t hcd_port_speed_get(uint8_t rhport) { (void)rhport; @@ -583,8 +587,9 @@ bool hcd_edpt_clear_stall(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr) { /*--------------------------------------------------------------------+ * ISR *--------------------------------------------------------------------+*/ -void hcd_int_handler(uint8_t rhport) +void hcd_int_handler(uint8_t rhport, bool in_isr) { + (void) in_isr; uint32_t is = KHCI->ISTAT; uint32_t msk = KHCI->INTEN; diff --git a/src/portable/ohci/ohci.c b/src/portable/ohci/ohci.c index 413e72037..f978b0965 100644 --- a/src/portable/ohci/ohci.c +++ b/src/portable/ohci/ohci.c @@ -667,8 +667,9 @@ static void done_queue_isr(uint8_t hostid) } } -void hcd_int_handler(uint8_t hostid) -{ +void hcd_int_handler(uint8_t hostid, bool in_isr) { + (void) in_isr; + uint32_t const int_en = OHCI_REG->interrupt_enable; uint32_t const int_status = OHCI_REG->interrupt_status & int_en; diff --git a/src/portable/raspberrypi/rp2040/hcd_rp2040.c b/src/portable/raspberrypi/rp2040/hcd_rp2040.c index 21dc3f67d..4ed6d36bb 100644 --- a/src/portable/raspberrypi/rp2040/hcd_rp2040.c +++ b/src/portable/raspberrypi/rp2040/hcd_rp2040.c @@ -252,9 +252,9 @@ static void __tusb_irq_path_func(hcd_rp2040_irq)(void) } } -void __tusb_irq_path_func(hcd_int_handler)(uint8_t rhport) -{ +void __tusb_irq_path_func(hcd_int_handler)(uint8_t rhport, bool in_isr) { (void) rhport; + (void) in_isr; hcd_rp2040_irq(); } diff --git a/src/portable/renesas/rusb2/hcd_rusb2.c b/src/portable/renesas/rusb2/hcd_rusb2.c index 790cd6b32..bf95be707 100644 --- a/src/portable/renesas/rusb2/hcd_rusb2.c +++ b/src/portable/renesas/rusb2/hcd_rusb2.c @@ -771,8 +771,9 @@ bool hcd_edpt_clear_stall(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr) { //--------------------------------------------------------------------+ // ISR //--------------------------------------------------------------------+ -void hcd_int_handler(uint8_t rhport) -{ +void hcd_int_handler(uint8_t rhport, bool in_isr) { + (void) in_isr; + rusb2_reg_t* rusb = RUSB2_REG(rhport); unsigned is0 = rusb->INTSTS0; unsigned is1 = rusb->INTSTS1; diff --git a/src/portable/template/hcd_template.c b/src/portable/template/hcd_template.c index 3e3b91558..b073d6057 100644 --- a/src/portable/template/hcd_template.c +++ b/src/portable/template/hcd_template.c @@ -51,8 +51,9 @@ bool hcd_init(uint8_t rhport) { } // Interrupt Handler -void hcd_int_handler(uint8_t rhport) { +void hcd_int_handler(uint8_t rhport, bool in_isr) { (void) rhport; + (void) in_isr; } // Enable USB interrupt diff --git a/src/tusb.h b/src/tusb.h index d6534ca28..c9d56d3c3 100644 --- a/src/tusb.h +++ b/src/tusb.h @@ -66,7 +66,7 @@ #endif #else #ifndef tuh_int_handler - #define tuh_int_handler(_x) + #define tuh_int_handler(...) #endif #endif @@ -123,7 +123,7 @@ #endif #else #ifndef tud_int_handler - #define tud_int_handler(_x) + #define tud_int_handler(...) #endif #endif -- cgit v1.3.1 From 277852afc1798f2acdb61917984e76b4bafa699e Mon Sep 17 00:00:00 2001 From: hathach Date: Thu, 28 Sep 2023 10:56:38 +0700 Subject: fix esp32 msc example --- examples/host/cdc_msc_hid_freertos/src/cdc_app.c | 8 +- examples/host/cdc_msc_hid_freertos/src/hid_app.c | 4 + examples/host/cdc_msc_hid_freertos/src/main.c | 12 +- examples/host/cdc_msc_hid_freertos/src/msc_app.c | 8 +- src/class/msc/msc_host.c | 265 ++++++++++------------- src/class/msc/msc_host.h | 8 +- src/host/usbh.c | 22 +- 7 files changed, 151 insertions(+), 176 deletions(-) (limited to 'src/host') diff --git a/examples/host/cdc_msc_hid_freertos/src/cdc_app.c b/examples/host/cdc_msc_hid_freertos/src/cdc_app.c index 943e534d8..91dcc2e1a 100644 --- a/examples/host/cdc_msc_hid_freertos/src/cdc_app.c +++ b/examples/host/cdc_msc_hid_freertos/src/cdc_app.c @@ -31,9 +31,7 @@ // MACRO TYPEDEF CONSTANT ENUM DECLARATION //--------------------------------------------------------------------+ - -//------------- IMPLEMENTATION -------------// - +// helper size_t get_console_inputs(uint8_t *buf, size_t bufsize) { size_t count = 0; while (count < bufsize) { @@ -47,6 +45,10 @@ size_t get_console_inputs(uint8_t *buf, size_t bufsize) { return count; } +void cdc_app_init(void) { + // nothing to do +} + void cdc_app_task(void* param) { (void) param; diff --git a/examples/host/cdc_msc_hid_freertos/src/hid_app.c b/examples/host/cdc_msc_hid_freertos/src/hid_app.c index a2df3b909..9ea5c1be0 100644 --- a/examples/host/cdc_msc_hid_freertos/src/hid_app.c +++ b/examples/host/cdc_msc_hid_freertos/src/hid_app.c @@ -48,6 +48,10 @@ static void process_kbd_report(hid_keyboard_report_t const *report); static void process_mouse_report(hid_mouse_report_t const *report); static void process_generic_report(uint8_t dev_addr, uint8_t instance, uint8_t const *report, uint16_t len); +void hid_app_init(void) { + // nothing to do +} + //--------------------------------------------------------------------+ // TinyUSB Callbacks //--------------------------------------------------------------------+ diff --git a/examples/host/cdc_msc_hid_freertos/src/main.c b/examples/host/cdc_msc_hid_freertos/src/main.c index 88e742ee2..b60be015b 100644 --- a/examples/host/cdc_msc_hid_freertos/src/main.c +++ b/examples/host/cdc_msc_hid_freertos/src/main.c @@ -82,10 +82,15 @@ StaticTask_t cdc_taskdef; TimerHandle_t blinky_tm; static void led_blinky_cb(TimerHandle_t xTimer); -static void usb_host_task(void* param); +extern void cdc_app_init(void); +extern void hid_app_init(void); +extern void msc_app_init(void); +static void usb_host_task(void* param); extern void cdc_app_task(void* param); + + /*------------- MAIN -------------*/ int main(void) { board_init(); @@ -131,6 +136,10 @@ static void usb_host_task(void *param) { board_init_after_tusb(); } + cdc_app_init(); + hid_app_init(); + msc_app_init(); + // RTOS forever loop while (1) { // put this thread to waiting state until there is new events @@ -154,7 +163,6 @@ void tuh_umount_cb(uint8_t dev_addr) { printf("A device with address %d is unmounted \r\n", dev_addr); } - //--------------------------------------------------------------------+ // BLINKING TASK //--------------------------------------------------------------------+ diff --git a/examples/host/cdc_msc_hid_freertos/src/msc_app.c b/examples/host/cdc_msc_hid_freertos/src/msc_app.c index a8d6fbfaa..ee02ba917 100644 --- a/examples/host/cdc_msc_hid_freertos/src/msc_app.c +++ b/examples/host/cdc_msc_hid_freertos/src/msc_app.c @@ -25,10 +25,12 @@ #include "tusb.h" -#if CFG_TUH_MSC - static scsi_inquiry_resp_t inquiry_resp; +void msc_app_init(void) { + // nothing to do +} + bool inquiry_complete_cb(uint8_t dev_addr, tuh_msc_complete_data_t const *cb_data) { msc_cbw_t const *cbw = cb_data->cbw; msc_csw_t const *csw = cb_data->csw; @@ -63,5 +65,3 @@ void tuh_msc_umount_cb(uint8_t dev_addr) { (void) dev_addr; printf("A MassStorage device is unmounted\r\n"); } - -#endif diff --git a/src/class/msc/msc_host.c b/src/class/msc/msc_host.c index da264142c..39f2d9f1c 100644 --- a/src/class/msc/msc_host.c +++ b/src/class/msc/msc_host.c @@ -43,16 +43,14 @@ //--------------------------------------------------------------------+ // MACRO CONSTANT TYPEDEF //--------------------------------------------------------------------+ -enum -{ +enum { MSC_STAGE_IDLE = 0, MSC_STAGE_CMD, MSC_STAGE_DATA, MSC_STAGE_STATUS, }; -typedef struct -{ +typedef struct { uint8_t itf_num; uint8_t ep_in; uint8_t ep_out; @@ -69,13 +67,13 @@ typedef struct //------------- SCSI -------------// uint8_t stage; - void* buffer; + void* buffer; tuh_msc_complete_cb_t complete_cb; uintptr_t complete_arg; CFG_TUH_MEM_ALIGN msc_cbw_t cbw; CFG_TUH_MEM_ALIGN msc_csw_t csw; -}msch_interface_t; +} msch_interface_t; CFG_TUH_MEM_SECTION static msch_interface_t _msch_itf[CFG_TUH_DEVICE_MAX]; @@ -86,40 +84,34 @@ static uint8_t _msch_buffer[sizeof(scsi_inquiry_resp_t)]; // FIXME potential nul reference TU_ATTR_ALWAYS_INLINE -static inline msch_interface_t* get_itf(uint8_t dev_addr) -{ - return &_msch_itf[dev_addr-1]; +static inline msch_interface_t* get_itf(uint8_t dev_addr) { + return &_msch_itf[dev_addr - 1]; } //--------------------------------------------------------------------+ // PUBLIC API //--------------------------------------------------------------------+ -uint8_t tuh_msc_get_maxlun(uint8_t dev_addr) -{ +uint8_t tuh_msc_get_maxlun(uint8_t dev_addr) { msch_interface_t* p_msc = get_itf(dev_addr); return p_msc->max_lun; } -uint32_t tuh_msc_get_block_count(uint8_t dev_addr, uint8_t lun) -{ +uint32_t tuh_msc_get_block_count(uint8_t dev_addr, uint8_t lun) { msch_interface_t* p_msc = get_itf(dev_addr); return p_msc->capacity[lun].block_count; } -uint32_t tuh_msc_get_block_size(uint8_t dev_addr, uint8_t lun) -{ +uint32_t tuh_msc_get_block_size(uint8_t dev_addr, uint8_t lun) { msch_interface_t* p_msc = get_itf(dev_addr); return p_msc->capacity[lun].block_size; } -bool tuh_msc_mounted(uint8_t dev_addr) -{ +bool tuh_msc_mounted(uint8_t dev_addr) { msch_interface_t* p_msc = get_itf(dev_addr); return p_msc->mounted; } -bool tuh_msc_ready(uint8_t dev_addr) -{ +bool tuh_msc_ready(uint8_t dev_addr) { msch_interface_t* p_msc = get_itf(dev_addr); return p_msc->mounted && !usbh_edpt_busy(dev_addr, p_msc->ep_in) && !usbh_edpt_busy(dev_addr, p_msc->ep_out); } @@ -127,20 +119,20 @@ bool tuh_msc_ready(uint8_t dev_addr) //--------------------------------------------------------------------+ // PUBLIC API: SCSI COMMAND //--------------------------------------------------------------------+ -static inline void cbw_init(msc_cbw_t *cbw, uint8_t lun) -{ +static inline void cbw_init(msc_cbw_t* cbw, uint8_t lun) { tu_memclr(cbw, sizeof(msc_cbw_t)); cbw->signature = MSC_CBW_SIGNATURE; cbw->tag = 0x54555342; // TUSB cbw->lun = lun; } -bool tuh_msc_scsi_command(uint8_t dev_addr, msc_cbw_t const* cbw, void* data, tuh_msc_complete_cb_t complete_cb, uintptr_t arg) -{ - msch_interface_t* p_msc = get_itf(dev_addr); +bool tuh_msc_scsi_command(uint8_t daddr, msc_cbw_t const* cbw, void* data, + tuh_msc_complete_cb_t complete_cb, uintptr_t arg) { + msch_interface_t* p_msc = get_itf(daddr); TU_VERIFY(p_msc->configured); - // TODO claim endpoint + // claim endpoint + TU_VERIFY(usbh_edpt_claim(daddr, p_msc->ep_out)); p_msc->cbw = *cbw; p_msc->stage = MSC_STAGE_CMD; @@ -148,15 +140,18 @@ bool tuh_msc_scsi_command(uint8_t dev_addr, msc_cbw_t const* cbw, void* data, tu p_msc->complete_cb = complete_cb; p_msc->complete_arg = arg; - TU_ASSERT(usbh_edpt_xfer(dev_addr, p_msc->ep_out, (uint8_t*) &p_msc->cbw, sizeof(msc_cbw_t))); + if (!usbh_edpt_xfer(daddr, p_msc->ep_out, (uint8_t*) &p_msc->cbw, sizeof(msc_cbw_t))) { + usbh_edpt_release(daddr, p_msc->ep_out); + return false; + } return true; } -bool tuh_msc_read_capacity(uint8_t dev_addr, uint8_t lun, scsi_read_capacity10_resp_t* response, tuh_msc_complete_cb_t complete_cb, uintptr_t arg) -{ - msch_interface_t* p_msc = get_itf(dev_addr); - TU_VERIFY(p_msc->configured); +bool tuh_msc_read_capacity(uint8_t dev_addr, uint8_t lun, scsi_read_capacity10_resp_t* response, + tuh_msc_complete_cb_t complete_cb, uintptr_t arg) { + msch_interface_t* p_msc = get_itf(dev_addr); + TU_VERIFY(p_msc->configured); msc_cbw_t cbw; cbw_init(&cbw, lun); @@ -169,8 +164,8 @@ bool tuh_msc_read_capacity(uint8_t dev_addr, uint8_t lun, scsi_read_capacity10_r return tuh_msc_scsi_command(dev_addr, &cbw, response, complete_cb, arg); } -bool tuh_msc_inquiry(uint8_t dev_addr, uint8_t lun, scsi_inquiry_resp_t* response, tuh_msc_complete_cb_t complete_cb, uintptr_t arg) -{ +bool tuh_msc_inquiry(uint8_t dev_addr, uint8_t lun, scsi_inquiry_resp_t* response, + tuh_msc_complete_cb_t complete_cb, uintptr_t arg) { msch_interface_t* p_msc = get_itf(dev_addr); TU_VERIFY(p_msc->mounted); @@ -181,18 +176,16 @@ bool tuh_msc_inquiry(uint8_t dev_addr, uint8_t lun, scsi_inquiry_resp_t* respons cbw.dir = TUSB_DIR_IN_MASK; cbw.cmd_len = sizeof(scsi_inquiry_t); - scsi_inquiry_t const cmd_inquiry = - { - .cmd_code = SCSI_CMD_INQUIRY, - .alloc_length = sizeof(scsi_inquiry_resp_t) + scsi_inquiry_t const cmd_inquiry = { + .cmd_code = SCSI_CMD_INQUIRY, + .alloc_length = sizeof(scsi_inquiry_resp_t) }; memcpy(cbw.command, &cmd_inquiry, cbw.cmd_len); return tuh_msc_scsi_command(dev_addr, &cbw, response, complete_cb, arg); } -bool tuh_msc_test_unit_ready(uint8_t dev_addr, uint8_t lun, tuh_msc_complete_cb_t complete_cb, uintptr_t arg) -{ +bool tuh_msc_test_unit_ready(uint8_t dev_addr, uint8_t lun, tuh_msc_complete_cb_t complete_cb, uintptr_t arg) { msch_interface_t* p_msc = get_itf(dev_addr); TU_VERIFY(p_msc->configured); @@ -200,16 +193,16 @@ bool tuh_msc_test_unit_ready(uint8_t dev_addr, uint8_t lun, tuh_msc_complete_cb_ cbw_init(&cbw, lun); cbw.total_bytes = 0; - cbw.dir = TUSB_DIR_OUT; - cbw.cmd_len = sizeof(scsi_test_unit_ready_t); - cbw.command[0] = SCSI_CMD_TEST_UNIT_READY; - cbw.command[1] = lun; // according to wiki TODO need verification + cbw.dir = TUSB_DIR_OUT; + cbw.cmd_len = sizeof(scsi_test_unit_ready_t); + cbw.command[0] = SCSI_CMD_TEST_UNIT_READY; + cbw.command[1] = lun; // according to wiki TODO need verification return tuh_msc_scsi_command(dev_addr, &cbw, NULL, complete_cb, arg); } -bool tuh_msc_request_sense(uint8_t dev_addr, uint8_t lun, void *response, tuh_msc_complete_cb_t complete_cb, uintptr_t arg) -{ +bool tuh_msc_request_sense(uint8_t dev_addr, uint8_t lun, void* response, + tuh_msc_complete_cb_t complete_cb, uintptr_t arg) { msc_cbw_t cbw; cbw_init(&cbw, lun); @@ -217,73 +210,64 @@ bool tuh_msc_request_sense(uint8_t dev_addr, uint8_t lun, void *response, tuh_ms cbw.dir = TUSB_DIR_IN_MASK; cbw.cmd_len = sizeof(scsi_request_sense_t); - scsi_request_sense_t const cmd_request_sense = - { - .cmd_code = SCSI_CMD_REQUEST_SENSE, - .alloc_length = 18 + scsi_request_sense_t const cmd_request_sense = { + .cmd_code = SCSI_CMD_REQUEST_SENSE, + .alloc_length = 18 }; - memcpy(cbw.command, &cmd_request_sense, cbw.cmd_len); return tuh_msc_scsi_command(dev_addr, &cbw, response, complete_cb, arg); } -bool tuh_msc_read10(uint8_t dev_addr, uint8_t lun, void * buffer, uint32_t lba, uint16_t block_count, tuh_msc_complete_cb_t complete_cb, uintptr_t arg) -{ +bool tuh_msc_read10(uint8_t dev_addr, uint8_t lun, void* buffer, uint32_t lba, uint16_t block_count, + tuh_msc_complete_cb_t complete_cb, uintptr_t arg) { msch_interface_t* p_msc = get_itf(dev_addr); TU_VERIFY(p_msc->mounted); msc_cbw_t cbw; cbw_init(&cbw, lun); - cbw.total_bytes = block_count*p_msc->capacity[lun].block_size; - cbw.dir = TUSB_DIR_IN_MASK; - cbw.cmd_len = sizeof(scsi_read10_t); + cbw.total_bytes = block_count * p_msc->capacity[lun].block_size; + cbw.dir = TUSB_DIR_IN_MASK; + cbw.cmd_len = sizeof(scsi_read10_t); - scsi_read10_t const cmd_read10 = - { - .cmd_code = SCSI_CMD_READ_10, - .lba = tu_htonl(lba), - .block_count = tu_htons(block_count) + scsi_read10_t const cmd_read10 = { + .cmd_code = SCSI_CMD_READ_10, + .lba = tu_htonl(lba), + .block_count = tu_htons(block_count) }; - memcpy(cbw.command, &cmd_read10, cbw.cmd_len); return tuh_msc_scsi_command(dev_addr, &cbw, buffer, complete_cb, arg); } -bool tuh_msc_write10(uint8_t dev_addr, uint8_t lun, void const * buffer, uint32_t lba, uint16_t block_count, tuh_msc_complete_cb_t complete_cb, uintptr_t arg) -{ +bool tuh_msc_write10(uint8_t dev_addr, uint8_t lun, void const* buffer, uint32_t lba, uint16_t block_count, + tuh_msc_complete_cb_t complete_cb, uintptr_t arg) { msch_interface_t* p_msc = get_itf(dev_addr); TU_VERIFY(p_msc->mounted); msc_cbw_t cbw; cbw_init(&cbw, lun); - cbw.total_bytes = block_count*p_msc->capacity[lun].block_size; + cbw.total_bytes = block_count * p_msc->capacity[lun].block_size; cbw.dir = TUSB_DIR_OUT; cbw.cmd_len = sizeof(scsi_write10_t); - scsi_write10_t const cmd_write10 = - { - .cmd_code = SCSI_CMD_WRITE_10, - .lba = tu_htonl(lba), - .block_count = tu_htons(block_count) + scsi_write10_t const cmd_write10 = { + .cmd_code = SCSI_CMD_WRITE_10, + .lba = tu_htonl(lba), + .block_count = tu_htons(block_count) }; - memcpy(cbw.command, &cmd_write10, cbw.cmd_len); - return tuh_msc_scsi_command(dev_addr, &cbw, (void*)(uintptr_t) buffer, complete_cb, arg); + return tuh_msc_scsi_command(dev_addr, &cbw, (void*) (uintptr_t) buffer, complete_cb, arg); } #if 0 // MSC interface Reset (not used now) -bool tuh_msc_reset(uint8_t dev_addr) -{ - tusb_control_request_t const new_request = - { - .bmRequestType_bit = - { +bool tuh_msc_reset(uint8_t dev_addr) { + tusb_control_request_t const new_request = { + .bmRequestType_bit = { .recipient = TUSB_REQ_RCPT_INTERFACE, .type = TUSB_REQ_TYPE_CLASS, .direction = TUSB_DIR_OUT @@ -300,79 +284,71 @@ bool tuh_msc_reset(uint8_t dev_addr) //--------------------------------------------------------------------+ // CLASS-USBH API //--------------------------------------------------------------------+ -void msch_init(void) -{ +void msch_init(void) { tu_memclr(_msch_itf, sizeof(_msch_itf)); } -void msch_close(uint8_t dev_addr) -{ - TU_VERIFY(dev_addr <= CFG_TUH_DEVICE_MAX, ); +void msch_close(uint8_t dev_addr) { + TU_VERIFY(dev_addr <= CFG_TUH_DEVICE_MAX,); msch_interface_t* p_msc = get_itf(dev_addr); - TU_VERIFY(p_msc->configured, ); + TU_VERIFY(p_msc->configured,); TU_LOG_DRV(" MSCh close addr = %d\r\n", dev_addr); // invoke Application Callback if (p_msc->mounted) { - if(tuh_msc_umount_cb) tuh_msc_umount_cb(dev_addr); + if (tuh_msc_umount_cb) tuh_msc_umount_cb(dev_addr); } tu_memclr(p_msc, sizeof(msch_interface_t)); } -bool msch_xfer_cb(uint8_t dev_addr, uint8_t ep_addr, xfer_result_t event, uint32_t xferred_bytes) -{ +bool msch_xfer_cb(uint8_t dev_addr, uint8_t ep_addr, xfer_result_t event, uint32_t xferred_bytes) { msch_interface_t* p_msc = get_itf(dev_addr); msc_cbw_t const * cbw = &p_msc->cbw; msc_csw_t * csw = &p_msc->csw; - switch (p_msc->stage) - { + switch (p_msc->stage) { case MSC_STAGE_CMD: // Must be Command Block - TU_ASSERT(ep_addr == p_msc->ep_out && event == XFER_RESULT_SUCCESS && xferred_bytes == sizeof(msc_cbw_t)); + TU_ASSERT(ep_addr == p_msc->ep_out && event == XFER_RESULT_SUCCESS && xferred_bytes == sizeof(msc_cbw_t)); - if ( cbw->total_bytes && p_msc->buffer ) - { + if (cbw->total_bytes && p_msc->buffer) { // Data stage if any p_msc->stage = MSC_STAGE_DATA; - uint8_t const ep_data = (cbw->dir & TUSB_DIR_IN_MASK) ? p_msc->ep_in : p_msc->ep_out; TU_ASSERT(usbh_edpt_xfer(dev_addr, ep_data, p_msc->buffer, (uint16_t) cbw->total_bytes)); - }else - { + } else { // Status stage p_msc->stage = MSC_STAGE_STATUS; TU_ASSERT(usbh_edpt_xfer(dev_addr, p_msc->ep_in, (uint8_t*) &p_msc->csw, (uint16_t) sizeof(msc_csw_t))); } - break; + break; case MSC_STAGE_DATA: // Status stage p_msc->stage = MSC_STAGE_STATUS; TU_ASSERT(usbh_edpt_xfer(dev_addr, p_msc->ep_in, (uint8_t*) &p_msc->csw, (uint16_t) sizeof(msc_csw_t))); - break; + break; case MSC_STAGE_STATUS: // SCSI op is complete p_msc->stage = MSC_STAGE_IDLE; - if (p_msc->complete_cb) - { - tuh_msc_complete_data_t const cb_data = - { - .cbw = cbw, - .csw = csw, - .scsi_data = p_msc->buffer, - .user_arg = p_msc->complete_arg + if (p_msc->complete_cb) { + tuh_msc_complete_data_t const cb_data = { + .cbw = cbw, + .csw = csw, + .scsi_data = p_msc->buffer, + .user_arg = p_msc->complete_arg }; p_msc->complete_cb(dev_addr, &cb_data); } - break; + break; - // unknown state - default: break; + // unknown state + default: + break; } return true; @@ -381,39 +357,35 @@ bool msch_xfer_cb(uint8_t dev_addr, uint8_t ep_addr, xfer_result_t event, uint32 //--------------------------------------------------------------------+ // MSC Enumeration //--------------------------------------------------------------------+ - -static void config_get_maxlun_complete (tuh_xfer_t* xfer); -static bool config_test_unit_ready_complete(uint8_t dev_addr, tuh_msc_complete_data_t const * cb_data); +static void config_get_maxlun_complete(tuh_xfer_t* xfer); +static bool config_test_unit_ready_complete(uint8_t dev_addr, tuh_msc_complete_data_t const* cb_data); static bool config_request_sense_complete(uint8_t dev_addr, tuh_msc_complete_data_t const* cb_data); static bool config_read_capacity_complete(uint8_t dev_addr, tuh_msc_complete_data_t const* cb_data); -bool msch_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const *desc_itf, uint16_t max_len) -{ +bool msch_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const* desc_itf, uint16_t max_len) { (void) rhport; TU_VERIFY (MSC_SUBCLASS_SCSI == desc_itf->bInterfaceSubClass && - MSC_PROTOCOL_BOT == desc_itf->bInterfaceProtocol); + MSC_PROTOCOL_BOT == desc_itf->bInterfaceProtocol); // msc driver length is fixed - uint16_t const drv_len = (uint16_t) (sizeof(tusb_desc_interface_t) + desc_itf->bNumEndpoints * sizeof(tusb_desc_endpoint_t)); + uint16_t const drv_len = (uint16_t) (sizeof(tusb_desc_interface_t) + + desc_itf->bNumEndpoints * sizeof(tusb_desc_endpoint_t)); TU_ASSERT(drv_len <= max_len); msch_interface_t* p_msc = get_itf(dev_addr); - tusb_desc_endpoint_t const * ep_desc = (tusb_desc_endpoint_t const *) tu_desc_next(desc_itf); + tusb_desc_endpoint_t const* ep_desc = (tusb_desc_endpoint_t const*) tu_desc_next(desc_itf); - for(uint32_t i=0; i<2; i++) - { + for (uint32_t i = 0; i < 2; i++) { TU_ASSERT(TUSB_DESC_ENDPOINT == ep_desc->bDescriptorType && TUSB_XFER_BULK == ep_desc->bmAttributes.xfer); TU_ASSERT(tuh_edpt_open(dev_addr, ep_desc)); - if ( tu_edpt_dir(ep_desc->bEndpointAddress) == TUSB_DIR_IN ) - { + if (TUSB_DIR_IN == tu_edpt_dir(ep_desc->bEndpointAddress)) { p_msc->ep_in = ep_desc->bEndpointAddress; - }else - { + } else { p_msc->ep_out = ep_desc->bEndpointAddress; } - ep_desc = (tusb_desc_endpoint_t const *) tu_desc_next(ep_desc); + ep_desc = (tusb_desc_endpoint_t const*) tu_desc_next(ep_desc); } p_msc->itf_num = desc_itf->bInterfaceNumber; @@ -430,32 +402,31 @@ bool msch_set_config(uint8_t dev_addr, uint8_t itf_num) { //------------- Get Max Lun -------------// TU_LOG_DRV("MSC Get Max Lun\r\n"); tusb_control_request_t const request = { - .bmRequestType_bit = { - .recipient = TUSB_REQ_RCPT_INTERFACE, - .type = TUSB_REQ_TYPE_CLASS, - .direction = TUSB_DIR_IN - }, - .bRequest = MSC_REQ_GET_MAX_LUN, - .wValue = 0, - .wIndex = itf_num, - .wLength = 1 + .bmRequestType_bit = { + .recipient = TUSB_REQ_RCPT_INTERFACE, + .type = TUSB_REQ_TYPE_CLASS, + .direction = TUSB_DIR_IN + }, + .bRequest = MSC_REQ_GET_MAX_LUN, + .wValue = 0, + .wIndex = itf_num, + .wLength = 1 }; tuh_xfer_t xfer = { - .daddr = dev_addr, - .ep_addr = 0, - .setup = &request, - .buffer = _msch_buffer, - .complete_cb = config_get_maxlun_complete, - .user_data = 0 + .daddr = dev_addr, + .ep_addr = 0, + .setup = &request, + .buffer = _msch_buffer, + .complete_cb = config_get_maxlun_complete, + .user_data = 0 }; TU_ASSERT(tuh_control_xfer(&xfer)); return true; } -static void config_get_maxlun_complete (tuh_xfer_t* xfer) -{ +static void config_get_maxlun_complete(tuh_xfer_t* xfer) { uint8_t const daddr = xfer->daddr; msch_interface_t* p_msc = get_itf(daddr); @@ -471,18 +442,16 @@ static void config_get_maxlun_complete (tuh_xfer_t* xfer) tuh_msc_test_unit_ready(daddr, lun, config_test_unit_ready_complete, 0); } -static bool config_test_unit_ready_complete(uint8_t dev_addr, tuh_msc_complete_data_t const * cb_data) -{ +static bool config_test_unit_ready_complete(uint8_t dev_addr, tuh_msc_complete_data_t const* cb_data) { msc_cbw_t const* cbw = cb_data->cbw; msc_csw_t const* csw = cb_data->csw; - if (csw->status == 0) - { + if (csw->status == 0) { // Unit is ready, read its capacity TU_LOG_DRV("SCSI Read Capacity\r\n"); - tuh_msc_read_capacity(dev_addr, cbw->lun, (scsi_read_capacity10_resp_t*) ((void*) _msch_buffer), config_read_capacity_complete, 0); - }else - { + tuh_msc_read_capacity(dev_addr, cbw->lun, (scsi_read_capacity10_resp_t*) ((void*) _msch_buffer), + config_read_capacity_complete, 0); + } else { // Note: During enumeration, some device fails Test Unit Ready and require a few retries // with Request Sense to start working !! // TODO limit number of retries @@ -493,8 +462,7 @@ static bool config_test_unit_ready_complete(uint8_t dev_addr, tuh_msc_complete_d return true; } -static bool config_request_sense_complete(uint8_t dev_addr, tuh_msc_complete_data_t const * cb_data) -{ +static bool config_request_sense_complete(uint8_t dev_addr, tuh_msc_complete_data_t const* cb_data) { msc_cbw_t const* cbw = cb_data->cbw; msc_csw_t const* csw = cb_data->csw; @@ -503,8 +471,7 @@ static bool config_request_sense_complete(uint8_t dev_addr, tuh_msc_complete_dat return true; } -static bool config_read_capacity_complete(uint8_t dev_addr, tuh_msc_complete_data_t const * cb_data) -{ +static bool config_read_capacity_complete(uint8_t dev_addr, tuh_msc_complete_data_t const* cb_data) { msc_cbw_t const* cbw = cb_data->cbw; msc_csw_t const* csw = cb_data->csw; diff --git a/src/class/msc/msc_host.h b/src/class/msc/msc_host.h index 6c0e5c9dd..9ca1b4703 100644 --- a/src/class/msc/msc_host.h +++ b/src/class/msc/msc_host.h @@ -24,8 +24,8 @@ * This file is part of the TinyUSB stack. */ -#ifndef _TUSB_MSC_HOST_H_ -#define _TUSB_MSC_HOST_H_ +#ifndef TUSB_MSC_HOST_H_ +#define TUSB_MSC_HOST_H_ #include "msc.h" @@ -73,7 +73,7 @@ uint32_t tuh_msc_get_block_size(uint8_t dev_addr, uint8_t lun); // Perform a full SCSI command (cbw, data, csw) in non-blocking manner. // Complete callback is invoked when SCSI op is complete. // return true if success, false if there is already pending operation. -bool tuh_msc_scsi_command(uint8_t dev_addr, msc_cbw_t const* cbw, void* data, tuh_msc_complete_cb_t complete_cb, uintptr_t arg); +bool tuh_msc_scsi_command(uint8_t daddr, msc_cbw_t const* cbw, void* data, tuh_msc_complete_cb_t complete_cb, uintptr_t arg); // Perform SCSI Inquiry command // Complete callback is invoked when SCSI op is complete. @@ -123,4 +123,4 @@ bool msch_xfer_cb (uint8_t dev_addr, uint8_t ep_addr, xfer_result_t event, ui } #endif -#endif /* _TUSB_MSC_HOST_H_ */ +#endif diff --git a/src/host/usbh.c b/src/host/usbh.c index e332f35cc..8d75c9726 100644 --- a/src/host/usbh.c +++ b/src/host/usbh.c @@ -817,6 +817,7 @@ bool usbh_edpt_release(uint8_t dev_addr, uint8_t ep_addr) } // Submit an transfer +// TODO call usbh_edpt_release if failed bool usbh_edpt_xfer_with_callback(uint8_t dev_addr, uint8_t ep_addr, uint8_t * buffer, uint16_t total_bytes, tuh_xfer_cb_t complete_cb, uintptr_t user_data) { @@ -1713,19 +1714,16 @@ static bool _parse_configuration_descriptor(uint8_t dev_addr, tusb_desc_configur return true; } -void usbh_driver_set_config_complete(uint8_t dev_addr, uint8_t itf_num) -{ +void usbh_driver_set_config_complete(uint8_t dev_addr, uint8_t itf_num) { usbh_device_t* dev = get_device(dev_addr); - for(itf_num++; itf_num < CFG_TUH_INTERFACE_MAX; itf_num++) - { + for(itf_num++; itf_num < CFG_TUH_INTERFACE_MAX; itf_num++) { // continue with next valid interface // IAD binding interface such as CDCs should return itf_num + 1 when complete // with usbh_driver_set_config_complete() uint8_t const drv_id = dev->itf2drv[itf_num]; usbh_class_driver_t const * driver = get_driver(drv_id); - if (driver) - { + if (driver) { TU_LOG_USBH("%s set config: itf = %u\r\n", driver->name, itf_num); driver->set_config(dev_addr, itf_num); break; @@ -1733,23 +1731,19 @@ void usbh_driver_set_config_complete(uint8_t dev_addr, uint8_t itf_num) } // all interface are configured - if (itf_num == CFG_TUH_INTERFACE_MAX) - { + if (itf_num == CFG_TUH_INTERFACE_MAX) { enum_full_complete(); - if (is_hub_addr(dev_addr)) - { + if (is_hub_addr(dev_addr)) { TU_LOG(CFG_TUH_LOG_LEVEL, "HUB address = %u is mounted\r\n", dev_addr); - }else - { + }else { // Invoke callback if available if (tuh_mount_cb) tuh_mount_cb(dev_addr); } } } -static void enum_full_complete(void) -{ +static void enum_full_complete(void) { // mark enumeration as complete _dev0.enumerating = 0; -- cgit v1.3.1 From 8348631bf538e2aa0a433ed6e7df9e42bb39bdd5 Mon Sep 17 00:00:00 2001 From: hathach Date: Thu, 28 Sep 2023 16:15:31 +0700 Subject: improve esp32 ci, build esp32 with -DDMAX3421_HOST=1 for max3421 testing revert change in hcd.h --- .github/workflows/build_esp.yml | 21 +------- .../espressif/boards/espressif_s3_devkitm/board.h | 8 +++ src/host/hcd.h | 3 -- tools/build_esp32.py | 63 ++++++++++++---------- 4 files changed, 45 insertions(+), 50 deletions(-) (limited to 'src/host') diff --git a/.github/workflows/build_esp.yml b/.github/workflows/build_esp.yml index 29585cb36..897616f09 100644 --- a/.github/workflows/build_esp.yml +++ b/.github/workflows/build_esp.yml @@ -29,12 +29,10 @@ jobs: fail-fast: false matrix: board: - # Alphabetical order # ESP32-S2 - - 'espressif_saola_1' + - 'espressif_kaluga_1' # ESP32-S3 - #- 'espressif_s3_devkitm' - # S3 compile error with "dangerous relocation: call8: call target out of range: memcpy" + - 'espressif_s3_devkitm' steps: - name: Setup Python @@ -48,20 +46,5 @@ jobs: - name: Checkout TinyUSB uses: actions/checkout@v3 - - name: Checkout hathach/linkermap - uses: actions/checkout@v3 - with: - repository: hathach/linkermap - path: linkermap - - name: Build run: docker run --rm -v $PWD:/project -w /project espressif/idf:latest python3 tools/build_esp32.py ${{ matrix.board }} - - - name: Linker Map - run: | - pip install linkermap/ - # find -quit to only print linkermap of 1 board per example - for ex in `ls -d examples/device/*/` - do - find ${ex} -maxdepth 3 -name *.map -print -quit | xargs -I % sh -c 'echo "::group::%"; linkermap -v %; echo "::endgroup::"' - done diff --git a/hw/bsp/espressif/boards/espressif_s3_devkitm/board.h b/hw/bsp/espressif/boards/espressif_s3_devkitm/board.h index fe33b5c43..4b4151e72 100644 --- a/hw/bsp/espressif/boards/espressif_s3_devkitm/board.h +++ b/hw/bsp/espressif/boards/espressif_s3_devkitm/board.h @@ -36,6 +36,14 @@ #define BUTTON_PIN 0 #define BUTTON_STATE_ACTIVE 0 +// SPI for USB host shield +#define MAX3421_SPI_HOST SPI2_HOST +#define MAX3421_SCK_PIN 36 +#define MAX3421_MOSI_PIN 35 +#define MAX3421_MISO_PIN 37 +#define MAX3421_CS_PIN 15 +#define MAX3421_INTR_PIN 14 + #ifdef __cplusplus } #endif diff --git a/src/host/hcd.h b/src/host/hcd.h index edffb34cb..2bde289df 100644 --- a/src/host/hcd.h +++ b/src/host/hcd.h @@ -133,9 +133,6 @@ bool hcd_init(uint8_t rhport); // Interrupt Handler void hcd_int_handler(uint8_t rhport, bool in_isr); -// Interrupt Hanndler (extended version) -void hcd_int_handler_ext(uint8_t rhport, bool in_isr); - // Enable USB interrupt void hcd_int_enable (uint8_t rhport); diff --git a/tools/build_esp32.py b/tools/build_esp32.py index 00783bf58..1f73d3b22 100644 --- a/tools/build_esp32.py +++ b/tools/build_esp32.py @@ -17,8 +17,8 @@ exit_status = 0 total_time = time.monotonic() -build_format = '| {:23} | {:30} | {:18} | {:7} | {:6} | {:6} |' -build_separator = '-' * 100 +build_format = '| {:30} | {:30} | {:18} | {:7} | {:6} | {:6} |' +build_separator = '-' * 107 def filter_with_input(mylist): if len(sys.argv) > 1: @@ -26,12 +26,9 @@ def filter_with_input(mylist): if len(input_args) > 0: mylist[:] = input_args + # Build all examples if not specified -all_examples = [] -for entry in os.scandir("examples/device"): - # Only includes example with CMakeLists.txt for esp32s, and skip board_test to speed up ci - if entry.is_dir() and os.path.exists(entry.path + "/sdkconfig.defaults") and entry.name != 'board_test': - all_examples.append(entry.name) +all_examples = [entry.replace('examples/', '') for entry in glob.glob("examples/*/*_freertos")] filter_with_input(all_examples) all_examples.sort() @@ -46,32 +43,41 @@ all_boards.sort() def build_board(example, board): global success_count, fail_count, skip_count, exit_status start_time = time.monotonic() + + # Check if board is skipped + build_dir = f"cmake-build/cmake-build-{board}/{example}" + + # Generate and build + r = subprocess.run(f"cmake examples/{example} -B {build_dir} -G \"Ninja\" -DBOARD={board} -DMAX3421_HOST=1", + shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) + if r.returncode == 0: + r = subprocess.run(f"cmake --build {build_dir}", shell=True, stdout=subprocess.PIPE, + stderr=subprocess.STDOUT) + build_duration = time.monotonic() - start_time flash_size = "-" sram_size = "-" - # Check if board is skipped - if build_utils.skip_example(example, board): - success = SKIPPED - skip_count += 1 - print(build_format.format(example, board, success, '-', flash_size, sram_size)) + if r.returncode == 0: + success = SUCCEEDED + success_count += 1 + #(flash_size, sram_size) = build_size(example, board) else: - subprocess.run("make -C examples/device/{} BOARD={} clean".format(example, board), shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) - build_result = subprocess.run("make -j -C examples/device/{} BOARD={} all".format(example, board), shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) - - if build_result.returncode == 0: - success = SUCCEEDED - success_count += 1 - (flash_size, sram_size) = build_size(example, board) - else: - exit_status = build_result.returncode - success = FAILED - fail_count += 1 - - build_duration = time.monotonic() - start_time - print(build_format.format(example, board, success, "{:.2f}s".format(build_duration), flash_size, sram_size)) + exit_status = r.returncode + success = FAILED + fail_count += 1 + + title = build_format.format(example, board, success, "{:.2f}s".format(build_duration), flash_size, sram_size) + if os.getenv('CI'): + # always print build output if in CI + print(f"::group::{title}") + print(r.stdout.decode("utf-8")) + print(f"::endgroup::") + else: + # print build output if failed + print(title) + if r.returncode != 0: + print(r.stdout.decode("utf-8")) - if build_result.returncode != 0: - print(build_result.stdout.decode("utf-8")) def build_size(example, board): #elf_file = 'examples/device/{}/_build/{}/{}-firmware.elf'.format(example, board, board) @@ -82,6 +88,7 @@ def build_size(example, board): sram_size = int(size_list[1]) + int(size_list[2]) return (flash_size, sram_size) + print(build_separator) print(build_format.format('Example', 'Board', '\033[39mResult\033[0m', 'Time', 'Flash', 'SRAM')) print(build_separator) -- cgit v1.3.1 From 4b9320e40ea65ca023925d0a644b116b7066e06f Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 3 Nov 2023 22:22:13 +0700 Subject: fix race condition when dev0 is removed while enumerating --- src/host/usbh.c | 70 +++++++++++++------------- src/portable/raspberrypi/pio_usb/hcd_pio_usb.c | 16 +++--- 2 files changed, 44 insertions(+), 42 deletions(-) (limited to 'src/host') diff --git a/src/host/usbh.c b/src/host/usbh.c index 8d75c9726..fb4fbe3cb 100644 --- a/src/host/usbh.c +++ b/src/host/usbh.c @@ -55,16 +55,12 @@ typedef struct uint8_t rhport; uint8_t hub_addr; uint8_t hub_port; - uint8_t speed; - - // enumeration is in progress, done when all interfaces are configured - volatile uint8_t enumerating; -// struct TU_ATTR_PACKED { -// uint8_t speed : 4; // packed speed to save footprint -// volatile uint8_t enumerating : 1; -// uint8_t TU_RESERVED : 3; -// }; + struct TU_ATTR_PACKED { + uint8_t speed : 4; // packed speed to save footprint + volatile uint8_t enumerating : 1; // enumeration is in progress, false if not connected or all interfaces are configured + uint8_t TU_RESERVED : 3; + }; } usbh_dev0_t; typedef struct { @@ -431,8 +427,8 @@ void tuh_task_ext(uint32_t timeout_ms, bool in_isr) { switch (event.event_id) { case HCD_EVENT_DEVICE_ATTACH: - // due to the shared _usbh_ctrl_buf, we must complete enumerating - // one device before enumerating another one. + // due to the shared _usbh_ctrl_buf, we must complete enumerating one device before enumerating another one. + // TODO better to have an separated queue for newly attached devices if ( _dev0.enumerating ) { TU_LOG_USBH("[%u:] USBH Defer Attach until current enumeration complete\r\n", event.rhport); @@ -556,11 +552,13 @@ bool tuh_control_xfer (tuh_xfer_t* xfer) { // EP0 with setup packet TU_VERIFY(xfer->ep_addr == 0 && xfer->setup); - // pre-check to help reducing mutex lock - TU_VERIFY(_ctrl_xfer.stage == CONTROL_STAGE_IDLE); - + // Check if device is still connected (enumerating for dev0) uint8_t const daddr = xfer->daddr; + if ( daddr == 0 && !_dev0.enumerating) return false; + if ( daddr != 0 && get_device(daddr)->connected == 0) return false; + // pre-check to help reducing mutex lock + TU_VERIFY(_ctrl_xfer.stage == CONTROL_STAGE_IDLE); (void) osal_mutex_lock(_usbh_mutex, OSAL_TIMEOUT_WAIT_FOREVER); bool const is_idle = (_ctrl_xfer.stage == CONTROL_STAGE_IDLE); @@ -917,19 +915,23 @@ void hcd_devtree_get_info(uint8_t dev_addr, hcd_devtree_info_t* devtree_info) } } -TU_ATTR_FAST_FUNC void hcd_event_handler(hcd_event_t const* event, bool in_isr) -{ - switch (event->event_id) - { -// case HCD_EVENT_DEVICE_REMOVE: -// // FIXME device remove from a hub need an HCD API for hcd to free up endpoint -// // mark device as removing to prevent further xfer before the event is processed in usbh task -// break; +TU_ATTR_FAST_FUNC void hcd_event_handler(hcd_event_t const* event, bool in_isr) { + switch (event->event_id) { + case HCD_EVENT_DEVICE_REMOVE: + // FIXME device remove from a hub need an HCD API for hcd to free up endpoint + // mark device as removing to prevent further xfer before the event is processed in usbh task - default: - osal_queue_send(_usbh_q, event, in_isr); - break; + // Check if dev0 is removed + if ((event->rhport == _dev0.rhport) && (event->connection.hub_addr == _dev0.hub_addr) && + (event->connection.hub_port == _dev0.hub_port)) { + _dev0.enumerating = 0; + } + break; + + default: break; } + + osal_queue_send(_usbh_q, event, in_isr); } //--------------------------------------------------------------------+ @@ -1294,8 +1296,7 @@ static bool _parse_configuration_descriptor (uint8_t dev_addr, tusb_desc_configu static void enum_full_complete(void); // process device enumeration -static void process_enumeration(tuh_xfer_t* xfer) -{ +static void process_enumeration(tuh_xfer_t* xfer) { // Retry a few times with transfers in enumeration since device can be unstable when starting up enum { ATTEMPT_COUNT_MAX = 3, @@ -1303,19 +1304,20 @@ static void process_enumeration(tuh_xfer_t* xfer) }; static uint8_t failed_count = 0; - if (XFER_RESULT_SUCCESS != xfer->result) - { + if (XFER_RESULT_SUCCESS != xfer->result) { // retry if not reaching max attempt - if ( failed_count < ATTEMPT_COUNT_MAX ) - { + bool retry = _dev0.enumerating && (failed_count < ATTEMPT_COUNT_MAX); + if ( retry ) { failed_count++; osal_task_delay(ATTEMPT_DELAY_MS); // delay a bit TU_LOG1("Enumeration attempt %u\r\n", failed_count); - TU_ASSERT(tuh_control_xfer(xfer), ); - }else - { + retry = tuh_control_xfer(xfer); + } + + if (!retry) { enum_full_complete(); } + return; } failed_count = 0; diff --git a/src/portable/raspberrypi/pio_usb/hcd_pio_usb.c b/src/portable/raspberrypi/pio_usb/hcd_pio_usb.c index 93bc1bf43..f4de3c51d 100644 --- a/src/portable/raspberrypi/pio_usb/hcd_pio_usb.c +++ b/src/portable/raspberrypi/pio_usb/hcd_pio_usb.c @@ -182,14 +182,6 @@ void __no_inline_not_in_flash_func(pio_usb_host_irq_handler)(uint8_t root_id) { root_port_t *rport = PIO_USB_ROOT_PORT(root_id); uint32_t const ints = rport->ints; - if ( ints & PIO_USB_INTS_CONNECT_BITS ) { - hcd_event_device_attach(tu_rhport, true); - } - - if ( ints & PIO_USB_INTS_DISCONNECT_BITS ) { - hcd_event_device_remove(tu_rhport, true); - } - if ( ints & PIO_USB_INTS_ENDPOINT_COMPLETE_BITS ) { handle_endpoint_irq(rport, XFER_RESULT_SUCCESS, &rport->ep_complete); } @@ -202,6 +194,14 @@ void __no_inline_not_in_flash_func(pio_usb_host_irq_handler)(uint8_t root_id) { handle_endpoint_irq(rport, XFER_RESULT_FAILED, &rport->ep_error); } + if ( ints & PIO_USB_INTS_CONNECT_BITS ) { + hcd_event_device_attach(tu_rhport, true); + } + + if ( ints & PIO_USB_INTS_DISCONNECT_BITS ) { + hcd_event_device_remove(tu_rhport, true); + } + // clear all rport->ints &= ~ints; } -- cgit v1.3.1 From 9377fd6901dd9c7b5361a9ce5c01a99cc6761750 Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 3 Nov 2023 22:34:49 +0700 Subject: fix -Werror=null-dereference warning --- src/host/usbh.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'src/host') diff --git a/src/host/usbh.c b/src/host/usbh.c index fb4fbe3cb..d8fff9905 100644 --- a/src/host/usbh.c +++ b/src/host/usbh.c @@ -554,8 +554,12 @@ bool tuh_control_xfer (tuh_xfer_t* xfer) { // Check if device is still connected (enumerating for dev0) uint8_t const daddr = xfer->daddr; - if ( daddr == 0 && !_dev0.enumerating) return false; - if ( daddr != 0 && get_device(daddr)->connected == 0) return false; + if ( daddr == 0 ) { + if (!_dev0.enumerating) return false; + } else { + usbh_device_t const* dev = get_device(daddr); + if (dev && dev->connected == 0) return false; + } // pre-check to help reducing mutex lock TU_VERIFY(_ctrl_xfer.stage == CONTROL_STAGE_IDLE); -- cgit v1.3.1 From 68894398af9e8a096c700b7a4e8c127e53a2d6bc Mon Sep 17 00:00:00 2001 From: Angus Gratton Date: Wed, 1 Nov 2023 15:45:44 +1100 Subject: Add optional hooks for DCD and HCD events These are intended to allow bare metal platforms with one-shot scheduling capabilities to schedule the TinyUSB task handlers whenever they know there is work for them to do. Signed-off-by: Angus Gratton --- src/device/usbd.c | 15 +++++++++++---- src/host/usbh.c | 2 ++ src/tusb_option.h | 12 ++++++++++++ 3 files changed, 25 insertions(+), 4 deletions(-) (limited to 'src/host') diff --git a/src/device/usbd.c b/src/device/usbd.c index 50941c46f..2b6d07a96 100644 --- a/src/device/usbd.c +++ b/src/device/usbd.c @@ -1079,6 +1079,7 @@ static bool process_get_descriptor(uint8_t rhport, tusb_control_request_t const //--------------------------------------------------------------------+ TU_ATTR_FAST_FUNC void dcd_event_handler(dcd_event_t const * event, bool in_isr) { + bool send = false; switch (event->event_id) { case DCD_EVENT_UNPLUGGED: @@ -1086,7 +1087,7 @@ TU_ATTR_FAST_FUNC void dcd_event_handler(dcd_event_t const * event, bool in_isr) _usbd_dev.addressed = 0; _usbd_dev.cfg_num = 0; _usbd_dev.suspended = 0; - osal_queue_send(_usbd_q, event, in_isr); + send = true; break; case DCD_EVENT_SUSPEND: @@ -1097,7 +1098,7 @@ TU_ATTR_FAST_FUNC void dcd_event_handler(dcd_event_t const * event, bool in_isr) if ( _usbd_dev.connected ) { _usbd_dev.suspended = 1; - osal_queue_send(_usbd_q, event, in_isr); + send = true; } break; @@ -1106,7 +1107,7 @@ TU_ATTR_FAST_FUNC void dcd_event_handler(dcd_event_t const * event, bool in_isr) if ( _usbd_dev.connected ) { _usbd_dev.suspended = 0; - osal_queue_send(_usbd_q, event, in_isr); + send = true; } break; @@ -1129,15 +1130,21 @@ TU_ATTR_FAST_FUNC void dcd_event_handler(dcd_event_t const * event, bool in_isr) dcd_event_t const event_resume = { .rhport = event->rhport, .event_id = DCD_EVENT_RESUME }; osal_queue_send(_usbd_q, &event_resume, in_isr); + CFG_TUD_EVENT_HOOK(&event_resume, in_isr); } // skip osal queue for SOF in usbd task break; default: - osal_queue_send(_usbd_q, event, in_isr); + send = true; break; } + + if (send) { + osal_queue_send(_usbd_q, event, in_isr); + CFG_TUD_EVENT_HOOK(event, in_isr); + } } //--------------------------------------------------------------------+ diff --git a/src/host/usbh.c b/src/host/usbh.c index d8fff9905..2fdc8216d 100644 --- a/src/host/usbh.c +++ b/src/host/usbh.c @@ -780,6 +780,7 @@ void usbh_defer_func(osal_task_func_t func, void *param, bool in_isr) { event.func_call.param = param; osal_queue_send(_usbh_q, &event, in_isr); + CFG_TUH_EVENT_HOOK(event, in_isr); } //--------------------------------------------------------------------+ @@ -936,6 +937,7 @@ TU_ATTR_FAST_FUNC void hcd_event_handler(hcd_event_t const* event, bool in_isr) } osal_queue_send(_usbh_q, event, in_isr); + CFG_TUH_EVENT_HOOK(event, in_isr); } //--------------------------------------------------------------------+ diff --git a/src/tusb_option.h b/src/tusb_option.h index a29eb8a3a..aedc02dbc 100644 --- a/src/tusb_option.h +++ b/src/tusb_option.h @@ -485,6 +485,18 @@ #define tuc_int_handler(_p) #endif +//--------------------------------------------------------------------+ +// Optional event hook functions for platform integration (defaults) +//--------------------------------------------------------------------+ + +#ifndef CFG_TUD_EVENT_HOOK +#define CFG_TUD_EVENT_HOOK(EVENT, IN_ISR) +#endif + +#ifndef CFG_TUH_EVENT_HOOK +#define CFG_TUH_EVENT_HOOK(EVENT, IN_ISR) +#endif + //------------------------------------------------------------------ // Configuration Validation //------------------------------------------------------------------ -- cgit v1.3.1 From 188fbd8ed9b5e0f5cc3ddb5e89f7afd421fc7c06 Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 24 Nov 2023 18:21:24 +0700 Subject: add optional event hook callback tud_event_hook_cb() and tuh_event_hook_cb() --- src/device/usbd.c | 83 +++++++++++++++++++++++-------------------------------- src/device/usbd.h | 3 ++ src/host/usbh.c | 18 ++++++------ src/host/usbh.h | 5 +++- src/tusb_option.h | 12 -------- 5 files changed, 52 insertions(+), 69 deletions(-) (limited to 'src/host') diff --git a/src/device/usbd.c b/src/device/usbd.c index 2b6d07a96..59466b42e 100644 --- a/src/device/usbd.c +++ b/src/device/usbd.c @@ -242,22 +242,17 @@ tu_static uint8_t _app_driver_count = 0; // virtually joins built-in and application drivers together. // Application is positioned first to allow overwriting built-in ones. -static inline usbd_class_driver_t const * get_driver(uint8_t drvid) -{ +TU_ATTR_ALWAYS_INLINE static inline usbd_class_driver_t const * get_driver(uint8_t drvid) { usbd_class_driver_t const * driver = NULL; - if ( drvid < _app_driver_count ) { // Application drivers driver = &_app_driver[drvid]; } else if ( drvid < TOTAL_DRIVER_COUNT && BUILTIN_DRIVER_COUNT > 0 ){ driver = &_usbd_driver[drvid - _app_driver_count]; } - return driver; } - - //--------------------------------------------------------------------+ // DCD Event //--------------------------------------------------------------------+ @@ -278,6 +273,11 @@ tu_static osal_queue_t _usbd_q; #define _usbd_mutex NULL #endif +TU_ATTR_ALWAYS_INLINE static inline bool queue_event(dcd_event_t const * event, bool in_isr) { + bool ret = osal_queue_send(_usbd_q, event, in_isr); + if (tud_event_hook_cb) tud_event_hook_cb(event->rhport, event->event_id, in_isr); + return ret; +} //--------------------------------------------------------------------+ // Prototypes @@ -374,8 +374,7 @@ bool tud_connect(void) //--------------------------------------------------------------------+ // USBD Task //--------------------------------------------------------------------+ -bool tud_inited(void) -{ +bool tud_inited(void) { return _usbd_rhport != RHPORT_INVALID; } @@ -1077,73 +1076,64 @@ static bool process_get_descriptor(uint8_t rhport, tusb_control_request_t const //--------------------------------------------------------------------+ // DCD Event Handler //--------------------------------------------------------------------+ -TU_ATTR_FAST_FUNC void dcd_event_handler(dcd_event_t const * event, bool in_isr) -{ +TU_ATTR_FAST_FUNC void dcd_event_handler(dcd_event_t const* event, bool in_isr) { bool send = false; - switch (event->event_id) - { + switch (event->event_id) { case DCD_EVENT_UNPLUGGED: - _usbd_dev.connected = 0; - _usbd_dev.addressed = 0; - _usbd_dev.cfg_num = 0; - _usbd_dev.suspended = 0; + _usbd_dev.connected = 0; + _usbd_dev.addressed = 0; + _usbd_dev.cfg_num = 0; + _usbd_dev.suspended = 0; send = true; - break; + break; case DCD_EVENT_SUSPEND: // NOTE: When plugging/unplugging device, the D+/D- state are unstable and // can accidentally meet the SUSPEND condition ( Bus Idle for 3ms ). // In addition, some MCUs such as SAMD or boards that haven no VBUS detection cannot distinguish // suspended vs disconnected. We will skip handling SUSPEND/RESUME event if not currently connected - if ( _usbd_dev.connected ) - { + if (_usbd_dev.connected) { _usbd_dev.suspended = 1; send = true; } - break; + break; case DCD_EVENT_RESUME: // skip event if not connected (especially required for SAMD) - if ( _usbd_dev.connected ) - { + if (_usbd_dev.connected) { _usbd_dev.suspended = 0; send = true; } - break; + break; case DCD_EVENT_SOF: - // SOF driver handler in ISR context - for (uint8_t i = 0; i < TOTAL_DRIVER_COUNT; i++) - { - usbd_class_driver_t const * driver = get_driver(i); - if (driver && driver->sof) - { - driver->sof(event->rhport, event->sof.frame_count); - } - } - // Some MCUs after running dcd_remote_wakeup() does not have way to detect the end of remote wakeup // which last 1-15 ms. DCD can use SOF as a clear indicator that bus is back to operational - if ( _usbd_dev.suspended ) - { + if (_usbd_dev.suspended) { _usbd_dev.suspended = 0; - dcd_event_t const event_resume = { .rhport = event->rhport, .event_id = DCD_EVENT_RESUME }; - osal_queue_send(_usbd_q, &event_resume, in_isr); - CFG_TUD_EVENT_HOOK(&event_resume, in_isr); + dcd_event_t const event_resume = {.rhport = event->rhport, .event_id = DCD_EVENT_RESUME}; + queue_event(&event_resume, in_isr); + } + + // SOF driver handler in ISR context + for (uint8_t i = 0; i < TOTAL_DRIVER_COUNT; i++) { + usbd_class_driver_t const* driver = get_driver(i); + if (driver && driver->sof) { + driver->sof(event->rhport, event->sof.frame_count); + } } // skip osal queue for SOF in usbd task - break; + break; default: send = true; - break; + break; } if (send) { - osal_queue_send(_usbd_q, event, in_isr); - CFG_TUD_EVENT_HOOK(event, in_isr); + queue_event(event, in_isr); } } @@ -1187,18 +1177,15 @@ bool usbd_open_edpt_pair(uint8_t rhport, uint8_t const* p_desc, uint8_t ep_count } // Helper to defer an isr function -void usbd_defer_func(osal_task_func_t func, void* param, bool in_isr) -{ - dcd_event_t event = - { +void usbd_defer_func(osal_task_func_t func, void* param, bool in_isr) { + dcd_event_t event = { .rhport = 0, .event_id = USBD_EVENT_FUNC_CALL, }; - event.func_call.func = func; event.func_call.param = param; - dcd_event_handler(&event, in_isr); + queue_event(&event, in_isr); } //--------------------------------------------------------------------+ diff --git a/src/device/usbd.h b/src/device/usbd.h index 93a2033c4..1e2f31b06 100644 --- a/src/device/usbd.h +++ b/src/device/usbd.h @@ -146,6 +146,9 @@ TU_ATTR_WEAK void tud_suspend_cb(bool remote_wakeup_en); // Invoked when usb bus is resumed TU_ATTR_WEAK void tud_resume_cb(void); +// Invoked when there is a new usb event, which need to be processed by tud_task()/tud_task_ext() +TU_ATTR_WEAK void tud_event_hook_cb(uint8_t rhport, uint32_t eventid, bool in_isr); + // Invoked when received control request with VENDOR TYPE TU_ATTR_WEAK bool tud_vendor_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t const * request); diff --git a/src/host/usbh.c b/src/host/usbh.c index 2fdc8216d..bbda99ea2 100644 --- a/src/host/usbh.c +++ b/src/host/usbh.c @@ -247,9 +247,7 @@ CFG_TUH_MEM_SECTION struct //------------- Helper Function -------------// -TU_ATTR_ALWAYS_INLINE -static inline usbh_device_t* get_device(uint8_t dev_addr) -{ +TU_ATTR_ALWAYS_INLINE static inline usbh_device_t* get_device(uint8_t dev_addr) { TU_VERIFY(dev_addr > 0 && dev_addr <= TOTAL_DEVICES, NULL); return &_usbh_devices[dev_addr-1]; } @@ -268,6 +266,12 @@ TU_ATTR_WEAK void osal_task_delay(uint32_t msec) { } #endif +TU_ATTR_ALWAYS_INLINE static inline bool queue_event(hcd_event_t const * event, bool in_isr) { + bool ret = osal_queue_send(_usbh_q, event, in_isr); + if (tuh_event_hook_cb) tuh_event_hook_cb(event->rhport, event->event_id, in_isr); + return ret; +} + //--------------------------------------------------------------------+ // Device API //--------------------------------------------------------------------+ @@ -433,7 +437,7 @@ void tuh_task_ext(uint32_t timeout_ms, bool in_isr) { TU_LOG_USBH("[%u:] USBH Defer Attach until current enumeration complete\r\n", event.rhport); bool is_empty = osal_queue_empty(_usbh_q); - osal_queue_send(_usbh_q, &event, in_isr); + queue_event(&event, in_isr); if (is_empty) { // Exit if this is the only event in the queue, otherwise we may loop forever @@ -779,8 +783,7 @@ void usbh_defer_func(osal_task_func_t func, void *param, bool in_isr) { event.func_call.func = func; event.func_call.param = param; - osal_queue_send(_usbh_q, &event, in_isr); - CFG_TUH_EVENT_HOOK(event, in_isr); + queue_event(&event, in_isr); } //--------------------------------------------------------------------+ @@ -936,8 +939,7 @@ TU_ATTR_FAST_FUNC void hcd_event_handler(hcd_event_t const* event, bool in_isr) default: break; } - osal_queue_send(_usbh_q, event, in_isr); - CFG_TUH_EVENT_HOOK(event, in_isr); + queue_event(event, in_isr); } //--------------------------------------------------------------------+ diff --git a/src/host/usbh.h b/src/host/usbh.h index 770d70dfe..7591c7672 100644 --- a/src/host/usbh.h +++ b/src/host/usbh.h @@ -90,9 +90,12 @@ TU_ATTR_WEAK void tuh_mount_cb (uint8_t daddr); // Invoked when a device failed to mount during enumeration process // TU_ATTR_WEAK void tuh_mount_failed_cb (uint8_t daddr); -/// Invoked when a device is unmounted (detached) +// Invoked when a device is unmounted (detached) TU_ATTR_WEAK void tuh_umount_cb(uint8_t daddr); +// Invoked when there is a new usb event, which need to be processed by tuh_task()/tuh_task_ext() +TU_ATTR_WEAK void tuh_event_hook_cb(uint8_t rhport, uint32_t eventid, bool in_isr); + //--------------------------------------------------------------------+ // APPLICATION API //--------------------------------------------------------------------+ diff --git a/src/tusb_option.h b/src/tusb_option.h index cf774a41c..b8509a069 100644 --- a/src/tusb_option.h +++ b/src/tusb_option.h @@ -486,18 +486,6 @@ #define tuc_int_handler(_p) #endif -//--------------------------------------------------------------------+ -// Optional event hook functions for platform integration (defaults) -//--------------------------------------------------------------------+ - -#ifndef CFG_TUD_EVENT_HOOK -#define CFG_TUD_EVENT_HOOK(EVENT, IN_ISR) -#endif - -#ifndef CFG_TUH_EVENT_HOOK -#define CFG_TUH_EVENT_HOOK(EVENT, IN_ISR) -#endif - //------------------------------------------------------------------ // Configuration Validation //------------------------------------------------------------------ -- cgit v1.3.1 From b8881a3a141530a1d383d8869881e773b8a07d80 Mon Sep 17 00:00:00 2001 From: IngHK Date: Fri, 24 Nov 2023 22:34:28 +0100 Subject: fixed compile errors due to untreated CFG_TUH_LOG_LEVEL --- src/common/tusb_debug.h | 2 +- src/host/usbh.c | 8 ++++---- src/host/usbh_pvt.h | 2 +- src/tusb.c | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) (limited to 'src/host') diff --git a/src/common/tusb_debug.h b/src/common/tusb_debug.h index 99176c02a..bd388d910 100644 --- a/src/common/tusb_debug.h +++ b/src/common/tusb_debug.h @@ -43,7 +43,7 @@ #if CFG_TUSB_DEBUG // Enum to String for debugging purposes -#if CFG_TUSB_DEBUG >= 2 +#if CFG_TUSB_DEBUG >= CFG_TUH_LOG_LEVEL extern char const* const tu_str_speed[]; extern char const* const tu_str_std_request[]; extern char const* const tu_str_xfer_result[]; diff --git a/src/host/usbh.c b/src/host/usbh.c index d8fff9905..78c8abfbd 100644 --- a/src/host/usbh.c +++ b/src/host/usbh.c @@ -113,7 +113,7 @@ typedef struct { // MACRO CONSTANT TYPEDEF //--------------------------------------------------------------------+ -#if CFG_TUSB_DEBUG >= 2 +#if CFG_TUSB_DEBUG >= CFG_TUH_LOG_LEVEL #define DRIVER_NAME(_name) .name = _name, #else #define DRIVER_NAME(_name) @@ -1233,7 +1233,7 @@ static void process_removing_device(uint8_t rhport, uint8_t hub_addr, uint8_t hu TU_LOG_USBH("Device unplugged address = %u\r\n", daddr); if (is_hub_addr(daddr)) { - TU_LOG(CFG_TUH_LOG_LEVEL, " is a HUB device %u\r\n", daddr); + TU_LOG_USBH(" is a HUB device %u\r\n", daddr); // Submit removed event If the device itself is a hub (un-rolled recursive) // TODO a better to unroll recursrive is using array of removing_hubs and mark it here @@ -1708,7 +1708,7 @@ static bool _parse_configuration_descriptor(uint8_t dev_addr, tusb_desc_configur if ( drv_id == TOTAL_DRIVER_COUNT - 1 ) { - TU_LOG(CFG_TUH_LOG_LEVEL, "[%u:%u] Interface %u: class = %u subclass = %u protocol = %u is not supported\r\n", + TU_LOG_USBH("[%u:%u] Interface %u: class = %u subclass = %u protocol = %u is not supported\r\n", dev->rhport, dev_addr, desc_itf->bInterfaceNumber, desc_itf->bInterfaceClass, desc_itf->bInterfaceSubClass, desc_itf->bInterfaceProtocol); } } @@ -1741,7 +1741,7 @@ void usbh_driver_set_config_complete(uint8_t dev_addr, uint8_t itf_num) { enum_full_complete(); if (is_hub_addr(dev_addr)) { - TU_LOG(CFG_TUH_LOG_LEVEL, "HUB address = %u is mounted\r\n", dev_addr); + TU_LOG_USBH("HUB address = %u is mounted\r\n", dev_addr); }else { // Invoke callback if available if (tuh_mount_cb) tuh_mount_cb(dev_addr); diff --git a/src/host/usbh_pvt.h b/src/host/usbh_pvt.h index 2b61a77db..3363ab9eb 100644 --- a/src/host/usbh_pvt.h +++ b/src/host/usbh_pvt.h @@ -51,7 +51,7 @@ enum { //--------------------------------------------------------------------+ typedef struct { - #if CFG_TUSB_DEBUG >= 2 + #if CFG_TUSB_DEBUG >= CFG_TUH_LOG_LEVEL char const* name; #endif diff --git a/src/tusb.c b/src/tusb.c index 7b0a669a0..e0c1066d4 100644 --- a/src/tusb.c +++ b/src/tusb.c @@ -419,7 +419,7 @@ uint32_t tu_edpt_stream_read(tu_edpt_stream_t* s, void* buffer, uint32_t bufsize #if CFG_TUSB_DEBUG #include -#if CFG_TUSB_DEBUG >= 2 +#if CFG_TUSB_DEBUG >= CFG_TUH_LOG_LEVEL char const* const tu_str_speed[] = { "Full", "Low", "High" }; char const* const tu_str_std_request[] = -- cgit v1.3.1 From 19d7d62e804dbf26f9d193d72710574abcd6fa95 Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 13 Dec 2023 18:54:00 +0700 Subject: try to add samd51 to hil pool using doublereset (rpi gpio) and bossac --- .github/workflows/cmake_arm.yml | 10 +++++++++- hw/bsp/samd21/family.cmake | 3 ++- hw/bsp/samd51/family.c | 14 ++++++++++++++ hw/bsp/samd51/family.cmake | 4 +++- src/device/usbd_pvt.h | 5 ----- src/host/usbh_pvt.h | 5 ----- src/tusb_option.h | 10 ++++++++++ test/hil/hil_pi4.json | 9 +++++++++ test/hil/hil_test.py | 39 +++++++++++++++++++++++++++++++++++++-- 9 files changed, 84 insertions(+), 15 deletions(-) (limited to 'src/host') diff --git a/.github/workflows/cmake_arm.yml b/.github/workflows/cmake_arm.yml index f760ca3ca..46dc7a93b 100644 --- a/.github/workflows/cmake_arm.yml +++ b/.github/workflows/cmake_arm.yml @@ -102,6 +102,13 @@ jobs: path: | cmake-build/cmake-build-feather_nrf52840_express/*/*/*.elf + - name: Upload Artifacts for Hardware Testing (samd51) + if: matrix.family == 'samd51' && github.repository_owner == 'hathach' + uses: actions/upload-artifact@v3 + with: + name: itsybitsy_m4 + path: | + cmake-build/cmake-build-itsybitsy_m4/*/*/*.bin # --------------------------------------- # Hardware in the loop (HIL) @@ -116,8 +123,9 @@ jobs: fail-fast: false matrix: board: - - 'raspberry_pi_pico' - 'feather_nrf52840_express' + - 'itsybitsy_m4' + - 'raspberry_pi_pico' steps: - name: Clean workspace run: | diff --git a/hw/bsp/samd21/family.cmake b/hw/bsp/samd21/family.cmake index 44aad6ecb..a79a25b54 100644 --- a/hw/bsp/samd21/family.cmake +++ b/hw/bsp/samd21/family.cmake @@ -10,7 +10,7 @@ set(CMAKE_SYSTEM_PROCESSOR cortex-m0plus CACHE INTERNAL "System Processor") set(CMAKE_TOOLCHAIN_FILE ${TOP}/examples/build_system/cmake/toolchain/arm_${TOOLCHAIN}.cmake) set(FAMILY_MCUS SAMD21 CACHE INTERNAL "") - +set(OPENOCD_OPTION "-f interface/cmsis-dap.cfg -c \"transport select swd\" -f target/at91samdXX.cfg") #------------------------------------ # BOARD_TARGET @@ -102,4 +102,5 @@ function(family_configure_example TARGET RTOS) # Flashing family_flash_jlink(${TARGET}) + #family_flash_openocd(${TARGET} ${OPENOCD_OPTION}) endfunction() diff --git a/hw/bsp/samd51/family.c b/hw/bsp/samd51/family.c index 009a0d290..170c88191 100644 --- a/hw/bsp/samd51/family.c +++ b/hw/bsp/samd51/family.c @@ -157,6 +157,20 @@ uint32_t board_button_read(void) { return gpio_get_pin_level(BUTTON_PIN) ? 0 : 1; } +size_t board_get_unique_id(uint8_t id[], size_t max_len) { + (void) max_len; + + uint32_t did_addr[4] = {0x008061FC, 0x00806010, 0x00806014, 0x00806018}; + + for (int i = 0; i < 4; i++) { + uint32_t did = *((uint32_t const*) did_addr[i]); + did = TU_BSWAP32(did); // swap endian to match samd51 uf2 bootloader + memcpy(id + i * 4, &did, 4); + } + + return 16; +} + int board_uart_read(uint8_t* buf, int len) { (void) buf; (void) len; diff --git a/hw/bsp/samd51/family.cmake b/hw/bsp/samd51/family.cmake index 7591f3b1b..4d91bf1a6 100644 --- a/hw/bsp/samd51/family.cmake +++ b/hw/bsp/samd51/family.cmake @@ -10,7 +10,7 @@ set(CMAKE_SYSTEM_PROCESSOR cortex-m4 CACHE INTERNAL "System Processor") set(CMAKE_TOOLCHAIN_FILE ${TOP}/examples/build_system/cmake/toolchain/arm_${TOOLCHAIN}.cmake) set(FAMILY_MCUS SAMD51 CACHE INTERNAL "") - +set(OPENOCD_OPTION "-f interface/cmsis-dap.cfg -c \"transport select swd\" -c \"set CHIPNAME samd51\" -f target/atsame5x.cfg") #------------------------------------ # BOARD_TARGET @@ -100,5 +100,7 @@ function(family_configure_example TARGET RTOS) target_link_libraries(${TARGET} PUBLIC board_${BOARD} ${TARGET}-tinyusb) # Flashing + family_add_bin_hex(${TARGET}) family_flash_jlink(${TARGET}) + #family_flash_openocd(${TARGET} ${OPENOCD_OPTION}) endfunction() diff --git a/src/device/usbd_pvt.h b/src/device/usbd_pvt.h index 153be7cee..9039bc9d6 100644 --- a/src/device/usbd_pvt.h +++ b/src/device/usbd_pvt.h @@ -33,11 +33,6 @@ extern "C" { #endif -// Level where CFG_TUSB_DEBUG must be at least for USBD is logged -#ifndef CFG_TUD_LOG_LEVEL -#define CFG_TUD_LOG_LEVEL 2 -#endif - #define TU_LOG_USBD(...) TU_LOG(CFG_TUD_LOG_LEVEL, __VA_ARGS__) //--------------------------------------------------------------------+ diff --git a/src/host/usbh_pvt.h b/src/host/usbh_pvt.h index 3363ab9eb..4a97a1c18 100644 --- a/src/host/usbh_pvt.h +++ b/src/host/usbh_pvt.h @@ -35,11 +35,6 @@ extern "C" { #endif -// Level where CFG_TUSB_DEBUG must be at least for USBH is logged -#ifndef CFG_TUH_LOG_LEVEL - #define CFG_TUH_LOG_LEVEL 2 -#endif - #define TU_LOG_USBH(...) TU_LOG(CFG_TUH_LOG_LEVEL, __VA_ARGS__) enum { diff --git a/src/tusb_option.h b/src/tusb_option.h index 7597392d6..4d2aa137c 100644 --- a/src/tusb_option.h +++ b/src/tusb_option.h @@ -299,6 +299,16 @@ #define CFG_TUSB_DEBUG 0 #endif +// Level where CFG_TUSB_DEBUG must be at least for USBH is logged +#ifndef CFG_TUH_LOG_LEVEL + #define CFG_TUH_LOG_LEVEL 2 +#endif + +// Level where CFG_TUSB_DEBUG must be at least for USBD is logged +#ifndef CFG_TUD_LOG_LEVEL + #define CFG_TUD_LOG_LEVEL 2 +#endif + // Memory section for placing buffer used for usb transferring. If MEM_SECTION is different for // host and device use: CFG_TUD_MEM_SECTION, CFG_TUH_MEM_SECTION instead #ifndef CFG_TUSB_MEM_SECTION diff --git a/test/hil/hil_pi4.json b/test/hil/hil_pi4.json index 560c3964e..17d9ff1fa 100644 --- a/test/hil/hil_pi4.json +++ b/test/hil/hil_pi4.json @@ -23,6 +23,15 @@ "flasher": "jlink", "flasher_sn": "000682804350", "flasher_args": "-device nrf52840_xxaa" + }, + { + "name": "itsybitsy_m4", + "uid": "D784B28C5338533335202020FF044726", + "flasher": "bossac", + "flashser_vendor": "Adafruit Industries", + "flasher_product": "ItsyBitsy M4 Express", + "flasher_reset_pin": "2", + "flasher_args": "--offset 0x4000" } ] } diff --git a/test/hil/hil_test.py b/test/hil/hil_test.py index 8f8a3aa65..f9611b96e 100644 --- a/test/hil/hil_test.py +++ b/test/hil/hil_test.py @@ -34,6 +34,10 @@ import subprocess import json import glob +# for RPI double reset: install sudo apt install python3-gpiozero or sudo pip install gpiozero +from gpiozero import LED + + ENUM_TIMEOUT = 10 @@ -41,6 +45,8 @@ ENUM_TIMEOUT = 10 def get_serial_dev(id, vendor_str, product_str, ifnum): if vendor_str and product_str: # known vendor and product + vendor_str = vendor_str.replace(' ', '_') + product_str = product_str.replace(' ', '_') return f'/dev/serial/by-id/usb-{vendor_str}_{product_str}_{id}-if{ifnum:02d}' else: # just use id: mostly for cp210x/ftdi flasher @@ -115,7 +121,7 @@ def flash_jlink(board, firmware): def flash_openocd(board, firmware): ret = subprocess.run( - f'openocd -c "adapter serial {board["flasher_sn"]}" {board["flasher_args"]} -c "program {firmware}" -c "reset init" -c "resume" -c "exit"', + f'openocd -c "adapter serial {board["flasher_sn"]}" {board["flasher_args"]} -c "program {firmware} reset exit"', shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) return ret @@ -133,6 +139,35 @@ def flash_esptool(board, firmware): return ret +def doublereset_with_rpi_gpio(board): + # Off = 0 = Reset + led = LED(board["flasher_reset_pin"]) + + led.off() + time.sleep(0.1) + led.on() + time.sleep(0.1) + led.off() + time.sleep(0.1) + led.on() + +def flash_bossac(board, firmware): + # double reset to enter bootloader + doublereset_with_rpi_gpio(board) + + port = get_serial_dev(board["uid"], board["flashser_vendor"], board["flasher_product"], 0) + timeout = ENUM_TIMEOUT + while timeout: + if os.path.exists(port): + time.sleep(0.5) + break + else: + time.sleep(0.5) + timeout = timeout - 0.5 + ret = subprocess.run(f'bossac --port {port} {board["flasher_args"]} -U -i -R -e -w {firmware}', shell=True, stdout=subprocess.PIPE, + stderr=subprocess.STDOUT) + return ret + # ------------------------------------------------------------- # Tests # ------------------------------------------------------------- @@ -305,7 +340,7 @@ def main(config_file, board): for test in test_list: fw_list = [ - # cmake: esp32 use .bin file + # cmake: esp32 & samd51 use .bin file f'cmake-build/cmake-build-{item["name"]}/device/{test}/{test}.elf', f'cmake-build/cmake-build-{item["name"]}/device/{test}/{test}.bin', # make -- cgit v1.3.1 From a39be99a58847318e67d06db17c24e481d318f08 Mon Sep 17 00:00:00 2001 From: IngHK Date: Tue, 26 Dec 2023 12:24:54 +0100 Subject: improved hex debug print, improved USBH debug prints, added pid/vid debug print --- src/common/tusb_debug.h | 2 +- src/host/usbh.c | 29 ++++++++++++++++------------- src/host/usbh_pvt.h | 6 +++++- 3 files changed, 22 insertions(+), 15 deletions(-) (limited to 'src/host') diff --git a/src/common/tusb_debug.h b/src/common/tusb_debug.h index 0f4dc93f3..8db1606ae 100644 --- a/src/common/tusb_debug.h +++ b/src/common/tusb_debug.h @@ -76,7 +76,7 @@ static inline void tu_print_buf(uint8_t const* buf, uint32_t bufsize) { #define TU_LOG1_MEM tu_print_mem #define TU_LOG1_BUF(_x, _n) tu_print_buf((uint8_t const*)(_x), _n) #define TU_LOG1_INT(_x) tu_printf(#_x " = %ld\r\n", (unsigned long) (_x) ) -#define TU_LOG1_HEX(_x) tu_printf(#_x " = %lX\r\n", (unsigned long) (_x) ) +#define TU_LOG1_HEX(_x) tu_printf(#_x " = 0x%lX\r\n", (unsigned long) (_x) ) // Log Level 2: Warn #if CFG_TUSB_DEBUG >= 2 diff --git a/src/host/usbh.c b/src/host/usbh.c index 4d30d9f81..ee7424ed9 100644 --- a/src/host/usbh.c +++ b/src/host/usbh.c @@ -291,6 +291,9 @@ bool tuh_vid_pid_get(uint8_t dev_addr, uint16_t *vid, uint16_t *pid) { *vid = dev->vid; *pid = dev->pid; + TU_LOG_HEX_USBH(*vid); + TU_LOG_HEX_USBH(*pid); + return true; } @@ -340,12 +343,12 @@ bool tuh_init(uint8_t controller_id) { if ( tuh_inited() ) return true; TU_LOG_USBH("USBH init on controller %u\r\n", controller_id); - TU_LOG_INT(CFG_TUH_LOG_LEVEL, sizeof(usbh_device_t)); - TU_LOG_INT(CFG_TUH_LOG_LEVEL, sizeof(hcd_event_t)); - TU_LOG_INT(CFG_TUH_LOG_LEVEL, sizeof(_ctrl_xfer)); - TU_LOG_INT(CFG_TUH_LOG_LEVEL, sizeof(tuh_xfer_t)); - TU_LOG_INT(CFG_TUH_LOG_LEVEL, sizeof(tu_fifo_t)); - TU_LOG_INT(CFG_TUH_LOG_LEVEL, sizeof(tu_edpt_stream_t)); + TU_LOG_INT_USBH(sizeof(usbh_device_t)); + TU_LOG_INT_USBH(sizeof(hcd_event_t)); + TU_LOG_INT_USBH(sizeof(_ctrl_xfer)); + TU_LOG_INT_USBH(sizeof(tuh_xfer_t)); + TU_LOG_INT_USBH(sizeof(tu_fifo_t)); + TU_LOG_INT_USBH(sizeof(tu_edpt_stream_t)); // Event queue _usbh_q = osal_queue_create( &_usbh_qdef ); @@ -589,7 +592,7 @@ bool tuh_control_xfer (tuh_xfer_t* xfer) { TU_LOG_USBH("[%u:%u] %s: ", rhport, daddr, (xfer->setup->bmRequestType_bit.type == TUSB_REQ_TYPE_STANDARD && xfer->setup->bRequest <= TUSB_REQ_SYNCH_FRAME) ? tu_str_std_request[xfer->setup->bRequest] : "Class Request"); - TU_LOG_BUF(CFG_TUH_LOG_LEVEL, xfer->setup, 8); + TU_LOG_BUF_USBH(xfer->setup, 8); TU_LOG_USBH("\r\n"); if (xfer->complete_cb) { @@ -665,9 +668,9 @@ static bool usbh_control_xfer_cb (uint8_t dev_addr, uint8_t ep_addr, xfer_result tusb_control_request_t const * request = &_ctrl_xfer.request; if (XFER_RESULT_SUCCESS != result) { - TU_LOG1("[%u:%u] Control %s, xferred_bytes = %lu\r\n", rhport, dev_addr, result == XFER_RESULT_STALLED ? "STALLED" : "FAILED", xferred_bytes); - TU_LOG1_BUF(request, 8); - TU_LOG1("\r\n"); + TU_LOG_USBH("[%u:%u] Control %s, xferred_bytes = %lu\r\n", rhport, dev_addr, result == XFER_RESULT_STALLED ? "STALLED" : "FAILED", xferred_bytes); + TU_LOG_BUF_USBH(request, 8); + TU_LOG_USBH("\r\n"); // terminate transfer if any stage failed _xfer_complete(dev_addr, result); @@ -685,7 +688,7 @@ static bool usbh_control_xfer_cb (uint8_t dev_addr, uint8_t ep_addr, xfer_result case CONTROL_STAGE_DATA: if (request->wLength) { TU_LOG_USBH("[%u:%u] Control data:\r\n", rhport, dev_addr); - TU_LOG_MEM(CFG_TUH_LOG_LEVEL, _ctrl_xfer.buffer, xferred_bytes, 2); + TU_LOG_MEM_USBH(_ctrl_xfer.buffer, xferred_bytes, 2); } _ctrl_xfer.actual_len = (uint16_t) xferred_bytes; @@ -860,7 +863,7 @@ bool usbh_edpt_xfer_with_callback(uint8_t dev_addr, uint8_t ep_addr, uint8_t * b // HCD error, mark endpoint as ready to allow next transfer ep_state->busy = 0; ep_state->claimed = 0; - TU_LOG1("Failed\r\n"); + TU_LOG_USBH("Failed\r\n"); // TU_BREAKPOINT(); return false; } @@ -1318,7 +1321,7 @@ static void process_enumeration(tuh_xfer_t* xfer) { if ( retry ) { failed_count++; osal_task_delay(ATTEMPT_DELAY_MS); // delay a bit - TU_LOG1("Enumeration attempt %u\r\n", failed_count); + TU_LOG_USBH("Enumeration attempt %u\r\n", failed_count); retry = tuh_control_xfer(xfer); } diff --git a/src/host/usbh_pvt.h b/src/host/usbh_pvt.h index 4a97a1c18..4ed2a72b5 100644 --- a/src/host/usbh_pvt.h +++ b/src/host/usbh_pvt.h @@ -35,7 +35,11 @@ extern "C" { #endif -#define TU_LOG_USBH(...) TU_LOG(CFG_TUH_LOG_LEVEL, __VA_ARGS__) +#define TU_LOG_USBH(...) TU_LOG(CFG_TUH_LOG_LEVEL, __VA_ARGS__) +#define TU_LOG_MEM_USBH(...) TU_LOG_MEM(CFG_TUH_LOG_LEVEL, __VA_ARGS__) +#define TU_LOG_BUF_USBH(...) TU_LOG_BUF(CFG_TUH_LOG_LEVEL, __VA_ARGS__) +#define TU_LOG_INT_USBH(...) TU_LOG_INT(CFG_TUH_LOG_LEVEL, __VA_ARGS__) +#define TU_LOG_HEX_USBH(...) TU_LOG_HEX(CFG_TUH_LOG_LEVEL, __VA_ARGS__) enum { USBH_EPSIZE_BULK_MAX = (TUH_OPT_HIGH_SPEED ? TUSB_EPSIZE_BULK_HS : TUSB_EPSIZE_BULK_FS) -- cgit v1.3.1 From a4aa454a7a21c022569eccfea493b8a96d182d9c Mon Sep 17 00:00:00 2001 From: Ryzee119 Date: Sun, 7 Jan 2024 08:25:31 +1030 Subject: [HUB] Fix double status xfer --- src/host/hub.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'src/host') diff --git a/src/host/hub.c b/src/host/hub.c index 32f5e0ac7..3bac18698 100644 --- a/src/host/hub.c +++ b/src/host/hub.c @@ -435,9 +435,12 @@ static void hub_port_get_status_complete (tuh_xfer_t* xfer) // Other changes are: L1 state // TODO clear change - // prepare for next hub status - // TODO continue with status_change, or maybe we can do it again with status - hub_edpt_status_xfer(daddr); + else + { + // prepare for next hub status + // TODO continue with status_change, or maybe we can do it again with status + hub_edpt_status_xfer(daddr); + } } } -- cgit v1.3.1 From d39d06e6d920aadc9e479d4dfb8620dd3871cb98 Mon Sep 17 00:00:00 2001 From: Ryzee119 Date: Tue, 9 Jan 2024 16:22:54 +1030 Subject: [HUB] Prevent status request to invalid ep_num --- src/host/usbh.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/host') diff --git a/src/host/usbh.c b/src/host/usbh.c index 4d30d9f81..53e8a654b 100644 --- a/src/host/usbh.c +++ b/src/host/usbh.c @@ -456,7 +456,7 @@ void tuh_task_ext(uint32_t timeout_ms, bool in_isr) { #if CFG_TUH_HUB // TODO remove - if ( event.connection.hub_addr != 0) { + if ( event.connection.hub_addr != 0 && event.connection.hub_port != 0) { // done with hub, waiting for next data on status pipe (void) hub_edpt_status_xfer( event.connection.hub_addr ); } -- cgit v1.3.1 From 290f4bea91e739979217eb91d589a75f9ac0f6a7 Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 12 Jan 2024 15:47:08 +0700 Subject: - change tuh_event_hook_cb, tud_event_hook_cb to weak default implementation - change code style --- src/device/usbd.c | 362 +++++++++++++++++++++++----------------------- src/device/usbd.h | 2 +- src/device/usbd_control.c | 33 ++--- src/host/usbh.c | 126 ++++++++-------- src/host/usbh.h | 2 +- 5 files changed, 255 insertions(+), 270 deletions(-) (limited to 'src/host') diff --git a/src/device/usbd.c b/src/device/usbd.c index 59466b42e..5c94ebcc5 100644 --- a/src/device/usbd.c +++ b/src/device/usbd.c @@ -38,11 +38,19 @@ //--------------------------------------------------------------------+ // USBD Configuration //--------------------------------------------------------------------+ - #ifndef CFG_TUD_TASK_QUEUE_SZ #define CFG_TUD_TASK_QUEUE_SZ 16 #endif +//--------------------------------------------------------------------+ +// Callback weak stubs (called if application does not provide) +//--------------------------------------------------------------------+ +TU_ATTR_WEAK void tud_event_hook_cb(uint8_t rhport, uint32_t eventid, bool in_isr) { + (void)rhport; + (void)eventid; + (void)in_isr; +} + //--------------------------------------------------------------------+ // Device Data //--------------------------------------------------------------------+ @@ -50,10 +58,8 @@ // Invalid driver ID in itf2drv[] ep2drv[][] mapping enum { DRVID_INVALID = 0xFFu }; -typedef struct -{ - struct TU_ATTR_PACKED - { +typedef struct { + struct TU_ATTR_PACKED { volatile uint8_t connected : 1; volatile uint8_t addressed : 1; volatile uint8_t suspended : 1; @@ -85,151 +91,150 @@ tu_static usbd_device_t _usbd_dev; #endif // Built-in class drivers -tu_static usbd_class_driver_t const _usbd_driver[] = -{ - #if CFG_TUD_CDC - { - DRIVER_NAME("CDC") - .init = cdcd_init, - .reset = cdcd_reset, - .open = cdcd_open, - .control_xfer_cb = cdcd_control_xfer_cb, - .xfer_cb = cdcd_xfer_cb, - .sof = NULL - }, - #endif - - #if CFG_TUD_MSC - { - DRIVER_NAME("MSC") - .init = mscd_init, - .reset = mscd_reset, - .open = mscd_open, - .control_xfer_cb = mscd_control_xfer_cb, - .xfer_cb = mscd_xfer_cb, - .sof = NULL - }, - #endif - - #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 - }, - #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 - }, - #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 - }, - #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 - }, - #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 - }, - #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 - }, - #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 - }, - #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 - }, - #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, - }, - #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 - }, - #endif +tu_static usbd_class_driver_t const _usbd_driver[] = { + #if CFG_TUD_CDC + { + DRIVER_NAME("CDC") + .init = cdcd_init, + .reset = cdcd_reset, + .open = cdcd_open, + .control_xfer_cb = cdcd_control_xfer_cb, + .xfer_cb = cdcd_xfer_cb, + .sof = NULL + }, + #endif + + #if CFG_TUD_MSC + { + DRIVER_NAME("MSC") + .init = mscd_init, + .reset = mscd_reset, + .open = mscd_open, + .control_xfer_cb = mscd_control_xfer_cb, + .xfer_cb = mscd_xfer_cb, + .sof = NULL + }, + #endif + + #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 + }, + #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 + }, + #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 + }, + #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 + }, + #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 + }, + #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 + }, + #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 + }, + #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 + }, + #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, + }, + #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 + }, + #endif }; enum { BUILTIN_DRIVER_COUNT = TU_ARRAY_SIZE(_usbd_driver) }; @@ -275,7 +280,7 @@ tu_static osal_queue_t _usbd_q; TU_ATTR_ALWAYS_INLINE static inline bool queue_event(dcd_event_t const * event, bool in_isr) { bool ret = osal_queue_send(_usbd_q, event, in_isr); - if (tud_event_hook_cb) tud_event_hook_cb(event->rhport, event->event_id, in_isr); + tud_event_hook_cb(event->rhport, event->event_id, in_isr); return ret; } @@ -297,27 +302,23 @@ bool usbd_control_xfer_cb (uint8_t rhport, uint8_t ep_addr, xfer_result_t event, // Debug //--------------------------------------------------------------------+ #if CFG_TUSB_DEBUG >= CFG_TUD_LOG_LEVEL -tu_static char const* const _usbd_event_str[DCD_EVENT_COUNT] = -{ - "Invalid" , - "Bus Reset" , - "Unplugged" , - "SOF" , - "Suspend" , - "Resume" , - "Setup Received" , - "Xfer Complete" , - "Func Call" +tu_static char const* const _usbd_event_str[DCD_EVENT_COUNT] = { + "Invalid", + "Bus Reset", + "Unplugged", + "SOF", + "Suspend", + "Resume", + "Setup Received", + "Xfer Complete", + "Func Call" }; // for usbd_control to print the name of control complete driver -void usbd_driver_print_control_complete_name(usbd_control_xfer_cb_t callback) -{ - for (uint8_t i = 0; i < TOTAL_DRIVER_COUNT; i++) - { - usbd_class_driver_t const * driver = get_driver(i); - if ( driver && driver->control_xfer_cb == callback ) - { +void usbd_driver_print_control_complete_name(usbd_control_xfer_cb_t callback) { + for (uint8_t i = 0; i < TOTAL_DRIVER_COUNT; i++) { + usbd_class_driver_t const* driver = get_driver(i); + if (driver && driver->control_xfer_cb == callback) { TU_LOG_USBD(" %s control complete\r\n", driver->name); return; } @@ -329,43 +330,36 @@ void usbd_driver_print_control_complete_name(usbd_control_xfer_cb_t callback) //--------------------------------------------------------------------+ // Application API //--------------------------------------------------------------------+ -tusb_speed_t tud_speed_get(void) -{ +tusb_speed_t tud_speed_get(void) { return (tusb_speed_t) _usbd_dev.speed; } -bool tud_connected(void) -{ +bool tud_connected(void) { return _usbd_dev.connected; } -bool tud_mounted(void) -{ +bool tud_mounted(void) { return _usbd_dev.cfg_num ? true : false; } -bool tud_suspended(void) -{ +bool tud_suspended(void) { return _usbd_dev.suspended; } -bool tud_remote_wakeup(void) -{ +bool tud_remote_wakeup(void) { // only wake up host if this feature is supported and enabled and we are suspended - TU_VERIFY (_usbd_dev.suspended && _usbd_dev.remote_wakeup_support && _usbd_dev.remote_wakeup_en ); + TU_VERIFY (_usbd_dev.suspended && _usbd_dev.remote_wakeup_support && _usbd_dev.remote_wakeup_en); dcd_remote_wakeup(_usbd_rhport); return true; } -bool tud_disconnect(void) -{ +bool tud_disconnect(void) { TU_VERIFY(dcd_disconnect); dcd_disconnect(_usbd_rhport); return true; } -bool tud_connect(void) -{ +bool tud_connect(void) { TU_VERIFY(dcd_connect); dcd_connect(_usbd_rhport); return true; diff --git a/src/device/usbd.h b/src/device/usbd.h index 5456148bf..3ab6c813f 100644 --- a/src/device/usbd.h +++ b/src/device/usbd.h @@ -147,7 +147,7 @@ TU_ATTR_WEAK void tud_suspend_cb(bool remote_wakeup_en); TU_ATTR_WEAK void tud_resume_cb(void); // Invoked when there is a new usb event, which need to be processed by tud_task()/tud_task_ext() -TU_ATTR_WEAK void tud_event_hook_cb(uint8_t rhport, uint32_t eventid, bool in_isr); +void tud_event_hook_cb(uint8_t rhport, uint32_t eventid, bool in_isr); // Invoked when received control request with VENDOR TYPE TU_ATTR_WEAK bool tud_vendor_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t const * request); diff --git a/src/device/usbd_control.c b/src/device/usbd_control.c index a6081060e..ea18b28da 100644 --- a/src/device/usbd_control.c +++ b/src/device/usbd_control.c @@ -32,24 +32,32 @@ #include "tusb.h" #include "device/usbd_pvt.h" +//--------------------------------------------------------------------+ +// Callback weak stubs (called if application does not provide) +//--------------------------------------------------------------------+ +TU_ATTR_WEAK void dcd_edpt0_status_complete(uint8_t rhport, tusb_control_request_t const * request) { + (void)rhport; + (void)request; +} + +//--------------------------------------------------------------------+ +// MACRO CONSTANT TYPEDEF +//--------------------------------------------------------------------+ + #if CFG_TUSB_DEBUG >= CFG_TUD_LOG_LEVEL extern void usbd_driver_print_control_complete_name(usbd_control_xfer_cb_t callback); #endif -enum -{ +enum { EDPT_CTRL_OUT = 0x00, EDPT_CTRL_IN = 0x80 }; -typedef struct -{ +typedef struct { tusb_control_request_t request; - uint8_t* buffer; uint16_t data_len; uint16_t total_xferred; - usbd_control_xfer_cb_t complete_cb; } usbd_control_xfer_t; @@ -134,23 +142,12 @@ bool tud_control_xfer(uint8_t rhport, tusb_control_request_t const * request, vo //--------------------------------------------------------------------+ // USBD API //--------------------------------------------------------------------+ - -TU_ATTR_WEAK void dcd_edpt0_status_complete(uint8_t rhport, tusb_control_request_t const * request) -{ - (void)rhport; - (void)request; - - // this is the default implementation that is called when no "real" implementation - // of the function exists -} - void usbd_control_reset(void); void usbd_control_set_request(tusb_control_request_t const *request); void usbd_control_set_complete_callback( usbd_control_xfer_cb_t fp ); bool usbd_control_xfer_cb (uint8_t rhport, uint8_t ep_addr, xfer_result_t event, uint32_t xferred_bytes); -void usbd_control_reset(void) -{ +void usbd_control_reset(void) { tu_varclr(&_ctrl_xfer); } diff --git a/src/host/usbh.c b/src/host/usbh.c index 53e8a654b..dfe6ddb42 100644 --- a/src/host/usbh.c +++ b/src/host/usbh.c @@ -36,7 +36,6 @@ //--------------------------------------------------------------------+ // USBH Configuration //--------------------------------------------------------------------+ - #ifndef CFG_TUH_TASK_QUEUE_SZ #define CFG_TUH_TASK_QUEUE_SZ 16 #endif @@ -46,11 +45,18 @@ #endif //--------------------------------------------------------------------+ -// USBH-HCD common data structure +// Callback weak stubs (called if application does not provide) //--------------------------------------------------------------------+ +TU_ATTR_WEAK void tuh_event_hook_cb(uint8_t rhport, uint32_t eventid, bool in_isr) { + (void) rhport; + (void) eventid; + (void) in_isr; +} -typedef struct -{ +//--------------------------------------------------------------------+ +// USBH-HCD common data structure +//--------------------------------------------------------------------+ +typedef struct { // port uint8_t rhport; uint8_t hub_addr; @@ -112,60 +118,58 @@ typedef struct { //--------------------------------------------------------------------+ // MACRO CONSTANT TYPEDEF //--------------------------------------------------------------------+ - #if CFG_TUSB_DEBUG >= CFG_TUH_LOG_LEVEL #define DRIVER_NAME(_name) .name = _name, #else #define DRIVER_NAME(_name) #endif -static usbh_class_driver_t const usbh_class_drivers[] = -{ - #if CFG_TUH_CDC +static usbh_class_driver_t const usbh_class_drivers[] = { + #if CFG_TUH_CDC { - DRIVER_NAME("CDC") - .init = cdch_init, - .open = cdch_open, - .set_config = cdch_set_config, - .xfer_cb = cdch_xfer_cb, - .close = cdch_close + DRIVER_NAME("CDC") + .init = cdch_init, + .open = cdch_open, + .set_config = cdch_set_config, + .xfer_cb = cdch_xfer_cb, + .close = cdch_close }, - #endif + #endif - #if CFG_TUH_MSC + #if CFG_TUH_MSC { - DRIVER_NAME("MSC") - .init = msch_init, - .open = msch_open, - .set_config = msch_set_config, - .xfer_cb = msch_xfer_cb, - .close = msch_close + DRIVER_NAME("MSC") + .init = msch_init, + .open = msch_open, + .set_config = msch_set_config, + .xfer_cb = msch_xfer_cb, + .close = msch_close }, - #endif + #endif - #if CFG_TUH_HID + #if CFG_TUH_HID { - DRIVER_NAME("HID") - .init = hidh_init, - .open = hidh_open, - .set_config = hidh_set_config, - .xfer_cb = hidh_xfer_cb, - .close = hidh_close + DRIVER_NAME("HID") + .init = hidh_init, + .open = hidh_open, + .set_config = hidh_set_config, + .xfer_cb = hidh_xfer_cb, + .close = hidh_close }, - #endif + #endif - #if CFG_TUH_HUB + #if CFG_TUH_HUB { - DRIVER_NAME("HUB") - .init = hub_init, - .open = hub_open, - .set_config = hub_set_config, - .xfer_cb = hub_xfer_cb, - .close = hub_close + DRIVER_NAME("HUB") + .init = hub_init, + .open = hub_open, + .set_config = hub_set_config, + .xfer_cb = hub_xfer_cb, + .close = hub_close }, - #endif + #endif - #if CFG_TUH_VENDOR + #if CFG_TUH_VENDOR { DRIVER_NAME("VENDOR") .init = cush_init, @@ -173,7 +177,7 @@ static usbh_class_driver_t const usbh_class_drivers[] = .xfer_cb = cush_isr, .close = cush_close } - #endif + #endif }; enum { BUILTIN_DRIVER_COUNT = TU_ARRAY_SIZE(usbh_class_drivers) }; @@ -233,8 +237,7 @@ static uint8_t _usbh_ctrl_buf[CFG_TUH_ENUMERATION_BUFSIZE]; // Control transfers: since most controllers do not support multiple control transfers // on multiple devices concurrently and control transfers are not used much except for // enumeration, we will only execute control transfers one at a time. -CFG_TUH_MEM_SECTION struct -{ +CFG_TUH_MEM_SECTION struct { CFG_TUH_MEM_ALIGN tusb_control_request_t request; uint8_t* buffer; tuh_xfer_cb_t complete_cb; @@ -268,7 +271,7 @@ TU_ATTR_WEAK void osal_task_delay(uint32_t msec) { TU_ATTR_ALWAYS_INLINE static inline bool queue_event(hcd_event_t const * event, bool in_isr) { bool ret = osal_queue_send(_usbh_q, event, in_isr); - if (tuh_event_hook_cb) tuh_event_hook_cb(event->rhport, event->event_id, in_isr); + tuh_event_hook_cb(event->rhport, event->event_id, in_isr); return ret; } @@ -367,17 +370,14 @@ bool tuh_init(uint8_t controller_id) { tu_memclr(_usbh_devices, sizeof(_usbh_devices)); tu_memclr(&_ctrl_xfer, sizeof(_ctrl_xfer)); - for(uint8_t i=0; iname); driver->init(); } @@ -545,8 +545,7 @@ void tuh_task_ext(uint32_t timeout_ms, bool in_isr) { // Control transfer //--------------------------------------------------------------------+ -static void _control_blocking_complete_cb(tuh_xfer_t* xfer) -{ +static void _control_blocking_complete_cb(tuh_xfer_t* xfer) { // update result *((xfer_result_t*) xfer->user_data) = xfer->result; } @@ -625,21 +624,18 @@ bool tuh_control_xfer (tuh_xfer_t* xfer) { return true; } -TU_ATTR_ALWAYS_INLINE static inline void _set_control_xfer_stage(uint8_t stage) -{ +TU_ATTR_ALWAYS_INLINE static inline void _set_control_xfer_stage(uint8_t stage) { (void) osal_mutex_lock(_usbh_mutex, OSAL_TIMEOUT_WAIT_FOREVER); _ctrl_xfer.stage = stage; (void) osal_mutex_unlock(_usbh_mutex); } -static void _xfer_complete(uint8_t daddr, xfer_result_t result) -{ +static void _xfer_complete(uint8_t daddr, xfer_result_t result) { TU_LOG_USBH("\r\n"); // duplicate xfer since user can execute control transfer within callback tusb_control_request_t const request = _ctrl_xfer.request; - tuh_xfer_t xfer_temp = - { + tuh_xfer_t xfer_temp = { .daddr = daddr, .ep_addr = 0, .result = result, @@ -652,8 +648,7 @@ static void _xfer_complete(uint8_t daddr, xfer_result_t result) _set_control_xfer_stage(CONTROL_STAGE_IDLE); - if (xfer_temp.complete_cb) - { + if (xfer_temp.complete_cb) { xfer_temp.complete_cb(&xfer_temp); } } @@ -710,17 +705,16 @@ static bool usbh_control_xfer_cb (uint8_t dev_addr, uint8_t ep_addr, xfer_result // //--------------------------------------------------------------------+ -bool tuh_edpt_xfer(tuh_xfer_t* xfer) -{ - uint8_t const daddr = xfer->daddr; +bool tuh_edpt_xfer(tuh_xfer_t* xfer) { + uint8_t const daddr = xfer->daddr; uint8_t const ep_addr = xfer->ep_addr; TU_VERIFY(daddr && ep_addr); TU_VERIFY(usbh_edpt_claim(daddr, ep_addr)); - if ( !usbh_edpt_xfer_with_callback(daddr, ep_addr, xfer->buffer, (uint16_t) xfer->buflen, xfer->complete_cb, xfer->user_data) ) - { + if (!usbh_edpt_xfer_with_callback(daddr, ep_addr, xfer->buffer, (uint16_t) xfer->buflen, + xfer->complete_cb, xfer->user_data)) { usbh_edpt_release(daddr, ep_addr); return false; } diff --git a/src/host/usbh.h b/src/host/usbh.h index 7591c7672..9ff118543 100644 --- a/src/host/usbh.h +++ b/src/host/usbh.h @@ -94,7 +94,7 @@ TU_ATTR_WEAK void tuh_mount_cb (uint8_t daddr); TU_ATTR_WEAK void tuh_umount_cb(uint8_t daddr); // Invoked when there is a new usb event, which need to be processed by tuh_task()/tuh_task_ext() -TU_ATTR_WEAK void tuh_event_hook_cb(uint8_t rhport, uint32_t eventid, bool in_isr); +void tuh_event_hook_cb(uint8_t rhport, uint32_t eventid, bool in_isr); //--------------------------------------------------------------------+ // APPLICATION API -- cgit v1.3.1 From e784e20b93068f4b063e066eb50ea005aeec99f4 Mon Sep 17 00:00:00 2001 From: IngHK Date: Wed, 7 Feb 2024 10:11:28 +0100 Subject: changes after review --- src/host/usbh.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) (limited to 'src/host') diff --git a/src/host/usbh.c b/src/host/usbh.c index ee7424ed9..d4f308e48 100644 --- a/src/host/usbh.c +++ b/src/host/usbh.c @@ -291,9 +291,6 @@ bool tuh_vid_pid_get(uint8_t dev_addr, uint16_t *vid, uint16_t *pid) { *vid = dev->vid; *pid = dev->pid; - TU_LOG_HEX_USBH(*vid); - TU_LOG_HEX_USBH(*pid); - return true; } @@ -863,7 +860,7 @@ bool usbh_edpt_xfer_with_callback(uint8_t dev_addr, uint8_t ep_addr, uint8_t * b // HCD error, mark endpoint as ready to allow next transfer ep_state->busy = 0; ep_state->claimed = 0; - TU_LOG_USBH("Failed\r\n"); + TU_LOG1("Failed\r\n"); // TU_BREAKPOINT(); return false; } @@ -1321,7 +1318,7 @@ static void process_enumeration(tuh_xfer_t* xfer) { if ( retry ) { failed_count++; osal_task_delay(ATTEMPT_DELAY_MS); // delay a bit - TU_LOG_USBH("Enumeration attempt %u\r\n", failed_count); + TU_LOG1("Enumeration attempt %u\r\n", failed_count); retry = tuh_control_xfer(xfer); } -- cgit v1.3.1 From 4d4e20b71efe8d9e1b5a141d84e058ff54801c67 Mon Sep 17 00:00:00 2001 From: IngHK Date: Thu, 8 Feb 2024 12:00:44 +0100 Subject: missing \r\n after TU_LOG_BUF => moved \r\n to tu_print_buf() --- src/common/tusb_debug.h | 1 + src/device/usbd.c | 1 - src/host/usbh.c | 2 -- 3 files changed, 1 insertion(+), 3 deletions(-) (limited to 'src/host') diff --git a/src/common/tusb_debug.h b/src/common/tusb_debug.h index 8db1606ae..2e9f1d9cd 100644 --- a/src/common/tusb_debug.h +++ b/src/common/tusb_debug.h @@ -60,6 +60,7 @@ void tu_print_mem(void const *buf, uint32_t count, uint8_t indent); static inline void tu_print_buf(uint8_t const* buf, uint32_t bufsize) { for(uint32_t i=0; isetup->bmRequestType_bit.type == TUSB_REQ_TYPE_STANDARD && xfer->setup->bRequest <= TUSB_REQ_SYNCH_FRAME) ? tu_str_std_request[xfer->setup->bRequest] : "Class Request"); TU_LOG_BUF_USBH(xfer->setup, 8); - TU_LOG_USBH("\r\n"); if (xfer->complete_cb) { TU_ASSERT( hcd_setup_send(rhport, daddr, (uint8_t const*) &_ctrl_xfer.request) ); @@ -662,7 +661,6 @@ static bool usbh_control_xfer_cb (uint8_t dev_addr, uint8_t ep_addr, xfer_result if (XFER_RESULT_SUCCESS != result) { TU_LOG_USBH("[%u:%u] Control %s, xferred_bytes = %lu\r\n", rhport, dev_addr, result == XFER_RESULT_STALLED ? "STALLED" : "FAILED", xferred_bytes); TU_LOG_BUF_USBH(request, 8); - TU_LOG_USBH("\r\n"); // terminate transfer if any stage failed _xfer_complete(dev_addr, result); -- cgit v1.3.1 From ff76eca311f4026c1a9b36e9ad37bbb53b39cf5d Mon Sep 17 00:00:00 2001 From: hathach Date: Mon, 4 Mar 2024 16:15:26 +0700 Subject: code reformat --- src/host/usbh.c | 563 ++++++++++++++++++++++++-------------------------------- src/tusb.c | 12 +- 2 files changed, 245 insertions(+), 330 deletions(-) (limited to 'src/host') diff --git a/src/host/usbh.c b/src/host/usbh.c index f56290a0c..407d97234 100644 --- a/src/host/usbh.c +++ b/src/host/usbh.c @@ -420,20 +420,18 @@ void tuh_task_ext(uint32_t timeout_ms, bool in_isr) { (void) in_isr; // not implemented yet // Skip if stack is not initialized - if ( !tuh_inited() ) return; + if (!tuh_inited()) return; // Loop until there is no more events in the queue - while (1) - { + while (1) { hcd_event_t event; - if ( !osal_queue_receive(_usbh_q, &event, timeout_ms) ) return; + if (!osal_queue_receive(_usbh_q, &event, timeout_ms)) return; - switch (event.event_id) - { + switch (event.event_id) { case HCD_EVENT_DEVICE_ATTACH: // due to the shared _usbh_ctrl_buf, we must complete enumerating one device before enumerating another one. // TODO better to have an separated queue for newly attached devices - if ( _dev0.enumerating ) { + if (_dev0.enumerating) { TU_LOG_USBH("[%u:] USBH Defer Attach until current enumeration complete\r\n", event.rhport); bool is_empty = osal_queue_empty(_usbh_q); @@ -443,12 +441,12 @@ void tuh_task_ext(uint32_t timeout_ms, bool in_isr) { // Exit if this is the only event in the queue, otherwise we may loop forever return; } - }else { + } else { TU_LOG_USBH("[%u:] USBH DEVICE ATTACH\r\n", event.rhport); _dev0.enumerating = 1; enum_new_device(&event); } - break; + break; case HCD_EVENT_DEVICE_REMOVE: TU_LOG_USBH("[%u:%u:%u] USBH DEVICE REMOVED\r\n", event.rhport, event.connection.hub_addr, event.connection.hub_port); @@ -456,37 +454,34 @@ void tuh_task_ext(uint32_t timeout_ms, bool in_isr) { #if CFG_TUH_HUB // TODO remove - if ( event.connection.hub_addr != 0 && event.connection.hub_port != 0) { + if (event.connection.hub_addr != 0 && event.connection.hub_port != 0) { // done with hub, waiting for next data on status pipe - (void) hub_edpt_status_xfer( event.connection.hub_addr ); + (void) hub_edpt_status_xfer(event.connection.hub_addr); } #endif - break; + break; - case HCD_EVENT_XFER_COMPLETE: - { + case HCD_EVENT_XFER_COMPLETE: { uint8_t const ep_addr = event.xfer_complete.ep_addr; - uint8_t const epnum = tu_edpt_number(ep_addr); - uint8_t const ep_dir = tu_edpt_dir(ep_addr); + uint8_t const epnum = tu_edpt_number(ep_addr); + uint8_t const ep_dir = (uint8_t) tu_edpt_dir(ep_addr); - TU_LOG_USBH("on EP %02X with %u bytes: %s\r\n", ep_addr, (unsigned int) event.xfer_complete.len, - tu_str_xfer_result[event.xfer_complete.result]); + TU_LOG_USBH("on EP %02X with %u bytes: %s\r\n", ep_addr, (unsigned int) event.xfer_complete.len, tu_str_xfer_result[event.xfer_complete.result]); if (event.dev_addr == 0) { // device 0 only has control endpoint - TU_ASSERT(epnum == 0, ); + TU_ASSERT(epnum == 0,); usbh_control_xfer_cb(event.dev_addr, ep_addr, (xfer_result_t) event.xfer_complete.result, event.xfer_complete.len); } else { usbh_device_t* dev = get_device(event.dev_addr); - TU_VERIFY(dev && dev->connected, ); + TU_VERIFY(dev && dev->connected,); - dev->ep_status[epnum][ep_dir].busy = 0; + dev->ep_status[epnum][ep_dir].busy = 0; dev->ep_status[epnum][ep_dir].claimed = 0; - if ( 0 == epnum ) { - usbh_control_xfer_cb(event.dev_addr, ep_addr, (xfer_result_t) event.xfer_complete.result, - event.xfer_complete.len); - }else { + if (0 == epnum) { + usbh_control_xfer_cb(event.dev_addr, ep_addr, (xfer_result_t) event.xfer_complete.result, event.xfer_complete.len); + } else { // Prefer application callback over built-in one if available. This occurs when tuh_edpt_xfer() is used // with enabled driver e.g HID endpoint #if CFG_TUH_API_EDPT_XFER @@ -503,35 +498,32 @@ void tuh_task_ext(uint32_t timeout_ms, bool in_isr) { .complete_cb = complete_cb, .user_data = dev->ep_callback[epnum][ep_dir].user_data }; - complete_cb(&xfer); }else #endif { uint8_t drv_id = dev->ep2drv[epnum][ep_dir]; - usbh_class_driver_t const * driver = get_driver(drv_id); - if ( driver ) - { + usbh_class_driver_t const* driver = get_driver(drv_id); + if (driver) { TU_LOG_USBH("%s xfer callback\r\n", driver->name); driver->xfer_cb(event.dev_addr, ep_addr, (xfer_result_t) event.xfer_complete.result, event.xfer_complete.len); - } - else - { + } else { // no driver/callback responsible for this transfer TU_ASSERT(false,); } } } } + break; } - break; case USBH_EVENT_FUNC_CALL: - if ( event.func_call.func ) event.func_call.func(event.func_call.param); - break; + if (event.func_call.func) event.func_call.func(event.func_call.param); + break; - default: break; + default: + break; } #if CFG_TUSB_OS != OPT_OS_NONE && CFG_TUSB_OS != OPT_OS_PICO @@ -708,7 +700,6 @@ bool tuh_edpt_xfer(tuh_xfer_t* xfer) { uint8_t const ep_addr = xfer->ep_addr; TU_VERIFY(daddr && ep_addr); - TU_VERIFY(usbh_edpt_claim(daddr, ep_addr)); if (!usbh_edpt_xfer_with_callback(daddr, ep_addr, xfer->buffer, (uint16_t) xfer->buflen, @@ -783,14 +774,13 @@ void usbh_defer_func(osal_task_func_t func, void *param, bool in_isr) { //--------------------------------------------------------------------+ // Claim an endpoint for transfer -bool usbh_edpt_claim(uint8_t dev_addr, uint8_t ep_addr) -{ +bool usbh_edpt_claim(uint8_t dev_addr, uint8_t ep_addr) { // Note: addr0 only use tuh_control_xfer usbh_device_t* dev = get_device(dev_addr); TU_ASSERT(dev && dev->connected); uint8_t const epnum = tu_edpt_number(ep_addr); - uint8_t const dir = tu_edpt_dir(ep_addr); + uint8_t const dir = tu_edpt_dir(ep_addr); TU_VERIFY(tu_edpt_claim(&dev->ep_status[epnum][dir], _usbh_mutex)); TU_LOG_USBH("[%u] Claimed EP 0x%02x\r\n", dev_addr, ep_addr); @@ -799,14 +789,13 @@ bool usbh_edpt_claim(uint8_t dev_addr, uint8_t ep_addr) } // Release an claimed endpoint due to failed transfer attempt -bool usbh_edpt_release(uint8_t dev_addr, uint8_t ep_addr) -{ +bool usbh_edpt_release(uint8_t dev_addr, uint8_t ep_addr) { // Note: addr0 only use tuh_control_xfer usbh_device_t* dev = get_device(dev_addr); TU_VERIFY(dev && dev->connected); uint8_t const epnum = tu_edpt_number(ep_addr); - uint8_t const dir = tu_edpt_dir(ep_addr); + uint8_t const dir = tu_edpt_dir(ep_addr); TU_VERIFY(tu_edpt_release(&dev->ep_status[epnum][dir], _usbh_mutex)); TU_LOG_USBH("[%u] Released EP 0x%02x\r\n", dev_addr, ep_addr); @@ -816,9 +805,8 @@ bool usbh_edpt_release(uint8_t dev_addr, uint8_t ep_addr) // Submit an transfer // TODO call usbh_edpt_release if failed -bool usbh_edpt_xfer_with_callback(uint8_t dev_addr, uint8_t ep_addr, uint8_t * buffer, uint16_t total_bytes, - tuh_xfer_cb_t complete_cb, uintptr_t user_data) -{ +bool usbh_edpt_xfer_with_callback(uint8_t dev_addr, uint8_t ep_addr, uint8_t* buffer, uint16_t total_bytes, + tuh_xfer_cb_t complete_cb, uintptr_t user_data) { (void) complete_cb; (void) user_data; @@ -826,7 +814,7 @@ bool usbh_edpt_xfer_with_callback(uint8_t dev_addr, uint8_t ep_addr, uint8_t * b TU_VERIFY(dev); uint8_t const epnum = tu_edpt_number(ep_addr); - uint8_t const dir = tu_edpt_dir(ep_addr); + uint8_t const dir = tu_edpt_dir(ep_addr); tu_edpt_state_t* ep_state = &dev->ep_status[epnum][dir]; TU_LOG_USBH(" Queue EP %02X with %u bytes ... \r\n", ep_addr, total_bytes); @@ -843,14 +831,12 @@ bool usbh_edpt_xfer_with_callback(uint8_t dev_addr, uint8_t ep_addr, uint8_t * b dev->ep_callback[epnum][dir].user_data = user_data; #endif - if ( hcd_edpt_xfer(dev->rhport, dev_addr, ep_addr, buffer, total_bytes) ) - { + if (hcd_edpt_xfer(dev->rhport, dev_addr, ep_addr, buffer, total_bytes)) { TU_LOG_USBH("OK\r\n"); return true; - }else - { + } else { // HCD error, mark endpoint as ready to allow next transfer - ep_state->busy = 0; + ep_state->busy = 0; ep_state->claimed = 0; TU_LOG1("Failed\r\n"); // TU_BREAKPOINT(); @@ -858,12 +844,9 @@ bool usbh_edpt_xfer_with_callback(uint8_t dev_addr, uint8_t ep_addr, uint8_t * b } } -static bool usbh_edpt_control_open(uint8_t dev_addr, uint8_t max_packet_size) -{ +static bool usbh_edpt_control_open(uint8_t dev_addr, uint8_t max_packet_size) { TU_LOG_USBH("[%u:%u] Open EP0 with Size = %u\r\n", usbh_get_rhport(dev_addr), dev_addr, max_packet_size); - - tusb_desc_endpoint_t ep0_desc = - { + tusb_desc_endpoint_t ep0_desc = { .bLength = sizeof(tusb_desc_endpoint_t), .bDescriptorType = TUSB_DESC_ENDPOINT, .bEndpointAddress = 0, @@ -875,10 +858,8 @@ static bool usbh_edpt_control_open(uint8_t dev_addr, uint8_t max_packet_size) return hcd_edpt_open(usbh_get_rhport(dev_addr), dev_addr, &ep0_desc); } -bool tuh_edpt_open(uint8_t dev_addr, tusb_desc_endpoint_t const * desc_ep) -{ - TU_ASSERT( tu_edpt_validate(desc_ep, tuh_speed_get(dev_addr)) ); - +bool tuh_edpt_open(uint8_t dev_addr, tusb_desc_endpoint_t const* desc_ep) { + TU_ASSERT(tu_edpt_validate(desc_ep, tuh_speed_get(dev_addr))); return hcd_edpt_open(usbh_get_rhport(dev_addr), dev_addr, desc_ep); } @@ -887,7 +868,7 @@ bool usbh_edpt_busy(uint8_t dev_addr, uint8_t ep_addr) { TU_VERIFY(dev); uint8_t const epnum = tu_edpt_number(ep_addr); - uint8_t const dir = tu_edpt_dir(ep_addr); + uint8_t const dir = tu_edpt_dir(ep_addr); return dev->ep_status[epnum][dir].busy; } @@ -896,22 +877,18 @@ bool usbh_edpt_busy(uint8_t dev_addr, uint8_t ep_addr) { // HCD Event Handler //--------------------------------------------------------------------+ -void hcd_devtree_get_info(uint8_t dev_addr, hcd_devtree_info_t* devtree_info) -{ +void hcd_devtree_get_info(uint8_t dev_addr, hcd_devtree_info_t* devtree_info) { usbh_device_t const* dev = get_device(dev_addr); - - if (dev) - { - devtree_info->rhport = dev->rhport; + if (dev) { + devtree_info->rhport = dev->rhport; devtree_info->hub_addr = dev->hub_addr; devtree_info->hub_port = dev->hub_port; - devtree_info->speed = dev->speed; - }else - { - devtree_info->rhport = _dev0.rhport; + devtree_info->speed = dev->speed; + } else { + devtree_info->rhport = _dev0.rhport; devtree_info->hub_addr = _dev0.hub_addr; devtree_info->hub_port = _dev0.hub_port; - devtree_info->speed = _dev0.speed; + devtree_info->speed = _dev0.speed; } } @@ -941,12 +918,9 @@ TU_ATTR_FAST_FUNC void hcd_event_handler(hcd_event_t const* event, bool in_isr) // generic helper to get a descriptor // if blocking, user_data is pointed to xfer_result static bool _get_descriptor(uint8_t daddr, uint8_t type, uint8_t index, uint16_t language_id, void* buffer, uint16_t len, - tuh_xfer_cb_t complete_cb, uintptr_t user_data) -{ - tusb_control_request_t const request = - { - .bmRequestType_bit = - { + tuh_xfer_cb_t complete_cb, uintptr_t user_data) { + tusb_control_request_t const request = { + .bmRequestType_bit = { .recipient = TUSB_REQ_RCPT_DEVICE, .type = TUSB_REQ_TYPE_STANDARD, .direction = TUSB_DIR_IN @@ -956,9 +930,7 @@ static bool _get_descriptor(uint8_t daddr, uint8_t type, uint8_t index, uint16_t .wIndex = tu_htole16(language_id), .wLength = tu_htole16(len) }; - - tuh_xfer_t xfer = - { + tuh_xfer_t xfer = { .daddr = daddr, .ep_addr = 0, .setup = &request, @@ -971,29 +943,25 @@ static bool _get_descriptor(uint8_t daddr, uint8_t type, uint8_t index, uint16_t } bool tuh_descriptor_get(uint8_t daddr, uint8_t type, uint8_t index, void* buffer, uint16_t len, - tuh_xfer_cb_t complete_cb, uintptr_t user_data) -{ + tuh_xfer_cb_t complete_cb, uintptr_t user_data) { return _get_descriptor(daddr, type, index, 0x0000, buffer, len, complete_cb, user_data); } bool tuh_descriptor_get_device(uint8_t daddr, void* buffer, uint16_t len, - tuh_xfer_cb_t complete_cb, uintptr_t user_data) -{ + tuh_xfer_cb_t complete_cb, uintptr_t user_data) { len = tu_min16(len, sizeof(tusb_desc_device_t)); return tuh_descriptor_get(daddr, TUSB_DESC_DEVICE, 0, buffer, len, complete_cb, user_data); } bool tuh_descriptor_get_configuration(uint8_t daddr, uint8_t index, void* buffer, uint16_t len, - tuh_xfer_cb_t complete_cb, uintptr_t user_data) -{ + tuh_xfer_cb_t complete_cb, uintptr_t user_data) { return tuh_descriptor_get(daddr, TUSB_DESC_CONFIGURATION, index, buffer, len, complete_cb, user_data); } //------------- String Descriptor -------------// bool tuh_descriptor_get_string(uint8_t daddr, uint8_t index, uint16_t language_id, void* buffer, uint16_t len, - tuh_xfer_cb_t complete_cb, uintptr_t user_data) -{ + tuh_xfer_cb_t complete_cb, uintptr_t user_data) { return _get_descriptor(daddr, TUSB_DESC_STRING, index, language_id, buffer, len, complete_cb, user_data); } @@ -1008,8 +976,7 @@ bool tuh_descriptor_get_manufacturer_string(uint8_t daddr, uint16_t language_id, // Get product string descriptor bool tuh_descriptor_get_product_string(uint8_t daddr, uint16_t language_id, void* buffer, uint16_t len, - tuh_xfer_cb_t complete_cb, uintptr_t user_data) -{ + tuh_xfer_cb_t complete_cb, uintptr_t user_data) { usbh_device_t const* dev = get_device(daddr); TU_VERIFY(dev && dev->i_product); return tuh_descriptor_get_string(daddr, dev->i_product, language_id, buffer, len, complete_cb, user_data); @@ -1017,8 +984,7 @@ bool tuh_descriptor_get_product_string(uint8_t daddr, uint16_t language_id, void // Get serial string descriptor bool tuh_descriptor_get_serial_string(uint8_t daddr, uint16_t language_id, void* buffer, uint16_t len, - tuh_xfer_cb_t complete_cb, uintptr_t user_data) -{ + tuh_xfer_cb_t complete_cb, uintptr_t user_data) { usbh_device_t const* dev = get_device(daddr); TU_VERIFY(dev && dev->i_serial); return tuh_descriptor_get_string(daddr, dev->i_serial, language_id, buffer, len, complete_cb, user_data); @@ -1027,95 +993,78 @@ bool tuh_descriptor_get_serial_string(uint8_t daddr, uint16_t language_id, void* // Get HID report descriptor // if blocking, user_data is pointed to xfer_result bool tuh_descriptor_get_hid_report(uint8_t daddr, uint8_t itf_num, uint8_t desc_type, uint8_t index, void* buffer, uint16_t len, - tuh_xfer_cb_t complete_cb, uintptr_t user_data) -{ + tuh_xfer_cb_t complete_cb, uintptr_t user_data) { TU_LOG_USBH("HID Get Report Descriptor\r\n"); - tusb_control_request_t const request = - { - .bmRequestType_bit = - { - .recipient = TUSB_REQ_RCPT_INTERFACE, - .type = TUSB_REQ_TYPE_STANDARD, - .direction = TUSB_DIR_IN - }, - .bRequest = TUSB_REQ_GET_DESCRIPTOR, - .wValue = tu_htole16(TU_U16(desc_type, index)), - .wIndex = tu_htole16((uint16_t) itf_num), - .wLength = len + tusb_control_request_t const request = { + .bmRequestType_bit = { + .recipient = TUSB_REQ_RCPT_INTERFACE, + .type = TUSB_REQ_TYPE_STANDARD, + .direction = TUSB_DIR_IN + }, + .bRequest = TUSB_REQ_GET_DESCRIPTOR, + .wValue = tu_htole16(TU_U16(desc_type, index)), + .wIndex = tu_htole16((uint16_t) itf_num), + .wLength = len }; - - tuh_xfer_t xfer = - { - .daddr = daddr, - .ep_addr = 0, - .setup = &request, - .buffer = buffer, - .complete_cb = complete_cb, - .user_data = user_data + tuh_xfer_t xfer = { + .daddr = daddr, + .ep_addr = 0, + .setup = &request, + .buffer = buffer, + .complete_cb = complete_cb, + .user_data = user_data }; return tuh_control_xfer(&xfer); } bool tuh_configuration_set(uint8_t daddr, uint8_t config_num, - tuh_xfer_cb_t complete_cb, uintptr_t user_data) -{ + tuh_xfer_cb_t complete_cb, uintptr_t user_data) { TU_LOG_USBH("Set Configuration = %d\r\n", config_num); - - tusb_control_request_t const request = - { - .bmRequestType_bit = - { - .recipient = TUSB_REQ_RCPT_DEVICE, - .type = TUSB_REQ_TYPE_STANDARD, - .direction = TUSB_DIR_OUT - }, - .bRequest = TUSB_REQ_SET_CONFIGURATION, - .wValue = tu_htole16(config_num), - .wIndex = 0, - .wLength = 0 + tusb_control_request_t const request = { + .bmRequestType_bit = { + .recipient = TUSB_REQ_RCPT_DEVICE, + .type = TUSB_REQ_TYPE_STANDARD, + .direction = TUSB_DIR_OUT + }, + .bRequest = TUSB_REQ_SET_CONFIGURATION, + .wValue = tu_htole16(config_num), + .wIndex = 0, + .wLength = 0 }; - - tuh_xfer_t xfer = - { - .daddr = daddr, - .ep_addr = 0, - .setup = &request, - .buffer = NULL, - .complete_cb = complete_cb, - .user_data = user_data + tuh_xfer_t xfer = { + .daddr = daddr, + .ep_addr = 0, + .setup = &request, + .buffer = NULL, + .complete_cb = complete_cb, + .user_data = user_data }; return tuh_control_xfer(&xfer); } bool tuh_interface_set(uint8_t daddr, uint8_t itf_num, uint8_t itf_alt, - tuh_xfer_cb_t complete_cb, uintptr_t user_data) -{ + tuh_xfer_cb_t complete_cb, uintptr_t user_data) { TU_LOG_USBH("Set Interface %u Alternate %u\r\n", itf_num, itf_alt); - - tusb_control_request_t const request = - { - .bmRequestType_bit = - { - .recipient = TUSB_REQ_RCPT_DEVICE, - .type = TUSB_REQ_TYPE_STANDARD, - .direction = TUSB_DIR_OUT - }, - .bRequest = TUSB_REQ_SET_INTERFACE, - .wValue = tu_htole16(itf_alt), - .wIndex = tu_htole16(itf_num), - .wLength = 0 + tusb_control_request_t const request = { + .bmRequestType_bit = { + .recipient = TUSB_REQ_RCPT_DEVICE, + .type = TUSB_REQ_TYPE_STANDARD, + .direction = TUSB_DIR_OUT + }, + .bRequest = TUSB_REQ_SET_INTERFACE, + .wValue = tu_htole16(itf_alt), + .wIndex = tu_htole16(itf_num), + .wLength = 0 }; - - tuh_xfer_t xfer = - { - .daddr = daddr, - .ep_addr = 0, - .setup = &request, - .buffer = NULL, - .complete_cb = complete_cb, - .user_data = user_data + tuh_xfer_t xfer = { + .daddr = daddr, + .ep_addr = 0, + .setup = &request, + .buffer = NULL, + .complete_cb = complete_cb, + .user_data = user_data }; return tuh_control_xfer(&xfer); @@ -1174,9 +1123,7 @@ uint8_t tuh_descriptor_get_serial_string_sync(uint8_t daddr, uint16_t language_i // Detaching //--------------------------------------------------------------------+ -TU_ATTR_ALWAYS_INLINE -static inline bool is_hub_addr(uint8_t daddr) -{ +TU_ATTR_ALWAYS_INLINE static inline bool is_hub_addr(uint8_t daddr) { return (CFG_TUH_HUB > 0) && (daddr > CFG_TUH_DEVICE_MAX); } @@ -1201,8 +1148,7 @@ static inline bool is_hub_addr(uint8_t daddr) //} // a device unplugged from rhport:hub_addr:hub_port -static void process_removing_device(uint8_t rhport, uint8_t hub_addr, uint8_t hub_port) -{ +static void process_removing_device(uint8_t rhport, uint8_t hub_addr, uint8_t hub_port) { //------------- find the all devices (star-network) under port that is unplugged -------------// // TODO mark as disconnected in ISR, also handle dev0 @@ -1217,8 +1163,7 @@ static void process_removing_device(uint8_t rhport, uint8_t hub_addr, uint8_t hu uint8_t nop_count = 0; #endif - for (uint8_t dev_id = 0; dev_id < TOTAL_DEVICES; dev_id++) - { + for (uint8_t dev_id = 0; dev_id < TOTAL_DEVICES; dev_id++) { usbh_device_t *dev = &_usbh_devices[dev_id]; uint8_t const daddr = dev_id + 1; @@ -1325,165 +1270,160 @@ static void process_enumeration(tuh_xfer_t* xfer) { uint8_t const daddr = xfer->daddr; uintptr_t const state = xfer->user_data; - switch(state) - { -#if CFG_TUH_HUB + switch (state) { + #if CFG_TUH_HUB //case ENUM_HUB_GET_STATUS_1: break; - case ENUM_HUB_CLEAR_RESET_1: - { + case ENUM_HUB_CLEAR_RESET_1: { hub_port_status_response_t port_status; memcpy(&port_status, _usbh_ctrl_buf, sizeof(hub_port_status_response_t)); - if ( !port_status.status.connection ) - { + if (!port_status.status.connection) { // device unplugged while delaying, nothing else to do enum_full_complete(); return; } _dev0.speed = (port_status.status.high_speed) ? TUSB_SPEED_HIGH : - (port_status.status.low_speed ) ? TUSB_SPEED_LOW : TUSB_SPEED_FULL; + (port_status.status.low_speed) ? TUSB_SPEED_LOW : TUSB_SPEED_FULL; // Acknowledge Port Reset Change - if (port_status.change.reset) - { - hub_port_clear_reset_change(_dev0.hub_addr, _dev0.hub_port, process_enumeration, ENUM_ADDR0_DEVICE_DESC); + if (port_status.change.reset) { + hub_port_clear_reset_change(_dev0.hub_addr, _dev0.hub_port, + process_enumeration, ENUM_ADDR0_DEVICE_DESC); } + break; } - break; case ENUM_HUB_GET_STATUS_2: osal_task_delay(ENUM_RESET_DELAY); - TU_ASSERT( hub_port_get_status(_dev0.hub_addr, _dev0.hub_port, _usbh_ctrl_buf, process_enumeration, ENUM_HUB_CLEAR_RESET_2), ); - break; + TU_ASSERT(hub_port_get_status(_dev0.hub_addr, _dev0.hub_port, _usbh_ctrl_buf, + process_enumeration, ENUM_HUB_CLEAR_RESET_2),); + break; - case ENUM_HUB_CLEAR_RESET_2: - { + case ENUM_HUB_CLEAR_RESET_2: { hub_port_status_response_t port_status; memcpy(&port_status, _usbh_ctrl_buf, sizeof(hub_port_status_response_t)); // Acknowledge Port Reset Change if Reset Successful - if (port_status.change.reset) - { - TU_ASSERT( hub_port_clear_reset_change(_dev0.hub_addr, _dev0.hub_port, process_enumeration, ENUM_SET_ADDR), ); + if (port_status.change.reset) { + TU_ASSERT(hub_port_clear_reset_change(_dev0.hub_addr, _dev0.hub_port, + process_enumeration, ENUM_SET_ADDR),); } + break; } - break; -#endif + #endif - case ENUM_ADDR0_DEVICE_DESC: - { + case ENUM_ADDR0_DEVICE_DESC: { // TODO probably doesn't need to open/close each enumeration uint8_t const addr0 = 0; - TU_ASSERT( usbh_edpt_control_open(addr0, 8), ); + TU_ASSERT(usbh_edpt_control_open(addr0, 8),); // Get first 8 bytes of device descriptor for Control Endpoint size TU_LOG_USBH("Get 8 byte of Device Descriptor\r\n"); - TU_ASSERT(tuh_descriptor_get_device(addr0, _usbh_ctrl_buf, 8, process_enumeration, ENUM_SET_ADDR), ); + TU_ASSERT(tuh_descriptor_get_device(addr0, _usbh_ctrl_buf, 8, + process_enumeration, ENUM_SET_ADDR),); + break; } - break; #if 0 - case ENUM_RESET_2: - // TODO not used by now, but may be needed for some devices !? - // Reset device again before Set Address - TU_LOG_USBH("Port reset2 \r\n"); - if (_dev0.hub_addr == 0) - { - // connected directly to roothub - hcd_port_reset( _dev0.rhport ); - osal_task_delay(RESET_DELAY); // TODO may not work for no-OS on MCU that require reset_end() since - // sof of controller may not running while resetting - hcd_port_reset_end(_dev0.rhport); - // TODO: fall through to SET ADDRESS, refactor later - } - #if CFG_TUH_HUB - else - { - // after RESET_DELAY the hub_port_reset() already complete - TU_ASSERT( hub_port_reset(_dev0.hub_addr, _dev0.hub_port, process_enumeration, ENUM_HUB_GET_STATUS_2), ); - break; - } - #endif - TU_ATTR_FALLTHROUGH; + case ENUM_RESET_2: + // TODO not used by now, but may be needed for some devices !? + // Reset device again before Set Address + TU_LOG_USBH("Port reset2 \r\n"); + if (_dev0.hub_addr == 0) { + // connected directly to roothub + hcd_port_reset( _dev0.rhport ); + osal_task_delay(RESET_DELAY); // TODO may not work for no-OS on MCU that require reset_end() since + // sof of controller may not running while resetting + hcd_port_reset_end(_dev0.rhport); + // TODO: fall through to SET ADDRESS, refactor later + } +#if CFG_TUH_HUB + else { + // after RESET_DELAY the hub_port_reset() already complete + TU_ASSERT( hub_port_reset(_dev0.hub_addr, _dev0.hub_port, + process_enumeration, ENUM_HUB_GET_STATUS_2), ); + break; + } +#endif + TU_ATTR_FALLTHROUGH; #endif case ENUM_SET_ADDR: enum_request_set_addr(); - break; + break; - case ENUM_GET_DEVICE_DESC: - { + case ENUM_GET_DEVICE_DESC: { uint8_t const new_addr = (uint8_t) tu_le16toh(xfer->setup->wValue); usbh_device_t* new_dev = get_device(new_addr); - TU_ASSERT(new_dev, ); + TU_ASSERT(new_dev,); new_dev->addressed = 1; // Close device 0 hcd_device_close(_dev0.rhport, 0); // open control pipe for new address - TU_ASSERT( usbh_edpt_control_open(new_addr, new_dev->ep0_size), ); + TU_ASSERT(usbh_edpt_control_open(new_addr, new_dev->ep0_size),); // Get full device descriptor TU_LOG_USBH("Get Device Descriptor\r\n"); - TU_ASSERT(tuh_descriptor_get_device(new_addr, _usbh_ctrl_buf, sizeof(tusb_desc_device_t), process_enumeration, ENUM_GET_9BYTE_CONFIG_DESC), ); + TU_ASSERT(tuh_descriptor_get_device(new_addr, _usbh_ctrl_buf, sizeof(tusb_desc_device_t), + process_enumeration, ENUM_GET_9BYTE_CONFIG_DESC),); + break; } - break; - case ENUM_GET_9BYTE_CONFIG_DESC: - { - tusb_desc_device_t const * desc_device = (tusb_desc_device_t const*) _usbh_ctrl_buf; + case ENUM_GET_9BYTE_CONFIG_DESC: { + tusb_desc_device_t const* desc_device = (tusb_desc_device_t const*) _usbh_ctrl_buf; usbh_device_t* dev = get_device(daddr); - TU_ASSERT(dev, ); + TU_ASSERT(dev,); - dev->vid = desc_device->idVendor; - dev->pid = desc_device->idProduct; + dev->vid = desc_device->idVendor; + dev->pid = desc_device->idProduct; dev->i_manufacturer = desc_device->iManufacturer; - dev->i_product = desc_device->iProduct; - dev->i_serial = desc_device->iSerialNumber; + dev->i_product = desc_device->iProduct; + dev->i_serial = desc_device->iSerialNumber; - // if (tuh_attach_cb) tuh_attach_cb((tusb_desc_device_t*) _usbh_ctrl_buf); + // if (tuh_attach_cb) tuh_attach_cb((tusb_desc_device_t*) _usbh_ctrl_buf); // Get 9-byte for total length uint8_t const config_idx = CONFIG_NUM - 1; TU_LOG_USBH("Get Configuration[0] Descriptor (9 bytes)\r\n"); - TU_ASSERT( tuh_descriptor_get_configuration(daddr, config_idx, _usbh_ctrl_buf, 9, process_enumeration, ENUM_GET_FULL_CONFIG_DESC), ); + TU_ASSERT(tuh_descriptor_get_configuration(daddr, config_idx, _usbh_ctrl_buf, 9, + process_enumeration, ENUM_GET_FULL_CONFIG_DESC),); + break; } - break; - case ENUM_GET_FULL_CONFIG_DESC: - { - uint8_t const * desc_config = _usbh_ctrl_buf; + case ENUM_GET_FULL_CONFIG_DESC: { + uint8_t const* desc_config = _usbh_ctrl_buf; // Use offsetof to avoid pointer to the odd/misaligned address - uint16_t const total_len = tu_le16toh( tu_unaligned_read16(desc_config + offsetof(tusb_desc_configuration_t, wTotalLength)) ); + uint16_t const total_len = tu_le16toh( + tu_unaligned_read16(desc_config + offsetof(tusb_desc_configuration_t, wTotalLength))); // TODO not enough buffer to hold configuration descriptor - TU_ASSERT(total_len <= CFG_TUH_ENUMERATION_BUFSIZE, ); + TU_ASSERT(total_len <= CFG_TUH_ENUMERATION_BUFSIZE,); // Get full configuration descriptor uint8_t const config_idx = CONFIG_NUM - 1; TU_LOG_USBH("Get Configuration[0] Descriptor\r\n"); - TU_ASSERT( tuh_descriptor_get_configuration(daddr, config_idx, _usbh_ctrl_buf, total_len, process_enumeration, ENUM_SET_CONFIG), ); + TU_ASSERT(tuh_descriptor_get_configuration(daddr, config_idx, _usbh_ctrl_buf, total_len, + process_enumeration, ENUM_SET_CONFIG),); + break; } - break; case ENUM_SET_CONFIG: // Parse configuration & set up drivers // Driver open aren't allowed to make any usb transfer yet - TU_ASSERT( _parse_configuration_descriptor(daddr, (tusb_desc_configuration_t*) _usbh_ctrl_buf), ); - - TU_ASSERT( tuh_configuration_set(daddr, CONFIG_NUM, process_enumeration, ENUM_CONFIG_DRIVER), ); - break; + TU_ASSERT(_parse_configuration_descriptor(daddr, (tusb_desc_configuration_t*) _usbh_ctrl_buf),); + TU_ASSERT(tuh_configuration_set(daddr, CONFIG_NUM, process_enumeration, ENUM_CONFIG_DRIVER),); + break; - case ENUM_CONFIG_DRIVER: - { + case ENUM_CONFIG_DRIVER: { TU_LOG_USBH("Device configured\r\n"); usbh_device_t* dev = get_device(daddr); - TU_ASSERT(dev, ); + TU_ASSERT(dev,); dev->configured = 1; @@ -1492,60 +1432,58 @@ static void process_enumeration(tuh_xfer_t* xfer) { // The process continue with next interface when class driver complete its sequence with usbh_driver_set_config_complete() // TODO use separated API instead of using TUSB_INDEX_INVALID_8 usbh_driver_set_config_complete(daddr, TUSB_INDEX_INVALID_8); + break; } - break; default: // stop enumeration if unknown state enum_full_complete(); - break; + break; } } -static bool enum_new_device(hcd_event_t* event) -{ - _dev0.rhport = event->rhport; +static bool enum_new_device(hcd_event_t* event) { + _dev0.rhport = event->rhport; _dev0.hub_addr = event->connection.hub_addr; _dev0.hub_port = event->connection.hub_port; - if (_dev0.hub_addr == 0) - { + if (_dev0.hub_addr == 0) { // connected/disconnected directly with roothub hcd_port_reset(_dev0.rhport); osal_task_delay(ENUM_RESET_DELAY); // TODO may not work for no-OS on MCU that require reset_end() since - // sof of controller may not running while resetting - hcd_port_reset_end( _dev0.rhport); + // sof of controller may not running while resetting + hcd_port_reset_end(_dev0.rhport); // wait until device connection is stable TODO non blocking osal_task_delay(ENUM_CONTACT_DEBOUNCING_DELAY); // device unplugged while delaying - if ( !hcd_port_connect_status(_dev0.rhport) ) { + if (!hcd_port_connect_status(_dev0.rhport)) { enum_full_complete(); return true; } - _dev0.speed = hcd_port_speed_get(_dev0.rhport ); + _dev0.speed = hcd_port_speed_get(_dev0.rhport); TU_LOG_USBH("%s Speed\r\n", tu_str_speed[_dev0.speed]); // fake transfer to kick-off the enumeration process tuh_xfer_t xfer; - xfer.daddr = 0; - xfer.result = XFER_RESULT_SUCCESS; + xfer.daddr = 0; + xfer.result = XFER_RESULT_SUCCESS; xfer.user_data = ENUM_ADDR0_DEVICE_DESC; process_enumeration(&xfer); } #if CFG_TUH_HUB - else - { + else { // connected/disconnected via external hub // wait until device connection is stable TODO non blocking osal_task_delay(ENUM_CONTACT_DEBOUNCING_DELAY); // ENUM_HUB_GET_STATUS //TU_ASSERT( hub_port_get_status(_dev0.hub_addr, _dev0.hub_port, _usbh_ctrl_buf, enum_hub_get_status0_complete, 0) ); - TU_ASSERT( hub_port_get_status(_dev0.hub_addr, _dev0.hub_port, _usbh_ctrl_buf, process_enumeration, ENUM_HUB_CLEAR_RESET_1) ); + TU_ASSERT(hub_port_get_status(_dev0.hub_addr, _dev0.hub_port, _usbh_ctrl_buf, + process_enumeration, ENUM_HUB_CLEAR_RESET_1)); } #endif // hub @@ -1571,58 +1509,48 @@ static uint8_t get_new_address(bool is_hub) { return 0; // invalid address } -static bool enum_request_set_addr(void) -{ - tusb_desc_device_t const * desc_device = (tusb_desc_device_t const*) _usbh_ctrl_buf; +static bool enum_request_set_addr(void) { + tusb_desc_device_t const* desc_device = (tusb_desc_device_t const*) _usbh_ctrl_buf; // Get new address uint8_t const new_addr = get_new_address(desc_device->bDeviceClass == TUSB_CLASS_HUB); TU_ASSERT(new_addr != 0); - TU_LOG_USBH("Set Address = %d\r\n", new_addr); usbh_device_t* new_dev = get_device(new_addr); - - new_dev->rhport = _dev0.rhport; - new_dev->hub_addr = _dev0.hub_addr; - new_dev->hub_port = _dev0.hub_port; - new_dev->speed = _dev0.speed; + new_dev->rhport = _dev0.rhport; + new_dev->hub_addr = _dev0.hub_addr; + new_dev->hub_port = _dev0.hub_port; + new_dev->speed = _dev0.speed; new_dev->connected = 1; - new_dev->ep0_size = desc_device->bMaxPacketSize0; - - tusb_control_request_t const request = - { - .bmRequestType_bit = - { - .recipient = TUSB_REQ_RCPT_DEVICE, - .type = TUSB_REQ_TYPE_STANDARD, - .direction = TUSB_DIR_OUT - }, - .bRequest = TUSB_REQ_SET_ADDRESS, - .wValue = tu_htole16(new_addr), - .wIndex = 0, - .wLength = 0 + new_dev->ep0_size = desc_device->bMaxPacketSize0; + + tusb_control_request_t const request = { + .bmRequestType_bit = { + .recipient = TUSB_REQ_RCPT_DEVICE, + .type = TUSB_REQ_TYPE_STANDARD, + .direction = TUSB_DIR_OUT + }, + .bRequest = TUSB_REQ_SET_ADDRESS, + .wValue = tu_htole16(new_addr), + .wIndex = 0, + .wLength = 0 }; - - tuh_xfer_t xfer = - { - .daddr = 0, // dev0 - .ep_addr = 0, - .setup = &request, - .buffer = NULL, - .complete_cb = process_enumeration, - .user_data = ENUM_GET_DEVICE_DESC + tuh_xfer_t xfer = { + .daddr = 0, // dev0 + .ep_addr = 0, + .setup = &request, + .buffer = NULL, + .complete_cb = process_enumeration, + .user_data = ENUM_GET_DEVICE_DESC }; - TU_ASSERT( tuh_control_xfer(&xfer) ); - + TU_ASSERT(tuh_control_xfer(&xfer)); return true; } -static bool _parse_configuration_descriptor(uint8_t dev_addr, tusb_desc_configuration_t const* desc_cfg) -{ +static bool _parse_configuration_descriptor(uint8_t dev_addr, tusb_desc_configuration_t const* desc_cfg) { usbh_device_t* dev = get_device(dev_addr); - uint16_t const total_len = tu_le16toh(desc_cfg->wTotalLength); uint8_t const* desc_end = ((uint8_t const*) desc_cfg) + total_len; uint8_t const* p_desc = tu_desc_next(desc_cfg); @@ -1630,13 +1558,11 @@ static bool _parse_configuration_descriptor(uint8_t dev_addr, tusb_desc_configur TU_LOG_USBH("Parsing Configuration descriptor (wTotalLength = %u)\r\n", total_len); // parse each interfaces - while( p_desc < desc_end ) - { + while( p_desc < desc_end ) { uint8_t assoc_itf_count = 1; // Class will always starts with Interface Association (if any) and then Interface descriptor - if ( TUSB_DESC_INTERFACE_ASSOCIATION == tu_desc_type(p_desc) ) - { + if ( TUSB_DESC_INTERFACE_ASSOCIATION == tu_desc_type(p_desc) ) { tusb_desc_interface_assoc_t const * desc_iad = (tusb_desc_interface_assoc_t const *) p_desc; assoc_itf_count = desc_iad->bInterfaceCount; @@ -1656,8 +1582,7 @@ static bool _parse_configuration_descriptor(uint8_t dev_addr, tusb_desc_configur if (1 == assoc_itf_count && TUSB_CLASS_AUDIO == desc_itf->bInterfaceClass && AUDIO_SUBCLASS_CONTROL == desc_itf->bInterfaceSubClass && - AUDIO_FUNC_PROTOCOL_CODE_UNDEF == desc_itf->bInterfaceProtocol) - { + AUDIO_FUNC_PROTOCOL_CODE_UNDEF == desc_itf->bInterfaceProtocol) { assoc_itf_count = 2; } #endif @@ -1667,8 +1592,7 @@ static bool _parse_configuration_descriptor(uint8_t dev_addr, tusb_desc_configur // manually force associated count = 2 if (1 == assoc_itf_count && TUSB_CLASS_CDC == desc_itf->bInterfaceClass && - CDC_COMM_SUBCLASS_ABSTRACT_CONTROL_MODEL == desc_itf->bInterfaceSubClass) - { + CDC_COMM_SUBCLASS_ABSTRACT_CONTROL_MODEL == desc_itf->bInterfaceSubClass) { assoc_itf_count = 2; } #endif @@ -1677,18 +1601,14 @@ static bool _parse_configuration_descriptor(uint8_t dev_addr, tusb_desc_configur TU_ASSERT(drv_len >= sizeof(tusb_desc_interface_t)); // Find driver for this interface - for (uint8_t drv_id = 0; drv_id < TOTAL_DRIVER_COUNT; drv_id++) - { + 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 && driver->open(dev->rhport, dev_addr, desc_itf, drv_len) ) - { + if (driver && driver->open(dev->rhport, dev_addr, desc_itf, drv_len) ) { // open successfully TU_LOG_USBH(" %s opened\r\n", driver->name); // bind (associated) interfaces to found driver - for(uint8_t i=0; ibInterfaceNumber+i; // Interface number must not be used already @@ -1702,8 +1622,7 @@ static bool _parse_configuration_descriptor(uint8_t dev_addr, tusb_desc_configur break; // exit driver find loop } - if ( drv_id == TOTAL_DRIVER_COUNT - 1 ) - { + if ( drv_id == TOTAL_DRIVER_COUNT - 1 ) { TU_LOG_USBH("[%u:%u] Interface %u: class = %u subclass = %u protocol = %u is not supported\r\n", dev->rhport, dev_addr, desc_itf->bInterfaceNumber, desc_itf->bInterfaceClass, desc_itf->bInterfaceSubClass, desc_itf->bInterfaceProtocol); } diff --git a/src/tusb.c b/src/tusb.c index 3ef380c83..7c86f1ca5 100644 --- a/src/tusb.c +++ b/src/tusb.c @@ -112,8 +112,7 @@ uint8_t const * tu_desc_find3(uint8_t const* desc, uint8_t const* end, uint8_t b // Endpoint Helper for both Host and Device stack //--------------------------------------------------------------------+ -bool tu_edpt_claim(tu_edpt_state_t* ep_state, osal_mutex_t mutex) -{ +bool tu_edpt_claim(tu_edpt_state_t* ep_state, osal_mutex_t mutex) { (void) mutex; // pre-check to help reducing mutex lock @@ -122,8 +121,7 @@ bool tu_edpt_claim(tu_edpt_state_t* ep_state, osal_mutex_t mutex) // can only claim the endpoint if it is not busy and not claimed yet. bool const available = (ep_state->busy == 0) && (ep_state->claimed == 0); - if (available) - { + if (available) { ep_state->claimed = 1; } @@ -132,16 +130,14 @@ bool tu_edpt_claim(tu_edpt_state_t* ep_state, osal_mutex_t mutex) return available; } -bool tu_edpt_release(tu_edpt_state_t* ep_state, osal_mutex_t mutex) -{ +bool tu_edpt_release(tu_edpt_state_t* ep_state, osal_mutex_t mutex) { (void) mutex; (void) osal_mutex_lock(mutex, OSAL_TIMEOUT_WAIT_FOREVER); // can only release the endpoint if it is claimed and not busy bool const ret = (ep_state->claimed == 1) && (ep_state->busy == 0); - if (ret) - { + if (ret) { ep_state->claimed = 0; } -- cgit v1.3.1 From 1d3969acbd1d85753c8ad085097a26dcd628afcb Mon Sep 17 00:00:00 2001 From: hathach Date: Mon, 4 Mar 2024 17:44:53 +0700 Subject: - usbh enumeration: move _parse_configuration_descriptor after SET_CONFIGURATION is successful - usbh: abort all pending xfer when SET_CONFIGURATION is complete - use tu_edpt_release in tuh_edpt_abort_xfer instead of usbh_edpt_release - rename _xfer_complete -> _control_xfer_complete --- src/host/usbh.c | 44 ++++++++++++++++++++++++++++---------------- 1 file changed, 28 insertions(+), 16 deletions(-) (limited to 'src/host') diff --git a/src/host/usbh.c b/src/host/usbh.c index 407d97234..625857683 100644 --- a/src/host/usbh.c +++ b/src/host/usbh.c @@ -621,7 +621,7 @@ TU_ATTR_ALWAYS_INLINE static inline void _set_control_xfer_stage(uint8_t stage) (void) osal_mutex_unlock(_usbh_mutex); } -static void _xfer_complete(uint8_t daddr, xfer_result_t result) { +static void _control_xfer_complete(uint8_t daddr, xfer_result_t result) { TU_LOG_USBH("\r\n"); // duplicate xfer since user can execute control transfer within callback @@ -644,32 +644,32 @@ static void _xfer_complete(uint8_t daddr, xfer_result_t result) { } } -static bool usbh_control_xfer_cb (uint8_t dev_addr, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes) { +static bool usbh_control_xfer_cb (uint8_t daddr, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes) { (void) ep_addr; - const uint8_t rhport = usbh_get_rhport(dev_addr); + const uint8_t rhport = usbh_get_rhport(daddr); tusb_control_request_t const * request = &_ctrl_xfer.request; if (XFER_RESULT_SUCCESS != result) { - TU_LOG_USBH("[%u:%u] Control %s, xferred_bytes = %lu\r\n", rhport, dev_addr, result == XFER_RESULT_STALLED ? "STALLED" : "FAILED", xferred_bytes); + TU_LOG_USBH("[%u:%u] Control %s, xferred_bytes = %lu\r\n", rhport, daddr, result == XFER_RESULT_STALLED ? "STALLED" : "FAILED", xferred_bytes); TU_LOG_BUF_USBH(request, 8); // terminate transfer if any stage failed - _xfer_complete(dev_addr, result); + _control_xfer_complete(daddr, result); }else { switch(_ctrl_xfer.stage) { case CONTROL_STAGE_SETUP: if (request->wLength) { // DATA stage: initial data toggle is always 1 _set_control_xfer_stage(CONTROL_STAGE_DATA); - TU_ASSERT( hcd_edpt_xfer(rhport, dev_addr, tu_edpt_addr(0, request->bmRequestType_bit.direction), _ctrl_xfer.buffer, request->wLength) ); + TU_ASSERT( hcd_edpt_xfer(rhport, daddr, tu_edpt_addr(0, request->bmRequestType_bit.direction), _ctrl_xfer.buffer, request->wLength) ); return true; } TU_ATTR_FALLTHROUGH; case CONTROL_STAGE_DATA: if (request->wLength) { - TU_LOG_USBH("[%u:%u] Control data:\r\n", rhport, dev_addr); + TU_LOG_USBH("[%u:%u] Control data:\r\n", rhport, daddr); TU_LOG_MEM_USBH(_ctrl_xfer.buffer, xferred_bytes, 2); } @@ -677,12 +677,23 @@ static bool usbh_control_xfer_cb (uint8_t dev_addr, uint8_t ep_addr, xfer_result // ACK stage: toggle is always 1 _set_control_xfer_stage(CONTROL_STAGE_ACK); - TU_ASSERT( hcd_edpt_xfer(rhport, dev_addr, tu_edpt_addr(0, 1-request->bmRequestType_bit.direction), NULL, 0) ); - break; + TU_ASSERT( hcd_edpt_xfer(rhport, daddr, tu_edpt_addr(0, 1 - request->bmRequestType_bit.direction), NULL, 0) ); + break; - case CONTROL_STAGE_ACK: - _xfer_complete(dev_addr, result); - break; + case CONTROL_STAGE_ACK: { + // Abort all pending transfers if SET_CONFIGURATION request + // NOTE: should we force closing all non-control endpoints in the future? + if (request->bRequest == TUSB_REQ_SET_CONFIGURATION && request->bmRequestType == 0x00) { + for(uint8_t epnum=1; epnumrhport, daddr, ep_addr)); // mark as ready and release endpoint if transfer is aborted dev->ep_status[epnum][dir].busy = false; - usbh_edpt_release(daddr, ep_addr); + tu_edpt_release(&dev->ep_status[epnum][dir], _usbh_mutex); } return true; @@ -1414,9 +1425,6 @@ static void process_enumeration(tuh_xfer_t* xfer) { } case ENUM_SET_CONFIG: - // Parse configuration & set up drivers - // Driver open aren't allowed to make any usb transfer yet - TU_ASSERT(_parse_configuration_descriptor(daddr, (tusb_desc_configuration_t*) _usbh_ctrl_buf),); TU_ASSERT(tuh_configuration_set(daddr, CONFIG_NUM, process_enumeration, ENUM_CONFIG_DRIVER),); break; @@ -1427,6 +1435,10 @@ static void process_enumeration(tuh_xfer_t* xfer) { dev->configured = 1; + // Parse configuration & set up drivers + // driver_open() must not make any usb transfer + TU_ASSERT(_parse_configuration_descriptor(daddr, (tusb_desc_configuration_t*) _usbh_ctrl_buf),); + // Start the Set Configuration process for interfaces (itf = TUSB_INDEX_INVALID_8) // Since driver can perform control transfer within its set_config, this is done asynchronously. // The process continue with next interface when class driver complete its sequence with usbh_driver_set_config_complete() -- cgit v1.3.1 From 74bd2647589790b3bee49146774133c2061a34fe Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 22 Mar 2024 11:42:33 +0700 Subject: adding deinit() stub for usbh/hcd class driver add TUSB_VERSION_BUILD, also add TUSB_VERSION_NUMBER --- src/class/cdc/cdc_host.c | 4 ++++ src/class/cdc/cdc_host.h | 1 + src/class/hid/hid_host.c | 4 ++++ src/class/hid/hid_host.h | 1 + src/class/msc/msc_host.c | 5 +++++ src/class/msc/msc_host.h | 1 + src/host/hcd.h | 3 +++ src/host/hub.c | 7 ++++-- src/host/hub.h | 1 + src/host/usbh.c | 55 ++++++++++++++++++++++++++++++++++++------------ src/host/usbh.h | 4 ++++ src/host/usbh_pvt.h | 4 +--- src/tusb_option.h | 5 +++++ 13 files changed, 76 insertions(+), 19 deletions(-) (limited to 'src/host') diff --git a/src/class/cdc/cdc_host.c b/src/class/cdc/cdc_host.c index 2fb37d835..14f380b40 100644 --- a/src/class/cdc/cdc_host.c +++ b/src/class/cdc/cdc_host.c @@ -637,6 +637,10 @@ void cdch_init(void) { } } +bool cdch_deinit(void) { + return true; +} + void cdch_close(uint8_t daddr) { for (uint8_t idx = 0; idx < CFG_TUH_CDC; idx++) { cdch_interface_t* p_cdc = &cdch_data[idx]; diff --git a/src/class/cdc/cdc_host.h b/src/class/cdc/cdc_host.h index d512a23a5..7530b1e9d 100644 --- a/src/class/cdc/cdc_host.h +++ b/src/class/cdc/cdc_host.h @@ -193,6 +193,7 @@ TU_ATTR_WEAK extern void tuh_cdc_tx_complete_cb(uint8_t idx); // Internal Class Driver API //--------------------------------------------------------------------+ void cdch_init (void); +bool cdch_deinit (void); bool cdch_open (uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const *itf_desc, uint16_t max_len); bool cdch_set_config (uint8_t dev_addr, uint8_t itf_num); bool cdch_xfer_cb (uint8_t dev_addr, uint8_t ep_addr, xfer_result_t event, uint32_t xferred_bytes); diff --git a/src/class/hid/hid_host.c b/src/class/hid/hid_host.c index 7330fa237..16e2d3c2c 100644 --- a/src/class/hid/hid_host.c +++ b/src/class/hid/hid_host.c @@ -376,6 +376,10 @@ void hidh_init(void) { tu_memclr(_hidh_itf, sizeof(_hidh_itf)); } +bool hidh_deinit(void) { + return true; +} + bool hidh_xfer_cb(uint8_t daddr, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes) { (void) result; diff --git a/src/class/hid/hid_host.h b/src/class/hid/hid_host.h index 17f4e27c0..9ea222b3d 100644 --- a/src/class/hid/hid_host.h +++ b/src/class/hid/hid_host.h @@ -164,6 +164,7 @@ TU_ATTR_WEAK void tuh_hid_set_protocol_complete_cb(uint8_t dev_addr, uint8_t idx // Internal Class Driver API //--------------------------------------------------------------------+ void hidh_init(void); +bool hidh_deinit(void); bool hidh_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const* desc_itf, uint16_t max_len); bool hidh_set_config(uint8_t dev_addr, uint8_t itf_num); bool hidh_xfer_cb(uint8_t dev_addr, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes); diff --git a/src/class/msc/msc_host.c b/src/class/msc/msc_host.c index 39f2d9f1c..61ecb8e4e 100644 --- a/src/class/msc/msc_host.c +++ b/src/class/msc/msc_host.c @@ -288,6 +288,11 @@ void msch_init(void) { tu_memclr(_msch_itf, sizeof(_msch_itf)); } +bool msch_deinit(void) { + return true; +} + + void msch_close(uint8_t dev_addr) { TU_VERIFY(dev_addr <= CFG_TUH_DEVICE_MAX,); msch_interface_t* p_msc = get_itf(dev_addr); diff --git a/src/class/msc/msc_host.h b/src/class/msc/msc_host.h index 9ca1b4703..5bf2e62e3 100644 --- a/src/class/msc/msc_host.h +++ b/src/class/msc/msc_host.h @@ -114,6 +114,7 @@ TU_ATTR_WEAK void tuh_msc_umount_cb(uint8_t dev_addr); //--------------------------------------------------------------------+ void msch_init (void); +bool msch_deinit (void); bool msch_open (uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const *desc_itf, uint16_t max_len); bool msch_set_config (uint8_t dev_addr, uint8_t itf_num); void msch_close (uint8_t dev_addr); diff --git a/src/host/hcd.h b/src/host/hcd.h index 2bde289df..d5804c608 100644 --- a/src/host/hcd.h +++ b/src/host/hcd.h @@ -130,6 +130,9 @@ bool hcd_configure(uint8_t rhport, uint32_t cfg_id, const void* cfg_param) TU_AT // Initialize controller to host mode bool hcd_init(uint8_t rhport); +// De-initialize controller +bool hcd_deinit(uint8_t rhport); + // Interrupt Handler void hcd_int_handler(uint8_t rhport, bool in_isr); diff --git a/src/host/hub.c b/src/host/hub.c index 3bac18698..0853ff27a 100644 --- a/src/host/hub.c +++ b/src/host/hub.c @@ -182,11 +182,14 @@ bool hub_port_get_status(uint8_t hub_addr, uint8_t hub_port, void* resp, //--------------------------------------------------------------------+ // CLASS-USBH API (don't require to verify parameters) //--------------------------------------------------------------------+ -void hub_init(void) -{ +void hub_init(void) { tu_memclr(hub_data, sizeof(hub_data)); } +bool hub_deinit(void) { + return true; +} + bool hub_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const *itf_desc, uint16_t max_len) { (void) rhport; diff --git a/src/host/hub.h b/src/host/hub.h index 390740e1f..c3f4a3612 100644 --- a/src/host/hub.h +++ b/src/host/hub.h @@ -205,6 +205,7 @@ static inline bool hub_port_clear_reset_change(uint8_t hub_addr, uint8_t hub_por // Internal Class Driver API //--------------------------------------------------------------------+ void hub_init (void); +bool hub_deinit (void); bool hub_open (uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const *itf_desc, uint16_t max_len); bool hub_set_config (uint8_t dev_addr, uint8_t itf_num); bool hub_xfer_cb (uint8_t dev_addr, uint8_t ep_addr, xfer_result_t event, uint32_t xferred_bytes); diff --git a/src/host/usbh.c b/src/host/usbh.c index 625857683..cf348bbb2 100644 --- a/src/host/usbh.c +++ b/src/host/usbh.c @@ -45,8 +45,13 @@ #endif //--------------------------------------------------------------------+ -// Callback weak stubs (called if application does not provide) +// Weak stubs: invoked if no strong implementation is available //--------------------------------------------------------------------+ +TU_ATTR_WEAK bool hcd_deinit(uint8_t rhport) { + (void) rhport; + return false; +} + TU_ATTR_WEAK void tuh_event_hook_cb(uint8_t rhport, uint32_t eventid, bool in_isr) { (void) rhport; (void) eventid; @@ -119,16 +124,17 @@ typedef struct { // MACRO CONSTANT TYPEDEF //--------------------------------------------------------------------+ #if CFG_TUSB_DEBUG >= CFG_TUH_LOG_LEVEL - #define DRIVER_NAME(_name) .name = _name, + #define DRIVER_NAME(_name) _name #else - #define DRIVER_NAME(_name) + #define DRIVER_NAME(_name) NULL #endif static usbh_class_driver_t const usbh_class_drivers[] = { #if CFG_TUH_CDC { - DRIVER_NAME("CDC") + .name = DRIVER_NAME("CDC"), .init = cdch_init, + .deinit = cdch_deinit, .open = cdch_open, .set_config = cdch_set_config, .xfer_cb = cdch_xfer_cb, @@ -138,8 +144,9 @@ static usbh_class_driver_t const usbh_class_drivers[] = { #if CFG_TUH_MSC { - DRIVER_NAME("MSC") + .name = DRIVER_NAME("MSC"), .init = msch_init, + .deinit = msch_deinit, .open = msch_open, .set_config = msch_set_config, .xfer_cb = msch_xfer_cb, @@ -149,8 +156,9 @@ static usbh_class_driver_t const usbh_class_drivers[] = { #if CFG_TUH_HID { - DRIVER_NAME("HID") + .name = DRIVER_NAME("HID"), .init = hidh_init, + .deinit = hidh_deinit, .open = hidh_open, .set_config = hidh_set_config, .xfer_cb = hidh_xfer_cb, @@ -160,8 +168,9 @@ static usbh_class_driver_t const usbh_class_drivers[] = { #if CFG_TUH_HUB { - DRIVER_NAME("HUB") + .name = DRIVER_NAME("HUB"), .init = hub_init, + .deinit = hub_deinit, .open = hub_open, .set_config = hub_set_config, .xfer_cb = hub_xfer_cb, @@ -171,9 +180,11 @@ static usbh_class_driver_t const usbh_class_drivers[] = { #if CFG_TUH_VENDOR { - DRIVER_NAME("VENDOR") + .name = DRIVER_NAME("VENDOR"), .init = cush_init, - .open = cush_open_subtask, + .deinit = cush_deinit, + .open = cush_open, + .set_config = cush_set_config, .xfer_cb = cush_isr, .close = cush_close } @@ -338,11 +349,11 @@ bool tuh_inited(void) { return _usbh_controller != TUSB_INDEX_INVALID_8; } -bool tuh_init(uint8_t controller_id) { +bool tuh_init(uint8_t rhport) { // skip if already initialized if ( tuh_inited() ) return true; - TU_LOG_USBH("USBH init on controller %u\r\n", controller_id); + TU_LOG_USBH("USBH init on controller %u\r\n", rhport); TU_LOG_INT_USBH(sizeof(usbh_device_t)); TU_LOG_INT_USBH(sizeof(hcd_event_t)); TU_LOG_INT_USBH(sizeof(_ctrl_xfer)); @@ -383,10 +394,26 @@ bool tuh_init(uint8_t controller_id) { } } - _usbh_controller = controller_id;; + _usbh_controller = rhport;; + + TU_ASSERT(hcd_init(rhport)); + hcd_int_enable(rhport); + + return true; +} + +bool tuh_deinit(uint8_t rhport) { + if (!tuh_rhport_is_active(rhport)) return true; + + hcd_int_disable(rhport); + hcd_deinit(rhport); - TU_ASSERT(hcd_init(controller_id)); - hcd_int_enable(controller_id); + _usbh_controller = TUSB_INDEX_INVALID_8; + + // no other controller is active, deinit the stack + if (!tuh_inited()) { + + } return true; } diff --git a/src/host/usbh.h b/src/host/usbh.h index 9ff118543..0e31e80a7 100644 --- a/src/host/usbh.h +++ b/src/host/usbh.h @@ -109,7 +109,11 @@ bool tuh_configure(uint8_t rhport, uint32_t cfg_id, const void* cfg_param); // Init host stack bool tuh_init(uint8_t rhport); +// Deinit host stack on rhport +bool tuh_deinit(uint8_t rhport); + // Check if host stack is already initialized with any roothub ports +// To check if an rhport is initialized, use tuh_rhport_is_active() bool tuh_inited(void); // Task function should be called in main/rtos loop, extended version of tuh_task() diff --git a/src/host/usbh_pvt.h b/src/host/usbh_pvt.h index 4ed2a72b5..204315175 100644 --- a/src/host/usbh_pvt.h +++ b/src/host/usbh_pvt.h @@ -50,11 +50,9 @@ enum { //--------------------------------------------------------------------+ typedef struct { - #if CFG_TUSB_DEBUG >= CFG_TUH_LOG_LEVEL char const* name; - #endif - void (* const init )(void); + bool (* const deinit )(void); bool (* const open )(uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const * itf_desc, uint16_t max_len); bool (* const set_config )(uint8_t dev_addr, uint8_t itf_num); bool (* const xfer_cb )(uint8_t dev_addr, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes); diff --git a/src/tusb_option.h b/src/tusb_option.h index 96378cb80..22f27e9e1 100644 --- a/src/tusb_option.h +++ b/src/tusb_option.h @@ -29,9 +29,14 @@ #include "common/tusb_compiler.h" +// Version is release as major.minor.revision eg 1.0.0. though there could be notable APIs before a new release. +// For notable API changes within a release, we increase the build number. #define TUSB_VERSION_MAJOR 0 #define TUSB_VERSION_MINOR 16 #define TUSB_VERSION_REVISION 0 +#define TUSB_VERSION_BUILD 1 + +#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) //--------------------------------------------------------------------+ -- cgit v1.3.1 From e84c9f3e221092687808f175e1e19732a10fea72 Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 22 Mar 2024 16:12:57 +0700 Subject: implement tuh_init() change usbh driver init() return type from void to bool --- src/class/cdc/cdc_host.c | 12 +++++-- src/class/cdc/cdc_host.h | 2 +- src/class/hid/hid_host.c | 4 ++- src/class/hid/hid_host.h | 2 +- src/class/msc/msc_host.c | 5 +-- src/class/msc/msc_host.h | 2 +- src/host/hub.c | 3 +- src/host/hub.h | 12 +++---- src/host/usbh.c | 85 ++++++++++++++++++++++++++++++------------------ src/host/usbh_pvt.h | 2 +- 10 files changed, 79 insertions(+), 50 deletions(-) (limited to 'src/host') diff --git a/src/class/cdc/cdc_host.c b/src/class/cdc/cdc_host.c index 14f380b40..5bdd41f1f 100644 --- a/src/class/cdc/cdc_host.c +++ b/src/class/cdc/cdc_host.c @@ -621,12 +621,11 @@ bool tuh_cdc_set_line_coding(uint8_t idx, cdc_line_coding_t const* line_coding, // CLASS-USBH API //--------------------------------------------------------------------+ -void cdch_init(void) { +bool cdch_init(void) { + TU_LOG_DRV("sizeof(cdch_interface_t) = %u\r\n", sizeof(cdch_interface_t)); tu_memclr(cdch_data, sizeof(cdch_data)); - for (size_t i = 0; i < CFG_TUH_CDC; i++) { cdch_interface_t* p_cdc = &cdch_data[i]; - tu_edpt_stream_init(&p_cdc->stream.tx, true, true, false, p_cdc->stream.tx_ff_buf, CFG_TUH_CDC_TX_BUFSIZE, p_cdc->stream.tx_ep_buf, CFG_TUH_CDC_TX_EPSIZE); @@ -635,9 +634,16 @@ void cdch_init(void) { p_cdc->stream.rx_ff_buf, CFG_TUH_CDC_RX_BUFSIZE, p_cdc->stream.rx_ep_buf, CFG_TUH_CDC_RX_EPSIZE); } + + return true; } bool cdch_deinit(void) { + for (size_t i = 0; i < CFG_TUH_CDC; i++) { + cdch_interface_t* p_cdc = &cdch_data[i]; + tu_edpt_stream_deinit(&p_cdc->stream.tx); + tu_edpt_stream_deinit(&p_cdc->stream.rx); + } return true; } diff --git a/src/class/cdc/cdc_host.h b/src/class/cdc/cdc_host.h index 7530b1e9d..b63dd1530 100644 --- a/src/class/cdc/cdc_host.h +++ b/src/class/cdc/cdc_host.h @@ -192,7 +192,7 @@ TU_ATTR_WEAK extern void tuh_cdc_tx_complete_cb(uint8_t idx); //--------------------------------------------------------------------+ // Internal Class Driver API //--------------------------------------------------------------------+ -void cdch_init (void); +bool cdch_init (void); bool cdch_deinit (void); bool cdch_open (uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const *itf_desc, uint16_t max_len); bool cdch_set_config (uint8_t dev_addr, uint8_t itf_num); diff --git a/src/class/hid/hid_host.c b/src/class/hid/hid_host.c index 16e2d3c2c..efc54656e 100644 --- a/src/class/hid/hid_host.c +++ b/src/class/hid/hid_host.c @@ -372,8 +372,10 @@ bool tuh_hid_send_report(uint8_t daddr, uint8_t idx, uint8_t report_id, const vo //--------------------------------------------------------------------+ // USBH API //--------------------------------------------------------------------+ -void hidh_init(void) { +bool hidh_init(void) { + TU_LOG_DRV("sizeof(hidh_interface_t) = %u\r\n", sizeof(hidh_interface_t)); tu_memclr(_hidh_itf, sizeof(_hidh_itf)); + return true; } bool hidh_deinit(void) { diff --git a/src/class/hid/hid_host.h b/src/class/hid/hid_host.h index 9ea222b3d..0902bf1af 100644 --- a/src/class/hid/hid_host.h +++ b/src/class/hid/hid_host.h @@ -163,7 +163,7 @@ TU_ATTR_WEAK void tuh_hid_set_protocol_complete_cb(uint8_t dev_addr, uint8_t idx //--------------------------------------------------------------------+ // Internal Class Driver API //--------------------------------------------------------------------+ -void hidh_init(void); +bool hidh_init(void); bool hidh_deinit(void); bool hidh_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const* desc_itf, uint16_t max_len); bool hidh_set_config(uint8_t dev_addr, uint8_t itf_num); diff --git a/src/class/msc/msc_host.c b/src/class/msc/msc_host.c index 61ecb8e4e..ce6e7fb2d 100644 --- a/src/class/msc/msc_host.c +++ b/src/class/msc/msc_host.c @@ -284,15 +284,16 @@ bool tuh_msc_reset(uint8_t dev_addr) { //--------------------------------------------------------------------+ // CLASS-USBH API //--------------------------------------------------------------------+ -void msch_init(void) { +bool msch_init(void) { + TU_LOG_DRV("sizeof(msch_interface_t) = %u\r\n", sizeof(msch_interface_t)); tu_memclr(_msch_itf, sizeof(_msch_itf)); + return true; } bool msch_deinit(void) { return true; } - void msch_close(uint8_t dev_addr) { TU_VERIFY(dev_addr <= CFG_TUH_DEVICE_MAX,); msch_interface_t* p_msc = get_itf(dev_addr); diff --git a/src/class/msc/msc_host.h b/src/class/msc/msc_host.h index 5bf2e62e3..9fda566d8 100644 --- a/src/class/msc/msc_host.h +++ b/src/class/msc/msc_host.h @@ -113,7 +113,7 @@ TU_ATTR_WEAK void tuh_msc_umount_cb(uint8_t dev_addr); // Internal Class Driver API //--------------------------------------------------------------------+ -void msch_init (void); +bool msch_init (void); bool msch_deinit (void); bool msch_open (uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const *desc_itf, uint16_t max_len); bool msch_set_config (uint8_t dev_addr, uint8_t itf_num); diff --git a/src/host/hub.c b/src/host/hub.c index 0853ff27a..e97014443 100644 --- a/src/host/hub.c +++ b/src/host/hub.c @@ -182,8 +182,9 @@ bool hub_port_get_status(uint8_t hub_addr, uint8_t hub_port, void* resp, //--------------------------------------------------------------------+ // CLASS-USBH API (don't require to verify parameters) //--------------------------------------------------------------------+ -void hub_init(void) { +bool hub_init(void) { tu_memclr(hub_data, sizeof(hub_data)); + return true; } bool hub_deinit(void) { diff --git a/src/host/hub.h b/src/host/hub.h index c3f4a3612..385efe6b2 100644 --- a/src/host/hub.h +++ b/src/host/hub.h @@ -187,16 +187,14 @@ bool hub_port_get_status (uint8_t hub_addr, uint8_t hub_port, void* resp, bool hub_edpt_status_xfer(uint8_t dev_addr); // Reset a port -static inline bool hub_port_reset(uint8_t hub_addr, uint8_t hub_port, - tuh_xfer_cb_t complete_cb, uintptr_t user_data) -{ +TU_ATTR_ALWAYS_INLINE static inline +bool hub_port_reset(uint8_t hub_addr, uint8_t hub_port, tuh_xfer_cb_t complete_cb, uintptr_t user_data) { return hub_port_set_feature(hub_addr, hub_port, HUB_FEATURE_PORT_RESET, complete_cb, user_data); } // Clear Reset Change -static inline bool hub_port_clear_reset_change(uint8_t hub_addr, uint8_t hub_port, - tuh_xfer_cb_t complete_cb, uintptr_t user_data) -{ +TU_ATTR_ALWAYS_INLINE static inline +bool hub_port_clear_reset_change(uint8_t hub_addr, uint8_t hub_port, tuh_xfer_cb_t complete_cb, uintptr_t user_data) { return hub_port_clear_feature(hub_addr, hub_port, HUB_FEATURE_PORT_RESET_CHANGE, complete_cb, user_data); } @@ -204,7 +202,7 @@ static inline bool hub_port_clear_reset_change(uint8_t hub_addr, uint8_t hub_por //--------------------------------------------------------------------+ // Internal Class Driver API //--------------------------------------------------------------------+ -void hub_init (void); +bool hub_init (void); bool hub_deinit (void); bool hub_open (uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const *itf_desc, uint16_t max_len); bool hub_set_config (uint8_t dev_addr, uint8_t itf_num); diff --git a/src/host/usbh.c b/src/host/usbh.c index cf348bbb2..1edc43fd6 100644 --- a/src/host/usbh.c +++ b/src/host/usbh.c @@ -351,51 +351,55 @@ bool tuh_inited(void) { bool tuh_init(uint8_t rhport) { // skip if already initialized - if ( tuh_inited() ) return true; + if (tuh_rhport_is_active(rhport)) return true; TU_LOG_USBH("USBH init on controller %u\r\n", rhport); - TU_LOG_INT_USBH(sizeof(usbh_device_t)); - TU_LOG_INT_USBH(sizeof(hcd_event_t)); - TU_LOG_INT_USBH(sizeof(_ctrl_xfer)); - TU_LOG_INT_USBH(sizeof(tuh_xfer_t)); - TU_LOG_INT_USBH(sizeof(tu_fifo_t)); - TU_LOG_INT_USBH(sizeof(tu_edpt_stream_t)); - // Event queue - _usbh_q = osal_queue_create( &_usbh_qdef ); - TU_ASSERT(_usbh_q != NULL); + // Init host stack if not already + if (!tuh_inited()) { + TU_LOG_INT_USBH(sizeof(usbh_device_t)); + TU_LOG_INT_USBH(sizeof(hcd_event_t)); + TU_LOG_INT_USBH(sizeof(_ctrl_xfer)); + TU_LOG_INT_USBH(sizeof(tuh_xfer_t)); + TU_LOG_INT_USBH(sizeof(tu_fifo_t)); + TU_LOG_INT_USBH(sizeof(tu_edpt_stream_t)); + + // Event queue + _usbh_q = osal_queue_create(&_usbh_qdef); + TU_ASSERT(_usbh_q != NULL); #if OSAL_MUTEX_REQUIRED - // Init mutex - _usbh_mutex = osal_mutex_create(&_usbh_mutexdef); - TU_ASSERT(_usbh_mutex); + // Init mutex + _usbh_mutex = osal_mutex_create(&_usbh_mutexdef); + TU_ASSERT(_usbh_mutex); #endif - // Get application driver if available - if ( usbh_app_driver_get_cb ) { - _app_driver = usbh_app_driver_get_cb(&_app_driver_count); - } + // Get application driver if available + if (usbh_app_driver_get_cb) { + _app_driver = usbh_app_driver_get_cb(&_app_driver_count); + } - // Device - tu_memclr(&_dev0, sizeof(_dev0)); - tu_memclr(_usbh_devices, sizeof(_usbh_devices)); - tu_memclr(&_ctrl_xfer, sizeof(_ctrl_xfer)); + // Device + tu_memclr(&_dev0, sizeof(_dev0)); + tu_memclr(_usbh_devices, sizeof(_usbh_devices)); + tu_memclr(&_ctrl_xfer, sizeof(_ctrl_xfer)); - for(uint8_t i=0; iname); - driver->init(); + // 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) { + TU_LOG_USBH("%s init\r\n", driver->name); + driver->init(); + } } } + // Init host controller _usbh_controller = rhport;; - TU_ASSERT(hcd_init(rhport)); hcd_int_enable(rhport); @@ -405,14 +409,31 @@ bool tuh_init(uint8_t rhport) { bool tuh_deinit(uint8_t rhport) { if (!tuh_rhport_is_active(rhport)) return true; + // deinit host controller hcd_int_disable(rhport); hcd_deinit(rhport); _usbh_controller = TUSB_INDEX_INVALID_8; - // no other controller is active, deinit the stack + // deinit host stack if no controller is active if (!tuh_inited()) { + // 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) { + TU_LOG_USBH("%s deinit\r\n", driver->name); + driver->deinit(); + } + } + + osal_queue_delete(_usbh_q); + _usbh_q = NULL; + #if OSAL_MUTEX_REQUIRED + // TODO make sure there is no task waiting on this mutex + osal_mutex_delete(_usbh_mutex); + _usbh_mutex = NULL; + #endif } return true; diff --git a/src/host/usbh_pvt.h b/src/host/usbh_pvt.h index 204315175..95de915e9 100644 --- a/src/host/usbh_pvt.h +++ b/src/host/usbh_pvt.h @@ -51,7 +51,7 @@ enum { typedef struct { char const* name; - void (* const init )(void); + bool (* const init )(void); bool (* const deinit )(void); bool (* const open )(uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const * itf_desc, uint16_t max_len); bool (* const set_config )(uint8_t dev_addr, uint8_t itf_num); -- cgit v1.3.1 From 0da1da942a735bcac7b48786a511a38b02519e88 Mon Sep 17 00:00:00 2001 From: hathach Date: Thu, 28 Mar 2024 16:32:02 +0700 Subject: enhance hub removal using while loop to unroll recursive instead of event queue. --- src/host/usbh.c | 117 +++++++++++++++++++++++++++----------------------------- 1 file changed, 57 insertions(+), 60 deletions(-) (limited to 'src/host') diff --git a/src/host/usbh.c b/src/host/usbh.c index 1edc43fd6..71691fad6 100644 --- a/src/host/usbh.c +++ b/src/host/usbh.c @@ -1138,43 +1138,42 @@ bool tuh_interface_set(uint8_t daddr, uint8_t itf_num, uint8_t itf_alt, TU_VERIFY(_async_func(__VA_ARGS__, NULL, (uintptr_t) &result), XFER_RESULT_TIMEOUT); \ return (uint8_t) result -uint8_t tuh_descriptor_get_sync(uint8_t daddr, uint8_t type, uint8_t index, void* buffer, uint16_t len) -{ +uint8_t tuh_descriptor_get_sync(uint8_t daddr, uint8_t type, uint8_t index, + void* buffer, uint16_t len) { _CONTROL_SYNC_API(tuh_descriptor_get, daddr, type, index, buffer, len); } -uint8_t tuh_descriptor_get_device_sync(uint8_t daddr, void* buffer, uint16_t len) -{ +uint8_t tuh_descriptor_get_device_sync(uint8_t daddr, void* buffer, uint16_t len) { _CONTROL_SYNC_API(tuh_descriptor_get_device, daddr, buffer, len); } -uint8_t tuh_descriptor_get_configuration_sync(uint8_t daddr, uint8_t index, void* buffer, uint16_t len) -{ +uint8_t tuh_descriptor_get_configuration_sync(uint8_t daddr, uint8_t index, + void* buffer, uint16_t len) { _CONTROL_SYNC_API(tuh_descriptor_get_configuration, daddr, index, buffer, len); } -uint8_t tuh_descriptor_get_hid_report_sync(uint8_t daddr, uint8_t itf_num, uint8_t desc_type, uint8_t index, void* buffer, uint16_t len) -{ +uint8_t tuh_descriptor_get_hid_report_sync(uint8_t daddr, uint8_t itf_num, uint8_t desc_type, uint8_t index, + void* buffer, uint16_t len) { _CONTROL_SYNC_API(tuh_descriptor_get_hid_report, daddr, itf_num, desc_type, index, buffer, len); } -uint8_t tuh_descriptor_get_string_sync(uint8_t daddr, uint8_t index, uint16_t language_id, void* buffer, uint16_t len) -{ +uint8_t tuh_descriptor_get_string_sync(uint8_t daddr, uint8_t index, uint16_t language_id, + void* buffer, uint16_t len) { _CONTROL_SYNC_API(tuh_descriptor_get_string, daddr, index, language_id, buffer, len); } -uint8_t tuh_descriptor_get_manufacturer_string_sync(uint8_t daddr, uint16_t language_id, void* buffer, uint16_t len) -{ +uint8_t tuh_descriptor_get_manufacturer_string_sync(uint8_t daddr, uint16_t language_id, + void* buffer, uint16_t len) { _CONTROL_SYNC_API(tuh_descriptor_get_manufacturer_string, daddr, language_id, buffer, len); } -uint8_t tuh_descriptor_get_product_string_sync(uint8_t daddr, uint16_t language_id, void* buffer, uint16_t len) -{ +uint8_t tuh_descriptor_get_product_string_sync(uint8_t daddr, uint16_t language_id, + void* buffer, uint16_t len) { _CONTROL_SYNC_API(tuh_descriptor_get_product_string, daddr, language_id, buffer, len); } -uint8_t tuh_descriptor_get_serial_string_sync(uint8_t daddr, uint16_t language_id, void* buffer, uint16_t len) -{ +uint8_t tuh_descriptor_get_serial_string_sync(uint8_t daddr, uint16_t language_id, + void* buffer, uint16_t len) { _CONTROL_SYNC_API(tuh_descriptor_get_serial_string, daddr, language_id, buffer, len); } @@ -1210,57 +1209,55 @@ TU_ATTR_ALWAYS_INLINE static inline bool is_hub_addr(uint8_t daddr) { static void process_removing_device(uint8_t rhport, uint8_t hub_addr, uint8_t hub_port) { //------------- find the all devices (star-network) under port that is unplugged -------------// // TODO mark as disconnected in ISR, also handle dev0 + uint32_t removing_hubs = 0; + do { + for (uint8_t dev_id = 0; dev_id < TOTAL_DEVICES; dev_id++) { + usbh_device_t* dev = &_usbh_devices[dev_id]; + uint8_t const daddr = dev_id + 1; + + // hub_addr = 0 means roothub, hub_port = 0 means all devices of downstream hub + if (dev->rhport == rhport && dev->connected && + (hub_addr == 0 || dev->hub_addr == hub_addr) && + (hub_port == 0 || dev->hub_port == hub_port)) { + TU_LOG_USBH("Device unplugged address = %u\r\n", daddr); + + if (is_hub_addr(daddr)) { + TU_LOG_USBH(" is a HUB device %u\r\n", daddr); + // marking this hub to run the loop on its children next (unroll recursive) + removing_hubs |= TU_BIT(dev_id - CFG_TUH_DEVICE_MAX); + } else { + // Invoke callback before closing driver (maybe call it later ?) + if (tuh_umount_cb) tuh_umount_cb(daddr); + } -#if 0 - // index as hub addr, value is hub port (0xFF for invalid) - uint8_t removing_hubs[CFG_TUH_HUB]; - memset(removing_hubs, TUSB_INDEX_INVALID_8, sizeof(removing_hubs)); - - removing_hubs[hub_addr-CFG_TUH_DEVICE_MAX] = hub_port; + // Close class driver + 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) driver->close(daddr); + } - // consecutive non-removing hub - uint8_t nop_count = 0; -#endif + hcd_device_close(rhport, daddr); + clear_device(dev); - for (uint8_t dev_id = 0; dev_id < TOTAL_DEVICES; dev_id++) { - usbh_device_t *dev = &_usbh_devices[dev_id]; - uint8_t const daddr = dev_id + 1; - - // hub_addr = 0 means roothub, hub_port = 0 means all devices of downstream hub - if (dev->rhport == rhport && dev->connected && - (hub_addr == 0 || dev->hub_addr == hub_addr) && - (hub_port == 0 || dev->hub_port == hub_port)) { - TU_LOG_USBH("Device unplugged address = %u\r\n", daddr); - - if (is_hub_addr(daddr)) { - TU_LOG_USBH(" is a HUB device %u\r\n", daddr); - - // Submit removed event If the device itself is a hub (un-rolled recursive) - // TODO a better to unroll recursrive is using array of removing_hubs and mark it here - hcd_event_t event; - event.rhport = rhport; - event.event_id = HCD_EVENT_DEVICE_REMOVE; - event.connection.hub_addr = daddr; - event.connection.hub_port = 0; - - hcd_event_handler(&event, false); - } else { - // Invoke callback before closing driver (maybe call it later ?) - if (tuh_umount_cb) tuh_umount_cb(daddr); + // abort on-going control xfer on this device if any + if (_ctrl_xfer.daddr == daddr) _set_control_xfer_stage(CONTROL_STAGE_IDLE); } + } - // Close class driver - 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 ) driver->close(daddr); - } + if (removing_hubs == 0) break; + + // find the next hub to process + for (uint8_t h_id = 0; h_id < CFG_TUH_HUB; h_id++) { + if (tu_bit_test(removing_hubs, h_id)) { + removing_hubs &= ~TU_BIT(h_id); - hcd_device_close(rhport, daddr); - clear_device(dev); - // abort on-going control xfer if any - if (_ctrl_xfer.daddr == daddr) _set_control_xfer_stage(CONTROL_STAGE_IDLE); + // update hub_addr and hub_port for next loop + hub_addr = h_id + 1 + CFG_TUH_DEVICE_MAX; + hub_port = 0; + break; + } } - } + } while(1); } //--------------------------------------------------------------------+ -- cgit v1.3.1 From 3dcb7362aa8f0e710157da4b28be44abb2c26230 Mon Sep 17 00:00:00 2001 From: hathach Date: Thu, 28 Mar 2024 19:18:20 +0700 Subject: fix build when CFG_TUH_HUB == 0 --- src/host/usbh.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) (limited to 'src/host') diff --git a/src/host/usbh.c b/src/host/usbh.c index 71691fad6..f2dc2f7c1 100644 --- a/src/host/usbh.c +++ b/src/host/usbh.c @@ -1219,11 +1219,10 @@ static void process_removing_device(uint8_t rhport, uint8_t hub_addr, uint8_t hu if (dev->rhport == rhport && dev->connected && (hub_addr == 0 || dev->hub_addr == hub_addr) && (hub_port == 0 || dev->hub_port == hub_port)) { - TU_LOG_USBH("Device unplugged address = %u\r\n", daddr); + TU_LOG_USBH("[%u:%u:%u] unplugged address = %u\r\n", rhport, hub_addr, hub_port, daddr); if (is_hub_addr(daddr)) { TU_LOG_USBH(" is a HUB device %u\r\n", daddr); - // marking this hub to run the loop on its children next (unroll recursive) removing_hubs |= TU_BIT(dev_id - CFG_TUH_DEVICE_MAX); } else { // Invoke callback before closing driver (maybe call it later ?) @@ -1244,9 +1243,11 @@ static void process_removing_device(uint8_t rhport, uint8_t hub_addr, uint8_t hu } } + // if removing a hub, we need to remove its downstream devices + #if CFG_TUH_HUB if (removing_hubs == 0) break; - // find the next hub to process + // find a marked hub to process for (uint8_t h_id = 0; h_id < CFG_TUH_HUB; h_id++) { if (tu_bit_test(removing_hubs, h_id)) { removing_hubs &= ~TU_BIT(h_id); @@ -1257,6 +1258,10 @@ static void process_removing_device(uint8_t rhport, uint8_t hub_addr, uint8_t hu break; } } + #else + (void) removing_hubs; + break; + #endif } while(1); } -- cgit v1.3.1 From d50003e33d89740c0993ae236629392df82453c2 Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Wed, 27 Mar 2024 11:21:13 -0700 Subject: Fake unplug devices when a root hub is deinit --- src/host/usbh.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'src/host') diff --git a/src/host/usbh.c b/src/host/usbh.c index f2dc2f7c1..29c6eb1e9 100644 --- a/src/host/usbh.c +++ b/src/host/usbh.c @@ -415,6 +415,15 @@ bool tuh_deinit(uint8_t rhport) { _usbh_controller = TUSB_INDEX_INVALID_8; + // "unplug" all devices on this rhport + for (uint8_t idx = 0; idx < CFG_TUH_DEVICE_MAX + CFG_TUH_HUB; idx++) { + usbh_device_t *dev = &_usbh_devices[idx]; + if (!dev->connected || dev->rhport != rhport) { + continue; + } + process_removing_device(rhport, dev->hub_addr, dev->hub_port); + } + // deinit host stack if no controller is active if (!tuh_inited()) { // Class drivers -- cgit v1.3.1 From ddb1034a9c77d8ef4efccf3df76013f86efe5e09 Mon Sep 17 00:00:00 2001 From: hathach Date: Thu, 28 Mar 2024 21:45:52 +0700 Subject: use hub_addr=0, hub_port=0 for removing root hub port --- src/host/usbh.c | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) (limited to 'src/host') diff --git a/src/host/usbh.c b/src/host/usbh.c index 29c6eb1e9..05091736e 100644 --- a/src/host/usbh.c +++ b/src/host/usbh.c @@ -412,17 +412,10 @@ bool tuh_deinit(uint8_t rhport) { // deinit host controller hcd_int_disable(rhport); hcd_deinit(rhport); - _usbh_controller = TUSB_INDEX_INVALID_8; - // "unplug" all devices on this rhport - for (uint8_t idx = 0; idx < CFG_TUH_DEVICE_MAX + CFG_TUH_HUB; idx++) { - usbh_device_t *dev = &_usbh_devices[idx]; - if (!dev->connected || dev->rhport != rhport) { - continue; - } - process_removing_device(rhport, dev->hub_addr, dev->hub_port); - } + // "unplug" all devices on this rhport (hub_addr = 0, hub_port = 0) + process_removing_device(rhport, 0, 0); // deinit host stack if no controller is active if (!tuh_inited()) { -- cgit v1.3.1 From 7d3d60f96de3f6e15291c9302463c294e2dc98de Mon Sep 17 00:00:00 2001 From: hathach Date: Tue, 2 Apr 2024 16:38:40 +0700 Subject: add hcd_configure() to change max NAK dynamically --- src/host/hcd.h | 2 +- src/host/usbh.c | 13 ++++++++----- src/host/usbh.h | 14 ++++++++++++-- src/portable/analog/max3421/hcd_max3421.c | 17 +++++++++++------ src/tusb_option.h | 1 - 5 files changed, 32 insertions(+), 15 deletions(-) (limited to 'src/host') diff --git a/src/host/hcd.h b/src/host/hcd.h index d5804c608..5547c7cc5 100644 --- a/src/host/hcd.h +++ b/src/host/hcd.h @@ -125,7 +125,7 @@ bool hcd_dcache_clean_invalidate(void const* addr, uint32_t data_size) TU_ATTR_W //--------------------------------------------------------------------+ // optional hcd configuration, called by tuh_configure() -bool hcd_configure(uint8_t rhport, uint32_t cfg_id, const void* cfg_param) TU_ATTR_WEAK; +bool hcd_configure(uint8_t rhport, uint32_t cfg_id, const void* cfg_param); // Initialize controller to host mode bool hcd_init(uint8_t rhport); diff --git a/src/host/usbh.c b/src/host/usbh.c index 05091736e..aa0603d47 100644 --- a/src/host/usbh.c +++ b/src/host/usbh.c @@ -52,6 +52,13 @@ TU_ATTR_WEAK bool hcd_deinit(uint8_t rhport) { return false; } +TU_ATTR_WEAK bool hcd_configure(uint8_t rhport, uint32_t cfg_id, const void* cfg_param) { + (void) rhport; + (void) cfg_id; + (void) cfg_param; + return false; +} + TU_ATTR_WEAK void tuh_event_hook_cb(uint8_t rhport, uint32_t eventid, bool in_isr) { (void) rhport; (void) eventid; @@ -332,11 +339,7 @@ bool tuh_rhport_reset_bus(uint8_t rhport, bool active) { //--------------------------------------------------------------------+ bool tuh_configure(uint8_t rhport, uint32_t cfg_id, const void *cfg_param) { - if ( hcd_configure ) { - return hcd_configure(rhport, cfg_id, cfg_param); - } else { - return false; - } + return hcd_configure(rhport, cfg_id, cfg_param); } static void clear_device(usbh_device_t* dev) { diff --git a/src/host/usbh.h b/src/host/usbh.h index 0e31e80a7..57362c778 100644 --- a/src/host/usbh.h +++ b/src/host/usbh.h @@ -73,11 +73,21 @@ typedef struct { tusb_desc_interface_t desc; } tuh_itf_info_t; -// ConfigID for tuh_config() +// ConfigID for tuh_configure() enum { - TUH_CFGID_RPI_PIO_USB_CONFIGURATION = OPT_MCU_RP2040 << 8 // cfg_param: pio_usb_configuration_t + TUH_CFGID_INVALID = 0, + TUH_CFGID_RPI_PIO_USB_CONFIGURATION = 100, // cfg_param: pio_usb_configuration_t + TUH_CFGID_MAX3421 = 200, }; +typedef union { + // For TUH_CFGID_RPI_PIO_USB_CONFIGURATION use pio_usb_configuration_t + + struct { + uint8_t max_nak; + } max3421; +} tuh_configure_param_t; + //--------------------------------------------------------------------+ // APPLICATION CALLBACK //--------------------------------------------------------------------+ diff --git a/src/portable/analog/max3421/hcd_max3421.c b/src/portable/analog/max3421/hcd_max3421.c index 1b182e551..12d80e0b5 100644 --- a/src/portable/analog/max3421/hcd_max3421.c +++ b/src/portable/analog/max3421/hcd_max3421.c @@ -30,6 +30,7 @@ #include #include "host/hcd.h" +#include "host/usbh.h" //--------------------------------------------------------------------+ // @@ -230,7 +231,9 @@ typedef struct { } max3421_data_t; static max3421_data_t _hcd_data; -static uint8_t _max_nak = MAX_NAK_DEFAULT; // max NAK before giving up in a usb frame + +// max NAK before giving up in a frame. 0 means infinite NAKs +static uint8_t _max_nak = MAX_NAK_DEFAULT; //--------------------------------------------------------------------+ // API: SPI transfer with MAX3421E @@ -409,10 +412,11 @@ static void free_ep(uint8_t daddr) { } } -// Check if endpoint has an queued transfer +// Check if endpoint has an queued transfer and not reach max NAK TU_ATTR_ALWAYS_INLINE static inline bool is_ep_pending(max3421_ep_t const * ep) { uint8_t const state = ep->state; - return ep->packet_size && state >= EP_STATE_ATTEMPT_1 && state < EP_STATE_ATTEMPT_1 + _max_nak; + return ep->packet_size && (state >= EP_STATE_ATTEMPT_1) && + (_max_nak == 0 || state < EP_STATE_ATTEMPT_1 + _max_nak); } // Find the next pending endpoint using round-robin scheduling, starting from next endpoint. @@ -447,10 +451,11 @@ static max3421_ep_t * find_next_pending_ep(max3421_ep_t * cur_ep) { // optional hcd configuration, called by tuh_configure() bool hcd_configure(uint8_t rhport, uint32_t cfg_id, const void* cfg_param) { (void) rhport; - (void) cfg_id; - (void) cfg_param; + TU_VERIFY(cfg_id == TUH_CFGID_MAX3421); - return false; + tuh_configure_param_t const* cfg = (tuh_configure_param_t const*) cfg_param; + _max_nak = cfg->max3421.max_nak; + return true; } // Initialize controller to host mode diff --git a/src/tusb_option.h b/src/tusb_option.h index f90fb7026..812074c44 100644 --- a/src/tusb_option.h +++ b/src/tusb_option.h @@ -144,7 +144,6 @@ #define OPT_MCU_RX72N 1402 ///< Renesas RX72N #define OPT_MCU_RAXXX 1403 ///< Renesas RAxxx families - // Mind Motion #define OPT_MCU_MM32F327X 1500 ///< Mind Motion MM32F327 -- cgit v1.3.1 From cbbfbbb57ea8b4ea97ce4f2e2d157da9c25019fe Mon Sep 17 00:00:00 2001 From: hathach Date: Mon, 8 Apr 2024 13:16:08 +0700 Subject: add cpuctl and pinctl to tuh_configure() option for max3421 --- .github/workflows/build_iar.yml | 1 + src/host/usbh.h | 10 +++++++--- src/portable/analog/max3421/hcd_max3421.c | 18 +++++++++++------- 3 files changed, 19 insertions(+), 10 deletions(-) (limited to 'src/host') diff --git a/.github/workflows/build_iar.yml b/.github/workflows/build_iar.yml index a0a022ecc..499349904 100644 --- a/.github/workflows/build_iar.yml +++ b/.github/workflows/build_iar.yml @@ -28,6 +28,7 @@ concurrency: jobs: cmake: + if: github.repository_owner == 'hathach' runs-on: [self-hosted, Linux, X64, hifiphile] strategy: fail-fast: false diff --git a/src/host/usbh.h b/src/host/usbh.h index 57362c778..359684169 100644 --- a/src/host/usbh.h +++ b/src/host/usbh.h @@ -80,12 +80,16 @@ enum { TUH_CFGID_MAX3421 = 200, }; +typedef struct { + uint8_t max_nak; // max NAK per endpoint per frame + uint8_t cpuctl; // R16: CPU Control Register + uint8_t pinctl; // R17: Pin Control Register. FDUPSPI bit is ignored +} tuh_configure_max3421_t; + typedef union { // For TUH_CFGID_RPI_PIO_USB_CONFIGURATION use pio_usb_configuration_t - struct { - uint8_t max_nak; - } max3421; + tuh_configure_max3421_t max3421; } tuh_configure_param_t; //--------------------------------------------------------------------+ diff --git a/src/portable/analog/max3421/hcd_max3421.c b/src/portable/analog/max3421/hcd_max3421.c index 059f674cd..39afb7505 100644 --- a/src/portable/analog/max3421/hcd_max3421.c +++ b/src/portable/analog/max3421/hcd_max3421.c @@ -233,7 +233,11 @@ typedef struct { static max3421_data_t _hcd_data; // max NAK before giving up in a frame. 0 means infinite NAKs -static uint8_t _max_nak = MAX_NAK_DEFAULT; +static tuh_configure_max3421_t _tuh_cfg = { + .max_nak = MAX_NAK_DEFAULT, + .cpuctl = 0, // default: INT pulse width = 10.6 us + .pinctl = 0, // default: negative edge interrupt +}; //--------------------------------------------------------------------+ // API: SPI transfer with MAX3421E @@ -416,7 +420,7 @@ static void free_ep(uint8_t daddr) { TU_ATTR_ALWAYS_INLINE static inline bool is_ep_pending(max3421_ep_t const * ep) { uint8_t const state = ep->state; return ep->packet_size && (state >= EP_STATE_ATTEMPT_1) && - (_max_nak == 0 || state < EP_STATE_ATTEMPT_1 + _max_nak); + (_tuh_cfg.max_nak == 0 || state < EP_STATE_ATTEMPT_1 + _tuh_cfg.max_nak); } // Find the next pending endpoint using round-robin scheduling, starting from next endpoint. @@ -454,7 +458,7 @@ bool hcd_configure(uint8_t rhport, uint32_t cfg_id, const void* cfg_param) { TU_VERIFY(cfg_id == TUH_CFGID_MAX3421 && cfg_param != NULL); tuh_configure_param_t const* cfg = (tuh_configure_param_t const*) cfg_param; - _max_nak = tu_min8(cfg->max3421.max_nak, EP_STATE_ATTEMPT_MAX-EP_STATE_ATTEMPT_1); + _tuh_cfg = cfg->max3421; return true; } @@ -476,7 +480,7 @@ bool hcd_init(uint8_t rhport) { #endif // full duplex, interrupt negative edge - reg_write(rhport, PINCTL_ADDR, PINCTL_FDUPSPI, false); + reg_write(rhport, PINCTL_ADDR, _tuh_cfg.pinctl | PINCTL_FDUPSPI, false); // v1 is 0x01, v2 is 0x12, v3 is 0x13 uint8_t const revision = reg_read(rhport, REVISION_ADDR, false); @@ -505,7 +509,7 @@ bool hcd_init(uint8_t rhport) { tuh_max3421_int_api(rhport, true); // Enable Interrupt pin - reg_write(rhport, CPUCTL_ADDR, CPUCTL_IE, false); + reg_write(rhport, CPUCTL_ADDR, _tuh_cfg.cpuctl | CPUCTL_IE, false); return true; } @@ -516,9 +520,9 @@ bool hcd_deinit(uint8_t rhport) { // disable interrupt tuh_max3421_int_api(rhport, false); - // reset max3421 + // reset max3421 and power down reg_write(rhport, USBCTL_ADDR, USBCTL_CHIPRES, false); - reg_write(rhport, USBCTL_ADDR, 0, false); + reg_write(rhport, USBCTL_ADDR, USBCTL_PWRDOWN, false); #if OSAL_MUTEX_REQUIRED osal_mutex_delete(_hcd_data.spi_mutex); -- cgit v1.3.1 From c3c06484560d0102366a3a1b1101c35301009f97 Mon Sep 17 00:00:00 2001 From: hathach Date: Mon, 8 Apr 2024 22:07:56 +0700 Subject: add class driver deinit --- src/class/audio/audio_device.c | 4 + src/class/audio/audio_device.h | 1 + src/class/bth/bth_device.c | 7 +- src/class/bth/bth_device.h | 1 + src/class/cdc/cdc_device.c | 32 ++++- src/class/cdc/cdc_device.h | 1 + src/class/dfu/dfu_device.c | 7 +- src/class/dfu/dfu_device.h | 1 + src/class/dfu/dfu_rt_device.c | 7 +- src/class/dfu/dfu_rt_device.h | 1 + src/class/hid/hid_device.c | 7 +- src/class/hid/hid_device.h | 1 + src/class/midi/midi_device.c | 36 ++++- src/class/midi/midi_device.h | 1 + src/class/msc/msc_device.c | 8 +- src/class/msc/msc_device.h | 1 + src/class/net/ecm_rndis_device.c | 7 +- src/class/net/ncm_device.c | 4 + src/class/net/net_device.h | 1 + src/class/usbtmc/usbtmc_device.c | 5 + src/class/usbtmc/usbtmc_device.h | 3 +- src/class/vendor/vendor_device.c | 38 ++++- src/class/vendor/vendor_device.h | 1 + src/class/video/video_device.c | 4 + src/class/video/video_device.h | 1 + src/device/dcd.h | 2 +- src/device/usbd.c | 204 +++++++++++++++++---------- src/device/usbd.h | 2 +- src/device/usbd_pvt.h | 4 +- src/host/usbh.c | 2 +- src/portable/raspberrypi/rp2040/dcd_rp2040.c | 5 +- src/portable/raspberrypi/rp2040/hcd_rp2040.c | 4 +- src/tusb_option.h | 2 +- 33 files changed, 292 insertions(+), 113 deletions(-) (limited to 'src/host') diff --git a/src/class/audio/audio_device.c b/src/class/audio/audio_device.c index 9a361419b..7077d66f8 100644 --- a/src/class/audio/audio_device.c +++ b/src/class/audio/audio_device.c @@ -1396,6 +1396,10 @@ void audiod_init(void) } } +bool audiod_deinit(void) { + return false; // TODO not implemented yet +} + void audiod_reset(uint8_t rhport) { (void) rhport; diff --git a/src/class/audio/audio_device.h b/src/class/audio/audio_device.h index 040a760d6..b16514fd4 100644 --- a/src/class/audio/audio_device.h +++ b/src/class/audio/audio_device.h @@ -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); diff --git a/src/class/bth/bth_device.c b/src/class/bth/bth_device.c index f145e2ead..cbf6e1332 100755 --- a/src/class/bth/bth_device.c +++ b/src/class/bth/bth_device.c @@ -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; diff --git a/src/class/bth/bth_device.h b/src/class/bth/bth_device.h index e782c532b..4f6350839 100755 --- a/src/class/bth/bth_device.h +++ b/src/class/bth/bth_device.h @@ -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); diff --git a/src/class/cdc/cdc_device.c b/src/class/cdc/cdc_device.c index c26264e60..7ef0530ec 100644 --- a/src/class/cdc/cdc_device.c +++ b/src/class/cdc/cdc_device.c @@ -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; irx_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; diff --git a/src/class/cdc/cdc_device.h b/src/class/cdc/cdc_device.h index a6e07aa5c..20e908451 100644 --- a/src/class/cdc/cdc_device.h +++ b/src/class/cdc/cdc_device.h @@ -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); diff --git a/src/class/dfu/dfu_device.c b/src/class/dfu/dfu_device.c index 3e7c13dea..71e7ac2b3 100644 --- a/src/class/dfu/dfu_device.c +++ b/src/class/dfu/dfu_device.c @@ -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; diff --git a/src/class/dfu/dfu_device.h b/src/class/dfu/dfu_device.h index fecf8596f..00c22ea8b 100644 --- a/src/class/dfu/dfu_device.h +++ b/src/class/dfu/dfu_device.h @@ -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); diff --git a/src/class/dfu/dfu_rt_device.c b/src/class/dfu/dfu_rt_device.c index a940d8d62..3b801b787 100644 --- a/src/class/dfu/dfu_rt_device.c +++ b/src/class/dfu/dfu_rt_device.c @@ -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) diff --git a/src/class/dfu/dfu_rt_device.h b/src/class/dfu/dfu_rt_device.h index babaa8214..67eb26d95 100644 --- a/src/class/dfu/dfu_rt_device.h +++ b/src/class/dfu/dfu_rt_device.h @@ -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); diff --git a/src/class/hid/hid_device.c b/src/class/hid/hid_device.c index 5637ea6b4..e8eda1400 100644 --- a/src/class/hid/hid_device.c +++ b/src/class/hid/hid_device.c @@ -166,11 +166,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; diff --git a/src/class/hid/hid_device.h b/src/class/hid/hid_device.h index 17b24def1..53ecf9c06 100644 --- a/src/class/hid/hid_device.h +++ b/src/class/hid/hid_device.h @@ -406,6 +406,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); diff --git a/src/class/midi/midi_device.c b/src/class/midi/midi_device.c index 052372a93..42905ab0d 100644 --- a/src/class/midi/midi_device.c +++ b/src/class/midi/midi_device.c @@ -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; itx_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; irx_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; diff --git a/src/class/midi/midi_device.h b/src/class/midi/midi_device.h index 1c6f996be..3e89cc0a3 100644 --- a/src/class/midi/midi_device.h +++ b/src/class/midi/midi_device.h @@ -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); diff --git a/src/class/msc/msc_device.c b/src/class/msc/msc_device.c index c145d86a6..588fcaaca 100644 --- a/src/class/msc/msc_device.c +++ b/src/class/msc/msc_device.c @@ -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; diff --git a/src/class/msc/msc_device.h b/src/class/msc/msc_device.h index 72f95be06..4247a40bd 100644 --- a/src/class/msc/msc_device.h +++ b/src/class/msc/msc_device.h @@ -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); diff --git a/src/class/net/ecm_rndis_device.c b/src/class/net/ecm_rndis_device.c index 762425732..f7a5fd225 100644 --- a/src/class/net/ecm_rndis_device.c +++ b/src/class/net/ecm_rndis_device.c @@ -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; diff --git a/src/class/net/ncm_device.c b/src/class/net/ncm_device.c index 226c42c4e..f84bd9f73 100644 --- a/src/class/net/ncm_device.c +++ b/src/class/net/ncm_device.c @@ -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; diff --git a/src/class/net/net_device.h b/src/class/net/net_device.h index 399916355..da1a7b1e8 100644 --- a/src/class/net/net_device.h +++ b/src/class/net/net_device.h @@ -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); diff --git a/src/class/usbtmc/usbtmc_device.c b/src/class/usbtmc/usbtmc_device.c index 573654d58..972a450e6 100644 --- a/src/class/usbtmc/usbtmc_device.c +++ b/src/class/usbtmc/usbtmc_device.c @@ -260,6 +260,11 @@ void usbtmcd_init_cb(void) usbtmcLock = osal_mutex_create(&usbtmcLockBuffer); } +bool usbtmcd_deinit(void) { + osal_mutex_delete(usbtmcLock); + return true; +} + uint16_t usbtmcd_open_cb(uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint16_t max_len) { (void)rhport; diff --git a/src/class/usbtmc/usbtmc_device.h b/src/class/usbtmc/usbtmc_device.h index c1298ddb8..3299a36eb 100644 --- a/src/class/usbtmc/usbtmc_device.h +++ b/src/class/usbtmc/usbtmc_device.h @@ -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 diff --git a/src/class/vendor/vendor_device.c b/src/class/vendor/vendor_device.c index a68cb2156..e87ce3997 100644 --- a/src/class/vendor/vendor_device.c +++ b/src/class/vendor/vendor_device.c @@ -169,21 +169,47 @@ 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; irx_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; irx_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) diff --git a/src/class/vendor/vendor_device.h b/src/class/vendor/vendor_device.h index d239406b4..cd69ec7c6 100644 --- a/src/class/vendor/vendor_device.h +++ b/src/class/vendor/vendor_device.h @@ -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); diff --git a/src/class/video/video_device.c b/src/class/video/video_device.c index 5306356ba..c30690232 100644 --- a/src/class/video/video_device.c +++ b/src/class/video/video_device.c @@ -1229,6 +1229,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) { diff --git a/src/class/video/video_device.h b/src/class/video/video_device.h index ee2fcb9d5..92930c013 100644 --- a/src/class/video/video_device.h +++ b/src/class/video/video_device.h @@ -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); diff --git a/src/device/dcd.h b/src/device/dcd.h index 21f404e4f..d4f105aa3 100644 --- a/src/device/dcd.h +++ b/src/device/dcd.h @@ -123,7 +123,7 @@ void dcd_dcache_clean_invalidate(void const* addr, uint32_t data_size) TU_ATTR_W void dcd_init(uint8_t rhport); // Deinitialize controller, unset device mode. -void dcd_deinit(uint8_t rhport); +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..439e071ff 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; @@ -85,17 +90,18 @@ tu_static usbd_device_t _usbd_dev; // Class Driver //--------------------------------------------------------------------+ #if CFG_TUSB_DEBUG >= CFG_TUD_LOG_LEVEL - #define DRIVER_NAME(_name) .name = _name, + #define DRIVER_NAME(_name) _name #else - #define DRIVER_NAME(_name) + #define DRIVER_NAME(_name) NULL #endif // Built-in class drivers tu_static usbd_class_driver_t const _usbd_driver[] = { #if CFG_TUD_CDC { - DRIVER_NAME("CDC") + .name = DRIVER_NAME("CDC"), .init = cdcd_init, + .deinit = cdcd_deinit, .reset = cdcd_reset, .open = cdcd_open, .control_xfer_cb = cdcd_control_xfer_cb, @@ -106,8 +112,9 @@ tu_static usbd_class_driver_t const _usbd_driver[] = { #if CFG_TUD_MSC { - DRIVER_NAME("MSC") + .name = 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 + .name = 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 + .name = 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 + .name = 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 + .name = 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 + .name = 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 + .name = 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 + .name = 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 + .name = 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, + .name = 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 + .name = 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 a9350192b..0197628e2 100644 --- a/src/device/usbd.h +++ b/src/device/usbd.h @@ -41,7 +41,7 @@ extern "C" { bool tud_init (uint8_t rhport); // Deinit device stack on roothub port -void tud_deinit(uint8_t rhport); +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..5ae96e589 100644 --- a/src/device/usbd_pvt.h +++ b/src/device/usbd_pvt.h @@ -40,11 +40,9 @@ //--------------------------------------------------------------------+ typedef struct { - #if CFG_TUSB_DEBUG >= CFG_TUD_LOG_LEVEL char const* name; - #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); diff --git a/src/host/usbh.c b/src/host/usbh.c index aa0603d47..6a5491998 100644 --- a/src/host/usbh.c +++ b/src/host/usbh.c @@ -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(); } diff --git a/src/portable/raspberrypi/rp2040/dcd_rp2040.c b/src/portable/raspberrypi/rp2040/dcd_rp2040.c index ccc7ee102..a2b3375a3 100644 --- a/src/portable/raspberrypi/rp2040/dcd_rp2040.c +++ b/src/portable/raspberrypi/rp2040/dcd_rp2040.c @@ -407,16 +407,17 @@ void dcd_init(uint8_t rhport) { dcd_connect(rhport); } -void dcd_deinit(uint8_t rhport) { +bool dcd_deinit(uint8_t rhport) { assert(rhport == 0); - dcd_disconnect(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) { diff --git a/src/portable/raspberrypi/rp2040/hcd_rp2040.c b/src/portable/raspberrypi/rp2040/hcd_rp2040.c index 762753a25..222dbbbf0 100644 --- a/src/portable/raspberrypi/rp2040/hcd_rp2040.c +++ b/src/portable/raspberrypi/rp2040/hcd_rp2040.c @@ -409,12 +409,14 @@ bool hcd_init(uint8_t rhport) return true; } -void hcd_deinit(uint8_t rhport) { +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) diff --git a/src/tusb_option.h b/src/tusb_option.h index 2921d3ae0..cbcb69edd 100644 --- a/src/tusb_option.h +++ b/src/tusb_option.h @@ -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) -- cgit v1.3.1 From 189080b684b298e0b3e7df6528f24a43c646ab8c Mon Sep 17 00:00:00 2001 From: hathach Date: Tue, 16 Apr 2024 10:40:24 +0700 Subject: add TU_ASSERT() to check for adding new usb event --- src/device/usbd.c | 4 ++-- src/host/usbh.c | 4 ++-- src/osal/osal_none.h | 1 - src/osal/osal_pico.h | 1 - 4 files changed, 4 insertions(+), 6 deletions(-) (limited to 'src/host') diff --git a/src/device/usbd.c b/src/device/usbd.c index 96982c30b..76b7b3ee5 100644 --- a/src/device/usbd.c +++ b/src/device/usbd.c @@ -296,9 +296,9 @@ tu_static osal_queue_t _usbd_q; #endif TU_ATTR_ALWAYS_INLINE static inline bool queue_event(dcd_event_t const * event, bool in_isr) { - bool ret = osal_queue_send(_usbd_q, event, in_isr); + TU_ASSERT(osal_queue_send(_usbd_q, event, in_isr)); tud_event_hook_cb(event->rhport, event->event_id, in_isr); - return ret; + return true; } //--------------------------------------------------------------------+ diff --git a/src/host/usbh.c b/src/host/usbh.c index 6a5491998..f8fddf394 100644 --- a/src/host/usbh.c +++ b/src/host/usbh.c @@ -288,9 +288,9 @@ TU_ATTR_WEAK void osal_task_delay(uint32_t msec) { #endif TU_ATTR_ALWAYS_INLINE static inline bool queue_event(hcd_event_t const * event, bool in_isr) { - bool ret = osal_queue_send(_usbh_q, event, in_isr); + TU_ASSERT(osal_queue_send(_usbh_q, event, in_isr)); tuh_event_hook_cb(event->rhport, event->event_id, in_isr); - return ret; + return true; } //--------------------------------------------------------------------+ diff --git a/src/osal/osal_none.h b/src/osal/osal_none.h index c954fcfe8..c93f7a86c 100644 --- a/src/osal/osal_none.h +++ b/src/osal/osal_none.h @@ -180,7 +180,6 @@ TU_ATTR_ALWAYS_INLINE static inline bool osal_queue_send(osal_queue_t qhdl, void _osal_q_unlock(qhdl); } - TU_ASSERT(success); return success; } diff --git a/src/osal/osal_pico.h b/src/osal/osal_pico.h index 00c589ef9..315de0950 100644 --- a/src/osal/osal_pico.h +++ b/src/osal/osal_pico.h @@ -145,7 +145,6 @@ TU_ATTR_ALWAYS_INLINE static inline bool osal_queue_send(osal_queue_t qhdl, void bool success = tu_fifo_write(&qhdl->ff, data); critical_section_exit(&qhdl->critsec); - TU_ASSERT(success); return success; } -- cgit v1.3.1 From 62331f02070bdb1bec2890885008e9f88b06bdb6 Mon Sep 17 00:00:00 2001 From: hathach Date: Mon, 22 Apr 2024 15:55:50 +0700 Subject: fix nrfx v3 spim freq when init fix clang build with nrf --- examples/host/cdc_msc_hid/src/msc_app.c | 4 ++-- hw/bsp/nrf/boards/pca10059/pca10059.ld | 8 +++++++- hw/bsp/nrf/boards/pca10095/board.cmake | 1 - hw/bsp/nrf/boards/pca10100/board.cmake | 1 - hw/bsp/nrf/boards/raytac_mdbt50q_rx/board.cmake | 1 - hw/bsp/nrf/family.c | 6 ++++-- hw/bsp/nrf/family.cmake | 18 +++++++++--------- hw/bsp/nrf/linker/nrf52833_xxaa.ld | 20 ++++++++++++++++++++ hw/bsp/nrf/linker/nrf5340_xxaa_application.ld | 21 +++++++++++++++++++++ src/class/cdc/cdc_host.c | 4 ++-- src/host/usbh.c | 2 +- 11 files changed, 66 insertions(+), 20 deletions(-) create mode 100644 hw/bsp/nrf/linker/nrf52833_xxaa.ld create mode 100644 hw/bsp/nrf/linker/nrf5340_xxaa_application.ld (limited to 'src/host') diff --git a/examples/host/cdc_msc_hid/src/msc_app.c b/examples/host/cdc_msc_hid/src/msc_app.c index e9c9676b8..1d7e18e6e 100644 --- a/examples/host/cdc_msc_hid/src/msc_app.c +++ b/examples/host/cdc_msc_hid/src/msc_app.c @@ -48,8 +48,8 @@ bool inquiry_complete_cb(uint8_t dev_addr, tuh_msc_complete_data_t const * cb_da uint32_t const block_count = tuh_msc_get_block_count(dev_addr, cbw->lun); uint32_t const block_size = tuh_msc_get_block_size(dev_addr, cbw->lun); - printf("Disk Size: %lu MB\r\n", block_count / ((1024*1024)/block_size)); - printf("Block Count = %lu, Block Size: %lu\r\n", block_count, block_size); + printf("Disk Size: %" PRIu32 " MB\r\n", block_count / ((1024*1024)/block_size)); + printf("Block Count = %" PRIu32 ", Block Size: %" PRIu32 "\r\n", block_count, block_size); return true; } diff --git a/hw/bsp/nrf/boards/pca10059/pca10059.ld b/hw/bsp/nrf/boards/pca10059/pca10059.ld index 510bfdd8c..adc80f3c4 100644 --- a/hw/bsp/nrf/boards/pca10059/pca10059.ld +++ b/hw/bsp/nrf/boards/pca10059/pca10059.ld @@ -1,7 +1,7 @@ /* Linker script to configure memory regions. */ SEARCH_DIR(.) -GROUP(-lgcc -lc -lnosys) +/*GROUP(-lgcc -lc -lnosys) not compatible with clang*/ MEMORY { @@ -11,3 +11,9 @@ MEMORY INCLUDE "nrf_common.ld" + +/* nrfx v2 linker does not define __tbss_start/end__ __sbss_start/end__*/ +__tbss_start__ = __tbss_start; +__tbss_end__ = __tbss_end; +__sbss_start__ = __sbss_start; +__sbss_end__ = __sbss_end; diff --git a/hw/bsp/nrf/boards/pca10095/board.cmake b/hw/bsp/nrf/boards/pca10095/board.cmake index ca5399a3a..95dd30969 100644 --- a/hw/bsp/nrf/boards/pca10095/board.cmake +++ b/hw/bsp/nrf/boards/pca10095/board.cmake @@ -1,5 +1,4 @@ set(MCU_VARIANT nrf5340_application) -set(LD_FILE_GNU ${NRFX_DIR}/mdk/nrf5340_xxaa_application.ld) function(update_board TARGET) target_sources(${TARGET} PRIVATE diff --git a/hw/bsp/nrf/boards/pca10100/board.cmake b/hw/bsp/nrf/boards/pca10100/board.cmake index c30026815..a925dae80 100644 --- a/hw/bsp/nrf/boards/pca10100/board.cmake +++ b/hw/bsp/nrf/boards/pca10100/board.cmake @@ -1,5 +1,4 @@ set(MCU_VARIANT nrf52833) -set(LD_FILE_GNU ${NRFX_DIR}/mdk/nrf52833_xxaa.ld) function(update_board TARGET) endfunction() diff --git a/hw/bsp/nrf/boards/raytac_mdbt50q_rx/board.cmake b/hw/bsp/nrf/boards/raytac_mdbt50q_rx/board.cmake index 693d7beed..cc370aac8 100644 --- a/hw/bsp/nrf/boards/raytac_mdbt50q_rx/board.cmake +++ b/hw/bsp/nrf/boards/raytac_mdbt50q_rx/board.cmake @@ -1,5 +1,4 @@ set(MCU_VARIANT nrf52840) -set(LD_FILE_GNU ${NRFX_DIR}/mdk/nrf52840_xxaa.ld) function(update_board TARGET) endfunction() diff --git a/hw/bsp/nrf/family.c b/hw/bsp/nrf/family.c index deae64f05..aff851ddc 100644 --- a/hw/bsp/nrf/family.c +++ b/hw/bsp/nrf/family.c @@ -356,20 +356,22 @@ static void max3421_init(void) { .miso_pin = MAX3421_MISO_PIN, #if NRFX_VER <= 2 .ss_pin = NRFX_SPIM_PIN_NOT_USED, + .frequency = NRF_SPIM_FREQ_4M, #else .ss_pin = NRF_SPIM_PIN_NOT_CONNECTED, + .frequency = 4000000u, #endif .ss_active_high = false, .irq_priority = 3, .orc = 0xFF, // default setting 4 Mhz, Mode 0, MSB first - .frequency = NRF_SPIM_FREQ_4M, .mode = NRF_SPIM_MODE_0, .bit_order = NRF_SPIM_BIT_ORDER_MSB_FIRST, + .miso_pull = NRF_GPIO_PIN_NOPULL, }; // no handler --> blocking - nrfx_spim_init(&_spi, &cfg, NULL, NULL); + TU_ASSERT(NRFX_SUCCESS == nrfx_spim_init(&_spi, &cfg, NULL, NULL), ); // max3421e interrupt pin #if NRFX_VER <= 2 diff --git a/hw/bsp/nrf/family.cmake b/hw/bsp/nrf/family.cmake index 52a6fc196..56ff62bc4 100644 --- a/hw/bsp/nrf/family.cmake +++ b/hw/bsp/nrf/family.cmake @@ -30,8 +30,14 @@ set(FAMILY_MCUS NRF5X CACHE INTERNAL "") # only need to be built ONCE for all examples function(add_board_target BOARD_TARGET) if (NOT TARGET ${BOARD_TARGET}) + if (MCU_VARIANT STREQUAL "nrf5340_application") + set(MCU_VARIANT_XXAA "nrf5340_xxaa_application") + else () + set(MCU_VARIANT_XXAA "${MCU_VARIANT}_xxaa") + endif () + if (NOT DEFINED LD_FILE_GNU) - set(LD_FILE_GNU ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/linker/${MCU_VARIANT}_xxaa.ld) + set(LD_FILE_GNU ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/linker/${MCU_VARIANT_XXAA}.ld) endif () set(LD_FILE_Clang ${LD_FILE_GNU}) @@ -50,19 +56,13 @@ function(add_board_target BOARD_TARGET) ${NRFX_DIR}/soc/nrfx_atomic.c ${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} ) + string(TOUPPER "${MCU_VARIANT_XXAA}" MCU_VARIANT_XXAA_UPPER) target_compile_definitions(${BOARD_TARGET} PUBLIC __STARTUP_CLEAR_BSS CONFIG_GPIO_AS_PINRESET + ${MCU_VARIANT_XXAA_UPPER} ) - if (MCU_VARIANT STREQUAL "nrf52840") - target_compile_definitions(${BOARD_TARGET} PUBLIC NRF52840_XXAA) - elseif (MCU_VARIANT STREQUAL "nrf52833") - target_compile_definitions(${BOARD_TARGET} PUBLIC NRF52833_XXAA) - elseif (MCU_VARIANT STREQUAL "nrf5340_application") - target_compile_definitions(${BOARD_TARGET} PUBLIC NRF5340_XXAA NRF5340_XXAA_APPLICATION) - endif () - if (TRACE_ETM STREQUAL "1") # ENABLE_TRACE will cause system_nrf5x.c to set up ETM trace target_compile_definitions(${BOARD_TARGET} PUBLIC ENABLE_TRACE) diff --git a/hw/bsp/nrf/linker/nrf52833_xxaa.ld b/hw/bsp/nrf/linker/nrf52833_xxaa.ld new file mode 100644 index 000000000..ae4d0e5b3 --- /dev/null +++ b/hw/bsp/nrf/linker/nrf52833_xxaa.ld @@ -0,0 +1,20 @@ +/* Linker script to configure memory regions. */ + +SEARCH_DIR(.) +/*GROUP(-lgcc -lc -lnosys) not compatible with clang*/ + +MEMORY +{ + FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 0x80000 + RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 0x20000 + CODE_RAM (rwx) : ORIGIN = 0x800000, LENGTH = 0x20000 +} + + +INCLUDE "nrf_common.ld" + +/* nrfx v2 linker does not define __tbss_start/end__ __sbss_start/end__*/ +__tbss_start__ = __tbss_start; +__tbss_end__ = __tbss_end; +__sbss_start__ = __sbss_start; +__sbss_end__ = __sbss_end; diff --git a/hw/bsp/nrf/linker/nrf5340_xxaa_application.ld b/hw/bsp/nrf/linker/nrf5340_xxaa_application.ld new file mode 100644 index 000000000..31762d0b2 --- /dev/null +++ b/hw/bsp/nrf/linker/nrf5340_xxaa_application.ld @@ -0,0 +1,21 @@ +/* Linker script to configure memory regions. */ + +SEARCH_DIR(.) +/*GROUP(-lgcc -lc) not compatible with clang*/ + +MEMORY +{ + FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 0x100000 + EXTFLASH (rx) : ORIGIN = 0x10000000, LENGTH = 0x8000000 + RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 0x40000 + RAM1 (rwx) : ORIGIN = 0x20040000, LENGTH = 0x3F000 +} + + +INCLUDE "nrf_common.ld" + +/* nrfx v2 linker does not define __tbss_start/end__ __sbss_start/end__*/ +__tbss_start__ = __tbss_start; +__tbss_end__ = __tbss_end; +__sbss_start__ = __sbss_start; +__sbss_end__ = __sbss_end; diff --git a/src/class/cdc/cdc_host.c b/src/class/cdc/cdc_host.c index 5bdd41f1f..133a10f6e 100644 --- a/src/class/cdc/cdc_host.c +++ b/src/class/cdc/cdc_host.c @@ -1079,7 +1079,7 @@ static uint32_t ftdi_232bm_baud_to_divisor(uint32_t baud) { static bool ftdi_sio_set_baudrate(cdch_interface_t* p_cdc, uint32_t baudrate, tuh_xfer_cb_t complete_cb, uintptr_t user_data) { uint16_t const divisor = (uint16_t) ftdi_232bm_baud_to_divisor(baudrate); - TU_LOG_DRV("CDC FTDI Set BaudRate = %lu, divisor = 0x%04x\r\n", baudrate, divisor); + TU_LOG_DRV("CDC FTDI Set BaudRate = %" PRIu32 ", divisor = 0x%04x\r\n", baudrate, divisor); p_cdc->user_control_cb = complete_cb; p_cdc->requested_line_coding.bit_rate = baudrate; @@ -1222,7 +1222,7 @@ static bool cp210x_set_line_coding(cdch_interface_t* p_cdc, cdc_line_coding_t co } static bool cp210x_set_baudrate(cdch_interface_t* p_cdc, uint32_t baudrate, tuh_xfer_cb_t complete_cb, uintptr_t user_data) { - TU_LOG_DRV("CDC CP210x Set BaudRate = %lu\r\n", baudrate); + TU_LOG_DRV("CDC CP210x Set BaudRate = %" PRIu32 "\r\n", baudrate); uint32_t baud_le = tu_htole32(baudrate); p_cdc->user_control_cb = complete_cb; return cp210x_set_request(p_cdc, CP210X_SET_BAUDRATE, 0, (uint8_t *) &baud_le, 4, diff --git a/src/host/usbh.c b/src/host/usbh.c index f8fddf394..7a47f5056 100644 --- a/src/host/usbh.c +++ b/src/host/usbh.c @@ -704,7 +704,7 @@ static bool usbh_control_xfer_cb (uint8_t daddr, uint8_t ep_addr, xfer_result_t tusb_control_request_t const * request = &_ctrl_xfer.request; if (XFER_RESULT_SUCCESS != result) { - TU_LOG_USBH("[%u:%u] Control %s, xferred_bytes = %lu\r\n", rhport, daddr, result == XFER_RESULT_STALLED ? "STALLED" : "FAILED", xferred_bytes); + TU_LOG_USBH("[%u:%u] Control %s, xferred_bytes = %" PRIu32 "\r\n", rhport, daddr, result == XFER_RESULT_STALLED ? "STALLED" : "FAILED", xferred_bytes); TU_LOG_BUF_USBH(request, 8); // terminate transfer if any stage failed -- cgit v1.3.1