Merge pull request #2530 from hathach/add-tuh-deinit

This commit is contained in:
Ha Thach 2024-03-25 19:15:39 +07:00 committed by GitHub
commit 5b0e255f7e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
34 changed files with 402 additions and 315 deletions

View File

@ -52,7 +52,7 @@ jobs:
- name: Upload Artifacts for Hardware Testing - name: Upload Artifacts for Hardware Testing
if: matrix.board == 'espressif_s3_devkitc' && github.repository_owner == 'hathach' if: matrix.board == 'espressif_s3_devkitc' && github.repository_owner == 'hathach'
uses: actions/upload-artifact@v3 uses: actions/upload-artifact@v4
with: with:
name: ${{ matrix.board }} name: ${{ matrix.board }}
path: | path: |
@ -98,7 +98,7 @@ jobs:
sparse-checkout: test/hil sparse-checkout: test/hil
- name: Download Artifacts - name: Download Artifacts
uses: actions/download-artifact@v3 uses: actions/download-artifact@v4
with: with:
name: ${{ matrix.board }} name: ${{ matrix.board }}
path: cmake-build/cmake-build-${{ matrix.board }} path: cmake-build/cmake-build-${{ matrix.board }}

View File

@ -27,7 +27,7 @@ jobs:
language: c++ language: c++
fuzz-seconds: 600 fuzz-seconds: 600
- name: Upload Crash - name: Upload Crash
uses: actions/upload-artifact@v3 uses: actions/upload-artifact@v4
if: failure() && steps.build.outcome == 'success' if: failure() && steps.build.outcome == 'success'
with: with:
name: artifacts name: artifacts

View File

@ -93,7 +93,7 @@ jobs:
- name: Upload Artifacts for Hardware Testing (rp2040) - name: Upload Artifacts for Hardware Testing (rp2040)
if: matrix.family == 'rp2040' && github.repository_owner == 'hathach' if: matrix.family == 'rp2040' && github.repository_owner == 'hathach'
uses: actions/upload-artifact@v3 uses: actions/upload-artifact@v4
with: with:
name: raspberry_pi_pico name: raspberry_pi_pico
path: | path: |
@ -101,7 +101,7 @@ jobs:
- name: Upload Artifacts for Hardware Testing (nRF) - name: Upload Artifacts for Hardware Testing (nRF)
if: matrix.family == 'nrf' && github.repository_owner == 'hathach' if: matrix.family == 'nrf' && github.repository_owner == 'hathach'
uses: actions/upload-artifact@v3 uses: actions/upload-artifact@v4
with: with:
name: feather_nrf52840_express name: feather_nrf52840_express
path: | path: |
@ -109,7 +109,7 @@ jobs:
- name: Upload Artifacts for Hardware Testing (samd51) - name: Upload Artifacts for Hardware Testing (samd51)
if: matrix.family == 'samd51' && github.repository_owner == 'hathach' if: matrix.family == 'samd51' && github.repository_owner == 'hathach'
uses: actions/upload-artifact@v3 uses: actions/upload-artifact@v4
with: with:
name: itsybitsy_m4 name: itsybitsy_m4
path: | path: |
@ -153,7 +153,7 @@ jobs:
sparse-checkout: test/hil sparse-checkout: test/hil
- name: Download Artifacts - name: Download Artifacts
uses: actions/download-artifact@v3 uses: actions/download-artifact@v4
with: with:
name: ${{ matrix.board }} name: ${{ matrix.board }}
path: cmake-build/cmake-build-${{ matrix.board }} path: cmake-build/cmake-build-${{ matrix.board }}

View File

@ -130,7 +130,7 @@ jobs:
category: "/language:${{matrix.language}}" category: "/language:${{matrix.language}}"
- name: Archive CodeQL results - name: Archive CodeQL results
uses: actions/upload-artifact@v3 uses: actions/upload-artifact@v4
with: with:
name: codeql-results name: codeql-results
path: ${{ steps.step1.outputs.sarif-output }} path: ${{ steps.step1.outputs.sarif-output }}

View File

@ -8,5 +8,6 @@ family_initialize_project(tinyusb_host_examples ${CMAKE_CURRENT_LIST_DIR})
# family_add_subdirectory will filter what to actually add based on selected FAMILY # family_add_subdirectory will filter what to actually add based on selected FAMILY
family_add_subdirectory(bare_api) family_add_subdirectory(bare_api)
family_add_subdirectory(cdc_msc_hid) family_add_subdirectory(cdc_msc_hid)
family_add_subdirectory(cdc_msc_hid_freertos)
family_add_subdirectory(hid_controller) family_add_subdirectory(hid_controller)
family_add_subdirectory(msc_file_explorer) family_add_subdirectory(msc_file_explorer)

View File

@ -6,7 +6,6 @@ mcu:LPC43XX
mcu:MIMXRT1XXX mcu:MIMXRT1XXX
mcu:MIMXRT10XX mcu:MIMXRT10XX
mcu:MIMXRT11XX mcu:MIMXRT11XX
mcu:RP2040
mcu:MSP432E4 mcu:MSP432E4
mcu:RX65X mcu:RX65X
mcu:RAXXX mcu:RAXXX

View File

@ -46,11 +46,12 @@
#define UART_TX_PIN 6 #define UART_TX_PIN 6
// SPI for USB host shield // SPI for USB host shield
#define MAX3421_SCK_PIN _PINNUM(1, 15) // Pin is correct but not working probably due to signal incompatible (1.8V 3v3) with MAC3421E !?
#define MAX3421_MOSI_PIN _PINNUM(1, 13) //#define MAX3421_SCK_PIN _PINNUM(1, 15)
#define MAX3421_MISO_PIN _PINNUM(1, 14) //#define MAX3421_MOSI_PIN _PINNUM(1, 13)
#define MAX3421_CS_PIN _PINNUM(1, 12) //#define MAX3421_MISO_PIN _PINNUM(1, 14)
#define MAX3421_INTR_PIN _PINNUM(1, 11) //#define MAX3421_CS_PIN _PINNUM(1, 12)
//#define MAX3421_INTR_PIN _PINNUM(1, 11)
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@ -1,9 +1,6 @@
set(MCU_VARIANT nrf5340_application) set(MCU_VARIANT nrf5340_application)
set(LD_FILE_GNU ${NRFX_DIR}/mdk/nrf5340_xxaa_application.ld) set(LD_FILE_GNU ${NRFX_DIR}/mdk/nrf5340_xxaa_application.ld)
# enable max3421 host driver for this board
set(MAX3421_HOST 1)
function(update_board TARGET) function(update_board TARGET)
target_sources(${TARGET} PRIVATE target_sources(${TARGET} PRIVATE
${NRFX_DIR}/drivers/src/nrfx_usbreg.c ${NRFX_DIR}/drivers/src/nrfx_usbreg.c

View File

@ -46,11 +46,12 @@
#define UART_TX_PIN 20 #define UART_TX_PIN 20
// SPI for USB host shield // SPI for USB host shield
#define MAX3421_SCK_PIN _PINNUM(1, 15) // Pin is correct but not working probably due to signal incompatible (1.8V 3v3) with MAC3421E !?
#define MAX3421_MOSI_PIN _PINNUM(1, 13) //#define MAX3421_SCK_PIN _PINNUM(1, 15)
#define MAX3421_MISO_PIN _PINNUM(1, 14) //#define MAX3421_MOSI_PIN _PINNUM(1, 13)
#define MAX3421_CS_PIN _PINNUM(1, 12) //#define MAX3421_MISO_PIN _PINNUM(1, 14)
#define MAX3421_INTR_PIN _PINNUM(1, 11) //#define MAX3421_CS_PIN _PINNUM(1, 12)
//#define MAX3421_INTR_PIN _PINNUM(1, 11)
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@ -292,20 +292,7 @@ void max3421_int_handler(nrfx_gpiote_pin_t pin, nrf_gpiote_polarity_t action) {
} }
static void max3421_init(void) { static void max3421_init(void) {
// MAX3421 need 3.3v signal (may not be needed) // Somehow pca10056/95 is not working probably due to signal incompatible (1.8V 3v3) with MAC3421E !?
// #if defined(UICR_REGOUT0_VOUT_Msk)
// if ((NRF_UICR->REGOUT0 & UICR_REGOUT0_VOUT_Msk) != UICR_REGOUT0_VOUT_3V3) {
// NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Wen << NVMC_CONFIG_WEN_Pos;
// while (NRF_NVMC->READY == NVMC_READY_READY_Busy){}
//
// NRF_UICR->REGOUT0 = (NRF_UICR->REGOUT0 & ~UICR_REGOUT0_VOUT_Msk) | UICR_REGOUT0_VOUT_3V3;
//
// NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Ren << NVMC_CONFIG_WEN_Pos;
// while (NRF_NVMC->READY == NVMC_READY_READY_Busy){}
//
// NVIC_SystemReset();
// }
// #endif
// manually manage CS // manually manage CS
nrf_gpio_cfg_output(MAX3421_CS_PIN); nrf_gpio_cfg_output(MAX3421_CS_PIN);

View File

@ -171,7 +171,7 @@ function(family_configure_target TARGET RTOS)
pico_add_extra_outputs(${TARGET}) pico_add_extra_outputs(${TARGET})
pico_enable_stdio_uart(${TARGET} 1) pico_enable_stdio_uart(${TARGET} 1)
target_link_libraries(${TARGET} PUBLIC pico_stdlib pico_bootsel_via_double_reset tinyusb_board${RTOS_SUFFIX} tinyusb_additions) target_link_libraries(${TARGET} PUBLIC pico_stdlib tinyusb_board${RTOS_SUFFIX} tinyusb_additions)
family_flash_openocd(${TARGET} ${OPENOCD_OPTION}) family_flash_openocd(${TARGET} ${OPENOCD_OPTION})
family_flash_jlink(${TARGET}) family_flash_jlink(${TARGET})

View File

@ -621,12 +621,11 @@ bool tuh_cdc_set_line_coding(uint8_t idx, cdc_line_coding_t const* line_coding,
// CLASS-USBH API // CLASS-USBH API
//--------------------------------------------------------------------+ //--------------------------------------------------------------------+
void cdch_init(void) { bool cdch_init(void) {
TU_LOG_DRV("sizeof(cdch_interface_t) = %u\r\n", sizeof(cdch_interface_t));
tu_memclr(cdch_data, sizeof(cdch_data)); tu_memclr(cdch_data, sizeof(cdch_data));
for (size_t i = 0; i < CFG_TUH_CDC; i++) { for (size_t i = 0; i < CFG_TUH_CDC; i++) {
cdch_interface_t* p_cdc = &cdch_data[i]; cdch_interface_t* p_cdc = &cdch_data[i];
tu_edpt_stream_init(&p_cdc->stream.tx, true, true, false, tu_edpt_stream_init(&p_cdc->stream.tx, true, true, false,
p_cdc->stream.tx_ff_buf, CFG_TUH_CDC_TX_BUFSIZE, p_cdc->stream.tx_ff_buf, CFG_TUH_CDC_TX_BUFSIZE,
p_cdc->stream.tx_ep_buf, CFG_TUH_CDC_TX_EPSIZE); p_cdc->stream.tx_ep_buf, CFG_TUH_CDC_TX_EPSIZE);
@ -635,6 +634,17 @@ void cdch_init(void) {
p_cdc->stream.rx_ff_buf, CFG_TUH_CDC_RX_BUFSIZE, p_cdc->stream.rx_ff_buf, CFG_TUH_CDC_RX_BUFSIZE,
p_cdc->stream.rx_ep_buf, CFG_TUH_CDC_RX_EPSIZE); p_cdc->stream.rx_ep_buf, CFG_TUH_CDC_RX_EPSIZE);
} }
return true;
}
bool cdch_deinit(void) {
for (size_t i = 0; i < CFG_TUH_CDC; i++) {
cdch_interface_t* p_cdc = &cdch_data[i];
tu_edpt_stream_deinit(&p_cdc->stream.tx);
tu_edpt_stream_deinit(&p_cdc->stream.rx);
}
return true;
} }
void cdch_close(uint8_t daddr) { void cdch_close(uint8_t daddr) {

View File

@ -192,7 +192,8 @@ TU_ATTR_WEAK extern void tuh_cdc_tx_complete_cb(uint8_t idx);
//--------------------------------------------------------------------+ //--------------------------------------------------------------------+
// Internal Class Driver API // Internal Class Driver API
//--------------------------------------------------------------------+ //--------------------------------------------------------------------+
void cdch_init (void); bool cdch_init (void);
bool cdch_deinit (void);
bool cdch_open (uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const *itf_desc, uint16_t max_len); bool cdch_open (uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const *itf_desc, uint16_t max_len);
bool cdch_set_config (uint8_t dev_addr, uint8_t itf_num); bool cdch_set_config (uint8_t dev_addr, uint8_t itf_num);
bool cdch_xfer_cb (uint8_t dev_addr, uint8_t ep_addr, xfer_result_t event, uint32_t xferred_bytes); bool cdch_xfer_cb (uint8_t dev_addr, uint8_t ep_addr, xfer_result_t event, uint32_t xferred_bytes);

View File

@ -372,8 +372,14 @@ bool tuh_hid_send_report(uint8_t daddr, uint8_t idx, uint8_t report_id, const vo
//--------------------------------------------------------------------+ //--------------------------------------------------------------------+
// USBH API // USBH API
//--------------------------------------------------------------------+ //--------------------------------------------------------------------+
void hidh_init(void) { bool hidh_init(void) {
TU_LOG_DRV("sizeof(hidh_interface_t) = %u\r\n", sizeof(hidh_interface_t));
tu_memclr(_hidh_itf, sizeof(_hidh_itf)); tu_memclr(_hidh_itf, sizeof(_hidh_itf));
return true;
}
bool hidh_deinit(void) {
return true;
} }
bool hidh_xfer_cb(uint8_t daddr, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes) { bool hidh_xfer_cb(uint8_t daddr, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes) {

View File

@ -163,7 +163,8 @@ TU_ATTR_WEAK void tuh_hid_set_protocol_complete_cb(uint8_t dev_addr, uint8_t idx
//--------------------------------------------------------------------+ //--------------------------------------------------------------------+
// Internal Class Driver API // Internal Class Driver API
//--------------------------------------------------------------------+ //--------------------------------------------------------------------+
void hidh_init(void); bool hidh_init(void);
bool hidh_deinit(void);
bool hidh_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const* desc_itf, uint16_t max_len); bool hidh_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const* desc_itf, uint16_t max_len);
bool hidh_set_config(uint8_t dev_addr, uint8_t itf_num); bool hidh_set_config(uint8_t dev_addr, uint8_t itf_num);
bool hidh_xfer_cb(uint8_t dev_addr, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes); bool hidh_xfer_cb(uint8_t dev_addr, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes);

View File

@ -284,8 +284,14 @@ bool tuh_msc_reset(uint8_t dev_addr) {
//--------------------------------------------------------------------+ //--------------------------------------------------------------------+
// CLASS-USBH API // CLASS-USBH API
//--------------------------------------------------------------------+ //--------------------------------------------------------------------+
void msch_init(void) { bool msch_init(void) {
TU_LOG_DRV("sizeof(msch_interface_t) = %u\r\n", sizeof(msch_interface_t));
tu_memclr(_msch_itf, sizeof(_msch_itf)); tu_memclr(_msch_itf, sizeof(_msch_itf));
return true;
}
bool msch_deinit(void) {
return true;
} }
void msch_close(uint8_t dev_addr) { void msch_close(uint8_t dev_addr) {

View File

@ -113,7 +113,8 @@ TU_ATTR_WEAK void tuh_msc_umount_cb(uint8_t dev_addr);
// Internal Class Driver API // Internal Class Driver API
//--------------------------------------------------------------------+ //--------------------------------------------------------------------+
void msch_init (void); bool msch_init (void);
bool msch_deinit (void);
bool msch_open (uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const *desc_itf, uint16_t max_len); bool msch_open (uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const *desc_itf, uint16_t max_len);
bool msch_set_config (uint8_t dev_addr, uint8_t itf_num); bool msch_set_config (uint8_t dev_addr, uint8_t itf_num);
void msch_close (uint8_t dev_addr); void msch_close (uint8_t dev_addr);

View File

@ -102,10 +102,8 @@ extern "C" {
* | * |
* ------------------------- * -------------------------
* | R | 1 | 2 | W | 4 | 5 | * | R | 1 | 2 | W | 4 | 5 |
*/ */
typedef struct typedef struct {
{
uint8_t* buffer ; // buffer pointer uint8_t* buffer ; // buffer pointer
uint16_t depth ; // max items uint16_t depth ; // max items
@ -124,16 +122,14 @@ typedef struct
} tu_fifo_t; } tu_fifo_t;
typedef struct typedef struct {
{
uint16_t len_lin ; ///< linear length in item size uint16_t len_lin ; ///< linear length in item size
uint16_t len_wrap ; ///< wrapped length in item size uint16_t len_wrap ; ///< wrapped length in item size
void * ptr_lin ; ///< linear part start pointer void * ptr_lin ; ///< linear part start pointer
void * ptr_wrap ; ///< wrapped part start pointer void * ptr_wrap ; ///< wrapped part start pointer
} tu_fifo_buffer_info_t; } tu_fifo_buffer_info_t;
#define TU_FIFO_INIT(_buffer, _depth, _type, _overwritable) \ #define TU_FIFO_INIT(_buffer, _depth, _type, _overwritable){\
{ \
.buffer = _buffer, \ .buffer = _buffer, \
.depth = _depth, \ .depth = _depth, \
.item_size = sizeof(_type), \ .item_size = sizeof(_type), \
@ -144,23 +140,18 @@ typedef struct
uint8_t _name##_buf[_depth*sizeof(_type)]; \ uint8_t _name##_buf[_depth*sizeof(_type)]; \
tu_fifo_t _name = TU_FIFO_INIT(_name##_buf, _depth, _type, _overwritable) tu_fifo_t _name = TU_FIFO_INIT(_name##_buf, _depth, _type, _overwritable)
bool tu_fifo_set_overwritable(tu_fifo_t *f, bool overwritable); bool tu_fifo_set_overwritable(tu_fifo_t *f, bool overwritable);
bool tu_fifo_clear(tu_fifo_t *f); bool tu_fifo_clear(tu_fifo_t *f);
bool tu_fifo_config(tu_fifo_t *f, void* buffer, uint16_t depth, uint16_t item_size, bool overwritable); bool tu_fifo_config(tu_fifo_t *f, void* buffer, uint16_t depth, uint16_t item_size, bool overwritable);
#if OSAL_MUTEX_REQUIRED #if OSAL_MUTEX_REQUIRED
TU_ATTR_ALWAYS_INLINE static inline TU_ATTR_ALWAYS_INLINE static inline
void tu_fifo_config_mutex(tu_fifo_t *f, osal_mutex_t wr_mutex, osal_mutex_t rd_mutex) void tu_fifo_config_mutex(tu_fifo_t *f, osal_mutex_t wr_mutex, osal_mutex_t rd_mutex) {
{
f->mutex_wr = wr_mutex; f->mutex_wr = wr_mutex;
f->mutex_rd = rd_mutex; f->mutex_rd = rd_mutex;
} }
#else #else
#define tu_fifo_config_mutex(_f, _wr_mutex, _rd_mutex) #define tu_fifo_config_mutex(_f, _wr_mutex, _rd_mutex)
#endif #endif
bool tu_fifo_write (tu_fifo_t* f, void const * p_data); bool tu_fifo_write (tu_fifo_t* f, void const * p_data);
@ -182,8 +173,7 @@ bool tu_fifo_overflowed (tu_fifo_t* f);
void tu_fifo_correct_read_pointer (tu_fifo_t* f); void tu_fifo_correct_read_pointer (tu_fifo_t* f);
TU_ATTR_ALWAYS_INLINE static inline TU_ATTR_ALWAYS_INLINE static inline
uint16_t tu_fifo_depth(tu_fifo_t* f) uint16_t tu_fifo_depth(tu_fifo_t* f) {
{
return f->depth; return f->depth;
} }
@ -198,7 +188,6 @@ void tu_fifo_advance_read_pointer (tu_fifo_t *f, uint16_t n);
void tu_fifo_get_read_info (tu_fifo_t *f, tu_fifo_buffer_info_t *info); void tu_fifo_get_read_info (tu_fifo_t *f, tu_fifo_buffer_info_t *info);
void tu_fifo_get_write_info(tu_fifo_t *f, tu_fifo_buffer_info_t *info); void tu_fifo_get_write_info(tu_fifo_t *f, tu_fifo_buffer_info_t *info);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View File

@ -60,7 +60,7 @@ typedef struct {
tu_fifo_t ff; tu_fifo_t ff;
// mutex: read if ep rx, write if e tx // mutex: read if ep rx, write if e tx
OSAL_MUTEX_DEF(ff_mutex); OSAL_MUTEX_DEF(ff_mutexdef);
}tu_edpt_stream_t; }tu_edpt_stream_t;
@ -87,15 +87,17 @@ bool tu_edpt_release(tu_edpt_state_t* ep_state, osal_mutex_t mutex);
// Endpoint Stream // Endpoint Stream
//--------------------------------------------------------------------+ //--------------------------------------------------------------------+
// Init an stream, should only be called once // Init an endpoint stream
bool tu_edpt_stream_init(tu_edpt_stream_t* s, bool is_host, bool is_tx, bool overwritable, bool tu_edpt_stream_init(tu_edpt_stream_t* s, bool is_host, bool is_tx, bool overwritable,
void* ff_buf, uint16_t ff_bufsize, uint8_t* ep_buf, uint16_t ep_bufsize); void* ff_buf, uint16_t ff_bufsize, uint8_t* ep_buf, uint16_t ep_bufsize);
// Deinit an endpoint stream
bool tu_edpt_stream_deinit(tu_edpt_stream_t* s);
// Open an stream for an endpoint // Open an stream for an endpoint
// hwid is either device address (host mode) or rhport (device mode) // hwid is either device address (host mode) or rhport (device mode)
TU_ATTR_ALWAYS_INLINE static inline TU_ATTR_ALWAYS_INLINE static inline
void tu_edpt_stream_open(tu_edpt_stream_t* s, uint8_t hwid, tusb_desc_endpoint_t const *desc_ep) void tu_edpt_stream_open(tu_edpt_stream_t* s, uint8_t hwid, tusb_desc_endpoint_t const *desc_ep) {
{
tu_fifo_clear(&s->ff); tu_fifo_clear(&s->ff);
s->hwid = hwid; s->hwid = hwid;
s->ep_addr = desc_ep->bEndpointAddress; s->ep_addr = desc_ep->bEndpointAddress;
@ -103,16 +105,14 @@ void tu_edpt_stream_open(tu_edpt_stream_t* s, uint8_t hwid, tusb_desc_endpoint_t
} }
TU_ATTR_ALWAYS_INLINE static inline TU_ATTR_ALWAYS_INLINE static inline
void tu_edpt_stream_close(tu_edpt_stream_t* s) void tu_edpt_stream_close(tu_edpt_stream_t* s) {
{
s->hwid = 0; s->hwid = 0;
s->ep_addr = 0; s->ep_addr = 0;
} }
// Clear fifo // Clear fifo
TU_ATTR_ALWAYS_INLINE static inline TU_ATTR_ALWAYS_INLINE static inline
bool tu_edpt_stream_clear(tu_edpt_stream_t* s) bool tu_edpt_stream_clear(tu_edpt_stream_t* s) {
{
return tu_fifo_clear(&s->ff); return tu_fifo_clear(&s->ff);
} }
@ -131,8 +131,7 @@ bool tu_edpt_stream_write_zlp_if_needed(tu_edpt_stream_t* s, uint32_t last_xferr
// Get the number of bytes available for writing // Get the number of bytes available for writing
TU_ATTR_ALWAYS_INLINE static inline TU_ATTR_ALWAYS_INLINE static inline
uint32_t tu_edpt_stream_write_available(tu_edpt_stream_t* s) uint32_t tu_edpt_stream_write_available(tu_edpt_stream_t* s) {
{
return (uint32_t) tu_fifo_remaining(&s->ff); return (uint32_t) tu_fifo_remaining(&s->ff);
} }

View File

@ -130,6 +130,9 @@ bool hcd_configure(uint8_t rhport, uint32_t cfg_id, const void* cfg_param) TU_AT
// Initialize controller to host mode // Initialize controller to host mode
bool hcd_init(uint8_t rhport); bool hcd_init(uint8_t rhport);
// De-initialize controller
bool hcd_deinit(uint8_t rhport);
// Interrupt Handler // Interrupt Handler
void hcd_int_handler(uint8_t rhport, bool in_isr); void hcd_int_handler(uint8_t rhport, bool in_isr);

View File

@ -182,9 +182,13 @@ bool hub_port_get_status(uint8_t hub_addr, uint8_t hub_port, void* resp,
//--------------------------------------------------------------------+ //--------------------------------------------------------------------+
// CLASS-USBH API (don't require to verify parameters) // CLASS-USBH API (don't require to verify parameters)
//--------------------------------------------------------------------+ //--------------------------------------------------------------------+
void hub_init(void) bool hub_init(void) {
{
tu_memclr(hub_data, sizeof(hub_data)); tu_memclr(hub_data, sizeof(hub_data));
return true;
}
bool hub_deinit(void) {
return true;
} }
bool hub_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const *itf_desc, uint16_t max_len) bool hub_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const *itf_desc, uint16_t max_len)

View File

@ -187,16 +187,14 @@ bool hub_port_get_status (uint8_t hub_addr, uint8_t hub_port, void* resp,
bool hub_edpt_status_xfer(uint8_t dev_addr); bool hub_edpt_status_xfer(uint8_t dev_addr);
// Reset a port // Reset a port
static inline bool hub_port_reset(uint8_t hub_addr, uint8_t hub_port, TU_ATTR_ALWAYS_INLINE static inline
tuh_xfer_cb_t complete_cb, uintptr_t user_data) bool hub_port_reset(uint8_t hub_addr, uint8_t hub_port, tuh_xfer_cb_t complete_cb, uintptr_t user_data) {
{
return hub_port_set_feature(hub_addr, hub_port, HUB_FEATURE_PORT_RESET, complete_cb, user_data); return hub_port_set_feature(hub_addr, hub_port, HUB_FEATURE_PORT_RESET, complete_cb, user_data);
} }
// Clear Reset Change // Clear Reset Change
static inline bool hub_port_clear_reset_change(uint8_t hub_addr, uint8_t hub_port, TU_ATTR_ALWAYS_INLINE static inline
tuh_xfer_cb_t complete_cb, uintptr_t user_data) bool hub_port_clear_reset_change(uint8_t hub_addr, uint8_t hub_port, tuh_xfer_cb_t complete_cb, uintptr_t user_data) {
{
return hub_port_clear_feature(hub_addr, hub_port, HUB_FEATURE_PORT_RESET_CHANGE, complete_cb, user_data); return hub_port_clear_feature(hub_addr, hub_port, HUB_FEATURE_PORT_RESET_CHANGE, complete_cb, user_data);
} }
@ -204,7 +202,8 @@ static inline bool hub_port_clear_reset_change(uint8_t hub_addr, uint8_t hub_por
//--------------------------------------------------------------------+ //--------------------------------------------------------------------+
// Internal Class Driver API // Internal Class Driver API
//--------------------------------------------------------------------+ //--------------------------------------------------------------------+
void hub_init (void); bool hub_init (void);
bool hub_deinit (void);
bool hub_open (uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const *itf_desc, uint16_t max_len); bool hub_open (uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const *itf_desc, uint16_t max_len);
bool hub_set_config (uint8_t dev_addr, uint8_t itf_num); bool hub_set_config (uint8_t dev_addr, uint8_t itf_num);
bool hub_xfer_cb (uint8_t dev_addr, uint8_t ep_addr, xfer_result_t event, uint32_t xferred_bytes); bool hub_xfer_cb (uint8_t dev_addr, uint8_t ep_addr, xfer_result_t event, uint32_t xferred_bytes);

View File

@ -45,8 +45,13 @@
#endif #endif
//--------------------------------------------------------------------+ //--------------------------------------------------------------------+
// Callback weak stubs (called if application does not provide) // Weak stubs: invoked if no strong implementation is available
//--------------------------------------------------------------------+ //--------------------------------------------------------------------+
TU_ATTR_WEAK bool hcd_deinit(uint8_t rhport) {
(void) rhport;
return false;
}
TU_ATTR_WEAK void tuh_event_hook_cb(uint8_t rhport, uint32_t eventid, bool in_isr) { TU_ATTR_WEAK void tuh_event_hook_cb(uint8_t rhport, uint32_t eventid, bool in_isr) {
(void) rhport; (void) rhport;
(void) eventid; (void) eventid;
@ -119,16 +124,17 @@ typedef struct {
// MACRO CONSTANT TYPEDEF // MACRO CONSTANT TYPEDEF
//--------------------------------------------------------------------+ //--------------------------------------------------------------------+
#if CFG_TUSB_DEBUG >= CFG_TUH_LOG_LEVEL #if CFG_TUSB_DEBUG >= CFG_TUH_LOG_LEVEL
#define DRIVER_NAME(_name) .name = _name, #define DRIVER_NAME(_name) _name
#else #else
#define DRIVER_NAME(_name) #define DRIVER_NAME(_name) NULL
#endif #endif
static usbh_class_driver_t const usbh_class_drivers[] = { static usbh_class_driver_t const usbh_class_drivers[] = {
#if CFG_TUH_CDC #if CFG_TUH_CDC
{ {
DRIVER_NAME("CDC") .name = DRIVER_NAME("CDC"),
.init = cdch_init, .init = cdch_init,
.deinit = cdch_deinit,
.open = cdch_open, .open = cdch_open,
.set_config = cdch_set_config, .set_config = cdch_set_config,
.xfer_cb = cdch_xfer_cb, .xfer_cb = cdch_xfer_cb,
@ -138,8 +144,9 @@ static usbh_class_driver_t const usbh_class_drivers[] = {
#if CFG_TUH_MSC #if CFG_TUH_MSC
{ {
DRIVER_NAME("MSC") .name = DRIVER_NAME("MSC"),
.init = msch_init, .init = msch_init,
.deinit = msch_deinit,
.open = msch_open, .open = msch_open,
.set_config = msch_set_config, .set_config = msch_set_config,
.xfer_cb = msch_xfer_cb, .xfer_cb = msch_xfer_cb,
@ -149,8 +156,9 @@ static usbh_class_driver_t const usbh_class_drivers[] = {
#if CFG_TUH_HID #if CFG_TUH_HID
{ {
DRIVER_NAME("HID") .name = DRIVER_NAME("HID"),
.init = hidh_init, .init = hidh_init,
.deinit = hidh_deinit,
.open = hidh_open, .open = hidh_open,
.set_config = hidh_set_config, .set_config = hidh_set_config,
.xfer_cb = hidh_xfer_cb, .xfer_cb = hidh_xfer_cb,
@ -160,8 +168,9 @@ static usbh_class_driver_t const usbh_class_drivers[] = {
#if CFG_TUH_HUB #if CFG_TUH_HUB
{ {
DRIVER_NAME("HUB") .name = DRIVER_NAME("HUB"),
.init = hub_init, .init = hub_init,
.deinit = hub_deinit,
.open = hub_open, .open = hub_open,
.set_config = hub_set_config, .set_config = hub_set_config,
.xfer_cb = hub_xfer_cb, .xfer_cb = hub_xfer_cb,
@ -171,9 +180,11 @@ static usbh_class_driver_t const usbh_class_drivers[] = {
#if CFG_TUH_VENDOR #if CFG_TUH_VENDOR
{ {
DRIVER_NAME("VENDOR") .name = DRIVER_NAME("VENDOR"),
.init = cush_init, .init = cush_init,
.open = cush_open_subtask, .deinit = cush_deinit,
.open = cush_open,
.set_config = cush_set_config,
.xfer_cb = cush_isr, .xfer_cb = cush_isr,
.close = cush_close .close = cush_close
} }
@ -338,11 +349,14 @@ bool tuh_inited(void) {
return _usbh_controller != TUSB_INDEX_INVALID_8; return _usbh_controller != TUSB_INDEX_INVALID_8;
} }
bool tuh_init(uint8_t controller_id) { bool tuh_init(uint8_t rhport) {
// skip if already initialized // skip if already initialized
if ( tuh_inited() ) return true; if (tuh_rhport_is_active(rhport)) return true;
TU_LOG_USBH("USBH init on controller %u\r\n", controller_id); TU_LOG_USBH("USBH init on controller %u\r\n", rhport);
// Init host stack if not already
if (!tuh_inited()) {
TU_LOG_INT_USBH(sizeof(usbh_device_t)); TU_LOG_INT_USBH(sizeof(usbh_device_t));
TU_LOG_INT_USBH(sizeof(hcd_event_t)); TU_LOG_INT_USBH(sizeof(hcd_event_t));
TU_LOG_INT_USBH(sizeof(_ctrl_xfer)); TU_LOG_INT_USBH(sizeof(_ctrl_xfer));
@ -382,11 +396,45 @@ bool tuh_init(uint8_t controller_id) {
driver->init(); driver->init();
} }
} }
}
_usbh_controller = controller_id;; // Init host controller
_usbh_controller = rhport;;
TU_ASSERT(hcd_init(rhport));
hcd_int_enable(rhport);
TU_ASSERT(hcd_init(controller_id)); return true;
hcd_int_enable(controller_id); }
bool tuh_deinit(uint8_t rhport) {
if (!tuh_rhport_is_active(rhport)) return true;
// deinit host controller
hcd_int_disable(rhport);
hcd_deinit(rhport);
_usbh_controller = TUSB_INDEX_INVALID_8;
// deinit host stack if no controller is active
if (!tuh_inited()) {
// Class drivers
for (uint8_t drv_id = 0; drv_id < TOTAL_DRIVER_COUNT; drv_id++) {
usbh_class_driver_t const* driver = get_driver(drv_id);
if (driver) {
TU_LOG_USBH("%s deinit\r\n", driver->name);
driver->deinit();
}
}
osal_queue_delete(_usbh_q);
_usbh_q = NULL;
#if OSAL_MUTEX_REQUIRED
// TODO make sure there is no task waiting on this mutex
osal_mutex_delete(_usbh_mutex);
_usbh_mutex = NULL;
#endif
}
return true; return true;
} }

View File

@ -109,7 +109,11 @@ bool tuh_configure(uint8_t rhport, uint32_t cfg_id, const void* cfg_param);
// Init host stack // Init host stack
bool tuh_init(uint8_t rhport); bool tuh_init(uint8_t rhport);
// Deinit host stack on rhport
bool tuh_deinit(uint8_t rhport);
// Check if host stack is already initialized with any roothub ports // Check if host stack is already initialized with any roothub ports
// To check if an rhport is initialized, use tuh_rhport_is_active()
bool tuh_inited(void); bool tuh_inited(void);
// Task function should be called in main/rtos loop, extended version of tuh_task() // Task function should be called in main/rtos loop, extended version of tuh_task()

View File

@ -50,11 +50,9 @@ enum {
//--------------------------------------------------------------------+ //--------------------------------------------------------------------+
typedef struct { typedef struct {
#if CFG_TUSB_DEBUG >= CFG_TUH_LOG_LEVEL
char const* name; char const* name;
#endif bool (* const init )(void);
bool (* const deinit )(void);
void (* const init )(void);
bool (* const open )(uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const * itf_desc, uint16_t max_len); bool (* const open )(uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const * itf_desc, uint16_t max_len);
bool (* const set_config )(uint8_t dev_addr, uint8_t itf_num); bool (* const set_config )(uint8_t dev_addr, uint8_t itf_num);
bool (* const xfer_cb )(uint8_t dev_addr, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes); bool (* const xfer_cb )(uint8_t dev_addr, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes);

View File

@ -74,15 +74,18 @@ typedef void (*osal_task_func_t)( void * );
// Should be implemented as static inline function in osal_port.h header // Should be implemented as static inline function in osal_port.h header
/* /*
osal_semaphore_t osal_semaphore_create(osal_semaphore_def_t* semdef); osal_semaphore_t osal_semaphore_create(osal_semaphore_def_t* semdef);
bool osal_semaphore_delete(osal_semaphore_t semd_hdl);
bool osal_semaphore_post(osal_semaphore_t sem_hdl, bool in_isr); bool osal_semaphore_post(osal_semaphore_t sem_hdl, bool in_isr);
bool osal_semaphore_wait(osal_semaphore_t sem_hdl, uint32_t msec); bool osal_semaphore_wait(osal_semaphore_t sem_hdl, uint32_t msec);
void osal_semaphore_reset(osal_semaphore_t sem_hdl); // TODO removed void osal_semaphore_reset(osal_semaphore_t sem_hdl); // TODO removed
osal_mutex_t osal_mutex_create(osal_mutex_def_t* mdef); osal_mutex_t osal_mutex_create(osal_mutex_def_t* mdef);
bool osal_mutex_delete(osal_mutex_t mutex_hdl)
bool osal_mutex_lock (osal_mutex_t sem_hdl, uint32_t msec); bool osal_mutex_lock (osal_mutex_t sem_hdl, uint32_t msec);
bool osal_mutex_unlock(osal_mutex_t mutex_hdl); bool osal_mutex_unlock(osal_mutex_t mutex_hdl);
osal_queue_t osal_queue_create(osal_queue_def_t* qdef); osal_queue_t osal_queue_create(osal_queue_def_t* qdef);
bool osal_queue_delete(osal_queue_t qhdl);
bool osal_queue_receive(osal_queue_t qhdl, void* data, uint32_t msec); bool osal_queue_receive(osal_queue_t qhdl, void* data, uint32_t msec);
bool osal_queue_send(osal_queue_t qhdl, void const * data, bool in_isr); bool osal_queue_send(osal_queue_t qhdl, void const * data, bool in_isr);
bool osal_queue_empty(osal_queue_t qhdl); bool osal_queue_empty(osal_queue_t qhdl);

View File

@ -24,8 +24,8 @@
* This file is part of the TinyUSB stack. * This file is part of the TinyUSB stack.
*/ */
#ifndef _TUSB_OSAL_FREERTOS_H_ #ifndef TUSB_OSAL_FREERTOS_H_
#define _TUSB_OSAL_FREERTOS_H_ #define TUSB_OSAL_FREERTOS_H_
// FreeRTOS Headers // FreeRTOS Headers
#include TU_INCLUDE_PATH(CFG_TUSB_OS_INC_PATH,FreeRTOS.h) #include TU_INCLUDE_PATH(CFG_TUSB_OS_INC_PATH,FreeRTOS.h)
@ -114,6 +114,11 @@ TU_ATTR_ALWAYS_INLINE static inline osal_semaphore_t osal_semaphore_create(osal_
#endif #endif
} }
TU_ATTR_ALWAYS_INLINE static inline bool osal_semaphore_delete(osal_semaphore_t semd_hdl) {
vSemaphoreDelete(semd_hdl);
return true;
}
TU_ATTR_ALWAYS_INLINE static inline bool osal_semaphore_post(osal_semaphore_t sem_hdl, bool in_isr) { TU_ATTR_ALWAYS_INLINE static inline bool osal_semaphore_post(osal_semaphore_t sem_hdl, bool in_isr) {
if ( !in_isr ) { if ( !in_isr ) {
return xSemaphoreGive(sem_hdl) != 0; return xSemaphoreGive(sem_hdl) != 0;
@ -153,6 +158,11 @@ TU_ATTR_ALWAYS_INLINE static inline osal_mutex_t osal_mutex_create(osal_mutex_de
#endif #endif
} }
TU_ATTR_ALWAYS_INLINE static inline bool osal_mutex_delete(osal_mutex_t mutex_hdl) {
vSemaphoreDelete(mutex_hdl);
return true;
}
TU_ATTR_ALWAYS_INLINE static inline bool osal_mutex_lock(osal_mutex_t mutex_hdl, uint32_t msec) { TU_ATTR_ALWAYS_INLINE static inline bool osal_mutex_lock(osal_mutex_t mutex_hdl, uint32_t msec) {
return osal_semaphore_wait(mutex_hdl, msec); return osal_semaphore_wait(mutex_hdl, msec);
} }
@ -181,6 +191,11 @@ TU_ATTR_ALWAYS_INLINE static inline osal_queue_t osal_queue_create(osal_queue_de
return q; return q;
} }
TU_ATTR_ALWAYS_INLINE static inline bool osal_queue_delete(osal_queue_t qhdl) {
vQueueDelete(qhdl);
return true;
}
TU_ATTR_ALWAYS_INLINE static inline bool osal_queue_receive(osal_queue_t qhdl, void* data, uint32_t msec) { TU_ATTR_ALWAYS_INLINE static inline bool osal_queue_receive(osal_queue_t qhdl, void* data, uint32_t msec) {
return xQueueReceive(qhdl, data, _osal_ms2tick(msec)); return xQueueReceive(qhdl, data, _osal_ms2tick(msec));
} }

View File

@ -36,8 +36,7 @@
//--------------------------------------------------------------------+ //--------------------------------------------------------------------+
// TASK API // TASK API
//--------------------------------------------------------------------+ //--------------------------------------------------------------------+
TU_ATTR_ALWAYS_INLINE static inline void osal_task_delay(uint32_t msec) TU_ATTR_ALWAYS_INLINE static inline void osal_task_delay(uint32_t msec) {
{
os_time_delay( os_time_ms_to_ticks32(msec) ); os_time_delay( os_time_ms_to_ticks32(msec) );
} }
@ -47,25 +46,26 @@ TU_ATTR_ALWAYS_INLINE static inline void osal_task_delay(uint32_t msec)
typedef struct os_sem osal_semaphore_def_t; typedef struct os_sem osal_semaphore_def_t;
typedef struct os_sem* osal_semaphore_t; typedef struct os_sem* osal_semaphore_t;
TU_ATTR_ALWAYS_INLINE static inline osal_semaphore_t osal_semaphore_create(osal_semaphore_def_t* semdef) TU_ATTR_ALWAYS_INLINE static inline osal_semaphore_t osal_semaphore_create(osal_semaphore_def_t* semdef) {
{
return (os_sem_init(semdef, 0) == OS_OK) ? (osal_semaphore_t) semdef : NULL; return (os_sem_init(semdef, 0) == OS_OK) ? (osal_semaphore_t) semdef : NULL;
} }
TU_ATTR_ALWAYS_INLINE static inline bool osal_semaphore_post(osal_semaphore_t sem_hdl, bool in_isr) TU_ATTR_ALWAYS_INLINE static inline bool osal_semaphore_delete(osal_semaphore_t semd_hdl) {
{ (void) semd_hdl;
return true; // nothing to do
}
TU_ATTR_ALWAYS_INLINE static inline bool osal_semaphore_post(osal_semaphore_t sem_hdl, bool in_isr) {
(void) in_isr; (void) in_isr;
return os_sem_release(sem_hdl) == OS_OK; return os_sem_release(sem_hdl) == OS_OK;
} }
TU_ATTR_ALWAYS_INLINE static inline bool osal_semaphore_wait(osal_semaphore_t sem_hdl, uint32_t msec) TU_ATTR_ALWAYS_INLINE static inline bool osal_semaphore_wait(osal_semaphore_t sem_hdl, uint32_t msec) {
{
uint32_t const ticks = (msec == OSAL_TIMEOUT_WAIT_FOREVER) ? OS_TIMEOUT_NEVER : os_time_ms_to_ticks32(msec); uint32_t const ticks = (msec == OSAL_TIMEOUT_WAIT_FOREVER) ? OS_TIMEOUT_NEVER : os_time_ms_to_ticks32(msec);
return os_sem_pend(sem_hdl, ticks) == OS_OK; return os_sem_pend(sem_hdl, ticks) == OS_OK;
} }
static inline void osal_semaphore_reset(osal_semaphore_t sem_hdl) static inline void osal_semaphore_reset(osal_semaphore_t sem_hdl) {
{
// TODO implement later // TODO implement later
} }
@ -75,19 +75,21 @@ static inline void osal_semaphore_reset(osal_semaphore_t sem_hdl)
typedef struct os_mutex osal_mutex_def_t; typedef struct os_mutex osal_mutex_def_t;
typedef struct os_mutex* osal_mutex_t; typedef struct os_mutex* osal_mutex_t;
TU_ATTR_ALWAYS_INLINE static inline osal_mutex_t osal_mutex_create(osal_mutex_def_t* mdef) TU_ATTR_ALWAYS_INLINE static inline osal_mutex_t osal_mutex_create(osal_mutex_def_t* mdef) {
{
return (os_mutex_init(mdef) == OS_OK) ? (osal_mutex_t) mdef : NULL; return (os_mutex_init(mdef) == OS_OK) ? (osal_mutex_t) mdef : NULL;
} }
TU_ATTR_ALWAYS_INLINE static inline bool osal_mutex_lock(osal_mutex_t mutex_hdl, uint32_t msec) TU_ATTR_ALWAYS_INLINE static inline bool osal_mutex_delete(osal_mutex_t mutex_hdl) {
{ (void) mutex_hdl;
return true; // nothing to do
}
TU_ATTR_ALWAYS_INLINE static inline bool osal_mutex_lock(osal_mutex_t mutex_hdl, uint32_t msec) {
uint32_t const ticks = (msec == OSAL_TIMEOUT_WAIT_FOREVER) ? OS_TIMEOUT_NEVER : os_time_ms_to_ticks32(msec); uint32_t const ticks = (msec == OSAL_TIMEOUT_WAIT_FOREVER) ? OS_TIMEOUT_NEVER : os_time_ms_to_ticks32(msec);
return os_mutex_pend(mutex_hdl, ticks) == OS_OK; return os_mutex_pend(mutex_hdl, ticks) == OS_OK;
} }
TU_ATTR_ALWAYS_INLINE static inline bool osal_mutex_unlock(osal_mutex_t mutex_hdl) TU_ATTR_ALWAYS_INLINE static inline bool osal_mutex_unlock(osal_mutex_t mutex_hdl) {
{
return os_mutex_release(mutex_hdl) == OS_OK; return os_mutex_release(mutex_hdl) == OS_OK;
} }
@ -101,8 +103,7 @@ TU_ATTR_ALWAYS_INLINE static inline bool osal_mutex_unlock(osal_mutex_t mutex_hd
static struct os_event _name##_##evbuf[_depth];\ static struct os_event _name##_##evbuf[_depth];\
osal_queue_def_t _name = { .depth = _depth, .item_sz = sizeof(_type), .buf = _name##_##buf, .evbuf = _name##_##evbuf};\ osal_queue_def_t _name = { .depth = _depth, .item_sz = sizeof(_type), .buf = _name##_##buf, .evbuf = _name##_##evbuf};\
typedef struct typedef struct {
{
uint16_t depth; uint16_t depth;
uint16_t item_sz; uint16_t item_sz;
void* buf; void* buf;
@ -116,17 +117,20 @@ typedef struct
typedef osal_queue_def_t* osal_queue_t; typedef osal_queue_def_t* osal_queue_t;
TU_ATTR_ALWAYS_INLINE static inline osal_queue_t osal_queue_create(osal_queue_def_t* qdef) TU_ATTR_ALWAYS_INLINE static inline osal_queue_t osal_queue_create(osal_queue_def_t* qdef) {
{ if ( OS_OK != os_mempool_init(&qdef->mpool, qdef->depth, qdef->item_sz, qdef->buf, "usb queue") ) return NULL;
if ( OS_OK != os_mempool_init(&qdef->mpool, qdef->depth, qdef->item_sz, qdef->buf, "usbd queue") ) return NULL; if ( OS_OK != os_mempool_init(&qdef->epool, qdef->depth, sizeof(struct os_event), qdef->evbuf, "usb evqueue") ) return NULL;
if ( OS_OK != os_mempool_init(&qdef->epool, qdef->depth, sizeof(struct os_event), qdef->evbuf, "usbd evqueue") ) return NULL;
os_eventq_init(&qdef->evq); os_eventq_init(&qdef->evq);
return (osal_queue_t) qdef; return (osal_queue_t) qdef;
} }
TU_ATTR_ALWAYS_INLINE static inline bool osal_queue_receive(osal_queue_t qhdl, void* data, uint32_t msec) TU_ATTR_ALWAYS_INLINE static inline bool osal_queue_delete(osal_queue_t qhdl) {
{ (void) qhdl;
return true; // nothing to do
}
TU_ATTR_ALWAYS_INLINE static inline bool osal_queue_receive(osal_queue_t qhdl, void* data, uint32_t msec) {
(void) msec; // os_eventq_get() does not take timeout, always behave as msec = WAIT_FOREVER (void) msec; // os_eventq_get() does not take timeout, always behave as msec = WAIT_FOREVER
struct os_event* ev; struct os_event* ev;
@ -139,8 +143,7 @@ TU_ATTR_ALWAYS_INLINE static inline bool osal_queue_receive(osal_queue_t qhdl, v
return true; return true;
} }
static inline bool osal_queue_send(osal_queue_t qhdl, void const * data, bool in_isr) static inline bool osal_queue_send(osal_queue_t qhdl, void const * data, bool in_isr) {
{
(void) in_isr; (void) in_isr;
// get a block from mem pool for data // get a block from mem pool for data
@ -150,8 +153,7 @@ static inline bool osal_queue_send(osal_queue_t qhdl, void const * data, bool in
// get a block from event pool to put into queue // get a block from event pool to put into queue
struct os_event* ev = (struct os_event*) os_memblock_get(&qhdl->epool); struct os_event* ev = (struct os_event*) os_memblock_get(&qhdl->epool);
if (!ev) if (!ev) {
{
os_memblock_put(&qhdl->mpool, ptr); os_memblock_put(&qhdl->mpool, ptr);
return false; return false;
} }
@ -163,8 +165,7 @@ static inline bool osal_queue_send(osal_queue_t qhdl, void const * data, bool in
return true; return true;
} }
TU_ATTR_ALWAYS_INLINE static inline bool osal_queue_empty(osal_queue_t qhdl) TU_ATTR_ALWAYS_INLINE static inline bool osal_queue_empty(osal_queue_t qhdl) {
{
return STAILQ_EMPTY(&qhdl->evq.evq_list); return STAILQ_EMPTY(&qhdl->evq.evq_list);
} }

View File

@ -54,6 +54,12 @@ TU_ATTR_ALWAYS_INLINE static inline osal_semaphore_t osal_semaphore_create(osal_
return semdef; return semdef;
} }
TU_ATTR_ALWAYS_INLINE static inline bool osal_semaphore_delete(osal_semaphore_t semd_hdl) {
(void) semd_hdl;
return true; // nothing to do
}
TU_ATTR_ALWAYS_INLINE static inline bool osal_semaphore_post(osal_semaphore_t sem_hdl, bool in_isr) { TU_ATTR_ALWAYS_INLINE static inline bool osal_semaphore_post(osal_semaphore_t sem_hdl, bool in_isr) {
(void) in_isr; (void) in_isr;
sem_hdl->count++; sem_hdl->count++;
@ -90,6 +96,11 @@ TU_ATTR_ALWAYS_INLINE static inline osal_mutex_t osal_mutex_create(osal_mutex_de
return mdef; return mdef;
} }
TU_ATTR_ALWAYS_INLINE static inline bool osal_mutex_delete(osal_mutex_t mutex_hdl) {
(void) mutex_hdl;
return true; // nothing to do
}
TU_ATTR_ALWAYS_INLINE static inline bool osal_mutex_lock (osal_mutex_t mutex_hdl, uint32_t msec) { TU_ATTR_ALWAYS_INLINE static inline bool osal_mutex_lock (osal_mutex_t mutex_hdl, uint32_t msec) {
return osal_semaphore_wait(mutex_hdl, msec); return osal_semaphore_wait(mutex_hdl, msec);
} }
@ -143,6 +154,11 @@ TU_ATTR_ALWAYS_INLINE static inline osal_queue_t osal_queue_create(osal_queue_de
return (osal_queue_t) qdef; return (osal_queue_t) qdef;
} }
TU_ATTR_ALWAYS_INLINE static inline bool osal_queue_delete(osal_queue_t qhdl) {
(void) qhdl;
return true; // nothing to do
}
TU_ATTR_ALWAYS_INLINE static inline bool osal_queue_receive(osal_queue_t qhdl, void* data, uint32_t msec) { TU_ATTR_ALWAYS_INLINE static inline bool osal_queue_receive(osal_queue_t qhdl, void* data, uint32_t msec) {
(void) msec; // not used, always behave as msec = 0 (void) msec; // not used, always behave as msec = 0

View File

@ -24,8 +24,8 @@
* This file is part of the TinyUSB stack. * This file is part of the TinyUSB stack.
*/ */
#ifndef _TUSB_OSAL_PICO_H_ #ifndef TUSB_OSAL_PICO_H_
#define _TUSB_OSAL_PICO_H_ #define TUSB_OSAL_PICO_H_
#include "pico/time.h" #include "pico/time.h"
#include "pico/sem.h" #include "pico/sem.h"
@ -39,8 +39,7 @@
//--------------------------------------------------------------------+ //--------------------------------------------------------------------+
// TASK API // TASK API
//--------------------------------------------------------------------+ //--------------------------------------------------------------------+
TU_ATTR_ALWAYS_INLINE static inline void osal_task_delay(uint32_t msec) TU_ATTR_ALWAYS_INLINE static inline void osal_task_delay(uint32_t msec) {
{
sleep_ms(msec); sleep_ms(msec);
} }
@ -49,26 +48,27 @@ TU_ATTR_ALWAYS_INLINE static inline void osal_task_delay(uint32_t msec)
//--------------------------------------------------------------------+ //--------------------------------------------------------------------+
typedef struct semaphore osal_semaphore_def_t, * osal_semaphore_t; typedef struct semaphore osal_semaphore_def_t, * osal_semaphore_t;
TU_ATTR_ALWAYS_INLINE static inline osal_semaphore_t osal_semaphore_create(osal_semaphore_def_t* semdef) TU_ATTR_ALWAYS_INLINE static inline osal_semaphore_t osal_semaphore_create(osal_semaphore_def_t* semdef) {
{
sem_init(semdef, 0, 255); sem_init(semdef, 0, 255);
return semdef; return semdef;
} }
TU_ATTR_ALWAYS_INLINE static inline bool osal_semaphore_post(osal_semaphore_t sem_hdl, bool in_isr) TU_ATTR_ALWAYS_INLINE static inline bool osal_semaphore_delete(osal_semaphore_t semd_hdl) {
{ (void) semd_hdl;
return true; // nothing to do
}
TU_ATTR_ALWAYS_INLINE static inline bool osal_semaphore_post(osal_semaphore_t sem_hdl, bool in_isr) {
(void) in_isr; (void) in_isr;
sem_release(sem_hdl); sem_release(sem_hdl);
return true; return true;
} }
TU_ATTR_ALWAYS_INLINE static inline bool osal_semaphore_wait (osal_semaphore_t sem_hdl, uint32_t msec) TU_ATTR_ALWAYS_INLINE static inline bool osal_semaphore_wait(osal_semaphore_t sem_hdl, uint32_t msec) {
{
return sem_acquire_timeout_ms(sem_hdl, msec); return sem_acquire_timeout_ms(sem_hdl, msec);
} }
TU_ATTR_ALWAYS_INLINE static inline void osal_semaphore_reset(osal_semaphore_t sem_hdl) TU_ATTR_ALWAYS_INLINE static inline void osal_semaphore_reset(osal_semaphore_t sem_hdl) {
{
sem_reset(sem_hdl, 0); sem_reset(sem_hdl, 0);
} }
@ -78,19 +78,21 @@ TU_ATTR_ALWAYS_INLINE static inline void osal_semaphore_reset(osal_semaphore_t s
//--------------------------------------------------------------------+ //--------------------------------------------------------------------+
typedef struct mutex osal_mutex_def_t, * osal_mutex_t; typedef struct mutex osal_mutex_def_t, * osal_mutex_t;
TU_ATTR_ALWAYS_INLINE static inline osal_mutex_t osal_mutex_create(osal_mutex_def_t* mdef) TU_ATTR_ALWAYS_INLINE static inline osal_mutex_t osal_mutex_create(osal_mutex_def_t* mdef) {
{
mutex_init(mdef); mutex_init(mdef);
return mdef; return mdef;
} }
TU_ATTR_ALWAYS_INLINE static inline bool osal_mutex_lock (osal_mutex_t mutex_hdl, uint32_t msec) TU_ATTR_ALWAYS_INLINE static inline bool osal_mutex_delete(osal_mutex_t mutex_hdl) {
{ (void) mutex_hdl;
return true; // nothing to do
}
TU_ATTR_ALWAYS_INLINE static inline bool osal_mutex_lock(osal_mutex_t mutex_hdl, uint32_t msec) {
return mutex_enter_timeout_ms(mutex_hdl, msec); return mutex_enter_timeout_ms(mutex_hdl, msec);
} }
TU_ATTR_ALWAYS_INLINE static inline bool osal_mutex_unlock(osal_mutex_t mutex_hdl) TU_ATTR_ALWAYS_INLINE static inline bool osal_mutex_unlock(osal_mutex_t mutex_hdl) {
{
mutex_exit(mutex_hdl); mutex_exit(mutex_hdl);
return true; return true;
} }
@ -100,8 +102,7 @@ TU_ATTR_ALWAYS_INLINE static inline bool osal_mutex_unlock(osal_mutex_t mutex_hd
//--------------------------------------------------------------------+ //--------------------------------------------------------------------+
#include "common/tusb_fifo.h" #include "common/tusb_fifo.h"
typedef struct typedef struct {
{
tu_fifo_t ff; tu_fifo_t ff;
struct critical_section critsec; // osal_queue may be used in IRQs, so need critical section struct critical_section critsec; // osal_queue may be used in IRQs, so need critical section
} osal_queue_def_t; } osal_queue_def_t;
@ -115,60 +116,40 @@ typedef osal_queue_def_t* osal_queue_t;
.ff = TU_FIFO_INIT(_name##_buf, _depth, _type, false) \ .ff = TU_FIFO_INIT(_name##_buf, _depth, _type, false) \
} }
// lock queue by disable USB interrupt TU_ATTR_ALWAYS_INLINE static inline osal_queue_t osal_queue_create(osal_queue_def_t* qdef) {
TU_ATTR_ALWAYS_INLINE static inline void _osal_q_lock(osal_queue_t qhdl)
{
critical_section_enter_blocking(&qhdl->critsec);
}
// unlock queue
TU_ATTR_ALWAYS_INLINE static inline void _osal_q_unlock(osal_queue_t qhdl)
{
critical_section_exit(&qhdl->critsec);
}
TU_ATTR_ALWAYS_INLINE static inline osal_queue_t osal_queue_create(osal_queue_def_t* qdef)
{
critical_section_init(&qdef->critsec); critical_section_init(&qdef->critsec);
tu_fifo_clear(&qdef->ff); tu_fifo_clear(&qdef->ff);
return (osal_queue_t) qdef; return (osal_queue_t) qdef;
} }
TU_ATTR_ALWAYS_INLINE static inline bool osal_queue_receive(osal_queue_t qhdl, void* data, uint32_t msec) TU_ATTR_ALWAYS_INLINE static inline bool osal_queue_delete(osal_queue_t qhdl) {
{ osal_queue_def_t* qdef = (osal_queue_def_t*) qhdl;
critical_section_deinit(&qdef->critsec);
return true;
}
TU_ATTR_ALWAYS_INLINE static inline bool osal_queue_receive(osal_queue_t qhdl, void* data, uint32_t msec) {
(void) msec; // not used, always behave as msec = 0 (void) msec; // not used, always behave as msec = 0
// TODO: revisit... docs say that mutexes are never used from IRQ context, critical_section_enter_blocking(&qhdl->critsec);
// however osal_queue_recieve may be. therefore my assumption is that
// the fifo mutex is not populated for queues used from an IRQ context
//assert(!qhdl->ff.mutex);
_osal_q_lock(qhdl);
bool success = tu_fifo_read(&qhdl->ff, data); bool success = tu_fifo_read(&qhdl->ff, data);
_osal_q_unlock(qhdl); critical_section_exit(&qhdl->critsec);
return success; return success;
} }
TU_ATTR_ALWAYS_INLINE static inline bool osal_queue_send(osal_queue_t qhdl, void const * data, bool in_isr) TU_ATTR_ALWAYS_INLINE static inline bool osal_queue_send(osal_queue_t qhdl, void const* data, bool in_isr) {
{
// TODO: revisit... docs say that mutexes are never used from IRQ context,
// however osal_queue_recieve may be. therefore my assumption is that
// the fifo mutex is not populated for queues used from an IRQ context
//assert(!qhdl->ff.mutex);
(void) in_isr; (void) in_isr;
_osal_q_lock(qhdl); critical_section_enter_blocking(&qhdl->critsec);
bool success = tu_fifo_write(&qhdl->ff, data); bool success = tu_fifo_write(&qhdl->ff, data);
_osal_q_unlock(qhdl); critical_section_exit(&qhdl->critsec);
TU_ASSERT(success); TU_ASSERT(success);
return success; return success;
} }
TU_ATTR_ALWAYS_INLINE static inline bool osal_queue_empty(osal_queue_t qhdl) TU_ATTR_ALWAYS_INLINE static inline bool osal_queue_empty(osal_queue_t qhdl) {
{
// TODO: revisit; whether this is true or not currently, tu_fifo_empty is a single // TODO: revisit; whether this is true or not currently, tu_fifo_empty is a single
// volatile read. // volatile read.
@ -181,4 +162,4 @@ TU_ATTR_ALWAYS_INLINE static inline bool osal_queue_empty(osal_queue_t qhdl)
} }
#endif #endif
#endif /* _TUSB_OSAL_PICO_H_ */ #endif

View File

@ -25,8 +25,8 @@
* This file is part of the TinyUSB stack. * This file is part of the TinyUSB stack.
*/ */
#ifndef _TUSB_OSAL_RTTHREAD_H_ #ifndef TUSB_OSAL_RTTHREAD_H_
#define _TUSB_OSAL_RTTHREAD_H_ #define TUSB_OSAL_RTTHREAD_H_
// RT-Thread Headers // RT-Thread Headers
#include "rtthread.h" #include "rtthread.h"
@ -48,12 +48,16 @@ TU_ATTR_ALWAYS_INLINE static inline void osal_task_delay(uint32_t msec) {
typedef struct rt_semaphore osal_semaphore_def_t; typedef struct rt_semaphore osal_semaphore_def_t;
typedef rt_sem_t osal_semaphore_t; typedef rt_sem_t osal_semaphore_t;
TU_ATTR_ALWAYS_INLINE static inline osal_semaphore_t TU_ATTR_ALWAYS_INLINE static inline
osal_semaphore_create(osal_semaphore_def_t *semdef) { osal_semaphore_t osal_semaphore_create(osal_semaphore_def_t *semdef) {
rt_sem_init(semdef, "tusb", 0, RT_IPC_FLAG_PRIO); rt_sem_init(semdef, "tusb", 0, RT_IPC_FLAG_PRIO);
return semdef; return semdef;
} }
TU_ATTR_ALWAYS_INLINE static inline bool osal_semaphore_delete(osal_semaphore_t semd_hdl) {
return RT_EOK == rt_sem_detach(semd_hdl);
}
TU_ATTR_ALWAYS_INLINE static inline bool osal_semaphore_post(osal_semaphore_t sem_hdl, bool in_isr) { TU_ATTR_ALWAYS_INLINE static inline bool osal_semaphore_post(osal_semaphore_t sem_hdl, bool in_isr) {
(void) in_isr; (void) in_isr;
return rt_sem_release(sem_hdl) == RT_EOK; return rt_sem_release(sem_hdl) == RT_EOK;
@ -78,6 +82,10 @@ TU_ATTR_ALWAYS_INLINE static inline osal_mutex_t osal_mutex_create(osal_mutex_de
return mdef; return mdef;
} }
TU_ATTR_ALWAYS_INLINE static inline bool osal_mutex_delete(osal_mutex_t mutex_hdl) {
return RT_EOK == rt_mutex_detach(mutex_hdl);
}
TU_ATTR_ALWAYS_INLINE static inline bool osal_mutex_lock(osal_mutex_t mutex_hdl, uint32_t msec) { TU_ATTR_ALWAYS_INLINE static inline bool osal_mutex_lock(osal_mutex_t mutex_hdl, uint32_t msec) {
return rt_mutex_take(mutex_hdl, rt_tick_from_millisecond((rt_int32_t) msec)) == RT_EOK; return rt_mutex_take(mutex_hdl, rt_tick_from_millisecond((rt_int32_t) msec)) == RT_EOK;
} }
@ -111,6 +119,10 @@ TU_ATTR_ALWAYS_INLINE static inline osal_queue_t osal_queue_create(osal_queue_de
return &(qdef->sq); return &(qdef->sq);
} }
TU_ATTR_ALWAYS_INLINE static inline bool osal_queue_delete(osal_queue_t qhdl) {
return RT_EOK == rt_mq_detach(qhdl);
}
TU_ATTR_ALWAYS_INLINE static inline bool osal_queue_receive(osal_queue_t qhdl, void *data, uint32_t msec) { TU_ATTR_ALWAYS_INLINE static inline bool osal_queue_receive(osal_queue_t qhdl, void *data, uint32_t msec) {
rt_tick_t tick = rt_tick_from_millisecond((rt_int32_t) msec); rt_tick_t tick = rt_tick_from_millisecond((rt_int32_t) msec);
#if RT_VERSION_MAJOR >= 5 #if RT_VERSION_MAJOR >= 5
@ -133,4 +145,4 @@ TU_ATTR_ALWAYS_INLINE static inline bool osal_queue_empty(osal_queue_t qhdl) {
} }
#endif #endif
#endif /* _TUSB_OSAL_RTTHREAD_H_ */ #endif

View File

@ -25,8 +25,8 @@
* This file is part of the TinyUSB stack. * This file is part of the TinyUSB stack.
*/ */
#ifndef _TUSB_OSAL_RTX4_H_ #ifndef TUSB_OSAL_RTX4_H_
#define _TUSB_OSAL_RTX4_H_ #define TUSB_OSAL_RTX4_H_
#include <rtl.h> #include <rtl.h>
@ -37,8 +37,7 @@ extern "C" {
//--------------------------------------------------------------------+ //--------------------------------------------------------------------+
// TASK API // TASK API
//--------------------------------------------------------------------+ //--------------------------------------------------------------------+
TU_ATTR_ALWAYS_INLINE static inline void osal_task_delay(uint32_t msec) TU_ATTR_ALWAYS_INLINE static inline void osal_task_delay(uint32_t msec) {
{
uint16_t hi = msec >> 16; uint16_t hi = msec >> 16;
uint16_t lo = msec; uint16_t lo = msec;
while (hi--) { while (hi--) {
@ -48,13 +47,14 @@ TU_ATTR_ALWAYS_INLINE static inline void osal_task_delay(uint32_t msec)
} }
TU_ATTR_ALWAYS_INLINE static inline uint16_t msec2wait(uint32_t msec) { TU_ATTR_ALWAYS_INLINE static inline uint16_t msec2wait(uint32_t msec) {
if (msec == OSAL_TIMEOUT_WAIT_FOREVER) if (msec == OSAL_TIMEOUT_WAIT_FOREVER) {
return 0xFFFF; return 0xFFFF;
else if (msec >= 0xFFFE) } else if (msec >= 0xFFFE) {
return 0xFFFE; return 0xFFFE;
else } else {
return msec; return msec;
} }
}
//--------------------------------------------------------------------+ //--------------------------------------------------------------------+
// Semaphore API // Semaphore API
@ -67,6 +67,11 @@ TU_ATTR_ALWAYS_INLINE static inline OS_ID osal_semaphore_create(osal_semaphore_d
return semdef; return semdef;
} }
TU_ATTR_ALWAYS_INLINE static inline bool osal_semaphore_delete(osal_semaphore_t semd_hdl) {
(void) semd_hdl;
return true; // nothing to do
}
TU_ATTR_ALWAYS_INLINE static inline bool osal_semaphore_post(osal_semaphore_t sem_hdl, bool in_isr) { TU_ATTR_ALWAYS_INLINE static inline bool osal_semaphore_post(osal_semaphore_t sem_hdl, bool in_isr) {
if ( !in_isr ) { if ( !in_isr ) {
os_sem_send(sem_hdl); os_sem_send(sem_hdl);
@ -90,19 +95,21 @@ TU_ATTR_ALWAYS_INLINE static inline void osal_semaphore_reset(osal_semaphore_t c
typedef OS_MUT osal_mutex_def_t; typedef OS_MUT osal_mutex_def_t;
typedef OS_ID osal_mutex_t; typedef OS_ID osal_mutex_t;
TU_ATTR_ALWAYS_INLINE static inline osal_mutex_t osal_mutex_create(osal_mutex_def_t* mdef) TU_ATTR_ALWAYS_INLINE static inline osal_mutex_t osal_mutex_create(osal_mutex_def_t* mdef) {
{
os_mut_init(mdef); os_mut_init(mdef);
return mdef; return mdef;
} }
TU_ATTR_ALWAYS_INLINE static inline bool osal_mutex_lock (osal_mutex_t mutex_hdl, uint32_t msec) TU_ATTR_ALWAYS_INLINE static inline bool osal_mutex_delete(osal_mutex_t mutex_hdl) {
{ (void) mutex_hdl;
return true; // nothing to do
}
TU_ATTR_ALWAYS_INLINE static inline bool osal_mutex_lock (osal_mutex_t mutex_hdl, uint32_t msec) {
return os_mut_wait(mutex_hdl, msec2wait(msec)) != OS_R_TMO; return os_mut_wait(mutex_hdl, msec2wait(msec)) != OS_R_TMO;
} }
TU_ATTR_ALWAYS_INLINE static inline bool osal_mutex_unlock(osal_mutex_t mutex_hdl) TU_ATTR_ALWAYS_INLINE static inline bool osal_mutex_unlock(osal_mutex_t mutex_hdl) {
{
return os_mut_release(mutex_hdl) == OS_R_OK; return os_mut_release(mutex_hdl) == OS_R_OK;
} }
@ -116,9 +123,7 @@ TU_ATTR_ALWAYS_INLINE static inline bool osal_mutex_unlock(osal_mutex_t mutex_hd
_declare_box(_name##__pool, sizeof(_type), _depth); \ _declare_box(_name##__pool, sizeof(_type), _depth); \
osal_queue_def_t _name = { .depth = _depth, .item_sz = sizeof(_type), .pool = _name##__pool, .mbox = _name##__mbox }; osal_queue_def_t _name = { .depth = _depth, .item_sz = sizeof(_type), .pool = _name##__pool, .mbox = _name##__mbox };
typedef struct {
typedef struct
{
uint16_t depth; uint16_t depth;
uint16_t item_sz; uint16_t item_sz;
U32* pool; U32* pool;
@ -127,15 +132,13 @@ typedef struct
typedef osal_queue_def_t* osal_queue_t; typedef osal_queue_def_t* osal_queue_t;
TU_ATTR_ALWAYS_INLINE static inline osal_queue_t osal_queue_create(osal_queue_def_t* qdef) TU_ATTR_ALWAYS_INLINE static inline osal_queue_t osal_queue_create(osal_queue_def_t* qdef) {
{
os_mbx_init(qdef->mbox, (qdef->depth + 4) * 4); os_mbx_init(qdef->mbox, (qdef->depth + 4) * 4);
_init_box(qdef->pool, ((qdef->item_sz+3)/4)*(qdef->depth) + 3, qdef->item_sz); _init_box(qdef->pool, ((qdef->item_sz+3)/4)*(qdef->depth) + 3, qdef->item_sz);
return qdef; return qdef;
} }
TU_ATTR_ALWAYS_INLINE static inline bool osal_queue_receive(osal_queue_t qhdl, void* data, uint32_t msec) TU_ATTR_ALWAYS_INLINE static inline bool osal_queue_receive(osal_queue_t qhdl, void* data, uint32_t msec) {
{
void* buf; void* buf;
os_mbx_wait(qhdl->mbox, &buf, msec2wait(msec)); os_mbx_wait(qhdl->mbox, &buf, msec2wait(msec));
memcpy(data, buf, qhdl->item_sz); memcpy(data, buf, qhdl->item_sz);
@ -143,23 +146,23 @@ TU_ATTR_ALWAYS_INLINE static inline bool osal_queue_receive(osal_queue_t qhdl, v
return true; return true;
} }
TU_ATTR_ALWAYS_INLINE static inline bool osal_queue_send(osal_queue_t qhdl, void const * data, bool in_isr) TU_ATTR_ALWAYS_INLINE static inline bool osal_queue_delete(osal_queue_t qhdl) {
{ (void) qhdl;
return true; // nothing to do ?
}
TU_ATTR_ALWAYS_INLINE static inline bool osal_queue_send(osal_queue_t qhdl, void const * data, bool in_isr) {
void* buf = _alloc_box(qhdl->pool); void* buf = _alloc_box(qhdl->pool);
memcpy(buf, data, qhdl->item_sz); memcpy(buf, data, qhdl->item_sz);
if ( !in_isr ) if ( !in_isr ) {
{
os_mbx_send(qhdl->mbox, buf, 0xFFFF); os_mbx_send(qhdl->mbox, buf, 0xFFFF);
} } else {
else
{
isr_mbx_send(qhdl->mbox, buf); isr_mbx_send(qhdl->mbox, buf);
} }
return true; return true;
} }
TU_ATTR_ALWAYS_INLINE static inline bool osal_queue_empty(osal_queue_t qhdl) TU_ATTR_ALWAYS_INLINE static inline bool osal_queue_empty(osal_queue_t qhdl) {
{
return os_mbx_check(qhdl->mbox) == qhdl->depth; return os_mbx_check(qhdl->mbox) == qhdl->depth;
} }

View File

@ -168,18 +168,17 @@ bool tu_edpt_validate(tusb_desc_endpoint_t const* desc_ep, tusb_speed_t speed) {
return true; return true;
} }
void tu_edpt_bind_driver(uint8_t ep2drv[][2], tusb_desc_interface_t const* desc_itf, uint16_t desc_len, uint8_t driver_id) { void tu_edpt_bind_driver(uint8_t ep2drv[][2], tusb_desc_interface_t const* desc_itf, uint16_t desc_len,
uint8_t driver_id) {
uint8_t const* p_desc = (uint8_t const*) desc_itf; uint8_t const* p_desc = (uint8_t const*) desc_itf;
uint8_t const* desc_end = p_desc + desc_len; uint8_t const* desc_end = p_desc + desc_len;
while (p_desc < desc_end) { while (p_desc < desc_end) {
if (TUSB_DESC_ENDPOINT == tu_desc_type(p_desc)) { if (TUSB_DESC_ENDPOINT == tu_desc_type(p_desc)) {
uint8_t const ep_addr = ((tusb_desc_endpoint_t const*) p_desc)->bEndpointAddress; uint8_t const ep_addr = ((tusb_desc_endpoint_t const*) p_desc)->bEndpointAddress;
TU_LOG(2, " Bind EP %02x to driver id %u\r\n", ep_addr, driver_id); TU_LOG(2, " Bind EP %02x to driver id %u\r\n", ep_addr, driver_id);
ep2drv[tu_edpt_number(ep_addr)][tu_edpt_dir(ep_addr)] = driver_id; ep2drv[tu_edpt_number(ep_addr)][tu_edpt_dir(ep_addr)] = driver_id;
} }
p_desc = tu_desc_next(p_desc); p_desc = tu_desc_next(p_desc);
} }
} }
@ -195,8 +194,9 @@ uint16_t tu_desc_get_interface_total_len(tusb_desc_interface_t const* desc_itf,
while (len < max_len) { while (len < max_len) {
// return on IAD regardless of itf count // return on IAD regardless of itf count
if (tu_desc_type(p_desc) == TUSB_DESC_INTERFACE_ASSOCIATION) return len; if (tu_desc_type(p_desc) == TUSB_DESC_INTERFACE_ASSOCIATION) {
return len;
}
if ((tu_desc_type(p_desc) == TUSB_DESC_INTERFACE) && if ((tu_desc_type(p_desc) == TUSB_DESC_INTERFACE) &&
((tusb_desc_interface_t const*) p_desc)->bAlternateSetting == 0) { ((tusb_desc_interface_t const*) p_desc)->bAlternateSetting == 0) {
break; break;
@ -216,7 +216,7 @@ uint16_t tu_desc_get_interface_total_len(tusb_desc_interface_t const* desc_itf,
bool tu_edpt_stream_init(tu_edpt_stream_t* s, bool is_host, bool is_tx, bool overwritable, bool tu_edpt_stream_init(tu_edpt_stream_t* s, bool is_host, bool is_tx, bool overwritable,
void* ff_buf, uint16_t ff_bufsize, uint8_t* ep_buf, uint16_t ep_bufsize) { void* ff_buf, uint16_t ff_bufsize, uint8_t* ep_buf, uint16_t ep_bufsize) {
osal_mutex_t new_mutex = osal_mutex_create(&s->ff_mutex); osal_mutex_t new_mutex = osal_mutex_create(&s->ff_mutexdef);
(void) new_mutex; (void) new_mutex;
(void) is_tx; (void) is_tx;
@ -230,7 +230,17 @@ bool tu_edpt_stream_init(tu_edpt_stream_t* s, bool is_host, bool is_tx, bool ove
return true; return true;
} }
TU_ATTR_ALWAYS_INLINE static inline bool stream_claim(tu_edpt_stream_t* s) { bool tu_edpt_stream_deinit(tu_edpt_stream_t* s) {
(void) s;
#if OSAL_MUTEX_REQUIRED
if (s->ff.mutex_wr) osal_mutex_delete(s->ff.mutex_wr);
if (s->ff.mutex_rd) osal_mutex_delete(s->ff.mutex_rd);
#endif
return true;
}
TU_ATTR_ALWAYS_INLINE static inline
bool stream_claim(tu_edpt_stream_t* s) {
if (s->is_host) { if (s->is_host) {
#if CFG_TUH_ENABLED #if CFG_TUH_ENABLED
return usbh_edpt_claim(s->daddr, s->ep_addr); return usbh_edpt_claim(s->daddr, s->ep_addr);
@ -240,11 +250,11 @@ TU_ATTR_ALWAYS_INLINE static inline bool stream_claim(tu_edpt_stream_t* s) {
return usbd_edpt_claim(s->rhport, s->ep_addr); return usbd_edpt_claim(s->rhport, s->ep_addr);
#endif #endif
} }
return false; return false;
} }
TU_ATTR_ALWAYS_INLINE static inline bool stream_xfer(tu_edpt_stream_t* s, uint16_t count) { TU_ATTR_ALWAYS_INLINE static inline
bool stream_xfer(tu_edpt_stream_t* s, uint16_t count) {
if (s->is_host) { if (s->is_host) {
#if CFG_TUH_ENABLED #if CFG_TUH_ENABLED
return usbh_edpt_xfer(s->daddr, s->ep_addr, count ? s->ep_buf : NULL, count); return usbh_edpt_xfer(s->daddr, s->ep_addr, count ? s->ep_buf : NULL, count);
@ -254,11 +264,11 @@ TU_ATTR_ALWAYS_INLINE static inline bool stream_xfer(tu_edpt_stream_t* s, uint16
return usbd_edpt_xfer(s->rhport, s->ep_addr, count ? s->ep_buf : NULL, count); return usbd_edpt_xfer(s->rhport, s->ep_addr, count ? s->ep_buf : NULL, count);
#endif #endif
} }
return false; return false;
} }
TU_ATTR_ALWAYS_INLINE static inline bool stream_release(tu_edpt_stream_t* s) { TU_ATTR_ALWAYS_INLINE static inline
bool stream_release(tu_edpt_stream_t* s) {
if (s->is_host) { if (s->is_host) {
#if CFG_TUH_ENABLED #if CFG_TUH_ENABLED
return usbh_edpt_release(s->daddr, s->ep_addr); return usbh_edpt_release(s->daddr, s->ep_addr);
@ -268,20 +278,17 @@ TU_ATTR_ALWAYS_INLINE static inline bool stream_release(tu_edpt_stream_t* s) {
return usbd_edpt_release(s->rhport, s->ep_addr); return usbd_edpt_release(s->rhport, s->ep_addr);
#endif #endif
} }
return false; return false;
} }
//--------------------------------------------------------------------+ //--------------------------------------------------------------------+
// Stream Write // Stream Write
//--------------------------------------------------------------------+ //--------------------------------------------------------------------+
bool tu_edpt_stream_write_zlp_if_needed(tu_edpt_stream_t* s, uint32_t last_xferred_bytes) { bool tu_edpt_stream_write_zlp_if_needed(tu_edpt_stream_t* s, uint32_t last_xferred_bytes) {
// ZLP condition: no pending data, last transferred bytes is multiple of packet size // ZLP condition: no pending data, last transferred bytes is multiple of packet size
TU_VERIFY(!tu_fifo_count(&s->ff) && last_xferred_bytes && (0 == (last_xferred_bytes & (s->ep_packetsize - 1)))); TU_VERIFY(!tu_fifo_count(&s->ff) && last_xferred_bytes && (0 == (last_xferred_bytes & (s->ep_packetsize - 1))));
TU_VERIFY(stream_claim(s)); TU_VERIFY(stream_claim(s));
TU_ASSERT(stream_xfer(s, 0)); TU_ASSERT(stream_xfer(s, 0));
return true; return true;
} }
@ -308,7 +315,6 @@ uint32_t tu_edpt_stream_write_xfer(tu_edpt_stream_t* s) {
uint32_t tu_edpt_stream_write(tu_edpt_stream_t* s, void const* buffer, uint32_t bufsize) { uint32_t tu_edpt_stream_write(tu_edpt_stream_t* s, void const* buffer, uint32_t bufsize) {
TU_VERIFY(bufsize); // TODO support ZLP TU_VERIFY(bufsize); // TODO support ZLP
uint16_t ret = tu_fifo_write_n(&s->ff, buffer, (uint16_t) bufsize); uint16_t ret = tu_fifo_write_n(&s->ff, buffer, (uint16_t) bufsize);
// flush if fifo has more than packet size or // flush if fifo has more than packet size or
@ -323,7 +329,6 @@ uint32_t tu_edpt_stream_write(tu_edpt_stream_t* s, void const* buffer, uint32_t
//--------------------------------------------------------------------+ //--------------------------------------------------------------------+
// Stream Read // Stream Read
//--------------------------------------------------------------------+ //--------------------------------------------------------------------+
uint32_t tu_edpt_stream_read_xfer(tu_edpt_stream_t* s) { uint32_t tu_edpt_stream_read_xfer(tu_edpt_stream_t* s) {
uint16_t available = tu_fifo_remaining(&s->ff); uint16_t available = tu_fifo_remaining(&s->ff);
@ -343,6 +348,7 @@ uint32_t tu_edpt_stream_read_xfer(tu_edpt_stream_t* s) {
// multiple of packet size limit by ep bufsize // multiple of packet size limit by ep bufsize
uint16_t count = (uint16_t) (available & ~(s->ep_packetsize - 1)); uint16_t count = (uint16_t) (available & ~(s->ep_packetsize - 1));
count = tu_min16(count, s->ep_bufsize); count = tu_min16(count, s->ep_bufsize);
TU_ASSERT(stream_xfer(s, count), 0); TU_ASSERT(stream_xfer(s, count), 0);
return count; return count;
} else { } else {
@ -390,13 +396,11 @@ char const* const tu_str_xfer_result[] = {
static void dump_str_line(uint8_t const* buf, uint16_t count) { static void dump_str_line(uint8_t const* buf, uint16_t count) {
tu_printf(" |"); tu_printf(" |");
// each line is 16 bytes // each line is 16 bytes
for (uint16_t i = 0; i < count; i++) { for (uint16_t i = 0; i < count; i++) {
const char ch = buf[i]; const char ch = buf[i];
tu_printf("%c", isprint(ch) ? ch : '.'); tu_printf("%c", isprint(ch) ? ch : '.');
} }
tu_printf("|\r\n"); tu_printf("|\r\n");
} }
@ -407,17 +411,14 @@ static void dump_str_line(uint8_t const* buf, uint16_t count) {
*/ */
void tu_print_mem(void const* buf, uint32_t count, uint8_t indent) { void tu_print_mem(void const* buf, uint32_t count, uint8_t indent) {
uint8_t const size = 1; // fixed 1 byte for now uint8_t const size = 1; // fixed 1 byte for now
if (!buf || !count) { if (!buf || !count) {
tu_printf("NULL\r\n"); tu_printf("NULL\r\n");
return; return;
} }
uint8_t const* buf8 = (uint8_t const*) buf; uint8_t const* buf8 = (uint8_t const*) buf;
char format[] = "%00X"; char format[] = "%00X";
format[2] += (uint8_t) (2 * size); // 1 byte = 2 hex digits format[2] += (uint8_t) (2 * size); // 1 byte = 2 hex digits
const uint8_t item_per_line = 16 / size; const uint8_t item_per_line = 16 / size;
for (unsigned int i = 0; i < count; i++) { for (unsigned int i = 0; i < count; i++) {
@ -425,12 +426,8 @@ void tu_print_mem(void const* buf, uint32_t count, uint8_t indent) {
if (i % item_per_line == 0) { if (i % item_per_line == 0) {
// Print Ascii // Print Ascii
if (i != 0) { if (i != 0) dump_str_line(buf8 - 16, 16);
dump_str_line(buf8 - 16, 16);
}
for (uint8_t s = 0; s < indent; s++) tu_printf(" "); for (uint8_t s = 0; s < indent; s++) tu_printf(" ");
// print offset or absolute address // print offset or absolute address
tu_printf("%04X: ", 16 * i / item_per_line); tu_printf("%04X: ", 16 * i / item_per_line);
} }
@ -445,7 +442,6 @@ void tu_print_mem(void const* buf, uint32_t count, uint8_t indent) {
// fill up last row to 16 for printing ascii // fill up last row to 16 for printing ascii
const uint32_t remain = count % 16; const uint32_t remain = count % 16;
uint8_t nback = (uint8_t) (remain ? remain : 16); uint8_t nback = (uint8_t) (remain ? remain : 16);
if (remain) { if (remain) {
for (uint32_t i = 0; i < 16 - remain; i++) { for (uint32_t i = 0; i < 16 - remain; i++) {
tu_printf(" "); tu_printf(" ");

View File

@ -29,9 +29,14 @@
#include "common/tusb_compiler.h" #include "common/tusb_compiler.h"
// Version is release as major.minor.revision eg 1.0.0. though there could be notable APIs before a new release.
// For notable API changes within a release, we increase the build number.
#define TUSB_VERSION_MAJOR 0 #define TUSB_VERSION_MAJOR 0
#define TUSB_VERSION_MINOR 16 #define TUSB_VERSION_MINOR 16
#define TUSB_VERSION_REVISION 0 #define TUSB_VERSION_REVISION 0
#define TUSB_VERSION_BUILD 1
#define TUSB_VERSION_NUMBER (TUSB_VERSION_MAJOR << 24 | TUSB_VERSION_MINOR << 16 | TUSB_VERSION_REVISION << 8 | TUSB_VERSION_BUILD)
#define TUSB_VERSION_STRING TU_STRING(TUSB_VERSION_MAJOR) "." TU_STRING(TUSB_VERSION_MINOR) "." TU_STRING(TUSB_VERSION_REVISION) #define TUSB_VERSION_STRING TU_STRING(TUSB_VERSION_MAJOR) "." TU_STRING(TUSB_VERSION_MINOR) "." TU_STRING(TUSB_VERSION_REVISION)
//--------------------------------------------------------------------+ //--------------------------------------------------------------------+