From 2e47210c1af88b88b6f2d92fe2b6d08117041363 Mon Sep 17 00:00:00 2001 From: Nathaniel Brough Date: Fri, 13 Jan 2023 13:37:55 -0800 Subject: fix: Replace device calls to memcpy with tu_memcpy_s Introduces a new function tu_memcpy_s, which is effectively a backport of memcpy_s. The change also refactors calls to memcpy over to the more secure tu_memcpy_s. --- src/common/tusb_common.h | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'src/common/tusb_common.h') diff --git a/src/common/tusb_common.h b/src/common/tusb_common.h index b1ee40a1a..78fdcfe36 100644 --- a/src/common/tusb_common.h +++ b/src/common/tusb_common.h @@ -83,6 +83,14 @@ #define tu_memclr(buffer, size) memset((buffer), 0, (size)) #define tu_varclr(_var) tu_memclr(_var, sizeof(*(_var))) +// This is a backport of memset_s from c11 +int32_t tu_memset_s(void *dest, size_t destsz, int ch, size_t count); + +// This is a backport of memcpy_s from c11 +int32_t tu_memcpy_s(void *dest, size_t destsz, + const void * src, size_t count ); + + //------------- Bytes -------------// TU_ATTR_ALWAYS_INLINE static inline uint32_t tu_u32(uint8_t b3, uint8_t b2, uint8_t b1, uint8_t b0) { -- cgit v1.3.1 From 1466afafeb927621f9cbb6efd2a0d7e4b6cf8d41 Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 22 Feb 2023 22:14:50 +0700 Subject: move and add optional tusb_app_virt_to_phys/tusb_app_phys_to_virt also add place holder for tusb_app_dcache_flush() and tusb_app_dcache_invalidate() --- src/common/tusb_common.h | 15 +++++++++++++++ src/common/tusb_mcu.h | 4 ++-- src/host/hcd.h | 2 +- src/osal/osal_none.h | 4 ++++ src/portable/ohci/ohci.c | 21 +++++++++++++-------- src/portable/ohci/ohci.h | 4 +++- 6 files changed, 38 insertions(+), 12 deletions(-) (limited to 'src/common/tusb_common.h') diff --git a/src/common/tusb_common.h b/src/common/tusb_common.h index b1ee40a1a..270339cca 100644 --- a/src/common/tusb_common.h +++ b/src/common/tusb_common.h @@ -75,6 +75,21 @@ #include "tusb_timeout.h" // TODO remove +//--------------------------------------------------------------------+ +// Optional API implemented by application if needed +// TODO move to a more ovious place/file +//--------------------------------------------------------------------+ + +// flush data cache +TU_ATTR_WEAK extern void tusb_app_dcache_flush(uintptr_t addr, uint32_t data_size); + +// invalidate data cache +TU_ATTR_WEAK extern void tusb_app_dcache_invalidate(uintptr_t addr, uint32_t data_size); + +// Optional physical <-> virtual address translation +TU_ATTR_WEAK extern void* tusb_app_virt_to_phys(void *virt_addr); +TU_ATTR_WEAK extern void* tusb_app_phys_to_virt(void *phys_addr); + //--------------------------------------------------------------------+ // Internal Inline Functions //--------------------------------------------------------------------+ diff --git a/src/common/tusb_mcu.h b/src/common/tusb_mcu.h index a599c4fe9..e7d4e2c32 100644 --- a/src/common/tusb_mcu.h +++ b/src/common/tusb_mcu.h @@ -28,8 +28,8 @@ #define TUSB_MCU_H_ //--------------------------------------------------------------------+ -// Port Specific -// TUP stand for TinyUSB Port (can be renamed) +// Port/Platform Specific +// TUP stand for TinyUSB Port/Platform (can be renamed) //--------------------------------------------------------------------+ //------------- Unaligned Memory Access -------------// diff --git a/src/host/hcd.h b/src/host/hcd.h index deebc59d4..a400626e4 100644 --- a/src/host/hcd.h +++ b/src/host/hcd.h @@ -106,7 +106,7 @@ typedef struct // Controller API //--------------------------------------------------------------------+ -// optional hcd configuration, called by tuh_config() +// optional hcd configuration, called by tuh_configure() bool hcd_configure(uint8_t rhport, uint32_t cfg_id, const void* cfg_param) TU_ATTR_WEAK; // Initialize controller to host mode diff --git a/src/osal/osal_none.h b/src/osal/osal_none.h index 1ad130557..2e2b3c7ce 100644 --- a/src/osal/osal_none.h +++ b/src/osal/osal_none.h @@ -35,6 +35,10 @@ // TASK API //--------------------------------------------------------------------+ +#if CFG_TUH_ENABLED +// currently only needed/available in host mode +void osal_task_delay(uint32_t msec); +#endif //--------------------------------------------------------------------+ // Binary Semaphore API diff --git a/src/portable/ohci/ohci.c b/src/portable/ohci/ohci.c index 792ef65ff..339f8e896 100644 --- a/src/portable/ohci/ohci.c +++ b/src/portable/ohci/ohci.c @@ -162,18 +162,16 @@ static void ed_list_remove_by_addr(ohci_ed_t * p_head, uint8_t dev_addr); // USBH-HCD API //--------------------------------------------------------------------+ -//If your system requires separation of virtual and physical memory, implement -//tuh_get_phys_addr and tuh_get_virt_addr in your application. -TU_ATTR_WEAK void *tuh_get_phys_addr(void *virtual_address); -TU_ATTR_WEAK void *tuh_get_virt_addr(void *physical_address); -TU_ATTR_ALWAYS_INLINE static void *_phys_addr(void *virtual_address) +// If your system requires separation of virtual and physical memory, implement +// tusb_app_virt_to_phys and tusb_app_virt_to_phys in your application. +TU_ATTR_ALWAYS_INLINE static inline void *_phys_addr(void *virtual_address) { - if (tuh_get_phys_addr) return tuh_get_phys_addr(virtual_address); + if (tusb_app_virt_to_phys) return tusb_app_virt_to_phys(virtual_address); return virtual_address; } -TU_ATTR_ALWAYS_INLINE static void *_virt_addr(void *physical_address) +TU_ATTR_ALWAYS_INLINE static inline void *_virt_addr(void *physical_address) { - if (tuh_get_virt_addr) return tuh_get_virt_addr(physical_address); + if (tusb_app_phys_to_virt) return tusb_app_phys_to_virt(physical_address); return physical_address; } @@ -206,7 +204,13 @@ bool hcd_init(uint8_t rhport) { //Wait 20 ms. (Ref Usb spec 7.1.7.7) OHCI_REG->control_bit.hc_functional_state = OHCI_CONTROL_FUNCSTATE_RESUME; + +#if CFG_TUSB_OS != OPT_OS_NONE + // os_none implement task delay using usb frame counter which is not started yet + // therefore cause infinite delay. + // TODO find a way to delay in case of os none e.g __nop osal_task_delay(20); +#endif } // reset controller @@ -233,6 +237,7 @@ bool hcd_init(uint8_t rhport) OHCI_REG->control_bit.hc_functional_state = OHCI_CONTROL_FUNCSTATE_OPERATIONAL; // make HC's state to operational state TODO use this to suspend (save power) OHCI_REG->rh_status_bit.local_power_status_change = 1; // set global power for ports + osal_task_delay(OHCI_REG->rh_descriptorA_bit.power_on_to_good_time * 2); // Wait POTG after power up return true; diff --git a/src/portable/ohci/ohci.h b/src/portable/ohci/ohci.h index 38c258e80..2081ffabb 100644 --- a/src/portable/ohci/ohci.h +++ b/src/portable/ohci/ohci.h @@ -58,7 +58,9 @@ typedef struct { TU_VERIFY_STATIC( sizeof(ohci_hcca_t) == 256, "size is not correct" ); -typedef struct { +// common link item for gtd and itd for list travel +// use as pointer only +typedef struct TU_ATTR_ALIGNED(16) { uint32_t reserved[2]; volatile uint32_t next; uint32_t reserved2; -- cgit v1.3.1 From e34aeb5cf69315d2d7711f0a1d040a28492d026d Mon Sep 17 00:00:00 2001 From: hathach Date: Mon, 27 Feb 2023 09:11:35 +0700 Subject: minor clean up --- src/class/audio/audio_device.c | 2 +- src/class/hid/hid_device.c | 6 +++--- src/class/midi/midi_device.c | 2 +- src/class/msc/msc_device.c | 10 +++++----- src/common/tusb_common.h | 21 ++++++++++++++++++--- src/device/usbd_control.c | 2 +- src/tusb.c | 21 --------------------- 7 files changed, 29 insertions(+), 35 deletions(-) (limited to 'src/common/tusb_common.h') diff --git a/src/class/audio/audio_device.c b/src/class/audio/audio_device.c index 81df95139..de5a20d6d 100644 --- a/src/class/audio/audio_device.c +++ b/src/class/audio/audio_device.c @@ -2199,7 +2199,7 @@ bool tud_audio_buffer_and_schedule_control_xfer(uint8_t rhport, tusb_control_req if (len > _audiod_fct[func_id].ctrl_buf_sz) len = _audiod_fct[func_id].ctrl_buf_sz; // Copy into buffer - TU_VERIFY(tu_memcpy_s(_audiod_fct[func_id].ctrl_buf, sizeof(_audiod_fct[func_id].ctrl_buf), data, (size_t)len)==0); + TU_VERIFY(0 == tu_memcpy_s(_audiod_fct[func_id].ctrl_buf, sizeof(_audiod_fct[func_id].ctrl_buf), data, (size_t)len)); // Schedule transmit return tud_control_xfer(rhport, p_request, (void*)_audiod_fct[func_id].ctrl_buf, len); diff --git a/src/class/hid/hid_device.c b/src/class/hid/hid_device.c index 40654eef9..37a22b609 100644 --- a/src/class/hid/hid_device.c +++ b/src/class/hid/hid_device.c @@ -93,11 +93,11 @@ bool tud_hid_n_report(uint8_t instance, uint8_t report_id, void const* report, u if (report_id) { p_hid->epin_buf[0] = report_id; - TU_VERIFY(tu_memcpy_s(p_hid->epin_buf+1, CFG_TUD_HID_EP_BUFSIZE-1, report, len)==0); + TU_VERIFY(0 == tu_memcpy_s(p_hid->epin_buf+1, CFG_TUD_HID_EP_BUFSIZE-1, report, len)); len++; }else { - TU_VERIFY(tu_memcpy_s(p_hid->epin_buf, CFG_TUD_HID_EP_BUFSIZE, report, len)==0); + TU_VERIFY(0 == tu_memcpy_s(p_hid->epin_buf, CFG_TUD_HID_EP_BUFSIZE, report, len)); } return usbd_edpt_xfer(rhport, p_hid->ep_in, p_hid->epin_buf, len); @@ -122,7 +122,7 @@ bool tud_hid_n_keyboard_report(uint8_t instance, uint8_t report_id, uint8_t modi if ( keycode ) { - TU_VERIFY(tu_memcpy_s(report.keycode, sizeof(report.keycode), keycode, sizeof(report.keycode))==0); + memcpy(report.keycode, keycode, sizeof(report.keycode)); }else { tu_memclr(report.keycode, 6); diff --git a/src/class/midi/midi_device.c b/src/class/midi/midi_device.c index 0b52be181..92689dfb0 100644 --- a/src/class/midi/midi_device.c +++ b/src/class/midi/midi_device.c @@ -182,7 +182,7 @@ uint32_t tud_midi_n_stream_read(uint8_t itf, uint8_t cable_num, void* buffer, ui uint8_t const count = (uint8_t) tu_min32(stream->total - stream->index, bufsize); // Skip the header (1st byte) in the buffer - TU_VERIFY(tu_memcpy_s(buf8, bufsize, stream->buffer + 1 + stream->index, count)==0); + TU_VERIFY(0 == tu_memcpy_s(buf8, bufsize, stream->buffer + 1 + stream->index, count)); total_read += count; stream->index += count; diff --git a/src/class/msc/msc_device.c b/src/class/msc/msc_device.c index ed4a3e86c..ecc95377f 100644 --- a/src/class/msc/msc_device.c +++ b/src/class/msc/msc_device.c @@ -707,7 +707,7 @@ static int32_t proc_builtin_scsi(uint8_t lun, uint8_t const scsi_cmd[16], uint8_ read_capa10.block_size = tu_htonl(block_size); resplen = sizeof(read_capa10); - TU_VERIFY(tu_memcpy_s(buffer, bufsize, &read_capa10, (size_t) resplen)); + TU_VERIFY(0 == tu_memcpy_s(buffer, bufsize, &read_capa10, (size_t) resplen)); } } break; @@ -741,7 +741,7 @@ static int32_t proc_builtin_scsi(uint8_t lun, uint8_t const scsi_cmd[16], uint8_ read_fmt_capa.block_size_u16 = tu_htons(block_size); resplen = sizeof(read_fmt_capa); - TU_VERIFY(tu_memcpy_s(buffer, bufsize, &read_fmt_capa, (size_t) resplen)==0); + TU_VERIFY(0 == tu_memcpy_s(buffer, bufsize, &read_fmt_capa, (size_t) resplen)); } } break; @@ -764,7 +764,7 @@ static int32_t proc_builtin_scsi(uint8_t lun, uint8_t const scsi_cmd[16], uint8_ tud_msc_inquiry_cb(lun, inquiry_rsp.vendor_id, inquiry_rsp.product_id, inquiry_rsp.product_rev); resplen = sizeof(inquiry_rsp); - TU_VERIFY(tu_memcpy_s(buffer, bufsize, &inquiry_rsp, (size_t) resplen)==0); + TU_VERIFY(0 == tu_memcpy_s(buffer, bufsize, &inquiry_rsp, (size_t) resplen)); } break; @@ -788,7 +788,7 @@ static int32_t proc_builtin_scsi(uint8_t lun, uint8_t const scsi_cmd[16], uint8_ mode_resp.write_protected = !writable; resplen = sizeof(mode_resp); - TU_VERIFY(tu_memcpy_s(buffer, bufsize, &mode_resp, (size_t) resplen)==0); + TU_VERIFY(0 == tu_memcpy_s(buffer, bufsize, &mode_resp, (size_t) resplen)); } break; @@ -806,7 +806,7 @@ static int32_t proc_builtin_scsi(uint8_t lun, uint8_t const scsi_cmd[16], uint8_ sense_rsp.add_sense_qualifier = p_msc->add_sense_qualifier; resplen = sizeof(sense_rsp); - TU_VERIFY(tu_memcpy_s(buffer, bufsize, &sense_rsp, (size_t) resplen)==0); + TU_VERIFY(0 == tu_memcpy_s(buffer, bufsize, &sense_rsp, (size_t) resplen)); // request sense callback could overwrite the sense data if (tud_msc_request_sense_cb) diff --git a/src/common/tusb_common.h b/src/common/tusb_common.h index 78fdcfe36..3e5e1d427 100644 --- a/src/common/tusb_common.h +++ b/src/common/tusb_common.h @@ -84,11 +84,26 @@ #define tu_varclr(_var) tu_memclr(_var, sizeof(*(_var))) // This is a backport of memset_s from c11 -int32_t tu_memset_s(void *dest, size_t destsz, int ch, size_t count); +TU_ATTR_ALWAYS_INLINE static inline int tu_memset_s(void *dest, size_t destsz, int ch, size_t count) +{ + // TODO may check if desst and src is not NULL + if (count > destsz) { + return -1; + } + memset(dest, ch, count); + return 0; +} // This is a backport of memcpy_s from c11 -int32_t tu_memcpy_s(void *dest, size_t destsz, - const void * src, size_t count ); +TU_ATTR_ALWAYS_INLINE static inline int tu_memcpy_s(void *dest, size_t destsz, const void * src, size_t count ) +{ + // TODO may check if desst and src is not NULL + if (count > destsz) { + return -1; + } + memcpy(dest, src, count); + return 0; +} //------------- Bytes -------------// diff --git a/src/device/usbd_control.c b/src/device/usbd_control.c index ce4ddab66..b8a200845 100644 --- a/src/device/usbd_control.c +++ b/src/device/usbd_control.c @@ -94,7 +94,7 @@ static bool _data_stage_xact(uint8_t rhport) { ep_addr = EDPT_CTRL_IN; if ( xact_len ) { - TU_VERIFY(tu_memcpy_s(_usbd_ctrl_buf, CFG_TUD_ENDPOINT0_SIZE, _ctrl_xfer.buffer, xact_len)==0); + TU_VERIFY(0 == tu_memcpy_s(_usbd_ctrl_buf, CFG_TUD_ENDPOINT0_SIZE, _ctrl_xfer.buffer, xact_len)); } } diff --git a/src/tusb.c b/src/tusb.c index c918b0248..8318e5275 100644 --- a/src/tusb.c +++ b/src/tusb.c @@ -24,7 +24,6 @@ * This file is part of the TinyUSB stack. */ -#include "common/tusb_common.h" #include "tusb_option.h" #if CFG_TUH_ENABLED || CFG_TUD_ENABLED @@ -487,23 +486,3 @@ void tu_print_mem(void const *buf, uint32_t count, uint8_t indent) #endif #endif // host or device enabled - -//--------------------------------------------------------------------+ -// Common -//--------------------------------------------------------------------+ - -int32_t tu_memset_s(void *dest, size_t destsz, int ch, size_t count) { - if (count > destsz) { - return -1; - } - memset(dest, ch, count); - return 0; -} - -int32_t tu_memcpy_s(void *dest, size_t destsz, const void *src, size_t count) { - if (count > destsz) { - return -1; - } - memcpy(dest, src, count); - return 0; -} \ No newline at end of file -- cgit v1.3.1 From 317177c83d3c28d66bfe60be971ff37a44bd84df Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 17 Mar 2023 14:06:25 +0700 Subject: update host example, add pio-pico-usb for rp2040 --- examples/host/bare_api/CMakeLists.txt | 5 +++++ examples/host/bare_api/src/tusb_config.h | 4 ++-- examples/host/cdc_msc_hid/CMakeLists.txt | 5 +++++ examples/host/cdc_msc_hid/src/tusb_config.h | 6 +++--- examples/host/hid_controller/CMakeLists.txt | 5 +++++ examples/host/hid_controller/src/tusb_config.h | 7 +++---- examples/host/msc_file_explorer/CMakeLists.txt | 4 ++++ examples/host/msc_file_explorer/src/tusb_config.h | 6 +++--- hw/bsp/rp2040/family.mk | 3 --- src/class/cdc/cdc_host.c | 8 ++++---- src/common/tusb_common.h | 6 ++++++ src/common/tusb_types.h | 5 ----- 12 files changed, 40 insertions(+), 24 deletions(-) (limited to 'src/common/tusb_common.h') diff --git a/examples/host/bare_api/CMakeLists.txt b/examples/host/bare_api/CMakeLists.txt index 4879613b4..616edd4ac 100644 --- a/examples/host/bare_api/CMakeLists.txt +++ b/examples/host/bare_api/CMakeLists.txt @@ -25,3 +25,8 @@ target_include_directories(${PROJECT} PUBLIC # Configure compilation flags and libraries for the example... see the corresponding function # in hw/bsp/FAMILY/family.cmake for details. family_configure_host_example(${PROJECT}) + +# Add pico-pio-usb for rp2040 since user can choose to run on bit-banging host +if(FAMILY STREQUAL "rp2040") + family_add_pico_pio_usb(${PROJECT}) +endif() diff --git a/examples/host/bare_api/src/tusb_config.h b/examples/host/bare_api/src/tusb_config.h index 701aa6d90..64be41a4e 100644 --- a/examples/host/bare_api/src/tusb_config.h +++ b/examples/host/bare_api/src/tusb_config.h @@ -1,4 +1,4 @@ -/* +/* * The MIT License (MIT) * * Copyright (c) 2019 Ha Thach (tinyusb.org) @@ -100,7 +100,7 @@ // max device support (excluding hub device) // 1 hub typically has 4 ports -#define CFG_TUH_DEVICE_MAX (CFG_TUH_HUB ? 4 : 1) +#define CFG_TUH_DEVICE_MAX (3*CFG_TUH_HUB + 1) // Max endpoint per device #define CFG_TUH_ENDPOINT_MAX 8 diff --git a/examples/host/cdc_msc_hid/CMakeLists.txt b/examples/host/cdc_msc_hid/CMakeLists.txt index dbba6bf44..d7d1a54d7 100644 --- a/examples/host/cdc_msc_hid/CMakeLists.txt +++ b/examples/host/cdc_msc_hid/CMakeLists.txt @@ -28,3 +28,8 @@ target_include_directories(${PROJECT} PUBLIC # Configure compilation flags and libraries for the example... see the corresponding function # in hw/bsp/FAMILY/family.cmake for details. family_configure_host_example(${PROJECT}) + +# Add pico-pio-usb for rp2040 since user can choose to run on bit-banging host +if(FAMILY STREQUAL "rp2040") + family_add_pico_pio_usb(${PROJECT}) +endif() diff --git a/examples/host/cdc_msc_hid/src/tusb_config.h b/examples/host/cdc_msc_hid/src/tusb_config.h index 139a921d1..4b50f2096 100644 --- a/examples/host/cdc_msc_hid/src/tusb_config.h +++ b/examples/host/cdc_msc_hid/src/tusb_config.h @@ -1,4 +1,4 @@ -/* +/* * The MIT License (MIT) * * Copyright (c) 2019 Ha Thach (tinyusb.org) @@ -101,8 +101,8 @@ #define CFG_TUH_MSC 1 #define CFG_TUH_VENDOR 0 -// max device support (excluding hub device) -#define CFG_TUH_DEVICE_MAX (CFG_TUH_HUB ? 4 : 1) // hub typically has 4 ports +// 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 diff --git a/examples/host/hid_controller/CMakeLists.txt b/examples/host/hid_controller/CMakeLists.txt index aa50b5a52..ac3070b82 100644 --- a/examples/host/hid_controller/CMakeLists.txt +++ b/examples/host/hid_controller/CMakeLists.txt @@ -26,3 +26,8 @@ target_include_directories(${PROJECT} PUBLIC # Configure compilation flags and libraries for the example... see the corresponding function # in hw/bsp/FAMILY/family.cmake for details. family_configure_host_example(${PROJECT}) + +# Add pico-pio-usb for rp2040 since user can choose to run on bit-banging host +if(FAMILY STREQUAL "rp2040") + family_add_pico_pio_usb(${PROJECT}) +endif() diff --git a/examples/host/hid_controller/src/tusb_config.h b/examples/host/hid_controller/src/tusb_config.h index e6d6f873d..2e0dd0dbe 100644 --- a/examples/host/hid_controller/src/tusb_config.h +++ b/examples/host/hid_controller/src/tusb_config.h @@ -1,4 +1,4 @@ -/* +/* * The MIT License (MIT) * * Copyright (c) 2019 Ha Thach (tinyusb.org) @@ -101,9 +101,8 @@ #define CFG_TUH_MSC 0 #define CFG_TUH_VENDOR 0 -// max device support (excluding hub device) -// 1 hub typically has 4 ports -#define CFG_TUH_DEVICE_MAX (CFG_TUH_HUB ? 4 : 1) +// max device support (excluding hub device): 1 hub typically has 4 ports +#define CFG_TUH_DEVICE_MAX (3*CFG_TUH_HUB + 1) //------------- HID -------------// diff --git a/examples/host/msc_file_explorer/CMakeLists.txt b/examples/host/msc_file_explorer/CMakeLists.txt index 2c06eafee..7955b3078 100644 --- a/examples/host/msc_file_explorer/CMakeLists.txt +++ b/examples/host/msc_file_explorer/CMakeLists.txt @@ -32,3 +32,7 @@ target_include_directories(${PROJECT} PUBLIC # in hw/bsp/FAMILY/family.cmake for details. family_configure_host_example(${PROJECT}) +# Add pico-pio-usb for rp2040 since user can choose to run on bit-banging host +if(FAMILY STREQUAL "rp2040") + family_add_pico_pio_usb(${PROJECT}) +endif() diff --git a/examples/host/msc_file_explorer/src/tusb_config.h b/examples/host/msc_file_explorer/src/tusb_config.h index ddf8368f4..eaf3ea6d4 100644 --- a/examples/host/msc_file_explorer/src/tusb_config.h +++ b/examples/host/msc_file_explorer/src/tusb_config.h @@ -1,4 +1,4 @@ -/* +/* * The MIT License (MIT) * * Copyright (c) 2019 Ha Thach (tinyusb.org) @@ -101,8 +101,8 @@ #define CFG_TUH_HID 0 // typical keyboard + mouse device can have 3-4 HID interfaces #define CFG_TUH_VENDOR 0 -// max device support (excluding hub device) -#define CFG_TUH_DEVICE_MAX (CFG_TUH_HUB ? 4 : 1) // hub typically has 4 ports +// max device support (excluding hub device): 1 hub typically has 4 ports +#define CFG_TUH_DEVICE_MAX (3*CFG_TUH_HUB + 1) //------------- MSC -------------// #define CFG_TUH_MSC_MAXLUN 4 // typical for most card reader diff --git a/hw/bsp/rp2040/family.mk b/hw/bsp/rp2040/family.mk index cf6b53793..25d1ad9c5 100644 --- a/hw/bsp/rp2040/family.mk +++ b/hw/bsp/rp2040/family.mk @@ -13,9 +13,6 @@ $(BUILD): all: $(BUILD) $(MAKE) -C $(BUILD) -clean: - $(RM) -rf $(BUILD) - flash: flash-pyocd flash-uf2: @$(CP) $(BUILD)/$(PROJECT).uf2 /media/$(USER)/RPI-RP2 diff --git a/src/class/cdc/cdc_host.c b/src/class/cdc/cdc_host.c index e9c3d34cb..011ee49dc 100644 --- a/src/class/cdc/cdc_host.c +++ b/src/class/cdc/cdc_host.c @@ -1,4 +1,4 @@ -/* +/* * The MIT License (MIT) * * Copyright (c) 2019 Ha Thach (tinyusb.org) @@ -97,7 +97,7 @@ static inline uint8_t get_idx_by_ep_addr(uint8_t daddr, uint8_t ep_addr) } } - return TUSB_INDEX_INVALID; + return TU_INDEX_INVALID_8; } @@ -124,7 +124,7 @@ uint8_t tuh_cdc_itf_get_index(uint8_t daddr, uint8_t itf_num) if (p_cdc->daddr == daddr && p_cdc->bInterfaceNumber == itf_num) return i; } - return TUSB_INDEX_INVALID; + return TU_INDEX_INVALID_8; } bool tuh_cdc_itf_get_info(uint8_t idx, tuh_cdc_itf_info_t* info) @@ -533,7 +533,7 @@ static void process_cdc_config(tuh_xfer_t* xfer) uintptr_t const state = xfer->user_data; uint8_t const itf_num = (uint8_t) tu_le16toh(xfer->setup->wIndex); uint8_t const idx = tuh_cdc_itf_get_index(xfer->daddr, itf_num); - TU_ASSERT(idx != TUSB_INDEX_INVALID, ); + TU_ASSERT(idx != TU_INDEX_INVALID_8, ); switch(state) { diff --git a/src/common/tusb_common.h b/src/common/tusb_common.h index 957491aa9..faccf8726 100644 --- a/src/common/tusb_common.h +++ b/src/common/tusb_common.h @@ -75,6 +75,12 @@ #include "tusb_timeout.h" // TODO remove +enum +{ + TU_INDEX_INVALID_8 = 0xFFu +}; + + //--------------------------------------------------------------------+ // Optional API implemented by application if needed // TODO move to a more ovious place/file diff --git a/src/common/tusb_types.h b/src/common/tusb_types.h index 7266a525e..d567bd482 100644 --- a/src/common/tusb_types.h +++ b/src/common/tusb_types.h @@ -273,11 +273,6 @@ enum CONTROL_STAGE_ACK }; -enum -{ - TUSB_INDEX_INVALID = 0xff -}; - //--------------------------------------------------------------------+ // USB Descriptors //--------------------------------------------------------------------+ -- cgit v1.3.1 From e44e461ce3295f5680ea211048ade473963ba016 Mon Sep 17 00:00:00 2001 From: hathach Date: Tue, 21 Mar 2023 12:54:43 +0700 Subject: add tuh_set_interface --- src/class/cdc/cdc_host.c | 6 +++--- src/class/cdc/cdc_host.h | 2 +- src/common/tusb_common.h | 6 ------ src/common/tusb_types.h | 5 +++++ src/host/usbh.c | 50 +++++++++++++++++++++++++++++++++++++++--------- src/host/usbh.h | 5 +++++ 6 files changed, 55 insertions(+), 19 deletions(-) (limited to 'src/common/tusb_common.h') diff --git a/src/class/cdc/cdc_host.c b/src/class/cdc/cdc_host.c index 011ee49dc..d34662cb7 100644 --- a/src/class/cdc/cdc_host.c +++ b/src/class/cdc/cdc_host.c @@ -97,7 +97,7 @@ static inline uint8_t get_idx_by_ep_addr(uint8_t daddr, uint8_t ep_addr) } } - return TU_INDEX_INVALID_8; + return TUSB_INDEX_INVALID_8; } @@ -124,7 +124,7 @@ uint8_t tuh_cdc_itf_get_index(uint8_t daddr, uint8_t itf_num) if (p_cdc->daddr == daddr && p_cdc->bInterfaceNumber == itf_num) return i; } - return TU_INDEX_INVALID_8; + return TUSB_INDEX_INVALID_8; } bool tuh_cdc_itf_get_info(uint8_t idx, tuh_cdc_itf_info_t* info) @@ -533,7 +533,7 @@ static void process_cdc_config(tuh_xfer_t* xfer) uintptr_t const state = xfer->user_data; uint8_t const itf_num = (uint8_t) tu_le16toh(xfer->setup->wIndex); uint8_t const idx = tuh_cdc_itf_get_index(xfer->daddr, itf_num); - TU_ASSERT(idx != TU_INDEX_INVALID_8, ); + TU_ASSERT(idx != TUSB_INDEX_INVALID_8, ); switch(state) { diff --git a/src/class/cdc/cdc_host.h b/src/class/cdc/cdc_host.h index 4090d0e9f..03f32e542 100644 --- a/src/class/cdc/cdc_host.h +++ b/src/class/cdc/cdc_host.h @@ -80,7 +80,7 @@ typedef struct } tuh_cdc_itf_info_t; // Get Interface index from device address + interface number -// return TUSB_INDEX_INVALID (0xFF) if not found +// return TUSB_INDEX_INVALID_8 (0xFF) if not found uint8_t tuh_cdc_itf_get_index(uint8_t daddr, uint8_t itf_num); // Get Interface information diff --git a/src/common/tusb_common.h b/src/common/tusb_common.h index faccf8726..957491aa9 100644 --- a/src/common/tusb_common.h +++ b/src/common/tusb_common.h @@ -75,12 +75,6 @@ #include "tusb_timeout.h" // TODO remove -enum -{ - TU_INDEX_INVALID_8 = 0xFFu -}; - - //--------------------------------------------------------------------+ // Optional API implemented by application if needed // TODO move to a more ovious place/file diff --git a/src/common/tusb_types.h b/src/common/tusb_types.h index d567bd482..39a2d4564 100644 --- a/src/common/tusb_types.h +++ b/src/common/tusb_types.h @@ -273,6 +273,11 @@ enum CONTROL_STAGE_ACK }; +enum +{ + TUSB_INDEX_INVALID_8 = 0xFFu +}; + //--------------------------------------------------------------------+ // USB Descriptors //--------------------------------------------------------------------+ diff --git a/src/host/usbh.c b/src/host/usbh.c index 9ccbe7557..5a14aea5f 100644 --- a/src/host/usbh.c +++ b/src/host/usbh.c @@ -195,7 +195,7 @@ enum { CONFIG_NUM = 1 }; // default to use configuration 1 // sum of end device + hub #define TOTAL_DEVICES (CFG_TUH_DEVICE_MAX + CFG_TUH_HUB) -static uint8_t _usbh_controller = TU_INDEX_INVALID_8; +static uint8_t _usbh_controller = TUSB_INDEX_INVALID_8; // Device with address = 0 for enumeration static usbh_dev0_t _dev0; @@ -303,13 +303,13 @@ tusb_speed_t tuh_speed_get (uint8_t dev_addr) static void clear_device(usbh_device_t* dev) { tu_memclr(dev, sizeof(usbh_device_t)); - memset(dev->itf2drv, TU_INDEX_INVALID_8, sizeof(dev->itf2drv)); // invalid mapping - memset(dev->ep2drv , TU_INDEX_INVALID_8, sizeof(dev->ep2drv )); // invalid mapping + 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) { - return _usbh_controller != TU_INDEX_INVALID_8; + return _usbh_controller != TUSB_INDEX_INVALID_8; } bool tuh_init(uint8_t controller_id) @@ -1033,6 +1033,38 @@ bool tuh_configuration_set(uint8_t daddr, uint8_t config_num, 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) +{ + 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 + }; + + 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); +} + //--------------------------------------------------------------------+ // Descriptor Sync //--------------------------------------------------------------------+ @@ -1358,11 +1390,11 @@ static void process_enumeration(tuh_xfer_t* xfer) dev->configured = 1; - // Start the Set Configuration process for interfaces (itf = TU_INDEX_INVALID_8) + // 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() - // TODO use separated API instead of using TU_INDEX_INVALID_8 - usbh_driver_set_config_complete(daddr, TU_INDEX_INVALID_8); + // TODO use separated API instead of using TUSB_INDEX_INVALID_8 + usbh_driver_set_config_complete(daddr, TUSB_INDEX_INVALID_8); } break; @@ -1562,7 +1594,7 @@ static bool _parse_configuration_descriptor(uint8_t dev_addr, tusb_desc_configur uint8_t const itf_num = desc_itf->bInterfaceNumber+i; // Interface number must not be used already - TU_ASSERT( TU_INDEX_INVALID_8 == dev->itf2drv[itf_num] ); + TU_ASSERT( TUSB_INDEX_INVALID_8 == dev->itf2drv[itf_num] ); dev->itf2drv[itf_num] = drv_id; } @@ -1596,7 +1628,7 @@ 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 != TU_INDEX_INVALID_8) + if (drv_id != TUSB_INDEX_INVALID_8) { usbh_class_driver_t const * driver = &usbh_class_drivers[drv_id]; TU_LOG_USBH("%s set config: itf = %u\r\n", driver->name, itf_num); diff --git a/src/host/usbh.h b/src/host/usbh.h index 7942de5c2..45e6356bc 100644 --- a/src/host/usbh.h +++ b/src/host/usbh.h @@ -171,6 +171,11 @@ bool tuh_edpt_open(uint8_t dev_addr, tusb_desc_endpoint_t const * desc_ep); bool tuh_configuration_set(uint8_t daddr, uint8_t config_num, tuh_xfer_cb_t complete_cb, uintptr_t user_data); +// Set Interface (control transfer) +// true on success, false if there is on-going control transfer or incorrect parameters +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); + //--------------------------------------------------------------------+ // Descriptors Asynchronous (non-blocking) //--------------------------------------------------------------------+ -- cgit v1.3.1 From 4c156100fafa682407f1a9a459d8b8800a029446 Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 7 Jul 2023 12:27:18 +0700 Subject: use unaligned access read for hw fifo --- src/common/tusb_common.h | 18 ++++++-- src/common/tusb_mcu.h | 12 ++++-- src/portable/renesas/rusb2/dcd_rusb2.c | 77 +++++++++++++++++++++------------- 3 files changed, 71 insertions(+), 36 deletions(-) (limited to 'src/common/tusb_common.h') diff --git a/src/common/tusb_common.h b/src/common/tusb_common.h index 957491aa9..576cb123f 100644 --- a/src/common/tusb_common.h +++ b/src/common/tusb_common.h @@ -260,11 +260,21 @@ TU_ATTR_ALWAYS_INLINE static inline void tu_unaligned_write16(void* mem, uint16_ #else // MCU that could access unaligned memory natively -TU_ATTR_ALWAYS_INLINE static inline uint32_t tu_unaligned_read32 (const void* mem) { return *((uint32_t const *) mem); } -TU_ATTR_ALWAYS_INLINE static inline uint16_t tu_unaligned_read16 (const void* mem) { return *((uint16_t const *) mem); } +TU_ATTR_ALWAYS_INLINE static inline uint32_t tu_unaligned_read32(const void *mem) { + return *((uint32_t const *) mem); +} + +TU_ATTR_ALWAYS_INLINE static inline uint16_t tu_unaligned_read16(const void *mem) { + return *((uint16_t const *) mem); +} -TU_ATTR_ALWAYS_INLINE static inline void tu_unaligned_write32 (void* mem, uint32_t value ) { *((uint32_t*) mem) = value; } -TU_ATTR_ALWAYS_INLINE static inline void tu_unaligned_write16 (void* mem, uint16_t value ) { *((uint16_t*) mem) = value; } +TU_ATTR_ALWAYS_INLINE static inline void tu_unaligned_write32(void *mem, uint32_t value) { + *((uint32_t *) mem) = value; +} + +TU_ATTR_ALWAYS_INLINE static inline void tu_unaligned_write16(void *mem, uint16_t value) { + *((uint16_t *) mem) = value; +} #endif diff --git a/src/common/tusb_mcu.h b/src/common/tusb_mcu.h index 496ebfc85..89f89182e 100644 --- a/src/common/tusb_mcu.h +++ b/src/common/tusb_mcu.h @@ -34,10 +34,16 @@ //------------- Unaligned Memory Access -------------// -// ARMv7+ (M3-M7, M23-M33) can access unaligned memory -#if (defined(__ARM_ARCH) && (__ARM_ARCH >= 7)) - #define TUP_ARCH_STRICT_ALIGN 0 +#ifdef __ARM_ARCH + // ARM Architecture set __ARM_FEATURE_UNALIGNED to 1 for mcu supports unaligned access + #if defined(__ARM_FEATURE_UNALIGNED) && __ARM_FEATURE_UNALIGNED == 1 + #define TUP_ARCH_STRICT_ALIGN 0 + #else + #define TUP_ARCH_STRICT_ALIGN 1 + #endif #else + // TODO default to strict align for others + // Should investigate other architecture such as risv, xtensa, mips for optimal setting #define TUP_ARCH_STRICT_ALIGN 1 #endif diff --git a/src/portable/renesas/rusb2/dcd_rusb2.c b/src/portable/renesas/rusb2/dcd_rusb2.c index 81b60b3bc..464929224 100644 --- a/src/portable/renesas/rusb2/dcd_rusb2.c +++ b/src/portable/renesas/rusb2/dcd_rusb2.c @@ -220,6 +220,11 @@ static inline void pipe_wait_for_ready(rusb2_reg_t * rusb, unsigned num) while ( !rusb->D0FIFOCTR_b.FRDY ) {} } +//--------------------------------------------------------------------+ +// Pipe FIFO +//--------------------------------------------------------------------+ + +// Write data buffer --> hw fifo static void pipe_write_packet(void *buf, volatile void *fifo, unsigned len) { #if (CFG_TUSB_RHPORT1_MODE & OPT_MODE_DEVICE) @@ -228,54 +233,68 @@ static void pipe_write_packet(void *buf, volatile void *fifo, unsigned len) volatile hw_fifo16_t *reg = (volatile hw_fifo16_t*) fifo; #endif - uintptr_t addr = (uintptr_t)buf; + uint8_t const* buf8 = (uint8_t const*) buf; while (len >= 2) { - reg->u16 = *(const uint16_t *)addr; - addr += 2; + reg->u16 = tu_unaligned_read16(buf8); + buf8 += 2; len -= 2; } if (len > 0) { - reg->u8 = *(const uint8_t *)addr; - ++addr; + reg->u8 = *buf8; + ++buf8; } } +// Read data buffer <-- hw fifo static void pipe_read_packet(void *buf, volatile void *fifo, unsigned len) { - uint8_t *p = (uint8_t*)buf; + uint8_t *p = (uint8_t*)buf; volatile uint8_t *reg = (volatile uint8_t*)fifo; /* byte access is always at base register address */ while (len--) *p++ = *reg; } -static void pipe_read_write_packet_ff(tu_fifo_t *f, volatile void *fifo, unsigned len, unsigned dir) -{ - static const struct { - void (*tu_fifo_get_info)(tu_fifo_t *f, tu_fifo_buffer_info_t *info); - void (*tu_fifo_advance)(tu_fifo_t *f, uint16_t n); - void (*pipe_read_write)(void *buf, volatile void *fifo, unsigned len); - } ops[] = { - /* OUT */ {tu_fifo_get_write_info,tu_fifo_advance_write_pointer,pipe_read_packet}, - /* IN */ {tu_fifo_get_read_info, tu_fifo_advance_read_pointer, pipe_write_packet}, - }; +// Write data sw fifo --> hw fifo +static void pipe_write_packet_ff(tu_fifo_t *f, volatile void *fifo, uint16_t total_len) { + tu_fifo_buffer_info_t info; + tu_fifo_get_read_info(f, &info); + + uint16_t count = tu_min16(total_len, info.len_lin); + pipe_write_packet(info.ptr_lin, fifo, count); + + uint16_t rem = total_len - count; + if (rem) { + rem = tu_min16(rem, info.len_wrap); + pipe_write_packet(info.ptr_wrap, fifo, rem); + count += rem; + } + + tu_fifo_advance_read_pointer(f, count); +} +// Read data sw fifo <-- hw fifo +static void pipe_read_packet_ff(tu_fifo_t *f, volatile void *fifo, uint16_t total_len) { tu_fifo_buffer_info_t info; - ops[dir].tu_fifo_get_info(f, &info); + tu_fifo_get_write_info(f, &info); - unsigned total_len = len; - len = TU_MIN(total_len, info.len_lin); - ops[dir].pipe_read_write(info.ptr_lin, fifo, len); + uint16_t count = tu_min16(total_len, info.len_lin); + pipe_read_packet(info.ptr_lin, fifo, count); - unsigned rem = total_len - len; + uint16_t rem = total_len - count; if (rem) { - len = TU_MIN(rem, info.len_wrap); - ops[dir].pipe_read_write(info.ptr_wrap, fifo, len); - rem -= len; + rem = tu_min16(rem, info.len_wrap); + pipe_read_packet(info.ptr_wrap, fifo, rem); + count += rem; } - ops[dir].tu_fifo_advance(f, total_len - rem); + + tu_fifo_advance_write_pointer(f, count); } +//--------------------------------------------------------------------+ +// Pipe Transfer +//--------------------------------------------------------------------+ + static bool pipe0_xfer_in(rusb2_reg_t* rusb) { pipe_state_t *pipe = &_dcd.pipe[0]; @@ -292,7 +311,7 @@ static bool pipe0_xfer_in(rusb2_reg_t* rusb) if (len) { if (pipe->ff) { - pipe_read_write_packet_ff((tu_fifo_t*)buf, (volatile void*)&rusb->CFIFO, len, TUSB_DIR_IN); + pipe_write_packet_ff((tu_fifo_t*)buf, (volatile void*)&rusb->CFIFO, len); } else { pipe_write_packet(buf, (volatile void*)&rusb->CFIFO, len); pipe->buf = (uint8_t*)buf + len; @@ -319,7 +338,7 @@ static bool pipe0_xfer_out(rusb2_reg_t* rusb) if (len) { if (pipe->ff) { - pipe_read_write_packet_ff((tu_fifo_t*)buf, (volatile void*)&rusb->CFIFO, len, TUSB_DIR_OUT); + pipe_read_packet_ff((tu_fifo_t*)buf, (volatile void*)&rusb->CFIFO, len); } else { pipe_read_packet(buf, (volatile void*)&rusb->CFIFO, len); pipe->buf = (uint8_t*)buf + len; @@ -357,7 +376,7 @@ static bool pipe_xfer_in(rusb2_reg_t* rusb, unsigned num) if (len) { if (pipe->ff) { - pipe_read_write_packet_ff((tu_fifo_t*)buf, (volatile void*)&rusb->D0FIFO, len, TUSB_DIR_IN); + pipe_write_packet_ff((tu_fifo_t*)buf, (volatile void*)&rusb->D0FIFO, len); } else { pipe_write_packet(buf, (volatile void*)&rusb->D0FIFO, len); pipe->buf = (uint8_t*)buf + len; @@ -391,7 +410,7 @@ static bool pipe_xfer_out(rusb2_reg_t* rusb, unsigned num) if (len) { if (pipe->ff) { - pipe_read_write_packet_ff((tu_fifo_t*)buf, (volatile void*)&rusb->D0FIFO, len, TUSB_DIR_OUT); + pipe_read_packet_ff((tu_fifo_t*)buf, (volatile void*)&rusb->D0FIFO, len); } else { pipe_read_packet(buf, (volatile void*)&rusb->D0FIFO, len); pipe->buf = (uint8_t*)buf + len; -- cgit v1.3.1 From c122e9df73331fa60d1713c7cc4cf46251b0cd76 Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 21 Jul 2023 19:06:36 +0700 Subject: implement hcd_edpt_abort_xfer() for EHCI, also move thing around a bit --- src/common/tusb_common.h | 2 + src/host/hcd.h | 1 + src/host/usbh.c | 10 ++- src/host/usbh.h | 1 + src/portable/ehci/ehci.c | 200 +++++++++++++++++++++++++++++------------------ src/portable/ehci/ehci.h | 19 +++-- 6 files changed, 147 insertions(+), 86 deletions(-) (limited to 'src/common/tusb_common.h') diff --git a/src/common/tusb_common.h b/src/common/tusb_common.h index 957491aa9..b3d9fc7cd 100644 --- a/src/common/tusb_common.h +++ b/src/common/tusb_common.h @@ -53,6 +53,8 @@ #define U32_TO_U8S_LE(_u32) TU_U32_BYTE0(_u32), TU_U32_BYTE1(_u32), TU_U32_BYTE2(_u32), TU_U32_BYTE3(_u32) #define TU_BIT(n) (1UL << (n)) + +// Generate a mask with bit from high (31) to low (0) set, e.g TU_GENMASK(3, 0) = 0b1111 #define TU_GENMASK(h, l) ( (UINT32_MAX << (l)) & (UINT32_MAX >> (31 - (h))) ) //--------------------------------------------------------------------+ diff --git a/src/host/hcd.h b/src/host/hcd.h index cbfffb349..90bfd79db 100644 --- a/src/host/hcd.h +++ b/src/host/hcd.h @@ -172,6 +172,7 @@ bool hcd_edpt_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_endpoint_t const bool hcd_edpt_xfer(uint8_t rhport, uint8_t dev_addr, 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 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 diff --git a/src/host/usbh.c b/src/host/usbh.c index bbf333d5f..15c48be47 100644 --- a/src/host/usbh.c +++ b/src/host/usbh.c @@ -718,9 +718,15 @@ bool tuh_edpt_abort_xfer(uint8_t daddr, uint8_t ep_addr) { uint8_t const dir = tu_edpt_dir(ep_addr); // skip if not busy - if (!dev->ep_status[epnum][dir].busy) return true; + TU_VERIFY(dev->ep_status[epnum][dir].busy); - return hcd_edpt_abort_xfer(dev->rhport, daddr, ep_addr); + bool const ret = hcd_edpt_abort_xfer(dev->rhport, daddr, ep_addr); + if (ret) { + // mark as ready if transfer is aborted + dev->ep_status[epnum][dir].busy = false; + } + + return ret; } //--------------------------------------------------------------------+ diff --git a/src/host/usbh.h b/src/host/usbh.h index d765f6744..0d56f40c9 100644 --- a/src/host/usbh.h +++ b/src/host/usbh.h @@ -176,6 +176,7 @@ bool tuh_edpt_xfer(tuh_xfer_t* xfer); bool tuh_edpt_open(uint8_t daddr, tusb_desc_endpoint_t const * desc_ep); // 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 tuh_edpt_abort_xfer(uint8_t daddr, uint8_t ep_addr); // Set Configuration (control transfer) diff --git a/src/portable/ehci/ehci.c b/src/portable/ehci/ehci.c index 0a26986d5..6388add08 100644 --- a/src/portable/ehci/ehci.c +++ b/src/portable/ehci/ehci.c @@ -48,8 +48,8 @@ #ifdef TUP_USBIP_CHIPIDEA_HS // NXP Transdimension: 8 elements #define FRAMELIST_SIZE_BIT_VALUE 7u - #define FRAMELIST_SIZE_USBCMD_VALUE (((FRAMELIST_SIZE_BIT_VALUE & 3) << EHCI_USBCMD_POS_FRAMELIST_SIZE) | \ - ((FRAMELIST_SIZE_BIT_VALUE >> 2) << EHCI_USBCMD_POS_NXP_FRAMELIST_SIZE_MSB)) + #define FRAMELIST_SIZE_USBCMD_VALUE (((FRAMELIST_SIZE_BIT_VALUE & 3) << EHCI_USBCMD_FRAMELIST_SIZE_SHIFT) | \ + ((FRAMELIST_SIZE_BIT_VALUE >> 2) << EHCI_USBCMD_CHIPIDEA_FRAMELIST_SIZE_MSB_SHIFT)) #else // STD EHCI: 256 elements #define FRAMELIST_SIZE_BIT_VALUE 2u @@ -132,24 +132,46 @@ TU_ATTR_WEAK void hcd_dcache_clean(void const* addr, uint32_t data_size) { (void TU_ATTR_WEAK void hcd_dcache_invalidate(void const* addr, uint32_t data_size) { (void) addr; (void) data_size; } TU_ATTR_WEAK void hcd_dcache_clean_invalidate(void const* addr, uint32_t data_size) { (void) addr; (void) data_size; } -TU_ATTR_ALWAYS_INLINE static inline ehci_link_t* list_get_period_head(uint8_t rhport, uint32_t interval_ms); -TU_ATTR_ALWAYS_INLINE static inline ehci_qhd_t* list_get_async_head(uint8_t rhport); - TU_ATTR_ALWAYS_INLINE static inline ehci_qhd_t* qhd_control(uint8_t dev_addr); TU_ATTR_ALWAYS_INLINE static inline ehci_qhd_t* qhd_next (ehci_qhd_t const * p_qhd); TU_ATTR_ALWAYS_INLINE static inline ehci_qhd_t* qhd_find_free (void); static ehci_qhd_t* qhd_get_from_addr (uint8_t dev_addr, uint8_t ep_addr); static void qhd_init(ehci_qhd_t *p_qhd, uint8_t dev_addr, tusb_desc_endpoint_t const * ep_desc); static void qhd_attach_qtd(ehci_qhd_t *qhd, ehci_qtd_t *qtd); +static void qhd_remove_qtd(ehci_qhd_t *qhd); TU_ATTR_ALWAYS_INLINE static inline ehci_qtd_t* qtd_control(uint8_t dev_addr); TU_ATTR_ALWAYS_INLINE static inline ehci_qtd_t* qtd_find_free (void); static void qtd_init (ehci_qtd_t* qtd, void const* buffer, uint16_t total_bytes); -static inline void list_insert (ehci_link_t *current, ehci_link_t *new, uint8_t new_type); -static inline ehci_link_t* list_next (ehci_link_t const *p_link); +TU_ATTR_ALWAYS_INLINE static inline ehci_link_t* list_get_period_head(uint8_t rhport, uint32_t interval_ms); +TU_ATTR_ALWAYS_INLINE static inline ehci_qhd_t* list_get_async_head(uint8_t rhport); +TU_ATTR_ALWAYS_INLINE static inline void list_insert (ehci_link_t *current, ehci_link_t *new, uint8_t new_type); +TU_ATTR_ALWAYS_INLINE static inline ehci_link_t* list_next (ehci_link_t const *p_link); static void list_remove_qhd_by_daddr(ehci_link_t* list_head, uint8_t dev_addr); +static void ehci_disable_schedule(ehci_registers_t* regs, bool is_period) { + // maybe have a timeout for status + if (is_period) { + regs->command_bm.periodic_enable = 0; + while(regs->status_bm.periodic_status) {} + } else { + regs->command_bm.async_enable = 0; + while(regs->status_bm.async_status) {} // should have a timeout + } +} + +static void ehci_enable_schedule(ehci_registers_t* regs, bool is_period) { + // maybe have a timeout for status + if (is_period) { + regs->command_bm.periodic_enable = 1; + while ( 0 == regs->status_bm.periodic_status ) {} + } else { + regs->command_bm.async_enable = 1; + while( 0 == regs->status_bm.async_status ) {} + } +} + //--------------------------------------------------------------------+ // HCD API //--------------------------------------------------------------------+ @@ -204,43 +226,6 @@ tusb_speed_t hcd_port_speed_get(uint8_t rhport) return (tusb_speed_t) ehci_data.regs->portsc_bm.nxp_port_speed; // NXP specific port speed } -static void list_remove_qhd_by_daddr(ehci_link_t* list_head, uint8_t dev_addr) { - ehci_link_t* prev = list_head; - - while (prev && !prev->terminate) { - ehci_qhd_t* qhd = (ehci_qhd_t*) (uintptr_t) list_next(prev); - - // done if loop back to head - if ( (uintptr_t) qhd == (uintptr_t) list_head) { - break; - } - - if ( qhd->dev_addr == dev_addr ) { - // TODO deactivate all TD, wait for QHD to inactive before removal - prev->address = qhd->next.address; - - // EHCI 4.8.2 link the removed qhd's next to async head (which always reachable by Host Controller) - qhd->next.address = ((uint32_t) list_head) | (EHCI_QTYPE_QHD << 1); - - if ( qhd->int_smask ) - { - // period list queue element is guarantee to be free in the next frame (1 ms) - qhd->used = 0; - }else - { - // async list use async advance handshake - // mark as removing, will completely re-usable when async advance isr occurs - qhd->removing = 1; - } - - hcd_dcache_clean(qhd, sizeof(ehci_qhd_t)); - hcd_dcache_clean(prev, sizeof(ehci_qhd_t)); - }else { - prev = list_next(prev); - } - } -} - // Close all opened endpoint belong to this device void hcd_device_close(uint8_t rhport, uint8_t daddr) { @@ -347,8 +332,7 @@ bool ehci_init(uint8_t rhport, uint32_t capability_reg, uint32_t operatial_reg) regs->nxp_tt_control = 0; //------------- USB CMD Register -------------// - regs->command |= TU_BIT(EHCI_USBCMD_POS_RUN_STOP) | TU_BIT(EHCI_USBCMD_POS_ASYNC_ENABLE) | - TU_BIT(EHCI_USBCMD_POS_PERIOD_ENABLE) | // TODO enable period list only there is int/iso endpoint + regs->command |= EHCI_USBCMD_RUN_STOP | EHCI_USBCMD_PERIOD_SCHEDULE_ENABLE | EHCI_USBCMD_ASYNC_SCHEDULE_ENABLE | FRAMELIST_SIZE_USBCMD_VALUE; //------------- ConfigFlag Register (skip) -------------// @@ -358,7 +342,7 @@ bool ehci_init(uint8_t rhport, uint32_t capability_reg, uint32_t operatial_reg) if (ehci_data.cap_regs->hcsparams_bm.port_power_control) { // mask out all change bits since they are Write 1 to clear uint32_t portsc = (regs->portsc & ~EHCI_PORTSC_MASK_W1C); - portsc |= ECHI_PORTSC_MASK_PORT_POWER; + portsc |= EHCI_PORTSC_MASK_PORT_POWER; regs->portsc = portsc; } @@ -455,20 +439,17 @@ bool hcd_edpt_xfer(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr, uint8_t * uint8_t const epnum = tu_edpt_number(ep_addr); uint8_t const dir = tu_edpt_dir(ep_addr); - ehci_qhd_t* qhd; + ehci_qhd_t* qhd = qhd_get_from_addr(dev_addr, ep_addr); ehci_qtd_t* qtd; if (epnum == 0) { - qhd = qhd_control(dev_addr); qtd = qtd_control(dev_addr); - qtd_init(qtd, buffer, buflen); // first data toggle is always 1 (data & setup stage) qtd->data_toggle = 1; qtd->pid = dir ? EHCI_PID_IN : EHCI_PID_OUT; } else { - qhd = qhd_get_from_addr(dev_addr, ep_addr); qtd = qtd_find_free(); TU_ASSERT(qtd); @@ -491,20 +472,34 @@ 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) { (void) rhport; - (void) dev_addr; - (void) ep_addr; - return false; + // TODO ISO not supported yet + ehci_qhd_t* qhd = qhd_get_from_addr(dev_addr, ep_addr); + ehci_qtd_t * volatile qtd = qhd->attached_qtd; + TU_VERIFY(qtd != NULL); // no queued transfer + + hcd_dcache_invalidate(qtd, sizeof(ehci_qtd_t)); + TU_VERIFY(qtd->active); // transfer is already complete + + // HC is still processing, disable HC list schedule before making changes + bool const is_period = (qhd->interval_ms > 0); + + ehci_disable_schedule(ehci_data.regs, is_period); + + // check active bit again just in case HC has just processed the TD + bool const still_active = qtd->active; + if (still_active) { + // remove TD from QH overlay + qhd->qtd_overlay.next.terminate = 1; + hcd_dcache_clean(qhd, sizeof(ehci_qhd_t)); + + // remove TD from QH software list + qhd_remove_qtd(qhd); + } -// uint8_t const epnum = tu_edpt_number(ep_addr); -// ehci_qhd_t* qhd; -// -// // TODO ISO not supported -// if (epnum == 0) { -// qhd = qhd_control(dev_addr); -// }else { -// qhd = qhd_get_from_addr(dev_addr, ep_addr); -// } + ehci_enable_schedule(ehci_data.regs, is_period); + + return still_active; // true if removed an active transfer } bool hcd_edpt_clear_stall(uint8_t daddr, uint8_t ep_addr) @@ -554,8 +549,12 @@ void port_connect_status_change_isr(uint8_t rhport) TU_ATTR_ALWAYS_INLINE static inline void qhd_xfer_complete_isr(ehci_qhd_t * qhd) { // examine TD attached to queue head - ehci_qtd_t * volatile qtd = (ehci_qtd_t * volatile) qhd->attached_qtd; - if (qtd == NULL) return; // no TD attached + ehci_qtd_t * volatile qtd = qhd->attached_qtd; + + if (qtd == NULL) { + return; // no TD attached + } + hcd_dcache_invalidate(qtd, sizeof(ehci_qtd_t)); // TD is still active, no need to process @@ -572,9 +571,7 @@ void qhd_xfer_complete_isr(ehci_qhd_t * qhd) { } // remove and free TD before invoking callback - qhd->attached_qtd = NULL; - qhd->attached_buffer = 0; - qtd->used = 0; // free QTD + qhd_remove_qtd(qhd); // notify usbh uint8_t const ep_addr = tu_edpt_addr(qhd->ep_number, dir); @@ -677,9 +674,7 @@ void qhd_xfer_error_isr(ehci_qhd_t * qhd) } // remove and free TD before invoking callback - qhd->attached_qtd = NULL; - qhd->attached_buffer = 0; - qtd->used = 0; // free QTD + qhd_remove_qtd(qhd); if (0 == qhd->ep_number ) { // control cannot be halted @@ -822,18 +817,55 @@ TU_ATTR_ALWAYS_INLINE static inline ehci_qhd_t* list_get_async_head(uint8_t rhpo return qhd_control(0); // control qhd of dev0 is used as async head } -// insert at head -static inline void list_insert(ehci_link_t *current, ehci_link_t *new, uint8_t new_type) +TU_ATTR_ALWAYS_INLINE static inline ehci_link_t* list_next(ehci_link_t const *p_link) { + return (ehci_link_t*) tu_align32(p_link->address); +} + +TU_ATTR_ALWAYS_INLINE static inline void list_insert(ehci_link_t *current, ehci_link_t *new, uint8_t new_type) { new->address = current->address; current->address = ((uint32_t) new) | (new_type << 1); } -static inline ehci_link_t* list_next(ehci_link_t const *p_link) -{ - return (ehci_link_t*) tu_align32(p_link->address); +// Remove all queue head belong to this device address +static void list_remove_qhd_by_daddr(ehci_link_t* list_head, uint8_t dev_addr) { + ehci_link_t* prev = list_head; + + while (prev && !prev->terminate) { + ehci_qhd_t* qhd = (ehci_qhd_t*) (uintptr_t) list_next(prev); + + // done if loop back to head + if ( (uintptr_t) qhd == (uintptr_t) list_head) { + break; + } + + if ( qhd->dev_addr == dev_addr ) { + // TODO deactivate all TD, wait for QHD to inactive before removal + prev->address = qhd->next.address; + + // EHCI 4.8.2 link the removed qhd's next to async head (which always reachable by Host Controller) + qhd->next.address = ((uint32_t) list_head) | (EHCI_QTYPE_QHD << 1); + + if ( qhd->int_smask ) + { + // period list queue element is guarantee to be free in the next frame (1 ms) + qhd->used = 0; + }else + { + // async list use async advance handshake + // mark as removing, will completely re-usable when async advance isr occurs + qhd->removing = 1; + } + + hcd_dcache_clean(qhd, sizeof(ehci_qhd_t)); + hcd_dcache_clean(prev, sizeof(ehci_qhd_t)); + }else { + prev = list_next(prev); + } + } } + //--------------------------------------------------------------------+ // Queue Header helper //--------------------------------------------------------------------+ @@ -856,8 +888,12 @@ TU_ATTR_ALWAYS_INLINE static inline ehci_qhd_t *qhd_next(ehci_qhd_t const *p_qhd return (ehci_qhd_t *) tu_align32(p_qhd->next.address); } -// Get queue head from address +// Get queue head from device + endpoint address static ehci_qhd_t *qhd_get_from_addr(uint8_t dev_addr, uint8_t ep_addr) { + if ( 0 == tu_edpt_number(ep_addr) ) { + return qhd_control(dev_addr); + } + ehci_qhd_t *qhd_pool = ehci_data.qhd_pool; for ( uint32_t i = 0; i < QHD_MAX; i++ ) { @@ -957,6 +993,16 @@ static void qhd_attach_qtd(ehci_qhd_t *qhd, ehci_qtd_t *qtd) { hcd_dcache_clean_invalidate(qhd, sizeof(ehci_qhd_t)); } +// Remove an attached TD from queue head +static void qhd_remove_qtd(ehci_qhd_t *qhd) { + ehci_qtd_t * volatile qtd = qhd->attached_qtd; + + qhd->attached_qtd = NULL; + qhd->attached_buffer = 0; + + qtd->used = 0; // free QTD +} + //--------------------------------------------------------------------+ // Queue TD helper //--------------------------------------------------------------------+ diff --git a/src/portable/ehci/ehci.h b/src/portable/ehci/ehci.h index 8338fb419..05de80539 100644 --- a/src/portable/ehci/ehci.h +++ b/src/portable/ehci/ehci.h @@ -289,12 +289,17 @@ enum { }; enum { - EHCI_USBCMD_POS_RUN_STOP = 0, - EHCI_USBCMD_POS_FRAMELIST_SIZE = 2, - EHCI_USBCMD_POS_PERIOD_ENABLE = 4, - EHCI_USBCMD_POS_ASYNC_ENABLE = 5, - EHCI_USBCMD_POS_NXP_FRAMELIST_SIZE_MSB = 15, - EHCI_USBCMD_POS_INTERRUPT_THRESHOLD = 16 + EHCI_USBCMD_FRAMELIST_SIZE_SHIFT = 2, // [2..3] + EHCI_USBCMD_CHIPIDEA_FRAMELIST_SIZE_MSB_SHIFT = 15, + EHCI_USBCMD_INTERRUPT_THRESHOLD_SHIFT = 16 +}; + +enum { + EHCI_USBCMD_RUN_STOP = TU_BIT(0), // [0..0] 1 = Run, 0 = Stop + EHCI_USBCMD_HCRESET = TU_BIT(1), // [1..1] SW write 1 to reset HC, clear by HC when complete + EHCI_USBCMD_PERIOD_SCHEDULE_ENABLE = TU_BIT(4), // [4..4] Enable periodic schedule + EHCI_USBCMD_ASYNC_SCHEDULE_ENABLE = TU_BIT(5), // [5..5] Enable async schedule + EHCI_USBCMD_INTR_ON_ASYNC_ADVANCE_DOORBELL = TU_BIT(6), // [6..6] Tell HC to interrupt next time it advances async list. Clear by HC }; enum { @@ -306,7 +311,7 @@ enum { EHCI_PORTSC_MASK_FORCE_RESUME = TU_BIT(6), EHCI_PORTSC_MASK_PORT_SUSPEND = TU_BIT(7), EHCI_PORTSC_MASK_PORT_RESET = TU_BIT(8), - ECHI_PORTSC_MASK_PORT_POWER = TU_BIT(12), + EHCI_PORTSC_MASK_PORT_POWER = TU_BIT(12), EHCI_PORTSC_MASK_W1C = EHCI_PORTSC_MASK_CONNECT_STATUS_CHANGE | -- cgit v1.3.1 From d2542560470de242dd8988d0b3c10d7df0496bb0 Mon Sep 17 00:00:00 2001 From: hathach Date: Mon, 24 Jul 2023 17:54:24 +0700 Subject: change dcache clean/invalidate return type to bool add tu_assert() check for aligned 32byte address for imxrt --- src/common/tusb_common.h | 13 +++++++------ src/host/hcd.h | 8 ++++---- src/portable/chipidea/ci_hs/ci_hs_imxrt.h | 15 +++++++++------ src/portable/chipidea/ci_hs/hcd_ci_hs.c | 12 ++++++------ src/portable/ehci/ehci.c | 9 ++++++--- 5 files changed, 32 insertions(+), 25 deletions(-) (limited to 'src/common/tusb_common.h') diff --git a/src/common/tusb_common.h b/src/common/tusb_common.h index 957491aa9..bae583c06 100644 --- a/src/common/tusb_common.h +++ b/src/common/tusb_common.h @@ -99,10 +99,9 @@ TU_ATTR_WEAK extern void* tusb_app_phys_to_virt(void *phys_addr); #define tu_varclr(_var) tu_memclr(_var, sizeof(*(_var))) // This is a backport of memset_s from c11 -TU_ATTR_ALWAYS_INLINE static inline int tu_memset_s(void *dest, size_t destsz, int ch, size_t count) -{ +TU_ATTR_ALWAYS_INLINE static inline int tu_memset_s(void *dest, size_t destsz, int ch, size_t count) { // TODO may check if desst and src is not NULL - if (count > destsz) { + if ( count > destsz ) { return -1; } memset(dest, ch, count); @@ -110,10 +109,9 @@ TU_ATTR_ALWAYS_INLINE static inline int tu_memset_s(void *dest, size_t destsz, i } // This is a backport of memcpy_s from c11 -TU_ATTR_ALWAYS_INLINE static inline int tu_memcpy_s(void *dest, size_t destsz, const void * src, size_t count ) -{ +TU_ATTR_ALWAYS_INLINE static inline int tu_memcpy_s(void *dest, size_t destsz, const void *src, size_t count) { // TODO may check if desst and src is not NULL - if (count > destsz) { + if ( count > destsz ) { return -1; } memcpy(dest, src, count); @@ -169,6 +167,9 @@ TU_ATTR_ALWAYS_INLINE static inline uint32_t tu_align32 (uint32_t value) { retur TU_ATTR_ALWAYS_INLINE static inline uint32_t tu_align4k (uint32_t value) { return (value & 0xFFFFF000UL); } TU_ATTR_ALWAYS_INLINE static inline uint32_t tu_offset4k(uint32_t value) { return (value & 0xFFFUL); } +TU_ATTR_ALWAYS_INLINE static inline bool tu_is_aligned32(uint32_t value) { return (value & 0x1FUL) == 0; } +TU_ATTR_ALWAYS_INLINE static inline bool tu_is_aligned64(uint64_t value) { return (value & 0x3FUL) == 0; } + //------------- Mathematics -------------// TU_ATTR_ALWAYS_INLINE static inline uint32_t tu_div_ceil(uint32_t v, uint32_t d) { return (v + d -1)/d; } diff --git a/src/host/hcd.h b/src/host/hcd.h index 3355c18b2..52fcc834e 100644 --- a/src/host/hcd.h +++ b/src/host/hcd.h @@ -104,21 +104,21 @@ typedef struct uint8_t speed; } hcd_devtree_info_t; -//--------------------------------------------------------------------+ +//-------------------------------------------------------------- // Memory API //--------------------------------------------------------------------+ // clean/flush data cache: write cache -> memory. // Required before an DMA TX transfer to make sure data is in memory -void hcd_dcache_clean(void const* addr, uint32_t data_size) TU_ATTR_WEAK; +bool hcd_dcache_clean(void const* addr, uint32_t data_size) TU_ATTR_WEAK; // invalidate data cache: mark cache as invalid, next read will read from memory // Required BOTH before and after an DMA RX transfer -void hcd_dcache_invalidate(void const* addr, uint32_t data_size) TU_ATTR_WEAK; +bool hcd_dcache_invalidate(void const* addr, uint32_t data_size) TU_ATTR_WEAK; // clean and invalidate data cache // Required before an DMA transfer where memory is both read/write by DMA -void hcd_dcache_clean_invalidate(void const* addr, uint32_t data_size) TU_ATTR_WEAK; +bool hcd_dcache_clean_invalidate(void const* addr, uint32_t data_size) TU_ATTR_WEAK; //--------------------------------------------------------------------+ // Controller API diff --git a/src/portable/chipidea/ci_hs/ci_hs_imxrt.h b/src/portable/chipidea/ci_hs/ci_hs_imxrt.h index 96f0ba766..c59c107ff 100644 --- a/src/portable/chipidea/ci_hs/ci_hs_imxrt.h +++ b/src/portable/chipidea/ci_hs/ci_hs_imxrt.h @@ -68,31 +68,34 @@ TU_ATTR_ALWAYS_INLINE static inline bool imxrt_is_cache_mem(uintptr_t addr) { return !(0x20000000 <= addr && addr < 0x20100000); } -TU_ATTR_ALWAYS_INLINE static inline void imxrt_dcache_clean(void const* addr, uint32_t data_size) { +TU_ATTR_ALWAYS_INLINE static inline bool imxrt_dcache_clean(void const* addr, uint32_t data_size) { const uintptr_t addr32 = (uintptr_t) addr; if (imxrt_is_cache_mem(addr32)) { + TU_ASSERT(tu_is_aligned32(addr32)); SCB_CleanDCache_by_Addr((uint32_t *) addr32, (int32_t) data_size); } + return true; } -TU_ATTR_ALWAYS_INLINE static inline void imxrt_dcache_invalidate(void const* addr, uint32_t data_size) { +TU_ATTR_ALWAYS_INLINE static inline bool imxrt_dcache_invalidate(void const* addr, uint32_t data_size) { const uintptr_t addr32 = (uintptr_t) addr; if (imxrt_is_cache_mem(addr32)) { // Invalidating does not push cached changes back to RAM so we need to be // *very* careful when we do it. If we're not aligned, then we risk resetting // values back to their RAM state. - // if (addr32 % 32 != 0) { - // TU_BREAKPOINT(); - // } + TU_ASSERT(tu_is_aligned32(addr32)); SCB_InvalidateDCache_by_Addr((void*) addr32, (int32_t) data_size); } + return true; } -TU_ATTR_ALWAYS_INLINE static inline void imxrt_dcache_clean_invalidate(void const* addr, uint32_t data_size) { +TU_ATTR_ALWAYS_INLINE static inline bool imxrt_dcache_clean_invalidate(void const* addr, uint32_t data_size) { const uintptr_t addr32 = (uintptr_t) addr; if (imxrt_is_cache_mem(addr32)) { + TU_ASSERT(tu_is_aligned32(addr32)); SCB_CleanInvalidateDCache_by_Addr((uint32_t *) addr32, (int32_t) data_size); } + return true; } #endif diff --git a/src/portable/chipidea/ci_hs/hcd_ci_hs.c b/src/portable/chipidea/ci_hs/hcd_ci_hs.c index 56167b8f6..6ee91e18e 100644 --- a/src/portable/chipidea/ci_hs/hcd_ci_hs.c +++ b/src/portable/chipidea/ci_hs/hcd_ci_hs.c @@ -41,16 +41,16 @@ #if CFG_TUSB_MCU == OPT_MCU_MIMXRT1XXX #include "ci_hs_imxrt.h" - void hcd_dcache_clean(void const* addr, uint32_t data_size) { - imxrt_dcache_clean(addr, data_size); + bool hcd_dcache_clean(void const* addr, uint32_t data_size) { + return imxrt_dcache_clean(addr, data_size); } - void hcd_dcache_invalidate(void const* addr, uint32_t data_size) { - imxrt_dcache_invalidate(addr, data_size); + bool hcd_dcache_invalidate(void const* addr, uint32_t data_size) { + return imxrt_dcache_invalidate(addr, data_size); } - void hcd_dcache_clean_invalidate(void const* addr, uint32_t data_size) { - 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) diff --git a/src/portable/ehci/ehci.c b/src/portable/ehci/ehci.c index 38711e382..6dfaab2a2 100644 --- a/src/portable/ehci/ehci.c +++ b/src/portable/ehci/ehci.c @@ -162,16 +162,19 @@ static void qtd_init (ehci_qtd_t* qtd, void const* buffer, uint16_t total_bytes) static inline void list_insert (ehci_link_t *current, ehci_link_t *new, uint8_t new_type); static inline ehci_link_t* list_next (ehci_link_t const *p_link); -TU_ATTR_WEAK void hcd_dcache_clean(void const* addr, uint32_t data_size) { +TU_ATTR_WEAK bool hcd_dcache_clean(void const* addr, uint32_t data_size) { (void) addr; (void) data_size; + return true; } -TU_ATTR_WEAK void hcd_dcache_invalidate(void const* addr, uint32_t data_size) { +TU_ATTR_WEAK bool hcd_dcache_invalidate(void const* addr, uint32_t data_size) { (void) addr; (void) data_size; + return true; } -TU_ATTR_WEAK void hcd_dcache_clean_invalidate(void const* addr, uint32_t data_size) { +TU_ATTR_WEAK bool hcd_dcache_clean_invalidate(void const* addr, uint32_t data_size) { (void) addr; (void) data_size; + return true; } //--------------------------------------------------------------------+ -- cgit v1.3.1 From b8b01c10758043d318716569e693912f3e02c75b Mon Sep 17 00:00:00 2001 From: hathach Date: Tue, 8 Aug 2023 21:59:36 +0700 Subject: update to dcd ip3511 to add work-around for lpc54628 usb hs errata USB.1 and USB.2 msc is mounted, but device couldn't work reliably and got constant reset due to other errata probably. --- .idea/cmake.xml | 4 +- hw/bsp/lpc54/family.c | 6 +- hw/bsp/lpc54/family.cmake | 1 + src/common/tusb_common.h | 5 +- src/common/tusb_mcu.h | 8 +- src/portable/nxp/lpc_ip3511/dcd_lpc_ip3511.c | 266 ++++++++++++++++----------- 6 files changed, 170 insertions(+), 120 deletions(-) (limited to 'src/common/tusb_common.h') diff --git a/.idea/cmake.xml b/.idea/cmake.xml index 76143ba10..4a69d02cf 100644 --- a/.idea/cmake.xml +++ b/.idea/cmake.xml @@ -30,7 +30,8 @@ - + + @@ -51,6 +52,7 @@ + \ No newline at end of file diff --git a/hw/bsp/lpc54/family.c b/hw/bsp/lpc54/family.c index 108a7d783..7411c72d4 100644 --- a/hw/bsp/lpc54/family.c +++ b/hw/bsp/lpc54/family.c @@ -70,13 +70,11 @@ //--------------------------------------------------------------------+ // Forward USB interrupt events to TinyUSB IRQ Handler //--------------------------------------------------------------------+ -void USB0_IRQHandler(void) -{ +void USB0_IRQHandler(void) { tud_int_handler(0); } -void USB1_IRQHandler(void) -{ +void USB1_IRQHandler(void) { tud_int_handler(1); } diff --git a/hw/bsp/lpc54/family.cmake b/hw/bsp/lpc54/family.cmake index 0512fe31f..b016441c1 100644 --- a/hw/bsp/lpc54/family.cmake +++ b/hw/bsp/lpc54/family.cmake @@ -59,6 +59,7 @@ function(add_board_target BOARD_TARGET) BOARD_TUD_MAX_SPEED=OPT_MODE_FULL_SPEED BOARD_TUH_MAX_SPEED=OPT_MODE_HIGH_SPEED CFG_TUH_MEM_SECTION=__attribute__\(\(section\(\"m_usb_global\"\)\)\) + #CFG_TUD_MEM_SECTION=__attribute__\(\(section\(\"m_usb_global\"\)\)\) ) endif () diff --git a/src/common/tusb_common.h b/src/common/tusb_common.h index 25f85e501..c303c6eaf 100644 --- a/src/common/tusb_common.h +++ b/src/common/tusb_common.h @@ -159,11 +159,12 @@ TU_ATTR_ALWAYS_INLINE static inline uint16_t tu_max16 (uint16_t x, uint16_t y) { TU_ATTR_ALWAYS_INLINE static inline uint32_t tu_max32 (uint32_t x, uint32_t y) { return (x > y) ? x : y; } //------------- Align -------------// -TU_ATTR_ALWAYS_INLINE static inline uint32_t tu_align(uint32_t value, uint32_t alignment) -{ +TU_ATTR_ALWAYS_INLINE static inline uint32_t tu_align(uint32_t value, uint32_t alignment) { return value & ((uint32_t) ~(alignment-1)); } +TU_ATTR_ALWAYS_INLINE static inline uint32_t tu_align4 (uint32_t value) { return (value & 0xFFFFFFFCUL); } +TU_ATTR_ALWAYS_INLINE static inline uint32_t tu_align8 (uint32_t value) { return (value & 0xFFFFFFF8UL); } TU_ATTR_ALWAYS_INLINE static inline uint32_t tu_align16 (uint32_t value) { return (value & 0xFFFFFFF0UL); } TU_ATTR_ALWAYS_INLINE static inline uint32_t tu_align32 (uint32_t value) { return (value & 0xFFFFFFE0UL); } TU_ATTR_ALWAYS_INLINE static inline uint32_t tu_align4k (uint32_t value) { return (value & 0xFFFFF000UL); } diff --git a/src/common/tusb_mcu.h b/src/common/tusb_mcu.h index 89f89182e..35f94efbc 100644 --- a/src/common/tusb_mcu.h +++ b/src/common/tusb_mcu.h @@ -58,6 +58,7 @@ // NXP //--------------------------------------------------------------------+ #if TU_CHECK_MCU(OPT_MCU_LPC11UXX, OPT_MCU_LPC13XX, OPT_MCU_LPC15XX) + #define TUP_USBIP_IP3511 #define TUP_DCD_ENDPOINT_MAX 5 #elif TU_CHECK_MCU(OPT_MCU_LPC175X_6X, OPT_MCU_LPC177X_8X, OPT_MCU_LPC40XX) @@ -66,14 +67,17 @@ #define TUP_OHCI_RHPORTS 2 #elif TU_CHECK_MCU(OPT_MCU_LPC51UXX) + #define TUP_USBIP_IP3511 #define TUP_DCD_ENDPOINT_MAX 5 -#elif TU_CHECK_MCU(OPT_MCU_LPC54XXX) +#elif TU_CHECK_MCU(OPT_MCU_LPC54) // TODO USB0 has 5, USB1 has 6 + #define TUP_USBIP_IP3511 #define TUP_DCD_ENDPOINT_MAX 6 -#elif TU_CHECK_MCU(OPT_MCU_LPC55XX) +#elif TU_CHECK_MCU(OPT_MCU_LPC55) // TODO USB0 has 5, USB1 has 6 + #define TUP_USBIP_IP3511 #define TUP_DCD_ENDPOINT_MAX 6 #elif TU_CHECK_MCU(OPT_MCU_LPC18XX, OPT_MCU_LPC43XX) diff --git a/src/portable/nxp/lpc_ip3511/dcd_lpc_ip3511.c b/src/portable/nxp/lpc_ip3511/dcd_lpc_ip3511.c index 7ca698a93..f4ed09d83 100644 --- a/src/portable/nxp/lpc_ip3511/dcd_lpc_ip3511.c +++ b/src/portable/nxp/lpc_ip3511/dcd_lpc_ip3511.c @@ -34,18 +34,13 @@ * - LPC54114 * - LPC55s69 */ -#if CFG_TUD_ENABLED && ( CFG_TUSB_MCU == OPT_MCU_LPC11UXX || \ - CFG_TUSB_MCU == OPT_MCU_LPC13XX || \ - CFG_TUSB_MCU == OPT_MCU_LPC15XX || \ - CFG_TUSB_MCU == OPT_MCU_LPC51UXX || \ - CFG_TUSB_MCU == OPT_MCU_LPC54XXX || \ - CFG_TUSB_MCU == OPT_MCU_LPC55XX) +#if CFG_TUD_ENABLED && defined(TUP_USBIP_IP3511) //--------------------------------------------------------------------+ // INCLUDE //--------------------------------------------------------------------+ -#if CFG_TUSB_MCU == OPT_MCU_LPC11UXX || CFG_TUSB_MCU == OPT_MCU_LPC13XX || CFG_TUSB_MCU == OPT_MCU_LPC15XX +#if TU_CHECK_MCU(OPT_MCU_LPC11UXX, OPT_MCU_LPC13XX, OPT_MCU_LPC15XX) // LPCOpen #include "chip.h" #else @@ -80,7 +75,7 @@ typedef struct { enum { NBYTES_ISO_FS_MAX = 1023, // FS ISO NBYTES_ISO_HS_MAX = 1024, // HS ISO - NBYTES_CBI_FS_MAX = 64, // FS control/bulk/interrupt + NBYTES_CBI_FS_MAX = 64, // FS control/bulk/interrupt. TODO some FS can do burst with higher size e.g 1024. Need to test NBYTES_CBI_HS_MAX = 32767 // can be up to all 15-bit, but only tested with 4096 }; @@ -90,26 +85,36 @@ enum { }; enum { - CMDSTAT_DEVICE_ADDR_MASK = TU_BIT(7 )-1, - CMDSTAT_DEVICE_ENABLE_MASK = TU_BIT(7 ), - CMDSTAT_SETUP_RECEIVED_MASK = TU_BIT(8 ), - CMDSTAT_DEVICE_CONNECT_MASK = TU_BIT(16), // reflect the soft-connect only, does not reflect the actual attached state - CMDSTAT_DEVICE_SUSPEND_MASK = TU_BIT(17), - // 23-22 is link speed (only available for HighSpeed port) - CMDSTAT_CONNECT_CHANGE_MASK = TU_BIT(24), - CMDSTAT_SUSPEND_CHANGE_MASK = TU_BIT(25), - CMDSTAT_RESET_CHANGE_MASK = TU_BIT(26), - CMDSTAT_VBUS_DEBOUNCED_MASK = TU_BIT(28), + DEVCMDSTAT_DEVICE_ADDR_MASK = TU_BIT(7 )-1, + DEVCMDSTAT_DEVICE_ENABLE_MASK = TU_BIT(7 ), + DEVCMDSTAT_SETUP_RECEIVED_MASK = TU_BIT(8 ), + DEVCMDSTAT_DEVICE_CONNECT_MASK = TU_BIT(16), // reflect the soft-connect only, does not reflect the actual attached state + DEVCMDSTAT_DEVICE_SUSPEND_MASK = TU_BIT(17), + // 23-22 is link speed (only available for HighSpeed port) + DEVCMDSTAT_CONNECT_CHANGE_MASK = TU_BIT(24), + DEVCMDSTAT_SUSPEND_CHANGE_MASK = TU_BIT(25), + DEVCMDSTAT_RESET_CHANGE_MASK = TU_BIT(26), + DEVCMDSTAT_VBUS_DEBOUNCED_MASK = TU_BIT(28), }; enum { - CMDSTAT_SPEED_SHIFT = 22 + DEVCMDSTAT_SPEED_SHIFT = 22 }; //--------------------------------------------------------------------+ // Endpoint Command/Status List //--------------------------------------------------------------------+ +// EP Command/Status field definition +enum { + EPCS_TYPE = TU_BIT(26), + EPCS_RF_TV = TU_BIT(27), + EPCS_TOGGLE_RESET = TU_BIT(28), + EPCS_STALL = TU_BIT(29), + EPCS_DISABLED = TU_BIT(30), + EPCS_ACTIVE = TU_BIT(31), +}; + // Endpoint Command/Status typedef union TU_ATTR_PACKED { @@ -133,8 +138,8 @@ typedef union TU_ATTR_PACKED volatile struct { uint32_t TU_RESERVED : 26; - uint32_t is_iso : 1 ; - uint32_t toggle_mode : 1 ; + uint32_t type : 1 ; + uint32_t rf_tv : 1 ; // rate feedback or toggle value uint32_t toggle_reset : 1 ; uint32_t stall : 1 ; uint32_t disable : 1 ; @@ -180,6 +185,7 @@ typedef struct CFG_TUD_MEM_SECTION TU_ATTR_ALIGNED(256) static dcd_data_t _dcd; // Dummy buffer to fix ZLPs overwriting the buffer (probably an USB/DMA controller bug) +// TODO find way to save memory CFG_TUD_MEM_SECTION TU_ATTR_ALIGNED(64) static uint8_t dummy[8]; //--------------------------------------------------------------------+ @@ -188,59 +194,73 @@ CFG_TUD_MEM_SECTION TU_ATTR_ALIGNED(64) static uint8_t dummy[8]; typedef struct { - dcd_registers_t* regs; // registers - const tusb_speed_t max_speed; // max link speed - const IRQn_Type irqnum; // IRQ number - const uint8_t ep_pairs; // Max bi-directional Endpoints + dcd_registers_t* regs; // registers + const bool is_highspeed; // max link speed + const IRQn_Type irqnum; // IRQ number + const uint8_t ep_pairs; // Max bi-directional Endpoints }dcd_controller_t; #ifdef INCLUDE_FSL_DEVICE_REGISTERS -static const dcd_controller_t _dcd_controller[] = -{ - { .regs = (dcd_registers_t*) USB0_BASE , .max_speed = TUSB_SPEED_FULL, .irqnum = USB0_IRQn, .ep_pairs = FSL_FEATURE_USB_EP_NUM }, +static const dcd_controller_t _dcd_controller[] = { + { .regs = (dcd_registers_t*) USB0_BASE , .is_highspeed = false, .irqnum = USB0_IRQn, .ep_pairs = FSL_FEATURE_USB_EP_NUM }, #if defined(FSL_FEATURE_SOC_USBHSD_COUNT) && FSL_FEATURE_SOC_USBHSD_COUNT - { .regs = (dcd_registers_t*) USBHSD_BASE, .max_speed = TUSB_SPEED_HIGH, .irqnum = USB1_IRQn, .ep_pairs = FSL_FEATURE_USBHSD_EP_NUM } + { .regs = (dcd_registers_t*) USBHSD_BASE, .is_highspeed = true, .irqnum = USB1_IRQn, .ep_pairs = FSL_FEATURE_USBHSD_EP_NUM } #endif }; #else -static const dcd_controller_t _dcd_controller[] = -{ - { .regs = (dcd_registers_t*) LPC_USB0_BASE, .max_speed = TUSB_SPEED_FULL, .irqnum = USB0_IRQn, .ep_pairs = 5 }, +static const dcd_controller_t _dcd_controller[] = { + { .regs = (dcd_registers_t*) LPC_USB0_BASE, .is_highspeed = false, .irqnum = USB0_IRQn, .ep_pairs = 5 }, }; #endif +#if defined(FSL_FEATURE_SOC_USBHSD_COUNT) && FSL_FEATURE_SOC_USBHSD_COUNT + #define IP3511_HAS_HIGHSPEED +#endif + //--------------------------------------------------------------------+ // INTERNAL OBJECT & FUNCTION DECLARATION //--------------------------------------------------------------------+ -static inline uint16_t get_buf_offset(void const * buffer) -{ +TU_ATTR_ALWAYS_INLINE static inline uint16_t get_buf_offset(void const * buffer) { uint32_t addr = (uint32_t) buffer; TU_ASSERT( (addr & 0x3f) == 0, 0 ); return ( (addr >> 6) & 0xFFFFUL ) ; } -static inline uint8_t ep_addr2id(uint8_t ep_addr) -{ +TU_ATTR_ALWAYS_INLINE static inline uint8_t ep_addr2id(uint8_t ep_addr) { return 2*(ep_addr & 0x0F) + ((ep_addr & TUSB_DIR_IN_MASK) ? 1 : 0); } +TU_ATTR_ALWAYS_INLINE static inline bool ep_is_iso(ep_cmd_sts_t* ep_cs, bool is_highspeed) { + return is_highspeed ? (ep_cs[0].cmd_sts.type && !ep_cs[0].cmd_sts.rf_tv) : ep_cs->cmd_sts.type; +} + +TU_ATTR_ALWAYS_INLINE static inline bool ep_is_bulk(ep_cmd_sts_t* ep_cs) { + return (ep_cs[0].cmd_sts.type == 0) && (ep_cs[0].cmd_sts.rf_tv == 0); +} + +TU_ATTR_ALWAYS_INLINE static inline ep_cmd_sts_t* get_ep_cs(uint8_t ep_id) { + return _dcd.ep[ep_id]; +} + +TU_ATTR_ALWAYS_INLINE static inline bool rhport_is_highspeed(uint8_t rhport) { + return _dcd_controller[rhport].is_highspeed; +} + //--------------------------------------------------------------------+ // CONTROLLER API //--------------------------------------------------------------------+ -static void prepare_setup_packet(uint8_t rhport) -{ - if (_dcd_controller[rhport].max_speed == TUSB_SPEED_FULL ) - { - _dcd.ep[0][1].buffer_fs.offset = get_buf_offset(_dcd.setup_packet); - }else - { - _dcd.ep[0][1].buffer_hs.offset = get_buf_offset(_dcd.setup_packet); +static void prepare_setup_packet(uint8_t rhport) { + uint16_t const buf_offset = get_buf_offset(_dcd.setup_packet); + if ( _dcd_controller[rhport].is_highspeed ) { + _dcd.ep[0][1].buffer_hs.offset = buf_offset; + } else { + _dcd.ep[0][1].buffer_fs.offset = buf_offset; } } @@ -268,8 +288,8 @@ void dcd_init(uint8_t rhport) dcd_reg->DATABUFSTART = tu_align((uint32_t) &_dcd, TU_BIT(22)); // 22-bit alignment dcd_reg->INTSTAT |= dcd_reg->INTSTAT; // clear all pending interrupt dcd_reg->INTEN = INT_DEVICE_STATUS_MASK; - dcd_reg->DEVCMDSTAT |= CMDSTAT_DEVICE_ENABLE_MASK | CMDSTAT_DEVICE_CONNECT_MASK | - CMDSTAT_RESET_CHANGE_MASK | CMDSTAT_CONNECT_CHANGE_MASK | CMDSTAT_SUSPEND_CHANGE_MASK; + dcd_reg->DEVCMDSTAT |= DEVCMDSTAT_DEVICE_ENABLE_MASK | DEVCMDSTAT_DEVICE_CONNECT_MASK | + DEVCMDSTAT_RESET_CHANGE_MASK | DEVCMDSTAT_CONNECT_CHANGE_MASK | DEVCMDSTAT_SUSPEND_CHANGE_MASK; NVIC_ClearPendingIRQ(_dcd_controller[rhport].irqnum); } @@ -291,7 +311,7 @@ void dcd_set_address(uint8_t rhport, uint8_t dev_addr) // Response with status first before changing device address dcd_edpt_xfer(rhport, tu_edpt_addr(0, TUSB_DIR_IN), NULL, 0); - dcd_reg->DEVCMDSTAT &= ~CMDSTAT_DEVICE_ADDR_MASK; + dcd_reg->DEVCMDSTAT &= ~DEVCMDSTAT_DEVICE_ADDR_MASK; dcd_reg->DEVCMDSTAT |= dev_addr; } @@ -303,13 +323,13 @@ void dcd_remote_wakeup(uint8_t rhport) void dcd_connect(uint8_t rhport) { dcd_registers_t* dcd_reg = _dcd_controller[rhport].regs; - dcd_reg->DEVCMDSTAT |= CMDSTAT_DEVICE_CONNECT_MASK; + dcd_reg->DEVCMDSTAT |= DEVCMDSTAT_DEVICE_CONNECT_MASK; } void dcd_disconnect(uint8_t rhport) { dcd_registers_t* dcd_reg = _dcd_controller[rhport].regs; - dcd_reg->DEVCMDSTAT &= ~CMDSTAT_DEVICE_CONNECT_MASK; + dcd_reg->DEVCMDSTAT &= ~DEVCMDSTAT_DEVICE_CONNECT_MASK; } void dcd_sof_enable(uint8_t rhport, bool en) @@ -340,19 +360,39 @@ void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr) _dcd.ep[ep_id][0].cmd_sts.stall = 0; _dcd.ep[ep_id][0].cmd_sts.toggle_reset = 1; - _dcd.ep[ep_id][0].cmd_sts.toggle_mode = 0; + _dcd.ep[ep_id][0].cmd_sts.rf_tv = 0; } bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const * p_endpoint_desc) { //------------- Prepare Queue Head -------------// uint8_t ep_id = ep_addr2id(p_endpoint_desc->bEndpointAddress); + ep_cmd_sts_t* ep_cs = get_ep_cs(ep_id); // Check if endpoint is available - TU_ASSERT( _dcd.ep[ep_id][0].cmd_sts.disable && _dcd.ep[ep_id][1].cmd_sts.disable ); + TU_ASSERT( ep_cs[0].cmd_sts.disable && ep_cs[1].cmd_sts.disable ); edpt_reset(rhport, ep_id); - _dcd.ep[ep_id][0].cmd_sts.is_iso = (p_endpoint_desc->bmAttributes.xfer == TUSB_XFER_ISOCHRONOUS); + + switch (p_endpoint_desc->bmAttributes.xfer) { + case TUSB_XFER_ISOCHRONOUS: + ep_cs[0].cmd_sts.type = 1; + break; + + case TUSB_XFER_INTERRUPT: + // What is interrupt endpoint in rate feedback mode ? + if ( rhport_is_highspeed(rhport) ) { + ep_cs[0].cmd_sts.type = 1; + ep_cs[0].cmd_sts.rf_tv = 1; + } + break; + + case TUSB_XFER_BULK: + // nothing to do both type and rf_tv are 0 + break; + + default: break; + } // Enable EP interrupt dcd_registers_t* dcd_reg = _dcd_controller[rhport].regs; @@ -379,42 +419,50 @@ void dcd_edpt_close(uint8_t rhport, uint8_t ep_addr) _dcd.ep[ep_id][0].cmd_sts.disable = _dcd.ep[ep_id][1].cmd_sts.disable = 1; } -static void prepare_ep_xfer(uint8_t rhport, uint8_t ep_id, uint16_t buf_offset, uint16_t total_bytes) -{ +static void prepare_ep_xfer(uint8_t rhport, uint8_t ep_id, uint16_t buf_offset, uint16_t total_bytes) { uint16_t nbytes; - - if (_dcd_controller[rhport].max_speed == TUSB_SPEED_FULL ) - { - nbytes = tu_min16(total_bytes, _dcd.ep[ep_id][0].cmd_sts.is_iso ? NBYTES_ISO_FS_MAX : NBYTES_CBI_FS_MAX); - _dcd.ep[ep_id][0].buffer_fs.offset = buf_offset; - _dcd.ep[ep_id][0].buffer_fs.nbytes = nbytes; - }else - { - nbytes = tu_min16(total_bytes, NBYTES_CBI_HS_MAX); - _dcd.ep[ep_id][0].buffer_hs.offset = buf_offset; - _dcd.ep[ep_id][0].buffer_hs.nbytes = nbytes; + ep_cmd_sts_t* ep_cs = get_ep_cs(ep_id); + + const bool is_iso = ep_is_iso(ep_cs, _dcd_controller[rhport].is_highspeed); + + if ( rhport_is_highspeed(rhport) ) { + nbytes = tu_min16(total_bytes, is_iso ? NBYTES_ISO_HS_MAX : NBYTES_CBI_HS_MAX); + #if TU_CHECK_MCU(OPT_MCU_LPC54) + // LPC54 Errata USB.1: In USB high-speed device mode, the NBytes field does not decrement after BULK OUT transfer. + // Suggested Work-around: Program the NByte to the max packet size (512) + // Actual Work-around: round up NByte to multiple of 4. + // Note: this can cause buffer overflowed and corrupt data if host send more data than total_bytes + if ( (ep_id > 1) && (ep_id & 0x01) == 0 && ep_is_bulk(ep_cs) ) { + if ( nbytes & 0x03 ) { + nbytes = tu_align4(nbytes) + 4; + } + } + #endif + + ep_cs[0].buffer_hs.offset = buf_offset; + ep_cs[0].buffer_hs.nbytes = nbytes; + }else { + nbytes = tu_min16(total_bytes, is_iso ? NBYTES_ISO_FS_MAX : NBYTES_CBI_FS_MAX); + ep_cs[0].buffer_fs.offset = buf_offset; + ep_cs[0].buffer_fs.nbytes = nbytes; } _dcd.dma[ep_id].nbytes = nbytes; - - _dcd.ep[ep_id][0].cmd_sts.active = 1; + ep_cs[0].cmd_sts.active = 1; } -bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t* buffer, uint16_t total_bytes) -{ +bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t* buffer, uint16_t total_bytes) { uint8_t const ep_id = ep_addr2id(ep_addr); + if (!buffer || total_bytes == 0) { + // Although having no data, ZLPs can cause buffer overwritten to zeroes. Probably due to USB/DMA controller side + // effect/bug. Assigned buffer offset to (valid) dummy to prevent overwriting to DATABUFSTART + buffer = (uint8_t *) (uint32_t) dummy; + } + tu_memclr(&_dcd.dma[ep_id], sizeof(xfer_dma_t)); _dcd.dma[ep_id].total_bytes = total_bytes; - if (!buffer) - { - // Although having no data, ZLPs can cause buffer overwritten to zeroes. - // Probably due to USB/DMA controller side effect/bug. - // Assigned buffer offset to (valid) dummy to prevent overwriting to DATABUFSTART - buffer = (uint8_t*)(uint32_t)dummy; - } - prepare_ep_xfer(rhport, ep_id, get_buf_offset(buffer), total_bytes); return true; @@ -441,23 +489,19 @@ static void bus_reset(uint8_t rhport) dcd_reg->EPSKIP = 0xFFFFFFFF; dcd_reg->INTSTAT = dcd_reg->INTSTAT; // clear all pending interrupt - dcd_reg->DEVCMDSTAT |= CMDSTAT_SETUP_RECEIVED_MASK; // clear setup received interrupt + dcd_reg->DEVCMDSTAT |= DEVCMDSTAT_SETUP_RECEIVED_MASK; // clear setup received interrupt dcd_reg->INTEN = INT_DEVICE_STATUS_MASK | TU_BIT(0) | TU_BIT(1); // enable device status & control endpoints } -static void process_xfer_isr(uint8_t rhport, uint32_t int_status) -{ +static void process_xfer_isr(uint8_t rhport, uint32_t int_status) { uint8_t const max_ep = 2*_dcd_controller[rhport].ep_pairs; - for(uint8_t ep_id = 0; ep_id < max_ep; ep_id++ ) - { - if ( tu_bit_test(int_status, ep_id) ) - { + for(uint8_t ep_id = 0; ep_id < max_ep; ep_id++ ) { + if ( tu_bit_test(int_status, ep_id) ) { ep_cmd_sts_t * ep_cs = &_dcd.ep[ep_id][0]; xfer_dma_t* xfer_dma = &_dcd.dma[ep_id]; - if ( ep_id == 0 || ep_id == 1) - { + if ( ep_id <= 1 ) { // For control endpoint, we need to manually clear Active bit ep_cs->cmd_sts.active = 0; } @@ -465,26 +509,29 @@ static void process_xfer_isr(uint8_t rhport, uint32_t int_status) uint16_t buf_offset; uint16_t buf_nbytes; - if (_dcd_controller[rhport].max_speed == TUSB_SPEED_FULL) - { - buf_offset = ep_cs->buffer_fs.offset; - buf_nbytes = ep_cs->buffer_fs.nbytes; - }else - { + if ( rhport_is_highspeed(rhport) ) { buf_offset = ep_cs->buffer_hs.offset; buf_nbytes = ep_cs->buffer_hs.nbytes; + + #if TU_CHECK_MCU(OPT_MCU_LPC54) + // LPC54 Errata USB.2: In USB high-speed device mode, the NBytes field is not correct after BULK IN transfer + // There is no work-around. For EP in transfer, the NByte value can be ignored after a packet is transmitted. + if ( (ep_id > 1) && (ep_id & 0x01) == 1 && ep_is_bulk(ep_cs) ) { + buf_nbytes = 0; + } + #endif + } else { + buf_offset = ep_cs->buffer_fs.offset; + buf_nbytes = ep_cs->buffer_fs.nbytes; } xfer_dma->xferred_bytes += xfer_dma->nbytes - buf_nbytes; - if ( (buf_nbytes == 0) && (xfer_dma->total_bytes > xfer_dma->xferred_bytes) ) - { + if ( (buf_nbytes == 0) && (xfer_dma->total_bytes > xfer_dma->xferred_bytes) ) { // There is more data to transfer // buff_offset has been already increased by hw to correct value for next transfer prepare_ep_xfer(rhport, ep_id, buf_offset, xfer_dma->total_bytes - xfer_dma->xferred_bytes); - } - else - { + } else { // for detecting ZLP xfer_dma->total_bytes = xfer_dma->xferred_bytes; @@ -511,19 +558,16 @@ void dcd_int_handler(uint8_t rhport) //------------- Device Status -------------// if ( int_status & INT_DEVICE_STATUS_MASK ) { - dcd_reg->DEVCMDSTAT |= CMDSTAT_RESET_CHANGE_MASK | CMDSTAT_CONNECT_CHANGE_MASK | CMDSTAT_SUSPEND_CHANGE_MASK; + dcd_reg->DEVCMDSTAT |= DEVCMDSTAT_RESET_CHANGE_MASK | DEVCMDSTAT_CONNECT_CHANGE_MASK | DEVCMDSTAT_SUSPEND_CHANGE_MASK; - if ( cmd_stat & CMDSTAT_RESET_CHANGE_MASK) // bus reset + if ( cmd_stat & DEVCMDSTAT_RESET_CHANGE_MASK) // bus reset { bus_reset(rhport); tusb_speed_t speed = TUSB_SPEED_FULL; - - if (_dcd_controller[rhport].max_speed == TUSB_SPEED_HIGH) - { + if ( _dcd_controller[rhport].is_highspeed ) { // 0 : reserved, 1 : full, 2 : high, 3: super - if ( 2 == ((cmd_stat >> CMDSTAT_SPEED_SHIFT) & 0x3UL) ) - { + if ( 2 == ((cmd_stat >> DEVCMDSTAT_SPEED_SHIFT) & 0x3UL) ) { speed= TUSB_SPEED_HIGH; } } @@ -531,35 +575,35 @@ void dcd_int_handler(uint8_t rhport) dcd_event_bus_reset(rhport, speed, true); } - if (cmd_stat & CMDSTAT_CONNECT_CHANGE_MASK) + if (cmd_stat & DEVCMDSTAT_CONNECT_CHANGE_MASK) { // device disconnect - if (cmd_stat & CMDSTAT_DEVICE_ADDR_MASK) + if (cmd_stat & DEVCMDSTAT_DEVICE_ADDR_MASK) { // debouncing as this can be set when device is powering dcd_event_bus_signal(rhport, DCD_EVENT_UNPLUGGED, true); } } - if (cmd_stat & CMDSTAT_SUSPEND_CHANGE_MASK) + if (cmd_stat & DEVCMDSTAT_SUSPEND_CHANGE_MASK) { // suspend signal, bus idle for more than 3ms // Note: Host may delay more than 3 ms before and/or after bus reset before doing enumeration. - if (cmd_stat & CMDSTAT_DEVICE_ADDR_MASK) + if (cmd_stat & DEVCMDSTAT_DEVICE_ADDR_MASK) { - dcd_event_bus_signal(rhport, (cmd_stat & CMDSTAT_DEVICE_SUSPEND_MASK) ? DCD_EVENT_SUSPEND : DCD_EVENT_RESUME, true); + dcd_event_bus_signal(rhport, (cmd_stat & DEVCMDSTAT_DEVICE_SUSPEND_MASK) ? DCD_EVENT_SUSPEND : DCD_EVENT_RESUME, true); } } } // Setup Receive - if ( tu_bit_test(int_status, 0) && (cmd_stat & CMDSTAT_SETUP_RECEIVED_MASK) ) + if ( tu_bit_test(int_status, 0) && (cmd_stat & DEVCMDSTAT_SETUP_RECEIVED_MASK) ) { // Follow UM flowchart to clear Active & Stall on both Control IN/OUT endpoints _dcd.ep[0][0].cmd_sts.active = _dcd.ep[1][0].cmd_sts.active = 0; _dcd.ep[0][0].cmd_sts.stall = _dcd.ep[1][0].cmd_sts.stall = 0; - dcd_reg->DEVCMDSTAT |= CMDSTAT_SETUP_RECEIVED_MASK; + dcd_reg->DEVCMDSTAT |= DEVCMDSTAT_SETUP_RECEIVED_MASK; dcd_event_setup_received(rhport, _dcd.setup_packet, true); -- 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/common/tusb_common.h') 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 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/common/tusb_common.h') 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 1f2901e8b12258c953e3c338897f188c98b5eaed Mon Sep 17 00:00:00 2001 From: hathach Date: Mon, 15 Jan 2024 18:42:39 +0700 Subject: fix conflict of BIT() macro --- src/class/cdc/cdc_host.c | 2 +- src/class/cdc/serial/ch34x.h | 11 ++++------- src/common/tusb_common.h | 1 + 3 files changed, 6 insertions(+), 8 deletions(-) (limited to 'src/common/tusb_common.h') diff --git a/src/class/cdc/cdc_host.c b/src/class/cdc/cdc_host.c index 0cc35da52..ca5bfff04 100644 --- a/src/class/cdc/cdc_host.c +++ b/src/class/cdc/cdc_host.c @@ -1358,7 +1358,7 @@ static int32_t ch341_set_baudrate (cdch_interface_t* p_cdc, uint32_t baud_rate, * inverted. */ if ( p_cdc->ch34x.version > 0x27 ) { - val = (val | BIT(7)); + val = (val | TU_BIT(7)); } return ch341_write_reg ( p_cdc, CH341_REG_DIVISOR << 8 | CH341_REG_PRESCALER, val, complete_cb, user_data ); diff --git a/src/class/cdc/serial/ch34x.h b/src/class/cdc/serial/ch34x.h index 94e18b252..4a5e61bbd 100644 --- a/src/class/cdc/serial/ch34x.h +++ b/src/class/cdc/serial/ch34x.h @@ -29,7 +29,7 @@ #include -#define BIT(nr) ( (uint32_t)1 << (nr) ) +//#define BIT(nr) ( (uint32_t)1 << (nr) ) #define CH34X_BUFFER_SIZE 2 @@ -93,20 +93,17 @@ #define CH341_LCR_CS6 0x01 #define CH341_LCR_CS5 0x00 -#define CH341_QUIRK_LIMITED_PRESCALER BIT(0) -#define CH341_QUIRK_SIMULATE_BREAK BIT(1) +#define CH341_QUIRK_LIMITED_PRESCALER TU_BIT(0) +#define CH341_QUIRK_SIMULATE_BREAK TU_BIT(1) #define CH341_CLKRATE 48000000 #define CH341_CLK_DIV(ps, fact) (1 << (12 - 3 * (ps) - (fact))) #define CH341_MIN_RATE(ps) (CH341_CLKRATE / (CH341_CLK_DIV((ps), 1) * 512)) /* Supported range is 46 to 3000000 bps. */ -#define CH341_MIN_BPS DIV_ROUND_UP(CH341_CLKRATE, CH341_CLK_DIV(0, 0) * 256) +#define CH341_MIN_BPS TU_DIV_CEIL(CH341_CLKRATE, CH341_CLK_DIV(0, 0) * 256) #define CH341_MAX_BPS (CH341_CLKRATE / (CH341_CLK_DIV(3, 0) * 2)) -#define DIV_ROUND_UP __KERNEL_DIV_ROUND_UP -#define __KERNEL_DIV_ROUND_UP(n, d) (((n) + (d) - 1) / (d)) - // error codes #define EINVAL 22 /* Invalid argument */ diff --git a/src/common/tusb_common.h b/src/common/tusb_common.h index caeb5f2ef..1f08ce4ed 100644 --- a/src/common/tusb_common.h +++ b/src/common/tusb_common.h @@ -37,6 +37,7 @@ #define TU_ARRAY_SIZE(_arr) ( sizeof(_arr) / sizeof(_arr[0]) ) #define TU_MIN(_x, _y) ( ( (_x) < (_y) ) ? (_x) : (_y) ) #define TU_MAX(_x, _y) ( ( (_x) > (_y) ) ? (_x) : (_y) ) +#define TU_DIV_CEIL(n, d) (((n) + (d) - 1) / (d)) #define TU_U16(_high, _low) ((uint16_t) (((_high) << 8) | (_low))) #define TU_U16_HIGH(_u16) ((uint8_t) (((_u16) >> 8) & 0x00ff)) -- cgit v1.3.1