From b4f092ec74d85d4e5567ebb45e1bd0dec20f0e02 Mon Sep 17 00:00:00 2001 From: Wini-Buh Date: Sat, 29 May 2021 21:23:39 +0200 Subject: Adaptations for Renesas CCRX toolchain and Rx72N controller performed --- src/class/cdc/cdc.h | 48 ++++++++++++++++++++++++++++++++++---- src/class/cdc/cdc_device.c | 23 +++++++++++++------ src/class/cdc/cdc_device.h | 57 ++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 117 insertions(+), 11 deletions(-) (limited to 'src/class') diff --git a/src/class/cdc/cdc.h b/src/class/cdc/cdc.h index f59bf0f1a..e5af9fc0c 100644 --- a/src/class/cdc/cdc.h +++ b/src/class/cdc/cdc.h @@ -216,6 +216,7 @@ typedef enum //--------------------------------------------------------------------+ /// Header Functional Descriptor (Communication Interface) +TU_PACK_STRUCT_BEGIN typedef struct TU_ATTR_PACKED { uint8_t bLength ; ///< Size of this descriptor in bytes. @@ -223,8 +224,10 @@ typedef struct TU_ATTR_PACKED uint8_t bDescriptorSubType ; ///< Descriptor SubType one of above CDC_FUNC_DESC_ uint16_t bcdCDC ; ///< CDC release number in Binary-Coded Decimal }cdc_desc_func_header_t; +TU_PACK_STRUCT_END /// Union Functional Descriptor (Communication Interface) +TU_PACK_STRUCT_BEGIN typedef struct TU_ATTR_PACKED { uint8_t bLength ; ///< Size of this descriptor in bytes. @@ -233,17 +236,21 @@ typedef struct TU_ATTR_PACKED uint8_t bControlInterface ; ///< Interface number of Communication Interface uint8_t bSubordinateInterface ; ///< Array of Interface number of Data Interface }cdc_desc_func_union_t; +TU_PACK_STRUCT_END #define cdc_desc_func_union_n_t(no_slave)\ - struct TU_ATTR_PACKED { \ + TU_PACK_STRUCT_BEGIN \ + struct TU_ATTR_PACKED { \ uint8_t bLength ;\ uint8_t bDescriptorType ;\ uint8_t bDescriptorSubType ;\ uint8_t bControlInterface ;\ uint8_t bSubordinateInterface[no_slave] ;\ -} +} \ +TU_PACK_STRUCT_END /// Country Selection Functional Descriptor (Communication Interface) +TU_PACK_STRUCT_BEGIN typedef struct TU_ATTR_PACKED { uint8_t bLength ; ///< Size of this descriptor in bytes. @@ -252,15 +259,18 @@ typedef struct TU_ATTR_PACKED uint8_t iCountryCodeRelDate ; ///< Index of a string giving the release date for the implemented ISO 3166 Country Codes. uint16_t wCountryCode ; ///< Country code in the format as defined in [ISO3166], release date as specified inoffset 3 for the first supported country. }cdc_desc_func_country_selection_t; +TU_PACK_STRUCT_END #define cdc_desc_func_country_selection_n_t(no_country) \ - struct TU_ATTR_PACKED {\ + TU_PACK_STRUCT_BEGIN \ + struct TU_ATTR_PACKED { \ uint8_t bLength ;\ uint8_t bDescriptorType ;\ uint8_t bDescriptorSubType ;\ uint8_t iCountryCodeRelDate ;\ uint16_t wCountryCode[no_country] ;\ -} +} \ +TU_PACK_STRUCT_END //--------------------------------------------------------------------+ // PUBLIC SWITCHED TELEPHONE NETWORK (PSTN) SUBCLASS @@ -268,22 +278,28 @@ typedef struct TU_ATTR_PACKED /// \brief Call Management Functional Descriptor /// \details This functional descriptor describes the processing of calls for the Communications Class interface. +TU_PACK_STRUCT_BEGIN typedef struct TU_ATTR_PACKED { uint8_t bLength ; ///< Size of this descriptor in bytes. uint8_t bDescriptorType ; ///< Descriptor Type, must be Class-Specific uint8_t bDescriptorSubType ; ///< Descriptor SubType one of above CDC_FUCN_DESC_ + TU_BIT_FIELD_ORDER_BEGIN struct { uint8_t handle_call : 1; ///< 0 - Device sends/receives call management information only over the Communications Class interface. 1 - Device can send/receive call management information over a Data Class interface. uint8_t send_recv_call : 1; ///< 0 - Device does not handle call management itself. 1 - Device handles call management itself. uint8_t TU_RESERVED : 6; } bmCapabilities; + TU_BIT_FIELD_ORDER_END uint8_t bDataInterface; }cdc_desc_func_call_management_t; +TU_PACK_STRUCT_END +TU_PACK_STRUCT_BEGIN +TU_BIT_FIELD_ORDER_BEGIN typedef struct TU_ATTR_PACKED { uint8_t support_comm_request : 1; ///< Device supports the request combination of Set_Comm_Feature, Clear_Comm_Feature, and Get_Comm_Feature. @@ -292,11 +308,14 @@ typedef struct TU_ATTR_PACKED uint8_t support_notification_network_connection : 1; ///< Device supports the notification Network_Connection. uint8_t TU_RESERVED : 4; }cdc_acm_capability_t; +TU_BIT_FIELD_ORDER_END +TU_PACK_STRUCT_END TU_VERIFY_STATIC(sizeof(cdc_acm_capability_t) == 1, "mostly problem with compiler"); /// \brief Abstract Control Management Functional Descriptor /// \details This functional descriptor describes the commands supported by by the Communications Class interface with SubClass code of \ref CDC_COMM_SUBCLASS_ABSTRACT_CONTROL_MODEL +TU_PACK_STRUCT_BEGIN typedef struct TU_ATTR_PACKED { uint8_t bLength ; ///< Size of this descriptor in bytes. @@ -304,25 +323,31 @@ typedef struct TU_ATTR_PACKED uint8_t bDescriptorSubType ; ///< Descriptor SubType one of above CDC_FUCN_DESC_ cdc_acm_capability_t bmCapabilities ; }cdc_desc_func_acm_t; +TU_PACK_STRUCT_END /// \brief Direct Line Management Functional Descriptor /// \details This functional descriptor describes the commands supported by the Communications Class interface with SubClass code of \ref CDC_FUNC_DESC_DIRECT_LINE_MANAGEMENT +TU_PACK_STRUCT_BEGIN typedef struct TU_ATTR_PACKED { uint8_t bLength ; ///< Size of this descriptor in bytes. uint8_t bDescriptorType ; ///< Descriptor Type, must be Class-Specific uint8_t bDescriptorSubType ; ///< Descriptor SubType one of above CDC_FUCN_DESC_ + TU_BIT_FIELD_ORDER_BEGIN struct { uint8_t require_pulse_setup : 1; ///< Device requires extra Pulse_Setup request during pulse dialing sequence to disengage holding circuit. uint8_t support_aux_request : 1; ///< Device supports the request combination of Set_Aux_Line_State, Ring_Aux_Jack, and notification Aux_Jack_Hook_State. uint8_t support_pulse_request : 1; ///< Device supports the request combination of Pulse_Setup, Send_Pulse, and Set_Pulse_Time. uint8_t TU_RESERVED : 5; } bmCapabilities; + TU_BIT_FIELD_ORDER_END }cdc_desc_func_direct_line_management_t; +TU_PACK_STRUCT_END /// \brief Telephone Ringer Functional Descriptor /// \details The Telephone Ringer functional descriptor describes the ringer capabilities supported by the Communications Class interface, /// with the SubClass code of \ref CDC_COMM_SUBCLASS_TELEPHONE_CONTROL_MODEL +TU_PACK_STRUCT_BEGIN typedef struct TU_ATTR_PACKED { uint8_t bLength ; ///< Size of this descriptor in bytes. @@ -331,31 +356,38 @@ typedef struct TU_ATTR_PACKED uint8_t bRingerVolSteps ; uint8_t bNumRingerPatterns ; }cdc_desc_func_telephone_ringer_t; +TU_PACK_STRUCT_END /// \brief Telephone Operational Modes Functional Descriptor /// \details The Telephone Operational Modes functional descriptor describes the operational modes supported by /// the Communications Class interface, with the SubClass code of \ref CDC_COMM_SUBCLASS_TELEPHONE_CONTROL_MODEL +TU_PACK_STRUCT_BEGIN typedef struct TU_ATTR_PACKED { uint8_t bLength ; ///< Size of this descriptor in bytes. uint8_t bDescriptorType ; ///< Descriptor Type, must be Class-Specific uint8_t bDescriptorSubType ; ///< Descriptor SubType one of above CDC_FUCN_DESC_ + TU_BIT_FIELD_ORDER_BEGIN struct { uint8_t simple_mode : 1; uint8_t standalone_mode : 1; uint8_t computer_centric_mode : 1; uint8_t TU_RESERVED : 5; } bmCapabilities; + TU_BIT_FIELD_ORDER_END }cdc_desc_func_telephone_operational_modes_t; +TU_PACK_STRUCT_END /// \brief Telephone Call and Line State Reporting Capabilities Descriptor /// \details The Telephone Call and Line State Reporting Capabilities functional descriptor describes the abilities of a /// telephone device to report optional call and line states. +TU_PACK_STRUCT_BEGIN typedef struct TU_ATTR_PACKED { uint8_t bLength ; ///< Size of this descriptor in bytes. uint8_t bDescriptorType ; ///< Descriptor Type, must be Class-Specific uint8_t bDescriptorSubType ; ///< Descriptor SubType one of above CDC_FUCN_DESC_ + TU_BIT_FIELD_ORDER_BEGIN struct { uint32_t interrupted_dialtone : 1; ///< 0 : Reports only dialtone (does not differentiate between normal and interrupted dialtone). 1 : Reports interrupted dialtone in addition to normal dialtone uint32_t ringback_busy_fastbusy : 1; ///< 0 : Reports only dialing state. 1 : Reports ringback, busy, and fast busy states. @@ -365,7 +397,9 @@ typedef struct TU_ATTR_PACKED uint32_t line_state_change : 1; ///< 0 : Does not support line state change notification. 1 : Does support line state change notification uint32_t TU_RESERVED : 26; } bmCapabilities; + TU_BIT_FIELD_ORDER_END }cdc_desc_func_telephone_call_state_reporting_capabilities_t; +TU_PACK_STRUCT_END static inline uint8_t cdc_functional_desc_typeof(uint8_t const * p_desc) { @@ -375,6 +409,7 @@ static inline uint8_t cdc_functional_desc_typeof(uint8_t const * p_desc) //--------------------------------------------------------------------+ // Requests //--------------------------------------------------------------------+ +TU_PACK_STRUCT_BEGIN typedef struct TU_ATTR_PACKED { uint32_t bit_rate; @@ -382,15 +417,20 @@ typedef struct TU_ATTR_PACKED uint8_t parity; ///< 0: None - 1: Odd - 2: Even - 3: Mark - 4: Space uint8_t data_bits; ///< can be 5, 6, 7, 8 or 16 } cdc_line_coding_t; +TU_PACK_STRUCT_END TU_VERIFY_STATIC(sizeof(cdc_line_coding_t) == 7, "size is not correct"); +TU_PACK_STRUCT_BEGIN +TU_BIT_FIELD_ORDER_BEGIN typedef struct TU_ATTR_PACKED { uint16_t dte_is_present : 1; ///< Indicates to DCE if DTE is presentor not. This signal corresponds to V.24 signal 108/2 and RS-232 signal DTR. uint16_t half_duplex_carrier_control : 1; uint16_t : 14; } cdc_line_control_state_t; +TU_BIT_FIELD_ORDER_END +TU_PACK_STRUCT_END TU_VERIFY_STATIC(sizeof(cdc_line_control_state_t) == 2, "size is not correct"); diff --git a/src/class/cdc/cdc_device.c b/src/class/cdc/cdc_device.c index f5853fddb..cf2ec64c8 100644 --- a/src/class/cdc/cdc_device.c +++ b/src/class/cdc/cdc_device.c @@ -31,6 +31,15 @@ #include "cdc_device.h" #include "device/usbd_pvt.h" +#if defined(TU_HAS_NO_ATTR_WEAK) +static void (*const MAKE_WEAK_FUNC(tud_cdc_rx_cb))(uint8_t) = TUD_CDC_RX_CB; +static void (*const MAKE_WEAK_FUNC(tud_cdc_rx_wanted_cb))(uint8_t, char) = TUD_CDC_RX_WANTED_CB; +static void (*const MAKE_WEAK_FUNC(tud_cdc_tx_complete_cb))(uint8_t) = TUD_CDC_TX_COMPLETE_CB; +static void (*const MAKE_WEAK_FUNC(tud_cdc_line_state_cb))(uint8_t, bool, bool) = TUD_CDC_LINE_STATE_CB; +static void (*const MAKE_WEAK_FUNC(tud_cdc_line_coding_cb))(uint8_t, cdc_line_coding_t const*) = TUD_CDC_LINE_CODING_CB; +static void (*const MAKE_WEAK_FUNC(tud_cdc_send_break_cb))(uint8_t, uint16_t) = TUD_CDC_SEND_BREAK_CB; +#endif + //--------------------------------------------------------------------+ // MACRO CONSTANT TYPEDEF //--------------------------------------------------------------------+ @@ -359,7 +368,7 @@ bool cdcd_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t } else if ( stage == CONTROL_STAGE_ACK) { - if ( tud_cdc_line_coding_cb ) tud_cdc_line_coding_cb(itf, &p_cdc->line_coding); + if ( MAKE_WEAK_FUNC(tud_cdc_line_coding_cb) ) MAKE_WEAK_FUNC(tud_cdc_line_coding_cb)(itf, &p_cdc->line_coding); } break; @@ -394,7 +403,7 @@ bool cdcd_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t TU_LOG2(" Set Control Line State: DTR = %d, RTS = %d\r\n", dtr, rts); // Invoke callback - if ( tud_cdc_line_state_cb ) tud_cdc_line_state_cb(itf, dtr, rts); + if ( MAKE_WEAK_FUNC(tud_cdc_line_state_cb) ) MAKE_WEAK_FUNC(tud_cdc_line_state_cb)(itf, dtr, rts); } break; case CDC_REQUEST_SEND_BREAK: @@ -405,7 +414,7 @@ bool cdcd_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t else if (stage == CONTROL_STAGE_ACK) { TU_LOG2(" Send Break\r\n"); - if ( tud_cdc_send_break_cb ) tud_cdc_send_break_cb(itf, request->wValue); + if ( MAKE_WEAK_FUNC(tud_cdc_send_break_cb) ) MAKE_WEAK_FUNC(tud_cdc_send_break_cb)(itf, request->wValue); } break; @@ -436,19 +445,19 @@ bool cdcd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_ tu_fifo_write_n(&p_cdc->rx_ff, &p_cdc->epout_buf, xferred_bytes); // Check for wanted char and invoke callback if needed - if ( tud_cdc_rx_wanted_cb && (((signed char) p_cdc->wanted_char) != -1) ) + if ( MAKE_WEAK_FUNC(tud_cdc_rx_wanted_cb) && (((signed char) p_cdc->wanted_char) != -1) ) { for ( uint32_t i = 0; i < xferred_bytes; i++ ) { if ( (p_cdc->wanted_char == p_cdc->epout_buf[i]) && !tu_fifo_empty(&p_cdc->rx_ff) ) { - tud_cdc_rx_wanted_cb(itf, p_cdc->wanted_char); + MAKE_WEAK_FUNC(tud_cdc_rx_wanted_cb)(itf, p_cdc->wanted_char); } } } // invoke receive callback (if there is still data) - if (tud_cdc_rx_cb && !tu_fifo_empty(&p_cdc->rx_ff) ) tud_cdc_rx_cb(itf); + if (MAKE_WEAK_FUNC(tud_cdc_rx_cb) && !tu_fifo_empty(&p_cdc->rx_ff) ) MAKE_WEAK_FUNC(tud_cdc_rx_cb)(itf); // prepare for OUT transaction _prep_out_transaction(p_cdc); @@ -460,7 +469,7 @@ bool cdcd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_ if ( ep_addr == p_cdc->ep_in ) { // invoke transmit callback to possibly refill tx fifo - if ( tud_cdc_tx_complete_cb ) tud_cdc_tx_complete_cb(itf); + if ( MAKE_WEAK_FUNC(tud_cdc_tx_complete_cb) ) MAKE_WEAK_FUNC(tud_cdc_tx_complete_cb)(itf); if ( 0 == tud_cdc_n_write_flush(itf) ) { diff --git a/src/class/cdc/cdc_device.h b/src/class/cdc/cdc_device.h index 986585c5b..ed816b707 100644 --- a/src/class/cdc/cdc_device.h +++ b/src/class/cdc/cdc_device.h @@ -130,6 +130,7 @@ static inline bool tud_cdc_write_clear (void); // Application Callback API (weak is optional) //--------------------------------------------------------------------+ +#if !defined(TU_HAS_NO_ATTR_WEAK) // Invoked when received new data TU_ATTR_WEAK void tud_cdc_rx_cb(uint8_t itf); @@ -148,6 +149,62 @@ TU_ATTR_WEAK void tud_cdc_line_coding_cb(uint8_t itf, cdc_line_coding_t const* p // Invoked when received send break TU_ATTR_WEAK void tud_cdc_send_break_cb(uint8_t itf, uint16_t duration_ms); +#else + #if ADD_WEAK_FUNC_TUD_CDC_RX_CB + #define TUD_CDC_RX_CB tud_cdc_rx_cb + #endif + #ifndef TUD_CDC_RX_CB + #define TUD_CDC_RX_CB NULL + #else + extern void TUD_CDC_RX_CB(uint8_t itf); + #endif + + #if ADD_WEAK_FUNC_TUD_CDC_RX_WANTED_CB + #define TUD_CDC_RX_WANTED_CB tud_cdc_rx_wanted_cb + #endif + #ifndef TUD_CDC_RX_WANTED_CB + #define TUD_CDC_RX_WANTED_CB NULL + #else + extern void TUD_CDC_RX_WANTED_CB(uint8_t itf, char wanted_char); + #endif + + #if ADD_WEAK_FUNC_TUD_CDC_TX_COMPLETE_CB + #define TUD_CDC_TX_COMPLETE_CB tud_cdc_tx_complete_cb + #endif + #ifndef TUD_CDC_TX_COMPLETE_CB + #define TUD_CDC_TX_COMPLETE_CB NULL + #else + extern void TUD_CDC_TX_COMPLETE_CB(uint8_t itf); + #endif + + #if ADD_WEAK_FUNC_TUD_CDC_LINE_STATE_CB + #define TUD_CDC_LINE_STATE_CB tud_cdc_line_state_cb + #endif + #ifndef TUD_CDC_LINE_STATE_CB + #define TUD_CDC_LINE_STATE_CB NULL + #else + extern void TUD_CDC_LINE_STATE_CB(uint8_t itf, bool dtr, bool rts); + #endif + + #if ADD_WEAK_FUNC_TUD_CDC_LINE_CODING_CB + #define TUD_CDC_LINE_CODING_CB tud_cdc_line_coding_cb + #endif + #ifndef TUD_CDC_LINE_CODING_CB + #define TUD_CDC_LINE_CODING_CB NULL + #else + extern void TUD_CDC_LINE_CODING_CB(uint8_t itf, cdc_line_coding_t const* p_line_coding); + #endif + + #if ADD_WEAK_FUNC_TUD_CDC_SEND_BREAK_CB + #define TUD_CDC_SEND_BREAK_CB tud_cdc_send_break_cb + #endif + #ifndef TUD_CDC_SEND_BREAK_CB + #define TUD_CDC_SEND_BREAK_CB NULL + #else + extern void TUD_CDC_SEND_BREAK_CB(uint8_t itf, uint16_t duration_ms); + #endif +#endif + //--------------------------------------------------------------------+ // Inline Functions //--------------------------------------------------------------------+ -- cgit v1.3.1 From 572d986a0260543ada22592e3f2216a152ac632d Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 11 Jun 2021 17:14:22 +0700 Subject: improve usbh --- examples/host/cdc_msc_hid/src/hid_app.c | 12 +++++- src/class/hid/hid_host.c | 10 ----- src/common/tusb_common.h | 4 +- src/host/usbh.c | 74 ++++++++++++++++++--------------- src/host/usbh_control.c | 4 +- 5 files changed, 54 insertions(+), 50 deletions(-) (limited to 'src/class') diff --git a/examples/host/cdc_msc_hid/src/hid_app.c b/examples/host/cdc_msc_hid/src/hid_app.c index 23ab12404..817646dab 100644 --- a/examples/host/cdc_msc_hid/src/hid_app.c +++ b/examples/host/cdc_msc_hid/src/hid_app.c @@ -30,7 +30,8 @@ // MACRO TYPEDEF CONSTANT ENUM DECLARATION //--------------------------------------------------------------------+ -// If your host terminal support ansi escape code, it can be use to simulate mouse cursor +// If your host terminal support ansi escape code such as TeraTerm +// it can be use to simulate mouse cursor movement within terminal #define USE_ANSI_ESCAPE 0 #define MAX_REPORT 4 @@ -113,6 +114,13 @@ void tuh_hid_report_received_cb(uint8_t dev_addr, uint8_t instance, uint8_t cons return; } + // For complete list of Usage Page & Usage checkout src/class/hid/hid.h. For examples: + // - Keyboard : Desktop, Keyboard + // - Mouse : Desktop, Mouse + // - Gamepad : Desktop, Gamepad + // - Consumer Control (Media Key) : Consumer, Consumer Control + // - System Control (Power key) : Desktop, System Control + // - Generic (vendor) : 0xFFxx, xx if ( rpt_info->usage_page == HID_USAGE_PAGE_DESKTOP ) { switch (rpt_info->usage) @@ -164,7 +172,7 @@ static void process_kbd_report(hid_keyboard_report_t const *report) }else { // not existed in previous report means the current key is pressed - bool const is_shift = report->modifier & (KEYBOARD_MODIFIER_LEFTSHIFT | KEYBOARD_MODIFIER_RIGHTSHIFT); + bool const is_shift = report->modifier & (KEYBOARD_MODIFIER_LEFTSHIFT | KEYBOARD_MODIFIER_RIGHTSHIFT); uint8_t ch = keycode2ascii[report->keycode[i]][is_shift ? 1 : 0]; putchar(ch); if ( ch == '\r' ) putchar('\n'); // added new line for enter key diff --git a/src/class/hid/hid_host.c b/src/class/hid/hid_host.c index cde5e23a5..a227c2a86 100644 --- a/src/class/hid/hid_host.c +++ b/src/class/hid/hid_host.c @@ -37,16 +37,6 @@ // MACRO CONSTANT TYPEDEF //--------------------------------------------------------------------+ -/* - "KEYBOARD" : in_len=8 , out_len=1, usage_page=0x01, usage=0x06 # Generic Desktop, Keyboard - "MOUSE" : in_len=4 , out_len=0, usage_page=0x01, usage=0x02 # Generic Desktop, Mouse - "CONSUMER" : in_len=2 , out_len=0, usage_page=0x0C, usage=0x01 # Consumer, Consumer Control - "SYS_CONTROL" : in_len=1 , out_len=0, usage_page=0x01, usage=0x80 # Generic Desktop, Sys Control - "GAMEPAD" : in_len=6 , out_len=0, usage_page=0x01, usage=0x05 # Generic Desktop, Game Pad - "DIGITIZER" : in_len=5 , out_len=0, usage_page=0x0D, usage=0x02 # Digitizers, Pen - "XAC_COMPATIBLE_GAMEPAD" : in_len=3 , out_len=0, usage_page=0x01, usage=0x05 # Generic Desktop, Game Pad - "RAW" : in_len=64, out_len=0, usage_page=0xFFAF, usage=0xAF # Vendor 0xFFAF "Adafruit", 0xAF - */ typedef struct { uint8_t itf_num; diff --git a/src/common/tusb_common.h b/src/common/tusb_common.h index 889ad7b25..fe5bf5f41 100644 --- a/src/common/tusb_common.h +++ b/src/common/tusb_common.h @@ -317,8 +317,8 @@ void tu_print_var(uint8_t const* buf, uint32_t bufsize) #define TU_LOG1 tu_printf #define TU_LOG1_MEM tu_print_mem #define TU_LOG1_VAR(_x) tu_print_var((uint8_t const*)(_x), sizeof(*(_x))) -#define TU_LOG1_INT(_x) tu_printf(#_x " = %ld\n", (uint32_t) (_x) ) -#define TU_LOG1_HEX(_x) tu_printf(#_x " = %lX\n", (uint32_t) (_x) ) +#define TU_LOG1_INT(_x) tu_printf(#_x " = %ld\r\n", (uint32_t) (_x) ) +#define TU_LOG1_HEX(_x) tu_printf(#_x " = %lX\r\n", (uint32_t) (_x) ) // Log Level 2: Warn #if CFG_TUSB_DEBUG >= 2 diff --git a/src/host/usbh.c b/src/host/usbh.c index 59246a663..81b9e84af 100644 --- a/src/host/usbh.c +++ b/src/host/usbh.c @@ -795,6 +795,8 @@ static bool enum_get_addr0_device_desc_complete(uint8_t dev_addr, tusb_control_r return false; } + TU_ASSERT(tu_desc_type(_usbh_ctrl_buf) == TUSB_DESC_DEVICE); + // Reset device again before Set Address TU_LOG2("Port reset \r\n"); @@ -938,7 +940,7 @@ static bool enum_get_config_desc_complete(uint8_t dev_addr, tusb_control_request // Parse configuration & set up drivers // Driver open aren't allowed to make any usb transfer yet - parse_configuration_descriptor(dev_addr, (tusb_desc_configuration_t*) _usbh_ctrl_buf); + TU_ASSERT( parse_configuration_descriptor(dev_addr, (tusb_desc_configuration_t*) _usbh_ctrl_buf) ); TU_LOG2("Set Configuration = %d\r\n", CONFIG_NUM); tusb_control_request_t const new_request = @@ -988,49 +990,53 @@ static bool parse_configuration_descriptor(uint8_t dev_addr, tusb_desc_configura // parse each interfaces while( p_desc < _usbh_ctrl_buf + desc_cfg->wTotalLength ) { - // skip until we see interface descriptor - if ( TUSB_DESC_INTERFACE != tu_desc_type(p_desc) ) + tusb_desc_interface_assoc_t const * desc_itf_assoc = NULL; + + // Class will always starts with Interface Association (if any) and then Interface descriptor + if ( TUSB_DESC_INTERFACE_ASSOCIATION == tu_desc_type(p_desc) ) { - p_desc = tu_desc_next(p_desc); // skip the descriptor, increase by the descriptor's length - }else + desc_itf_assoc = (tusb_desc_interface_assoc_t const *) p_desc; + p_desc = tu_desc_next(p_desc); // next to Interface + } + + TU_ASSERT( TUSB_DESC_INTERFACE == tu_desc_type(p_desc) ); + + tusb_desc_interface_t const* desc_itf = (tusb_desc_interface_t const*) p_desc; + + // Check if class is supported + uint8_t drv_id; + for (drv_id = 0; drv_id < USBH_CLASS_DRIVER_COUNT; drv_id++) { - tusb_desc_interface_t const* desc_itf = (tusb_desc_interface_t const*) p_desc; + if ( usbh_class_drivers[drv_id].class_code == desc_itf->bInterfaceClass ) break; + } - // Check if class is supported - uint8_t drv_id; - for (drv_id = 0; drv_id < USBH_CLASS_DRIVER_COUNT; drv_id++) - { - if ( usbh_class_drivers[drv_id].class_code == desc_itf->bInterfaceClass ) break; - } + if( drv_id >= USBH_CLASS_DRIVER_COUNT ) + { + // skip unsupported class + p_desc = tu_desc_next(p_desc); + } + else + { + usbh_class_driver_t const * driver = &usbh_class_drivers[drv_id]; - if( drv_id >= USBH_CLASS_DRIVER_COUNT ) + // Interface number must not be used already TODO alternate interface + TU_ASSERT( dev->itf2drv[desc_itf->bInterfaceNumber] == 0xff ); + dev->itf2drv[desc_itf->bInterfaceNumber] = drv_id; + + if (desc_itf->bInterfaceClass == TUSB_CLASS_HUB && dev->hub_addr != 0) { - // skip unsupported class + // TODO Attach hub to Hub is not currently supported + // skip this interface p_desc = tu_desc_next(p_desc); } else { - usbh_class_driver_t const * driver = &usbh_class_drivers[drv_id]; - - // Interface number must not be used already TODO alternate interface - TU_ASSERT( dev->itf2drv[desc_itf->bInterfaceNumber] == 0xff ); - dev->itf2drv[desc_itf->bInterfaceNumber] = drv_id; + TU_LOG2("%s open\r\n", driver->name); - if (desc_itf->bInterfaceClass == TUSB_CLASS_HUB && dev->hub_addr != 0) - { - // TODO Attach hub to Hub is not currently supported - // skip this interface - p_desc = tu_desc_next(p_desc); - } - else - { - TU_LOG2("%s open\r\n", driver->name); - - uint16_t itf_len = 0; - TU_ASSERT( driver->open(dev->rhport, dev_addr, desc_itf, &itf_len) ); - TU_ASSERT( itf_len >= sizeof(tusb_desc_interface_t) ); - p_desc += itf_len; - } + uint16_t itf_len = 0; + TU_ASSERT( driver->open(dev->rhport, dev_addr, desc_itf, &itf_len) ); + TU_ASSERT( itf_len >= sizeof(tusb_desc_interface_t) ); + p_desc += itf_len; } } } diff --git a/src/host/usbh_control.c b/src/host/usbh_control.c index aa82f14ba..91dbdfe99 100644 --- a/src/host/usbh_control.c +++ b/src/host/usbh_control.c @@ -68,7 +68,7 @@ bool tuh_control_xfer (uint8_t dev_addr, tusb_control_request_t const* request, _ctrl_xfer.stage = STAGE_SETUP; _ctrl_xfer.complete_cb = complete_cb; - TU_LOG2("Send Setup to address %u: ", dev_addr); + TU_LOG2("Control Setup (addr = %u): ", dev_addr); TU_LOG2_VAR(request); TU_LOG2("\r\n"); @@ -119,7 +119,7 @@ bool usbh_control_xfer_cb (uint8_t dev_addr, uint8_t ep_addr, xfer_result_t resu if (request->wLength) { - TU_LOG2("Control data:\r\n"); + TU_LOG2("Control data (addr = %u):\r\n", dev_addr); TU_LOG2_MEM(_ctrl_xfer.buffer, request->wLength, 2); } -- cgit v1.3.1 From dfe5a727c6b236c1b05b5447cdf0535545a6d32e Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 11 Jun 2021 18:53:56 +0700 Subject: log clean up --- src/class/hid/hid_host.c | 6 +++--- src/portable/raspberrypi/rp2040/hcd_rp2040.c | 8 +++----- 2 files changed, 6 insertions(+), 8 deletions(-) (limited to 'src/class') diff --git a/src/class/hid/hid_host.c b/src/class/hid/hid_host.c index a227c2a86..7444c10fe 100644 --- a/src/class/hid/hid_host.c +++ b/src/class/hid/hid_host.c @@ -442,9 +442,9 @@ uint8_t tuh_hid_parse_report_descriptor(tuh_hid_report_info_t* report_info_arr, uint8_t const data8 = desc_report[0]; - TU_LOG2("tag = %d, type = %d, size = %d, data = ", tag, type, size); - for(uint32_t i=0; iendpoint_control; if (ep_ctrl & EP_CTRL_DOUBLE_BUFFERED_BITS) { - TU_LOG(2, "Double Buffered "); + TU_LOG(3, "Double Buffered: "); }else { - TU_LOG(2, "Single Buffered "); + TU_LOG(3, "Single Buffered: "); } - if (ep_ctrl & EP_CTRL_INTERRUPT_PER_DOUBLE_BUFFER) TU_LOG(2, "Interrupt per double "); - if (ep_ctrl & EP_CTRL_INTERRUPT_PER_BUFFER) TU_LOG(2, "Interrupt per single "); - TU_LOG_HEX(2, ep_ctrl); + TU_LOG_HEX(3, ep_ctrl); _handle_buff_status_bit(bit, ep); } -- cgit v1.3.1 From 1c23462b43f47685cf0051568f4bfea5de37d563 Mon Sep 17 00:00:00 2001 From: Wini-Buh Date: Fri, 11 Jun 2021 22:25:36 +0200 Subject: weak atrribute work around removed from CCRX_Port --- src/class/cdc/cdc.h | 54 ++++++++++++----------------- src/class/cdc/cdc_device.c | 23 ++++--------- src/class/cdc/cdc_device.h | 57 ------------------------------- src/common/tusb_compiler.h | 39 --------------------- src/common/tusb_types.h | 42 ++++++----------------- src/device/dcd.h | 30 ---------------- src/device/usbd.c | 61 +++++++++++++-------------------- src/device/usbd.h | 66 ------------------------------------ src/device/usbd_control.c | 6 +--- src/device/usbd_pvt.h | 12 ------- src/portable/renesas/usba/dcd_usba.c | 33 ++++++------------ 11 files changed, 74 insertions(+), 349 deletions(-) (limited to 'src/class') diff --git a/src/class/cdc/cdc.h b/src/class/cdc/cdc.h index e5af9fc0c..f59690835 100644 --- a/src/class/cdc/cdc.h +++ b/src/class/cdc/cdc.h @@ -215,8 +215,9 @@ typedef enum // Class Specific Functional Descriptor (Communication Interface) //--------------------------------------------------------------------+ +TU_PACK_STRUCT_BEGIN // Start of definition of packed structs (used by the CCRX toolchain) + /// Header Functional Descriptor (Communication Interface) -TU_PACK_STRUCT_BEGIN typedef struct TU_ATTR_PACKED { uint8_t bLength ; ///< Size of this descriptor in bytes. @@ -224,10 +225,8 @@ typedef struct TU_ATTR_PACKED uint8_t bDescriptorSubType ; ///< Descriptor SubType one of above CDC_FUNC_DESC_ uint16_t bcdCDC ; ///< CDC release number in Binary-Coded Decimal }cdc_desc_func_header_t; -TU_PACK_STRUCT_END /// Union Functional Descriptor (Communication Interface) -TU_PACK_STRUCT_BEGIN typedef struct TU_ATTR_PACKED { uint8_t bLength ; ///< Size of this descriptor in bytes. @@ -236,7 +235,8 @@ typedef struct TU_ATTR_PACKED uint8_t bControlInterface ; ///< Interface number of Communication Interface uint8_t bSubordinateInterface ; ///< Array of Interface number of Data Interface }cdc_desc_func_union_t; -TU_PACK_STRUCT_END + +TU_PACK_STRUCT_END // End of definition of packed structs (used by the CCRX toolchain) #define cdc_desc_func_union_n_t(no_slave)\ TU_PACK_STRUCT_BEGIN \ @@ -249,8 +249,10 @@ TU_PACK_STRUCT_END } \ TU_PACK_STRUCT_END + +TU_PACK_STRUCT_BEGIN // Start of definition of packed structs (used by the CCRX toolchain) + /// Country Selection Functional Descriptor (Communication Interface) -TU_PACK_STRUCT_BEGIN typedef struct TU_ATTR_PACKED { uint8_t bLength ; ///< Size of this descriptor in bytes. @@ -259,7 +261,8 @@ typedef struct TU_ATTR_PACKED uint8_t iCountryCodeRelDate ; ///< Index of a string giving the release date for the implemented ISO 3166 Country Codes. uint16_t wCountryCode ; ///< Country code in the format as defined in [ISO3166], release date as specified inoffset 3 for the first supported country. }cdc_desc_func_country_selection_t; -TU_PACK_STRUCT_END + +TU_PACK_STRUCT_END // End of definition of packed structs (used by the CCRX toolchain) #define cdc_desc_func_country_selection_n_t(no_country) \ TU_PACK_STRUCT_BEGIN \ @@ -276,29 +279,28 @@ TU_PACK_STRUCT_END // PUBLIC SWITCHED TELEPHONE NETWORK (PSTN) SUBCLASS //--------------------------------------------------------------------+ +TU_PACK_STRUCT_BEGIN // Start of definition of packed structs (used by the CCRX toolchain) + /// \brief Call Management Functional Descriptor /// \details This functional descriptor describes the processing of calls for the Communications Class interface. -TU_PACK_STRUCT_BEGIN +TU_BIT_FIELD_ORDER_BEGIN typedef struct TU_ATTR_PACKED { uint8_t bLength ; ///< Size of this descriptor in bytes. uint8_t bDescriptorType ; ///< Descriptor Type, must be Class-Specific uint8_t bDescriptorSubType ; ///< Descriptor SubType one of above CDC_FUCN_DESC_ - TU_BIT_FIELD_ORDER_BEGIN struct { uint8_t handle_call : 1; ///< 0 - Device sends/receives call management information only over the Communications Class interface. 1 - Device can send/receive call management information over a Data Class interface. uint8_t send_recv_call : 1; ///< 0 - Device does not handle call management itself. 1 - Device handles call management itself. uint8_t TU_RESERVED : 6; } bmCapabilities; - TU_BIT_FIELD_ORDER_END uint8_t bDataInterface; }cdc_desc_func_call_management_t; -TU_PACK_STRUCT_END +TU_BIT_FIELD_ORDER_END -TU_PACK_STRUCT_BEGIN TU_BIT_FIELD_ORDER_BEGIN typedef struct TU_ATTR_PACKED { @@ -309,13 +311,11 @@ typedef struct TU_ATTR_PACKED uint8_t TU_RESERVED : 4; }cdc_acm_capability_t; TU_BIT_FIELD_ORDER_END -TU_PACK_STRUCT_END TU_VERIFY_STATIC(sizeof(cdc_acm_capability_t) == 1, "mostly problem with compiler"); /// \brief Abstract Control Management Functional Descriptor /// \details This functional descriptor describes the commands supported by by the Communications Class interface with SubClass code of \ref CDC_COMM_SUBCLASS_ABSTRACT_CONTROL_MODEL -TU_PACK_STRUCT_BEGIN typedef struct TU_ATTR_PACKED { uint8_t bLength ; ///< Size of this descriptor in bytes. @@ -323,31 +323,27 @@ typedef struct TU_ATTR_PACKED uint8_t bDescriptorSubType ; ///< Descriptor SubType one of above CDC_FUCN_DESC_ cdc_acm_capability_t bmCapabilities ; }cdc_desc_func_acm_t; -TU_PACK_STRUCT_END /// \brief Direct Line Management Functional Descriptor /// \details This functional descriptor describes the commands supported by the Communications Class interface with SubClass code of \ref CDC_FUNC_DESC_DIRECT_LINE_MANAGEMENT -TU_PACK_STRUCT_BEGIN +TU_BIT_FIELD_ORDER_BEGIN typedef struct TU_ATTR_PACKED { uint8_t bLength ; ///< Size of this descriptor in bytes. uint8_t bDescriptorType ; ///< Descriptor Type, must be Class-Specific uint8_t bDescriptorSubType ; ///< Descriptor SubType one of above CDC_FUCN_DESC_ - TU_BIT_FIELD_ORDER_BEGIN struct { uint8_t require_pulse_setup : 1; ///< Device requires extra Pulse_Setup request during pulse dialing sequence to disengage holding circuit. uint8_t support_aux_request : 1; ///< Device supports the request combination of Set_Aux_Line_State, Ring_Aux_Jack, and notification Aux_Jack_Hook_State. uint8_t support_pulse_request : 1; ///< Device supports the request combination of Pulse_Setup, Send_Pulse, and Set_Pulse_Time. uint8_t TU_RESERVED : 5; } bmCapabilities; - TU_BIT_FIELD_ORDER_END }cdc_desc_func_direct_line_management_t; -TU_PACK_STRUCT_END +TU_BIT_FIELD_ORDER_END /// \brief Telephone Ringer Functional Descriptor /// \details The Telephone Ringer functional descriptor describes the ringer capabilities supported by the Communications Class interface, /// with the SubClass code of \ref CDC_COMM_SUBCLASS_TELEPHONE_CONTROL_MODEL -TU_PACK_STRUCT_BEGIN typedef struct TU_ATTR_PACKED { uint8_t bLength ; ///< Size of this descriptor in bytes. @@ -356,38 +352,34 @@ typedef struct TU_ATTR_PACKED uint8_t bRingerVolSteps ; uint8_t bNumRingerPatterns ; }cdc_desc_func_telephone_ringer_t; -TU_PACK_STRUCT_END /// \brief Telephone Operational Modes Functional Descriptor /// \details The Telephone Operational Modes functional descriptor describes the operational modes supported by /// the Communications Class interface, with the SubClass code of \ref CDC_COMM_SUBCLASS_TELEPHONE_CONTROL_MODEL -TU_PACK_STRUCT_BEGIN +TU_BIT_FIELD_ORDER_BEGIN typedef struct TU_ATTR_PACKED { uint8_t bLength ; ///< Size of this descriptor in bytes. uint8_t bDescriptorType ; ///< Descriptor Type, must be Class-Specific uint8_t bDescriptorSubType ; ///< Descriptor SubType one of above CDC_FUCN_DESC_ - TU_BIT_FIELD_ORDER_BEGIN struct { uint8_t simple_mode : 1; uint8_t standalone_mode : 1; uint8_t computer_centric_mode : 1; uint8_t TU_RESERVED : 5; } bmCapabilities; - TU_BIT_FIELD_ORDER_END }cdc_desc_func_telephone_operational_modes_t; -TU_PACK_STRUCT_END +TU_BIT_FIELD_ORDER_END /// \brief Telephone Call and Line State Reporting Capabilities Descriptor /// \details The Telephone Call and Line State Reporting Capabilities functional descriptor describes the abilities of a /// telephone device to report optional call and line states. -TU_PACK_STRUCT_BEGIN +TU_BIT_FIELD_ORDER_BEGIN typedef struct TU_ATTR_PACKED { uint8_t bLength ; ///< Size of this descriptor in bytes. uint8_t bDescriptorType ; ///< Descriptor Type, must be Class-Specific uint8_t bDescriptorSubType ; ///< Descriptor SubType one of above CDC_FUCN_DESC_ - TU_BIT_FIELD_ORDER_BEGIN struct { uint32_t interrupted_dialtone : 1; ///< 0 : Reports only dialtone (does not differentiate between normal and interrupted dialtone). 1 : Reports interrupted dialtone in addition to normal dialtone uint32_t ringback_busy_fastbusy : 1; ///< 0 : Reports only dialing state. 1 : Reports ringback, busy, and fast busy states. @@ -397,9 +389,8 @@ typedef struct TU_ATTR_PACKED uint32_t line_state_change : 1; ///< 0 : Does not support line state change notification. 1 : Does support line state change notification uint32_t TU_RESERVED : 26; } bmCapabilities; - TU_BIT_FIELD_ORDER_END }cdc_desc_func_telephone_call_state_reporting_capabilities_t; -TU_PACK_STRUCT_END +TU_BIT_FIELD_ORDER_END static inline uint8_t cdc_functional_desc_typeof(uint8_t const * p_desc) { @@ -409,7 +400,6 @@ static inline uint8_t cdc_functional_desc_typeof(uint8_t const * p_desc) //--------------------------------------------------------------------+ // Requests //--------------------------------------------------------------------+ -TU_PACK_STRUCT_BEGIN typedef struct TU_ATTR_PACKED { uint32_t bit_rate; @@ -417,11 +407,9 @@ typedef struct TU_ATTR_PACKED uint8_t parity; ///< 0: None - 1: Odd - 2: Even - 3: Mark - 4: Space uint8_t data_bits; ///< can be 5, 6, 7, 8 or 16 } cdc_line_coding_t; -TU_PACK_STRUCT_END TU_VERIFY_STATIC(sizeof(cdc_line_coding_t) == 7, "size is not correct"); -TU_PACK_STRUCT_BEGIN TU_BIT_FIELD_ORDER_BEGIN typedef struct TU_ATTR_PACKED { @@ -430,7 +418,9 @@ typedef struct TU_ATTR_PACKED uint16_t : 14; } cdc_line_control_state_t; TU_BIT_FIELD_ORDER_END -TU_PACK_STRUCT_END + +TU_PACK_STRUCT_END // End of definition of packed structs (used by the CCRX toolchain) + TU_VERIFY_STATIC(sizeof(cdc_line_control_state_t) == 2, "size is not correct"); diff --git a/src/class/cdc/cdc_device.c b/src/class/cdc/cdc_device.c index 57bb804a8..cac811c45 100644 --- a/src/class/cdc/cdc_device.c +++ b/src/class/cdc/cdc_device.c @@ -33,15 +33,6 @@ #include "cdc_device.h" -#if defined(TU_HAS_NO_ATTR_WEAK) -static void (*const MAKE_WEAK_FUNC(tud_cdc_rx_cb))(uint8_t) = TUD_CDC_RX_CB; -static void (*const MAKE_WEAK_FUNC(tud_cdc_rx_wanted_cb))(uint8_t, char) = TUD_CDC_RX_WANTED_CB; -static void (*const MAKE_WEAK_FUNC(tud_cdc_tx_complete_cb))(uint8_t) = TUD_CDC_TX_COMPLETE_CB; -static void (*const MAKE_WEAK_FUNC(tud_cdc_line_state_cb))(uint8_t, bool, bool) = TUD_CDC_LINE_STATE_CB; -static void (*const MAKE_WEAK_FUNC(tud_cdc_line_coding_cb))(uint8_t, cdc_line_coding_t const*) = TUD_CDC_LINE_CODING_CB; -static void (*const MAKE_WEAK_FUNC(tud_cdc_send_break_cb))(uint8_t, uint16_t) = TUD_CDC_SEND_BREAK_CB; -#endif - //--------------------------------------------------------------------+ // MACRO CONSTANT TYPEDEF //--------------------------------------------------------------------+ @@ -370,7 +361,7 @@ bool cdcd_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t } else if ( stage == CONTROL_STAGE_ACK) { - if ( MAKE_WEAK_FUNC(tud_cdc_line_coding_cb) ) MAKE_WEAK_FUNC(tud_cdc_line_coding_cb)(itf, &p_cdc->line_coding); + if ( tud_cdc_line_coding_cb ) tud_cdc_line_coding_cb(itf, &p_cdc->line_coding); } break; @@ -405,7 +396,7 @@ bool cdcd_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t TU_LOG2(" Set Control Line State: DTR = %d, RTS = %d\r\n", dtr, rts); // Invoke callback - if ( MAKE_WEAK_FUNC(tud_cdc_line_state_cb) ) MAKE_WEAK_FUNC(tud_cdc_line_state_cb)(itf, dtr, rts); + if ( tud_cdc_line_state_cb ) tud_cdc_line_state_cb(itf, dtr, rts); } break; case CDC_REQUEST_SEND_BREAK: @@ -416,7 +407,7 @@ bool cdcd_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t else if (stage == CONTROL_STAGE_ACK) { TU_LOG2(" Send Break\r\n"); - if ( MAKE_WEAK_FUNC(tud_cdc_send_break_cb) ) MAKE_WEAK_FUNC(tud_cdc_send_break_cb)(itf, request->wValue); + if ( tud_cdc_send_break_cb ) tud_cdc_send_break_cb(itf, request->wValue); } break; @@ -447,19 +438,19 @@ bool cdcd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_ tu_fifo_write_n(&p_cdc->rx_ff, &p_cdc->epout_buf, xferred_bytes); // Check for wanted char and invoke callback if needed - if ( MAKE_WEAK_FUNC(tud_cdc_rx_wanted_cb) && (((signed char) p_cdc->wanted_char) != -1) ) + if ( tud_cdc_rx_wanted_cb && (((signed char) p_cdc->wanted_char) != -1) ) { for ( uint32_t i = 0; i < xferred_bytes; i++ ) { if ( (p_cdc->wanted_char == p_cdc->epout_buf[i]) && !tu_fifo_empty(&p_cdc->rx_ff) ) { - MAKE_WEAK_FUNC(tud_cdc_rx_wanted_cb)(itf, p_cdc->wanted_char); + tud_cdc_rx_wanted_cb(itf, p_cdc->wanted_char); } } } // invoke receive callback (if there is still data) - if (MAKE_WEAK_FUNC(tud_cdc_rx_cb) && !tu_fifo_empty(&p_cdc->rx_ff) ) MAKE_WEAK_FUNC(tud_cdc_rx_cb)(itf); + if (tud_cdc_rx_cb && !tu_fifo_empty(&p_cdc->rx_ff) ) tud_cdc_rx_cb(itf); // prepare for OUT transaction _prep_out_transaction(p_cdc); @@ -471,7 +462,7 @@ bool cdcd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_ if ( ep_addr == p_cdc->ep_in ) { // invoke transmit callback to possibly refill tx fifo - if ( MAKE_WEAK_FUNC(tud_cdc_tx_complete_cb) ) MAKE_WEAK_FUNC(tud_cdc_tx_complete_cb)(itf); + if ( tud_cdc_tx_complete_cb ) tud_cdc_tx_complete_cb(itf); if ( 0 == tud_cdc_n_write_flush(itf) ) { diff --git a/src/class/cdc/cdc_device.h b/src/class/cdc/cdc_device.h index 389516883..7ff757add 100644 --- a/src/class/cdc/cdc_device.h +++ b/src/class/cdc/cdc_device.h @@ -129,7 +129,6 @@ static inline bool tud_cdc_write_clear (void); // Application Callback API (weak is optional) //--------------------------------------------------------------------+ -#if !defined(TU_HAS_NO_ATTR_WEAK) // Invoked when received new data TU_ATTR_WEAK void tud_cdc_rx_cb(uint8_t itf); @@ -148,62 +147,6 @@ TU_ATTR_WEAK void tud_cdc_line_coding_cb(uint8_t itf, cdc_line_coding_t const* p // Invoked when received send break TU_ATTR_WEAK void tud_cdc_send_break_cb(uint8_t itf, uint16_t duration_ms); -#else - #if ADD_WEAK_FUNC_TUD_CDC_RX_CB - #define TUD_CDC_RX_CB tud_cdc_rx_cb - #endif - #ifndef TUD_CDC_RX_CB - #define TUD_CDC_RX_CB NULL - #else - extern void TUD_CDC_RX_CB(uint8_t itf); - #endif - - #if ADD_WEAK_FUNC_TUD_CDC_RX_WANTED_CB - #define TUD_CDC_RX_WANTED_CB tud_cdc_rx_wanted_cb - #endif - #ifndef TUD_CDC_RX_WANTED_CB - #define TUD_CDC_RX_WANTED_CB NULL - #else - extern void TUD_CDC_RX_WANTED_CB(uint8_t itf, char wanted_char); - #endif - - #if ADD_WEAK_FUNC_TUD_CDC_TX_COMPLETE_CB - #define TUD_CDC_TX_COMPLETE_CB tud_cdc_tx_complete_cb - #endif - #ifndef TUD_CDC_TX_COMPLETE_CB - #define TUD_CDC_TX_COMPLETE_CB NULL - #else - extern void TUD_CDC_TX_COMPLETE_CB(uint8_t itf); - #endif - - #if ADD_WEAK_FUNC_TUD_CDC_LINE_STATE_CB - #define TUD_CDC_LINE_STATE_CB tud_cdc_line_state_cb - #endif - #ifndef TUD_CDC_LINE_STATE_CB - #define TUD_CDC_LINE_STATE_CB NULL - #else - extern void TUD_CDC_LINE_STATE_CB(uint8_t itf, bool dtr, bool rts); - #endif - - #if ADD_WEAK_FUNC_TUD_CDC_LINE_CODING_CB - #define TUD_CDC_LINE_CODING_CB tud_cdc_line_coding_cb - #endif - #ifndef TUD_CDC_LINE_CODING_CB - #define TUD_CDC_LINE_CODING_CB NULL - #else - extern void TUD_CDC_LINE_CODING_CB(uint8_t itf, cdc_line_coding_t const* p_line_coding); - #endif - - #if ADD_WEAK_FUNC_TUD_CDC_SEND_BREAK_CB - #define TUD_CDC_SEND_BREAK_CB tud_cdc_send_break_cb - #endif - #ifndef TUD_CDC_SEND_BREAK_CB - #define TUD_CDC_SEND_BREAK_CB NULL - #else - extern void TUD_CDC_SEND_BREAK_CB(uint8_t itf, uint16_t duration_ms); - #endif -#endif - //--------------------------------------------------------------------+ // Inline Functions //--------------------------------------------------------------------+ diff --git a/src/common/tusb_compiler.h b/src/common/tusb_compiler.h index 508bb126e..f77cf94ee 100644 --- a/src/common/tusb_compiler.h +++ b/src/common/tusb_compiler.h @@ -64,9 +64,6 @@ // Compiler porting with Attribute and Endian //--------------------------------------------------------------------+ -// define the standard definition of this macro to construct a "weak" function name -#define MAKE_WEAK_FUNC(func_name) func_name - // TODO refactor since __attribute__ is supported across many compiler #if defined(__GNUC__) #define TU_ATTR_ALIGNED(Bytes) __attribute__ ((aligned(Bytes))) @@ -171,42 +168,6 @@ the aligned attribute (or something similar yet) */ #define TU_HAS_NO_ATTR_ALIGNED - /* activate the "weak" function emulation, because this toolchain does not - know the weak attribute (or something similar yet) */ - #define TU_HAS_NO_ATTR_WEAK - - // make sure to define away the standard definition of this macro - #undef MAKE_WEAK_FUNC - // Helper macro to construct a "weak" function name - #define MAKE_WEAK_FUNC(func_name) weak_ ## func_name - - #if defined(TU_HAS_NO_ATTR_WEAK) - // "Weak function" emulation defined in cdc_device.h - #define ADD_WEAK_FUNC_TUD_CDC_RX_CB 0 - #define ADD_WEAK_FUNC_TUD_CDC_RX_WANTED_CB 0 - #define ADD_WEAK_FUNC_TUD_CDC_TX_COMPLETE_CB 0 - #define ADD_WEAK_FUNC_TUD_CDC_LINE_STATE_CB 0 - #define ADD_WEAK_FUNC_TUD_CDC_LINE_CODING_CB 0 - #define ADD_WEAK_FUNC_TUD_CDC_SEND_BREAK_CB 0 - - // "Weak function" emulation defined in usbd_pvt.h - #define ADD_WEAK_FUNC_USBD_APP_DRIVER_GET_CB 0 - - // "Weak function" emulation defined in usbd.h - #define ADD_WEAK_FUNC_TUD_DESCRIPTOR_BOS_CB 0 - #define ADD_WEAK_FUNC_TUD_DESCRIPTOR_DEVICE_QUALIFIER_CB 0 - #define ADD_WEAK_FUNC_TUD_MOUNT_CB 0 - #define ADD_WEAK_FUNC_TUD_UMOUNT_CB 0 - #define ADD_WEAK_FUNC_TUD_SUSPEND_CB 0 - #define ADD_WEAK_FUNC_TUD_RESUME_CB 0 - #define ADD_WEAK_FUNC_TUD_VENDOR_CONTROL_XFER_CB 0 - - // "Weak function" emulation defined in dcd.h - #define ADD_WEAK_FUNC_DCD_EDPT0_STATUS_COMPLETE 0 - #define ADD_WEAK_FUNC_DCD_EDPT_CLOSE 0 - #define ADD_WEAK_FUNC_DCD_EDPT_XFER_FIFO 0 - #endif - #else #error "Compiler attribute porting is required" #endif diff --git a/src/common/tusb_types.h b/src/common/tusb_types.h index b20ea2974..a8a4d21e5 100644 --- a/src/common/tusb_types.h +++ b/src/common/tusb_types.h @@ -262,8 +262,9 @@ enum // USB Descriptors //--------------------------------------------------------------------+ +TU_PACK_STRUCT_BEGIN // Start of definition of packed structs (used by the CCRX toolchain) + /// USB Device Descriptor -TU_PACK_STRUCT_BEGIN typedef struct TU_ATTR_PACKED { uint8_t bLength ; ///< Size of this descriptor in bytes. @@ -284,12 +285,10 @@ typedef struct TU_ATTR_PACKED uint8_t bNumConfigurations ; ///< Number of possible configurations. } tusb_desc_device_t; -TU_PACK_STRUCT_END TU_VERIFY_STATIC( sizeof(tusb_desc_device_t) == 18, "size is not correct"); // USB Binary Device Object Store (BOS) Descriptor -TU_PACK_STRUCT_BEGIN typedef struct TU_ATTR_PACKED { uint8_t bLength ; ///< Size of this descriptor in bytes @@ -297,10 +296,8 @@ typedef struct TU_ATTR_PACKED uint16_t wTotalLength ; ///< Total length of data returned for this descriptor uint8_t bNumDeviceCaps ; ///< Number of device capability descriptors in the BOS } tusb_desc_bos_t; -TU_PACK_STRUCT_END /// USB Configuration Descriptor -TU_PACK_STRUCT_BEGIN typedef struct TU_ATTR_PACKED { uint8_t bLength ; ///< Size of this descriptor in bytes @@ -313,10 +310,8 @@ typedef struct TU_ATTR_PACKED uint8_t bmAttributes ; ///< Configuration characteristics \n D7: Reserved (set to one)\n D6: Self-powered \n D5: Remote Wakeup \n D4...0: Reserved (reset to zero) \n D7 is reserved and must be set to one for historical reasons. \n A device configuration that uses power from the bus and a local source reports a non-zero value in bMaxPower to indicate the amount of bus power required and sets D6. The actual power source at runtime may be determined using the GetStatus(DEVICE) request (see USB 2.0 spec Section 9.4.5). \n If a device configuration supports remote wakeup, D5 is set to one. uint8_t bMaxPower ; ///< Maximum power consumption of the USB device from the bus in this specific configuration when the device is fully operational. Expressed in 2 mA units (i.e., 50 = 100 mA). } tusb_desc_configuration_t; -TU_PACK_STRUCT_END /// USB Interface Descriptor -TU_PACK_STRUCT_BEGIN typedef struct TU_ATTR_PACKED { uint8_t bLength ; ///< Size of this descriptor in bytes @@ -330,10 +325,9 @@ typedef struct TU_ATTR_PACKED uint8_t bInterfaceProtocol ; ///< Protocol code (assigned by the USB). \n These codes are qualified by the value of the bInterfaceClass and the bInterfaceSubClass fields. If an interface supports class-specific requests, this code identifies the protocols that the device uses as defined by the specification of the device class. \li If this field is reset to zero, the device does not use a class-specific protocol on this interface. \li If this field is set to FFH, the device uses a vendor-specific protocol for this interface. uint8_t iInterface ; ///< Index of string descriptor describing this interface } tusb_desc_interface_t; -TU_PACK_STRUCT_END /// USB Endpoint Descriptor -TU_PACK_STRUCT_BEGIN +TU_BIT_FIELD_ORDER_BEGIN typedef struct TU_ATTR_PACKED { uint8_t bLength ; ///< Size of this descriptor in bytes @@ -341,14 +335,12 @@ typedef struct TU_ATTR_PACKED uint8_t bEndpointAddress ; ///< The address of the endpoint on the USB device described by this descriptor. The address is encoded as follows: \n Bit 3...0: The endpoint number \n Bit 6...4: Reserved, reset to zero \n Bit 7: Direction, ignored for control endpoints 0 = OUT endpoint 1 = IN endpoint. - TU_BIT_FIELD_ORDER_BEGIN struct TU_ATTR_PACKED { uint8_t xfer : 2; uint8_t sync : 2; uint8_t usage : 2; uint8_t : 2; } bmAttributes ; ///< This field describes the endpoint's attributes when it is configured using the bConfigurationValue. \n Bits 1..0: Transfer Type \n- 00 = Control \n- 01 = Isochronous \n- 10 = Bulk \n- 11 = Interrupt \n If not an isochronous endpoint, bits 5..2 are reserved and must be set to zero. If isochronous, they are defined as follows: \n Bits 3..2: Synchronization Type \n- 00 = No Synchronization \n- 01 = Asynchronous \n- 10 = Adaptive \n- 11 = Synchronous \n Bits 5..4: Usage Type \n- 00 = Data endpoint \n- 01 = Feedback endpoint \n- 10 = Implicit feedback Data endpoint \n- 11 = Reserved \n Refer to Chapter 5 of USB 2.0 specification for more information. \n All other bits are reserved and must be reset to zero. Reserved bits must be ignored by the host. - TU_BIT_FIELD_ORDER_END struct TU_ATTR_PACKED { #if defined(__CCRX__) @@ -363,10 +355,9 @@ typedef struct TU_ATTR_PACKED uint8_t bInterval ; ///< Interval for polling endpoint for data transfers. Expressed in frames or microframes depending on the device operating speed (i.e., either 1 millisecond or 125 us units). \n- For full-/high-speed isochronous endpoints, this value must be in the range from 1 to 16. The bInterval value is used as the exponent for a \f$ 2^(bInterval-1) \f$ value; e.g., a bInterval of 4 means a period of 8 (\f$ 2^(4-1) \f$). \n- For full-/low-speed interrupt endpoints, the value of this field may be from 1 to 255. \n- For high-speed interrupt endpoints, the bInterval value is used as the exponent for a \f$ 2^(bInterval-1) \f$ value; e.g., a bInterval of 4 means a period of 8 (\f$ 2^(4-1) \f$) . This value must be from 1 to 16. \n- For high-speed bulk/control OUT endpoints, the bInterval must specify the maximum NAK rate of the endpoint. A value of 0 indicates the endpoint never NAKs. Other values indicate at most 1 NAK each bInterval number of microframes. This value must be in the range from 0 to 255. \n Refer to Chapter 5 of USB 2.0 specification for more information. } tusb_desc_endpoint_t; -TU_PACK_STRUCT_END +TU_BIT_FIELD_ORDER_END /// USB Other Speed Configuration Descriptor -TU_PACK_STRUCT_BEGIN typedef struct TU_ATTR_PACKED { uint8_t bLength ; ///< Size of descriptor @@ -379,10 +370,8 @@ typedef struct TU_ATTR_PACKED uint8_t bmAttributes ; ///< Same as Configuration descriptor uint8_t bMaxPower ; ///< Same as Configuration descriptor } tusb_desc_other_speed_t; -TU_PACK_STRUCT_END /// USB Device Qualifier Descriptor -TU_PACK_STRUCT_BEGIN typedef struct TU_ATTR_PACKED { uint8_t bLength ; ///< Size of descriptor @@ -396,10 +385,8 @@ typedef struct TU_ATTR_PACKED uint8_t bNumConfigurations ; ///< Number of Other-speed Configurations uint8_t bReserved ; ///< Reserved for future use, must be zero } tusb_desc_device_qualifier_t; -TU_PACK_STRUCT_END /// USB Interface Association Descriptor (IAD ECN) -TU_PACK_STRUCT_BEGIN typedef struct TU_ATTR_PACKED { uint8_t bLength ; ///< Size of descriptor @@ -414,20 +401,16 @@ typedef struct TU_ATTR_PACKED uint8_t iFunction ; ///< Index of the string descriptor describing the interface association. } tusb_desc_interface_assoc_t; -TU_PACK_STRUCT_END // USB String Descriptor -TU_PACK_STRUCT_BEGIN typedef struct TU_ATTR_PACKED { uint8_t bLength ; ///< Size of this descriptor in bytes uint8_t bDescriptorType ; ///< Descriptor Type uint16_t unicode_string[]; } tusb_desc_string_t; -TU_PACK_STRUCT_END // USB Binary Device Object Store (BOS) -TU_PACK_STRUCT_BEGIN typedef struct TU_ATTR_PACKED { uint8_t bLength; @@ -437,10 +420,8 @@ typedef struct TU_ATTR_PACKED uint8_t PlatformCapabilityUUID[16]; uint8_t CapabilityData[]; } tusb_desc_bos_platform_t; -TU_PACK_STRUCT_END // USB WebuSB URL Descriptor -TU_PACK_STRUCT_BEGIN typedef struct TU_ATTR_PACKED { uint8_t bLength; @@ -448,17 +429,15 @@ typedef struct TU_ATTR_PACKED uint8_t bScheme; char url[]; } tusb_desc_webusb_url_t; -TU_PACK_STRUCT_END // DFU Functional Descriptor -TU_PACK_STRUCT_BEGIN +TU_BIT_FIELD_ORDER_BEGIN typedef struct TU_ATTR_PACKED { uint8_t bLength; uint8_t bDescriptorType; union { - TU_BIT_FIELD_ORDER_BEGIN struct TU_ATTR_PACKED { uint8_t bitCanDnload : 1; uint8_t bitCanUpload : 1; @@ -466,7 +445,6 @@ typedef struct TU_ATTR_PACKED uint8_t bitWillDetach : 1; uint8_t reserved : 4; } bmAttributes; - TU_BIT_FIELD_ORDER_END uint8_t bAttributes; }; @@ -475,21 +453,19 @@ typedef struct TU_ATTR_PACKED uint16_t wTransferSize; uint16_t bcdDFUVersion; } tusb_desc_dfu_functional_t; -TU_PACK_STRUCT_END +TU_BIT_FIELD_ORDER_END /*------------------------------------------------------------------*/ /* Types *------------------------------------------------------------------*/ -TU_PACK_STRUCT_BEGIN +TU_BIT_FIELD_ORDER_BEGIN typedef struct TU_ATTR_PACKED{ union { - TU_BIT_FIELD_ORDER_BEGIN struct TU_ATTR_PACKED { uint8_t recipient : 5; ///< Recipient type tusb_request_recipient_t. uint8_t type : 2; ///< Request type tusb_request_type_t. uint8_t direction : 1; ///< Direction type. tusb_dir_t } bmRequestType_bit; - TU_BIT_FIELD_ORDER_END uint8_t bmRequestType; }; @@ -499,7 +475,9 @@ typedef struct TU_ATTR_PACKED{ uint16_t wIndex; uint16_t wLength; } tusb_control_request_t; -TU_PACK_STRUCT_END +TU_BIT_FIELD_ORDER_END + +TU_PACK_STRUCT_END // End of definition of packed structs (used by the CCRX toolchain) TU_VERIFY_STATIC( sizeof(tusb_control_request_t) == 8, "size is not correct"); diff --git a/src/device/dcd.h b/src/device/dcd.h index d68f9baa7..25cfafc4b 100644 --- a/src/device/dcd.h +++ b/src/device/dcd.h @@ -117,7 +117,6 @@ void dcd_disconnect(uint8_t rhport) TU_ATTR_WEAK; // Endpoint API //--------------------------------------------------------------------+ -#if !defined(TU_HAS_NO_ATTR_WEAK) // Invoked when a control transfer's status stage is complete. // May help DCD to prepare for next control transfer, this API is optional. void dcd_edpt0_status_complete(uint8_t rhport, tusb_control_request_t const * request) TU_ATTR_WEAK; @@ -130,35 +129,6 @@ void dcd_edpt_close (uint8_t rhport, uint8_t ep_addr) TU_ATTR_WEAK; // This API is optional, may be useful for register-based for transferring data. bool dcd_edpt_xfer_fifo (uint8_t rhport, uint8_t ep_addr, tu_fifo_t * ff, uint16_t total_bytes) TU_ATTR_WEAK; -#else - #if ADD_WEAK_FUNC_DCD_EDPT0_STATUS_COMPLETE - #define DCD_EDPT0_STATUS_COMPLETE dcd_edpt0_status_complete - #endif - #ifndef DCD_EDPT0_STATUS_COMPLETE - #define DCD_EDPT0_STATUS_COMPLETE NULL - #else - extern void DCD_EDPT0_STATUS_COMPLETE(uint8_t rhport, tusb_control_request_t const * request); - #endif - - #if ADD_WEAK_FUNC_DCD_EDPT_CLOSE - #define DCD_EDPT_CLOSE dcd_edpt_close - #endif - #ifndef DCD_EDPT_CLOSE - #define DCD_EDPT_CLOSE NULL - #else - extern void DCD_EDPT_CLOSE(uint8_t rhport, uint8_t ep_addr); - #endif - - #if ADD_WEAK_FUNC_DCD_EDPT_XFER_FIFO - #define DCD_EDPT_XFER_FIFO dcd_edpt_xfer_fifo - #endif - #ifndef DCD_EDPT_XFER_FIFO - #define DCD_EDPT_XFER_FIFO NULL - #else - extern void DCD_EDPT_XFER_FIFO(uint8_t rhport, uint8_t ep_addr, tu_fifo_t * ff, uint16_t total_bytes); - #endif -#endif - // Configure endpoint's registers according to descriptor bool dcd_edpt_open (uint8_t rhport, tusb_desc_endpoint_t const * p_endpoint_desc); diff --git a/src/device/usbd.c b/src/device/usbd.c index 389ba4a4e..49c9279bf 100644 --- a/src/device/usbd.c +++ b/src/device/usbd.c @@ -33,19 +33,6 @@ #include "device/usbd_pvt.h" #include "device/dcd.h" -#if defined(TU_HAS_NO_ATTR_WEAK) -static uint8_t const* (*const MAKE_WEAK_FUNC(tud_descriptor_bos_cb))(void) = TUD_DESCRIPTOR_BOS_CB; -static uint8_t const* (*const MAKE_WEAK_FUNC(tud_descriptor_device_qualifier_cb))(void) = TUD_DESCRIPTOR_DEVICE_QUALIFIER_CB; -static void (*const MAKE_WEAK_FUNC(tud_mount_cb))(void) = TUD_MOUNT_CB; -static void (*const MAKE_WEAK_FUNC(tud_umount_cb))(void) = TUD_UMOUNT_CB; -static void (*const MAKE_WEAK_FUNC(tud_suspend_cb))(_Bool) = TUD_SUSPEND_CB; -static void (*const MAKE_WEAK_FUNC(tud_resume_cb))(void) = TUD_RESUME_CB; -static _Bool (*const MAKE_WEAK_FUNC(tud_vendor_control_xfer_cb))(uint8_t, uint8_t, tusb_control_request_t const *) = TUD_RESUME_CB; -static usbd_class_driver_t const* (*const MAKE_WEAK_FUNC(usbd_app_driver_get_cb))(uint8_t*) = USBD_APP_DRIVER_GET_CB; -static bool (*const MAKE_WEAK_FUNC(dcd_edpt_xfer_fifo))(uint8_t, uint8_t, tu_fifo_t *, uint16_t) = DCD_EDPT_XFER_FIFO; -static void (*const MAKE_WEAK_FUNC(dcd_edpt_close))(uint8_t, uint8_t) = DCD_EDPT_CLOSE; -#endif - #ifndef CFG_TUD_TASK_QUEUE_SZ #define CFG_TUD_TASK_QUEUE_SZ 16 #endif @@ -61,10 +48,11 @@ static void (*const MAKE_WEAK_FUNC(dcd_edpt_close))(uint8_t, uint8_t) = DCD_EDPT // Invalid driver ID in itf2drv[] ep2drv[][] mapping enum { DRVID_INVALID = 0xFFu }; +TU_PACK_STRUCT_BEGIN // Start of definition of packed structs (used by the CCRX toolchain) + +TU_BIT_FIELD_ORDER_BEGIN typedef struct { - TU_PACK_STRUCT_BEGIN - TU_BIT_FIELD_ORDER_BEGIN struct TU_ATTR_PACKED { volatile uint8_t connected : 1; @@ -75,8 +63,6 @@ typedef struct uint8_t remote_wakeup_support : 1; // configuration descriptor's attribute uint8_t self_powered : 1; // configuration descriptor's attribute }; - TU_BIT_FIELD_ORDER_END - TU_PACK_STRUCT_END volatile uint8_t cfg_num; // current active configuration (0x00 is not configured) uint8_t speed; @@ -84,8 +70,6 @@ typedef struct uint8_t itf2drv[16]; // map interface number to driver (0xff is invalid) uint8_t ep2drv[CFG_TUD_EP_MAX][2]; // map endpoint to driver ( 0xff is invalid ) - TU_PACK_STRUCT_BEGIN - TU_BIT_FIELD_ORDER_BEGIN struct TU_ATTR_PACKED { volatile bool busy : 1; @@ -94,10 +78,11 @@ typedef struct // TODO merge ep2drv here, 4-bit should be sufficient }ep_status[CFG_TUD_EP_MAX][2]; - TU_BIT_FIELD_ORDER_END - TU_PACK_STRUCT_END }usbd_device_t; +TU_BIT_FIELD_ORDER_END + +TU_PACK_STRUCT_END // End of definition of packed structs (used by the CCRX toolchain) static usbd_device_t _usbd_dev; @@ -257,7 +242,7 @@ static uint8_t _app_driver_count = 0; static inline usbd_class_driver_t const * get_driver(uint8_t drvid) { // Application drivers - if ( MAKE_WEAK_FUNC(usbd_app_driver_get_cb) ) + if ( usbd_app_driver_get_cb ) { if ( drvid < _app_driver_count ) return &_app_driver[drvid]; drvid -= _app_driver_count; @@ -429,9 +414,9 @@ bool tud_init (uint8_t rhport) TU_ASSERT(_usbd_q); // Get application driver if available - if ( MAKE_WEAK_FUNC(usbd_app_driver_get_cb) ) + if ( usbd_app_driver_get_cb ) { - _app_driver = MAKE_WEAK_FUNC(usbd_app_driver_get_cb)(&_app_driver_count); + _app_driver = usbd_app_driver_get_cb(&_app_driver_count); } // Init class drivers @@ -522,7 +507,7 @@ void tud_task (void) usbd_reset(event.rhport); // invoke callback - if (MAKE_WEAK_FUNC(tud_umount_cb)) MAKE_WEAK_FUNC(tud_umount_cb)(); + if (tud_umount_cb) tud_umount_cb(); break; case DCD_EVENT_SETUP_RECEIVED: @@ -578,12 +563,12 @@ void tud_task (void) case DCD_EVENT_SUSPEND: TU_LOG2("\r\n"); - if (MAKE_WEAK_FUNC(tud_suspend_cb)) MAKE_WEAK_FUNC(tud_suspend_cb)(_usbd_dev.remote_wakeup_en); + if (tud_suspend_cb) tud_suspend_cb(_usbd_dev.remote_wakeup_en); break; case DCD_EVENT_RESUME: TU_LOG2("\r\n"); - if (MAKE_WEAK_FUNC(tud_resume_cb)) MAKE_WEAK_FUNC(tud_resume_cb)(); + if (tud_resume_cb) tud_resume_cb(); break; case DCD_EVENT_SOF: @@ -630,10 +615,10 @@ static bool process_control_request(uint8_t rhport, tusb_control_request_t const // Vendor request if ( p_request->bmRequestType_bit.type == TUSB_REQ_TYPE_VENDOR ) { - TU_VERIFY(MAKE_WEAK_FUNC(tud_vendor_control_xfer_cb)); + TU_VERIFY(tud_vendor_control_xfer_cb); - usbd_control_set_complete_callback(MAKE_WEAK_FUNC(tud_vendor_control_xfer_cb)); - return MAKE_WEAK_FUNC(tud_vendor_control_xfer_cb)(rhport, CONTROL_STAGE_SETUP, p_request); + usbd_control_set_complete_callback(tud_vendor_control_xfer_cb); + return tud_vendor_control_xfer_cb(rhport, CONTROL_STAGE_SETUP, p_request); } #if CFG_TUSB_DEBUG >= 2 @@ -913,7 +898,7 @@ static bool process_set_config(uint8_t rhport, uint8_t cfg_num) } // invoke callback - if (MAKE_WEAK_FUNC(tud_mount_cb)) MAKE_WEAK_FUNC(tud_mount_cb)(); + if (tud_mount_cb) tud_mount_cb(); return true; } @@ -970,9 +955,9 @@ static bool process_get_descriptor(uint8_t rhport, tusb_control_request_t const TU_LOG2(" BOS\r\n"); // requested by host if USB > 2.0 ( i.e 2.1 or 3.x ) - if (!MAKE_WEAK_FUNC(tud_descriptor_bos_cb)) return false; + if (!tud_descriptor_bos_cb) return false; - tusb_desc_bos_t const* desc_bos = (tusb_desc_bos_t const*)MAKE_WEAK_FUNC(tud_descriptor_bos_cb)(); + tusb_desc_bos_t const* desc_bos = (tusb_desc_bos_t const*)tud_descriptor_bos_cb(); uint16_t total_len; // Use offsetof to avoid pointer to the odd/misaligned address @@ -1016,9 +1001,9 @@ static bool process_get_descriptor(uint8_t rhport, tusb_control_request_t const // Host sends this request to ask why our device with USB BCD from 2.0 // but is running at Full/Low Speed. If not highspeed capable stall this request, // otherwise return the descriptor that could work in highspeed mode - if (MAKE_WEAK_FUNC(tud_descriptor_device_qualifier_cb)) + if (tud_descriptor_device_qualifier_cb) { - uint8_t const* desc_qualifier = MAKE_WEAK_FUNC(tud_descriptor_device_qualifier_cb)(); + uint8_t const* desc_qualifier = tud_descriptor_device_qualifier_cb(); TU_ASSERT(desc_qualifier); // first byte of descriptor is its size @@ -1306,7 +1291,7 @@ bool usbd_edpt_xfer_fifo(uint8_t rhport, uint8_t ep_addr, tu_fifo_t * ff, uint16 // and usbd task can preempt and clear the busy _usbd_dev.ep_status[epnum][dir].busy = true; - if (MAKE_WEAK_FUNC(dcd_edpt_xfer_fifo)(rhport, ep_addr, ff, total_bytes)) + if (dcd_edpt_xfer_fifo(rhport, ep_addr, ff, total_bytes)) { TU_LOG2("OK\r\n"); return true; @@ -1369,10 +1354,10 @@ bool usbd_edpt_stalled(uint8_t rhport, uint8_t ep_addr) */ void usbd_edpt_close(uint8_t rhport, uint8_t ep_addr) { - TU_ASSERT(MAKE_WEAK_FUNC(dcd_edpt_close), /**/); + TU_ASSERT(dcd_edpt_close, /**/); TU_LOG2(" CLOSING Endpoint: 0x%02X\r\n", ep_addr); - MAKE_WEAK_FUNC(dcd_edpt_close(rhport, ep_addr)); + dcd_edpt_close(rhport, ep_addr); return; } diff --git a/src/device/usbd.h b/src/device/usbd.h index 67f1e2913..57c80fed1 100644 --- a/src/device/usbd.h +++ b/src/device/usbd.h @@ -111,7 +111,6 @@ uint8_t const * tud_descriptor_configuration_cb(uint8_t index); // Application return pointer to descriptor, whose contents must exist long enough for transfer to complete uint16_t const* tud_descriptor_string_cb(uint8_t index, uint16_t langid); -#if !defined(TU_HAS_NO_ATTR_WEAK) // Invoked when received GET BOS DESCRIPTOR request // Application return pointer to descriptor TU_ATTR_WEAK uint8_t const * tud_descriptor_bos_cb(void); @@ -136,71 +135,6 @@ TU_ATTR_WEAK void tud_resume_cb(void); // Invoked when received control request with VENDOR TYPE TU_ATTR_WEAK bool tud_vendor_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t const * request); -#else - #if ADD_WEAK_FUNC_TUD_DESCRIPTOR_BOS_CB - #define TUD_DESCRIPTOR_BOS_CB tud_descriptor_bos_cb - #endif - #ifndef TUD_DESCRIPTOR_BOS_CB - #define TUD_DESCRIPTOR_BOS_CB NULL - #else - extern uint8_t const* TUD_DESCRIPTOR_BOS_CB(void); - #endif - - #if ADD_WEAK_FUNC_TUD_DESCRIPTOR_DEVICE_QUALIFIER_CB - #define TUD_DESCRIPTOR_DEVICE_QUALIFIER_CB tud_descriptor_device_qualifier_cb - #endif - #ifndef TUD_DESCRIPTOR_DEVICE_QUALIFIER_CB - #define TUD_DESCRIPTOR_DEVICE_QUALIFIER_CB NULL - #else - extern uint8_t const* TUD_DESCRIPTOR_DEVICE_QUALIFIER_CB(void); - #endif - - #if ADD_WEAK_FUNC_TUD_MOUNT_CB - #define TUD_MOUNT_CB tud_mount_cb - #endif - #ifndef TUD_MOUNT_CB - #define TUD_MOUNT_CB NULL - #else - extern void TUD_MOUNT_CB(void); - #endif - - #if ADD_WEAK_FUNC_TUD_UMOUNT_CB - #define TUD_UMOUNT_CB tud_umount_cb - #endif - #ifndef TUD_UMOUNT_CB - #define TUD_UMOUNT_CB NULL - #else - extern void TUD_UMOUNT_CB(void); - #endif - - #if ADD_WEAK_FUNC_TUD_SUSPEND_CB - #define TUD_SUSPEND_CB tud_suspend_cb - #endif - #ifndef TUD_SUSPEND_CB - #define TUD_SUSPEND_CB NULL - #else - extern void TUD_SUSPEND_CB(bool remote_wakeup_en); - #endif - - #if ADD_WEAK_FUNC_TUD_RESUME_CB - #define TUD_RESUME_CB tud_resume_cb - #endif - #ifndef TUD_RESUME_CB - #define TUD_RESUME_CB NULL - #else - extern void TUD_RESUME_CB(void); - #endif - - #if ADD_WEAK_FUNC_TUD_VENDOR_CONTROL_XFER_CB - #define TUD_VENDOR_CONTROL_XFER_CB tud_vendor_control_xfer_cb - #endif - #ifndef TUD_VENDOR_CONTROL_XFER_CB - #define TUD_VENDOR_CONTROL_XFER_CB NULL - #else - extern bool TUD_VENDOR_CONTROL_XFER_CB(uint8_t rhport, uint8_t stage, tusb_control_request_t const * request); - #endif -#endif - //--------------------------------------------------------------------+ // Binary Device Object Store (BOS) Descriptor Templates //--------------------------------------------------------------------+ diff --git a/src/device/usbd_control.c b/src/device/usbd_control.c index 76f999f86..b3bab2e32 100644 --- a/src/device/usbd_control.c +++ b/src/device/usbd_control.c @@ -36,10 +36,6 @@ extern void usbd_driver_print_control_complete_name(usbd_control_xfer_cb_t callback); #endif -#if defined(TU_HAS_NO_ATTR_WEAK) -static void (*const MAKE_WEAK_FUNC(dcd_edpt0_status_complete))(uint8_t, tusb_control_request_t const *) = DCD_EDPT0_STATUS_COMPLETE; -#endif - enum { EDPT_CTRL_OUT = 0x00, @@ -184,7 +180,7 @@ bool usbd_control_xfer_cb (uint8_t rhport, uint8_t ep_addr, xfer_result_t result TU_ASSERT(0 == xferred_bytes); // invoke optional dcd hook if available - if (MAKE_WEAK_FUNC(dcd_edpt0_status_complete)) MAKE_WEAK_FUNC(dcd_edpt0_status_complete)(rhport, &_ctrl_xfer.request); + if (dcd_edpt0_status_complete) dcd_edpt0_status_complete(rhport, &_ctrl_xfer.request); if (_ctrl_xfer.complete_cb) { diff --git a/src/device/usbd_pvt.h b/src/device/usbd_pvt.h index c814353ae..bb2267d40 100644 --- a/src/device/usbd_pvt.h +++ b/src/device/usbd_pvt.h @@ -51,22 +51,10 @@ typedef struct void (* sof ) (uint8_t rhport); /* optional */ } usbd_class_driver_t; -#if !defined(TU_HAS_NO_ATTR_WEAK) // Invoked when initializing device stack to get additional class drivers. // Can optionally implemented by application to extend/overwrite class driver support. // Note: The drivers array must be accessible at all time when stack is active usbd_class_driver_t const* usbd_app_driver_get_cb(uint8_t* driver_count) TU_ATTR_WEAK; -#else - #if ADD_WEAK_FUNC_USBD_APP_DRIVER_GET_CB - #define USBD_APP_DRIVER_GET_CB usbd_app_driver_get_cb - #endif - #ifndef USBD_APP_DRIVER_GET_CB - #define USBD_APP_DRIVER_GET_CB NULL - #else - extern usbd_class_driver_t const* USBD_APP_DRIVER_GET_CB(uint8_t* driver_count); - #endif -#endif - typedef bool (*usbd_control_xfer_cb_t)(uint8_t rhport, uint8_t stage, tusb_control_request_t const * request); diff --git a/src/portable/renesas/usba/dcd_usba.c b/src/portable/renesas/usba/dcd_usba.c index 0e7881383..13fc50ae5 100644 --- a/src/portable/renesas/usba/dcd_usba.c +++ b/src/portable/renesas/usba/dcd_usba.c @@ -90,45 +90,47 @@ #define FIFO_REQ_CLR (1u) #define FIFO_COMPLETE (1u<<1) +TU_BIT_FIELD_ORDER_BEGIN typedef struct { union { - TU_BIT_FIELD_ORDER_BEGIN struct { uint16_t : 8; uint16_t TRCLR: 1; uint16_t TRENB: 1; uint16_t : 0; }; - TU_BIT_FIELD_ORDER_END uint16_t TRE; }; uint16_t TRN; } reg_pipetre_t; +TU_BIT_FIELD_ORDER_END +TU_BIT_FIELD_ORDER_BEGIN typedef union { - TU_BIT_FIELD_ORDER_BEGIN struct { volatile uint16_t u8: 8; volatile uint16_t : 0; }; - TU_BIT_FIELD_ORDER_END volatile uint16_t u16; } hw_fifo_t; +TU_BIT_FIELD_ORDER_END -TU_PACK_STRUCT_BEGIN +TU_PACK_STRUCT_BEGIN // Start of definition of packed structs (used by the CCRX toolchain) + +TU_BIT_FIELD_ORDER_BEGIN typedef struct TU_ATTR_PACKED { uintptr_t addr; /* the start address of a transfer data buffer */ uint16_t length; /* the number of bytes in the buffer */ uint16_t remaining; /* the number of bytes remaining in the buffer */ - TU_BIT_FIELD_ORDER_BEGIN struct { uint32_t ep : 8; /* an assigned endpoint address */ uint32_t : 0; }; - TU_BIT_FIELD_ORDER_END } pipe_state_t; -TU_PACK_STRUCT_END +TU_BIT_FIELD_ORDER_END + +TU_PACK_STRUCT_END // End of definition of packed structs (used by the CCRX toolchain) typedef struct { @@ -259,12 +261,6 @@ static int fifo_write(volatile void *fifo, pipe_state_t* pipe, unsigned mps) hw_fifo_t *reg = (hw_fifo_t*)fifo; uintptr_t addr = pipe->addr + pipe->length - rem; - if (addr & 1u) { - /* addr is not 2-byte aligned */ - reg->u8 = *(const uint8_t *)addr; - ++addr; - --len; - } while (len >= 2) { reg->u16 = *(const uint16_t *)addr; addr += 2; @@ -306,17 +302,10 @@ static void process_setup_packet(uint8_t rhport) uint16_t setup_packet[4]; if (0 == (USB0.INTSTS0.WORD & USB_IS0_VALID)) return; USB0.CFIFOCTR.WORD = USB_FIFOCTR_BCLR; - setup_packet[0] = USB0.USBREQ.WORD; + setup_packet[0] = tu_le16toh(USB0.USBREQ.WORD); setup_packet[1] = USB0.USBVAL; setup_packet[2] = USB0.USBINDX; setup_packet[3] = USB0.USBLENG; -#if TU_BYTE_ORDER==TU_BIG_ENDIAN - #if defined(__CCRX__) - setup_packet[0] = tu_le16toh(setup_packet[0]); - #else - //FIXME needs to implemented for other tool chains - #endif -#endif USB0.INTSTS0.WORD = ~USB_IS0_VALID; dcd_event_setup_received(rhport, (const uint8_t*)&setup_packet[0], true); } -- cgit v1.3.1 From 8433f638e64ce1b13fead28b4395d9a32c480548 Mon Sep 17 00:00:00 2001 From: MasterPhi Date: Sun, 20 Jun 2021 15:38:20 +0200 Subject: Add bracket to switch case, fix warning. --- src/class/audio/audio_device.c | 209 +++++++++++++++++++++-------------------- 1 file changed, 107 insertions(+), 102 deletions(-) (limited to 'src/class') diff --git a/src/class/audio/audio_device.c b/src/class/audio/audio_device.c index 8e4420ed0..7ad7edf9e 100644 --- a/src/class/audio/audio_device.c +++ b/src/class/audio/audio_device.c @@ -393,12 +393,12 @@ static uint8_t audiod_get_audio_fct_idx(audiod_function_t * audio); #if CFG_TUD_AUDIO_ENABLE_ENCODING || CFG_TUD_AUDIO_ENABLE_DECODING static void audiod_parse_for_AS_params(audiod_function_t* audio, uint8_t const * p_desc, uint8_t const * p_desc_end, uint8_t const as_itf); -#endif static inline uint8_t tu_desc_subtype(void const* desc) { return ((uint8_t const*) desc)[2]; } +#endif bool tud_audio_n_mounted(uint8_t func_id) { @@ -1658,64 +1658,65 @@ static bool audiod_control_complete(uint8_t rhport, tusb_control_request_t const switch (p_request->bmRequestType_bit.recipient) { - case TUSB_REQ_RCPT_INTERFACE: ; // The semicolon is there to enable a declaration right after the label - - uint8_t itf = TU_U16_LOW(p_request->wIndex); - uint8_t entityID = TU_U16_HIGH(p_request->wIndex); - - if (entityID != 0) + case TUSB_REQ_RCPT_INTERFACE: { - if (tud_audio_set_req_entity_cb) + uint8_t itf = TU_U16_LOW(p_request->wIndex); + uint8_t entityID = TU_U16_HIGH(p_request->wIndex); + + if (entityID != 0) { - // Check if entity is present and get corresponding driver index - TU_VERIFY(audiod_verify_entity_exists(itf, entityID, &func_id)); + if (tud_audio_set_req_entity_cb) + { + // Check if entity is present and get corresponding driver index + TU_VERIFY(audiod_verify_entity_exists(itf, entityID, &func_id)); - // Invoke callback - return tud_audio_set_req_entity_cb(rhport, p_request, _audiod_fct[func_id].ctrl_buf); + // Invoke callback + return tud_audio_set_req_entity_cb(rhport, p_request, _audiod_fct[func_id].ctrl_buf); + } + else + { + TU_LOG2(" No entity set request callback available!\r\n"); + return false; // In case no callback function is present or request can not be conducted we stall it + } } else { - TU_LOG2(" No entity set request callback available!\r\n"); - return false; // In case no callback function is present or request can not be conducted we stall it + if (tud_audio_set_req_itf_cb) + { + // Find index of audio driver structure and verify interface really exists + TU_VERIFY(audiod_verify_itf_exists(itf, &func_id)); + + // Invoke callback + return tud_audio_set_req_itf_cb(rhport, p_request, _audiod_fct[func_id].ctrl_buf); + } + else + { + TU_LOG2(" No interface set request callback available!\r\n"); + return false; // In case no callback function is present or request can not be conducted we stall it + } } } - else + break; + + case TUSB_REQ_RCPT_ENDPOINT: { - if (tud_audio_set_req_itf_cb) + uint8_t ep = TU_U16_LOW(p_request->wIndex); + + if (tud_audio_set_req_ep_cb) { - // Find index of audio driver structure and verify interface really exists - TU_VERIFY(audiod_verify_itf_exists(itf, &func_id)); + // Check if entity is present and get corresponding driver index + TU_VERIFY(audiod_verify_ep_exists(ep, &func_id)); // Invoke callback - return tud_audio_set_req_itf_cb(rhport, p_request, _audiod_fct[func_id].ctrl_buf); + return tud_audio_set_req_ep_cb(rhport, p_request, _audiod_fct[func_id].ctrl_buf); } else { - TU_LOG2(" No interface set request callback available!\r\n"); - return false; // In case no callback function is present or request can not be conducted we stall it + TU_LOG2(" No EP set request callback available!\r\n"); + return false; // In case no callback function is present or request can not be conducted we stall it } } - break; - - case TUSB_REQ_RCPT_ENDPOINT: ; // The semicolon is there to enable a declaration right after the label - - uint8_t ep = TU_U16_LOW(p_request->wIndex); - - if (tud_audio_set_req_ep_cb) - { - // Check if entity is present and get corresponding driver index - TU_VERIFY(audiod_verify_ep_exists(ep, &func_id)); - - // Invoke callback - return tud_audio_set_req_ep_cb(rhport, p_request, _audiod_fct[func_id].ctrl_buf); - } - else - { - TU_LOG2(" No EP set request callback available!\r\n"); - return false; // In case no callback function is present or request can not be conducted we stall it - } - // Unknown/Unsupported recipient default: TU_BREAKPOINT(); return false; } @@ -1754,73 +1755,75 @@ static bool audiod_control_request(uint8_t rhport, tusb_control_request_t const // Conduct checks which depend on the recipient switch (p_request->bmRequestType_bit.recipient) { - case TUSB_REQ_RCPT_INTERFACE: ; // The semicolon is there to enable a declaration right after the label - - uint8_t entityID = TU_U16_HIGH(p_request->wIndex); - - // Verify if entity is present - if (entityID != 0) + case TUSB_REQ_RCPT_INTERFACE: { - // Find index of audio driver structure and verify entity really exists - TU_VERIFY(audiod_verify_entity_exists(itf, entityID, &func_id)); + uint8_t entityID = TU_U16_HIGH(p_request->wIndex); - // In case we got a get request invoke callback - callback needs to answer as defined in UAC2 specification page 89 - 5. Requests - if (p_request->bmRequestType_bit.direction == TUSB_DIR_IN) + // Verify if entity is present + if (entityID != 0) { - if (tud_audio_get_req_entity_cb) + // Find index of audio driver structure and verify entity really exists + TU_VERIFY(audiod_verify_entity_exists(itf, entityID, &func_id)); + + // In case we got a get request invoke callback - callback needs to answer as defined in UAC2 specification page 89 - 5. Requests + if (p_request->bmRequestType_bit.direction == TUSB_DIR_IN) { - return tud_audio_get_req_entity_cb(rhport, p_request); + if (tud_audio_get_req_entity_cb) + { + return tud_audio_get_req_entity_cb(rhport, p_request); + } + else + { + TU_LOG2(" No entity get request callback available!\r\n"); + return false; // Stall + } } - else + } + else + { + // Find index of audio driver structure and verify interface really exists + TU_VERIFY(audiod_verify_itf_exists(itf, &func_id)); + + // In case we got a get request invoke callback - callback needs to answer as defined in UAC2 specification page 89 - 5. Requests + if (p_request->bmRequestType_bit.direction == TUSB_DIR_IN) { - TU_LOG2(" No entity get request callback available!\r\n"); - return false; // Stall + if (tud_audio_get_req_itf_cb) + { + return tud_audio_get_req_itf_cb(rhport, p_request); + } + else + { + TU_LOG2(" No interface get request callback available!\r\n"); + return false; // Stall + } } } } - else + break; + + case TUSB_REQ_RCPT_ENDPOINT: { - // Find index of audio driver structure and verify interface really exists - TU_VERIFY(audiod_verify_itf_exists(itf, &func_id)); + uint8_t ep = TU_U16_LOW(p_request->wIndex); + + // Find index of audio driver structure and verify EP really exists + TU_VERIFY(audiod_verify_ep_exists(ep, &func_id)); // In case we got a get request invoke callback - callback needs to answer as defined in UAC2 specification page 89 - 5. Requests if (p_request->bmRequestType_bit.direction == TUSB_DIR_IN) { - if (tud_audio_get_req_itf_cb) + if (tud_audio_get_req_ep_cb) { - return tud_audio_get_req_itf_cb(rhport, p_request); + return tud_audio_get_req_ep_cb(rhport, p_request); } else { - TU_LOG2(" No interface get request callback available!\r\n"); - return false; // Stall + TU_LOG2(" No EP get request callback available!\r\n"); + return false; // Stall } } } break; - case TUSB_REQ_RCPT_ENDPOINT: ; // The semicolon is there to enable a declaration right after the label - - uint8_t ep = TU_U16_LOW(p_request->wIndex); - - // Find index of audio driver structure and verify EP really exists - TU_VERIFY(audiod_verify_ep_exists(ep, &func_id)); - - // In case we got a get request invoke callback - callback needs to answer as defined in UAC2 specification page 89 - 5. Requests - if (p_request->bmRequestType_bit.direction == TUSB_DIR_IN) - { - if (tud_audio_get_req_ep_cb) - { - return tud_audio_get_req_ep_cb(rhport, p_request); - } - else - { - TU_LOG2(" No EP get request callback available!\r\n"); - return false; // Stall - } - } - break; - // Unknown/Unsupported recipient default: TU_LOG2(" Unsupported recipient: %d\r\n", p_request->bmRequestType_bit.recipient); TU_BREAKPOINT(); return false; } @@ -1935,29 +1938,31 @@ bool tud_audio_buffer_and_schedule_control_xfer(uint8_t rhport, tusb_control_req // Conduct checks which depend on the recipient switch (p_request->bmRequestType_bit.recipient) { - case TUSB_REQ_RCPT_INTERFACE: ; // The semicolon is there to enable a declaration right after the label - - uint8_t entityID = TU_U16_HIGH(p_request->wIndex); - - // Verify if entity is present - if (entityID != 0) + case TUSB_REQ_RCPT_INTERFACE: { - // Find index of audio driver structure and verify entity really exists - TU_VERIFY(audiod_verify_entity_exists(itf, entityID, &func_id)); - } - else - { - // Find index of audio driver structure and verify interface really exists - TU_VERIFY(audiod_verify_itf_exists(itf, &func_id)); + uint8_t entityID = TU_U16_HIGH(p_request->wIndex); + + // Verify if entity is present + if (entityID != 0) + { + // Find index of audio driver structure and verify entity really exists + TU_VERIFY(audiod_verify_entity_exists(itf, entityID, &func_id)); + } + else + { + // Find index of audio driver structure and verify interface really exists + TU_VERIFY(audiod_verify_itf_exists(itf, &func_id)); + } } break; case TUSB_REQ_RCPT_ENDPOINT: ; // The semicolon is there to enable a declaration right after the label + { + uint8_t ep = TU_U16_LOW(p_request->wIndex); - uint8_t ep = TU_U16_LOW(p_request->wIndex); - - // Find index of audio driver structure and verify EP really exists - TU_VERIFY(audiod_verify_ep_exists(ep, &func_id)); + // Find index of audio driver structure and verify EP really exists + TU_VERIFY(audiod_verify_ep_exists(ep, &func_id)); + } break; // Unknown/Unsupported recipient -- cgit v1.3.1 From 9323a9d094684a25e65fcae964e7ee91c9746f57 Mon Sep 17 00:00:00 2001 From: hathach Date: Mon, 21 Jun 2021 00:00:46 +0700 Subject: fix issue when calling midi API when not enumerated yet --- src/class/midi/midi_device.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) (limited to 'src/class') diff --git a/src/class/midi/midi_device.c b/src/class/midi/midi_device.c index 953ca26e6..4eac0de48 100644 --- a/src/class/midi/midi_device.c +++ b/src/class/midi/midi_device.c @@ -197,9 +197,11 @@ uint32_t tud_midi_n_stream_read(uint8_t itf, uint8_t cable_num, void* buffer, ui bool tud_midi_n_packet_read (uint8_t itf, uint8_t packet[4]) { - midid_interface_t* p_midi = &_midid_itf[itf]; - uint32_t num_read = tu_fifo_read_n(&p_midi->rx_ff, packet, 4); - _prep_out_transaction(p_midi); + midid_interface_t* midi = &_midid_itf[itf]; + TU_VERIFY(midi->ep_out); + + uint32_t const num_read = tu_fifo_read_n(&midi->rx_ff, packet, 4); + _prep_out_transaction(midi); return (num_read == 4); } @@ -234,7 +236,7 @@ static uint32_t write_flush(midid_interface_t* midi) uint32_t tud_midi_n_stream_write(uint8_t itf, uint8_t cable_num, uint8_t const* buffer, uint32_t bufsize) { midid_interface_t* midi = &_midid_itf[itf]; - TU_VERIFY(midi->itf_num, 0); + TU_VERIFY(midi->ep_in, 0); midid_stream_t* stream = &midi->stream_write; @@ -351,9 +353,7 @@ uint32_t tud_midi_n_stream_write(uint8_t itf, uint8_t cable_num, uint8_t const* bool tud_midi_n_packet_write (uint8_t itf, uint8_t const packet[4]) { midid_interface_t* midi = &_midid_itf[itf]; - if (midi->itf_num == 0) { - return 0; - } + TU_VERIFY(midi->ep_in); if (tu_fifo_remaining(&midi->tx_ff) < 4) return false; @@ -435,6 +435,7 @@ uint16_t midid_open(uint8_t rhport, tusb_desc_interface_t const * desc_itf, uint } p_midi->itf_num = desc_midi->bInterfaceNumber; + (void) p_midi->itf_num; // next descriptor drv_len += tu_desc_len(p_desc); -- cgit v1.3.1 From 264dc35b95a2313201845f3612d3e807afad62c3 Mon Sep 17 00:00:00 2001 From: Niklas Hauser Date: Mon, 21 Jun 2021 05:32:43 +0200 Subject: Fix typo in TUH configuration define --- examples/host/cdc_msc_hid/src/tusb_config.h | 2 +- src/class/hid/hid_host.c | 2 +- src/host/usbh.c | 4 ++-- src/host/usbh_control.c | 2 +- src/tusb_option.h | 4 ++-- 5 files changed, 7 insertions(+), 7 deletions(-) (limited to 'src/class') diff --git a/examples/host/cdc_msc_hid/src/tusb_config.h b/examples/host/cdc_msc_hid/src/tusb_config.h index 8253964c0..cc77b6554 100644 --- a/examples/host/cdc_msc_hid/src/tusb_config.h +++ b/examples/host/cdc_msc_hid/src/tusb_config.h @@ -72,7 +72,7 @@ //-------------------------------------------------------------------- // Size of buffer to hold descriptors and other data used for enumeration -#define CFG_TUH_ENUMERATION_BUFSZIE 256 +#define CFG_TUH_ENUMERATION_BUFSIZE 256 #define CFG_TUH_HUB 1 #define CFG_TUH_CDC 1 diff --git a/src/class/hid/hid_host.c b/src/class/hid/hid_host.c index cde5e23a5..761258f1b 100644 --- a/src/class/hid/hid_host.c +++ b/src/class/hid/hid_host.c @@ -368,7 +368,7 @@ static bool config_get_report_desc(uint8_t dev_addr, tusb_control_request_t cons // Get Report Descriptor // using usbh enumeration buffer since report descriptor can be very long - TU_ASSERT( hid_itf->report_desc_len <= CFG_TUH_ENUMERATION_BUFSZIE ); + TU_ASSERT( hid_itf->report_desc_len <= CFG_TUH_ENUMERATION_BUFSIZE ); TU_LOG2("HID Get Report Descriptor\r\n"); tusb_control_request_t const new_request = diff --git a/src/host/usbh.c b/src/host/usbh.c index 59246a663..8ecc87488 100644 --- a/src/host/usbh.c +++ b/src/host/usbh.c @@ -130,7 +130,7 @@ CFG_TUSB_MEM_SECTION usbh_device_t _usbh_devices[CFG_TUSB_HOST_DEVICE_MAX+1]; OSAL_QUEUE_DEF(OPT_MODE_HOST, _usbh_qdef, CFG_TUH_TASK_QUEUE_SZ, hcd_event_t); static osal_queue_t _usbh_q; -CFG_TUSB_MEM_SECTION CFG_TUSB_MEM_ALIGN static uint8_t _usbh_ctrl_buf[CFG_TUH_ENUMERATION_BUFSZIE]; +CFG_TUSB_MEM_SECTION CFG_TUSB_MEM_ALIGN static uint8_t _usbh_ctrl_buf[CFG_TUH_ENUMERATION_BUFSIZE]; //------------- Helper Function Prototypes -------------// static bool enum_new_device(hcd_event_t* event); @@ -907,7 +907,7 @@ static bool enum_get_9byte_config_desc_complete(uint8_t dev_addr, tusb_control_r // Use offsetof to avoid pointer to the odd/misaligned address memcpy(&total_len, (uint8_t*) desc_config + offsetof(tusb_desc_configuration_t, wTotalLength), 2); - TU_ASSERT(total_len <= CFG_TUH_ENUMERATION_BUFSZIE); + TU_ASSERT(total_len <= CFG_TUH_ENUMERATION_BUFSIZE); // Get full configuration descriptor TU_LOG2("Get Configuration Descriptor\r\n"); diff --git a/src/host/usbh_control.c b/src/host/usbh_control.c index 4dbf8592a..53413b6e5 100644 --- a/src/host/usbh_control.c +++ b/src/host/usbh_control.c @@ -50,7 +50,7 @@ typedef struct static usbh_control_xfer_t _ctrl_xfer; //CFG_TUSB_MEM_SECTION CFG_TUSB_MEM_ALIGN -//static uint8_t _tuh_ctrl_buf[CFG_TUH_ENUMERATION_BUFSZIE]; +//static uint8_t _tuh_ctrl_buf[CFG_TUH_ENUMERATION_BUFSIZE]; //--------------------------------------------------------------------+ // MACRO TYPEDEF CONSTANT ENUM DECLARATION diff --git a/src/tusb_option.h b/src/tusb_option.h index d5776c029..815e588de 100644 --- a/src/tusb_option.h +++ b/src/tusb_option.h @@ -278,8 +278,8 @@ #error there is no benefit enable hub with max device is 1. Please disable hub or increase CFG_TUSB_HOST_DEVICE_MAX #endif - #ifndef CFG_TUH_ENUMERATION_BUFSZIE - #define CFG_TUH_ENUMERATION_BUFSZIE 256 + #ifndef CFG_TUH_ENUMERATION_BUFSIZE + #define CFG_TUH_ENUMERATION_BUFSIZE 256 #endif //------------- CLASS -------------// -- cgit v1.3.1 From f5f087b2f85ebf4ff41c84c5f1a70a598d32cb21 Mon Sep 17 00:00:00 2001 From: Jeremiah McCarthy Date: Wed, 23 Jun 2021 10:58:18 -0400 Subject: Add dfu function memory access protection Adds TU_VERIFY to dfu internal buffer access from host. Adds TU_ASSERT to dfu internal buffer access by application. --- src/class/dfu/dfu_device.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src/class') diff --git a/src/class/dfu/dfu_device.c b/src/class/dfu/dfu_device.c index 81045ff7b..df731ee50 100644 --- a/src/class/dfu/dfu_device.c +++ b/src/class/dfu/dfu_device.c @@ -249,6 +249,7 @@ static uint16_t dfu_req_upload(uint8_t rhport, tusb_control_request_t const * re { TU_VERIFY( wLength <= CFG_TUD_DFU_TRANSFER_BUFFER_SIZE); uint16_t retval = tud_dfu_req_upload_data_cb(block_num, (uint8_t *)_dfu_state_ctx.transfer_buf, wLength); + TU_ASSERT( retval <= CFG_TUD_DFU_TRANSFER_BUFFER_SIZE); tud_control_xfer(rhport, request, _dfu_state_ctx.transfer_buf, retval); return retval; } @@ -276,6 +277,7 @@ static void dfu_req_dnload_setup(uint8_t rhport, tusb_control_request_t const * // if they wish, there still will be the internal control buffer copy to this buffer // but this mode would provide zero copy from the class driver to the application + TU_VERIFY( request->wLength <= CFG_TUD_DFU_TRANSFER_BUFFER_SIZE); // setup for data phase tud_control_xfer(rhport, request, _dfu_state_ctx.transfer_buf, request->wLength); } @@ -283,6 +285,7 @@ static void dfu_req_dnload_setup(uint8_t rhport, tusb_control_request_t const * static void dfu_req_dnload_reply(uint8_t rhport, tusb_control_request_t const * request) { (void) rhport; + TU_VERIFY( request->wLength <= CFG_TUD_DFU_TRANSFER_BUFFER_SIZE); tud_dfu_req_dnload_data_cb(request->wValue, (uint8_t *)_dfu_state_ctx.transfer_buf, request->wLength); _dfu_state_ctx.blk_transfer_in_proc = false; } -- cgit v1.3.1 From 5811122cfd04b84c8760991e287e29fc424453fd Mon Sep 17 00:00:00 2001 From: hathach Date: Thu, 17 Jun 2021 11:58:34 +0700 Subject: change usbh open driver to have max_len and return driver len --- src/class/cdc/cdc_device.c | 10 +++----- src/class/cdc/cdc_host.c | 62 ++++++++++++++++++++++----------------------- src/class/cdc/cdc_host.h | 10 ++++---- src/class/hid/hid_host.c | 20 +++++++++------ src/class/hid/hid_host.h | 10 ++++---- src/class/msc/msc_host.c | 13 ++++++---- src/class/msc/msc_host.h | 20 ++++----------- src/host/hub.c | 31 +++++++++++++---------- src/host/hub.h | 10 ++++---- src/host/usbh.c | 15 ++++++----- src/host/usbh_classdriver.h | 10 ++++---- 11 files changed, 104 insertions(+), 107 deletions(-) (limited to 'src/class') diff --git a/src/class/cdc/cdc_device.c b/src/class/cdc/cdc_device.c index cac811c45..e622bd616 100644 --- a/src/class/cdc/cdc_device.c +++ b/src/class/cdc/cdc_device.c @@ -273,9 +273,6 @@ uint16_t cdcd_open(uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint1 TU_VERIFY( TUSB_CLASS_CDC == itf_desc->bInterfaceClass && CDC_COMM_SUBCLASS_ABSTRACT_CONTROL_MODEL == itf_desc->bInterfaceSubClass, 0); - // Note: 0xFF can be used with RNDIS - TU_VERIFY(tu_within(CDC_COMM_PROTOCOL_NONE, itf_desc->bInterfaceProtocol, CDC_COMM_PROTOCOL_ATCOMMAND_CDMA), 0); - // Find available interface cdcd_interface_t * p_cdc = NULL; for(uint8_t cdc_id=0; cdc_idep_notif = ((tusb_desc_endpoint_t const *) p_desc)->bEndpointAddress; + TU_ASSERT( usbd_edpt_open(rhport, desc_ep), 0 ); + p_cdc->ep_notif = desc_ep->bEndpointAddress; drv_len += tu_desc_len(p_desc); p_desc = tu_desc_next(p_desc); diff --git a/src/class/cdc/cdc_host.c b/src/class/cdc/cdc_host.c index 33f1a8ad3..fc7100e81 100644 --- a/src/class/cdc/cdc_host.c +++ b/src/class/cdc/cdc_host.c @@ -149,29 +149,27 @@ void cdch_init(void) tu_memclr(cdch_data, sizeof(cdch_data_t)*CFG_TUSB_HOST_DEVICE_MAX); } -bool cdch_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const *itf_desc, uint16_t *p_length) +uint16_t cdch_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const *itf_desc, uint16_t max_len) { - // Only support ACM - TU_VERIFY( CDC_COMM_SUBCLASS_ABSTRACT_CONTROL_MODEL == itf_desc->bInterfaceSubClass); + (void) max_len; - // Only support AT commands, no protocol and vendor specific commands. - TU_VERIFY(tu_within(CDC_COMM_PROTOCOL_NONE, itf_desc->bInterfaceProtocol, CDC_COMM_PROTOCOL_ATCOMMAND_CDMA) || - 0xff == itf_desc->bInterfaceProtocol); + // Only support ACM subclass + // Protocol 0xFF can be RNDIS device for windows XP + TU_VERIFY( TUSB_CLASS_CDC == itf_desc->bInterfaceClass && + CDC_COMM_SUBCLASS_ABSTRACT_CONTROL_MODEL == itf_desc->bInterfaceSubClass && + 0xFF != itf_desc->bInterfaceProtocol, 0); - uint8_t const * p_desc; - cdch_data_t * p_cdc; - - p_desc = tu_desc_next(itf_desc); - p_cdc = get_itf(dev_addr); + cdch_data_t * p_cdc = get_itf(dev_addr); - p_cdc->itf_num = itf_desc->bInterfaceNumber; - p_cdc->itf_protocol = itf_desc->bInterfaceProtocol; // TODO 0xff is consider as rndis candidate, other is virtual Com + p_cdc->itf_num = itf_desc->bInterfaceNumber; + p_cdc->itf_protocol = itf_desc->bInterfaceProtocol; //------------- Communication Interface -------------// - (*p_length) = sizeof(tusb_desc_interface_t); + uint16_t drv_len = tu_desc_len(itf_desc); + uint8_t const * p_desc = tu_desc_next(itf_desc); // Communication Functional Descriptors - while( TUSB_DESC_CS_INTERFACE == p_desc[DESC_OFFSET_TYPE] ) + while( TUSB_DESC_CS_INTERFACE == tu_desc_type(p_desc) && drv_len <= max_len ) { if ( CDC_FUNC_DESC_ABSTRACT_CONTROL_MANAGEMENT == cdc_functional_desc_typeof(p_desc) ) { @@ -179,52 +177,52 @@ bool cdch_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const *it p_cdc->acm_capability = ((cdc_desc_func_acm_t const *) p_desc)->bmCapabilities; } - (*p_length) += p_desc[DESC_OFFSET_LEN]; + drv_len += tu_desc_len(p_desc); p_desc = tu_desc_next(p_desc); } - if ( TUSB_DESC_ENDPOINT == p_desc[DESC_OFFSET_TYPE]) + if ( TUSB_DESC_ENDPOINT == tu_desc_type(p_desc) ) { // notification endpoint - tusb_desc_endpoint_t const * ep_desc = (tusb_desc_endpoint_t const *) p_desc; + tusb_desc_endpoint_t const * desc_ep = (tusb_desc_endpoint_t const *) p_desc; - TU_ASSERT( usbh_edpt_open(rhport, dev_addr, ep_desc) ); - p_cdc->ep_notif = ep_desc->bEndpointAddress; + TU_ASSERT( usbh_edpt_open(rhport, dev_addr, desc_ep), 0 ); + p_cdc->ep_notif = desc_ep->bEndpointAddress; - (*p_length) += p_desc[DESC_OFFSET_LEN]; + drv_len += tu_desc_len(p_desc); p_desc = tu_desc_next(p_desc); } //------------- Data Interface (if any) -------------// - if ( (TUSB_DESC_INTERFACE == p_desc[DESC_OFFSET_TYPE]) && + if ( (TUSB_DESC_INTERFACE == tu_desc_type(p_desc)) && (TUSB_CLASS_CDC_DATA == ((tusb_desc_interface_t const *) p_desc)->bInterfaceClass) ) { - (*p_length) += p_desc[DESC_OFFSET_LEN]; + // next to endpoint descriptor + drv_len += tu_desc_len(p_desc); p_desc = tu_desc_next(p_desc); // data endpoints expected to be in pairs for(uint32_t i=0; i<2; i++) { - tusb_desc_endpoint_t const *ep_desc = (tusb_desc_endpoint_t const *) p_desc; - TU_ASSERT(TUSB_DESC_ENDPOINT == ep_desc->bDescriptorType); - TU_ASSERT(TUSB_XFER_BULK == ep_desc->bmAttributes.xfer); + tusb_desc_endpoint_t const *desc_ep = (tusb_desc_endpoint_t const *) p_desc; + TU_ASSERT(TUSB_DESC_ENDPOINT == desc_ep->bDescriptorType && TUSB_XFER_BULK == desc_ep->bmAttributes.xfer, 0); - TU_ASSERT(usbh_edpt_open(rhport, dev_addr, ep_desc)); + TU_ASSERT(usbh_edpt_open(rhport, dev_addr, desc_ep), 0); - if ( tu_edpt_dir(ep_desc->bEndpointAddress) == TUSB_DIR_IN ) + if ( tu_edpt_dir(desc_ep->bEndpointAddress) == TUSB_DIR_IN ) { - p_cdc->ep_in = ep_desc->bEndpointAddress; + p_cdc->ep_in = desc_ep->bEndpointAddress; }else { - p_cdc->ep_out = ep_desc->bEndpointAddress; + p_cdc->ep_out = desc_ep->bEndpointAddress; } - (*p_length) += p_desc[DESC_OFFSET_LEN]; + drv_len += tu_desc_len(p_desc); p_desc = tu_desc_next( p_desc ); } } - return true; + return drv_len; } bool cdch_set_config(uint8_t dev_addr, uint8_t itf_num) diff --git a/src/class/cdc/cdc_host.h b/src/class/cdc/cdc_host.h index 6ff392709..edcd258a8 100644 --- a/src/class/cdc/cdc_host.h +++ b/src/class/cdc/cdc_host.h @@ -121,11 +121,11 @@ void tuh_cdc_xfer_isr(uint8_t dev_addr, xfer_result_t event, cdc_pipeid_t pipe_i //--------------------------------------------------------------------+ // Internal Class Driver API //--------------------------------------------------------------------+ -void cdch_init(void); -bool cdch_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const *itf_desc, uint16_t *p_length); -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); -void cdch_close(uint8_t dev_addr); +void cdch_init (void); +uint16_t cdch_open (uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const *itf_desc, uint16_t max_len); +bool cdch_set_config (uint8_t dev_addr, uint8_t itf_num); +bool cdch_xfer_cb (uint8_t dev_addr, uint8_t ep_addr, xfer_result_t event, uint32_t xferred_bytes); +void cdch_close (uint8_t dev_addr); #ifdef __cplusplus } diff --git a/src/class/hid/hid_host.c b/src/class/hid/hid_host.c index 16d908a5d..81ed6e8b6 100644 --- a/src/class/hid/hid_host.c +++ b/src/class/hid/hid_host.c @@ -247,29 +247,33 @@ static bool config_get_protocol (uint8_t dev_addr, tusb_control_requ static bool config_get_report_desc (uint8_t dev_addr, tusb_control_request_t const * request, xfer_result_t result); static bool config_get_report_desc_complete (uint8_t dev_addr, tusb_control_request_t const * request, xfer_result_t result); -bool hidh_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const *desc_itf, uint16_t *p_length) +uint16_t hidh_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const *desc_itf, uint16_t max_len) { - TU_VERIFY(TUSB_CLASS_HID == desc_itf->bInterfaceClass); + (void) max_len; + TU_VERIFY(TUSB_CLASS_HID == desc_itf->bInterfaceClass, 0); + + uint16_t drv_len = sizeof(tusb_desc_interface_t); uint8_t const *p_desc = (uint8_t const *) desc_itf; //------------- HID descriptor -------------// p_desc = tu_desc_next(p_desc); tusb_hid_descriptor_hid_t const *desc_hid = (tusb_hid_descriptor_hid_t const *) p_desc; - TU_ASSERT(HID_DESC_TYPE_HID == desc_hid->bDescriptorType); + TU_ASSERT(HID_DESC_TYPE_HID == desc_hid->bDescriptorType, 0); // not enough interface, try to increase CFG_TUH_HID // TODO multiple devices hidh_device_t* hid_dev = get_dev(dev_addr); - TU_ASSERT(hid_dev->inst_count < CFG_TUH_HID); + TU_ASSERT(hid_dev->inst_count < CFG_TUH_HID, 0); //------------- Endpoint Descriptor -------------// + drv_len += tu_desc_len(p_desc); p_desc = tu_desc_next(p_desc); tusb_desc_endpoint_t const * desc_ep = (tusb_desc_endpoint_t const *) p_desc; - TU_ASSERT(TUSB_DESC_ENDPOINT == desc_ep->bDescriptorType); + TU_ASSERT(TUSB_DESC_ENDPOINT == desc_ep->bDescriptorType, 0); // TODO also open endpoint OUT - TU_ASSERT( usbh_edpt_open(rhport, dev_addr, desc_ep) ); + TU_ASSERT( usbh_edpt_open(rhport, dev_addr, desc_ep), 0 ); hidh_interface_t* hid_itf = get_instance(dev_addr, hid_dev->inst_count); hid_dev->inst_count++; @@ -285,9 +289,9 @@ bool hidh_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const *de hid_itf->protocol_mode = HID_PROTOCOL_REPORT; // Per Specs: default is report mode if ( HID_SUBCLASS_BOOT == desc_itf->bInterfaceSubClass ) hid_itf->itf_protocol = desc_itf->bInterfaceProtocol; - *p_length = sizeof(tusb_desc_interface_t) + sizeof(tusb_hid_descriptor_hid_t) + desc_itf->bNumEndpoints*sizeof(tusb_desc_endpoint_t); + drv_len += desc_itf->bNumEndpoints*sizeof(tusb_desc_endpoint_t); - return true; + return drv_len; } bool hidh_set_config(uint8_t dev_addr, uint8_t itf_num) diff --git a/src/class/hid/hid_host.h b/src/class/hid/hid_host.h index 2e4cce600..6ae7c6721 100644 --- a/src/class/hid/hid_host.h +++ b/src/class/hid/hid_host.h @@ -118,11 +118,11 @@ TU_ATTR_WEAK void tuh_hid_set_protocol_complete_cb(uint8_t dev_addr, uint8_t ins //--------------------------------------------------------------------+ // Internal Class Driver API //--------------------------------------------------------------------+ -void hidh_init(void); -bool hidh_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const *desc_itf, uint16_t *p_length); -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); -void hidh_close(uint8_t dev_addr); +void hidh_init (void); +uint16_t hidh_open (uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const *desc_itf, uint16_t max_len); +bool hidh_set_config (uint8_t dev_addr, uint8_t itf_num); +bool hidh_xfer_cb (uint8_t dev_addr, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes); +void hidh_close (uint8_t dev_addr); #ifdef __cplusplus } diff --git a/src/class/msc/msc_host.c b/src/class/msc/msc_host.c index 7f98ef9b1..83cbe7c89 100644 --- a/src/class/msc/msc_host.c +++ b/src/class/msc/msc_host.c @@ -360,18 +360,22 @@ static bool config_test_unit_ready_complete(uint8_t dev_addr, msc_cbw_t const* c static bool config_request_sense_complete(uint8_t dev_addr, msc_cbw_t const* cbw, msc_csw_t const* csw); static bool config_read_capacity_complete(uint8_t dev_addr, msc_cbw_t const* cbw, msc_csw_t const* csw); -bool msch_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const *desc_itf, uint16_t *p_length) +uint16_t msch_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const *desc_itf, uint16_t max_len) { TU_VERIFY (MSC_SUBCLASS_SCSI == desc_itf->bInterfaceSubClass && MSC_PROTOCOL_BOT == desc_itf->bInterfaceProtocol); + // msc driver length is fixed + uint16_t const drv_len = sizeof(tusb_desc_interface_t) + 2*sizeof(tusb_desc_endpoint_t); + TU_ASSERT(drv_len <= max_len, 0); + msch_interface_t* p_msc = get_itf(dev_addr); tusb_desc_endpoint_t const * ep_desc = (tusb_desc_endpoint_t const *) tu_desc_next(desc_itf); for(uint32_t i=0; i<2; i++) { - TU_ASSERT(TUSB_DESC_ENDPOINT == ep_desc->bDescriptorType && TUSB_XFER_BULK == ep_desc->bmAttributes.xfer); - TU_ASSERT(usbh_edpt_open(rhport, dev_addr, ep_desc)); + TU_ASSERT(TUSB_DESC_ENDPOINT == ep_desc->bDescriptorType && TUSB_XFER_BULK == ep_desc->bmAttributes.xfer, 0); + TU_ASSERT(usbh_edpt_open(rhport, dev_addr, ep_desc), 0); if ( tu_edpt_dir(ep_desc->bEndpointAddress) == TUSB_DIR_IN ) { @@ -385,9 +389,8 @@ bool msch_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const *de } p_msc->itf_num = desc_itf->bInterfaceNumber; - (*p_length) += sizeof(tusb_desc_interface_t) + 2*sizeof(tusb_desc_endpoint_t); - return true; + return drv_len; } bool msch_set_config(uint8_t dev_addr, uint8_t itf_num) diff --git a/src/class/msc/msc_host.h b/src/class/msc/msc_host.h index ce4fe64dc..9e4217ba5 100644 --- a/src/class/msc/msc_host.h +++ b/src/class/msc/msc_host.h @@ -41,13 +41,6 @@ #define CFG_TUH_MSC_MAXLUN 4 #endif - -/** \addtogroup ClassDriver_MSC - * @{ - * \defgroup MSC_Host Host - * The interface API includes status checking function, data transferring function and callback functions - * @{ */ - typedef bool (*tuh_msc_complete_cb_t)(uint8_t dev_addr, msc_cbw_t const* cbw, msc_csw_t const* csw); //--------------------------------------------------------------------+ @@ -113,17 +106,14 @@ TU_ATTR_WEAK void tuh_msc_umount_cb(uint8_t dev_addr); // Internal Class Driver API //--------------------------------------------------------------------+ -void msch_init(void); -bool msch_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const *desc_itf, uint16_t *p_length); -bool msch_set_config(uint8_t dev_addr, uint8_t itf_num); -bool msch_xfer_cb(uint8_t dev_addr, uint8_t ep_addr, xfer_result_t event, uint32_t xferred_bytes); -void msch_close(uint8_t dev_addr); +void msch_init (void); +uint16_t 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_xfer_cb (uint8_t dev_addr, uint8_t ep_addr, xfer_result_t event, uint32_t xferred_bytes); +void msch_close (uint8_t dev_addr); #ifdef __cplusplus } #endif #endif /* _TUSB_MSC_HOST_H_ */ - -/// @} -/// @} diff --git a/src/host/hub.c b/src/host/hub.c index b2761184d..2ead5bed1 100644 --- a/src/host/hub.c +++ b/src/host/hub.c @@ -144,29 +144,32 @@ bool hub_port_get_status(uint8_t hub_addr, uint8_t hub_port, void* resp, tuh_con //--------------------------------------------------------------------+ void hub_init(void) { - tu_memclr(hub_data, CFG_TUSB_HOST_DEVICE_MAX*sizeof( hub_interface_t)); + tu_memclr(hub_data, CFG_TUSB_HOST_DEVICE_MAX*sizeof(hub_interface_t)); } -bool hub_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const *itf_desc, uint16_t *p_length) +uint16_t hub_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const *itf_desc, uint16_t max_len) { - // not support multiple TT yet - if ( itf_desc->bInterfaceProtocol > 1 ) return false; + // hub driver does not support multiple TT yet + TU_VERIFY(TUSB_CLASS_HUB == itf_desc->bInterfaceClass && + 0 == itf_desc->bInterfaceSubClass && + 1 <= itf_desc->bInterfaceProtocol, 0); - //------------- Open Interrupt Status Pipe -------------// - tusb_desc_endpoint_t const *ep_desc; - ep_desc = (tusb_desc_endpoint_t const *) tu_desc_next(itf_desc); + // msc driver length is fixed + uint16_t const drv_len = sizeof(tusb_desc_interface_t) + sizeof(tusb_desc_endpoint_t); + TU_ASSERT(drv_len <= max_len, 0); - TU_ASSERT(TUSB_DESC_ENDPOINT == ep_desc->bDescriptorType); - TU_ASSERT(TUSB_XFER_INTERRUPT == ep_desc->bmAttributes.xfer); + //------------- Interrupt Status endpoint -------------// + tusb_desc_endpoint_t const *desc_ep = (tusb_desc_endpoint_t const *) tu_desc_next(itf_desc); + + TU_ASSERT(TUSB_DESC_ENDPOINT == desc_ep->bDescriptorType && + TUSB_XFER_INTERRUPT == desc_ep->bmAttributes.xfer, 0); - TU_ASSERT(usbh_edpt_open(rhport, dev_addr, ep_desc)); + TU_ASSERT(usbh_edpt_open(rhport, dev_addr, desc_ep)); hub_data[dev_addr-1].itf_num = itf_desc->bInterfaceNumber; - hub_data[dev_addr-1].ep_in = ep_desc->bEndpointAddress; - - (*p_length) = sizeof(tusb_desc_interface_t) + sizeof(tusb_desc_endpoint_t); + hub_data[dev_addr-1].ep_in = desc_ep->bEndpointAddress; - return true; + return drv_len; } void hub_close(uint8_t dev_addr) diff --git a/src/host/hub.h b/src/host/hub.h index a5111b8e7..c9ffe4985 100644 --- a/src/host/hub.h +++ b/src/host/hub.h @@ -181,11 +181,11 @@ bool hub_status_pipe_queue(uint8_t dev_addr); //--------------------------------------------------------------------+ // Internal Class Driver API //--------------------------------------------------------------------+ -void hub_init(void); -bool hub_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const *itf_desc, uint16_t *p_length); -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); -void hub_close(uint8_t dev_addr); +void hub_init (void); +uint16_t hub_open (uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const *itf_desc, uint16_t max_len); +bool hub_set_config (uint8_t dev_addr, uint8_t itf_num); +bool hub_xfer_cb (uint8_t dev_addr, uint8_t ep_addr, xfer_result_t event, uint32_t xferred_bytes); +void hub_close (uint8_t dev_addr); #ifdef __cplusplus } diff --git a/src/host/usbh.c b/src/host/usbh.c index bad1aa61a..93621c42a 100644 --- a/src/host/usbh.c +++ b/src/host/usbh.c @@ -984,11 +984,12 @@ static bool enum_set_config_complete(uint8_t dev_addr, tusb_control_request_t co static bool parse_configuration_descriptor(uint8_t dev_addr, tusb_desc_configuration_t const* desc_cfg) { usbh_device_t* dev = &_usbh_devices[dev_addr]; - uint8_t const* p_desc = (uint8_t const*) desc_cfg; - p_desc = tu_desc_next(p_desc); + + uint8_t const* desc_end = ((uint8_t const*) desc_cfg) + tu_le16toh(desc_cfg->wTotalLength); + uint8_t const* p_desc = tu_desc_next(desc_cfg); // parse each interfaces - while( p_desc < _usbh_ctrl_buf + desc_cfg->wTotalLength ) + while( p_desc < desc_end ) { // TODO Do we need to use IAD // tusb_desc_interface_assoc_t const * desc_itf_assoc = NULL; @@ -1003,8 +1004,9 @@ static bool parse_configuration_descriptor(uint8_t dev_addr, tusb_desc_configura TU_ASSERT( TUSB_DESC_INTERFACE == tu_desc_type(p_desc) ); tusb_desc_interface_t const* desc_itf = (tusb_desc_interface_t const*) p_desc; + uint16_t const remaining_len = desc_end-p_desc; - // Check if class is supported + // Check if class is supported TODO drop class_code uint8_t drv_id; for (drv_id = 0; drv_id < USBH_CLASS_DRIVER_COUNT; drv_id++) { @@ -1034,9 +1036,8 @@ static bool parse_configuration_descriptor(uint8_t dev_addr, tusb_desc_configura { TU_LOG2("%s open\r\n", driver->name); - uint16_t itf_len = 0; - TU_ASSERT( driver->open(dev->rhport, dev_addr, desc_itf, &itf_len) ); - TU_ASSERT( itf_len >= sizeof(tusb_desc_interface_t) ); + uint16_t const itf_len = driver->open(dev->rhport, dev_addr, desc_itf, remaining_len); + TU_ASSERT( sizeof(tusb_desc_interface_t) <= itf_len && itf_len <= remaining_len); p_desc += itf_len; } } diff --git a/src/host/usbh_classdriver.h b/src/host/usbh_classdriver.h index 07480fe8e..0736fefa1 100644 --- a/src/host/usbh_classdriver.h +++ b/src/host/usbh_classdriver.h @@ -45,11 +45,11 @@ typedef struct { uint8_t class_code; - void (* const init )(void); - bool (* const open )(uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const * itf_desc, uint16_t* outlen); - bool (* const set_config )(uint8_t dev_addr, uint8_t itf_num); - bool (* const xfer_cb )(uint8_t dev_addr, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes); - void (* const close )(uint8_t dev_addr); + void (* const init )(void); + uint16_t (* const open )(uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const * itf_desc, uint16_t max_len); + bool (* const set_config )(uint8_t dev_addr, uint8_t itf_num); + bool (* const xfer_cb )(uint8_t dev_addr, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes); + void (* const close )(uint8_t dev_addr); } usbh_class_driver_t; // Call by class driver to tell USBH that it has complete the enumeration -- cgit v1.3.1 From c99b70c08cb9c3b252e015fd455c35674282aa91 Mon Sep 17 00:00:00 2001 From: hathach Date: Thu, 17 Jun 2021 12:35:51 +0700 Subject: force boot protocol for keyboard/mouse --- src/class/hid/hid_host.c | 27 +++++++++++++++------------ src/class/hid/hid_host.h | 6 +++--- 2 files changed, 18 insertions(+), 15 deletions(-) (limited to 'src/class') diff --git a/src/class/hid/hid_host.c b/src/class/hid/hid_host.c index 81ed6e8b6..59fbb097e 100644 --- a/src/class/hid/hid_host.c +++ b/src/class/hid/hid_host.c @@ -98,7 +98,7 @@ uint8_t tuh_hid_interface_protocol(uint8_t dev_addr, uint8_t instance) return hid_itf->itf_protocol; } -bool tuh_hid_get_protocol(uint8_t dev_addr, uint8_t instance) +uint8_t tuh_hid_get_protocol(uint8_t dev_addr, uint8_t instance) { hidh_interface_t* hid_itf = get_instance(dev_addr, instance); return hid_itf->protocol_mode; @@ -243,7 +243,7 @@ void hidh_close(uint8_t dev_addr) // Enumeration //--------------------------------------------------------------------+ -static bool config_get_protocol (uint8_t dev_addr, tusb_control_request_t const * request, xfer_result_t result); +static bool config_set_protocol (uint8_t dev_addr, tusb_control_request_t const * request, xfer_result_t result); static bool config_get_report_desc (uint8_t dev_addr, tusb_control_request_t const * request, xfer_result_t result); static bool config_get_report_desc_complete (uint8_t dev_addr, tusb_control_request_t const * request, xfer_result_t result); @@ -286,7 +286,8 @@ uint16_t hidh_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const hid_itf->report_desc_type = desc_hid->bReportType; hid_itf->report_desc_len = tu_unaligned_read16(&desc_hid->wReportLength); - hid_itf->protocol_mode = HID_PROTOCOL_REPORT; // Per Specs: default is report mode + // Per HID Specs: default is Report protocol, though we will force Boot protocol when set_config + hid_itf->protocol_mode = HID_PROTOCOL_BOOT; if ( HID_SUBCLASS_BOOT == desc_itf->bInterfaceSubClass ) hid_itf->itf_protocol = desc_itf->bInterfaceProtocol; drv_len += desc_itf->bNumEndpoints*sizeof(tusb_desc_endpoint_t); @@ -318,42 +319,44 @@ bool hidh_set_config(uint8_t dev_addr, uint8_t itf_num) .wLength = 0 }; - TU_ASSERT( tuh_control_xfer(dev_addr, &request, NULL, (hid_itf->itf_protocol != HID_ITF_PROTOCOL_NONE) ? config_get_protocol : config_get_report_desc) ); + TU_ASSERT( tuh_control_xfer(dev_addr, &request, NULL, (hid_itf->itf_protocol != HID_ITF_PROTOCOL_NONE) ? config_set_protocol : config_get_report_desc) ); return true; } -static bool config_get_protocol(uint8_t dev_addr, tusb_control_request_t const * request, xfer_result_t result) +// Force device to work in BOOT protocol +static bool config_set_protocol(uint8_t dev_addr, tusb_control_request_t const * request, xfer_result_t result) { - // Stall is a valid response for SET_IDLE GET_PROTOCOL, therefore we could ignore its result + // Stall is a valid response for SET_PROTOCOL, therefore we could ignore its result (void) result; uint8_t const itf_num = (uint8_t) request->wIndex; uint8_t const instance = get_instance_id_by_itfnum(dev_addr, itf_num); hidh_interface_t* hid_itf = get_instance(dev_addr, instance); - TU_LOG2("HID Get Protocol\r\n"); + TU_LOG2("HID Set Protocol\r\n"); + hid_itf->protocol_mode = HID_PROTOCOL_BOOT; tusb_control_request_t const new_request = { .bmRequestType_bit = { .recipient = TUSB_REQ_RCPT_INTERFACE, .type = TUSB_REQ_TYPE_CLASS, - .direction = TUSB_DIR_IN + .direction = TUSB_DIR_OUT }, - .bRequest = HID_REQ_CONTROL_GET_PROTOCOL, - .wValue = 0, + .bRequest = HID_REQ_CONTROL_SET_PROTOCOL, + .wValue = HID_PROTOCOL_BOOT, .wIndex = hid_itf->itf_num, .wLength = 1 }; - TU_ASSERT( tuh_control_xfer(dev_addr, &new_request, &hid_itf->protocol_mode, config_get_report_desc) ); + TU_ASSERT( tuh_control_xfer(dev_addr, &new_request, NULL, config_get_report_desc) ); return false; } static bool config_get_report_desc(uint8_t dev_addr, tusb_control_request_t const * request, xfer_result_t result) { - // Stall is a valid response for SET_IDLE GET_PROTOCOL, therefore we could ignore its result + // Stall is a valid response for SET_IDLE, therefore we could ignore its result (void) result; uint8_t const itf_num = (uint8_t) request->wIndex; diff --git a/src/class/hid/hid_host.h b/src/class/hid/hid_host.h index 6ae7c6721..b95f0d9b7 100644 --- a/src/class/hid/hid_host.h +++ b/src/class/hid/hid_host.h @@ -66,9 +66,9 @@ bool tuh_hid_mounted(uint8_t dev_addr, uint8_t instance); // Get interface supported protocol (bInterfaceProtocol) check out hid_interface_protocol_enum_t for possible values uint8_t tuh_hid_interface_protocol(uint8_t dev_addr, uint8_t instance); -// Get current active protocol: HID_PROTOCOL_BOOT (0) or HID_PROTOCOL_REPORT (1) -// Note: as HID spec, device will be initialized in Report mode -bool tuh_hid_get_protocol(uint8_t dev_addr, uint8_t instance); +// Get current protocol: HID_PROTOCOL_BOOT (0) or HID_PROTOCOL_REPORT (1) +// Note: device will be initialized in Boot protocol for simplicity. +uint8_t tuh_hid_get_protocol(uint8_t dev_addr, uint8_t instance); // Set protocol to HID_PROTOCOL_BOOT (0) or HID_PROTOCOL_REPORT (1) // This function is only supported by Boot interface (tuh_n_hid_interface_protocol() != NONE) -- cgit v1.3.1 From 58d3e8c08b05ac00bd2510c04f7679b5f7503404 Mon Sep 17 00:00:00 2001 From: hathach Date: Thu, 17 Jun 2021 12:47:48 +0700 Subject: update func comment --- src/class/hid/hid_host.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/class') diff --git a/src/class/hid/hid_host.h b/src/class/hid/hid_host.h index b95f0d9b7..ef203123d 100644 --- a/src/class/hid/hid_host.h +++ b/src/class/hid/hid_host.h @@ -67,7 +67,8 @@ bool tuh_hid_mounted(uint8_t dev_addr, uint8_t instance); uint8_t tuh_hid_interface_protocol(uint8_t dev_addr, uint8_t instance); // Get current protocol: HID_PROTOCOL_BOOT (0) or HID_PROTOCOL_REPORT (1) -// Note: device will be initialized in Boot protocol for simplicity. +// Note: Device will be initialized in Boot protocol for simplicity. +// Application can use set_protocol() to switch back to Report protocol. uint8_t tuh_hid_get_protocol(uint8_t dev_addr, uint8_t instance); // Set protocol to HID_PROTOCOL_BOOT (0) or HID_PROTOCOL_REPORT (1) -- cgit v1.3.1 From 268dcc8d20da15e64ba7198f0412f758f6b8a911 Mon Sep 17 00:00:00 2001 From: hathach Date: Thu, 17 Jun 2021 13:05:12 +0700 Subject: fix issue with weird msc device with 3 endpoints --- src/class/msc/msc_host.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/class') diff --git a/src/class/msc/msc_host.c b/src/class/msc/msc_host.c index 83cbe7c89..2c027deff 100644 --- a/src/class/msc/msc_host.c +++ b/src/class/msc/msc_host.c @@ -366,7 +366,7 @@ uint16_t msch_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const MSC_PROTOCOL_BOT == desc_itf->bInterfaceProtocol); // msc driver length is fixed - uint16_t const drv_len = sizeof(tusb_desc_interface_t) + 2*sizeof(tusb_desc_endpoint_t); + uint16_t const drv_len = sizeof(tusb_desc_interface_t) + desc_itf->bNumEndpoints*sizeof(tusb_desc_endpoint_t); TU_ASSERT(drv_len <= max_len, 0); msch_interface_t* p_msc = get_itf(dev_addr); -- cgit v1.3.1 From efc12ae7d4e2c3d6834203aff5dd1178ed601288 Mon Sep 17 00:00:00 2001 From: hathach Date: Mon, 28 Jun 2021 23:57:57 +0700 Subject: fix SET_PROTOCOl, update hid host behavior for default boot interface --- examples/host/cdc_msc_hid/src/hid_app.c | 166 +++++++++++++++++++------------- src/class/hid/hid_host.c | 12 ++- 2 files changed, 108 insertions(+), 70 deletions(-) (limited to 'src/class') diff --git a/examples/host/cdc_msc_hid/src/hid_app.c b/examples/host/cdc_msc_hid/src/hid_app.c index 817646dab..fd00cf653 100644 --- a/examples/host/cdc_msc_hid/src/hid_app.c +++ b/examples/host/cdc_msc_hid/src/hid_app.c @@ -39,11 +39,15 @@ static uint8_t const keycode2ascii[128][2] = { HID_KEYCODE_TO_ASCII }; // Each HID instance can has multiple reports -static uint8_t _report_count[CFG_TUH_HID]; -static tuh_hid_report_info_t _report_info_arr[CFG_TUH_HID][MAX_REPORT]; +static struct +{ + uint8_t report_count; + tuh_hid_report_info_t report_info[MAX_REPORT]; +}hid_info[CFG_TUH_HID]; static void process_kbd_report(hid_keyboard_report_t const *report); static void process_mouse_report(hid_mouse_report_t const * report); +static void process_generic_report(uint8_t dev_addr, uint8_t instance, uint8_t const* report, uint16_t len); void hid_app_task(void) { @@ -61,13 +65,19 @@ void tuh_hid_mount_cb(uint8_t dev_addr, uint8_t instance, uint8_t const* desc_re { printf("HID device address = %d, instance = %d is mounted\r\n", dev_addr, instance); - // Interface protocol - const char* protocol_str[] = { "None", "Keyboard", "Mouse" }; // hid_protocol_type_t - uint8_t const interface_protocol = tuh_hid_interface_protocol(dev_addr, instance); + // Interface protocol (hid_interface_protocol_enum_t) + const char* protocol_str[] = { "None", "Keyboard", "Mouse" }; + uint8_t const itf_protocol = tuh_hid_interface_protocol(dev_addr, instance); + + printf("HID Interface Protocol = %s\r\n", protocol_str[itf_protocol]); - // Parse report descriptor with built-in parser - _report_count[instance] = tuh_hid_parse_report_descriptor(_report_info_arr[instance], MAX_REPORT, desc_report, desc_len); - printf("HID has %u reports and interface protocol = %s\r\n", _report_count[instance], protocol_str[interface_protocol]); + // By default host stack will use activate boot protocol on supported interface. + // Therefore for this simple example, we only need to parse generic report descriptor (with built-in parser) + if ( itf_protocol == HID_ITF_PROTOCOL_NONE ) + { + hid_info[instance].report_count = tuh_hid_parse_report_descriptor(hid_info[instance].report_info, MAX_REPORT, desc_report, desc_len); + printf("HID has %u reports \r\n", hid_info[instance].report_count); + } } // Invoked when device with hid interface is un-mounted @@ -79,66 +89,24 @@ void tuh_hid_umount_cb(uint8_t dev_addr, uint8_t instance) // Invoked when received report from device via interrupt endpoint void tuh_hid_report_received_cb(uint8_t dev_addr, uint8_t instance, uint8_t const* report, uint16_t len) { - (void) dev_addr; + uint8_t const itf_protocol = tuh_hid_interface_protocol(dev_addr, instance); - uint8_t const rpt_count = _report_count[instance]; - tuh_hid_report_info_t* rpt_info_arr = _report_info_arr[instance]; - tuh_hid_report_info_t* rpt_info = NULL; - - if ( rpt_count == 1 && rpt_info_arr[0].report_id == 0) - { - // Simple report without report ID as 1st byte - rpt_info = &rpt_info_arr[0]; - }else + switch (itf_protocol) { - // Composite report, 1st byte is report ID, data starts from 2nd byte - uint8_t const rpt_id = report[0]; - - // Find report id in the arrray - for(uint8_t i=0; iusage_page == HID_USAGE_PAGE_DESKTOP ) - { - switch (rpt_info->usage) - { - case HID_USAGE_DESKTOP_KEYBOARD: - TU_LOG1("HID receive keyboard report\r\n"); - // Assume keyboard follow boot report layout - process_kbd_report( (hid_keyboard_report_t const*) report ); - break; - - case HID_USAGE_DESKTOP_MOUSE: - TU_LOG1("HID receive mouse report\r\n"); - // Assume mouse follow boot report layout - process_mouse_report( (hid_mouse_report_t const*) report ); - break; - - default: break; - } + case HID_ITF_PROTOCOL_KEYBOARD: + TU_LOG2("HID receive boot keyboard report\r\n"); + process_kbd_report( (hid_keyboard_report_t const*) report ); + break; + + case HID_ITF_PROTOCOL_MOUSE: + TU_LOG2("HID receive boot mouse report\r\n"); + process_mouse_report( (hid_mouse_report_t const*) report ); + break; + + default: + // Generic report requires matching ReportID and contents with previous parsed report info + process_generic_report(dev_addr, instance, report, len); + break; } } @@ -243,3 +211,69 @@ static void process_mouse_report(hid_mouse_report_t const * report) //------------- cursor movement -------------// cursor_movement(report->x, report->y, report->wheel); } + +//--------------------------------------------------------------------+ +// Generic Report +//--------------------------------------------------------------------+ +static void process_generic_report(uint8_t dev_addr, uint8_t instance, uint8_t const* report, uint16_t len) +{ + uint8_t const rpt_count = hid_info[instance].report_count; + tuh_hid_report_info_t* rpt_info_arr = hid_info[instance].report_info; + tuh_hid_report_info_t* rpt_info = NULL; + + if ( rpt_count == 1 && rpt_info_arr[0].report_id == 0) + { + // Simple report without report ID as 1st byte + rpt_info = &rpt_info_arr[0]; + }else + { + // Composite report, 1st byte is report ID, data starts from 2nd byte + uint8_t const rpt_id = report[0]; + + // Find report id in the arrray + for(uint8_t i=0; iusage_page == HID_USAGE_PAGE_DESKTOP ) + { + switch (rpt_info->usage) + { + case HID_USAGE_DESKTOP_KEYBOARD: + TU_LOG1("HID receive keyboard report\r\n"); + // Assume keyboard follow boot report layout + process_kbd_report( (hid_keyboard_report_t const*) report ); + break; + + case HID_USAGE_DESKTOP_MOUSE: + TU_LOG1("HID receive mouse report\r\n"); + // Assume mouse follow boot report layout + process_mouse_report( (hid_mouse_report_t const*) report ); + break; + + default: break; + } + } +} diff --git a/src/class/hid/hid_host.c b/src/class/hid/hid_host.c index 59fbb097e..091c5c1c4 100644 --- a/src/class/hid/hid_host.c +++ b/src/class/hid/hid_host.c @@ -327,7 +327,7 @@ bool hidh_set_config(uint8_t dev_addr, uint8_t itf_num) // Force device to work in BOOT protocol static bool config_set_protocol(uint8_t dev_addr, tusb_control_request_t const * request, xfer_result_t result) { - // Stall is a valid response for SET_PROTOCOL, therefore we could ignore its result + // Stall is a valid response for SET_IDLE, therefore we could ignore its result (void) result; uint8_t const itf_num = (uint8_t) request->wIndex; @@ -347,7 +347,7 @@ static bool config_set_protocol(uint8_t dev_addr, tusb_control_request_t const * .bRequest = HID_REQ_CONTROL_SET_PROTOCOL, .wValue = HID_PROTOCOL_BOOT, .wIndex = hid_itf->itf_num, - .wLength = 1 + .wLength = 0 }; TU_ASSERT( tuh_control_xfer(dev_addr, &new_request, NULL, config_get_report_desc) ); @@ -356,8 +356,12 @@ static bool config_set_protocol(uint8_t dev_addr, tusb_control_request_t const * static bool config_get_report_desc(uint8_t dev_addr, tusb_control_request_t const * request, xfer_result_t result) { - // Stall is a valid response for SET_IDLE, therefore we could ignore its result - (void) result; + // We can be here after SET_IDLE or SET_PROTOCOL (boot device) + // Trigger assert if result is not successful with set protocol + if ( request->bRequest != HID_REQ_CONTROL_SET_IDLE ) + { + TU_ASSERT(result == XFER_RESULT_SUCCESS); + } uint8_t const itf_num = (uint8_t) request->wIndex; uint8_t const instance = get_instance_id_by_itfnum(dev_addr, itf_num); -- cgit v1.3.1 From c172caa288213535ed5c59cea2c13d0e5b4a0597 Mon Sep 17 00:00:00 2001 From: hathach Date: Tue, 29 Jun 2021 00:03:34 +0700 Subject: clean up --- src/class/hid/hid_host.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/class') diff --git a/src/class/hid/hid_host.c b/src/class/hid/hid_host.c index 091c5c1c4..40b6f5631 100644 --- a/src/class/hid/hid_host.c +++ b/src/class/hid/hid_host.c @@ -351,7 +351,7 @@ static bool config_set_protocol(uint8_t dev_addr, tusb_control_request_t const * }; TU_ASSERT( tuh_control_xfer(dev_addr, &new_request, NULL, config_get_report_desc) ); - return false; + return true; } static bool config_get_report_desc(uint8_t dev_addr, tusb_control_request_t const * request, xfer_result_t result) -- cgit v1.3.1 From 5877f20d4b5d54b2dfe310fedddf1c30fe6dc66c Mon Sep 17 00:00:00 2001 From: MasterPhi Date: Tue, 29 Jun 2021 10:57:26 +0200 Subject: Fix IAR compile error on pointer type. Clean up warnings. Signed-off-by: MasterPhi --- src/class/audio/audio_device.c | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) (limited to 'src/class') diff --git a/src/class/audio/audio_device.c b/src/class/audio/audio_device.c index 7ad7edf9e..7263958df 100644 --- a/src/class/audio/audio_device.c +++ b/src/class/audio/audio_device.c @@ -885,7 +885,7 @@ range [-1, +1) * */ // Helper function -static inline uint8_t * audiod_interleaved_copy_bytes_fast_encode(uint16_t const nBytesToCopy, void * src, uint8_t * src_end, uint8_t * dst, uint8_t const n_ff_used) +static inline uint8_t * audiod_interleaved_copy_bytes_fast_encode(uint16_t const nBytesToCopy, uint8_t * src, uint8_t * src_end, uint8_t * dst, uint8_t const n_ff_used) { // Optimize for fast half word copies typedef struct{ @@ -900,15 +900,15 @@ static inline uint8_t * audiod_interleaved_copy_bytes_fast_encode(uint16_t const switch (nBytesToCopy) { case 1: - while((uint8_t *)src < src_end) + while(src < src_end) { - *dst = *(uint8_t *)src++; + *dst = *src++; dst += n_ff_used; } break; case 2: - while((uint8_t *)src < src_end) + while(src < src_end) { *(unaligned_uint16_t*)dst = *(unaligned_uint16_t*)src; src += 2; @@ -917,23 +917,23 @@ static inline uint8_t * audiod_interleaved_copy_bytes_fast_encode(uint16_t const break; case 3: - while((uint8_t *)src < src_end) + while(src < src_end) { // memcpy(dst, src, 3); // src = (uint8_t *)src + 3; // dst += 3 * n_ff_used; // TODO: Is there a faster way to copy 3 bytes? - *dst++ = *(uint8_t *)src++; - *dst++ = *(uint8_t *)src++; - *dst++ = *(uint8_t *)src++; + *dst++ = *src++; + *dst++ = *src++; + *dst++ = *src++; dst += 3 * (n_ff_used - 1); } break; case 4: - while((uint8_t *)src < src_end) + while(src < src_end) { *(unaligned_uint32_t*)dst = *(unaligned_uint32_t*)src; src += 4; @@ -993,7 +993,7 @@ static uint16_t audiod_encode_type_I_pcm(uint8_t rhport, audiod_function_t* audi if (info.len_lin != 0) { info.len_lin = tu_min16(nBytesPerFFToSend, info.len_lin); // Limit up to desired length - src_end = info.ptr_lin + info.len_lin; + src_end = (uint8_t *)info.ptr_lin + info.len_lin; dst = audiod_interleaved_copy_bytes_fast_encode(nBytesToCopy, info.ptr_lin, src_end, dst, n_ff_used); // Limit up to desired length @@ -1002,7 +1002,7 @@ static uint16_t audiod_encode_type_I_pcm(uint8_t rhport, audiod_function_t* audi // Handle wrapped part of FIFO if (info.len_wrap != 0) { - src_end = info.ptr_wrap + info.len_wrap; + src_end = (uint8_t *)info.ptr_wrap + info.len_wrap; audiod_interleaved_copy_bytes_fast_encode(nBytesToCopy, info.ptr_wrap, src_end, dst, n_ff_used); } @@ -1956,7 +1956,7 @@ bool tud_audio_buffer_and_schedule_control_xfer(uint8_t rhport, tusb_control_req } break; - case TUSB_REQ_RCPT_ENDPOINT: ; // The semicolon is there to enable a declaration right after the label + case TUSB_REQ_RCPT_ENDPOINT: { uint8_t ep = TU_U16_LOW(p_request->wIndex); @@ -2142,10 +2142,10 @@ static void audiod_parse_for_AS_params(audiod_function_t* audio, uint8_t const * if (as_itf == audio->ep_in_as_intf_num) { audio->n_channels_tx = ((audio_desc_cs_as_interface_t const * )p_desc)->bNrChannels; - audio->format_type_tx = ((audio_desc_cs_as_interface_t const * )p_desc)->bFormatType; + audio->format_type_tx = (audio_format_type_t)(((audio_desc_cs_as_interface_t const * )p_desc)->bFormatType); #if CFG_TUD_AUDIO_ENABLE_TYPE_I_ENCODING - audio->format_type_I_tx = ((audio_desc_cs_as_interface_t const * )p_desc)->bmFormats; + audio->format_type_I_tx = (audio_data_format_type_I_t)(((audio_desc_cs_as_interface_t const * )p_desc)->bmFormats); #endif } #endif -- cgit v1.3.1 From ca98996e1f9ac802c60d9da4c28ab0e16ca640d6 Mon Sep 17 00:00:00 2001 From: hathach Date: Thu, 1 Jul 2021 22:46:39 +0700 Subject: better support for hid device set/get protocol add caplock detection for hid_composite --- examples/device/hid_composite/src/main.c | 31 ++++++++++++++--- hw/bsp/board.c | 58 +++++++++++++++++++++++++++++--- hw/bsp/board.h | 9 +++-- src/class/hid/hid_device.c | 28 +++++++++++++-- src/device/usbd.c | 2 +- src/device/usbd_control.c | 1 + 6 files changed, 115 insertions(+), 14 deletions(-) (limited to 'src/class') diff --git a/examples/device/hid_composite/src/main.c b/examples/device/hid_composite/src/main.c index 512f6f9d9..6ddad5aae 100644 --- a/examples/device/hid_composite/src/main.c +++ b/examples/device/hid_composite/src/main.c @@ -255,12 +255,30 @@ uint16_t tud_hid_get_report_cb(uint8_t itf, uint8_t report_id, hid_report_type_t // received data on OUT endpoint ( Report ID = 0, Type = 0 ) void tud_hid_set_report_cb(uint8_t itf, uint8_t report_id, hid_report_type_t report_type, uint8_t const* buffer, uint16_t bufsize) { - // TODO set LED based on CAPLOCK, NUMLOCK etc... (void) itf; - (void) report_id; - (void) report_type; - (void) buffer; - (void) bufsize; + + if (report_type == HID_REPORT_TYPE_OUTPUT) + { + // Set keyboard LED e.g Capslock, Numlock etc... + if (report_id == REPORT_ID_KEYBOARD) + { + // bufsize should be (at least) 1 + if ( bufsize < 1 ) return; + + uint8_t const kbd_leds = buffer[0]; + + if (kbd_leds & KEYBOARD_LED_CAPSLOCK) + { + // Capslock On: disable blink, turn led on + blink_interval_ms = 0; + board_led_write(true); + }else + { + // Caplocks Off: back to normal link + blink_interval_ms = BLINK_MOUNTED; + } + } + } } //--------------------------------------------------------------------+ @@ -271,6 +289,9 @@ void led_blinking_task(void) static uint32_t start_ms = 0; static bool led_state = false; + // blink is disabled + if (!blink_interval_ms) return; + // Blink every interval ms if ( board_millis() - start_ms < blink_interval_ms) return; // not enough time start_ms += blink_interval_ms; diff --git a/hw/bsp/board.c b/hw/bsp/board.c index 383a02ef4..c21c9e976 100644 --- a/hw/bsp/board.c +++ b/hw/bsp/board.c @@ -25,6 +25,60 @@ #include "board.h" +#if 0 +#define LED_PHASE_MAX 8 + +static struct +{ + uint32_t phase[LED_PHASE_MAX]; + uint8_t phase_count; + + bool led_state; + uint8_t current_phase; + uint32_t current_ms; +}led_pattern; + +void board_led_pattern(uint32_t const phase_ms[], uint8_t count) +{ + memcpy(led_pattern.phase, phase_ms, 4*count); + led_pattern.phase_count = count; + + // reset with 1st phase is on + led_pattern.current_ms = board_millis(); + led_pattern.current_phase = 0; + led_pattern.led_state = true; + board_led_on(); +} + +void board_led_task(void) +{ + if ( led_pattern.phase_count == 0 ) return; + + uint32_t const duration = led_pattern.phase[led_pattern.current_phase]; + + // return if not enough time + if (board_millis() - led_pattern.current_ms < duration) return; + + led_pattern.led_state = !led_pattern.led_state; + board_led_write(led_pattern.led_state); + + led_pattern.current_ms += duration; + led_pattern.current_phase++; + + if (led_pattern.current_phase == led_pattern.phase_count) + { + led_pattern.current_phase = 0; + led_pattern.led_state = true; + board_led_on(); + } +} + +#endif + +//--------------------------------------------------------------------+ +// newlib read()/write() retarget +//--------------------------------------------------------------------+ + #if defined(__MSP430__) #define sys_write write #define sys_read read @@ -33,10 +87,6 @@ #define sys_read _read #endif -//--------------------------------------------------------------------+ -// newlib read()/write() retarget -//--------------------------------------------------------------------+ - #if defined(LOGGER_RTT) // Logging with RTT diff --git a/hw/bsp/board.h b/hw/bsp/board.h index 7b77def50..782e0939c 100644 --- a/hw/bsp/board.h +++ b/hw/bsp/board.h @@ -54,6 +54,10 @@ void board_init(void); // Turn LED on or off void board_led_write(bool state); +// Control led pattern using phase duration in ms. +// For each phase, LED is toggle then repeated, board_led_task() is required to be called +//void board_led_pattern(uint32_t const phase_ms[], uint8_t count); + // Get the current state of button // a '1' means active (pressed), a '0' means inactive. uint32_t board_button_read(void); @@ -81,11 +85,12 @@ int board_uart_write(void const * buf, int len); } #elif CFG_TUSB_OS == OPT_OS_PICO -#include "pico/time.h" -static inline uint32_t board_millis(void) + #include "pico/time.h" + static inline uint32_t board_millis(void) { return to_ms_since_boot(get_absolute_time()); } + #elif CFG_TUSB_OS == OPT_OS_RTTHREAD static inline uint32_t board_millis(void) { diff --git a/src/class/hid/hid_device.c b/src/class/hid/hid_device.c index e44f282c4..65c7d1a18 100644 --- a/src/class/hid/hid_device.c +++ b/src/class/hid/hid_device.c @@ -280,7 +280,21 @@ bool hidd_control_xfer_cb (uint8_t rhport, uint8_t stage, tusb_control_request_t uint8_t const report_type = tu_u16_high(request->wValue); uint8_t const report_id = tu_u16_low(request->wValue); - uint16_t xferlen = tud_hid_get_report_cb(hid_itf, report_id, (hid_report_type_t) report_type, p_hid->epin_buf, request->wLength); + uint8_t* report_buf = p_hid->epin_buf; + uint16_t req_len = request->wLength; + + uint16_t xferlen = 0; + + // If host request a specific Report ID, add ID to as 1 byte of response + if ( (report_id != HID_REPORT_TYPE_INVALID) && (req_len > 1) ) + { + *report_buf++ = report_id; + req_len--; + + xferlen++; + } + + xferlen += tud_hid_get_report_cb(hid_itf, report_id, (hid_report_type_t) report_type, report_buf, req_len); TU_ASSERT( xferlen > 0 ); tud_control_xfer(rhport, request, p_hid->epin_buf, xferlen); @@ -298,7 +312,17 @@ bool hidd_control_xfer_cb (uint8_t rhport, uint8_t stage, tusb_control_request_t uint8_t const report_type = tu_u16_high(request->wValue); uint8_t const report_id = tu_u16_low(request->wValue); - tud_hid_set_report_cb(hid_itf, report_id, (hid_report_type_t) report_type, p_hid->epout_buf, request->wLength); + uint8_t const* report_buf = p_hid->epout_buf; + uint16_t report_len = request->wLength; + + // If host request a specific Report ID, extract report ID in buffer before invoking callback + if ( (report_id != HID_REPORT_TYPE_INVALID) && (report_len > 1) && (report_id == p_hid->epout_buf[0]) ) + { + report_buf++; + report_len--; + } + + tud_hid_set_report_cb(hid_itf, report_id, (hid_report_type_t) report_type, report_buf, report_len); } break; diff --git a/src/device/usbd.c b/src/device/usbd.c index 587d487dc..af4fd58c4 100644 --- a/src/device/usbd.c +++ b/src/device/usbd.c @@ -1243,7 +1243,7 @@ bool usbd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t uint8_t const epnum = tu_edpt_number(ep_addr); uint8_t const dir = tu_edpt_dir(ep_addr); - TU_LOG2(" Queue EP %02X with %u bytes ... ", ep_addr, total_bytes); + TU_LOG2(" Queue EP %02X with %u bytes ...\r\n", ep_addr, total_bytes); // Attempt to transfer on a busy endpoint, sound like an race condition ! TU_ASSERT(_usbd_dev.ep_status[epnum][dir].busy == 0); diff --git a/src/device/usbd_control.c b/src/device/usbd_control.c index 724c652e6..7a8244699 100644 --- a/src/device/usbd_control.c +++ b/src/device/usbd_control.c @@ -186,6 +186,7 @@ bool usbd_control_xfer_cb (uint8_t rhport, uint8_t ep_addr, xfer_result_t result { TU_VERIFY(_ctrl_xfer.buffer); memcpy(_ctrl_xfer.buffer, _usbd_ctrl_buf, xferred_bytes); + TU_LOG_MEM(2, _usbd_ctrl_buf, xferred_bytes, 2); } _ctrl_xfer.total_xferred += xferred_bytes; -- cgit v1.3.1 From 2b3d547b7bccf46c6a274c75cb1769532611c5bf Mon Sep 17 00:00:00 2001 From: hathach Date: Thu, 1 Jul 2021 23:05:21 +0700 Subject: clean up --- src/class/hid/hid_device.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/class') diff --git a/src/class/hid/hid_device.c b/src/class/hid/hid_device.c index 65c7d1a18..a10e3a5e3 100644 --- a/src/class/hid/hid_device.c +++ b/src/class/hid/hid_device.c @@ -316,7 +316,7 @@ bool hidd_control_xfer_cb (uint8_t rhport, uint8_t stage, tusb_control_request_t uint16_t report_len = request->wLength; // If host request a specific Report ID, extract report ID in buffer before invoking callback - if ( (report_id != HID_REPORT_TYPE_INVALID) && (report_len > 1) && (report_id == p_hid->epout_buf[0]) ) + if ( (report_id != HID_REPORT_TYPE_INVALID) && (report_len > 1) && (report_id == report_buf[0]) ) { report_buf++; report_len--; -- cgit v1.3.1 From 6e9da70c18a0dbabaedb1c9aadcc9fe53a0113a7 Mon Sep 17 00:00:00 2001 From: MasterPhi Date: Tue, 29 Jun 2021 22:40:21 +0200 Subject: Fix audiod_get_AS_interface_index in audio class. Enhance uac2_headset example with multiple sample rates. Add macro to calculate EP size. --- examples/device/uac2_headset/src/main.c | 69 ++++++++++++++++------ examples/device/uac2_headset/src/tusb_config.h | 13 ++-- examples/device/uac2_headset/src/usb_descriptors.c | 2 +- examples/device/uac2_headset/src/usb_descriptors.h | 8 +-- src/class/audio/audio_device.c | 16 ++--- src/device/usbd.h | 5 ++ 6 files changed, 77 insertions(+), 36 deletions(-) (limited to 'src/class') diff --git a/examples/device/uac2_headset/src/main.c b/examples/device/uac2_headset/src/main.c index 1b6a770a3..e76b081c8 100644 --- a/examples/device/uac2_headset/src/main.c +++ b/examples/device/uac2_headset/src/main.c @@ -34,9 +34,11 @@ // MACRO CONSTANT TYPEDEF PROTOTYPES //--------------------------------------------------------------------+ -#ifndef AUDIO_SAMPLE_RATE -#define AUDIO_SAMPLE_RATE 48000 -#endif +// List of supported sample rates +const uint32_t sample_rates[] = {44100, 48000, 88200, 96000}; +uint32_t current_sample_rate = 44100; + +#define N_SAMPLE_RATES (sizeof(sample_rates) / 4) /* Blink pattern * - 25 ms : streaming data @@ -166,24 +168,30 @@ static bool tud_audio_clock_get_request(uint8_t rhport, audio_control_request_t { TU_ASSERT(request->bEntityID == UAC2_ENTITY_CLOCK); - // Example supports only single frequency, same value will be used for current value and range if (request->bControlSelector == AUDIO_CS_CTRL_SAM_FREQ) { if (request->bRequest == AUDIO_CS_REQ_CUR) { - TU_LOG2("Clock get current freq %u\r\n", AUDIO_SAMPLE_RATE); + TU_LOG1("Clock get current freq %u\r\n", current_sample_rate); - audio_control_cur_4_t curf = { tu_htole32(AUDIO_SAMPLE_RATE) }; + audio_control_cur_4_t curf = { tu_htole32(current_sample_rate) }; return tud_audio_buffer_and_schedule_control_xfer(rhport, (tusb_control_request_t const *)request, &curf, sizeof(curf)); } else if (request->bRequest == AUDIO_CS_REQ_RANGE) { - audio_control_range_4_n_t(1) rangef = + audio_control_range_4_n_t(N_SAMPLE_RATES) rangef = { - .wNumSubRanges = tu_htole16(1), - .subrange[0] = { tu_htole32(AUDIO_SAMPLE_RATE), tu_htole32(AUDIO_SAMPLE_RATE), 0} + .wNumSubRanges = tu_htole16(N_SAMPLE_RATES) }; - TU_LOG2("Clock get freq range (%d, %d, %d)\r\n", (int)rangef.subrange[0].bMin, (int)rangef.subrange[0].bMax, (int)rangef.subrange[0].bRes); + TU_LOG1("Clock get %d freq ranges\r\n", N_SAMPLE_RATES); + for(uint8_t i = 0; i < N_SAMPLE_RATES; i++) + { + rangef.subrange[i].bMin = sample_rates[i]; + rangef.subrange[i].bMax = sample_rates[i]; + rangef.subrange[i].bRes = 0; + TU_LOG1("Range %d (%d, %d, %d)\r\n", i, (int)rangef.subrange[i].bMin, (int)rangef.subrange[i].bMax, (int)rangef.subrange[i].bRes); + } + return tud_audio_buffer_and_schedule_control_xfer(rhport, (tusb_control_request_t const *)request, &rangef, sizeof(rangef)); } } @@ -191,7 +199,7 @@ static bool tud_audio_clock_get_request(uint8_t rhport, audio_control_request_t request->bRequest == AUDIO_CS_REQ_CUR) { audio_control_cur_1_t cur_valid = { .bCur = 1 }; - TU_LOG2("Clock get is valid %u\r\n", cur_valid.bCur); + TU_LOG1("Clock get is valid %u\r\n", cur_valid.bCur); return tud_audio_buffer_and_schedule_control_xfer(rhport, (tusb_control_request_t const *)request, &cur_valid, sizeof(cur_valid)); } TU_LOG1("Clock get request not supported, entity = %u, selector = %u, request = %u\r\n", @@ -199,6 +207,32 @@ static bool tud_audio_clock_get_request(uint8_t rhport, audio_control_request_t return false; } +// Helper for clock set requests +static bool tud_audio_clock_set_request(uint8_t rhport, audio_control_request_t const *request, uint8_t const *buf) +{ + (void)rhport; + + TU_ASSERT(request->bEntityID == UAC2_ENTITY_SPK_FEATURE_UNIT); + TU_VERIFY(request->bRequest == AUDIO_CS_REQ_CUR); + + if (request->bControlSelector == AUDIO_CS_CTRL_SAM_FREQ) + { + TU_VERIFY(request->wLength == sizeof(audio_control_cur_4_t)); + + current_sample_rate = ((audio_control_cur_4_t *)buf)->bCur; + + TU_LOG1("Clock set current freq: %d\r\n", current_sample_rate); + + return true; + } + else + { + TU_LOG1("Clock set request not supported, entity = %u, selector = %u, request = %u\r\n", + request->bEntityID, request->bControlSelector, request->bRequest); + return false; + } +} + // Helper for feature unit get requests static bool tud_audio_feature_unit_get_request(uint8_t rhport, audio_control_request_t const *request) { @@ -207,7 +241,7 @@ static bool tud_audio_feature_unit_get_request(uint8_t rhport, audio_control_req if (request->bControlSelector == AUDIO_FU_CTRL_MUTE && request->bRequest == AUDIO_CS_REQ_CUR) { audio_control_cur_1_t mute1 = { .bCur = mute[request->bChannelNumber] }; - TU_LOG2("Get channel %u mute %d\r\n", request->bChannelNumber, mute1.bCur); + TU_LOG1("Get channel %u mute %d\r\n", request->bChannelNumber, mute1.bCur); return tud_audio_buffer_and_schedule_control_xfer(rhport, (tusb_control_request_t const *)request, &mute1, sizeof(mute1)); } else if (UAC2_ENTITY_SPK_FEATURE_UNIT && request->bControlSelector == AUDIO_FU_CTRL_VOLUME) @@ -218,14 +252,14 @@ static bool tud_audio_feature_unit_get_request(uint8_t rhport, audio_control_req .wNumSubRanges = tu_htole16(1), .subrange[0] = { .bMin = tu_htole16(-VOLUME_CTRL_50_DB), tu_htole16(VOLUME_CTRL_0_DB), tu_htole16(256) } }; - TU_LOG2("Get channel %u volume range (%d, %d, %u) dB\r\n", request->bChannelNumber, + TU_LOG1("Get channel %u volume range (%d, %d, %u) dB\r\n", request->bChannelNumber, range_vol.subrange[0].bMin / 256, range_vol.subrange[0].bMax / 256, range_vol.subrange[0].bRes / 256); return tud_audio_buffer_and_schedule_control_xfer(rhport, (tusb_control_request_t const *)request, &range_vol, sizeof(range_vol)); } else if (request->bRequest == AUDIO_CS_REQ_CUR) { audio_control_cur_2_t cur_vol = { .bCur = tu_htole16(volume[request->bChannelNumber]) }; - TU_LOG2("Get channel %u volume %u dB\r\n", request->bChannelNumber, cur_vol.bCur); + TU_LOG1("Get channel %u volume %d dB\r\n", request->bChannelNumber, cur_vol.bCur / 256); return tud_audio_buffer_and_schedule_control_xfer(rhport, (tusb_control_request_t const *)request, &cur_vol, sizeof(cur_vol)); } } @@ -249,7 +283,7 @@ static bool tud_audio_feature_unit_set_request(uint8_t rhport, audio_control_req mute[request->bChannelNumber] = ((audio_control_cur_1_t *)buf)->bCur; - TU_LOG2("Set channel %d Mute: %d\r\n", request->bChannelNumber, mute[request->bChannelNumber]); + TU_LOG1("Set channel %d Mute: %d\r\n", request->bChannelNumber, mute[request->bChannelNumber]); return true; } @@ -259,7 +293,7 @@ static bool tud_audio_feature_unit_set_request(uint8_t rhport, audio_control_req volume[request->bChannelNumber] = ((audio_control_cur_2_t const *)buf)->bCur; - TU_LOG2("Set channel %d volume: %d dB\r\n", request->bChannelNumber, volume[request->bChannelNumber] / 256); + TU_LOG1("Set channel %d volume: %d dB\r\n", request->bChannelNumber, volume[request->bChannelNumber] / 256); return true; } @@ -299,7 +333,8 @@ bool tud_audio_set_req_entity_cb(uint8_t rhport, tusb_control_request_t const *p if (request->bEntityID == UAC2_ENTITY_SPK_FEATURE_UNIT) return tud_audio_feature_unit_set_request(rhport, request, buf); - + if (request->bEntityID == UAC2_ENTITY_CLOCK) + return tud_audio_clock_set_request(rhport, request, buf); TU_LOG1("Set request not handled, entity = %d, selector = %d, request = %d\r\n", request->bEntityID, request->bControlSelector, request->bRequest); diff --git a/examples/device/uac2_headset/src/tusb_config.h b/examples/device/uac2_headset/src/tusb_config.h index 88f9efcff..9b7ed337c 100644 --- a/examples/device/uac2_headset/src/tusb_config.h +++ b/examples/device/uac2_headset/src/tusb_config.h @@ -93,13 +93,12 @@ extern "C" { //-------------------------------------------------------------------- // AUDIO CLASS DRIVER CONFIGURATION //-------------------------------------------------------------------- -#define CFG_TUD_AUDIO_IN_PATH (CFG_TUD_AUDIO) -#define CFG_TUD_AUDIO_OUT_PATH (CFG_TUD_AUDIO) //#define CFG_TUD_AUDIO_FUNC_1_DESC_LEN 220 // This equals TUD_AUDIO_HEADSET_STEREO_DESC_LEN, however, including it from usb_descriptors.h is not possible due to some strange include hassle #define CFG_TUD_AUDIO_FUNC_1_DESC_LEN TUD_AUDIO_HEADSET_STEREO_DESC_LEN // Audio format type I specifications +#define CFG_TUD_AUDIO_FUNC_1_N_MAX_SAMPLE_RATE 96000 #define CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX 1 #define CFG_TUD_AUDIO_FUNC_1_N_BYTES_PER_SAMPLE_TX 2 #define CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_RX 2 @@ -108,18 +107,18 @@ extern "C" { // EP and buffer size - for isochronous EP´s, the buffer and EP size are equal (different sizes would not make sense) #define CFG_TUD_AUDIO_ENABLE_EP_IN 1 -#define CFG_TUD_AUDIO_EP_SZ_IN (CFG_TUD_AUDIO_IN_PATH * (48 + 1) * (CFG_TUD_AUDIO_FUNC_1_N_BYTES_PER_SAMPLE_TX) * (CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX)) // 48 Samples (48 kHz) x 2 Bytes/Sample x n Channels +#define CFG_TUD_AUDIO_EP_SZ_IN TUD_AUDIO_EP_SIZE(CFG_TUD_AUDIO_FUNC_1_N_MAX_SAMPLE_RATE, CFG_TUD_AUDIO_FUNC_1_N_BYTES_PER_SAMPLE_TX, CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX) // 48 Samples (48 kHz) x 2 Bytes/Sample x n Channels #define CFG_TUD_AUDIO_FUNC_1_EP_IN_SW_BUF_SZ CFG_TUD_AUDIO_EP_SZ_IN #define CFG_TUD_AUDIO_FUNC_1_EP_IN_SZ_MAX CFG_TUD_AUDIO_EP_SZ_IN // Maximum EP IN size for all AS alternate settings used // EP and buffer size - for isochronous EP´s, the buffer and EP size are equal (different sizes would not make sense) #define CFG_TUD_AUDIO_ENABLE_EP_OUT 1 -#define CFG_TUD_AUDIO_EP_OUT_SZ (CFG_TUD_AUDIO_OUT_PATH * ((48 + CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP) * (CFG_TUD_AUDIO_FUNC_1_N_BYTES_PER_SAMPLE_RX) * (CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_RX))) // N Samples (N kHz) x 2 Bytes/Sample x n Channels -#define CFG_TUD_AUDIO_FUNC_1_EP_OUT_SW_BUF_SZ CFG_TUD_AUDIO_EP_OUT_SZ*3 -#define CFG_TUD_AUDIO_FUNC_1_EP_OUT_SZ_MAX CFG_TUD_AUDIO_EP_OUT_SZ // Maximum EP IN size for all AS alternate settings used +#define CFG_TUD_AUDIO_EP_SZ_OUT TUD_AUDIO_EP_SIZE(CFG_TUD_AUDIO_FUNC_1_N_MAX_SAMPLE_RATE, CFG_TUD_AUDIO_FUNC_1_N_BYTES_PER_SAMPLE_RX, CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_RX) // N Samples (N kHz) x 2 Bytes/Sample x n Channels +#define CFG_TUD_AUDIO_FUNC_1_EP_OUT_SW_BUF_SZ CFG_TUD_AUDIO_EP_SZ_OUT*3 +#define CFG_TUD_AUDIO_FUNC_1_EP_OUT_SZ_MAX CFG_TUD_AUDIO_EP_SZ_OUT // Maximum EP IN size for all AS alternate settings used // Number of Standard AS Interface Descriptors (4.9.1) defined per audio function - this is required to be able to remember the current alternate settings of these interfaces - We restrict us here to have a constant number for all audio functions (which means this has to be the maximum number of AS interfaces an audio function has and a second audio function with less AS interfaces just wastes a few bytes) -#define CFG_TUD_AUDIO_FUNC_1_N_AS_INT 1 +#define CFG_TUD_AUDIO_FUNC_1_N_AS_INT 2 // Size of control request buffer #define CFG_TUD_AUDIO_FUNC_1_CTRL_BUF_SZ 64 diff --git a/examples/device/uac2_headset/src/usb_descriptors.c b/examples/device/uac2_headset/src/usb_descriptors.c index cd749eb65..f5d8e461b 100644 --- a/examples/device/uac2_headset/src/usb_descriptors.c +++ b/examples/device/uac2_headset/src/usb_descriptors.c @@ -93,7 +93,7 @@ uint8_t const desc_configuration[] = TUD_CONFIG_DESCRIPTOR(1, ITF_NUM_TOTAL, 0, CONFIG_TOTAL_LEN, TUSB_DESC_CONFIG_ATT_REMOTE_WAKEUP, 100), // Interface number, string index, EP Out & EP In address, EP size - TUD_AUDIO_HEADSET_STEREO_DESCRIPTOR(2, 2, 16, EPNUM_AUDIO, CFG_TUD_AUDIO_EP_OUT_SZ, EPNUM_AUDIO | 0x80, CFG_TUD_AUDIO_EP_SZ_IN) + TUD_AUDIO_HEADSET_STEREO_DESCRIPTOR(2, 2, 16, EPNUM_AUDIO, CFG_TUD_AUDIO_EP_SZ_OUT, EPNUM_AUDIO | 0x80, CFG_TUD_AUDIO_EP_SZ_IN) }; // Invoked when received GET CONFIGURATION DESCRIPTOR diff --git a/examples/device/uac2_headset/src/usb_descriptors.h b/examples/device/uac2_headset/src/usb_descriptors.h index d9c5a63a7..1595d9c5d 100644 --- a/examples/device/uac2_headset/src/usb_descriptors.h +++ b/examples/device/uac2_headset/src/usb_descriptors.h @@ -77,7 +77,7 @@ enum /* Class-Specific AC Interface Header Descriptor(4.7.2) */\ TUD_AUDIO_DESC_CS_AC(/*_bcdADC*/ 0x0200, /*_category*/ AUDIO_FUNC_HEADSET, /*_totallen*/ TUD_AUDIO_DESC_CLK_SRC_LEN+TUD_AUDIO_DESC_FEATURE_UNIT_TWO_CHANNEL_LEN+TUD_AUDIO_DESC_INPUT_TERM_LEN+TUD_AUDIO_DESC_OUTPUT_TERM_LEN+TUD_AUDIO_DESC_INPUT_TERM_LEN+TUD_AUDIO_DESC_OUTPUT_TERM_LEN, /*_ctrl*/ AUDIO_CS_AS_INTERFACE_CTRL_LATENCY_POS),\ /* Clock Source Descriptor(4.7.2.1) */\ - TUD_AUDIO_DESC_CLK_SRC(/*_clkid*/ UAC2_ENTITY_CLOCK, /*_attr*/ 3, /*_ctrl*/ 5, /*_assocTerm*/ 0x00, /*_stridx*/ 0x00), \ + TUD_AUDIO_DESC_CLK_SRC(/*_clkid*/ UAC2_ENTITY_CLOCK, /*_attr*/ 3, /*_ctrl*/ 7, /*_assocTerm*/ 0x00, /*_stridx*/ 0x00), \ /* Input Terminal Descriptor(4.7.2.4) */\ TUD_AUDIO_DESC_INPUT_TERM(/*_termid*/ UAC2_ENTITY_SPK_INPUT_TERMINAL, /*_termtype*/ AUDIO_TERM_TYPE_USB_STREAMING, /*_assocTerm*/ 0x00, /*_clkid*/ UAC2_ENTITY_CLOCK, /*_nchannelslogical*/ 0x02, /*_channelcfg*/ AUDIO_CHANNEL_CONFIG_NON_PREDEFINED, /*_idxchannelnames*/ 0x00, /*_ctrl*/ 0 * (AUDIO_CTRL_R << AUDIO_IN_TERM_CTRL_CONNECTOR_POS), /*_stridx*/ 0x00),\ /* Feature Unit Descriptor(4.7.2.8) */\ @@ -99,21 +99,21 @@ enum /* Type I Format Type Descriptor(2.3.1.6 - Audio Formats) */\ TUD_AUDIO_DESC_TYPE_I_FORMAT(_nBytesPerSample, _nBitsUsedPerSample),\ /* Standard AS Isochronous Audio Data Endpoint Descriptor(4.10.1.1) */\ - TUD_AUDIO_DESC_STD_AS_ISO_EP(/*_ep*/ _epout, /*_attr*/ (TUSB_XFER_ISOCHRONOUS | TUSB_ISO_EP_ATT_ADAPTIVE | TUSB_ISO_EP_ATT_DATA), /*_maxEPsize*/ _epoutsize, /*_interval*/ (CFG_TUSB_RHPORT0_MODE & OPT_MODE_HIGH_SPEED) ? 0x04 : 0x01),\ + TUD_AUDIO_DESC_STD_AS_ISO_EP(/*_ep*/ _epout, /*_attr*/ (TUSB_XFER_ISOCHRONOUS | TUSB_ISO_EP_ATT_DATA), /*_maxEPsize*/ _epoutsize, /*_interval*/ 0x01),\ /* Class-Specific AS Isochronous Audio Data Endpoint Descriptor(4.10.1.2) */\ TUD_AUDIO_DESC_CS_AS_ISO_EP(/*_attr*/ AUDIO_CS_AS_ISO_DATA_EP_ATT_NON_MAX_PACKETS_OK, /*_ctrl*/ AUDIO_CTRL_NONE, /*_lockdelayunit*/ AUDIO_CS_AS_ISO_DATA_EP_LOCK_DELAY_UNIT_MILLISEC, /*_lockdelay*/ 0x0001),\ /* Standard AS Interface Descriptor(4.9.1) */\ /* Interface 2, Alternate 0 - default alternate setting with 0 bandwidth */\ TUD_AUDIO_DESC_STD_AS_INT(/*_itfnum*/ (uint8_t)(ITF_NUM_AUDIO_STREAMING_MIC), /*_altset*/ 0x00, /*_nEPs*/ 0x00, /*_stridx*/ 0x04),\ /* Standard AS Interface Descriptor(4.9.1) */\ - /* Interface 1, Alternate 1 - alternate interface for data streaming */\ + /* Interface 2, Alternate 1 - alternate interface for data streaming */\ TUD_AUDIO_DESC_STD_AS_INT(/*_itfnum*/ (uint8_t)(ITF_NUM_AUDIO_STREAMING_MIC), /*_altset*/ 0x01, /*_nEPs*/ 0x01, /*_stridx*/ 0x04),\ /* Class-Specific AS Interface Descriptor(4.9.2) */\ TUD_AUDIO_DESC_CS_AS_INT(/*_termid*/ UAC2_ENTITY_MIC_OUTPUT_TERMINAL, /*_ctrl*/ AUDIO_CTRL_NONE, /*_formattype*/ AUDIO_FORMAT_TYPE_I, /*_formats*/ AUDIO_DATA_FORMAT_TYPE_I_PCM, /*_nchannelsphysical*/ 0x01, /*_channelcfg*/ AUDIO_CHANNEL_CONFIG_NON_PREDEFINED, /*_stridx*/ 0x00),\ /* Type I Format Type Descriptor(2.3.1.6 - Audio Formats) */\ TUD_AUDIO_DESC_TYPE_I_FORMAT(_nBytesPerSample, _nBitsUsedPerSample),\ /* Standard AS Isochronous Audio Data Endpoint Descriptor(4.10.1.1) */\ - TUD_AUDIO_DESC_STD_AS_ISO_EP(/*_ep*/ _epin, /*_attr*/ (TUSB_XFER_ISOCHRONOUS | TUSB_ISO_EP_ATT_ASYNCHRONOUS | TUSB_ISO_EP_ATT_DATA), /*_maxEPsize*/ _epinsize, /*_interval*/ (CFG_TUSB_RHPORT0_MODE & OPT_MODE_HIGH_SPEED) ? 0x04 : 0x01),\ + TUD_AUDIO_DESC_STD_AS_ISO_EP(/*_ep*/ _epin, /*_attr*/ (TUSB_XFER_ISOCHRONOUS | TUSB_ISO_EP_ATT_DATA), /*_maxEPsize*/ _epinsize, /*_interval*/ 0x01),\ /* Class-Specific AS Isochronous Audio Data Endpoint Descriptor(4.10.1.2) */\ TUD_AUDIO_DESC_CS_AS_ISO_EP(/*_attr*/ AUDIO_CS_AS_ISO_DATA_EP_ATT_NON_MAX_PACKETS_OK, /*_ctrl*/ AUDIO_CTRL_NONE, /*_lockdelayunit*/ AUDIO_CS_AS_ISO_DATA_EP_LOCK_DELAY_UNIT_UNDEFINED, /*_lockdelay*/ 0x0000)\ diff --git a/src/class/audio/audio_device.c b/src/class/audio/audio_device.c index 7263958df..cb35adb82 100644 --- a/src/class/audio/audio_device.c +++ b/src/class/audio/audio_device.c @@ -1997,15 +1997,17 @@ static bool audiod_get_AS_interface_index(uint8_t itf, audiod_function_t * audio while (p_desc < p_desc_end) { // We assume the number of alternate settings is increasing thus we return the index of alternate setting zero! - if (tu_desc_type(p_desc) == TUSB_DESC_INTERFACE && ((tusb_desc_interface_t const * )p_desc)->bInterfaceNumber == itf) + if (tu_desc_type(p_desc) == TUSB_DESC_INTERFACE && ((tusb_desc_interface_t const * )p_desc)->bAlternateSetting == 0) { - *idxItf = tmp; - *pp_desc_int = p_desc; - return true; + if (((tusb_desc_interface_t const * )p_desc)->bInterfaceNumber == itf) + { + *idxItf = tmp; + *pp_desc_int = p_desc; + return true; + } + // Increase index, bytes read, and pointer + tmp++; } - - // Increase index, bytes read, and pointer - tmp++; p_desc = tu_desc_next(p_desc); } } diff --git a/src/device/usbd.h b/src/device/usbd.h index 3857295d7..45aefe53b 100644 --- a/src/device/usbd.h +++ b/src/device/usbd.h @@ -542,6 +542,11 @@ TU_ATTR_WEAK bool tud_vendor_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb /* Standard AS Isochronous Feedback Endpoint Descriptor(4.10.2.1) */\ TUD_AUDIO_DESC_STD_AS_ISO_FB_EP(/*_ep*/ _epfb, /*_interval*/ 1)\ +// Calculate wMaxPacketSize of Endpoints +#define TUD_AUDIO_EP_SIZE(_maxFrequency, _nBytesPerSample, _nChannels) \ + ((((_maxFrequency + ((CFG_TUSB_RHPORT0_MODE & OPT_MODE_HIGH_SPEED) ? 7999 : 999)) / ((CFG_TUSB_RHPORT0_MODE & OPT_MODE_HIGH_SPEED) ? 8000 : 1000)) + 1) * _nBytesPerSample * _nChannels) + + //------------- TUD_USBTMC/USB488 -------------// #define TUD_USBTMC_APP_CLASS (TUSB_CLASS_APPLICATION_SPECIFIC) #define TUD_USBTMC_APP_SUBCLASS 0x03u -- cgit v1.3.1 From 204f3152cb486b8de3817bf940efd4593c8bfd07 Mon Sep 17 00:00:00 2001 From: MasterPhi Date: Thu, 1 Jul 2021 11:38:06 +0200 Subject: audio_device : clear fifo on intf change. --- src/class/audio/audio_device.c | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'src/class') diff --git a/src/class/audio/audio_device.c b/src/class/audio/audio_device.c index cb35adb82..230b689cd 100644 --- a/src/class/audio/audio_device.c +++ b/src/class/audio/audio_device.c @@ -1481,6 +1481,9 @@ static bool audiod_set_interface(uint8_t rhport, tusb_control_request_t const * audio->ep_in_as_intf_num = 0; usbd_edpt_close(rhport, audio->ep_in); + // Clear FIFOs, since data is no longer valid + tu_fifo_clear(&audio->ep_in_ff); + // Invoke callback - can be used to stop data sampling if (tud_audio_set_itf_close_EP_cb) TU_VERIFY(tud_audio_set_itf_close_EP_cb(rhport, p_request)); @@ -1502,6 +1505,13 @@ static bool audiod_set_interface(uint8_t rhport, tusb_control_request_t const * { audio->ep_out_as_intf_num = 0; usbd_edpt_close(rhport, audio->ep_out); + + // Clear FIFOs, since data is no longer valid + tu_fifo_clear(&audio->ep_out_ff); + + // Invoke callback - can be used to stop data sampling + if (tud_audio_set_itf_close_EP_cb) TU_VERIFY(tud_audio_set_itf_close_EP_cb(rhport, p_request)); + audio->ep_out = 0; // Necessary? // Clear support FIFOs if used -- cgit v1.3.1 From 5f67e5c1e9b10e40ac6e3a649f45f7719b437dc5 Mon Sep 17 00:00:00 2001 From: MasterPhi Date: Thu, 1 Jul 2021 11:45:39 +0200 Subject: Clear FIFO only if enabled... Add buffer align --- examples/device/uac2_headset/src/main.c | 14 +++++++------- examples/device/uac2_headset/src/tusb_config.h | 4 ++-- src/class/audio/audio_device.c | 4 ++++ 3 files changed, 13 insertions(+), 9 deletions(-) (limited to 'src/class') diff --git a/examples/device/uac2_headset/src/main.c b/examples/device/uac2_headset/src/main.c index c9e79a543..f7d20a607 100644 --- a/examples/device/uac2_headset/src/main.c +++ b/examples/device/uac2_headset/src/main.c @@ -78,9 +78,9 @@ int8_t mute[CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX + 1]; // +1 for master chan int16_t volume[CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX + 1]; // +1 for master channel 0 // Buffer for microphone data -uint8_t mic_buf[CFG_TUD_AUDIO_FUNC_1_EP_OUT_SW_BUF_SZ]; +int32_t mic_buf[CFG_TUD_AUDIO_FUNC_1_EP_IN_SW_BUF_SZ / 4]; // Buffer for speaker data -uint8_t spk_buf[CFG_TUD_AUDIO_FUNC_1_EP_OUT_SW_BUF_SZ]; +int32_t spk_buf[CFG_TUD_AUDIO_FUNC_1_EP_OUT_SW_BUF_SZ / 4]; // Speaker data size received in the last frame int spk_data_size; // Resolution per format @@ -430,14 +430,14 @@ void audio_task(void) } else if (current_resolution == 24) { - int32_t *src = (int32_t*)spk_buf; - int32_t *limit = (int32_t*)spk_buf + spk_data_size / 4; - int32_t *dst = (int32_t*)mic_buf; + int32_t *src = spk_buf; + int32_t *limit = spk_buf + spk_data_size / 4; + int32_t *dst = mic_buf; while (src < limit) { // Combine two channels into one - int32_t left = (*src++); - int32_t right = (*src++); + int32_t left = *src++; + int32_t right = *src++; *dst++ = (int32_t)((left + right) / 2) & 0xffffff00; } tud_audio_write((uint8_t *)mic_buf, spk_data_size / 2); diff --git a/examples/device/uac2_headset/src/tusb_config.h b/examples/device/uac2_headset/src/tusb_config.h index 642e52551..d955a746d 100644 --- a/examples/device/uac2_headset/src/tusb_config.h +++ b/examples/device/uac2_headset/src/tusb_config.h @@ -122,7 +122,7 @@ extern "C" { #define CFG_TUD_AUDIO_FUNC_1_FORMAT_1_EP_SZ_IN TUD_AUDIO_EP_SIZE(CFG_TUD_AUDIO_FUNC_1_MAX_SAMPLE_RATE, CFG_TUD_AUDIO_FUNC_1_FORMAT_1_N_BYTES_PER_SAMPLE_TX, CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX) #define CFG_TUD_AUDIO_FUNC_1_FORMAT_2_EP_SZ_IN TUD_AUDIO_EP_SIZE(CFG_TUD_AUDIO_FUNC_1_MAX_SAMPLE_RATE, CFG_TUD_AUDIO_FUNC_1_FORMAT_2_N_BYTES_PER_SAMPLE_TX, CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX) -#define CFG_TUD_AUDIO_FUNC_1_EP_IN_SW_BUF_SZ TU_MAX(CFG_TUD_AUDIO_FUNC_1_FORMAT_1_EP_SZ_IN, CFG_TUD_AUDIO_FUNC_1_FORMAT_2_EP_SZ_IN) +#define CFG_TUD_AUDIO_FUNC_1_EP_IN_SW_BUF_SZ TU_MAX(CFG_TUD_AUDIO_FUNC_1_FORMAT_1_EP_SZ_IN, CFG_TUD_AUDIO_FUNC_1_FORMAT_2_EP_SZ_IN)*2 #define CFG_TUD_AUDIO_FUNC_1_EP_IN_SZ_MAX TU_MAX(CFG_TUD_AUDIO_FUNC_1_FORMAT_1_EP_SZ_IN, CFG_TUD_AUDIO_FUNC_1_FORMAT_2_EP_SZ_IN) // Maximum EP IN size for all AS alternate settings used // EP and buffer size - for isochronous EP´s, the buffer and EP size are equal (different sizes would not make sense) @@ -131,7 +131,7 @@ extern "C" { #define CFG_TUD_AUDIO_UNC_1_FORMAT_1_EP_SZ_OUT TUD_AUDIO_EP_SIZE(CFG_TUD_AUDIO_FUNC_1_MAX_SAMPLE_RATE, CFG_TUD_AUDIO_FUNC_1_FORMAT_1_N_BYTES_PER_SAMPLE_RX, CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_RX) #define CFG_TUD_AUDIO_UNC_1_FORMAT_2_EP_SZ_OUT TUD_AUDIO_EP_SIZE(CFG_TUD_AUDIO_FUNC_1_MAX_SAMPLE_RATE, CFG_TUD_AUDIO_FUNC_1_FORMAT_2_N_BYTES_PER_SAMPLE_RX, CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_RX) -#define CFG_TUD_AUDIO_FUNC_1_EP_OUT_SW_BUF_SZ TU_MAX(CFG_TUD_AUDIO_UNC_1_FORMAT_1_EP_SZ_OUT, CFG_TUD_AUDIO_UNC_1_FORMAT_2_EP_SZ_OUT)*3 +#define CFG_TUD_AUDIO_FUNC_1_EP_OUT_SW_BUF_SZ TU_MAX(CFG_TUD_AUDIO_UNC_1_FORMAT_1_EP_SZ_OUT, CFG_TUD_AUDIO_UNC_1_FORMAT_2_EP_SZ_OUT)*2 #define CFG_TUD_AUDIO_FUNC_1_EP_OUT_SZ_MAX TU_MAX(CFG_TUD_AUDIO_UNC_1_FORMAT_1_EP_SZ_OUT, CFG_TUD_AUDIO_UNC_1_FORMAT_2_EP_SZ_OUT) // Maximum EP IN size for all AS alternate settings used // Number of Standard AS Interface Descriptors (4.9.1) defined per audio function - this is required to be able to remember the current alternate settings of these interfaces - We restrict us here to have a constant number for all audio functions (which means this has to be the maximum number of AS interfaces an audio function has and a second audio function with less AS interfaces just wastes a few bytes) diff --git a/src/class/audio/audio_device.c b/src/class/audio/audio_device.c index 230b689cd..3e05b3763 100644 --- a/src/class/audio/audio_device.c +++ b/src/class/audio/audio_device.c @@ -1481,8 +1481,10 @@ static bool audiod_set_interface(uint8_t rhport, tusb_control_request_t const * audio->ep_in_as_intf_num = 0; usbd_edpt_close(rhport, audio->ep_in); +#if !CFG_TUD_AUDIO_ENABLE_ENCODING // Clear FIFOs, since data is no longer valid tu_fifo_clear(&audio->ep_in_ff); +#endif // Invoke callback - can be used to stop data sampling if (tud_audio_set_itf_close_EP_cb) TU_VERIFY(tud_audio_set_itf_close_EP_cb(rhport, p_request)); @@ -1506,8 +1508,10 @@ static bool audiod_set_interface(uint8_t rhport, tusb_control_request_t const * audio->ep_out_as_intf_num = 0; usbd_edpt_close(rhport, audio->ep_out); +#if !CFG_TUD_AUDIO_ENABLE_ENCODING // Clear FIFOs, since data is no longer valid tu_fifo_clear(&audio->ep_out_ff); +#endif // Invoke callback - can be used to stop data sampling if (tud_audio_set_itf_close_EP_cb) TU_VERIFY(tud_audio_set_itf_close_EP_cb(rhport, p_request)); -- cgit v1.3.1 From 449936c0f11ea72dd969c8bb353b0f58814f7bc6 Mon Sep 17 00:00:00 2001 From: MasterPhi Date: Fri, 2 Jul 2021 21:51:54 +0200 Subject: more uac fixes, --- src/class/audio/audio.h | 2 +- src/class/audio/audio_device.c | 50 +++++++++++++++++++++--------------------- 2 files changed, 26 insertions(+), 26 deletions(-) (limited to 'src/class') diff --git a/src/class/audio/audio.h b/src/class/audio/audio.h index 936f09104..238295d25 100644 --- a/src/class/audio/audio.h +++ b/src/class/audio/audio.h @@ -489,7 +489,7 @@ typedef enum AUDIO_DATA_FORMAT_TYPE_I_IEEE_FLOAT = (uint32_t) (1 << 2), AUDIO_DATA_FORMAT_TYPE_I_ALAW = (uint32_t) (1 << 3), AUDIO_DATA_FORMAT_TYPE_I_MULAW = (uint32_t) (1 << 4), - AUDIO_DATA_FORMAT_TYPE_I_RAW_DATA = 0x100000000, + AUDIO_DATA_FORMAT_TYPE_I_RAW_DATA = 0x80000000, } audio_data_format_type_I_t; /// All remaining definitions are taken from the descriptor descriptions in the UAC2 main specification diff --git a/src/class/audio/audio_device.c b/src/class/audio/audio_device.c index 3e05b3763..31b318c3f 100644 --- a/src/class/audio/audio_device.c +++ b/src/class/audio/audio_device.c @@ -102,19 +102,19 @@ // EP IN software buffers and mutexes #if CFG_TUD_AUDIO_ENABLE_EP_IN && !CFG_TUD_AUDIO_ENABLE_ENCODING #if CFG_TUD_AUDIO_FUNC_1_EP_IN_SW_BUF_SZ > 0 -CFG_TUSB_MEM_ALIGN uint8_t audio_ep_in_sw_buf_1[CFG_TUD_AUDIO_FUNC_1_EP_IN_SW_BUF_SZ]; +CFG_TUSB_MEM_SECTION CFG_TUSB_MEM_ALIGN uint8_t audio_ep_in_sw_buf_1[CFG_TUD_AUDIO_FUNC_1_EP_IN_SW_BUF_SZ]; #if CFG_FIFO_MUTEX osal_mutex_def_t ep_in_ff_mutex_wr_1; // No need for read mutex as only USB driver reads from FIFO #endif #endif // CFG_TUD_AUDIO_FUNC_1_EP_IN_SW_BUF_SZ > 0 #if CFG_TUD_AUDIO > 1 && CFG_TUD_AUDIO_FUNC_2_EP_IN_SW_BUF_SZ > 0 -CFG_TUSB_MEM_ALIGN uint8_t audio_ep_in_sw_buf_2[CFG_TUD_AUDIO_FUNC_2_EP_IN_SW_BUF_SZ]; +CFG_TUSB_MEM_SECTION CFG_TUSB_MEM_ALIGN uint8_t audio_ep_in_sw_buf_2[CFG_TUD_AUDIO_FUNC_2_EP_IN_SW_BUF_SZ]; #if CFG_FIFO_MUTEX osal_mutex_def_t ep_in_ff_mutex_wr_2; // No need for read mutex as only USB driver reads from FIFO #endif #endif // CFG_TUD_AUDIO > 1 && CFG_TUD_AUDIO_FUNC_2_EP_IN_SW_BUF_SZ > 0 #if CFG_TUD_AUDIO > 2 && CFG_TUD_AUDIO_FUNC_3_EP_IN_SW_BUF_SZ > 0 -CFG_TUSB_MEM_ALIGN uint8_t audio_ep_in_sw_buf_3[CFG_TUD_AUDIO_FUNC_3_EP_IN_SW_BUF_SZ]; +CFG_TUSB_MEM_SECTION CFG_TUSB_MEM_ALIGN uint8_t audio_ep_in_sw_buf_3[CFG_TUD_AUDIO_FUNC_3_EP_IN_SW_BUF_SZ]; #if CFG_FIFO_MUTEX osal_mutex_def_t ep_in_ff_mutex_wr_3; // No need for read mutex as only USB driver reads from FIFO #endif @@ -126,32 +126,32 @@ osal_mutex_def_t ep_in_ff_mutex_wr_3; // - the software encoding is used - in this case the linear buffers serve as a target memory where logical channels are encoded into #if CFG_TUD_AUDIO_ENABLE_EP_IN && (USE_LINEAR_BUFFER || CFG_TUD_AUDIO_ENABLE_ENCODING) #if CFG_TUD_AUDIO_FUNC_1_EP_IN_SZ_MAX > 0 -CFG_TUSB_MEM_ALIGN uint8_t lin_buf_in_1[CFG_TUD_AUDIO_FUNC_1_EP_IN_SZ_MAX]; +CFG_TUSB_MEM_SECTION CFG_TUSB_MEM_ALIGN uint8_t lin_buf_in_1[CFG_TUD_AUDIO_FUNC_1_EP_IN_SZ_MAX]; #endif #if CFG_TUD_AUDIO > 1 && CFG_TUD_AUDIO_FUNC_2_EP_IN_SZ_MAX > 0 -CFG_TUSB_MEM_ALIGN uint8_t lin_buf_in_2[CFG_TUD_AUDIO_FUNC_2_EP_IN_SZ_MAX]; +CFG_TUSB_MEM_SECTION CFG_TUSB_MEM_ALIGN uint8_t lin_buf_in_2[CFG_TUD_AUDIO_FUNC_2_EP_IN_SZ_MAX]; #endif #if CFG_TUD_AUDIO > 2 && CFG_TUD_AUDIO_FUNC_3_EP_IN_SZ_MAX > 0 -CFG_TUSB_MEM_ALIGN uint8_t lin_buf_in_3[CFG_TUD_AUDIO_FUNC_3_EP_IN_SZ_MAX]; +CFG_TUSB_MEM_SECTION CFG_TUSB_MEM_ALIGN uint8_t lin_buf_in_3[CFG_TUD_AUDIO_FUNC_3_EP_IN_SZ_MAX]; #endif #endif // CFG_TUD_AUDIO_ENABLE_EP_IN && (USE_LINEAR_BUFFER || CFG_TUD_AUDIO_ENABLE_DECODING) // EP OUT software buffers and mutexes #if CFG_TUD_AUDIO_ENABLE_EP_OUT && !CFG_TUD_AUDIO_ENABLE_DECODING #if CFG_TUD_AUDIO_FUNC_1_EP_OUT_SW_BUF_SZ > 0 -CFG_TUSB_MEM_ALIGN uint8_t audio_ep_out_sw_buf_1[CFG_TUD_AUDIO_FUNC_1_EP_OUT_SW_BUF_SZ]; +CFG_TUSB_MEM_SECTION CFG_TUSB_MEM_ALIGN uint8_t audio_ep_out_sw_buf_1[CFG_TUD_AUDIO_FUNC_1_EP_OUT_SW_BUF_SZ]; #if CFG_FIFO_MUTEX osal_mutex_def_t ep_out_ff_mutex_rd_1; // No need for write mutex as only USB driver writes into FIFO #endif #endif // CFG_TUD_AUDIO_FUNC_1_EP_OUT_SW_BUF_SZ > 0 #if CFG_TUD_AUDIO > 1 && CFG_TUD_AUDIO_FUNC_2_EP_OUT_SW_BUF_SZ > 0 -CFG_TUSB_MEM_ALIGN uint8_t audio_ep_out_sw_buf_2[CFG_TUD_AUDIO_FUNC_2_EP_OUT_SW_BUF_SZ]; +CFG_TUSB_MEM_SECTION CFG_TUSB_MEM_ALIGN uint8_t audio_ep_out_sw_buf_2[CFG_TUD_AUDIO_FUNC_2_EP_OUT_SW_BUF_SZ]; #if CFG_FIFO_MUTEX osal_mutex_def_t ep_out_ff_mutex_rd_2; // No need for write mutex as only USB driver writes into FIFO #endif #endif // CFG_TUD_AUDIO > 1 && CFG_TUD_AUDIO_FUNC_2_EP_OUT_SW_BUF_SZ > 0 #if CFG_TUD_AUDIO > 2 && CFG_TUD_AUDIO_FUNC_3_EP_OUT_SW_BUF_SZ > 0 -CFG_TUSB_MEM_ALIGN uint8_t audio_ep_out_sw_buf_3[CFG_TUD_AUDIO_FUNC_3_EP_OUT_SW_BUF_SZ]; +CFG_TUSB_MEM_SECTION CFG_TUSB_MEM_ALIGN uint8_t audio_ep_out_sw_buf_3[CFG_TUD_AUDIO_FUNC_3_EP_OUT_SW_BUF_SZ]; #if CFG_FIFO_MUTEX osal_mutex_def_t ep_out_ff_mutex_rd_3; // No need for write mutex as only USB driver writes into FIFO #endif @@ -163,52 +163,52 @@ osal_mutex_def_t ep_out_ff_mutex_rd_3; // - the software encoding is used - in this case the linear buffers serve as a target memory where logical channels are encoded into #if CFG_TUD_AUDIO_ENABLE_EP_OUT && (USE_LINEAR_BUFFER || CFG_TUD_AUDIO_ENABLE_DECODING) #if CFG_TUD_AUDIO_FUNC_1_EP_OUT_SZ_MAX > 0 -CFG_TUSB_MEM_ALIGN uint8_t lin_buf_out_1[CFG_TUD_AUDIO_FUNC_1_EP_OUT_SZ_MAX]; +CFG_TUSB_MEM_SECTION CFG_TUSB_MEM_ALIGN uint8_t lin_buf_out_1[CFG_TUD_AUDIO_FUNC_1_EP_OUT_SZ_MAX]; #endif #if CFG_TUD_AUDIO > 1 && CFG_TUD_AUDIO_FUNC_2_EP_OUT_SZ_MAX > 0 -CFG_TUSB_MEM_ALIGN uint8_t lin_buf_out_2[CFG_TUD_AUDIO_FUNC_2_EP_OUT_SZ_MAX]; +CFG_TUSB_MEM_SECTION CFG_TUSB_MEM_ALIGN uint8_t lin_buf_out_2[CFG_TUD_AUDIO_FUNC_2_EP_OUT_SZ_MAX]; #endif #if CFG_TUD_AUDIO > 2 && CFG_TUD_AUDIO_FUNC_3_EP_OUT_SZ_MAX > 0 -CFG_TUSB_MEM_ALIGN uint8_t lin_buf_out_3[CFG_TUD_AUDIO_FUNC_3_EP_OUT_SZ_MAX]; +CFG_TUSB_MEM_SECTION CFG_TUSB_MEM_ALIGN uint8_t lin_buf_out_3[CFG_TUD_AUDIO_FUNC_3_EP_OUT_SZ_MAX]; #endif #endif // CFG_TUD_AUDIO_ENABLE_EP_OUT && (USE_LINEAR_BUFFER || CFG_TUD_AUDIO_ENABLE_DECODING) // Control buffers -CFG_TUSB_MEM_ALIGN uint8_t ctrl_buf_1[CFG_TUD_AUDIO_FUNC_1_CTRL_BUF_SZ]; +CFG_TUSB_MEM_SECTION CFG_TUSB_MEM_ALIGN uint8_t ctrl_buf_1[CFG_TUD_AUDIO_FUNC_1_CTRL_BUF_SZ]; #if CFG_TUD_AUDIO > 1 -CFG_TUSB_MEM_ALIGN uint8_t ctrl_buf_2[CFG_TUD_AUDIO_FUNC_2_CTRL_BUF_SZ]; +CFG_TUSB_MEM_SECTION CFG_TUSB_MEM_ALIGN uint8_t ctrl_buf_2[CFG_TUD_AUDIO_FUNC_2_CTRL_BUF_SZ]; #endif #if CFG_TUD_AUDIO > 2 -CFG_TUSB_MEM_ALIGN uint8_t ctrl_buf_3[CFG_TUD_AUDIO_FUNC_3_CTRL_BUF_SZ]; +CFG_TUSB_MEM_SECTION CFG_TUSB_MEM_ALIGN uint8_t ctrl_buf_3[CFG_TUD_AUDIO_FUNC_3_CTRL_BUF_SZ]; #endif // Active alternate setting of interfaces -CFG_TUSB_MEM_ALIGN uint8_t alt_setting_1[CFG_TUD_AUDIO_FUNC_1_N_AS_INT]; +CFG_TUSB_MEM_SECTION CFG_TUSB_MEM_ALIGN uint8_t alt_setting_1[CFG_TUD_AUDIO_FUNC_1_N_AS_INT]; #if CFG_TUD_AUDIO > 1 && CFG_TUD_AUDIO_FUNC_2_N_AS_INT > 0 -CFG_TUSB_MEM_ALIGN uint8_t alt_setting_2[CFG_TUD_AUDIO_FUNC_2_N_AS_INT]; +CFG_TUSB_MEM_SECTION CFG_TUSB_MEM_ALIGN uint8_t alt_setting_2[CFG_TUD_AUDIO_FUNC_2_N_AS_INT]; #endif #if CFG_TUD_AUDIO > 2 && CFG_TUD_AUDIO_FUNC_3_N_AS_INT > 0 -CFG_TUSB_MEM_ALIGN uint8_t alt_setting_3[CFG_TUD_AUDIO_FUNC_3_N_AS_INT]; +CFG_TUSB_MEM_SECTION CFG_TUSB_MEM_ALIGN uint8_t alt_setting_3[CFG_TUD_AUDIO_FUNC_3_N_AS_INT]; #endif // Software encoding/decoding support FIFOs #if CFG_TUD_AUDIO_ENABLE_EP_IN && CFG_TUD_AUDIO_ENABLE_ENCODING #if CFG_TUD_AUDIO_FUNC_1_TX_SUPP_SW_FIFO_SZ > 0 -CFG_TUSB_MEM_ALIGN uint8_t tx_supp_ff_buf_1[CFG_TUD_AUDIO_FUNC_1_N_TX_SUPP_SW_FIFO][CFG_TUD_AUDIO_FUNC_1_TX_SUPP_SW_FIFO_SZ]; +CFG_TUSB_MEM_SECTION CFG_TUSB_MEM_ALIGN uint8_t tx_supp_ff_buf_1[CFG_TUD_AUDIO_FUNC_1_N_TX_SUPP_SW_FIFO][CFG_TUD_AUDIO_FUNC_1_TX_SUPP_SW_FIFO_SZ]; tu_fifo_t tx_supp_ff_1[CFG_TUD_AUDIO_FUNC_1_N_TX_SUPP_SW_FIFO]; #if CFG_FIFO_MUTEX osal_mutex_def_t tx_supp_ff_mutex_wr_1[CFG_TUD_AUDIO_FUNC_1_N_TX_SUPP_SW_FIFO]; // No need for read mutex as only USB driver reads from FIFO #endif #endif #if CFG_TUD_AUDIO > 1 && CFG_TUD_AUDIO_FUNC_2_TX_SUPP_SW_FIFO_SZ > 0 -CFG_TUSB_MEM_ALIGN uint8_t tx_supp_ff_buf_2[CFG_TUD_AUDIO_FUNC_2_N_TX_SUPP_SW_FIFO][CFG_TUD_AUDIO_FUNC_2_TX_SUPP_SW_FIFO_SZ]; +CFG_TUSB_MEM_SECTION CFG_TUSB_MEM_ALIGN uint8_t tx_supp_ff_buf_2[CFG_TUD_AUDIO_FUNC_2_N_TX_SUPP_SW_FIFO][CFG_TUD_AUDIO_FUNC_2_TX_SUPP_SW_FIFO_SZ]; tu_fifo_t tx_supp_ff_2[CFG_TUD_AUDIO_FUNC_2_N_TX_SUPP_SW_FIFO]; #if CFG_FIFO_MUTEX osal_mutex_def_t tx_supp_ff_mutex_wr_2[CFG_TUD_AUDIO_FUNC_2_N_TX_SUPP_SW_FIFO]; // No need for read mutex as only USB driver reads from FIFO #endif #endif #if CFG_TUD_AUDIO > 2 && CFG_TUD_AUDIO_FUNC_3_TX_SUPP_SW_FIFO_SZ > 0 -CFG_TUSB_MEM_ALIGN uint8_t tx_supp_ff_buf_3[CFG_TUD_AUDIO_FUNC_3_N_TX_SUPP_SW_FIFO][CFG_TUD_AUDIO_FUNC_3_TX_SUPP_SW_FIFO_SZ]; +CFG_TUSB_MEM_SECTION CFG_TUSB_MEM_ALIGN uint8_t tx_supp_ff_buf_3[CFG_TUD_AUDIO_FUNC_3_N_TX_SUPP_SW_FIFO][CFG_TUD_AUDIO_FUNC_3_TX_SUPP_SW_FIFO_SZ]; tu_fifo_t tx_supp_ff_3[CFG_TUD_AUDIO_FUNC_3_N_TX_SUPP_SW_FIFO]; #if CFG_FIFO_MUTEX osal_mutex_def_t tx_supp_ff_mutex_wr_3[CFG_TUD_AUDIO_FUNC_3_N_TX_SUPP_SW_FIFO]; // No need for read mutex as only USB driver reads from FIFO @@ -218,21 +218,21 @@ osal_mutex_def_t tx_supp_ff_mutex_wr_3[CFG_TUD_AUDIO_FUNC_3_N_TX_SUPP_SW_FIFO]; #if CFG_TUD_AUDIO_ENABLE_EP_OUT && CFG_TUD_AUDIO_ENABLE_DECODING #if CFG_TUD_AUDIO_FUNC_1_RX_SUPP_SW_FIFO_SZ > 0 -CFG_TUSB_MEM_ALIGN uint8_t rx_supp_ff_buf_1[CFG_TUD_AUDIO_FUNC_1_N_RX_SUPP_SW_FIFO][CFG_TUD_AUDIO_FUNC_1_RX_SUPP_SW_FIFO_SZ]; +CFG_TUSB_MEM_SECTION CFG_TUSB_MEM_ALIGN uint8_t rx_supp_ff_buf_1[CFG_TUD_AUDIO_FUNC_1_N_RX_SUPP_SW_FIFO][CFG_TUD_AUDIO_FUNC_1_RX_SUPP_SW_FIFO_SZ]; tu_fifo_t rx_supp_ff_1[CFG_TUD_AUDIO_FUNC_1_N_RX_SUPP_SW_FIFO]; #if CFG_FIFO_MUTEX osal_mutex_def_t rx_supp_ff_mutex_rd_1[CFG_TUD_AUDIO_FUNC_1_N_RX_SUPP_SW_FIFO]; // No need for write mutex as only USB driver writes into FIFO #endif #endif #if CFG_TUD_AUDIO > 1 && CFG_TUD_AUDIO_FUNC_2_RX_SUPP_SW_FIFO_SZ > 0 -CFG_TUSB_MEM_ALIGN uint8_t rx_supp_ff_buf_2[CFG_TUD_AUDIO_FUNC_2_N_RX_SUPP_SW_FIFO][CFG_TUD_AUDIO_FUNC_2_RX_SUPP_SW_FIFO_SZ]; +CFG_TUSB_MEM_SECTION CFG_TUSB_MEM_ALIGN uint8_t rx_supp_ff_buf_2[CFG_TUD_AUDIO_FUNC_2_N_RX_SUPP_SW_FIFO][CFG_TUD_AUDIO_FUNC_2_RX_SUPP_SW_FIFO_SZ]; tu_fifo_t rx_supp_ff_2[CFG_TUD_AUDIO_FUNC_2_N_RX_SUPP_SW_FIFO]; #if CFG_FIFO_MUTEX osal_mutex_def_t rx_supp_ff_mutex_rd_2[CFG_TUD_AUDIO_FUNC_2_N_RX_SUPP_SW_FIFO]; // No need for write mutex as only USB driver writes into FIFO #endif #endif #if CFG_TUD_AUDIO > 2 && CFG_TUD_AUDIO_FUNC_3_RX_SUPP_SW_FIFO_SZ > 0 -CFG_TUSB_MEM_ALIGN uint8_t rx_supp_ff_buf_3[CFG_TUD_AUDIO_FUNC_3_N_RX_SUPP_SW_FIFO][CFG_TUD_AUDIO_FUNC_3_RX_SUPP_SW_FIFO_SZ]; +CFG_TUSB_MEM_SECTION CFG_TUSB_MEM_ALIGN uint8_t rx_supp_ff_buf_3[CFG_TUD_AUDIO_FUNC_3_N_RX_SUPP_SW_FIFO][CFG_TUD_AUDIO_FUNC_3_RX_SUPP_SW_FIFO_SZ]; tu_fifo_t rx_supp_ff_3[CFG_TUD_AUDIO_FUNC_3_N_RX_SUPP_SW_FIFO]; #if CFG_FIFO_MUTEX osal_mutex_def_t rx_supp_ff_mutex_rd_3[CFG_TUD_AUDIO_FUNC_3_N_RX_SUPP_SW_FIFO]; // No need for write mutex as only USB driver writes into FIFO @@ -294,7 +294,7 @@ typedef struct // Audio control interrupt buffer - no FIFO - 6 Bytes according to UAC 2 specification (p. 74) #if CFG_TUD_AUDIO_INT_CTR_EPSIZE_IN - CFG_TUSB_MEM_ALIGN uint8_t ep_int_ctr_buf[CFG_TUD_AUDIO_INT_CTR_EP_IN_SW_BUFFER_SIZE]; + CFG_TUSB_MEM_SECTION CFG_TUSB_MEM_ALIGN uint8_t ep_int_ctr_buf[CFG_TUD_AUDIO_INT_CTR_EP_IN_SW_BUFFER_SIZE]; #endif // Decoding parameters - parameters are set when alternate AS interface is set by host -- cgit v1.3.1 From 090859bf424e910002fff7dc9195d38d6c22ae1f Mon Sep 17 00:00:00 2001 From: MasterPhi Date: Fri, 2 Jul 2021 23:44:46 +0200 Subject: Fix speed detection --- src/class/audio/audio_device.c | 29 +++++++++++++---------------- 1 file changed, 13 insertions(+), 16 deletions(-) (limited to 'src/class') diff --git a/src/class/audio/audio_device.c b/src/class/audio/audio_device.c index 31b318c3f..cc07d5e19 100644 --- a/src/class/audio/audio_device.c +++ b/src/class/audio/audio_device.c @@ -2223,22 +2223,19 @@ bool tud_audio_n_fb_set(uint8_t func_id, uint32_t feedback) TU_VERIFY(func_id < CFG_TUD_AUDIO && _audiod_fct[func_id].p_desc != NULL); // Format the feedback value - if (_audiod_fct[func_id].rhport == 0) - { - uint8_t * fb = (uint8_t *) &_audiod_fct[func_id].fb_val; - - // For FS format is 10.14 - *(fb++) = (feedback >> 2) & 0xFF; - *(fb++) = (feedback >> 10) & 0xFF; - *(fb++) = (feedback >> 18) & 0xFF; - // 4th byte is needed to work correctly with MS Windows - *fb = 0; - } - else - { - // For HS format is 16.16 as originally demanded - _audiod_fct[func_id].fb_val = feedback; - } +#if !TUD_OPT_HIGH_SPEED + uint8_t * fb = (uint8_t *) &_audiod_fct[func_id].fb_val; + + // For FS format is 10.14 + *(fb++) = (feedback >> 2) & 0xFF; + *(fb++) = (feedback >> 10) & 0xFF; + *(fb++) = (feedback >> 18) & 0xFF; + // 4th byte is needed to work correctly with MS Windows + *fb = 0; +#else + // For HS format is 16.16 as originally demanded + _audiod_fct[func_id].fb_val = feedback; +#endif // Schedule a transmit with the new value if EP is not busy - this triggers repetitive scheduling of the feedback value if (!usbd_edpt_busy(_audiod_fct[func_id].rhport, _audiod_fct[func_id].ep_fb)) -- cgit v1.3.1 From 61fd0e2c1cd60921ea3cc6de01534a1e512aff12 Mon Sep 17 00:00:00 2001 From: MasterPhi Date: Sat, 3 Jul 2021 10:54:20 +0200 Subject: Delay tud_audio_set_itf_cb call with feedback EP. --- src/class/audio/audio_device.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) (limited to 'src/class') diff --git a/src/class/audio/audio_device.c b/src/class/audio/audio_device.c index cc07d5e19..61884f867 100644 --- a/src/class/audio/audio_device.c +++ b/src/class/audio/audio_device.c @@ -1619,9 +1619,17 @@ static bool audiod_set_interface(uint8_t rhport, tusb_control_request_t const * TU_ASSERT( audio->n_ff_used_rx <= audio->n_rx_supp_ff ); #endif #endif + +#if CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP + // In case of asynchronous EP, call Cb after ep_fb is set + if (((tusb_desc_endpoint_t const *) p_desc)->bmAttributes.sync != 0x01) + { + if (tud_audio_set_itf_cb) TU_VERIFY(tud_audio_set_itf_cb(rhport, p_request)); + } +#else // Invoke callback if (tud_audio_set_itf_cb) TU_VERIFY(tud_audio_set_itf_cb(rhport, p_request)); - +#endif // Prepare for incoming data #if USE_LINEAR_BUFFER_RX TU_VERIFY(usbd_edpt_xfer(rhport, audio->ep_out, audio->lin_buf_out, audio->ep_out_sz), false); -- cgit v1.3.1 From 1c8b685457aee291f8352003c7ca7b852c412982 Mon Sep 17 00:00:00 2001 From: MasterPhi Date: Sun, 4 Jul 2021 00:19:33 +0200 Subject: Move audio_control_request_t to audio.h --- examples/device/uac2_headset/src/main.c | 26 -------------------------- src/class/audio/audio.h | 27 +++++++++++++++++++++++++++ 2 files changed, 27 insertions(+), 26 deletions(-) (limited to 'src/class') diff --git a/examples/device/uac2_headset/src/main.c b/examples/device/uac2_headset/src/main.c index b459bc2a8..ba27350b4 100644 --- a/examples/device/uac2_headset/src/main.c +++ b/examples/device/uac2_headset/src/main.c @@ -142,32 +142,6 @@ void tud_resume_cb(void) blink_interval_ms = BLINK_MOUNTED; } -typedef struct TU_ATTR_PACKED -{ - union - { - struct TU_ATTR_PACKED - { - uint8_t recipient : 5; ///< Recipient type tusb_request_recipient_t. - uint8_t type : 2; ///< Request type tusb_request_type_t. - uint8_t direction : 1; ///< Direction type. tusb_dir_t - } bmRequestType_bit; - - uint8_t bmRequestType; - }; - - uint8_t bRequest; ///< Request type audio_cs_req_t - uint8_t bChannelNumber; - uint8_t bControlSelector; - union - { - uint8_t bInterface; - uint8_t bEndpoint; - }; - uint8_t bEntityID; - uint16_t wLength; -} audio_control_request_t; - // Helper for clock get requests static bool tud_audio_clock_get_request(uint8_t rhport, audio_control_request_t const *request) { diff --git a/src/class/audio/audio.h b/src/class/audio/audio.h index 238295d25..f99061eae 100644 --- a/src/class/audio/audio.h +++ b/src/class/audio/audio.h @@ -823,6 +823,33 @@ typedef struct TU_ATTR_PACKED uint16_t wLockDelay ; ///< Indicates the time it takes this endpoint to reliably lock its internal clock recovery circuitry. Units used depend on the value of the bLockDelayUnits field. } audio_desc_cs_as_iso_data_ep_t; +// 5.2.2 Control Request Layout +typedef struct TU_ATTR_PACKED +{ + union + { + struct TU_ATTR_PACKED + { + uint8_t recipient : 5; ///< Recipient type tusb_request_recipient_t. + uint8_t type : 2; ///< Request type tusb_request_type_t. + uint8_t direction : 1; ///< Direction type. tusb_dir_t + } bmRequestType_bit; + + uint8_t bmRequestType; + }; + + uint8_t bRequest; ///< Request type audio_cs_req_t + uint8_t bChannelNumber; + uint8_t bControlSelector; + union + { + uint8_t bInterface; + uint8_t bEndpoint; + }; + uint8_t bEntityID; + uint16_t wLength; +} audio_control_request_t; + //// 5.2.3 Control Request Parameter Block Layout // 5.2.3.1 1-byte Control CUR Parameter Block -- cgit v1.3.1 From 98d921c4b3657e473f2231857bb6c82ef567b0e3 Mon Sep 17 00:00:00 2001 From: MasterPhi Date: Sun, 4 Jul 2021 15:10:45 +0200 Subject: Better handling tud_audio_set_itf_cb with FB. --- src/class/audio/audio_device.c | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) (limited to 'src/class') diff --git a/src/class/audio/audio_device.c b/src/class/audio/audio_device.c index 61884f867..c7b8b8519 100644 --- a/src/class/audio/audio_device.c +++ b/src/class/audio/audio_device.c @@ -1622,7 +1622,7 @@ static bool audiod_set_interface(uint8_t rhport, tusb_control_request_t const * #if CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP // In case of asynchronous EP, call Cb after ep_fb is set - if (((tusb_desc_endpoint_t const *) p_desc)->bmAttributes.sync != 0x01) + if (!(((tusb_desc_endpoint_t const *) p_desc)->bmAttributes.sync == 0x01 && audio->ep_fb == 0)) { if (tud_audio_set_itf_cb) TU_VERIFY(tud_audio_set_itf_cb(rhport, p_request)); } @@ -1643,8 +1643,11 @@ static bool audiod_set_interface(uint8_t rhport, tusb_control_request_t const * { audio->ep_fb = ep_addr; - // Invoke callback - if (tud_audio_set_itf_cb) TU_VERIFY(tud_audio_set_itf_cb(rhport, p_request)); + // Invoke callback after ep_out is set + if (audio->ep_out != 0) + { + if (tud_audio_set_itf_cb) TU_VERIFY(tud_audio_set_itf_cb(rhport, p_request)); + } } #endif #endif // CFG_TUD_AUDIO_ENABLE_EP_OUT @@ -1938,8 +1941,12 @@ bool audiod_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint3 { if (tud_audio_fb_done_cb) TU_VERIFY(tud_audio_fb_done_cb(rhport)); - // Schedule next transmission - value is changed bytud_audio_n_fb_set() in the meantime or the old value gets sent - return audiod_fb_send(rhport, &_audiod_fct[func_id]); + // Schedule a transmit with the new value if EP is not busy + if (!usbd_edpt_busy(rhport, _audiod_fct[func_id].ep_fb)) + { + // Schedule next transmission - value is changed bytud_audio_n_fb_set() in the meantime or the old value gets sent + return audiod_fb_send(rhport, &_audiod_fct[func_id]); + } } #endif #endif -- cgit v1.3.1 From dfe410ea8beb15b4d85320efeb059f42be647ea6 Mon Sep 17 00:00:00 2001 From: hathach Date: Mon, 5 Jul 2021 12:38:15 +0700 Subject: fix ci build, address review comment --- src/class/dfu/dfu_device.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'src/class') diff --git a/src/class/dfu/dfu_device.c b/src/class/dfu/dfu_device.c index df731ee50..c696d70a2 100644 --- a/src/class/dfu/dfu_device.c +++ b/src/class/dfu/dfu_device.c @@ -247,9 +247,8 @@ bool dfu_moded_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_reque static uint16_t dfu_req_upload(uint8_t rhport, tusb_control_request_t const * request, uint16_t block_num, uint16_t wLength) { - TU_VERIFY( wLength <= CFG_TUD_DFU_TRANSFER_BUFFER_SIZE); + TU_VERIFY( wLength <= CFG_TUD_DFU_TRANSFER_BUFFER_SIZE, 0); uint16_t retval = tud_dfu_req_upload_data_cb(block_num, (uint8_t *)_dfu_state_ctx.transfer_buf, wLength); - TU_ASSERT( retval <= CFG_TUD_DFU_TRANSFER_BUFFER_SIZE); tud_control_xfer(rhport, request, _dfu_state_ctx.transfer_buf, retval); return retval; } @@ -277,7 +276,7 @@ static void dfu_req_dnload_setup(uint8_t rhport, tusb_control_request_t const * // if they wish, there still will be the internal control buffer copy to this buffer // but this mode would provide zero copy from the class driver to the application - TU_VERIFY( request->wLength <= CFG_TUD_DFU_TRANSFER_BUFFER_SIZE); + TU_VERIFY( request->wLength <= CFG_TUD_DFU_TRANSFER_BUFFER_SIZE, ); // setup for data phase tud_control_xfer(rhport, request, _dfu_state_ctx.transfer_buf, request->wLength); } @@ -285,7 +284,7 @@ static void dfu_req_dnload_setup(uint8_t rhport, tusb_control_request_t const * static void dfu_req_dnload_reply(uint8_t rhport, tusb_control_request_t const * request) { (void) rhport; - TU_VERIFY( request->wLength <= CFG_TUD_DFU_TRANSFER_BUFFER_SIZE); + TU_VERIFY( request->wLength <= CFG_TUD_DFU_TRANSFER_BUFFER_SIZE, ); tud_dfu_req_dnload_data_cb(request->wValue, (uint8_t *)_dfu_state_ctx.transfer_buf, request->wLength); _dfu_state_ctx.blk_transfer_in_proc = false; } -- cgit v1.3.1 From c2d8ed3fd1fdb722d67a30a6768720c9ed578779 Mon Sep 17 00:00:00 2001 From: Mengsk Date: Mon, 5 Jul 2021 17:56:21 +0200 Subject: Add alt settings support in DFU class. --- examples/device/dfu/src/main.c | 25 ++++++++--------- examples/device/dfu/src/usb_descriptors.c | 8 ++++-- src/class/dfu/dfu_device.c | 46 ++++++++++++++++++++----------- src/class/dfu/dfu_device.h | 10 ++++--- src/device/usbd.h | 8 +++--- 5 files changed, 56 insertions(+), 41 deletions(-) (limited to 'src/class') diff --git a/examples/device/dfu/src/main.c b/examples/device/dfu/src/main.c index 1c09066a8..81532ee90 100644 --- a/examples/device/dfu/src/main.c +++ b/examples/device/dfu/src/main.c @@ -115,25 +115,20 @@ void tud_resume_cb(void) blink_interval_ms = BLINK_MOUNTED; } -// Invoked on DFU_DETACH request to reboot to the bootloader -void tud_dfu_runtime_reboot_to_dfu_cb(void) -{ - blink_interval_ms = BLINK_DFU_MODE; -} - //--------------------------------------------------------------------+ // Class callbacks //--------------------------------------------------------------------+ -bool tud_dfu_firmware_valid_check_cb(void) +bool tud_dfu_firmware_valid_check_cb(uint8_t alt) { + (void) alt; printf(" Firmware check\r\n"); return true; } -void tud_dfu_req_dnload_data_cb(uint16_t wBlockNum, uint8_t* data, uint16_t length) +void tud_dfu_req_dnload_data_cb(uint8_t alt, uint16_t wBlockNum, uint8_t* data, uint16_t length) { (void) data; - printf(" Received BlockNum %u of length %u\r\n", wBlockNum, length); + printf(" Received Alt %u BlockNum %u of length %u\r\n", alt, wBlockNum, length); #if DFU_VERBOSE for(uint16_t i=0; ibInterfaceSubClass == TUD_DFU_APP_SUBCLASS) && - (itf_desc->bInterfaceProtocol == DFU_PROTOCOL_DFU), 0); + uint16_t drv_len = 0; + uint8_t const * p_desc = (uint8_t*)itf_desc; - uint8_t const * p_desc = tu_desc_next( itf_desc ); - uint16_t drv_len = sizeof(tusb_desc_interface_t); - - if ( TUSB_DESC_FUNCTIONAL == tu_desc_type(p_desc) ) + while (max_len) { - tusb_desc_dfu_functional_t const *dfu_desc = (tusb_desc_dfu_functional_t const *)p_desc; - _dfu_state_ctx.attrs = (uint8_t)dfu_desc->bAttributes; - + // Ensure this is DFU Mode + TU_VERIFY((((tusb_desc_interface_t const *)p_desc)->bInterfaceSubClass == TUD_DFU_APP_SUBCLASS) && + (((tusb_desc_interface_t const *)p_desc)->bInterfaceProtocol == DFU_PROTOCOL_DFU), drv_len); + + p_desc = tu_desc_next( p_desc ); drv_len += tu_desc_len(p_desc); - p_desc = tu_desc_next(p_desc); - } + if ( TUSB_DESC_FUNCTIONAL == tu_desc_type(p_desc) ) + { + tusb_desc_dfu_functional_t const *dfu_desc = (tusb_desc_dfu_functional_t const *)p_desc; + _dfu_state_ctx.attrs = (uint8_t)dfu_desc->bAttributes; + + drv_len += tu_desc_len(p_desc); + p_desc = tu_desc_next(p_desc); + } + + max_len -= drv_len; + } return drv_len; } @@ -200,6 +208,8 @@ bool dfu_moded_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_reque if ( TUSB_REQ_TYPE_STANDARD == request->bmRequestType_bit.type && TUSB_REQ_SET_INTERFACE == request->bRequest ) { + // Save Alt interface + _dfu_state_ctx.alt = request->wValue; tud_control_status(rhport, request); return true; } @@ -248,7 +258,11 @@ bool dfu_moded_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_reque static uint16_t dfu_req_upload(uint8_t rhport, tusb_control_request_t const * request, uint16_t block_num, uint16_t wLength) { TU_VERIFY( wLength <= CFG_TUD_DFU_TRANSFER_BUFFER_SIZE, 0); - uint16_t retval = tud_dfu_req_upload_data_cb(block_num, (uint8_t *)_dfu_state_ctx.transfer_buf, wLength); + uint16_t retval = 0; + if (tud_dfu_req_upload_data_cb) + { + tud_dfu_req_upload_data_cb(_dfu_state_ctx.alt, block_num, (uint8_t *)_dfu_state_ctx.transfer_buf, wLength); + } tud_control_xfer(rhport, request, _dfu_state_ctx.transfer_buf, retval); return retval; } @@ -285,7 +299,7 @@ static void dfu_req_dnload_reply(uint8_t rhport, tusb_control_request_t const * { (void) rhport; TU_VERIFY( request->wLength <= CFG_TUD_DFU_TRANSFER_BUFFER_SIZE, ); - tud_dfu_req_dnload_data_cb(request->wValue, (uint8_t *)_dfu_state_ctx.transfer_buf, request->wLength); + tud_dfu_req_dnload_data_cb(_dfu_state_ctx.alt, request->wValue, (uint8_t *)_dfu_state_ctx.transfer_buf, request->wLength); _dfu_state_ctx.blk_transfer_in_proc = false; } @@ -426,7 +440,7 @@ static bool dfu_state_machine(uint8_t rhport, tusb_control_request_t const * req _dfu_state_ctx.blk_transfer_in_proc = true; dfu_req_dnload_setup(rhport, request); } else { - if ( tud_dfu_device_data_done_check_cb() ) + if ( tud_dfu_device_data_done_check_cb(_dfu_state_ctx.alt) ) { _dfu_state_ctx.state = DFU_MANIFEST_SYNC; tud_control_status(rhport, request); @@ -481,7 +495,7 @@ static bool dfu_state_machine(uint8_t rhport, tusb_control_request_t const * req _dfu_state_ctx.state = DFU_MANIFEST; dfu_req_getstatus_reply(rhport, request); } else { - if ( tud_dfu_firmware_valid_check_cb() ) + if ( tud_dfu_firmware_valid_check_cb(_dfu_state_ctx.alt) ) { _dfu_state_ctx.state = DFU_IDLE; } diff --git a/src/class/dfu/dfu_device.h b/src/class/dfu/dfu_device.h index 9a09a46b1..d5bc88ab2 100644 --- a/src/class/dfu/dfu_device.h +++ b/src/class/dfu/dfu_device.h @@ -39,13 +39,14 @@ //--------------------------------------------------------------------+ // Invoked during DFU_MANIFEST_SYNC get status request to check if firmware // is valid -bool tud_dfu_firmware_valid_check_cb(void); +bool tud_dfu_firmware_valid_check_cb(uint8_t alt); // Invoked when a DFU_DNLOAD request is received // This callback takes the wBlockNum chunk of length length and provides it // to the application at the data pointer. This data is only valid for this // call, so the app must use it not or copy it. -void tud_dfu_req_dnload_data_cb(uint16_t wBlockNum, uint8_t* data, uint16_t length); +// alt is used as the partition number, in order to multiple partitions like FLASH, EEPROM, etc. +void tud_dfu_req_dnload_data_cb(uint8_t alt, uint16_t wBlockNum, uint8_t* data, uint16_t length); // Must be called when the application is done using the last block of data // provided by tud_dfu_req_dnload_data_cb @@ -56,7 +57,7 @@ void tud_dfu_dnload_complete(void); // Return true if the application agrees there is no more data // Return false if the device disagrees, which will stall the pipe, and the Host // should initiate a recovery procedure -bool tud_dfu_device_data_done_check_cb(void); +bool tud_dfu_device_data_done_check_cb(uint8_t alt); // Invoked when the Host has terminated a download or upload transfer TU_ATTR_WEAK void tud_dfu_abort_cb(void); @@ -64,7 +65,8 @@ TU_ATTR_WEAK void tud_dfu_abort_cb(void); // Invoked when a DFU_UPLOAD request is received // This callback must populate data with up to length bytes // Return the number of bytes to write -uint16_t tud_dfu_req_upload_data_cb(uint16_t block_num, uint8_t* data, uint16_t length); +// alt is used as the partition number, in order to multiple partitions like FLASH, EEPROM, etc. +TU_ATTR_WEAK uint16_t tud_dfu_req_upload_data_cb(uint8_t alt, uint16_t block_num, uint8_t* data, uint16_t length); //--------------------------------------------------------------------+ // Internal Class Driver API diff --git a/src/device/usbd.h b/src/device/usbd.h index 3857295d7..41c78de10 100644 --- a/src/device/usbd.h +++ b/src/device/usbd.h @@ -603,11 +603,11 @@ TU_ATTR_WEAK bool tud_vendor_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb // Length of template descriptr: 18 bytes #define TUD_DFU_MODE_DESC_LEN (9 + 9) -// DFU runtime descriptor -// Interface number, string index, attributes, detach timeout, transfer size -#define TUD_DFU_MODE_DESCRIPTOR(_itfnum, _stridx, _attr, _timeout, _xfer_size) \ +// DFU mode descriptor +// Interface number, alt settings, string index, attributes, detach timeout, transfer size +#define TUD_DFU_MODE_DESCRIPTOR(_itfnum, _alt, _stridx, _attr, _timeout, _xfer_size) \ /* Interface */ \ - 9, TUSB_DESC_INTERFACE, _itfnum, 0, 0, TUD_DFU_APP_CLASS, TUD_DFU_APP_SUBCLASS, DFU_PROTOCOL_DFU, _stridx, \ + 9, TUSB_DESC_INTERFACE, _itfnum, _alt, 0, TUD_DFU_APP_CLASS, TUD_DFU_APP_SUBCLASS, DFU_PROTOCOL_DFU, _stridx, \ /* Function */ \ 9, DFU_DESC_FUNCTIONAL, _attr, U16_TO_U8S_LE(_timeout), U16_TO_U8S_LE(_xfer_size), U16_TO_U8S_LE(0x0101) -- cgit v1.3.1 From c2b9ac9dd415505350c40f6830c1d211de67c342 Mon Sep 17 00:00:00 2001 From: Mengsk Date: Mon, 5 Jul 2021 17:57:23 +0200 Subject: Fix ATTR_MANIFESTATION_TOLERANT logic. --- src/class/dfu/dfu_device.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/class') diff --git a/src/class/dfu/dfu_device.c b/src/class/dfu/dfu_device.c index 0570b5958..9eafca359 100644 --- a/src/class/dfu/dfu_device.c +++ b/src/class/dfu/dfu_device.c @@ -310,7 +310,7 @@ void tud_dfu_dnload_complete(void) _dfu_state_ctx.state = DFU_DNLOAD_SYNC; } else if (_dfu_state_ctx.state == DFU_MANIFEST) { - _dfu_state_ctx.state = ((_dfu_state_ctx.attrs & DFU_FUNC_ATTR_MANIFESTATION_TOLERANT_BITMASK) != 0) + _dfu_state_ctx.state = ((_dfu_state_ctx.attrs & DFU_FUNC_ATTR_MANIFESTATION_TOLERANT_BITMASK) == 0) ? DFU_MANIFEST_WAIT_RESET : DFU_MANIFEST_SYNC; } } @@ -490,7 +490,7 @@ static bool dfu_state_machine(uint8_t rhport, tusb_control_request_t const * req { case DFU_REQUEST_GETSTATUS: { - if ((_dfu_state_ctx.attrs & DFU_FUNC_ATTR_MANIFESTATION_TOLERANT_BITMASK) != 0) + if ((_dfu_state_ctx.attrs & DFU_FUNC_ATTR_MANIFESTATION_TOLERANT_BITMASK) == 0) { _dfu_state_ctx.state = DFU_MANIFEST; dfu_req_getstatus_reply(rhport, request); -- cgit v1.3.1 From 05a1b854ffcebe8144481a8af9e447d0eac2ae1f Mon Sep 17 00:00:00 2001 From: MasterPhi Date: Mon, 5 Jul 2021 21:00:04 +0200 Subject: ENCODE -> DECODE --- src/class/audio/audio_device.c | 30 ++++++++++++------------------ 1 file changed, 12 insertions(+), 18 deletions(-) (limited to 'src/class') diff --git a/src/class/audio/audio_device.c b/src/class/audio/audio_device.c index c7b8b8519..97a9c495e 100644 --- a/src/class/audio/audio_device.c +++ b/src/class/audio/audio_device.c @@ -1481,9 +1481,14 @@ static bool audiod_set_interface(uint8_t rhport, tusb_control_request_t const * audio->ep_in_as_intf_num = 0; usbd_edpt_close(rhport, audio->ep_in); -#if !CFG_TUD_AUDIO_ENABLE_ENCODING // Clear FIFOs, since data is no longer valid +#if !CFG_TUD_AUDIO_ENABLE_ENCODING tu_fifo_clear(&audio->ep_in_ff); +#else + for (uint8_t cnt = 0; cnt < audio->n_tx_supp_ff; cnt++) + { + tu_fifo_clear(&audio->tx_supp_ff[cnt]); + } #endif // Invoke callback - can be used to stop data sampling @@ -1491,14 +1496,6 @@ static bool audiod_set_interface(uint8_t rhport, tusb_control_request_t const * audio->ep_in = 0; // Necessary? - // Clear support FIFOs if used -#if CFG_TUD_AUDIO_ENABLE_ENCODING - for (uint8_t cnt = 0; cnt < audio->n_tx_supp_ff; cnt++) - { - tu_fifo_clear(&audio->tx_supp_ff[cnt]); - } -#endif - } #endif @@ -1508,9 +1505,14 @@ static bool audiod_set_interface(uint8_t rhport, tusb_control_request_t const * audio->ep_out_as_intf_num = 0; usbd_edpt_close(rhport, audio->ep_out); -#if !CFG_TUD_AUDIO_ENABLE_ENCODING // Clear FIFOs, since data is no longer valid +#if !CFG_TUD_AUDIO_ENABLE_DECODING tu_fifo_clear(&audio->ep_out_ff); +#else + for (uint8_t cnt = 0; cnt < audio->n_rx_supp_ff; cnt++) + { + tu_fifo_clear(&audio->rx_supp_ff[cnt]); + } #endif // Invoke callback - can be used to stop data sampling @@ -1518,14 +1520,6 @@ static bool audiod_set_interface(uint8_t rhport, tusb_control_request_t const * audio->ep_out = 0; // Necessary? - // Clear support FIFOs if used -#if CFG_TUD_AUDIO_ENABLE_DECODING - for (uint8_t cnt = 0; cnt < audio->n_rx_supp_ff; cnt++) - { - tu_fifo_clear(&audio->rx_supp_ff[cnt]); - } -#endif - // Close corresponding feedback EP #if CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP usbd_edpt_close(rhport, audio->ep_fb); -- cgit v1.3.1 From 82d355aefe5251f6dd15a7406920efaf516df705 Mon Sep 17 00:00:00 2001 From: MasterPhi Date: Tue, 6 Jul 2021 00:25:00 +0200 Subject: - Remove alt_setting alignment --- src/class/audio/audio_device.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src/class') diff --git a/src/class/audio/audio_device.c b/src/class/audio/audio_device.c index 97a9c495e..f6e6e13f4 100644 --- a/src/class/audio/audio_device.c +++ b/src/class/audio/audio_device.c @@ -183,12 +183,12 @@ CFG_TUSB_MEM_SECTION CFG_TUSB_MEM_ALIGN uint8_t ctrl_buf_3[CFG_TUD_AUDIO_FUNC_3_ #endif // Active alternate setting of interfaces -CFG_TUSB_MEM_SECTION CFG_TUSB_MEM_ALIGN uint8_t alt_setting_1[CFG_TUD_AUDIO_FUNC_1_N_AS_INT]; +uint8_t alt_setting_1[CFG_TUD_AUDIO_FUNC_1_N_AS_INT]; #if CFG_TUD_AUDIO > 1 && CFG_TUD_AUDIO_FUNC_2_N_AS_INT > 0 -CFG_TUSB_MEM_SECTION CFG_TUSB_MEM_ALIGN uint8_t alt_setting_2[CFG_TUD_AUDIO_FUNC_2_N_AS_INT]; +uint8_t alt_setting_2[CFG_TUD_AUDIO_FUNC_2_N_AS_INT]; #endif #if CFG_TUD_AUDIO > 2 && CFG_TUD_AUDIO_FUNC_3_N_AS_INT > 0 -CFG_TUSB_MEM_SECTION CFG_TUSB_MEM_ALIGN uint8_t alt_setting_3[CFG_TUD_AUDIO_FUNC_3_N_AS_INT]; +uint8_t alt_setting_3[CFG_TUD_AUDIO_FUNC_3_N_AS_INT]; #endif // Software encoding/decoding support FIFOs -- cgit v1.3.1 From 72f916423e85083a090186ecc05a6a5b8962685a Mon Sep 17 00:00:00 2001 From: MasterPhi Date: Tue, 6 Jul 2021 10:56:13 +0200 Subject: Fix copy byte count --- src/class/audio/audio_device.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) (limited to 'src/class') diff --git a/src/class/audio/audio_device.c b/src/class/audio/audio_device.c index f6e6e13f4..404d28817 100644 --- a/src/class/audio/audio_device.c +++ b/src/class/audio/audio_device.c @@ -643,7 +643,6 @@ static bool audiod_decode_type_I_pcm(uint8_t rhport, audiod_function_t* audio, u // Determine amount of samples uint8_t const n_ff_used = audio->n_ff_used_rx; - uint16_t const nBytesToCopy = audio->n_channels_per_ff_rx * audio->n_bytes_per_sampe_rx; uint16_t const nBytesPerFFToRead = n_bytes_received / n_ff_used; uint8_t cnt_ff; @@ -662,14 +661,14 @@ static bool audiod_decode_type_I_pcm(uint8_t rhport, audiod_function_t* audio, u info.len_lin = tu_min16(nBytesPerFFToRead, info.len_lin); src = &audio->lin_buf_out[cnt_ff*audio->n_channels_per_ff_rx * audio->n_bytes_per_sampe_rx]; dst_end = info.ptr_lin + info.len_lin; - src = audiod_interleaved_copy_bytes_fast_decode(nBytesToCopy, info.ptr_lin, dst_end, src, n_ff_used); + src = audiod_interleaved_copy_bytes_fast_decode(audio->n_bytes_per_sampe_rx, info.ptr_lin, dst_end, src, n_ff_used); // Handle wrapped part of FIFO info.len_wrap = tu_min16(nBytesPerFFToRead - info.len_lin, info.len_wrap); if (info.len_wrap != 0) { dst_end = info.ptr_wrap + info.len_wrap; - audiod_interleaved_copy_bytes_fast_decode(nBytesToCopy, info.ptr_wrap, dst_end, src, n_ff_used); + audiod_interleaved_copy_bytes_fast_decode(audio->n_bytes_per_sampe_rx, info.ptr_wrap, dst_end, src, n_ff_used); } tu_fifo_advance_write_pointer(&audio->rx_supp_ff[cnt_ff], info.len_lin + info.len_wrap); } @@ -994,7 +993,7 @@ static uint16_t audiod_encode_type_I_pcm(uint8_t rhport, audiod_function_t* audi { info.len_lin = tu_min16(nBytesPerFFToSend, info.len_lin); // Limit up to desired length src_end = (uint8_t *)info.ptr_lin + info.len_lin; - dst = audiod_interleaved_copy_bytes_fast_encode(nBytesToCopy, info.ptr_lin, src_end, dst, n_ff_used); + dst = audiod_interleaved_copy_bytes_fast_encode(audio->n_bytes_per_sampe_tx, info.ptr_lin, src_end, dst, n_ff_used); // Limit up to desired length info.len_wrap = tu_min16(nBytesPerFFToSend - info.len_lin, info.len_wrap); @@ -1003,7 +1002,7 @@ static uint16_t audiod_encode_type_I_pcm(uint8_t rhport, audiod_function_t* audi if (info.len_wrap != 0) { src_end = (uint8_t *)info.ptr_wrap + info.len_wrap; - audiod_interleaved_copy_bytes_fast_encode(nBytesToCopy, info.ptr_wrap, src_end, dst, n_ff_used); + audiod_interleaved_copy_bytes_fast_encode(audio->n_bytes_per_sampe_tx, info.ptr_wrap, src_end, dst, n_ff_used); } tu_fifo_advance_read_pointer(&audio->tx_supp_ff[cnt_ff], info.len_lin + info.len_wrap); -- cgit v1.3.1 From cf4220a9fb24279b423656257cea39b3ab68aa67 Mon Sep 17 00:00:00 2001 From: MasterPhi Date: Tue, 6 Jul 2021 18:03:05 +0200 Subject: Update --- examples/device/dfu/src/tusb_config.h | 1 + src/class/dfu/dfu_device.c | 3 +++ src/class/dfu/dfu_device.h | 11 +++++++++-- 3 files changed, 13 insertions(+), 2 deletions(-) (limited to 'src/class') diff --git a/examples/device/dfu/src/tusb_config.h b/examples/device/dfu/src/tusb_config.h index 90e90b2e4..0df46c14e 100644 --- a/examples/device/dfu/src/tusb_config.h +++ b/examples/device/dfu/src/tusb_config.h @@ -76,6 +76,7 @@ #define CFG_TUD_ENDPOINT0_SIZE 64 #endif +// DFU buffer size, must to be set to the largest buffer size used by an any given storage type #define CFG_TUD_DFU_TRANSFER_BUFFER_SIZE 4096 //------------- CLASS -------------// diff --git a/src/class/dfu/dfu_device.c b/src/class/dfu/dfu_device.c index 9eafca359..a186e9140 100644 --- a/src/class/dfu/dfu_device.c +++ b/src/class/dfu/dfu_device.c @@ -147,6 +147,7 @@ void dfu_moded_init(void) _dfu_state_ctx.status = DFU_STATUS_OK; _dfu_state_ctx.attrs = 0; _dfu_state_ctx.blk_transfer_in_proc = false; + _dfu_state_ctx.alt = 0; dfu_debug_print_context(); } @@ -158,6 +159,8 @@ void dfu_moded_reset(uint8_t rhport) _dfu_state_ctx.state = DFU_IDLE; _dfu_state_ctx.status = DFU_STATUS_OK; _dfu_state_ctx.blk_transfer_in_proc = false; + _dfu_state_ctx.alt = 0; + dfu_debug_print_context(); } diff --git a/src/class/dfu/dfu_device.h b/src/class/dfu/dfu_device.h index d5bc88ab2..c5c1ede28 100644 --- a/src/class/dfu/dfu_device.h +++ b/src/class/dfu/dfu_device.h @@ -33,6 +33,13 @@ extern "C" { #endif +//--------------------------------------------------------------------+ +// Class Driver Default Configure & Validation +//--------------------------------------------------------------------+ + +#if !defined(CFG_TUD_DFU_TRANSFER_BUFFER_SIZE) + #error " CFG_TUD_DFU_TRANSFER_BUFFER_SIZE must be defined, it have to be set to the largest buffer size used by an any given storage type" +#endif //--------------------------------------------------------------------+ // Application Callback API (weak is optional) @@ -45,7 +52,7 @@ bool tud_dfu_firmware_valid_check_cb(uint8_t alt); // This callback takes the wBlockNum chunk of length length and provides it // to the application at the data pointer. This data is only valid for this // call, so the app must use it not or copy it. -// alt is used as the partition number, in order to multiple partitions like FLASH, EEPROM, etc. +// alt is used as the partition number, in order to support multiple partitions like FLASH, EEPROM, etc. void tud_dfu_req_dnload_data_cb(uint8_t alt, uint16_t wBlockNum, uint8_t* data, uint16_t length); // Must be called when the application is done using the last block of data @@ -65,7 +72,7 @@ TU_ATTR_WEAK void tud_dfu_abort_cb(void); // Invoked when a DFU_UPLOAD request is received // This callback must populate data with up to length bytes // Return the number of bytes to write -// alt is used as the partition number, in order to multiple partitions like FLASH, EEPROM, etc. +// alt is used as the partition number, in order to support multiple partitions like FLASH, EEPROM, etc. TU_ATTR_WEAK uint16_t tud_dfu_req_upload_data_cb(uint8_t alt, uint16_t block_num, uint8_t* data, uint16_t length); //--------------------------------------------------------------------+ -- cgit v1.3.1 From bc49ee7f2fc74932c332520b0fd8eccefbae659a Mon Sep 17 00:00:00 2001 From: Mengsk Date: Wed, 7 Jul 2021 11:55:36 +0200 Subject: Better alt settings support --- src/class/dfu/dfu_device.c | 92 +++++++++++++++++++++++++++++++++------------- src/class/dfu/dfu_device.h | 7 +++- 2 files changed, 72 insertions(+), 27 deletions(-) (limited to 'src/class') diff --git a/src/class/dfu/dfu_device.c b/src/class/dfu/dfu_device.c index a186e9140..f6fcb1339 100644 --- a/src/class/dfu/dfu_device.c +++ b/src/class/dfu/dfu_device.c @@ -37,6 +37,8 @@ // MACRO CONSTANT TYPEDEF //--------------------------------------------------------------------+ +#define DFU_INTF_UNUSED 0xFF + //--------------------------------------------------------------------+ // INTERNAL OBJECT & FUNCTION DECLARATION //--------------------------------------------------------------------+ @@ -44,9 +46,10 @@ typedef struct TU_ATTR_PACKED { dfu_device_status_t status; dfu_state_t state; - uint8_t attrs; + uint8_t attrs[CFG_TUD_DFU_ATL_MAX]; bool blk_transfer_in_proc; uint8_t alt; + uint8_t intf; CFG_TUSB_MEM_ALIGN uint8_t transfer_buf[CFG_TUD_DFU_TRANSFER_BUFFER_SIZE]; } dfu_state_ctx_t; @@ -145,9 +148,13 @@ void dfu_moded_init(void) { _dfu_state_ctx.state = DFU_IDLE; _dfu_state_ctx.status = DFU_STATUS_OK; - _dfu_state_ctx.attrs = 0; + for (uint8_t i = 0; i < CFG_TUD_DFU_ATL_MAX; i++) + { + _dfu_state_ctx.attrs[i] = 0; + } _dfu_state_ctx.blk_transfer_in_proc = false; _dfu_state_ctx.alt = 0; + _dfu_state_ctx.intf = DFU_INTF_UNUSED; dfu_debug_print_context(); } @@ -158,8 +165,13 @@ void dfu_moded_reset(uint8_t rhport) _dfu_state_ctx.state = DFU_IDLE; _dfu_state_ctx.status = DFU_STATUS_OK; + for (uint8_t i = 0; i < CFG_TUD_DFU_ATL_MAX; i++) + { + _dfu_state_ctx.attrs[i] = 0; + } _dfu_state_ctx.blk_transfer_in_proc = false; _dfu_state_ctx.alt = 0; + _dfu_state_ctx.intf = DFU_INTF_UNUSED; dfu_debug_print_context(); } @@ -167,32 +179,55 @@ void dfu_moded_reset(uint8_t rhport) uint16_t dfu_moded_open(uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint16_t max_len) { (void) rhport; - (void) max_len; - uint16_t drv_len = 0; - uint8_t const * p_desc = (uint8_t*)itf_desc; + uint16_t const drv_len = sizeof(tusb_desc_interface_t) + sizeof(tusb_desc_dfu_functional_t); + + uint8_t const *p_desc = (uint8_t const *)itf_desc; - while (max_len) + uint16_t total_len = 0; + + uint8_t last_alt = 0; + + while(max_len >= drv_len) { // Ensure this is DFU Mode TU_VERIFY((((tusb_desc_interface_t const *)p_desc)->bInterfaceSubClass == TUD_DFU_APP_SUBCLASS) && - (((tusb_desc_interface_t const *)p_desc)->bInterfaceProtocol == DFU_PROTOCOL_DFU), drv_len); - - p_desc = tu_desc_next( p_desc ); - drv_len += tu_desc_len(p_desc); + (((tusb_desc_interface_t const *)p_desc)->bInterfaceProtocol == DFU_PROTOCOL_DFU), 0); - if ( TUSB_DESC_FUNCTIONAL == tu_desc_type(p_desc) ) - { - tusb_desc_dfu_functional_t const *dfu_desc = (tusb_desc_dfu_functional_t const *)p_desc; - _dfu_state_ctx.attrs = (uint8_t)dfu_desc->bAttributes; + uint8_t const alt = ((tusb_desc_interface_t const *)p_desc)->bAlternateSetting; + uint8_t const intf = ((tusb_desc_interface_t const *)p_desc)->bInterfaceNumber; - drv_len += tu_desc_len(p_desc); - p_desc = tu_desc_next(p_desc); + if (_dfu_state_ctx.intf == DFU_INTF_UNUSED) + { + _dfu_state_ctx.intf = intf; } + else + { + // Only one DFU interface is supported + TU_ASSERT(_dfu_state_ctx.intf == intf); + } + + // CFG_TUD_DFU_ATL_MAX should big enough to hold all alt settings + TU_ASSERT(alt < CFG_TUD_DFU_ATL_MAX); + + // Alt should increse by one every time + TU_ASSERT(alt == last_alt++); + + //------------- DFU descriptor -------------// + p_desc = tu_desc_next(p_desc); + TU_ASSERT(tu_desc_type(p_desc) == TUSB_DESC_FUNCTIONAL, 0); + _dfu_state_ctx.attrs[alt] = ((tusb_desc_dfu_functional_t const *)p_desc)->bAttributes; + + // CFG_TUD_DFU_TRANSFER_BUFFER_SIZE has to be set to the largest buffer size used by all alt settings + TU_ASSERT(((tusb_desc_dfu_functional_t const *)p_desc)->wTransferSize <= CFG_TUD_DFU_TRANSFER_BUFFER_SIZE); + + p_desc = tu_desc_next(p_desc); max_len -= drv_len; + total_len += drv_len; } - return drv_len; + + return total_len; } // Invoked when a control transfer occurred on an interface of this class @@ -208,11 +243,16 @@ bool dfu_moded_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_reque if(stage == CONTROL_STAGE_SETUP) { // dfu-util will try to claim the interface with SET_INTERFACE request before sending DFU request - if ( TUSB_REQ_TYPE_STANDARD == request->bmRequestType_bit.type && - TUSB_REQ_SET_INTERFACE == request->bRequest ) + if (request->bmRequestType_bit.type == TUSB_REQ_TYPE_STANDARD && request->bRequest == TUSB_REQ_SET_INTERFACE) { - // Save Alt interface + // Switch Alt interface _dfu_state_ctx.alt = request->wValue; + + // Re-initalise state machine (Necessary ?) + _dfu_state_ctx.state = DFU_IDLE; + _dfu_state_ctx.status = DFU_STATUS_OK; + _dfu_state_ctx.blk_transfer_in_proc = false; + tud_control_status(rhport, request); return true; } @@ -226,7 +266,7 @@ bool dfu_moded_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_reque case DFU_REQUEST_DNLOAD: { if ( (stage == CONTROL_STAGE_ACK) - && ((_dfu_state_ctx.attrs & DFU_FUNC_ATTR_CAN_DOWNLOAD_BITMASK) != 0) + && ((_dfu_state_ctx.attrs[_dfu_state_ctx.alt] & DFU_FUNC_ATTR_CAN_DOWNLOAD_BITMASK) != 0) && (_dfu_state_ctx.state == DFU_DNLOAD_SYNC)) { dfu_req_dnload_reply(rhport, request); @@ -313,7 +353,7 @@ void tud_dfu_dnload_complete(void) _dfu_state_ctx.state = DFU_DNLOAD_SYNC; } else if (_dfu_state_ctx.state == DFU_MANIFEST) { - _dfu_state_ctx.state = ((_dfu_state_ctx.attrs & DFU_FUNC_ATTR_MANIFESTATION_TOLERANT_BITMASK) == 0) + _dfu_state_ctx.state = ((_dfu_state_ctx.attrs[_dfu_state_ctx.alt] & DFU_FUNC_ATTR_MANIFESTATION_TOLERANT_BITMASK) == 0) ? DFU_MANIFEST_WAIT_RESET : DFU_MANIFEST_SYNC; } } @@ -331,7 +371,7 @@ static bool dfu_state_machine(uint8_t rhport, tusb_control_request_t const * req { case DFU_REQUEST_DNLOAD: { - if( ((_dfu_state_ctx.attrs & DFU_FUNC_ATTR_CAN_DOWNLOAD_BITMASK) != 0) + if( ((_dfu_state_ctx.attrs[_dfu_state_ctx.alt] & DFU_FUNC_ATTR_CAN_DOWNLOAD_BITMASK) != 0) && (request->wLength > 0) ) { _dfu_state_ctx.state = DFU_DNLOAD_SYNC; @@ -345,7 +385,7 @@ static bool dfu_state_machine(uint8_t rhport, tusb_control_request_t const * req case DFU_REQUEST_UPLOAD: { - if( ((_dfu_state_ctx.attrs & DFU_FUNC_ATTR_CAN_UPLOAD_BITMASK) != 0) ) + if( ((_dfu_state_ctx.attrs[_dfu_state_ctx.alt] & DFU_FUNC_ATTR_CAN_UPLOAD_BITMASK) != 0) ) { _dfu_state_ctx.state = DFU_UPLOAD_IDLE; dfu_req_upload(rhport, request, request->wValue, request->wLength); @@ -436,7 +476,7 @@ static bool dfu_state_machine(uint8_t rhport, tusb_control_request_t const * req { case DFU_REQUEST_DNLOAD: { - if( ((_dfu_state_ctx.attrs & DFU_FUNC_ATTR_CAN_DOWNLOAD_BITMASK) != 0) + if( ((_dfu_state_ctx.attrs[_dfu_state_ctx.alt] & DFU_FUNC_ATTR_CAN_DOWNLOAD_BITMASK) != 0) && (request->wLength > 0) ) { _dfu_state_ctx.state = DFU_DNLOAD_SYNC; @@ -493,7 +533,7 @@ static bool dfu_state_machine(uint8_t rhport, tusb_control_request_t const * req { case DFU_REQUEST_GETSTATUS: { - if ((_dfu_state_ctx.attrs & DFU_FUNC_ATTR_MANIFESTATION_TOLERANT_BITMASK) == 0) + if ((_dfu_state_ctx.attrs[_dfu_state_ctx.alt] & DFU_FUNC_ATTR_MANIFESTATION_TOLERANT_BITMASK) == 0) { _dfu_state_ctx.state = DFU_MANIFEST; dfu_req_getstatus_reply(rhport, request); diff --git a/src/class/dfu/dfu_device.h b/src/class/dfu/dfu_device.h index c5c1ede28..6f826152f 100644 --- a/src/class/dfu/dfu_device.h +++ b/src/class/dfu/dfu_device.h @@ -37,8 +37,13 @@ // Class Driver Default Configure & Validation //--------------------------------------------------------------------+ +// Maximum alternate settings (used for different partitons) supported +#if !defined(CFG_TUD_DFU_ATL_MAX) + #define CFG_TUD_DFU_ATL_MAX 2 +#endif + #if !defined(CFG_TUD_DFU_TRANSFER_BUFFER_SIZE) - #error " CFG_TUD_DFU_TRANSFER_BUFFER_SIZE must be defined, it have to be set to the largest buffer size used by an any given storage type" + #error "CFG_TUD_DFU_TRANSFER_BUFFER_SIZE must be defined, it has to be set to the largest buffer size used by an any given storage type" #endif //--------------------------------------------------------------------+ -- cgit v1.3.1 From 88478594bc0c5946853567620beb944940f81a1d Mon Sep 17 00:00:00 2001 From: Mengsk Date: Wed, 7 Jul 2021 12:06:41 +0200 Subject: Update comment --- src/class/dfu/dfu_device.h | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'src/class') diff --git a/src/class/dfu/dfu_device.h b/src/class/dfu/dfu_device.h index 6f826152f..67d15c3c6 100644 --- a/src/class/dfu/dfu_device.h +++ b/src/class/dfu/dfu_device.h @@ -49,15 +49,15 @@ //--------------------------------------------------------------------+ // Application Callback API (weak is optional) //--------------------------------------------------------------------+ -// Invoked during DFU_MANIFEST_SYNC get status request to check if firmware -// is valid +// Invoked during DFU_MANIFEST_SYNC get status request to check if firmware is valid +// alt is used as the partition number, in order to support multiple partitions like FLASH, EEPROM, etc. bool tud_dfu_firmware_valid_check_cb(uint8_t alt); // Invoked when a DFU_DNLOAD request is received +// alt is used as the partition number, in order to support multiple partitions like FLASH, EEPROM, etc. // This callback takes the wBlockNum chunk of length length and provides it // to the application at the data pointer. This data is only valid for this // call, so the app must use it not or copy it. -// alt is used as the partition number, in order to support multiple partitions like FLASH, EEPROM, etc. void tud_dfu_req_dnload_data_cb(uint8_t alt, uint16_t wBlockNum, uint8_t* data, uint16_t length); // Must be called when the application is done using the last block of data @@ -66,6 +66,7 @@ void tud_dfu_dnload_complete(void); // Invoked during the last DFU_DNLOAD request, signifying that the host believes // it is done transmitting data. +// alt is used as the partition number, in order to support multiple partitions like FLASH, EEPROM, etc. // Return true if the application agrees there is no more data // Return false if the device disagrees, which will stall the pipe, and the Host // should initiate a recovery procedure @@ -75,9 +76,9 @@ bool tud_dfu_device_data_done_check_cb(uint8_t alt); TU_ATTR_WEAK void tud_dfu_abort_cb(void); // Invoked when a DFU_UPLOAD request is received +// alt is used as the partition number, in order to support multiple partitions like FLASH, EEPROM, etc. // This callback must populate data with up to length bytes // Return the number of bytes to write -// alt is used as the partition number, in order to support multiple partitions like FLASH, EEPROM, etc. TU_ATTR_WEAK uint16_t tud_dfu_req_upload_data_cb(uint8_t alt, uint16_t block_num, uint8_t* data, uint16_t length); //--------------------------------------------------------------------+ -- cgit v1.3.1 From 3949fb9e8c1b9a9646223e3edf7a0df4f010b5be Mon Sep 17 00:00:00 2001 From: Mengsk Date: Wed, 7 Jul 2021 12:07:10 +0200 Subject: Add DFU_DETACH support --- src/class/dfu/dfu_device.c | 7 ++++++- src/class/dfu/dfu_device.h | 2 ++ 2 files changed, 8 insertions(+), 1 deletion(-) (limited to 'src/class') diff --git a/src/class/dfu/dfu_device.c b/src/class/dfu/dfu_device.c index f6fcb1339..f4edd713a 100644 --- a/src/class/dfu/dfu_device.c +++ b/src/class/dfu/dfu_device.c @@ -263,6 +263,12 @@ bool dfu_moded_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_reque switch (request->bRequest) { + case DFU_REQUEST_DETACH: + { + tud_control_status(rhport, request); + if (tud_dfu_reboot_cb) tud_dfu_reboot_cb(); + break; + } case DFU_REQUEST_DNLOAD: { if ( (stage == CONTROL_STAGE_ACK) @@ -273,7 +279,6 @@ bool dfu_moded_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_reque return true; } } // fallthrough - case DFU_REQUEST_DETACH: case DFU_REQUEST_UPLOAD: case DFU_REQUEST_GETSTATUS: case DFU_REQUEST_CLRSTATUS: diff --git a/src/class/dfu/dfu_device.h b/src/class/dfu/dfu_device.h index 67d15c3c6..53be0005e 100644 --- a/src/class/dfu/dfu_device.h +++ b/src/class/dfu/dfu_device.h @@ -81,6 +81,8 @@ TU_ATTR_WEAK void tud_dfu_abort_cb(void); // Return the number of bytes to write TU_ATTR_WEAK uint16_t tud_dfu_req_upload_data_cb(uint8_t alt, uint16_t block_num, uint8_t* data, uint16_t length); +// Invoked when a DFU_DETACH request is received +TU_ATTR_WEAK void tud_dfu_reboot_cb(void); //--------------------------------------------------------------------+ // Internal Class Driver API //--------------------------------------------------------------------+ -- cgit v1.3.1 From 71c00432610780f07d0e0776eacdda1186481854 Mon Sep 17 00:00:00 2001 From: Mengsk Date: Wed, 7 Jul 2021 12:18:25 +0200 Subject: TU_ASSERT return 0. --- src/class/dfu/dfu_device.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src/class') diff --git a/src/class/dfu/dfu_device.c b/src/class/dfu/dfu_device.c index f4edd713a..8bf2e16be 100644 --- a/src/class/dfu/dfu_device.c +++ b/src/class/dfu/dfu_device.c @@ -204,14 +204,14 @@ uint16_t dfu_moded_open(uint8_t rhport, tusb_desc_interface_t const * itf_desc, else { // Only one DFU interface is supported - TU_ASSERT(_dfu_state_ctx.intf == intf); + TU_ASSERT(_dfu_state_ctx.intf == intf, 0); } // CFG_TUD_DFU_ATL_MAX should big enough to hold all alt settings - TU_ASSERT(alt < CFG_TUD_DFU_ATL_MAX); + TU_ASSERT(alt < CFG_TUD_DFU_ATL_MAX, 0); // Alt should increse by one every time - TU_ASSERT(alt == last_alt++); + TU_ASSERT(alt == last_alt++, 0); //------------- DFU descriptor -------------// p_desc = tu_desc_next(p_desc); @@ -220,7 +220,7 @@ uint16_t dfu_moded_open(uint8_t rhport, tusb_desc_interface_t const * itf_desc, _dfu_state_ctx.attrs[alt] = ((tusb_desc_dfu_functional_t const *)p_desc)->bAttributes; // CFG_TUD_DFU_TRANSFER_BUFFER_SIZE has to be set to the largest buffer size used by all alt settings - TU_ASSERT(((tusb_desc_dfu_functional_t const *)p_desc)->wTransferSize <= CFG_TUD_DFU_TRANSFER_BUFFER_SIZE); + TU_ASSERT(((tusb_desc_dfu_functional_t const *)p_desc)->wTransferSize <= CFG_TUD_DFU_TRANSFER_BUFFER_SIZE, 0); p_desc = tu_desc_next(p_desc); max_len -= drv_len; -- cgit v1.3.1 From 941b02c6a98cd34eb84cf499db9810108871d49b Mon Sep 17 00:00:00 2001 From: Mengsk Date: Wed, 7 Jul 2021 18:02:04 +0200 Subject: Reactor to one functional descriptor. --- examples/device/dfu/src/tusb_config.h | 8 +++-- examples/device/dfu/src/usb_descriptors.c | 7 ++--- src/class/dfu/dfu_device.c | 51 ++++++++++++++----------------- src/class/dfu/dfu_device.h | 7 +---- src/device/usbd.h | 47 +++++++++++++++++++++++----- 5 files changed, 72 insertions(+), 48 deletions(-) (limited to 'src/class') diff --git a/examples/device/dfu/src/tusb_config.h b/examples/device/dfu/src/tusb_config.h index 0df46c14e..55aa19922 100644 --- a/examples/device/dfu/src/tusb_config.h +++ b/examples/device/dfu/src/tusb_config.h @@ -76,14 +76,16 @@ #define CFG_TUD_ENDPOINT0_SIZE 64 #endif -// DFU buffer size, must to be set to the largest buffer size used by an any given storage type -#define CFG_TUD_DFU_TRANSFER_BUFFER_SIZE 4096 - //------------- CLASS -------------// #define CFG_TUD_DFU_RUNTIME 0 #define CFG_TUD_DFU_MODE 1 +// Count of all alt settings, typically it's the partition count (Flash, EEPROM, etc.) +#define CFG_TUD_DFU_ALT_COUNT 2 +// DFU buffer size, it has to be set to the buffer size used in TUD_DFU_MODE_DESCRIPTOR +#define CFG_TUD_DFU_TRANSFER_BUFFER_SIZE 4096 + #ifdef __cplusplus } #endif diff --git a/examples/device/dfu/src/usb_descriptors.c b/examples/device/dfu/src/usb_descriptors.c index 9565da9b2..200817eb4 100644 --- a/examples/device/dfu/src/usb_descriptors.c +++ b/examples/device/dfu/src/usb_descriptors.c @@ -87,7 +87,7 @@ enum ITF_NUM_TOTAL }; -#define CONFIG_TOTAL_LEN (TUD_CONFIG_DESC_LEN + 2 * TUD_DFU_MODE_DESC_LEN) +#define CONFIG_TOTAL_LEN (TUD_CONFIG_DESC_LEN + TUD_DFU_MODE_DESC_LEN) #define FUNC_ATTRS (DFU_FUNC_ATTR_CAN_UPLOAD_BITMASK | DFU_FUNC_ATTR_CAN_DOWNLOAD_BITMASK) @@ -96,9 +96,8 @@ uint8_t const desc_configuration[] = // Config number, interface count, string index, total length, attribute, power in mA TUD_CONFIG_DESCRIPTOR(1, ITF_NUM_TOTAL, 0, CONFIG_TOTAL_LEN, TUSB_DESC_CONFIG_ATT_REMOTE_WAKEUP, 100), - // Interface number, string index, attributes, detach timeout, transfer size */ - TUD_DFU_MODE_DESCRIPTOR(ITF_NUM_DFU_MODE, 0, 4, FUNC_ATTRS, 1000, CFG_TUD_DFU_TRANSFER_BUFFER_SIZE), - TUD_DFU_MODE_DESCRIPTOR(ITF_NUM_DFU_MODE, 1, 5, FUNC_ATTRS, 1000, CFG_TUD_DFU_TRANSFER_BUFFER_SIZE), + // Interface number, detach timeout, transfer size, string index 0, [string index 1 ... string index n] + TUD_DFU_MODE_DESCRIPTOR(ITF_NUM_DFU_MODE, 0, FUNC_ATTRS, 1000, CFG_TUD_DFU_TRANSFER_BUFFER_SIZE, 4, 5), }; // Invoked when received GET CONFIGURATION DESCRIPTOR diff --git a/src/class/dfu/dfu_device.c b/src/class/dfu/dfu_device.c index 8bf2e16be..834648c5a 100644 --- a/src/class/dfu/dfu_device.c +++ b/src/class/dfu/dfu_device.c @@ -46,7 +46,7 @@ typedef struct TU_ATTR_PACKED { dfu_device_status_t status; dfu_state_t state; - uint8_t attrs[CFG_TUD_DFU_ATL_MAX]; + uint8_t attrs; bool blk_transfer_in_proc; uint8_t alt; uint8_t intf; @@ -148,10 +148,7 @@ void dfu_moded_init(void) { _dfu_state_ctx.state = DFU_IDLE; _dfu_state_ctx.status = DFU_STATUS_OK; - for (uint8_t i = 0; i < CFG_TUD_DFU_ATL_MAX; i++) - { - _dfu_state_ctx.attrs[i] = 0; - } + _dfu_state_ctx.attrs = 0; _dfu_state_ctx.blk_transfer_in_proc = false; _dfu_state_ctx.alt = 0; _dfu_state_ctx.intf = DFU_INTF_UNUSED; @@ -165,10 +162,7 @@ void dfu_moded_reset(uint8_t rhport) _dfu_state_ctx.state = DFU_IDLE; _dfu_state_ctx.status = DFU_STATUS_OK; - for (uint8_t i = 0; i < CFG_TUD_DFU_ATL_MAX; i++) - { - _dfu_state_ctx.attrs[i] = 0; - } + _dfu_state_ctx.attrs = 0; _dfu_state_ctx.blk_transfer_in_proc = false; _dfu_state_ctx.alt = 0; _dfu_state_ctx.intf = DFU_INTF_UNUSED; @@ -180,15 +174,15 @@ uint16_t dfu_moded_open(uint8_t rhport, tusb_desc_interface_t const * itf_desc, { (void) rhport; - uint16_t const drv_len = sizeof(tusb_desc_interface_t) + sizeof(tusb_desc_dfu_functional_t); + uint16_t const drv_len = sizeof(tusb_desc_interface_t); uint8_t const *p_desc = (uint8_t const *)itf_desc; uint16_t total_len = 0; - + uint8_t last_alt = 0; - while(max_len >= drv_len) + while(max_len > drv_len) { // Ensure this is DFU Mode TU_VERIFY((((tusb_desc_interface_t const *)p_desc)->bInterfaceSubClass == TUD_DFU_APP_SUBCLASS) && @@ -208,25 +202,26 @@ uint16_t dfu_moded_open(uint8_t rhport, tusb_desc_interface_t const * itf_desc, } // CFG_TUD_DFU_ATL_MAX should big enough to hold all alt settings - TU_ASSERT(alt < CFG_TUD_DFU_ATL_MAX, 0); + TU_ASSERT(alt < CFG_TUD_DFU_ALT_COUNT, 0); // Alt should increse by one every time TU_ASSERT(alt == last_alt++, 0); - //------------- DFU descriptor -------------// - p_desc = tu_desc_next(p_desc); - TU_ASSERT(tu_desc_type(p_desc) == TUSB_DESC_FUNCTIONAL, 0); - - _dfu_state_ctx.attrs[alt] = ((tusb_desc_dfu_functional_t const *)p_desc)->bAttributes; - - // CFG_TUD_DFU_TRANSFER_BUFFER_SIZE has to be set to the largest buffer size used by all alt settings - TU_ASSERT(((tusb_desc_dfu_functional_t const *)p_desc)->wTransferSize <= CFG_TUD_DFU_TRANSFER_BUFFER_SIZE, 0); - p_desc = tu_desc_next(p_desc); max_len -= drv_len; total_len += drv_len; } + //------------- DFU descriptor -------------// + TU_ASSERT(tu_desc_type(p_desc) == TUSB_DESC_FUNCTIONAL, 0); + + _dfu_state_ctx.attrs = ((tusb_desc_dfu_functional_t const *)p_desc)->bAttributes; + + // CFG_TUD_DFU_TRANSFER_BUFFER_SIZE has to be set to the buffer size used in TUD_DFU_MODE_DESCRIPTOR + TU_ASSERT(((tusb_desc_dfu_functional_t const *)p_desc)->wTransferSize <= CFG_TUD_DFU_TRANSFER_BUFFER_SIZE, 0); + + total_len += sizeof(tusb_desc_dfu_functional_t); + return total_len; } @@ -272,7 +267,7 @@ bool dfu_moded_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_reque case DFU_REQUEST_DNLOAD: { if ( (stage == CONTROL_STAGE_ACK) - && ((_dfu_state_ctx.attrs[_dfu_state_ctx.alt] & DFU_FUNC_ATTR_CAN_DOWNLOAD_BITMASK) != 0) + && ((_dfu_state_ctx.attrs & DFU_FUNC_ATTR_CAN_DOWNLOAD_BITMASK) != 0) && (_dfu_state_ctx.state == DFU_DNLOAD_SYNC)) { dfu_req_dnload_reply(rhport, request); @@ -358,7 +353,7 @@ void tud_dfu_dnload_complete(void) _dfu_state_ctx.state = DFU_DNLOAD_SYNC; } else if (_dfu_state_ctx.state == DFU_MANIFEST) { - _dfu_state_ctx.state = ((_dfu_state_ctx.attrs[_dfu_state_ctx.alt] & DFU_FUNC_ATTR_MANIFESTATION_TOLERANT_BITMASK) == 0) + _dfu_state_ctx.state = ((_dfu_state_ctx.attrs & DFU_FUNC_ATTR_MANIFESTATION_TOLERANT_BITMASK) == 0) ? DFU_MANIFEST_WAIT_RESET : DFU_MANIFEST_SYNC; } } @@ -376,7 +371,7 @@ static bool dfu_state_machine(uint8_t rhport, tusb_control_request_t const * req { case DFU_REQUEST_DNLOAD: { - if( ((_dfu_state_ctx.attrs[_dfu_state_ctx.alt] & DFU_FUNC_ATTR_CAN_DOWNLOAD_BITMASK) != 0) + if( ((_dfu_state_ctx.attrs & DFU_FUNC_ATTR_CAN_DOWNLOAD_BITMASK) != 0) && (request->wLength > 0) ) { _dfu_state_ctx.state = DFU_DNLOAD_SYNC; @@ -390,7 +385,7 @@ static bool dfu_state_machine(uint8_t rhport, tusb_control_request_t const * req case DFU_REQUEST_UPLOAD: { - if( ((_dfu_state_ctx.attrs[_dfu_state_ctx.alt] & DFU_FUNC_ATTR_CAN_UPLOAD_BITMASK) != 0) ) + if( ((_dfu_state_ctx.attrs & DFU_FUNC_ATTR_CAN_UPLOAD_BITMASK) != 0) ) { _dfu_state_ctx.state = DFU_UPLOAD_IDLE; dfu_req_upload(rhport, request, request->wValue, request->wLength); @@ -481,7 +476,7 @@ static bool dfu_state_machine(uint8_t rhport, tusb_control_request_t const * req { case DFU_REQUEST_DNLOAD: { - if( ((_dfu_state_ctx.attrs[_dfu_state_ctx.alt] & DFU_FUNC_ATTR_CAN_DOWNLOAD_BITMASK) != 0) + if( ((_dfu_state_ctx.attrs & DFU_FUNC_ATTR_CAN_DOWNLOAD_BITMASK) != 0) && (request->wLength > 0) ) { _dfu_state_ctx.state = DFU_DNLOAD_SYNC; @@ -538,7 +533,7 @@ static bool dfu_state_machine(uint8_t rhport, tusb_control_request_t const * req { case DFU_REQUEST_GETSTATUS: { - if ((_dfu_state_ctx.attrs[_dfu_state_ctx.alt] & DFU_FUNC_ATTR_MANIFESTATION_TOLERANT_BITMASK) == 0) + if ((_dfu_state_ctx.attrs & DFU_FUNC_ATTR_MANIFESTATION_TOLERANT_BITMASK) == 0) { _dfu_state_ctx.state = DFU_MANIFEST; dfu_req_getstatus_reply(rhport, request); diff --git a/src/class/dfu/dfu_device.h b/src/class/dfu/dfu_device.h index 53be0005e..f41b4b651 100644 --- a/src/class/dfu/dfu_device.h +++ b/src/class/dfu/dfu_device.h @@ -37,13 +37,8 @@ // Class Driver Default Configure & Validation //--------------------------------------------------------------------+ -// Maximum alternate settings (used for different partitons) supported -#if !defined(CFG_TUD_DFU_ATL_MAX) - #define CFG_TUD_DFU_ATL_MAX 2 -#endif - #if !defined(CFG_TUD_DFU_TRANSFER_BUFFER_SIZE) - #error "CFG_TUD_DFU_TRANSFER_BUFFER_SIZE must be defined, it has to be set to the largest buffer size used by an any given storage type" + #error "CFG_TUD_DFU_TRANSFER_BUFFER_SIZE must be defined, it has to be set to the buffer size used in TUD_DFU_MODE_DESCRIPTOR" #endif //--------------------------------------------------------------------+ diff --git a/src/device/usbd.h b/src/device/usbd.h index 41c78de10..fe1863706 100644 --- a/src/device/usbd.h +++ b/src/device/usbd.h @@ -600,17 +600,50 @@ TU_ATTR_WEAK bool tud_vendor_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb /* Function */ \ 9, DFU_DESC_FUNCTIONAL, _attr, U16_TO_U8S_LE(_timeout), U16_TO_U8S_LE(_xfer_size), U16_TO_U8S_LE(0x0101) -// Length of template descriptr: 18 bytes -#define TUD_DFU_MODE_DESC_LEN (9 + 9) +// Maximum alternate settings (used for different partitons) supported +#ifndef CFG_TUD_DFU_ALT_COUNT +#define CFG_TUD_DFU_ALT_COUNT 1 +#endif -// DFU mode descriptor -// Interface number, alt settings, string index, attributes, detach timeout, transfer size -#define TUD_DFU_MODE_DESCRIPTOR(_itfnum, _alt, _stridx, _attr, _timeout, _xfer_size) \ - /* Interface */ \ - 9, TUSB_DESC_INTERFACE, _itfnum, _alt, 0, TUD_DFU_APP_CLASS, TUD_DFU_APP_SUBCLASS, DFU_PROTOCOL_DFU, _stridx, \ +// Length of template descriptor: 18 bytes + number of alternatives * 9 +#define TUD_DFU_MODE_DESC_LEN (9 + (CFG_TUD_DFU_ALT_COUNT) * 9) + +/* Primary Interface */ +#define TUD_DFU_MODE_FUNC(_attr, _timeout, _xfer_size) \ /* Function */ \ 9, DFU_DESC_FUNCTIONAL, _attr, U16_TO_U8S_LE(_timeout), U16_TO_U8S_LE(_xfer_size), U16_TO_U8S_LE(0x0101) +#define TUD_DFU_MODE_ALT(_itfnum, _alt, _stridx) \ + /* Interface */ \ + 9, TUSB_DESC_INTERFACE, _itfnum, _alt, 0, TUD_DFU_APP_CLASS, TUD_DFU_APP_SUBCLASS, DFU_PROTOCOL_DFU, _stridx, \ + +#define _TUD_DFU_FIRST(a, ...) a +#define _TUD_DFU_REST(a, ...) __VA_ARGS__ +#define _TUD_DFU_COMBINE(...) __VA_ARGS__ + +#define TUD_DFU_MODE_ALT_1(_itfnum, ...) TUD_DFU_MODE_ALT(_itfnum, (CFG_TUD_DFU_ALT_COUNT) - 1, _TUD_DFU_FIRST(__VA_ARGS__)) +#define TUD_DFU_MODE_ALT_2(_itfnum, ...) TUD_DFU_MODE_ALT(_itfnum, (CFG_TUD_DFU_ALT_COUNT) - 2, _TUD_DFU_FIRST(__VA_ARGS__)) \ + TUD_DFU_MODE_ALT_1(_itfnum, _TUD_DFU_REST(__VA_ARGS__)) +#define TUD_DFU_MODE_ALT_3(_itfnum, ...) TUD_DFU_MODE_ALT(_itfnum, (CFG_TUD_DFU_ALT_COUNT) - 3, _TUD_DFU_FIRST(__VA_ARGS__)) \ + TUD_DFU_MODE_ALT_2(_itfnum, _TUD_DFU_REST(__VA_ARGS__)) +#define TUD_DFU_MODE_ALT_4(_itfnum, ...) TUD_DFU_MODE_ALT(_itfnum, (CFG_TUD_DFU_ALT_COUNT) - 4, _TUD_DFU_FIRST(__VA_ARGS__)) \ + TUD_DFU_MODE_ALT_3(_itfnum, _TUD_DFU_REST(__VA_ARGS__)) +#define TUD_DFU_MODE_ALT_5(_itfnum, ...) TUD_DFU_MODE_ALT(_itfnum, (CFG_TUD_DFU_ALT_COUNT) - 5, _TUD_DFU_FIRST(__VA_ARGS__)) \ + TUD_DFU_MODE_ALT_4(_itfnum, _TUD_DFU_REST(__VA_ARGS__)) +#define TUD_DFU_MODE_ALT_6(_itfnum, ...) TUD_DFU_MODE_ALT(_itfnum, (CFG_TUD_DFU_ALT_COUNT) - 6, _TUD_DFU_FIRST(__VA_ARGS__)) \ + TUD_DFU_MODE_ALT_5(_itfnum, _TUD_DFU_REST(__VA_ARGS__)) +#define TUD_DFU_MODE_ALT_7(_itfnum, ...) TUD_DFU_MODE_ALT(_itfnum, (CFG_TUD_DFU_ALT_COUNT) - 7, _TUD_DFU_FIRST(__VA_ARGS__)) \ + TUD_DFU_MODE_ALT_6(_itfnum, _TUD_DFU_REST(__VA_ARGS__)) +#define TUD_DFU_MODE_ALT_8(_itfnum, ...) TUD_DFU_MODE_ALT(_itfnum, (CFG_TUD_DFU_ALT_COUNT) - 8, _TUD_DFU_FIRST(__VA_ARGS__)) \ + TUD_DFU_MODE_ALT_7(_itfnum, _TUD_DFU_REST(__VA_ARGS__)) + +#define TUD_DFU_MODE_ALTS(_itfnum, ...) \ + TU_XSTRCAT(TUD_DFU_MODE_ALT_, CFG_TUD_DFU_ALT_COUNT)(_itfnum, __VA_ARGS__) + +// Interface number, detach timeout, transfer size, string index 1, [string index 2, string index n] +#define TUD_DFU_MODE_DESCRIPTOR(_itfnum, _attr, _timeout, _xfer_size, _stridx, ...) \ + TUD_DFU_MODE_ALTS(_itfnum, _TUD_DFU_COMBINE(_stridx, __VA_ARGS__)) \ + TUD_DFU_MODE_FUNC(_attr, _timeout, _xfer_size) //------------- CDC-ECM -------------// -- cgit v1.3.1 From 7e883e0f41a4fdda699bbaf1d64a28d82527b8f9 Mon Sep 17 00:00:00 2001 From: HiFiPhile Date: Wed, 7 Jul 2021 19:01:00 +0200 Subject: Refactor with one DFU functionnal descriptor --- examples/device/dfu/src/tusb_config.h | 8 +++-- examples/device/dfu/src/usb_descriptors.c | 7 ++--- src/class/dfu/dfu_device.c | 51 ++++++++++++++----------------- src/class/dfu/dfu_device.h | 7 +---- src/device/usbd.h | 47 +++++++++++++++++++++++----- 5 files changed, 72 insertions(+), 48 deletions(-) (limited to 'src/class') diff --git a/examples/device/dfu/src/tusb_config.h b/examples/device/dfu/src/tusb_config.h index 0df46c14e..55aa19922 100644 --- a/examples/device/dfu/src/tusb_config.h +++ b/examples/device/dfu/src/tusb_config.h @@ -76,14 +76,16 @@ #define CFG_TUD_ENDPOINT0_SIZE 64 #endif -// DFU buffer size, must to be set to the largest buffer size used by an any given storage type -#define CFG_TUD_DFU_TRANSFER_BUFFER_SIZE 4096 - //------------- CLASS -------------// #define CFG_TUD_DFU_RUNTIME 0 #define CFG_TUD_DFU_MODE 1 +// Count of all alt settings, typically it's the partition count (Flash, EEPROM, etc.) +#define CFG_TUD_DFU_ALT_COUNT 2 +// DFU buffer size, it has to be set to the buffer size used in TUD_DFU_MODE_DESCRIPTOR +#define CFG_TUD_DFU_TRANSFER_BUFFER_SIZE 4096 + #ifdef __cplusplus } #endif diff --git a/examples/device/dfu/src/usb_descriptors.c b/examples/device/dfu/src/usb_descriptors.c index 9565da9b2..8c5eee455 100644 --- a/examples/device/dfu/src/usb_descriptors.c +++ b/examples/device/dfu/src/usb_descriptors.c @@ -87,7 +87,7 @@ enum ITF_NUM_TOTAL }; -#define CONFIG_TOTAL_LEN (TUD_CONFIG_DESC_LEN + 2 * TUD_DFU_MODE_DESC_LEN) +#define CONFIG_TOTAL_LEN (TUD_CONFIG_DESC_LEN + TUD_DFU_MODE_DESC_LEN) #define FUNC_ATTRS (DFU_FUNC_ATTR_CAN_UPLOAD_BITMASK | DFU_FUNC_ATTR_CAN_DOWNLOAD_BITMASK) @@ -96,9 +96,8 @@ uint8_t const desc_configuration[] = // Config number, interface count, string index, total length, attribute, power in mA TUD_CONFIG_DESCRIPTOR(1, ITF_NUM_TOTAL, 0, CONFIG_TOTAL_LEN, TUSB_DESC_CONFIG_ATT_REMOTE_WAKEUP, 100), - // Interface number, string index, attributes, detach timeout, transfer size */ - TUD_DFU_MODE_DESCRIPTOR(ITF_NUM_DFU_MODE, 0, 4, FUNC_ATTRS, 1000, CFG_TUD_DFU_TRANSFER_BUFFER_SIZE), - TUD_DFU_MODE_DESCRIPTOR(ITF_NUM_DFU_MODE, 1, 5, FUNC_ATTRS, 1000, CFG_TUD_DFU_TRANSFER_BUFFER_SIZE), + // Interface number, attributes, detach timeout, transfer size, string index 0, [string index 1 ... string index n] + TUD_DFU_MODE_DESCRIPTOR(ITF_NUM_DFU_MODE, FUNC_ATTRS, 1000, CFG_TUD_DFU_TRANSFER_BUFFER_SIZE, 4, 5), }; // Invoked when received GET CONFIGURATION DESCRIPTOR diff --git a/src/class/dfu/dfu_device.c b/src/class/dfu/dfu_device.c index 8bf2e16be..834648c5a 100644 --- a/src/class/dfu/dfu_device.c +++ b/src/class/dfu/dfu_device.c @@ -46,7 +46,7 @@ typedef struct TU_ATTR_PACKED { dfu_device_status_t status; dfu_state_t state; - uint8_t attrs[CFG_TUD_DFU_ATL_MAX]; + uint8_t attrs; bool blk_transfer_in_proc; uint8_t alt; uint8_t intf; @@ -148,10 +148,7 @@ void dfu_moded_init(void) { _dfu_state_ctx.state = DFU_IDLE; _dfu_state_ctx.status = DFU_STATUS_OK; - for (uint8_t i = 0; i < CFG_TUD_DFU_ATL_MAX; i++) - { - _dfu_state_ctx.attrs[i] = 0; - } + _dfu_state_ctx.attrs = 0; _dfu_state_ctx.blk_transfer_in_proc = false; _dfu_state_ctx.alt = 0; _dfu_state_ctx.intf = DFU_INTF_UNUSED; @@ -165,10 +162,7 @@ void dfu_moded_reset(uint8_t rhport) _dfu_state_ctx.state = DFU_IDLE; _dfu_state_ctx.status = DFU_STATUS_OK; - for (uint8_t i = 0; i < CFG_TUD_DFU_ATL_MAX; i++) - { - _dfu_state_ctx.attrs[i] = 0; - } + _dfu_state_ctx.attrs = 0; _dfu_state_ctx.blk_transfer_in_proc = false; _dfu_state_ctx.alt = 0; _dfu_state_ctx.intf = DFU_INTF_UNUSED; @@ -180,15 +174,15 @@ uint16_t dfu_moded_open(uint8_t rhport, tusb_desc_interface_t const * itf_desc, { (void) rhport; - uint16_t const drv_len = sizeof(tusb_desc_interface_t) + sizeof(tusb_desc_dfu_functional_t); + uint16_t const drv_len = sizeof(tusb_desc_interface_t); uint8_t const *p_desc = (uint8_t const *)itf_desc; uint16_t total_len = 0; - + uint8_t last_alt = 0; - while(max_len >= drv_len) + while(max_len > drv_len) { // Ensure this is DFU Mode TU_VERIFY((((tusb_desc_interface_t const *)p_desc)->bInterfaceSubClass == TUD_DFU_APP_SUBCLASS) && @@ -208,25 +202,26 @@ uint16_t dfu_moded_open(uint8_t rhport, tusb_desc_interface_t const * itf_desc, } // CFG_TUD_DFU_ATL_MAX should big enough to hold all alt settings - TU_ASSERT(alt < CFG_TUD_DFU_ATL_MAX, 0); + TU_ASSERT(alt < CFG_TUD_DFU_ALT_COUNT, 0); // Alt should increse by one every time TU_ASSERT(alt == last_alt++, 0); - //------------- DFU descriptor -------------// - p_desc = tu_desc_next(p_desc); - TU_ASSERT(tu_desc_type(p_desc) == TUSB_DESC_FUNCTIONAL, 0); - - _dfu_state_ctx.attrs[alt] = ((tusb_desc_dfu_functional_t const *)p_desc)->bAttributes; - - // CFG_TUD_DFU_TRANSFER_BUFFER_SIZE has to be set to the largest buffer size used by all alt settings - TU_ASSERT(((tusb_desc_dfu_functional_t const *)p_desc)->wTransferSize <= CFG_TUD_DFU_TRANSFER_BUFFER_SIZE, 0); - p_desc = tu_desc_next(p_desc); max_len -= drv_len; total_len += drv_len; } + //------------- DFU descriptor -------------// + TU_ASSERT(tu_desc_type(p_desc) == TUSB_DESC_FUNCTIONAL, 0); + + _dfu_state_ctx.attrs = ((tusb_desc_dfu_functional_t const *)p_desc)->bAttributes; + + // CFG_TUD_DFU_TRANSFER_BUFFER_SIZE has to be set to the buffer size used in TUD_DFU_MODE_DESCRIPTOR + TU_ASSERT(((tusb_desc_dfu_functional_t const *)p_desc)->wTransferSize <= CFG_TUD_DFU_TRANSFER_BUFFER_SIZE, 0); + + total_len += sizeof(tusb_desc_dfu_functional_t); + return total_len; } @@ -272,7 +267,7 @@ bool dfu_moded_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_reque case DFU_REQUEST_DNLOAD: { if ( (stage == CONTROL_STAGE_ACK) - && ((_dfu_state_ctx.attrs[_dfu_state_ctx.alt] & DFU_FUNC_ATTR_CAN_DOWNLOAD_BITMASK) != 0) + && ((_dfu_state_ctx.attrs & DFU_FUNC_ATTR_CAN_DOWNLOAD_BITMASK) != 0) && (_dfu_state_ctx.state == DFU_DNLOAD_SYNC)) { dfu_req_dnload_reply(rhport, request); @@ -358,7 +353,7 @@ void tud_dfu_dnload_complete(void) _dfu_state_ctx.state = DFU_DNLOAD_SYNC; } else if (_dfu_state_ctx.state == DFU_MANIFEST) { - _dfu_state_ctx.state = ((_dfu_state_ctx.attrs[_dfu_state_ctx.alt] & DFU_FUNC_ATTR_MANIFESTATION_TOLERANT_BITMASK) == 0) + _dfu_state_ctx.state = ((_dfu_state_ctx.attrs & DFU_FUNC_ATTR_MANIFESTATION_TOLERANT_BITMASK) == 0) ? DFU_MANIFEST_WAIT_RESET : DFU_MANIFEST_SYNC; } } @@ -376,7 +371,7 @@ static bool dfu_state_machine(uint8_t rhport, tusb_control_request_t const * req { case DFU_REQUEST_DNLOAD: { - if( ((_dfu_state_ctx.attrs[_dfu_state_ctx.alt] & DFU_FUNC_ATTR_CAN_DOWNLOAD_BITMASK) != 0) + if( ((_dfu_state_ctx.attrs & DFU_FUNC_ATTR_CAN_DOWNLOAD_BITMASK) != 0) && (request->wLength > 0) ) { _dfu_state_ctx.state = DFU_DNLOAD_SYNC; @@ -390,7 +385,7 @@ static bool dfu_state_machine(uint8_t rhport, tusb_control_request_t const * req case DFU_REQUEST_UPLOAD: { - if( ((_dfu_state_ctx.attrs[_dfu_state_ctx.alt] & DFU_FUNC_ATTR_CAN_UPLOAD_BITMASK) != 0) ) + if( ((_dfu_state_ctx.attrs & DFU_FUNC_ATTR_CAN_UPLOAD_BITMASK) != 0) ) { _dfu_state_ctx.state = DFU_UPLOAD_IDLE; dfu_req_upload(rhport, request, request->wValue, request->wLength); @@ -481,7 +476,7 @@ static bool dfu_state_machine(uint8_t rhport, tusb_control_request_t const * req { case DFU_REQUEST_DNLOAD: { - if( ((_dfu_state_ctx.attrs[_dfu_state_ctx.alt] & DFU_FUNC_ATTR_CAN_DOWNLOAD_BITMASK) != 0) + if( ((_dfu_state_ctx.attrs & DFU_FUNC_ATTR_CAN_DOWNLOAD_BITMASK) != 0) && (request->wLength > 0) ) { _dfu_state_ctx.state = DFU_DNLOAD_SYNC; @@ -538,7 +533,7 @@ static bool dfu_state_machine(uint8_t rhport, tusb_control_request_t const * req { case DFU_REQUEST_GETSTATUS: { - if ((_dfu_state_ctx.attrs[_dfu_state_ctx.alt] & DFU_FUNC_ATTR_MANIFESTATION_TOLERANT_BITMASK) == 0) + if ((_dfu_state_ctx.attrs & DFU_FUNC_ATTR_MANIFESTATION_TOLERANT_BITMASK) == 0) { _dfu_state_ctx.state = DFU_MANIFEST; dfu_req_getstatus_reply(rhport, request); diff --git a/src/class/dfu/dfu_device.h b/src/class/dfu/dfu_device.h index 53be0005e..f41b4b651 100644 --- a/src/class/dfu/dfu_device.h +++ b/src/class/dfu/dfu_device.h @@ -37,13 +37,8 @@ // Class Driver Default Configure & Validation //--------------------------------------------------------------------+ -// Maximum alternate settings (used for different partitons) supported -#if !defined(CFG_TUD_DFU_ATL_MAX) - #define CFG_TUD_DFU_ATL_MAX 2 -#endif - #if !defined(CFG_TUD_DFU_TRANSFER_BUFFER_SIZE) - #error "CFG_TUD_DFU_TRANSFER_BUFFER_SIZE must be defined, it has to be set to the largest buffer size used by an any given storage type" + #error "CFG_TUD_DFU_TRANSFER_BUFFER_SIZE must be defined, it has to be set to the buffer size used in TUD_DFU_MODE_DESCRIPTOR" #endif //--------------------------------------------------------------------+ diff --git a/src/device/usbd.h b/src/device/usbd.h index 41c78de10..3d49d4b12 100644 --- a/src/device/usbd.h +++ b/src/device/usbd.h @@ -600,17 +600,50 @@ TU_ATTR_WEAK bool tud_vendor_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb /* Function */ \ 9, DFU_DESC_FUNCTIONAL, _attr, U16_TO_U8S_LE(_timeout), U16_TO_U8S_LE(_xfer_size), U16_TO_U8S_LE(0x0101) -// Length of template descriptr: 18 bytes -#define TUD_DFU_MODE_DESC_LEN (9 + 9) +// Maximum alternate settings (used for different partitons) supported +#ifndef CFG_TUD_DFU_ALT_COUNT +#define CFG_TUD_DFU_ALT_COUNT 1 +#endif -// DFU mode descriptor -// Interface number, alt settings, string index, attributes, detach timeout, transfer size -#define TUD_DFU_MODE_DESCRIPTOR(_itfnum, _alt, _stridx, _attr, _timeout, _xfer_size) \ - /* Interface */ \ - 9, TUSB_DESC_INTERFACE, _itfnum, _alt, 0, TUD_DFU_APP_CLASS, TUD_DFU_APP_SUBCLASS, DFU_PROTOCOL_DFU, _stridx, \ +// Length of template descriptor: 18 bytes + number of alternatives * 9 +#define TUD_DFU_MODE_DESC_LEN (9 + (CFG_TUD_DFU_ALT_COUNT) * 9) + +/* Primary Interface */ +#define TUD_DFU_MODE_FUNC(_attr, _timeout, _xfer_size) \ /* Function */ \ 9, DFU_DESC_FUNCTIONAL, _attr, U16_TO_U8S_LE(_timeout), U16_TO_U8S_LE(_xfer_size), U16_TO_U8S_LE(0x0101) +#define TUD_DFU_MODE_ALT(_itfnum, _alt, _stridx) \ + /* Interface */ \ + 9, TUSB_DESC_INTERFACE, _itfnum, _alt, 0, TUD_DFU_APP_CLASS, TUD_DFU_APP_SUBCLASS, DFU_PROTOCOL_DFU, _stridx, \ + +#define _TUD_DFU_FIRST(a, ...) a +#define _TUD_DFU_REST(a, ...) __VA_ARGS__ +#define _TUD_DFU_COMBINE(...) __VA_ARGS__ + +#define TUD_DFU_MODE_ALT_1(_itfnum, ...) TUD_DFU_MODE_ALT(_itfnum, (CFG_TUD_DFU_ALT_COUNT) - 1, _TUD_DFU_FIRST(__VA_ARGS__)) +#define TUD_DFU_MODE_ALT_2(_itfnum, ...) TUD_DFU_MODE_ALT(_itfnum, (CFG_TUD_DFU_ALT_COUNT) - 2, _TUD_DFU_FIRST(__VA_ARGS__)) \ + TUD_DFU_MODE_ALT_1(_itfnum, _TUD_DFU_REST(__VA_ARGS__)) +#define TUD_DFU_MODE_ALT_3(_itfnum, ...) TUD_DFU_MODE_ALT(_itfnum, (CFG_TUD_DFU_ALT_COUNT) - 3, _TUD_DFU_FIRST(__VA_ARGS__)) \ + TUD_DFU_MODE_ALT_2(_itfnum, _TUD_DFU_REST(__VA_ARGS__)) +#define TUD_DFU_MODE_ALT_4(_itfnum, ...) TUD_DFU_MODE_ALT(_itfnum, (CFG_TUD_DFU_ALT_COUNT) - 4, _TUD_DFU_FIRST(__VA_ARGS__)) \ + TUD_DFU_MODE_ALT_3(_itfnum, _TUD_DFU_REST(__VA_ARGS__)) +#define TUD_DFU_MODE_ALT_5(_itfnum, ...) TUD_DFU_MODE_ALT(_itfnum, (CFG_TUD_DFU_ALT_COUNT) - 5, _TUD_DFU_FIRST(__VA_ARGS__)) \ + TUD_DFU_MODE_ALT_4(_itfnum, _TUD_DFU_REST(__VA_ARGS__)) +#define TUD_DFU_MODE_ALT_6(_itfnum, ...) TUD_DFU_MODE_ALT(_itfnum, (CFG_TUD_DFU_ALT_COUNT) - 6, _TUD_DFU_FIRST(__VA_ARGS__)) \ + TUD_DFU_MODE_ALT_5(_itfnum, _TUD_DFU_REST(__VA_ARGS__)) +#define TUD_DFU_MODE_ALT_7(_itfnum, ...) TUD_DFU_MODE_ALT(_itfnum, (CFG_TUD_DFU_ALT_COUNT) - 7, _TUD_DFU_FIRST(__VA_ARGS__)) \ + TUD_DFU_MODE_ALT_6(_itfnum, _TUD_DFU_REST(__VA_ARGS__)) +#define TUD_DFU_MODE_ALT_8(_itfnum, ...) TUD_DFU_MODE_ALT(_itfnum, (CFG_TUD_DFU_ALT_COUNT) - 8, _TUD_DFU_FIRST(__VA_ARGS__)) \ + TUD_DFU_MODE_ALT_7(_itfnum, _TUD_DFU_REST(__VA_ARGS__)) + +#define TUD_DFU_MODE_ALTS(_itfnum, ...) \ + TU_XSTRCAT(TUD_DFU_MODE_ALT_, CFG_TUD_DFU_ALT_COUNT)(_itfnum, __VA_ARGS__) + +// Interface number, attributes, detach timeout, transfer size, string index 1, [string index 2, string index n] +#define TUD_DFU_MODE_DESCRIPTOR(_itfnum, _attr, _timeout, _xfer_size, _stridx, ...) \ + TUD_DFU_MODE_ALTS(_itfnum, _TUD_DFU_COMBINE(_stridx, __VA_ARGS__)) \ + TUD_DFU_MODE_FUNC(_attr, _timeout, _xfer_size) //------------- CDC-ECM -------------// -- cgit v1.3.1 From 2147a31f25e6e848d9ec690d8324a6fa2d1d3127 Mon Sep 17 00:00:00 2001 From: Mengsk Date: Thu, 8 Jul 2021 01:10:02 +0200 Subject: Fix wrong blocknum and length --- src/class/dfu/dfu_device.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'src/class') diff --git a/src/class/dfu/dfu_device.c b/src/class/dfu/dfu_device.c index 34472bcdd..6e7ad151b 100644 --- a/src/class/dfu/dfu_device.c +++ b/src/class/dfu/dfu_device.c @@ -50,6 +50,8 @@ typedef struct TU_ATTR_PACKED bool blk_transfer_in_proc; uint8_t alt; uint8_t intf; + uint16_t block; + uint16_t length; CFG_TUSB_MEM_ALIGN uint8_t transfer_buf[CFG_TUD_DFU_TRANSFER_BUFFER_SIZE]; } dfu_state_ctx_t; @@ -270,6 +272,8 @@ bool dfu_moded_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_reque && ((_dfu_state_ctx.attrs & DFU_FUNC_ATTR_CAN_DOWNLOAD_BITMASK) != 0) && (_dfu_state_ctx.state == DFU_DNLOAD_SYNC)) { + _dfu_state_ctx.block = request->wValue; + _dfu_state_ctx.length = request->wLength; return true; } } // fallthrough @@ -349,7 +353,7 @@ static void dfu_req_dnload_reply(uint8_t rhport, tusb_control_request_t const * { (void) rhport; TU_VERIFY( request->wLength <= CFG_TUD_DFU_TRANSFER_BUFFER_SIZE, ); - tud_dfu_req_dnload_data_cb(_dfu_state_ctx.alt, request->wValue, (uint8_t *)_dfu_state_ctx.transfer_buf, request->wLength); + tud_dfu_req_dnload_data_cb(_dfu_state_ctx.alt,_dfu_state_ctx.block, (uint8_t *)_dfu_state_ctx.transfer_buf, _dfu_state_ctx.length); _dfu_state_ctx.blk_transfer_in_proc = false; } -- cgit v1.3.1 From a0691a4fd426f01915a7ce6452b5367aa667fb0b Mon Sep 17 00:00:00 2001 From: hathach Date: Mon, 12 Jul 2021 18:48:33 +0700 Subject: update dfu_moded_open --- src/class/dfu/dfu_device.c | 62 ++++++++++++++++------------------------------ 1 file changed, 21 insertions(+), 41 deletions(-) (limited to 'src/class') diff --git a/src/class/dfu/dfu_device.c b/src/class/dfu/dfu_device.c index 6e7ad151b..04f086e0e 100644 --- a/src/class/dfu/dfu_device.c +++ b/src/class/dfu/dfu_device.c @@ -49,7 +49,6 @@ typedef struct TU_ATTR_PACKED uint8_t attrs; bool blk_transfer_in_proc; uint8_t alt; - uint8_t intf; uint16_t block; uint16_t length; CFG_TUSB_MEM_ALIGN uint8_t transfer_buf[CFG_TUD_DFU_TRANSFER_BUFFER_SIZE]; @@ -153,7 +152,6 @@ void dfu_moded_init(void) _dfu_state_ctx.attrs = 0; _dfu_state_ctx.blk_transfer_in_proc = false; _dfu_state_ctx.alt = 0; - _dfu_state_ctx.intf = DFU_INTF_UNUSED; dfu_debug_print_context(); } @@ -167,7 +165,6 @@ void dfu_moded_reset(uint8_t rhport) _dfu_state_ctx.attrs = 0; _dfu_state_ctx.blk_transfer_in_proc = false; _dfu_state_ctx.alt = 0; - _dfu_state_ctx.intf = DFU_INTF_UNUSED; dfu_debug_print_context(); } @@ -176,55 +173,38 @@ uint16_t dfu_moded_open(uint8_t rhport, tusb_desc_interface_t const * itf_desc, { (void) rhport; - uint16_t const drv_len = sizeof(tusb_desc_interface_t); + //------------- Interface (with Alt) descriptor -------------// + uint8_t const itf_num = itf_desc->bInterfaceNumber; + uint8_t alt_count = 0; - uint8_t const *p_desc = (uint8_t const *)itf_desc; - - uint16_t total_len = 0; - - uint8_t last_alt = 0; - - while(max_len > drv_len) + uint16_t drv_len = 0; + while(itf_desc->bInterfaceSubClass == TUD_DFU_APP_SUBCLASS && itf_desc->bInterfaceProtocol == DFU_PROTOCOL_DFU) { - // Ensure this is DFU Mode - TU_VERIFY((((tusb_desc_interface_t const *)p_desc)->bInterfaceSubClass == TUD_DFU_APP_SUBCLASS) && - (((tusb_desc_interface_t const *)p_desc)->bInterfaceProtocol == DFU_PROTOCOL_DFU), 0); - - uint8_t const alt = ((tusb_desc_interface_t const *)p_desc)->bAlternateSetting; - uint8_t const intf = ((tusb_desc_interface_t const *)p_desc)->bInterfaceNumber; - - if (_dfu_state_ctx.intf == DFU_INTF_UNUSED) - { - _dfu_state_ctx.intf = intf; - } - else - { - // Only one DFU interface is supported - TU_ASSERT(_dfu_state_ctx.intf == intf, 0); - } + TU_ASSERT(max_len > drv_len, 0); - // CFG_TUD_DFU_ATL_MAX should big enough to hold all alt settings - TU_ASSERT(alt < CFG_TUD_DFU_ALT_COUNT, 0); + // Alternate must have the same interface number + TU_ASSERT(itf_desc->bInterfaceNumber == itf_num, 0); - // Alt should increse by one every time - TU_ASSERT(alt == last_alt++, 0); + // Alt should increase by one every time + TU_ASSERT(itf_desc->bAlternateSetting == alt_count, 0); + alt_count++; - p_desc = tu_desc_next(p_desc); - max_len -= drv_len; - total_len += drv_len; + drv_len += tu_desc_len(itf_desc); + itf_desc = (tusb_desc_interface_t const *) tu_desc_next(itf_desc); } - //------------- DFU descriptor -------------// - TU_ASSERT(tu_desc_type(p_desc) == TUSB_DESC_FUNCTIONAL, 0); + //------------- DFU Functional descriptor -------------// + tusb_desc_dfu_functional_t const *func_desc = (tusb_desc_dfu_functional_t const *) itf_desc; + TU_ASSERT(tu_desc_type(func_desc) == TUSB_DESC_FUNCTIONAL, 0); + drv_len += sizeof(tusb_desc_dfu_functional_t); - _dfu_state_ctx.attrs = ((tusb_desc_dfu_functional_t const *)p_desc)->bAttributes; + _dfu_state_ctx.attrs = func_desc->bAttributes; // CFG_TUD_DFU_TRANSFER_BUFFER_SIZE has to be set to the buffer size used in TUD_DFU_MODE_DESCRIPTOR - TU_ASSERT(((tusb_desc_dfu_functional_t const *)p_desc)->wTransferSize <= CFG_TUD_DFU_TRANSFER_BUFFER_SIZE, 0); - - total_len += sizeof(tusb_desc_dfu_functional_t); + uint16_t const transfer_size = tu_le16toh( tu_unaligned_read16(&func_desc->wTransferSize) ); + TU_ASSERT(transfer_size <= CFG_TUD_DFU_TRANSFER_BUFFER_SIZE, drv_len); - return total_len; + return drv_len; } // Invoked when a control transfer occurred on an interface of this class -- cgit v1.3.1 From 134ed995c82635d509621e40568b57309fc26101 Mon Sep 17 00:00:00 2001 From: hathach Date: Mon, 12 Jul 2021 18:50:19 +0700 Subject: add alt to tud_dfu_abort_cb() --- src/class/dfu/dfu_device.c | 4 ++-- src/class/dfu/dfu_device.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'src/class') diff --git a/src/class/dfu/dfu_device.c b/src/class/dfu/dfu_device.c index 04f086e0e..933946b7e 100644 --- a/src/class/dfu/dfu_device.c +++ b/src/class/dfu/dfu_device.c @@ -503,7 +503,7 @@ static bool dfu_state_machine(uint8_t rhport, tusb_control_request_t const * req { if ( tud_dfu_abort_cb ) { - tud_dfu_abort_cb(); + tud_dfu_abort_cb(_dfu_state_ctx.alt); } _dfu_state_ctx.state = DFU_IDLE; } @@ -613,7 +613,7 @@ static bool dfu_state_machine(uint8_t rhport, tusb_control_request_t const * req { if (tud_dfu_abort_cb) { - tud_dfu_abort_cb(); + tud_dfu_abort_cb(_dfu_state_ctx.alt); } _dfu_state_ctx.state = DFU_IDLE; } diff --git a/src/class/dfu/dfu_device.h b/src/class/dfu/dfu_device.h index c09b9a823..73e5055cd 100644 --- a/src/class/dfu/dfu_device.h +++ b/src/class/dfu/dfu_device.h @@ -73,7 +73,7 @@ void tud_dfu_dnload_complete(void); bool tud_dfu_device_data_done_check_cb(uint8_t alt); // Invoked when the Host has terminated a download or upload transfer -TU_ATTR_WEAK void tud_dfu_abort_cb(void); +TU_ATTR_WEAK void tud_dfu_abort_cb(uint8_t alt); // Invoked when a DFU_UPLOAD request is received // alt is used as the partition number, in order to support multiple partitions like FLASH, EEPROM, etc. -- cgit v1.3.1 From 2916cd45753ca579ee1d0b475b2daf3f715243b6 Mon Sep 17 00:00:00 2001 From: hathach Date: Mon, 12 Jul 2021 18:51:57 +0700 Subject: rename TUD_DFU_MODE_DESCRIPTOR to TUD_DFU_DESCRIPTOR --- examples/device/dfu/src/tusb_config.h | 2 +- examples/device/dfu/src/usb_descriptors.c | 2 +- src/class/dfu/dfu_device.c | 2 +- src/class/dfu/dfu_device.h | 2 +- src/device/usbd.h | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) (limited to 'src/class') diff --git a/examples/device/dfu/src/tusb_config.h b/examples/device/dfu/src/tusb_config.h index 55aa19922..7e10b4321 100644 --- a/examples/device/dfu/src/tusb_config.h +++ b/examples/device/dfu/src/tusb_config.h @@ -83,7 +83,7 @@ // Count of all alt settings, typically it's the partition count (Flash, EEPROM, etc.) #define CFG_TUD_DFU_ALT_COUNT 2 -// DFU buffer size, it has to be set to the buffer size used in TUD_DFU_MODE_DESCRIPTOR +// DFU buffer size, it has to be set to the buffer size used in TUD_DFU_DESCRIPTOR #define CFG_TUD_DFU_TRANSFER_BUFFER_SIZE 4096 #ifdef __cplusplus diff --git a/examples/device/dfu/src/usb_descriptors.c b/examples/device/dfu/src/usb_descriptors.c index 8c5eee455..870c18a04 100644 --- a/examples/device/dfu/src/usb_descriptors.c +++ b/examples/device/dfu/src/usb_descriptors.c @@ -97,7 +97,7 @@ uint8_t const desc_configuration[] = TUD_CONFIG_DESCRIPTOR(1, ITF_NUM_TOTAL, 0, CONFIG_TOTAL_LEN, TUSB_DESC_CONFIG_ATT_REMOTE_WAKEUP, 100), // Interface number, attributes, detach timeout, transfer size, string index 0, [string index 1 ... string index n] - TUD_DFU_MODE_DESCRIPTOR(ITF_NUM_DFU_MODE, FUNC_ATTRS, 1000, CFG_TUD_DFU_TRANSFER_BUFFER_SIZE, 4, 5), + TUD_DFU_DESCRIPTOR(ITF_NUM_DFU_MODE, FUNC_ATTRS, 1000, CFG_TUD_DFU_TRANSFER_BUFFER_SIZE, 4, 5), }; // Invoked when received GET CONFIGURATION DESCRIPTOR diff --git a/src/class/dfu/dfu_device.c b/src/class/dfu/dfu_device.c index 933946b7e..ae056b441 100644 --- a/src/class/dfu/dfu_device.c +++ b/src/class/dfu/dfu_device.c @@ -200,7 +200,7 @@ uint16_t dfu_moded_open(uint8_t rhport, tusb_desc_interface_t const * itf_desc, _dfu_state_ctx.attrs = func_desc->bAttributes; - // CFG_TUD_DFU_TRANSFER_BUFFER_SIZE has to be set to the buffer size used in TUD_DFU_MODE_DESCRIPTOR + // CFG_TUD_DFU_TRANSFER_BUFFER_SIZE has to be set to the buffer size used in TUD_DFU_DESCRIPTOR uint16_t const transfer_size = tu_le16toh( tu_unaligned_read16(&func_desc->wTransferSize) ); TU_ASSERT(transfer_size <= CFG_TUD_DFU_TRANSFER_BUFFER_SIZE, drv_len); diff --git a/src/class/dfu/dfu_device.h b/src/class/dfu/dfu_device.h index 73e5055cd..8edb2bae3 100644 --- a/src/class/dfu/dfu_device.h +++ b/src/class/dfu/dfu_device.h @@ -38,7 +38,7 @@ //--------------------------------------------------------------------+ #if !defined(CFG_TUD_DFU_TRANSFER_BUFFER_SIZE) - #error "CFG_TUD_DFU_TRANSFER_BUFFER_SIZE must be defined, it has to be set to the buffer size used in TUD_DFU_MODE_DESCRIPTOR" + #error "CFG_TUD_DFU_TRANSFER_BUFFER_SIZE must be defined, it has to be set to the buffer size used in TUD_DFU_DESCRIPTOR" #endif //--------------------------------------------------------------------+ diff --git a/src/device/usbd.h b/src/device/usbd.h index ba415abe8..8c5f0097d 100644 --- a/src/device/usbd.h +++ b/src/device/usbd.h @@ -646,7 +646,7 @@ TU_ATTR_WEAK bool tud_vendor_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb TU_XSTRCAT(TUD_DFU_MODE_ALT_, CFG_TUD_DFU_ALT_COUNT)(_itfnum, __VA_ARGS__) // Interface number, attributes, detach timeout, transfer size, string index 0, [string index 1, string index n] -#define TUD_DFU_MODE_DESCRIPTOR(_itfnum, _attr, _timeout, _xfer_size, _stridx, ...) \ +#define TUD_DFU_DESCRIPTOR(_itfnum, _attr, _timeout, _xfer_size, _stridx, ...) \ TUD_DFU_MODE_ALTS(_itfnum, _TUD_DFU_COMBINE(_stridx, __VA_ARGS__)) \ TUD_DFU_MODE_FUNC(_attr, _timeout, _xfer_size) -- cgit v1.3.1 From 389d34067854fcf39dd1839f2643bd8300aafe1d Mon Sep 17 00:00:00 2001 From: hathach Date: Mon, 12 Jul 2021 20:17:44 +0700 Subject: clean up --- src/class/dfu/dfu_device.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/class') diff --git a/src/class/dfu/dfu_device.c b/src/class/dfu/dfu_device.c index ae056b441..a7a8f578c 100644 --- a/src/class/dfu/dfu_device.c +++ b/src/class/dfu/dfu_device.c @@ -42,7 +42,7 @@ //--------------------------------------------------------------------+ // INTERNAL OBJECT & FUNCTION DECLARATION //--------------------------------------------------------------------+ -typedef struct TU_ATTR_PACKED +typedef struct { dfu_device_status_t status; dfu_state_t state; -- cgit v1.3.1 From 8c48a4a2886bdac96df274311f84bc6c04c56b95 Mon Sep 17 00:00:00 2001 From: hathach Date: Mon, 12 Jul 2021 20:23:19 +0700 Subject: clean up --- src/class/dfu/dfu_device.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'src/class') diff --git a/src/class/dfu/dfu_device.c b/src/class/dfu/dfu_device.c index a7a8f578c..51e6179bc 100644 --- a/src/class/dfu/dfu_device.c +++ b/src/class/dfu/dfu_device.c @@ -37,8 +37,6 @@ // MACRO CONSTANT TYPEDEF //--------------------------------------------------------------------+ -#define DFU_INTF_UNUSED 0xFF - //--------------------------------------------------------------------+ // INTERNAL OBJECT & FUNCTION DECLARATION //--------------------------------------------------------------------+ -- cgit v1.3.1 From 86d511f24452b13c8e5779c7a79bff54a03dafd8 Mon Sep 17 00:00:00 2001 From: hathach Date: Mon, 12 Jul 2021 21:08:13 +0700 Subject: rename tud_dfu_set_timeout_cb() to tud_dfu_get_status_cb() also add state as argument --- examples/device/dfu/src/main.c | 7 +++++-- src/class/dfu/dfu_device.c | 19 +++++++++---------- src/class/dfu/dfu_device.h | 6 +++--- 3 files changed, 17 insertions(+), 15 deletions(-) (limited to 'src/class') diff --git a/examples/device/dfu/src/main.c b/examples/device/dfu/src/main.c index ee201c1c5..4ec6d477c 100644 --- a/examples/device/dfu/src/main.c +++ b/examples/device/dfu/src/main.c @@ -125,10 +125,13 @@ bool tud_dfu_firmware_valid_check_cb(uint8_t alt) return true; } -uint16_t tud_dfu_set_timeout_cb(uint8_t alt) +uint32_t tud_dfu_get_status_cb(uint8_t alt, uint8_t state) { // For example Alt1 (EEPROM) is slow, add 2000ms timeout - if (alt == 1) return 2000; + if ( state == DFU_DNBUSY ) + { + if (alt == 1) return 2000; + } return 0; } diff --git a/src/class/dfu/dfu_device.c b/src/class/dfu/dfu_device.c index 51e6179bc..23669b508 100644 --- a/src/class/dfu/dfu_device.c +++ b/src/class/dfu/dfu_device.c @@ -293,18 +293,17 @@ static uint16_t dfu_req_upload(uint8_t rhport, tusb_control_request_t const * re static void dfu_req_getstatus_reply(uint8_t rhport, tusb_control_request_t const * request) { - dfu_status_req_payload_t resp; - - uint16_t timeout = 0; - resp.bStatus = _dfu_state_ctx.status; - if(_dfu_state_ctx.state == DFU_DNBUSY && tud_dfu_set_timeout_cb) + uint32_t timeout = 0; + if ( tud_dfu_get_status_cb ) { - timeout = tud_dfu_set_timeout_cb(_dfu_state_ctx.alt); - + timeout = tud_dfu_get_status_cb(_dfu_state_ctx.alt, _dfu_state_ctx.state); } - resp.bwPollTimeout[0] = TU_U16_LOW(timeout); - resp.bwPollTimeout[1] = TU_U16_HIGH(timeout); - resp.bwPollTimeout[2] = 0; + + dfu_status_req_payload_t resp; + resp.bStatus = _dfu_state_ctx.status; + resp.bwPollTimeout[0] = TU_U32_BYTE0(timeout); + resp.bwPollTimeout[1] = TU_U32_BYTE1(timeout); + resp.bwPollTimeout[2] = TU_U32_BYTE2(timeout); resp.bState = _dfu_state_ctx.state; resp.iString = 0; diff --git a/src/class/dfu/dfu_device.h b/src/class/dfu/dfu_device.h index 8edb2bae3..647fc2c04 100644 --- a/src/class/dfu/dfu_device.h +++ b/src/class/dfu/dfu_device.h @@ -48,10 +48,10 @@ // alt is used as the partition number, in order to support multiple partitions like FLASH, EEPROM, etc. bool tud_dfu_firmware_valid_check_cb(uint8_t alt); -// Invoked when a DFU_GETSTATUS request is received in DFU_DNBUSY state -// Used to set the bwPollTimeout value, useful for slow Flash in order to make host wait longer +// Invoked when a DFU_GETSTATUS request is received +// Return the bwPollTimeout value for host's response, useful for slow Flash in order to make host wait longer // alt is used as the partition number, in order to support multiple partitions like FLASH, EEPROM, etc. -TU_ATTR_WEAK uint16_t tud_dfu_set_timeout_cb(uint8_t alt); +TU_ATTR_WEAK uint32_t tud_dfu_get_status_cb(uint8_t alt, uint8_t state); // Invoked when a DFU_DNLOAD request is received // alt is used as the partition number, in order to support multiple partitions like FLASH, EEPROM, etc. -- cgit v1.3.1 From 137dff620bc5890afdf59a61cebe355fc6999f12 Mon Sep 17 00:00:00 2001 From: hathach Date: Tue, 13 Jul 2021 20:24:12 +0700 Subject: add option to silent a driver log --- src/class/msc/msc_device.c | 20 ++++++++++++-------- src/common/tusb_common.h | 18 +++++++++++++----- src/common/tusb_compiler.h | 12 ++++++++---- src/common/tusb_fifo.h | 2 +- 4 files changed, 34 insertions(+), 18 deletions(-) (limited to 'src/class') diff --git a/src/class/msc/msc_device.c b/src/class/msc/msc_device.c index 7f13b4891..014e8b69e 100644 --- a/src/class/msc/msc_device.c +++ b/src/class/msc/msc_device.c @@ -37,6 +37,10 @@ //--------------------------------------------------------------------+ // MACRO CONSTANT TYPEDEF //--------------------------------------------------------------------+ + +// Can be selectively disabled to reduce logging when troubleshooting other driver +#define MSC_DEBUG 2 + enum { MSC_STAGE_CMD = 0, @@ -99,7 +103,7 @@ static inline uint16_t rdwr10_get_blockcount(uint8_t const command[]) //--------------------------------------------------------------------+ #if CFG_TUSB_DEBUG >= 2 -static tu_lookup_entry_t const _msc_scsi_cmd_lookup[] = +TU_ATTR_UNUSED static tu_lookup_entry_t const _msc_scsi_cmd_lookup[] = { { .key = SCSI_CMD_TEST_UNIT_READY , .data = "Test Unit Ready" }, { .key = SCSI_CMD_INQUIRY , .data = "Inquiry" }, @@ -114,7 +118,7 @@ static tu_lookup_entry_t const _msc_scsi_cmd_lookup[] = { .key = SCSI_CMD_WRITE_10 , .data = "Write10" } }; -static tu_lookup_table_t const _msc_scsi_cmd_table = +TU_ATTR_UNUSED static tu_lookup_table_t const _msc_scsi_cmd_table = { .count = TU_ARRAY_SIZE(_msc_scsi_cmd_lookup), .items = _msc_scsi_cmd_lookup @@ -232,8 +236,8 @@ bool mscd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t event, uint32_t TU_ASSERT( event == XFER_RESULT_SUCCESS && xferred_bytes == sizeof(msc_cbw_t) && p_cbw->signature == MSC_CBW_SIGNATURE ); - TU_LOG2(" SCSI Command: %s\r\n", tu_lookup_find(&_msc_scsi_cmd_table, p_cbw->command[0])); - // TU_LOG2_MEM(p_cbw, xferred_bytes, 2); + TU_LOG(MSC_DEBUG, " SCSI Command: %s\r\n", tu_lookup_find(&_msc_scsi_cmd_table, p_cbw->command[0])); + // TU_LOG_MEM(MSC_DEBUG, p_cbw, xferred_bytes, 2); p_csw->signature = MSC_CSW_SIGNATURE; p_csw->tag = p_cbw->tag; @@ -305,8 +309,8 @@ bool mscd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t event, uint32_t break; case MSC_STAGE_DATA: - TU_LOG2(" SCSI Data\r\n"); - //TU_LOG2_MEM(_mscd_buf, xferred_bytes, 2); + TU_LOG(MSC_DEBUG, " SCSI Data\r\n"); + //TU_LOG_MEM(MSC_DEBUG, _mscd_buf, xferred_bytes, 2); // OUT transfer, invoke callback if needed if ( !tu_bit_test(p_cbw->dir, 7) ) @@ -402,8 +406,8 @@ bool mscd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t event, uint32_t // Wait for the Status phase to complete if( (ep_addr == p_msc->ep_in) && (xferred_bytes == sizeof(msc_csw_t)) ) { - TU_LOG2(" SCSI Status: %u\r\n", p_csw->status); - // TU_LOG2_MEM(p_csw, xferred_bytes, 2); + TU_LOG(MSC_DEBUG, " SCSI Status: %u\r\n", p_csw->status); + // TU_LOG_MEM(MSC_DEBUG, p_csw, xferred_bytes, 2); // Invoke complete callback if defined // Note: There is racing issue with samd51 + qspi flash testing with arduino diff --git a/src/common/tusb_common.h b/src/common/tusb_common.h index 8490daad7..c8a66a879 100644 --- a/src/common/tusb_common.h +++ b/src/common/tusb_common.h @@ -305,11 +305,11 @@ void tu_print_var(uint8_t const* buf, uint32_t bufsize) } // Log with Level -#define TU_LOG(n, ...) TU_LOG##n(__VA_ARGS__) -#define TU_LOG_MEM(n, ...) TU_LOG##n##_MEM(__VA_ARGS__) -#define TU_LOG_VAR(n, ...) TU_LOG##n##_VAR(__VA_ARGS__) -#define TU_LOG_INT(n, ...) TU_LOG##n##_INT(__VA_ARGS__) -#define TU_LOG_HEX(n, ...) TU_LOG##n##_HEX(__VA_ARGS__) +#define TU_LOG(n, ...) TU_XSTRCAT(TU_LOG, n)(__VA_ARGS__) +#define TU_LOG_MEM(n, ...) TU_XSTRCAT3(TU_LOG, n, _MEM)(__VA_ARGS__) +#define TU_LOG_VAR(n, ...) TU_XSTRCAT3(TU_LOG, n, _VAR)(__VA_ARGS__) +#define TU_LOG_INT(n, ...) TU_XSTRCAT3(TU_LOG, n, _INT)(__VA_ARGS__) +#define TU_LOG_HEX(n, ...) TU_XSTRCAT3(TU_LOG, n, _HEX)(__VA_ARGS__) #define TU_LOG_LOCATION() tu_printf("%s: %d:\r\n", __PRETTY_FUNCTION__, __LINE__) #define TU_LOG_FAILED() tu_printf("%s: %d: Failed\r\n", __PRETTY_FUNCTION__, __LINE__) @@ -373,6 +373,14 @@ static inline const char* tu_lookup_find(tu_lookup_table_t const* p_table, uint3 #endif // TODO replace all TU_LOGn with TU_LOG(n) + +#define TU_LOG0(...) +#define TU_LOG0_MEM(...) +#define TU_LOG0_VAR(...) +#define TU_LOG0_INT(...) +#define TU_LOG0_HEX(...) + + #ifndef TU_LOG1 #define TU_LOG1(...) #define TU_LOG1_MEM(...) diff --git a/src/common/tusb_compiler.h b/src/common/tusb_compiler.h index f755e13f4..0dd9ba016 100644 --- a/src/common/tusb_compiler.h +++ b/src/common/tusb_compiler.h @@ -32,10 +32,14 @@ #ifndef _TUSB_COMPILER_H_ #define _TUSB_COMPILER_H_ -#define TU_STRING(x) #x ///< stringify without expand -#define TU_XSTRING(x) TU_STRING(x) ///< expand then stringify -#define TU_STRCAT(a, b) a##b ///< concat without expand -#define TU_XSTRCAT(a, b) TU_STRCAT(a, b) ///< expand then concat +#define TU_STRING(x) #x ///< stringify without expand +#define TU_XSTRING(x) TU_STRING(x) ///< expand then stringify + +#define TU_STRCAT(a, b) a##b ///< concat without expand +#define TU_STRCAT3(a, b, c) a##b##c ///< concat without expand + +#define TU_XSTRCAT(a, b) TU_STRCAT(a, b) ///< expand then concat +#define TU_XSTRCAT3(a, b, c) TU_STRCAT3(a, b, c) ///< expand then concat 3 tokens #if defined __COUNTER__ && __COUNTER__ != __COUNTER__ #define _TU_COUNTER_ __COUNTER__ diff --git a/src/common/tusb_fifo.h b/src/common/tusb_fifo.h index de2ae163d..18db289a1 100644 --- a/src/common/tusb_fifo.h +++ b/src/common/tusb_fifo.h @@ -120,9 +120,9 @@ bool tu_fifo_peek (tu_fifo_t* f, void * p_buffer); uint16_t tu_fifo_peek_n (tu_fifo_t* f, void * p_buffer, uint16_t n); uint16_t tu_fifo_count (tu_fifo_t* f); +uint16_t tu_fifo_remaining (tu_fifo_t* f); bool tu_fifo_empty (tu_fifo_t* f); bool tu_fifo_full (tu_fifo_t* f); -uint16_t tu_fifo_remaining (tu_fifo_t* f); bool tu_fifo_overflowed (tu_fifo_t* f); void tu_fifo_correct_read_pointer (tu_fifo_t* f); -- cgit v1.3.1 From ebd98e1a18bf1dfbbf45420310c4dee96a3bfd24 Mon Sep 17 00:00:00 2001 From: hathach Date: Tue, 13 Jul 2021 21:09:23 +0700 Subject: fix midi stream write return value (off by 1) --- src/class/midi/midi_device.c | 21 ++++++++------------- 1 file changed, 8 insertions(+), 13 deletions(-) (limited to 'src/class') diff --git a/src/class/midi/midi_device.c b/src/class/midi/midi_device.c index 4eac0de48..c39e03976 100644 --- a/src/class/midi/midi_device.c +++ b/src/class/midi/midi_device.c @@ -240,15 +240,15 @@ uint32_t tud_midi_n_stream_write(uint8_t itf, uint8_t cable_num, uint8_t const* midid_stream_t* stream = &midi->stream_write; - uint32_t total_written = 0; uint32_t i = 0; - while ( i < bufsize ) + while ( (i < bufsize) && (tu_fifo_remaining(&midi->tx_ff) >= 4) ) { uint8_t const data = buffer[i]; + i++; if ( stream->index == 0 ) { - // new event packet + //------------- New event packet -------------// uint8_t const msg = data >> 4; @@ -310,9 +310,9 @@ uint32_t tud_midi_n_stream_write(uint8_t itf, uint8_t cable_num, uint8_t const* } else { - // On-going (buffering) packet + //------------- On-going (buffering) packet -------------// - TU_ASSERT(stream->index < 4, total_written); + TU_ASSERT(stream->index < 4, i); stream->buffer[stream->index] = data; stream->index++; @@ -335,19 +335,14 @@ uint32_t tud_midi_n_stream_write(uint8_t itf, uint8_t cable_num, uint8_t const* // complete current event packet, reset stream stream->index = stream->total = 0; - // fifo overflow, here we assume FIFO is multiple of 4 and didn't check remaining before writing - if ( count != 4 ) break; - - // updated written if succeeded - total_written = i; + // FIFO overflown, since we already check fifo remaining. It is probably race condition + TU_ASSERT(count == 4, i); } - - i++; } write_flush(midi); - return total_written; + return i; } bool tud_midi_n_packet_write (uint8_t itf, uint8_t const packet[4]) -- cgit v1.3.1 From ac8d0abecf93af2498f9d5d1438c2af7b133bedc Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 14 Jul 2021 15:04:38 +0700 Subject: rename dfu API - tud_dfu_dnload_complete() -> tud_dfu_download_complete() - tud_dfu_req_dnload_data_cb() -> tud_dfu_download_cb() - tud_dfu_req_upload_data_cb() -> tud_dfu_upload_cb() --- examples/device/dfu/src/main.c | 6 +++--- examples/device/midi_test/src/main.c | 10 +++++++--- src/class/dfu/dfu_device.c | 8 ++++---- src/class/dfu/dfu_device.h | 8 ++++---- 4 files changed, 18 insertions(+), 14 deletions(-) (limited to 'src/class') diff --git a/examples/device/dfu/src/main.c b/examples/device/dfu/src/main.c index 4ec6d477c..8e7fa9ee0 100644 --- a/examples/device/dfu/src/main.c +++ b/examples/device/dfu/src/main.c @@ -135,7 +135,7 @@ uint32_t tud_dfu_get_status_cb(uint8_t alt, uint8_t state) return 0; } -void tud_dfu_req_dnload_data_cb(uint8_t alt, uint16_t wBlockNum, uint8_t* data, uint16_t length) +void tud_dfu_download_cb(uint8_t alt, uint16_t wBlockNum, uint8_t* data, uint16_t length) { (void) data; printf(" Received Alt %u BlockNum %u of length %u\r\n", alt, wBlockNum, length); @@ -147,7 +147,7 @@ void tud_dfu_req_dnload_data_cb(uint8_t alt, uint16_t wBlockNum, uint8_t* data, } #endif - tud_dfu_dnload_complete(); + tud_dfu_download_complete(); } bool tud_dfu_device_data_done_check_cb(uint8_t alt) @@ -167,7 +167,7 @@ void tud_dfu_abort_cb(uint8_t alt) const uint8_t upload_test[2][UPLOAD_SIZE] = {"Hello world from TinyUSB DFU! - Partition 0", "Hello world from TinyUSB DFU! - Partition 1"}; -uint16_t tud_dfu_req_upload_data_cb(uint8_t alt, uint16_t block_num, uint8_t* data, uint16_t length) +uint16_t tud_dfu_upload_cb(uint8_t alt, uint16_t block_num, uint8_t* data, uint16_t length) { (void) block_num; (void) length; diff --git a/examples/device/midi_test/src/main.c b/examples/device/midi_test/src/main.c index 9e0e82a10..66b858323 100644 --- a/examples/device/midi_test/src/main.c +++ b/examples/device/midi_test/src/main.c @@ -134,10 +134,13 @@ void midi_task(void) uint8_t packet[4]; while ( tud_midi_available() ) tud_midi_packet_read(packet); - // send note every 1000 ms - if (board_millis() - start_ms < 286) return; // not enough time - start_ms += 286; + // send note periodically + if (board_millis() - start_ms < 1000) return; // not enough time + start_ms += 1000; +#if 1 + +#else // Previous positions in the note sequence. int previous = note_pos - 1; @@ -158,6 +161,7 @@ void midi_task(void) // If we are at the end of the sequence, start over. if (note_pos >= sizeof(note_sequence)) note_pos = 0; +#endif } //--------------------------------------------------------------------+ diff --git a/src/class/dfu/dfu_device.c b/src/class/dfu/dfu_device.c index 23669b508..c8c0bcfd4 100644 --- a/src/class/dfu/dfu_device.c +++ b/src/class/dfu/dfu_device.c @@ -283,9 +283,9 @@ static uint16_t dfu_req_upload(uint8_t rhport, tusb_control_request_t const * re { TU_VERIFY( wLength <= CFG_TUD_DFU_TRANSFER_BUFFER_SIZE, 0); uint16_t retval = 0; - if (tud_dfu_req_upload_data_cb) + if (tud_dfu_upload_cb) { - tud_dfu_req_upload_data_cb(_dfu_state_ctx.alt, block_num, (uint8_t *)_dfu_state_ctx.transfer_buf, wLength); + tud_dfu_upload_cb(_dfu_state_ctx.alt, block_num, (uint8_t *)_dfu_state_ctx.transfer_buf, wLength); } tud_control_xfer(rhport, request, _dfu_state_ctx.transfer_buf, retval); return retval; @@ -330,11 +330,11 @@ static void dfu_req_dnload_reply(uint8_t rhport, tusb_control_request_t const * { (void) rhport; TU_VERIFY( request->wLength <= CFG_TUD_DFU_TRANSFER_BUFFER_SIZE, ); - tud_dfu_req_dnload_data_cb(_dfu_state_ctx.alt,_dfu_state_ctx.block, (uint8_t *)_dfu_state_ctx.transfer_buf, _dfu_state_ctx.length); + tud_dfu_download_cb(_dfu_state_ctx.alt,_dfu_state_ctx.block, (uint8_t *)_dfu_state_ctx.transfer_buf, _dfu_state_ctx.length); _dfu_state_ctx.blk_transfer_in_proc = false; } -void tud_dfu_dnload_complete(void) +void tud_dfu_download_complete(void) { if (_dfu_state_ctx.state == DFU_DNBUSY) { diff --git a/src/class/dfu/dfu_device.h b/src/class/dfu/dfu_device.h index 647fc2c04..2a1f5a8e7 100644 --- a/src/class/dfu/dfu_device.h +++ b/src/class/dfu/dfu_device.h @@ -58,11 +58,11 @@ TU_ATTR_WEAK uint32_t tud_dfu_get_status_cb(uint8_t alt, uint8_t state); // This callback takes the wBlockNum chunk of length length and provides it // to the application at the data pointer. This data is only valid for this // call, so the app must use it not or copy it. -void tud_dfu_req_dnload_data_cb(uint8_t alt, uint16_t wBlockNum, uint8_t* data, uint16_t length); +void tud_dfu_download_cb(uint8_t alt, uint16_t wBlockNum, uint8_t* data, uint16_t length); // Must be called when the application is done using the last block of data -// provided by tud_dfu_req_dnload_data_cb -void tud_dfu_dnload_complete(void); +// provided by tud_dfu_download_cb +void tud_dfu_download_complete(void); // Invoked during the last DFU_DNLOAD request, signifying that the host believes // it is done transmitting data. @@ -79,7 +79,7 @@ TU_ATTR_WEAK void tud_dfu_abort_cb(uint8_t alt); // alt is used as the partition number, in order to support multiple partitions like FLASH, EEPROM, etc. // This callback must populate data with up to length bytes // Return the number of bytes to write -TU_ATTR_WEAK uint16_t tud_dfu_req_upload_data_cb(uint8_t alt, uint16_t block_num, uint8_t* data, uint16_t length); +TU_ATTR_WEAK uint16_t tud_dfu_upload_cb(uint8_t alt, uint16_t block_num, uint8_t* data, uint16_t length); // Invoked when a DFU_DETACH request is received TU_ATTR_WEAK void tud_dfu_reboot_cb(void); -- cgit v1.3.1 From 57d9f696a2c11cf0004ea2eec1204d80c657cb03 Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 14 Jul 2021 15:24:09 +0700 Subject: clean up --- src/class/dfu/dfu_device.c | 73 ++++++++++------------------------------------ 1 file changed, 16 insertions(+), 57 deletions(-) (limited to 'src/class') diff --git a/src/class/dfu/dfu_device.c b/src/class/dfu/dfu_device.c index c8c0bcfd4..dcdc34977 100644 --- a/src/class/dfu/dfu_device.c +++ b/src/class/dfu/dfu_device.c @@ -46,7 +46,7 @@ typedef struct dfu_state_t state; uint8_t attrs; bool blk_transfer_in_proc; - uint8_t alt; + uint8_t alt_num; uint16_t block; uint16_t length; CFG_TUSB_MEM_ALIGN uint8_t transfer_buf[CFG_TUD_DFU_TRANSFER_BUFFER_SIZE]; @@ -149,7 +149,7 @@ void dfu_moded_init(void) _dfu_state_ctx.status = DFU_STATUS_OK; _dfu_state_ctx.attrs = 0; _dfu_state_ctx.blk_transfer_in_proc = false; - _dfu_state_ctx.alt = 0; + _dfu_state_ctx.alt_num = 0; dfu_debug_print_context(); } @@ -162,7 +162,7 @@ void dfu_moded_reset(uint8_t rhport) _dfu_state_ctx.status = DFU_STATUS_OK; _dfu_state_ctx.attrs = 0; _dfu_state_ctx.blk_transfer_in_proc = false; - _dfu_state_ctx.alt = 0; + _dfu_state_ctx.alt_num = 0; dfu_debug_print_context(); } @@ -221,7 +221,7 @@ bool dfu_moded_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_reque if (request->bmRequestType_bit.type == TUSB_REQ_TYPE_STANDARD && request->bRequest == TUSB_REQ_SET_INTERFACE) { // Switch Alt interface - _dfu_state_ctx.alt = request->wValue; + _dfu_state_ctx.alt_num = (uint8_t) request->wValue; // Re-initalise state machine (Necessary ?) _dfu_state_ctx.state = DFU_IDLE; @@ -244,6 +244,7 @@ bool dfu_moded_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_reque if (tud_dfu_reboot_cb) tud_dfu_reboot_cb(); break; } + case DFU_REQUEST_DNLOAD: { if ( (stage == CONTROL_STAGE_ACK) @@ -254,7 +255,8 @@ bool dfu_moded_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_reque _dfu_state_ctx.length = request->wLength; return true; } - } // fallthrough + } + // fallthrough case DFU_REQUEST_UPLOAD: case DFU_REQUEST_GETSTATUS: case DFU_REQUEST_CLRSTATUS: @@ -285,7 +287,7 @@ static uint16_t dfu_req_upload(uint8_t rhport, tusb_control_request_t const * re uint16_t retval = 0; if (tud_dfu_upload_cb) { - tud_dfu_upload_cb(_dfu_state_ctx.alt, block_num, (uint8_t *)_dfu_state_ctx.transfer_buf, wLength); + tud_dfu_upload_cb(_dfu_state_ctx.alt_num, block_num, (uint8_t *)_dfu_state_ctx.transfer_buf, wLength); } tud_control_xfer(rhport, request, _dfu_state_ctx.transfer_buf, retval); return retval; @@ -296,7 +298,7 @@ static void dfu_req_getstatus_reply(uint8_t rhport, tusb_control_request_t const uint32_t timeout = 0; if ( tud_dfu_get_status_cb ) { - timeout = tud_dfu_get_status_cb(_dfu_state_ctx.alt, _dfu_state_ctx.state); + timeout = tud_dfu_get_status_cb(_dfu_state_ctx.alt_num, _dfu_state_ctx.state); } dfu_status_req_payload_t resp; @@ -330,7 +332,7 @@ static void dfu_req_dnload_reply(uint8_t rhport, tusb_control_request_t const * { (void) rhport; TU_VERIFY( request->wLength <= CFG_TUD_DFU_TRANSFER_BUFFER_SIZE, ); - tud_dfu_download_cb(_dfu_state_ctx.alt,_dfu_state_ctx.block, (uint8_t *)_dfu_state_ctx.transfer_buf, _dfu_state_ctx.length); + tud_dfu_download_cb(_dfu_state_ctx.alt_num,_dfu_state_ctx.block, (uint8_t *)_dfu_state_ctx.transfer_buf, _dfu_state_ctx.length); _dfu_state_ctx.blk_transfer_in_proc = false; } @@ -384,28 +386,20 @@ static bool dfu_state_machine(uint8_t rhport, tusb_control_request_t const * req break; case DFU_REQUEST_GETSTATUS: - { dfu_req_getstatus_reply(rhport, request); - } break; case DFU_REQUEST_GETSTATE: - { dfu_req_getstate_reply(rhport, request); - } break; case DFU_REQUEST_ABORT: - { ; // do nothing, but don't stall so continue on - } break; default: - { _dfu_state_ctx.state = DFU_ERROR; return false; // stall on all other requests - } break; } } @@ -430,16 +424,12 @@ static bool dfu_state_machine(uint8_t rhport, tusb_control_request_t const * req break; case DFU_REQUEST_GETSTATE: - { dfu_req_getstate_reply(rhport, request); - } break; default: - { _dfu_state_ctx.state = DFU_ERROR; return false; // stall on all other requests - } break; } } @@ -450,10 +440,8 @@ static bool dfu_state_machine(uint8_t rhport, tusb_control_request_t const * req switch (request->bRequest) { default: - { _dfu_state_ctx.state = DFU_ERROR; return false; // stall on all other requests - } break; } } @@ -472,7 +460,7 @@ static bool dfu_state_machine(uint8_t rhport, tusb_control_request_t const * req _dfu_state_ctx.blk_transfer_in_proc = true; dfu_req_dnload_setup(rhport, request); } else { - if ( tud_dfu_device_data_done_check_cb(_dfu_state_ctx.alt) ) + if ( tud_dfu_device_data_done_check_cb(_dfu_state_ctx.alt_num) ) { _dfu_state_ctx.state = DFU_MANIFEST_SYNC; tud_control_status(rhport, request); @@ -485,32 +473,24 @@ static bool dfu_state_machine(uint8_t rhport, tusb_control_request_t const * req break; case DFU_REQUEST_GETSTATUS: - { dfu_req_getstatus_reply(rhport, request); - } break; case DFU_REQUEST_GETSTATE: - { dfu_req_getstate_reply(rhport, request); - } break; case DFU_REQUEST_ABORT: - { if ( tud_dfu_abort_cb ) { - tud_dfu_abort_cb(_dfu_state_ctx.alt); + tud_dfu_abort_cb(_dfu_state_ctx.alt_num); } _dfu_state_ctx.state = DFU_IDLE; - } break; default: - { _dfu_state_ctx.state = DFU_ERROR; return false; // stall on all other requests - } break; } } @@ -528,7 +508,7 @@ static bool dfu_state_machine(uint8_t rhport, tusb_control_request_t const * req dfu_req_getstatus_reply(rhport, request); } else { - if ( tud_dfu_firmware_valid_check_cb(_dfu_state_ctx.alt) ) + if ( tud_dfu_firmware_valid_check_cb(_dfu_state_ctx.alt_num) ) { _dfu_state_ctx.state = DFU_IDLE; } @@ -538,16 +518,12 @@ static bool dfu_state_machine(uint8_t rhport, tusb_control_request_t const * req break; case DFU_REQUEST_GETSTATE: - { dfu_req_getstate_reply(rhport, request); - } break; default: - { _dfu_state_ctx.state = DFU_ERROR; return false; // stall on all other requests - } break; } } @@ -557,10 +533,9 @@ static bool dfu_state_machine(uint8_t rhport, tusb_control_request_t const * req { switch (request->bRequest) { + // stall on all other requests default: - { - return false; // stall on all other requests - } + return false; break; } } @@ -573,9 +548,7 @@ static bool dfu_state_machine(uint8_t rhport, tusb_control_request_t const * req switch (request->bRequest) { default: - { return false; // stall on all other requests - } break; } } @@ -595,31 +568,25 @@ static bool dfu_state_machine(uint8_t rhport, tusb_control_request_t const * req break; case DFU_REQUEST_GETSTATUS: - { dfu_req_getstatus_reply(rhport, request); - } break; case DFU_REQUEST_GETSTATE: - { dfu_req_getstate_reply(rhport, request); - } break; case DFU_REQUEST_ABORT: { if (tud_dfu_abort_cb) { - tud_dfu_abort_cb(_dfu_state_ctx.alt); + tud_dfu_abort_cb(_dfu_state_ctx.alt_num); } _dfu_state_ctx.state = DFU_IDLE; } break; default: - { return false; // stall on all other requests - } break; } } @@ -630,27 +597,19 @@ static bool dfu_state_machine(uint8_t rhport, tusb_control_request_t const * req switch (request->bRequest) { case DFU_REQUEST_GETSTATUS: - { dfu_req_getstatus_reply(rhport, request); - } break; case DFU_REQUEST_CLRSTATUS: - { _dfu_state_ctx.state = DFU_IDLE; - } break; case DFU_REQUEST_GETSTATE: - { dfu_req_getstate_reply(rhport, request); - } break; default: - { return false; // stall on all other requests - } break; } } -- cgit v1.3.1 From 27676f738d54c1edf87449531b3a1fd24fca59d3 Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 14 Jul 2021 15:31:20 +0700 Subject: rename tud_dfu_reboot_cb() to tud_dfu_detach_cb() --- src/class/dfu/dfu_device.c | 2 +- src/class/dfu/dfu_device.h | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) (limited to 'src/class') diff --git a/src/class/dfu/dfu_device.c b/src/class/dfu/dfu_device.c index dcdc34977..c807004ec 100644 --- a/src/class/dfu/dfu_device.c +++ b/src/class/dfu/dfu_device.c @@ -241,7 +241,7 @@ bool dfu_moded_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_reque case DFU_REQUEST_DETACH: { tud_control_status(rhport, request); - if (tud_dfu_reboot_cb) tud_dfu_reboot_cb(); + if (tud_dfu_detach_cb) tud_dfu_detach_cb(); break; } diff --git a/src/class/dfu/dfu_device.h b/src/class/dfu/dfu_device.h index 2a1f5a8e7..d5d464f3b 100644 --- a/src/class/dfu/dfu_device.h +++ b/src/class/dfu/dfu_device.h @@ -82,7 +82,8 @@ TU_ATTR_WEAK void tud_dfu_abort_cb(uint8_t alt); TU_ATTR_WEAK uint16_t tud_dfu_upload_cb(uint8_t alt, uint16_t block_num, uint8_t* data, uint16_t length); // Invoked when a DFU_DETACH request is received -TU_ATTR_WEAK void tud_dfu_reboot_cb(void); +TU_ATTR_WEAK void tud_dfu_detach_cb(void); + //--------------------------------------------------------------------+ // Internal Class Driver API //--------------------------------------------------------------------+ -- cgit v1.3.1 From 5b965a38883efb2d7210d48be6f305c0f31ca8fc Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 14 Jul 2021 15:52:38 +0700 Subject: more rename and update --- examples/device/dfu/src/main.c | 14 +-- src/class/dfu/dfu_device.c | 231 +++++++++++++++++++++-------------------- 2 files changed, 128 insertions(+), 117 deletions(-) (limited to 'src/class') diff --git a/examples/device/dfu/src/main.c b/examples/device/dfu/src/main.c index 8e7fa9ee0..2c114c5a2 100644 --- a/examples/device/dfu/src/main.c +++ b/examples/device/dfu/src/main.c @@ -28,11 +28,13 @@ * * To transfer firmware from host to device: * - * $ dfu-util -D [filename] + * $ dfu-util -d cafe -a 0 -D [filename] + * $ dfu-util -d cafe -a 1 -D [filename] * * To transfer firmware from device to host: * - * $ dfu-util -U [filename] + * $ dfu-util -d cafe -a 0 -U [filename] + * $ dfu-util -d cafe -a 1 -U [filename] * */ @@ -138,12 +140,12 @@ uint32_t tud_dfu_get_status_cb(uint8_t alt, uint8_t state) void tud_dfu_download_cb(uint8_t alt, uint16_t wBlockNum, uint8_t* data, uint16_t length) { (void) data; - printf(" Received Alt %u BlockNum %u of length %u\r\n", alt, wBlockNum, length); + printf("Received Alt %u BlockNum %u of length %u\r\n", alt, wBlockNum, length); #if DFU_VERBOSE for(uint16_t i=0; ibAttributes; + _dfu_ctx.attrs = func_desc->bAttributes; // CFG_TUD_DFU_TRANSFER_BUFFER_SIZE has to be set to the buffer size used in TUD_DFU_DESCRIPTOR uint16_t const transfer_size = tu_le16toh( tu_unaligned_read16(&func_desc->wTransferSize) ); @@ -215,67 +215,76 @@ bool dfu_moded_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_reque TU_VERIFY(request->bmRequestType_bit.recipient == TUSB_REQ_RCPT_INTERFACE); - if(stage == CONTROL_STAGE_SETUP) + if ( request->bmRequestType_bit.type == TUSB_REQ_TYPE_STANDARD ) { - // dfu-util will try to claim the interface with SET_INTERFACE request before sending DFU request - if (request->bmRequestType_bit.type == TUSB_REQ_TYPE_STANDARD && request->bRequest == TUSB_REQ_SET_INTERFACE) + // Standard request include GET/SET_INTERFACE + switch (request->bRequest ) { - // Switch Alt interface - _dfu_state_ctx.alt_num = (uint8_t) request->wValue; + case TUSB_REQ_SET_INTERFACE: + // Switch Alt interface and Re-initalize state machine + _dfu_ctx.alt_num = (uint8_t) request->wValue; + _dfu_ctx.state = DFU_IDLE; + _dfu_ctx.status = DFU_STATUS_OK; + _dfu_ctx.blk_transfer_in_proc = false; + + return tud_control_status(rhport, request); + break; - // Re-initalise state machine (Necessary ?) - _dfu_state_ctx.state = DFU_IDLE; - _dfu_state_ctx.status = DFU_STATUS_OK; - _dfu_state_ctx.blk_transfer_in_proc = false; + case TUSB_REQ_GET_INTERFACE: + return tud_control_xfer(rhport, request, &_dfu_ctx.alt_num, 1); + break; - tud_control_status(rhport, request); - return true; + // unsupported request + default: return false; } } - - // Handle class request only from here - TU_VERIFY(request->bmRequestType_bit.type == TUSB_REQ_TYPE_CLASS); - - switch (request->bRequest) + else if (request->bmRequestType_bit.type == TUSB_REQ_TYPE_CLASS) { - case DFU_REQUEST_DETACH: + // Class request + switch (request->bRequest) { - tud_control_status(rhport, request); - if (tud_dfu_detach_cb) tud_dfu_detach_cb(); - break; - } + case DFU_REQUEST_DETACH: + { + tud_control_status(rhport, request); + if (tud_dfu_detach_cb) tud_dfu_detach_cb(); + break; + } - case DFU_REQUEST_DNLOAD: - { - if ( (stage == CONTROL_STAGE_ACK) - && ((_dfu_state_ctx.attrs & DFU_FUNC_ATTR_CAN_DOWNLOAD_BITMASK) != 0) - && (_dfu_state_ctx.state == DFU_DNLOAD_SYNC)) + case DFU_REQUEST_DNLOAD: { - _dfu_state_ctx.block = request->wValue; - _dfu_state_ctx.length = request->wLength; - return true; + if ( (stage == CONTROL_STAGE_ACK) + && ((_dfu_ctx.attrs & DFU_FUNC_ATTR_CAN_DOWNLOAD_BITMASK) != 0) + && (_dfu_ctx.state == DFU_DNLOAD_SYNC)) + { + _dfu_ctx.block = request->wValue; + _dfu_ctx.length = request->wLength; + return true; + } } - } - // fallthrough - case DFU_REQUEST_UPLOAD: - case DFU_REQUEST_GETSTATUS: - case DFU_REQUEST_CLRSTATUS: - case DFU_REQUEST_GETSTATE: - case DFU_REQUEST_ABORT: - { - if(stage == CONTROL_STAGE_SETUP) + // fallthrough + case DFU_REQUEST_UPLOAD: + case DFU_REQUEST_GETSTATUS: + case DFU_REQUEST_CLRSTATUS: + case DFU_REQUEST_GETSTATE: + case DFU_REQUEST_ABORT: { - return dfu_state_machine(rhport, request); + if(stage == CONTROL_STAGE_SETUP) + { + return dfu_state_machine(rhport, request); + } } - } - break; + break; - default: - { - TU_LOG2(" DFU Nonstandard Request: %u\r\n", request->bRequest); - return false; // stall unsupported request + default: + { + TU_LOG2(" DFU Nonstandard Request: %u\r\n", request->bRequest); + return false; // stall unsupported request + } + break; } - break; + }else + { + return false; // unsupported request } return true; @@ -287,9 +296,9 @@ static uint16_t dfu_req_upload(uint8_t rhport, tusb_control_request_t const * re uint16_t retval = 0; if (tud_dfu_upload_cb) { - tud_dfu_upload_cb(_dfu_state_ctx.alt_num, block_num, (uint8_t *)_dfu_state_ctx.transfer_buf, wLength); + tud_dfu_upload_cb(_dfu_ctx.alt_num, block_num, (uint8_t *)_dfu_ctx.transfer_buf, wLength); } - tud_control_xfer(rhport, request, _dfu_state_ctx.transfer_buf, retval); + tud_control_xfer(rhport, request, _dfu_ctx.transfer_buf, retval); return retval; } @@ -298,15 +307,15 @@ static void dfu_req_getstatus_reply(uint8_t rhport, tusb_control_request_t const uint32_t timeout = 0; if ( tud_dfu_get_status_cb ) { - timeout = tud_dfu_get_status_cb(_dfu_state_ctx.alt_num, _dfu_state_ctx.state); + timeout = tud_dfu_get_status_cb(_dfu_ctx.alt_num, _dfu_ctx.state); } dfu_status_req_payload_t resp; - resp.bStatus = _dfu_state_ctx.status; + resp.bStatus = _dfu_ctx.status; resp.bwPollTimeout[0] = TU_U32_BYTE0(timeout); resp.bwPollTimeout[1] = TU_U32_BYTE1(timeout); resp.bwPollTimeout[2] = TU_U32_BYTE2(timeout); - resp.bState = _dfu_state_ctx.state; + resp.bState = _dfu_ctx.state; resp.iString = 0; tud_control_xfer(rhport, request, &resp, sizeof(dfu_status_req_payload_t)); @@ -314,7 +323,7 @@ static void dfu_req_getstatus_reply(uint8_t rhport, tusb_control_request_t const static void dfu_req_getstate_reply(uint8_t rhport, tusb_control_request_t const * request) { - tud_control_xfer(rhport, request, &_dfu_state_ctx.state, 1); + tud_control_xfer(rhport, request, &_dfu_ctx.state, 1); } static void dfu_req_dnload_setup(uint8_t rhport, tusb_control_request_t const * request) @@ -325,25 +334,25 @@ static void dfu_req_dnload_setup(uint8_t rhport, tusb_control_request_t const * TU_VERIFY( request->wLength <= CFG_TUD_DFU_TRANSFER_BUFFER_SIZE, ); // setup for data phase - tud_control_xfer(rhport, request, _dfu_state_ctx.transfer_buf, request->wLength); + tud_control_xfer(rhport, request, _dfu_ctx.transfer_buf, request->wLength); } static void dfu_req_dnload_reply(uint8_t rhport, tusb_control_request_t const * request) { (void) rhport; TU_VERIFY( request->wLength <= CFG_TUD_DFU_TRANSFER_BUFFER_SIZE, ); - tud_dfu_download_cb(_dfu_state_ctx.alt_num,_dfu_state_ctx.block, (uint8_t *)_dfu_state_ctx.transfer_buf, _dfu_state_ctx.length); - _dfu_state_ctx.blk_transfer_in_proc = false; + tud_dfu_download_cb(_dfu_ctx.alt_num,_dfu_ctx.block, (uint8_t *)_dfu_ctx.transfer_buf, _dfu_ctx.length); + _dfu_ctx.blk_transfer_in_proc = false; } void tud_dfu_download_complete(void) { - if (_dfu_state_ctx.state == DFU_DNBUSY) + if (_dfu_ctx.state == DFU_DNBUSY) { - _dfu_state_ctx.state = DFU_DNLOAD_SYNC; - } else if (_dfu_state_ctx.state == DFU_MANIFEST) + _dfu_ctx.state = DFU_DNLOAD_SYNC; + } else if (_dfu_ctx.state == DFU_MANIFEST) { - _dfu_state_ctx.state = ((_dfu_state_ctx.attrs & DFU_FUNC_ATTR_MANIFESTATION_TOLERANT_BITMASK) == 0) + _dfu_ctx.state = ((_dfu_ctx.attrs & DFU_FUNC_ATTR_MANIFESTATION_TOLERANT_BITMASK) == 0) ? DFU_MANIFEST_WAIT_RESET : DFU_MANIFEST_SYNC; } } @@ -351,9 +360,9 @@ void tud_dfu_download_complete(void) static bool dfu_state_machine(uint8_t rhport, tusb_control_request_t const * request) { TU_LOG2(" DFU Request: %s\r\n", tu_lookup_find(&_dfu_request_table, request->bRequest)); - TU_LOG2(" DFU State Machine: %s\r\n", tu_lookup_find(&_dfu_state_table, _dfu_state_ctx.state)); + TU_LOG2(" DFU State Machine: %s\r\n", tu_lookup_find(&_dfu_state_table, _dfu_ctx.state)); - switch (_dfu_state_ctx.state) + switch (_dfu_ctx.state) { case DFU_IDLE: { @@ -361,26 +370,26 @@ static bool dfu_state_machine(uint8_t rhport, tusb_control_request_t const * req { case DFU_REQUEST_DNLOAD: { - if( ((_dfu_state_ctx.attrs & DFU_FUNC_ATTR_CAN_DOWNLOAD_BITMASK) != 0) + if( ((_dfu_ctx.attrs & DFU_FUNC_ATTR_CAN_DOWNLOAD_BITMASK) != 0) && (request->wLength > 0) ) { - _dfu_state_ctx.state = DFU_DNLOAD_SYNC; - _dfu_state_ctx.blk_transfer_in_proc = true; + _dfu_ctx.state = DFU_DNLOAD_SYNC; + _dfu_ctx.blk_transfer_in_proc = true; dfu_req_dnload_setup(rhport, request); } else { - _dfu_state_ctx.state = DFU_ERROR; + _dfu_ctx.state = DFU_ERROR; } } break; case DFU_REQUEST_UPLOAD: { - if( ((_dfu_state_ctx.attrs & DFU_FUNC_ATTR_CAN_UPLOAD_BITMASK) != 0) ) + if( ((_dfu_ctx.attrs & DFU_FUNC_ATTR_CAN_UPLOAD_BITMASK) != 0) ) { - _dfu_state_ctx.state = DFU_UPLOAD_IDLE; + _dfu_ctx.state = DFU_UPLOAD_IDLE; dfu_req_upload(rhport, request, request->wValue, request->wLength); } else { - _dfu_state_ctx.state = DFU_ERROR; + _dfu_ctx.state = DFU_ERROR; } } break; @@ -398,7 +407,7 @@ static bool dfu_state_machine(uint8_t rhport, tusb_control_request_t const * req break; default: - _dfu_state_ctx.state = DFU_ERROR; + _dfu_ctx.state = DFU_ERROR; return false; // stall on all other requests break; } @@ -411,13 +420,13 @@ static bool dfu_state_machine(uint8_t rhport, tusb_control_request_t const * req { case DFU_REQUEST_GETSTATUS: { - if ( _dfu_state_ctx.blk_transfer_in_proc ) + if ( _dfu_ctx.blk_transfer_in_proc ) { - _dfu_state_ctx.state = DFU_DNBUSY; + _dfu_ctx.state = DFU_DNBUSY; dfu_req_getstatus_reply(rhport, request); dfu_req_dnload_reply(rhport, request); } else { - _dfu_state_ctx.state = DFU_DNLOAD_IDLE; + _dfu_ctx.state = DFU_DNLOAD_IDLE; dfu_req_getstatus_reply(rhport, request); } } @@ -428,7 +437,7 @@ static bool dfu_state_machine(uint8_t rhport, tusb_control_request_t const * req break; default: - _dfu_state_ctx.state = DFU_ERROR; + _dfu_ctx.state = DFU_ERROR; return false; // stall on all other requests break; } @@ -440,7 +449,7 @@ static bool dfu_state_machine(uint8_t rhport, tusb_control_request_t const * req switch (request->bRequest) { default: - _dfu_state_ctx.state = DFU_ERROR; + _dfu_ctx.state = DFU_ERROR; return false; // stall on all other requests break; } @@ -453,19 +462,19 @@ static bool dfu_state_machine(uint8_t rhport, tusb_control_request_t const * req { case DFU_REQUEST_DNLOAD: { - if( ((_dfu_state_ctx.attrs & DFU_FUNC_ATTR_CAN_DOWNLOAD_BITMASK) != 0) + if( ((_dfu_ctx.attrs & DFU_FUNC_ATTR_CAN_DOWNLOAD_BITMASK) != 0) && (request->wLength > 0) ) { - _dfu_state_ctx.state = DFU_DNLOAD_SYNC; - _dfu_state_ctx.blk_transfer_in_proc = true; + _dfu_ctx.state = DFU_DNLOAD_SYNC; + _dfu_ctx.blk_transfer_in_proc = true; dfu_req_dnload_setup(rhport, request); } else { - if ( tud_dfu_device_data_done_check_cb(_dfu_state_ctx.alt_num) ) + if ( tud_dfu_device_data_done_check_cb(_dfu_ctx.alt_num) ) { - _dfu_state_ctx.state = DFU_MANIFEST_SYNC; + _dfu_ctx.state = DFU_MANIFEST_SYNC; tud_control_status(rhport, request); } else { - _dfu_state_ctx.state = DFU_ERROR; + _dfu_ctx.state = DFU_ERROR; return false; // stall } } @@ -483,13 +492,13 @@ static bool dfu_state_machine(uint8_t rhport, tusb_control_request_t const * req case DFU_REQUEST_ABORT: if ( tud_dfu_abort_cb ) { - tud_dfu_abort_cb(_dfu_state_ctx.alt_num); + tud_dfu_abort_cb(_dfu_ctx.alt_num); } - _dfu_state_ctx.state = DFU_IDLE; + _dfu_ctx.state = DFU_IDLE; break; default: - _dfu_state_ctx.state = DFU_ERROR; + _dfu_ctx.state = DFU_ERROR; return false; // stall on all other requests break; } @@ -502,15 +511,15 @@ static bool dfu_state_machine(uint8_t rhport, tusb_control_request_t const * req { case DFU_REQUEST_GETSTATUS: { - if ((_dfu_state_ctx.attrs & DFU_FUNC_ATTR_MANIFESTATION_TOLERANT_BITMASK) == 0) + if ((_dfu_ctx.attrs & DFU_FUNC_ATTR_MANIFESTATION_TOLERANT_BITMASK) == 0) { - _dfu_state_ctx.state = DFU_MANIFEST; + _dfu_ctx.state = DFU_MANIFEST; dfu_req_getstatus_reply(rhport, request); } else { - if ( tud_dfu_firmware_valid_check_cb(_dfu_state_ctx.alt_num) ) + if ( tud_dfu_firmware_valid_check_cb(_dfu_ctx.alt_num) ) { - _dfu_state_ctx.state = DFU_IDLE; + _dfu_ctx.state = DFU_IDLE; } dfu_req_getstatus_reply(rhport, request); } @@ -522,7 +531,7 @@ static bool dfu_state_machine(uint8_t rhport, tusb_control_request_t const * req break; default: - _dfu_state_ctx.state = DFU_ERROR; + _dfu_ctx.state = DFU_ERROR; return false; // stall on all other requests break; } @@ -562,7 +571,7 @@ static bool dfu_state_machine(uint8_t rhport, tusb_control_request_t const * req { if (dfu_req_upload(rhport, request, request->wValue, request->wLength) != request->wLength) { - _dfu_state_ctx.state = DFU_IDLE; + _dfu_ctx.state = DFU_IDLE; } } break; @@ -579,9 +588,9 @@ static bool dfu_state_machine(uint8_t rhport, tusb_control_request_t const * req { if (tud_dfu_abort_cb) { - tud_dfu_abort_cb(_dfu_state_ctx.alt_num); + tud_dfu_abort_cb(_dfu_ctx.alt_num); } - _dfu_state_ctx.state = DFU_IDLE; + _dfu_ctx.state = DFU_IDLE; } break; @@ -601,7 +610,7 @@ static bool dfu_state_machine(uint8_t rhport, tusb_control_request_t const * req break; case DFU_REQUEST_CLRSTATUS: - _dfu_state_ctx.state = DFU_IDLE; + _dfu_ctx.state = DFU_IDLE; break; case DFU_REQUEST_GETSTATE: @@ -616,7 +625,7 @@ static bool dfu_state_machine(uint8_t rhport, tusb_control_request_t const * req break; default: - _dfu_state_ctx.state = DFU_ERROR; + _dfu_ctx.state = DFU_ERROR; TU_LOG2(" DFU ERROR: Unexpected state\r\nStalling control pipe\r\n"); return false; // Unexpected state, stall and change to error } -- cgit v1.3.1 From 95ded08e3b96b77bbbb1e11e7f0043fb86b7316f Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 14 Jul 2021 16:42:12 +0700 Subject: simplify upload request --- src/class/dfu/dfu.h | 8 ++--- src/class/dfu/dfu_device.c | 88 ++++++++++++++++++++-------------------------- src/common/tusb_types.h | 2 +- 3 files changed, 43 insertions(+), 55 deletions(-) (limited to 'src/class') diff --git a/src/class/dfu/dfu.h b/src/class/dfu/dfu.h index 18de3bf99..88f2f3529 100644 --- a/src/class/dfu/dfu.h +++ b/src/class/dfu/dfu.h @@ -95,10 +95,10 @@ typedef enum { DFU_STATUS_ERRSTALLEDPKT = 0x0F, } dfu_device_status_t; -#define DFU_FUNC_ATTR_CAN_DOWNLOAD_BITMASK (1 << 0) -#define DFU_FUNC_ATTR_CAN_UPLOAD_BITMASK (1 << 1) -#define DFU_FUNC_ATTR_MANIFESTATION_TOLERANT_BITMASK (1 << 2) -#define DFU_FUNC_ATTR_WILL_DETACH_BITMASK (1 << 3) +#define DFU_FUNC_ATTR_CAN_DOWNLOAD_BITMASK (1u << 0) +#define DFU_FUNC_ATTR_CAN_UPLOAD_BITMASK (1u << 1) +#define DFU_FUNC_ATTR_MANIFESTATION_TOLERANT_BITMASK (1u << 2) +#define DFU_FUNC_ATTR_WILL_DETACH_BITMASK (1u << 3) // DFU Status Request Payload typedef struct TU_ATTR_PACKED diff --git a/src/class/dfu/dfu_device.c b/src/class/dfu/dfu_device.c index 7b2f920d2..376feb053 100644 --- a/src/class/dfu/dfu_device.c +++ b/src/class/dfu/dfu_device.c @@ -58,7 +58,6 @@ CFG_TUSB_MEM_SECTION static dfu_state_ctx_t _dfu_ctx; static void dfu_req_dnload_setup(uint8_t rhport, tusb_control_request_t const * request); static void dfu_req_getstatus_reply(uint8_t rhport, tusb_control_request_t const * request); -static uint16_t dfu_req_upload(uint8_t rhport, tusb_control_request_t const * request, uint16_t block_num, uint16_t wLength); static void dfu_req_dnload_reply(uint8_t rhport, tusb_control_request_t const * request); static bool dfu_state_machine(uint8_t rhport, tusb_control_request_t const * request); @@ -218,37 +217,60 @@ bool dfu_moded_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_reque if ( request->bmRequestType_bit.type == TUSB_REQ_TYPE_STANDARD ) { // Standard request include GET/SET_INTERFACE - switch (request->bRequest ) + switch ( request->bRequest ) { case TUSB_REQ_SET_INTERFACE: - // Switch Alt interface and Re-initalize state machine - _dfu_ctx.alt_num = (uint8_t) request->wValue; - _dfu_ctx.state = DFU_IDLE; - _dfu_ctx.status = DFU_STATUS_OK; - _dfu_ctx.blk_transfer_in_proc = false; + if ( stage == CONTROL_STAGE_SETUP ) + { + // Switch Alt interface and Re-initalize state machine + _dfu_ctx.alt_num = (uint8_t) request->wValue; + _dfu_ctx.state = DFU_IDLE; + _dfu_ctx.status = DFU_STATUS_OK; + _dfu_ctx.blk_transfer_in_proc = false; - return tud_control_status(rhport, request); + return tud_control_status(rhport, request); + } break; case TUSB_REQ_GET_INTERFACE: - return tud_control_xfer(rhport, request, &_dfu_ctx.alt_num, 1); + if(stage == CONTROL_STAGE_SETUP) + { + return tud_control_xfer(rhport, request, &_dfu_ctx.alt_num, 1); + } break; // unsupported request default: return false; } } - else if (request->bmRequestType_bit.type == TUSB_REQ_TYPE_CLASS) + else if ( request->bmRequestType_bit.type == TUSB_REQ_TYPE_CLASS ) { // Class request - switch (request->bRequest) + switch ( request->bRequest ) { case DFU_REQUEST_DETACH: - { - tud_control_status(rhport, request); - if (tud_dfu_detach_cb) tud_dfu_detach_cb(); - break; - } + if ( stage == CONTROL_STAGE_SETUP ) + { + tud_control_status(rhport, request); + } + else if ( stage == CONTROL_STAGE_ACK ) + { + if (tud_dfu_detach_cb) tud_dfu_detach_cb(); + } + break; + + case DFU_REQUEST_UPLOAD: + if ( stage == CONTROL_STAGE_SETUP ) + { + TU_VERIFY(_dfu_ctx.attrs & DFU_FUNC_ATTR_CAN_UPLOAD_BITMASK); + TU_VERIFY(tud_dfu_upload_cb); + TU_VERIFY(request->wLength <= CFG_TUD_DFU_TRANSFER_BUFFER_SIZE); + + uint16_t const xfer_len = tud_dfu_upload_cb(_dfu_ctx.alt_num, request->wValue, _dfu_ctx.transfer_buf, request->wLength); + + tud_control_xfer(rhport, request, _dfu_ctx.transfer_buf, xfer_len); + } + break; case DFU_REQUEST_DNLOAD: { @@ -262,7 +284,6 @@ bool dfu_moded_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_reque } } // fallthrough - case DFU_REQUEST_UPLOAD: case DFU_REQUEST_GETSTATUS: case DFU_REQUEST_CLRSTATUS: case DFU_REQUEST_GETSTATE: @@ -290,18 +311,6 @@ bool dfu_moded_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_reque return true; } -static uint16_t dfu_req_upload(uint8_t rhport, tusb_control_request_t const * request, uint16_t block_num, uint16_t wLength) -{ - TU_VERIFY( wLength <= CFG_TUD_DFU_TRANSFER_BUFFER_SIZE, 0); - uint16_t retval = 0; - if (tud_dfu_upload_cb) - { - tud_dfu_upload_cb(_dfu_ctx.alt_num, block_num, (uint8_t *)_dfu_ctx.transfer_buf, wLength); - } - tud_control_xfer(rhport, request, _dfu_ctx.transfer_buf, retval); - return retval; -} - static void dfu_req_getstatus_reply(uint8_t rhport, tusb_control_request_t const * request) { uint32_t timeout = 0; @@ -382,18 +391,6 @@ static bool dfu_state_machine(uint8_t rhport, tusb_control_request_t const * req } break; - case DFU_REQUEST_UPLOAD: - { - if( ((_dfu_ctx.attrs & DFU_FUNC_ATTR_CAN_UPLOAD_BITMASK) != 0) ) - { - _dfu_ctx.state = DFU_UPLOAD_IDLE; - dfu_req_upload(rhport, request, request->wValue, request->wLength); - } else { - _dfu_ctx.state = DFU_ERROR; - } - } - break; - case DFU_REQUEST_GETSTATUS: dfu_req_getstatus_reply(rhport, request); break; @@ -567,15 +564,6 @@ static bool dfu_state_machine(uint8_t rhport, tusb_control_request_t const * req { switch (request->bRequest) { - case DFU_REQUEST_UPLOAD: - { - if (dfu_req_upload(rhport, request, request->wValue, request->wLength) != request->wLength) - { - _dfu_ctx.state = DFU_IDLE; - } - } - break; - case DFU_REQUEST_GETSTATUS: dfu_req_getstatus_reply(rhport, request); break; diff --git a/src/common/tusb_types.h b/src/common/tusb_types.h index ec58a3181..fc1035e2c 100644 --- a/src/common/tusb_types.h +++ b/src/common/tusb_types.h @@ -449,7 +449,7 @@ typedef struct TU_ATTR_PACKED /*------------------------------------------------------------------*/ /* Types *------------------------------------------------------------------*/ -typedef struct TU_ATTR_PACKED{ +typedef struct TU_ATTR_PACKED TU_ATTR_ALIGNED(4) { union { struct TU_ATTR_PACKED { uint8_t recipient : 5; ///< Recipient type tusb_request_recipient_t. -- cgit v1.3.1 From 6a68fc699724fb216b745dbf48fdae32305f1d35 Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 14 Jul 2021 16:51:28 +0700 Subject: update dfu abort --- src/class/dfu/dfu_device.c | 39 +++++++++++++-------------------------- 1 file changed, 13 insertions(+), 26 deletions(-) (limited to 'src/class') diff --git a/src/class/dfu/dfu_device.c b/src/class/dfu/dfu_device.c index 376feb053..ed36178f1 100644 --- a/src/class/dfu/dfu_device.c +++ b/src/class/dfu/dfu_device.c @@ -259,6 +259,19 @@ bool dfu_moded_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_reque } break; + case DFU_REQUEST_ABORT: + if ( stage == CONTROL_STAGE_SETUP ) + { + if (tud_dfu_abort_cb) tud_dfu_abort_cb(_dfu_ctx.alt_num); + + _dfu_ctx.state = DFU_IDLE; + _dfu_ctx.status = DFU_STATUS_OK; + _dfu_ctx.blk_transfer_in_proc = false; + + tud_control_status(rhport, request); + } + break; + case DFU_REQUEST_UPLOAD: if ( stage == CONTROL_STAGE_SETUP ) { @@ -287,7 +300,6 @@ bool dfu_moded_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_reque case DFU_REQUEST_GETSTATUS: case DFU_REQUEST_CLRSTATUS: case DFU_REQUEST_GETSTATE: - case DFU_REQUEST_ABORT: { if(stage == CONTROL_STAGE_SETUP) { @@ -297,10 +309,7 @@ bool dfu_moded_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_reque break; default: - { - TU_LOG2(" DFU Nonstandard Request: %u\r\n", request->bRequest); return false; // stall unsupported request - } break; } }else @@ -399,10 +408,6 @@ static bool dfu_state_machine(uint8_t rhport, tusb_control_request_t const * req dfu_req_getstate_reply(rhport, request); break; - case DFU_REQUEST_ABORT: - ; // do nothing, but don't stall so continue on - break; - default: _dfu_ctx.state = DFU_ERROR; return false; // stall on all other requests @@ -486,14 +491,6 @@ static bool dfu_state_machine(uint8_t rhport, tusb_control_request_t const * req dfu_req_getstate_reply(rhport, request); break; - case DFU_REQUEST_ABORT: - if ( tud_dfu_abort_cb ) - { - tud_dfu_abort_cb(_dfu_ctx.alt_num); - } - _dfu_ctx.state = DFU_IDLE; - break; - default: _dfu_ctx.state = DFU_ERROR; return false; // stall on all other requests @@ -572,16 +569,6 @@ static bool dfu_state_machine(uint8_t rhport, tusb_control_request_t const * req dfu_req_getstate_reply(rhport, request); break; - case DFU_REQUEST_ABORT: - { - if (tud_dfu_abort_cb) - { - tud_dfu_abort_cb(_dfu_ctx.alt_num); - } - _dfu_ctx.state = DFU_IDLE; - } - break; - default: return false; // stall on all other requests break; -- cgit v1.3.1 From b4fde90b5518c4e92750af2e27eae598267ad8cf Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 14 Jul 2021 17:03:20 +0700 Subject: update clear status and get state --- src/class/dfu/dfu_device.c | 66 +++++++++++++++++----------------------------- 1 file changed, 24 insertions(+), 42 deletions(-) (limited to 'src/class') diff --git a/src/class/dfu/dfu_device.c b/src/class/dfu/dfu_device.c index ed36178f1..686d9b023 100644 --- a/src/class/dfu/dfu_device.c +++ b/src/class/dfu/dfu_device.c @@ -61,6 +61,13 @@ static void dfu_req_getstatus_reply(uint8_t rhport, tusb_control_request_t c static void dfu_req_dnload_reply(uint8_t rhport, tusb_control_request_t const * request); static bool dfu_state_machine(uint8_t rhport, tusb_control_request_t const * request); +static void reset_state(void) +{ + _dfu_ctx.state = DFU_IDLE; + _dfu_ctx.status = DFU_STATUS_OK; + _dfu_ctx.blk_transfer_in_proc = false; +} + //--------------------------------------------------------------------+ // Debug //--------------------------------------------------------------------+ @@ -224,10 +231,7 @@ bool dfu_moded_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_reque { // Switch Alt interface and Re-initalize state machine _dfu_ctx.alt_num = (uint8_t) request->wValue; - _dfu_ctx.state = DFU_IDLE; - _dfu_ctx.status = DFU_STATUS_OK; - _dfu_ctx.blk_transfer_in_proc = false; - + reset_state(); return tud_control_status(rhport, request); } break; @@ -264,14 +268,26 @@ bool dfu_moded_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_reque { if (tud_dfu_abort_cb) tud_dfu_abort_cb(_dfu_ctx.alt_num); - _dfu_ctx.state = DFU_IDLE; - _dfu_ctx.status = DFU_STATUS_OK; - _dfu_ctx.blk_transfer_in_proc = false; + reset_state(); + tud_control_status(rhport, request); + } + break; + case DFU_REQUEST_CLRSTATUS: + if ( stage == CONTROL_STAGE_SETUP ) + { + reset_state(); tud_control_status(rhport, request); } break; + case DFU_REQUEST_GETSTATE: + if ( stage == CONTROL_STAGE_SETUP ) + { + tud_control_xfer(rhport, request, &_dfu_ctx.state, 1); + } + break; + case DFU_REQUEST_UPLOAD: if ( stage == CONTROL_STAGE_SETUP ) { @@ -298,8 +314,7 @@ bool dfu_moded_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_reque } // fallthrough case DFU_REQUEST_GETSTATUS: - case DFU_REQUEST_CLRSTATUS: - case DFU_REQUEST_GETSTATE: + { if(stage == CONTROL_STAGE_SETUP) { @@ -339,11 +354,6 @@ static void dfu_req_getstatus_reply(uint8_t rhport, tusb_control_request_t const tud_control_xfer(rhport, request, &resp, sizeof(dfu_status_req_payload_t)); } -static void dfu_req_getstate_reply(uint8_t rhport, tusb_control_request_t const * request) -{ - tud_control_xfer(rhport, request, &_dfu_ctx.state, 1); -} - static void dfu_req_dnload_setup(uint8_t rhport, tusb_control_request_t const * request) { // TODO: add "zero" copy mode so the buffer we read into can be provided by the user @@ -404,10 +414,6 @@ static bool dfu_state_machine(uint8_t rhport, tusb_control_request_t const * req dfu_req_getstatus_reply(rhport, request); break; - case DFU_REQUEST_GETSTATE: - dfu_req_getstate_reply(rhport, request); - break; - default: _dfu_ctx.state = DFU_ERROR; return false; // stall on all other requests @@ -434,10 +440,6 @@ static bool dfu_state_machine(uint8_t rhport, tusb_control_request_t const * req } break; - case DFU_REQUEST_GETSTATE: - dfu_req_getstate_reply(rhport, request); - break; - default: _dfu_ctx.state = DFU_ERROR; return false; // stall on all other requests @@ -487,10 +489,6 @@ static bool dfu_state_machine(uint8_t rhport, tusb_control_request_t const * req dfu_req_getstatus_reply(rhport, request); break; - case DFU_REQUEST_GETSTATE: - dfu_req_getstate_reply(rhport, request); - break; - default: _dfu_ctx.state = DFU_ERROR; return false; // stall on all other requests @@ -520,10 +518,6 @@ static bool dfu_state_machine(uint8_t rhport, tusb_control_request_t const * req } break; - case DFU_REQUEST_GETSTATE: - dfu_req_getstate_reply(rhport, request); - break; - default: _dfu_ctx.state = DFU_ERROR; return false; // stall on all other requests @@ -565,10 +559,6 @@ static bool dfu_state_machine(uint8_t rhport, tusb_control_request_t const * req dfu_req_getstatus_reply(rhport, request); break; - case DFU_REQUEST_GETSTATE: - dfu_req_getstate_reply(rhport, request); - break; - default: return false; // stall on all other requests break; @@ -584,14 +574,6 @@ static bool dfu_state_machine(uint8_t rhport, tusb_control_request_t const * req dfu_req_getstatus_reply(rhport, request); break; - case DFU_REQUEST_CLRSTATUS: - _dfu_ctx.state = DFU_IDLE; - break; - - case DFU_REQUEST_GETSTATE: - dfu_req_getstate_reply(rhport, request); - break; - default: return false; // stall on all other requests break; -- cgit v1.3.1 From daca9e520bce0b4eb5882c5692986ec5c513f319 Mon Sep 17 00:00:00 2001 From: hathach Date: Thu, 15 Jul 2021 20:47:50 +0700 Subject: wrap up DFU update --- examples/device/dfu/src/main.c | 95 +++++--- examples/device/dfu/src/tusb_config.h | 2 +- examples/device/dfu/src/usb_descriptors.c | 4 +- src/class/dfu/dfu.h | 47 ++-- src/class/dfu/dfu_device.c | 393 +++++++++++++++++++----------- src/class/dfu/dfu_device.h | 68 +++--- src/class/dfu/dfu_rt_device.c | 6 +- src/common/tusb_types.h | 2 +- src/device/usbd.c | 2 +- src/tusb_option.h | 4 - 10 files changed, 368 insertions(+), 255 deletions(-) (limited to 'src/class') diff --git a/examples/device/dfu/src/main.c b/examples/device/dfu/src/main.c index 2c114c5a2..1621a330b 100644 --- a/examples/device/dfu/src/main.c +++ b/examples/device/dfu/src/main.c @@ -26,7 +26,7 @@ /* * After device is enumerated in dfu mode run the following commands * - * To transfer firmware from host to device: + * To transfer firmware from host to device (best to test with text file) * * $ dfu-util -d cafe -a 0 -D [filename] * $ dfu-util -d cafe -a 1 -D [filename] @@ -45,22 +45,21 @@ #include "bsp/board.h" #include "tusb.h" - //--------------------------------------------------------------------+ // MACRO CONSTANT TYPEDEF PROTYPES //--------------------------------------------------------------------+ -#ifndef DFU_VERBOSE -#define DFU_VERBOSE 0 -#endif +const char* upload_image[2]= +{ + "Hello world from TinyUSB DFU! - Partition 0", + "Hello world from TinyUSB DFU! - Partition 1" +}; /* Blink pattern - * - 1000 ms : device should reboot * - 250 ms : device not mounted * - 1000 ms : device mounted * - 2500 ms : device is suspended */ enum { - BLINK_DFU_MODE = 100, BLINK_NOT_MOUNTED = 250, BLINK_MOUNTED = 1000, BLINK_SUSPENDED = 2500, @@ -118,65 +117,87 @@ void tud_resume_cb(void) } //--------------------------------------------------------------------+ -// Class callbacks +// DFU callbacks +// Note: alt is used as the partition number, in order to support multiple partitions like FLASH, EEPROM, etc. //--------------------------------------------------------------------+ -bool tud_dfu_firmware_valid_check_cb(uint8_t alt) -{ - (void) alt; - printf(" Firmware check\r\n"); - return true; -} -uint32_t tud_dfu_get_status_cb(uint8_t alt, uint8_t state) +// Invoked right before tud_dfu_download_cb() (state=DFU_DNBUSY) or tud_dfu_manifest_cb() (state=DFU_MANIFEST) +// Application return timeout in milliseconds (bwPollTimeout) for the next download/manifest operation. +// During this period, USB host won't try to communicate with us. +uint32_t tud_dfu_get_timeout_cb(uint8_t alt, uint8_t state) { - // For example Alt1 (EEPROM) is slow, add 2000ms timeout if ( state == DFU_DNBUSY ) { - if (alt == 1) return 2000; + // For this example + // - Atl0 Flash is fast : 1 ms + // - Alt1 EEPROM is slow: 100 ms + return (alt == 0) ? 1 : 100; } + else if (state == DFU_MANIFEST) + { + // since we don't buffer entire image and do any flashing in manifest stage + return 0; + } + return 0; } -void tud_dfu_download_cb(uint8_t alt, uint16_t wBlockNum, uint8_t* data, uint16_t length) +// Invoked when received DFU_DNLOAD (wLength>0) following by DFU_GETSTATUS (state=DFU_DNBUSY) requests +// This callback could be returned before flashing op is complete (async). +// Once finished flashing, application must call tud_dfu_finish_flashing() +void tud_dfu_download_cb(uint8_t alt, uint16_t wBlockNum, uint8_t const* data, uint16_t length) { (void) data; - printf("Received Alt %u BlockNum %u of length %u\r\n", alt, wBlockNum, length); + printf("\r\nReceived Alt %u BlockNum %u of length %u\r\n", alt, wBlockNum, length); -#if DFU_VERBOSE for(uint16_t i=0; ibAttributes; - // CFG_TUD_DFU_TRANSFER_BUFFER_SIZE has to be set to the buffer size used in TUD_DFU_DESCRIPTOR + // CFG_TUD_DFU_TRANSFER_BUFSIZE has to be set to the buffer size used in TUD_DFU_DESCRIPTOR uint16_t const transfer_size = tu_le16toh( tu_unaligned_read16(&func_desc->wTransferSize) ); - TU_ASSERT(transfer_size <= CFG_TUD_DFU_TRANSFER_BUFFER_SIZE, drv_len); + TU_ASSERT(transfer_size <= CFG_TUD_DFU_TRANSFER_BUFSIZE, drv_len); return drv_len; } @@ -216,11 +201,10 @@ uint16_t dfu_moded_open(uint8_t rhport, tusb_desc_interface_t const * itf_desc, // return false to stall control endpoint (e.g unsupported request) bool dfu_moded_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t const * request) { - // nothing to do with DATA stage - if ( stage == CONTROL_STAGE_DATA ) return true; - TU_VERIFY(request->bmRequestType_bit.recipient == TUSB_REQ_RCPT_INTERFACE); + TU_LOG2(" DFU State : %s, Status: %s\r\n", tu_lookup_find(&_dfu_state_table, _dfu_ctx.state), tu_lookup_find(&_dfu_status_table, _dfu_ctx.status)); + if ( request->bmRequestType_bit.type == TUSB_REQ_TYPE_STANDARD ) { // Standard request include GET/SET_INTERFACE @@ -229,8 +213,8 @@ bool dfu_moded_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_reque case TUSB_REQ_SET_INTERFACE: if ( stage == CONTROL_STAGE_SETUP ) { - // Switch Alt interface and Re-initalize state machine - _dfu_ctx.alt_num = (uint8_t) request->wValue; + // Switch Alt interface and reset state machine + _dfu_ctx.alt = (uint8_t) request->wValue; reset_state(); return tud_control_status(rhport, request); } @@ -239,7 +223,7 @@ bool dfu_moded_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_reque case TUSB_REQ_GET_INTERFACE: if(stage == CONTROL_STAGE_SETUP) { - return tud_control_xfer(rhport, request, &_dfu_ctx.alt_num, 1); + return tud_control_xfer(rhport, request, &_dfu_ctx.alt, 1); } break; @@ -249,6 +233,8 @@ bool dfu_moded_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_reque } else if ( request->bmRequestType_bit.type == TUSB_REQ_TYPE_CLASS ) { + TU_LOG2(" DFU Request: %s\r\n", tu_lookup_find(&_dfu_request_table, request->bRequest)); + // Class request switch ( request->bRequest ) { @@ -259,73 +245,97 @@ bool dfu_moded_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_reque } else if ( stage == CONTROL_STAGE_ACK ) { - if (tud_dfu_detach_cb) tud_dfu_detach_cb(); + if ( tud_dfu_detach_cb ) tud_dfu_detach_cb(); } break; - case DFU_REQUEST_ABORT: + case DFU_REQUEST_CLRSTATUS: if ( stage == CONTROL_STAGE_SETUP ) { - if (tud_dfu_abort_cb) tud_dfu_abort_cb(_dfu_ctx.alt_num); - reset_state(); tud_control_status(rhport, request); } break; - case DFU_REQUEST_CLRSTATUS: + case DFU_REQUEST_GETSTATE: if ( stage == CONTROL_STAGE_SETUP ) { - reset_state(); - tud_control_status(rhport, request); + tud_control_xfer(rhport, request, &_dfu_ctx.state, 1); } break; - case DFU_REQUEST_GETSTATE: + case DFU_REQUEST_ABORT: if ( stage == CONTROL_STAGE_SETUP ) { - tud_control_xfer(rhport, request, &_dfu_ctx.state, 1); + reset_state(); + tud_control_status(rhport, request); + } + else if ( stage == CONTROL_STAGE_ACK ) + { + if ( tud_dfu_abort_cb ) tud_dfu_abort_cb(_dfu_ctx.alt); } break; case DFU_REQUEST_UPLOAD: if ( stage == CONTROL_STAGE_SETUP ) { - TU_VERIFY(_dfu_ctx.attrs & DFU_FUNC_ATTR_CAN_UPLOAD_BITMASK); + TU_VERIFY(_dfu_ctx.attrs & DFU_ATTR_CAN_UPLOAD); TU_VERIFY(tud_dfu_upload_cb); - TU_VERIFY(request->wLength <= CFG_TUD_DFU_TRANSFER_BUFFER_SIZE); + TU_VERIFY(request->wLength <= CFG_TUD_DFU_TRANSFER_BUFSIZE); - uint16_t const xfer_len = tud_dfu_upload_cb(_dfu_ctx.alt_num, request->wValue, _dfu_ctx.transfer_buf, request->wLength); + uint16_t const xfer_len = tud_dfu_upload_cb(_dfu_ctx.alt, request->wValue, _dfu_ctx.transfer_buf, request->wLength); - tud_control_xfer(rhport, request, _dfu_ctx.transfer_buf, xfer_len); + return tud_control_xfer(rhport, request, _dfu_ctx.transfer_buf, xfer_len); } break; case DFU_REQUEST_DNLOAD: - { - if ( (stage == CONTROL_STAGE_ACK) - && ((_dfu_ctx.attrs & DFU_FUNC_ATTR_CAN_DOWNLOAD_BITMASK) != 0) - && (_dfu_ctx.state == DFU_DNLOAD_SYNC)) + if ( stage == CONTROL_STAGE_SETUP ) { - _dfu_ctx.block = request->wValue; + TU_VERIFY(_dfu_ctx.attrs & DFU_ATTR_CAN_DOWNLOAD); + TU_VERIFY(_dfu_ctx.state == DFU_IDLE || _dfu_ctx.state == DFU_DNLOAD_IDLE); + TU_VERIFY(request->wLength <= CFG_TUD_DFU_TRANSFER_BUFSIZE); + + // set to true for both download and manifest + _dfu_ctx.flashing_in_progress = true; + + // save block and length for flashing + _dfu_ctx.block = request->wValue; _dfu_ctx.length = request->wLength; - return true; + + if ( request->wLength ) + { + // Download with payload -> transition to DOWNLOAD SYNC + _dfu_ctx.state = DFU_DNLOAD_SYNC; + return tud_control_xfer(rhport, request, _dfu_ctx.transfer_buf, request->wLength); + } + else + { + // Download is complete -> transition to MANIFEST SYNC + _dfu_ctx.state = DFU_MANIFEST_SYNC; + return tud_control_status(rhport, request); + } } - } - // fallthrough - case DFU_REQUEST_GETSTATUS: + break; - { - if(stage == CONTROL_STAGE_SETUP) + case DFU_REQUEST_GETSTATUS: + switch ( _dfu_ctx.state ) { - return dfu_state_machine(rhport, request); + case DFU_DNLOAD_SYNC: + return process_download_get_status(rhport, stage, request); + break; + + case DFU_MANIFEST_SYNC: + return process_manifest_get_status(rhport, stage, request); + break; + + default: + if ( stage == CONTROL_STAGE_SETUP ) return reply_getstatus(rhport, request, _dfu_ctx.state, _dfu_ctx.status, 0); + break; } - } break; - default: - return false; // stall unsupported request - break; + default: return false; // stall unsupported request } }else { @@ -335,32 +345,130 @@ bool dfu_moded_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_reque return true; } -static void dfu_req_getstatus_reply(uint8_t rhport, tusb_control_request_t const * request) +void tud_dfu_finish_flashing(uint8_t status) +{ + _dfu_ctx.flashing_in_progress = false; + + if ( status == DFU_STATUS_OK ) + { + if (_dfu_ctx.state == DFU_DNBUSY) + { + _dfu_ctx.state = DFU_DNLOAD_SYNC; + } + else if (_dfu_ctx.state == DFU_MANIFEST) + { + _dfu_ctx.state = (_dfu_ctx.attrs & DFU_ATTR_MANIFESTATION_TOLERANT) + ? DFU_MANIFEST_SYNC : DFU_MANIFEST_WAIT_RESET; + } + } + else + { + // failed while flashing, move to dfuError + _dfu_ctx.state = DFU_ERROR; + _dfu_ctx.status = status; + } +} + +static bool process_download_get_status(uint8_t rhport, uint8_t stage, tusb_control_request_t const * request) +{ + if ( stage == CONTROL_STAGE_SETUP ) + { + // only transition to next state on CONTROL_STAGE_ACK + dfu_state_t next_state; + uint32_t timeout; + + if ( _dfu_ctx.flashing_in_progress ) + { + next_state = DFU_DNBUSY; + timeout = tud_dfu_get_timeout_cb(_dfu_ctx.alt, (uint8_t) next_state); + } + else + { + next_state = DFU_DNLOAD_IDLE; + timeout = 0; + } + + return reply_getstatus(rhport, request, next_state, _dfu_ctx.status, timeout); + } + else if ( stage == CONTROL_STAGE_ACK ) + { + if ( _dfu_ctx.flashing_in_progress ) + { + _dfu_ctx.state = DFU_DNBUSY; + tud_dfu_download_cb(_dfu_ctx.alt, _dfu_ctx.block, _dfu_ctx.transfer_buf, _dfu_ctx.length); + }else + { + _dfu_ctx.state = DFU_DNLOAD_IDLE; + } + } + + return true; +} + +static bool process_manifest_get_status(uint8_t rhport, uint8_t stage, tusb_control_request_t const * request) { - uint32_t timeout = 0; - if ( tud_dfu_get_status_cb ) + if ( stage == CONTROL_STAGE_SETUP ) { - timeout = tud_dfu_get_status_cb(_dfu_ctx.alt_num, _dfu_ctx.state); + // only transition to next state on CONTROL_STAGE_ACK + dfu_state_t next_state; + uint32_t timeout; + + if ( _dfu_ctx.flashing_in_progress ) + { + next_state = DFU_MANIFEST; + timeout = tud_dfu_get_timeout_cb(_dfu_ctx.alt, next_state); + } + else + { + next_state = DFU_IDLE; + timeout = 0; + } + + return reply_getstatus(rhport, request, next_state, _dfu_ctx.status, timeout); + } + else if ( stage == CONTROL_STAGE_ACK ) + { + if ( _dfu_ctx.flashing_in_progress ) + { + _dfu_ctx.state = DFU_MANIFEST; + tud_dfu_manifest_cb(_dfu_ctx.alt); + } + else + { + _dfu_ctx.state = DFU_IDLE; + } } - dfu_status_req_payload_t resp; - resp.bStatus = _dfu_ctx.status; + return true; +} + +static bool reply_getstatus(uint8_t rhport, tusb_control_request_t const * request, dfu_state_t state, dfu_status_t status, uint32_t timeout) +{ + dfu_status_response_t resp; + resp.bStatus = (uint8_t) status; resp.bwPollTimeout[0] = TU_U32_BYTE0(timeout); resp.bwPollTimeout[1] = TU_U32_BYTE1(timeout); resp.bwPollTimeout[2] = TU_U32_BYTE2(timeout); - resp.bState = _dfu_ctx.state; - resp.iString = 0; + resp.bState = (uint8_t) state; + resp.iString = 0; - tud_control_xfer(rhport, request, &resp, sizeof(dfu_status_req_payload_t)); + return tud_control_xfer(rhport, request, &resp, sizeof(dfu_status_response_t)); } + +#if 0 + +static void dfu_req_dnload_setup(uint8_t rhport, tusb_control_request_t const * request); +static void dfu_req_dnload_reply(uint8_t rhport, tusb_control_request_t const * request); +static bool dfu_state_machine(uint8_t rhport, tusb_control_request_t const * request); + static void dfu_req_dnload_setup(uint8_t rhport, tusb_control_request_t const * request) { // TODO: add "zero" copy mode so the buffer we read into can be provided by the user // if they wish, there still will be the internal control buffer copy to this buffer // but this mode would provide zero copy from the class driver to the application - TU_VERIFY( request->wLength <= CFG_TUD_DFU_TRANSFER_BUFFER_SIZE, ); + TU_VERIFY( request->wLength <= CFG_TUD_DFU_TRANSFER_BUFSIZE, ); // setup for data phase tud_control_xfer(rhport, request, _dfu_ctx.transfer_buf, request->wLength); } @@ -368,21 +476,9 @@ static void dfu_req_dnload_setup(uint8_t rhport, tusb_control_request_t const * static void dfu_req_dnload_reply(uint8_t rhport, tusb_control_request_t const * request) { (void) rhport; - TU_VERIFY( request->wLength <= CFG_TUD_DFU_TRANSFER_BUFFER_SIZE, ); - tud_dfu_download_cb(_dfu_ctx.alt_num,_dfu_ctx.block, (uint8_t *)_dfu_ctx.transfer_buf, _dfu_ctx.length); - _dfu_ctx.blk_transfer_in_proc = false; -} - -void tud_dfu_download_complete(void) -{ - if (_dfu_ctx.state == DFU_DNBUSY) - { - _dfu_ctx.state = DFU_DNLOAD_SYNC; - } else if (_dfu_ctx.state == DFU_MANIFEST) - { - _dfu_ctx.state = ((_dfu_ctx.attrs & DFU_FUNC_ATTR_MANIFESTATION_TOLERANT_BITMASK) == 0) - ? DFU_MANIFEST_WAIT_RESET : DFU_MANIFEST_SYNC; - } + TU_VERIFY( request->wLength <= CFG_TUD_DFU_TRANSFER_BUFSIZE, ); + tud_dfu_download_cb(_dfu_ctx.alt,_dfu_ctx.block, (uint8_t *)_dfu_ctx.transfer_buf, _dfu_ctx.length); + _dfu_ctx.flashing_in_progress = false; } static bool dfu_state_machine(uint8_t rhport, tusb_control_request_t const * request) @@ -398,11 +494,11 @@ static bool dfu_state_machine(uint8_t rhport, tusb_control_request_t const * req { case DFU_REQUEST_DNLOAD: { - if( ((_dfu_ctx.attrs & DFU_FUNC_ATTR_CAN_DOWNLOAD_BITMASK) != 0) + if( ((_dfu_ctx.attrs & DFU_ATTR_CAN_DOWNLOAD) != 0) && (request->wLength > 0) ) { _dfu_ctx.state = DFU_DNLOAD_SYNC; - _dfu_ctx.blk_transfer_in_proc = true; + _dfu_ctx.flashing_in_progress = true; dfu_req_dnload_setup(rhport, request); } else { _dfu_ctx.state = DFU_ERROR; @@ -411,7 +507,7 @@ static bool dfu_state_machine(uint8_t rhport, tusb_control_request_t const * req break; case DFU_REQUEST_GETSTATUS: - dfu_req_getstatus_reply(rhport, request); + reply_getstatus(rhport, request); break; default: @@ -428,14 +524,14 @@ static bool dfu_state_machine(uint8_t rhport, tusb_control_request_t const * req { case DFU_REQUEST_GETSTATUS: { - if ( _dfu_ctx.blk_transfer_in_proc ) + if ( _dfu_ctx.flashing_in_progress ) { _dfu_ctx.state = DFU_DNBUSY; - dfu_req_getstatus_reply(rhport, request); + reply_getstatus(rhport, request); dfu_req_dnload_reply(rhport, request); } else { _dfu_ctx.state = DFU_DNLOAD_IDLE; - dfu_req_getstatus_reply(rhport, request); + reply_getstatus(rhport, request); } } break; @@ -466,14 +562,14 @@ static bool dfu_state_machine(uint8_t rhport, tusb_control_request_t const * req { case DFU_REQUEST_DNLOAD: { - if( ((_dfu_ctx.attrs & DFU_FUNC_ATTR_CAN_DOWNLOAD_BITMASK) != 0) + if( ((_dfu_ctx.attrs & DFU_ATTR_CAN_DOWNLOAD) != 0) && (request->wLength > 0) ) { _dfu_ctx.state = DFU_DNLOAD_SYNC; - _dfu_ctx.blk_transfer_in_proc = true; + _dfu_ctx.flashing_in_progress = true; dfu_req_dnload_setup(rhport, request); } else { - if ( tud_dfu_device_data_done_check_cb(_dfu_ctx.alt_num) ) + if ( tud_dfu_download_complete_cb(_dfu_ctx.alt) ) { _dfu_ctx.state = DFU_MANIFEST_SYNC; tud_control_status(rhport, request); @@ -486,7 +582,7 @@ static bool dfu_state_machine(uint8_t rhport, tusb_control_request_t const * req break; case DFU_REQUEST_GETSTATUS: - dfu_req_getstatus_reply(rhport, request); + reply_getstatus(rhport, request); break; default: @@ -503,17 +599,17 @@ static bool dfu_state_machine(uint8_t rhport, tusb_control_request_t const * req { case DFU_REQUEST_GETSTATUS: { - if ((_dfu_ctx.attrs & DFU_FUNC_ATTR_MANIFESTATION_TOLERANT_BITMASK) == 0) + if ((_dfu_ctx.attrs & DFU_ATTR_MANIFESTATION_TOLERANT) == 0) { _dfu_ctx.state = DFU_MANIFEST; - dfu_req_getstatus_reply(rhport, request); + reply_getstatus(rhport, request); } else { - if ( tud_dfu_firmware_valid_check_cb(_dfu_ctx.alt_num) ) + if ( tud_dfu_manifest_cb(_dfu_ctx.alt) ) { _dfu_ctx.state = DFU_IDLE; } - dfu_req_getstatus_reply(rhport, request); + reply_getstatus(rhport, request); } } break; @@ -556,7 +652,7 @@ static bool dfu_state_machine(uint8_t rhport, tusb_control_request_t const * req switch (request->bRequest) { case DFU_REQUEST_GETSTATUS: - dfu_req_getstatus_reply(rhport, request); + reply_getstatus(rhport, request); break; default: @@ -571,7 +667,7 @@ static bool dfu_state_machine(uint8_t rhport, tusb_control_request_t const * req switch (request->bRequest) { case DFU_REQUEST_GETSTATUS: - dfu_req_getstatus_reply(rhport, request); + reply_getstatus(rhport, request); break; default: @@ -590,5 +686,6 @@ static bool dfu_state_machine(uint8_t rhport, tusb_control_request_t const * req return true; } +#endif #endif diff --git a/src/class/dfu/dfu_device.h b/src/class/dfu/dfu_device.h index d5d464f3b..2d398aada 100644 --- a/src/class/dfu/dfu_device.h +++ b/src/class/dfu/dfu_device.h @@ -37,53 +37,51 @@ // Class Driver Default Configure & Validation //--------------------------------------------------------------------+ -#if !defined(CFG_TUD_DFU_TRANSFER_BUFFER_SIZE) - #error "CFG_TUD_DFU_TRANSFER_BUFFER_SIZE must be defined, it has to be set to the buffer size used in TUD_DFU_DESCRIPTOR" +#if !defined(CFG_TUD_DFU_TRANSFER_BUFSIZE) + #error "CFG_TUD_DFU_TRANSFER_BUFSIZE must be defined, it has to be set to the buffer size used in TUD_DFU_DESCRIPTOR" #endif +//--------------------------------------------------------------------+ +// Application API +//--------------------------------------------------------------------+ + +// Must be called when the application is done with flashing started by +// tud_dfu_download_cb() and tud_dfu_manifest_cb(). +// status is DFU_STATUS_OK if successful, any other error status will cause state to enter dfuError +void tud_dfu_finish_flashing(uint8_t status); + //--------------------------------------------------------------------+ // Application Callback API (weak is optional) //--------------------------------------------------------------------+ -// Invoked during DFU_MANIFEST_SYNC get status request to check if firmware is valid -// alt is used as the partition number, in order to support multiple partitions like FLASH, EEPROM, etc. -bool tud_dfu_firmware_valid_check_cb(uint8_t alt); - -// Invoked when a DFU_GETSTATUS request is received -// Return the bwPollTimeout value for host's response, useful for slow Flash in order to make host wait longer -// alt is used as the partition number, in order to support multiple partitions like FLASH, EEPROM, etc. -TU_ATTR_WEAK uint32_t tud_dfu_get_status_cb(uint8_t alt, uint8_t state); - -// Invoked when a DFU_DNLOAD request is received -// alt is used as the partition number, in order to support multiple partitions like FLASH, EEPROM, etc. -// This callback takes the wBlockNum chunk of length length and provides it -// to the application at the data pointer. This data is only valid for this -// call, so the app must use it not or copy it. -void tud_dfu_download_cb(uint8_t alt, uint16_t wBlockNum, uint8_t* data, uint16_t length); - -// Must be called when the application is done using the last block of data -// provided by tud_dfu_download_cb -void tud_dfu_download_complete(void); - -// Invoked during the last DFU_DNLOAD request, signifying that the host believes -// it is done transmitting data. -// alt is used as the partition number, in order to support multiple partitions like FLASH, EEPROM, etc. -// Return true if the application agrees there is no more data -// Return false if the device disagrees, which will stall the pipe, and the Host -// should initiate a recovery procedure -bool tud_dfu_device_data_done_check_cb(uint8_t alt); -// Invoked when the Host has terminated a download or upload transfer -TU_ATTR_WEAK void tud_dfu_abort_cb(uint8_t alt); +// Note: alt is used as the partition number, in order to support multiple partitions like FLASH, EEPROM, etc. -// Invoked when a DFU_UPLOAD request is received -// alt is used as the partition number, in order to support multiple partitions like FLASH, EEPROM, etc. -// This callback must populate data with up to length bytes -// Return the number of bytes to write +// Invoked right before tud_dfu_download_cb() (state=DFU_DNBUSY) or tud_dfu_manifest_cb() (state=DFU_MANIFEST) +// Application return timeout in milliseconds (bwPollTimeout) for the next download/manifest operation. +// During this period, USB host won't try to communicate with us. +uint32_t tud_dfu_get_timeout_cb(uint8_t alt, uint8_t state); + +// Invoked when received DFU_DNLOAD (wLength>0) following by DFU_GETSTATUS (state=DFU_DNBUSY) requests +// This callback could be returned before flashing op is complete (async). +// Once finished flashing, application must call tud_dfu_finish_flashing() +void tud_dfu_download_cb (uint8_t alt, uint16_t block_num, uint8_t const *data, uint16_t length); + +// Invoked when download process is complete, received DFU_DNLOAD (wLength=0) following by DFU_GETSTATUS (state=Manifest) +// Application can do checksum, or actual flashing if buffered entire image previously. +// Once finished flashing, application must call tud_dfu_finish_flashing() +void tud_dfu_manifest_cb(uint8_t alt); + +// Invoked when received DFU_UPLOAD request +// Application must populate data with up to length bytes and +// Return the number of written bytes TU_ATTR_WEAK uint16_t tud_dfu_upload_cb(uint8_t alt, uint16_t block_num, uint8_t* data, uint16_t length); // Invoked when a DFU_DETACH request is received TU_ATTR_WEAK void tud_dfu_detach_cb(void); +// Invoked when the Host has terminated a download or upload transfer +TU_ATTR_WEAK void tud_dfu_abort_cb(uint8_t alt); + //--------------------------------------------------------------------+ // Internal Class Driver API //--------------------------------------------------------------------+ diff --git a/src/class/dfu/dfu_rt_device.c b/src/class/dfu/dfu_rt_device.c index 07e6f30f3..afee2aa1f 100644 --- a/src/class/dfu/dfu_rt_device.c +++ b/src/class/dfu/dfu_rt_device.c @@ -108,10 +108,10 @@ bool dfu_rtd_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request case DFU_REQUEST_GETSTATUS: { TU_LOG2(" DFU RT Request: GETSTATUS\r\n"); - dfu_status_req_payload_t resp; + dfu_status_response_t resp; // Status = OK, Poll timeout is ignored during RT, State = APP_IDLE, IString = 0 - memset(&resp, 0x00, sizeof(dfu_status_req_payload_t)); - tud_control_xfer(rhport, request, &resp, sizeof(dfu_status_req_payload_t)); + memset(&resp, 0x00, sizeof(dfu_status_response_t)); + tud_control_xfer(rhport, request, &resp, sizeof(dfu_status_response_t)); } break; diff --git a/src/common/tusb_types.h b/src/common/tusb_types.h index fc1035e2c..eab67ebd5 100644 --- a/src/common/tusb_types.h +++ b/src/common/tusb_types.h @@ -449,7 +449,7 @@ typedef struct TU_ATTR_PACKED /*------------------------------------------------------------------*/ /* Types *------------------------------------------------------------------*/ -typedef struct TU_ATTR_PACKED TU_ATTR_ALIGNED(4) { +typedef struct TU_ATTR_PACKED { union { struct TU_ATTR_PACKED { uint8_t recipient : 5; ///< Recipient type tusb_request_recipient_t. diff --git a/src/device/usbd.c b/src/device/usbd.c index af4fd58c4..cf9af783d 100644 --- a/src/device/usbd.c +++ b/src/device/usbd.c @@ -190,7 +190,7 @@ static usbd_class_driver_t const _usbd_driver[] = #if CFG_TUD_DFU_MODE { - DRIVER_NAME("DFU-MODE") + DRIVER_NAME("DFU") .init = dfu_moded_init, .reset = dfu_moded_reset, .open = dfu_moded_open, diff --git a/src/tusb_option.h b/src/tusb_option.h index bf7591dcf..4351d9486 100644 --- a/src/tusb_option.h +++ b/src/tusb_option.h @@ -253,10 +253,6 @@ #define CFG_TUD_DFU_MODE 0 #endif -#ifndef CFG_TUD_DFU_TRANSFER_BUFFER_SIZE - #define CFG_TUD_DFU_TRANSFER_BUFFER_SIZE 64 -#endif - #ifndef CFG_TUD_NET #define CFG_TUD_NET 0 #endif -- cgit v1.3.1 From 3960beece0ea3dccf7ca615bd7841daa6b703d56 Mon Sep 17 00:00:00 2001 From: hathach Date: Thu, 15 Jul 2021 20:52:58 +0700 Subject: rename CFG_TUD_DFU_MODE to simply CFG_TUD_DFU --- examples/device/dfu/src/main.c | 2 +- examples/device/dfu/src/tusb_config.h | 4 +--- src/class/dfu/dfu_device.c | 2 +- src/device/usbd.c | 2 +- src/tusb.h | 2 +- src/tusb_option.h | 4 ++-- 6 files changed, 7 insertions(+), 9 deletions(-) (limited to 'src/class') diff --git a/examples/device/dfu/src/main.c b/examples/device/dfu/src/main.c index 1621a330b..7133d1624 100644 --- a/examples/device/dfu/src/main.c +++ b/examples/device/dfu/src/main.c @@ -148,7 +148,7 @@ uint32_t tud_dfu_get_timeout_cb(uint8_t alt, uint8_t state) void tud_dfu_download_cb(uint8_t alt, uint16_t wBlockNum, uint8_t const* data, uint16_t length) { (void) data; - printf("\r\nReceived Alt %u BlockNum %u of length %u\r\n", alt, wBlockNum, length); + //printf("\r\nReceived Alt %u BlockNum %u of length %u\r\n", alt, wBlockNum, length); for(uint16_t i=0; i Date: Thu, 22 Jul 2021 01:00:06 +0700 Subject: rename CFG_TUD_DFU_TRANSFER_BUFSIZE to CFG_TUD_DFU_XFER_BUFSIZE --- examples/device/dfu/.skip.MCU_SAMD11 | 0 examples/device/dfu/src/tusb_config.h | 2 +- examples/device/dfu/src/usb_descriptors.c | 2 +- src/class/dfu/dfu_device.c | 243 +----------------------------- src/class/dfu/dfu_device.h | 4 +- 5 files changed, 9 insertions(+), 242 deletions(-) delete mode 100644 examples/device/dfu/.skip.MCU_SAMD11 (limited to 'src/class') diff --git a/examples/device/dfu/.skip.MCU_SAMD11 b/examples/device/dfu/.skip.MCU_SAMD11 deleted file mode 100644 index e69de29bb..000000000 diff --git a/examples/device/dfu/src/tusb_config.h b/examples/device/dfu/src/tusb_config.h index 2e3b89f49..66e357021 100644 --- a/examples/device/dfu/src/tusb_config.h +++ b/examples/device/dfu/src/tusb_config.h @@ -80,7 +80,7 @@ #define CFG_TUD_DFU 1 // DFU buffer size, it has to be set to the buffer size used in TUD_DFU_DESCRIPTOR -#define CFG_TUD_DFU_TRANSFER_BUFSIZE 512 +#define CFG_TUD_DFU_XFER_BUFSIZE 512 #ifdef __cplusplus } diff --git a/examples/device/dfu/src/usb_descriptors.c b/examples/device/dfu/src/usb_descriptors.c index a15bb6136..1cfe29c53 100644 --- a/examples/device/dfu/src/usb_descriptors.c +++ b/examples/device/dfu/src/usb_descriptors.c @@ -100,7 +100,7 @@ uint8_t const desc_configuration[] = TUD_CONFIG_DESCRIPTOR(1, ITF_NUM_TOTAL, 0, CONFIG_TOTAL_LEN, TUSB_DESC_CONFIG_ATT_REMOTE_WAKEUP, 100), // Interface number, Alternate count, starting string index, attributes, detach timeout, transfer size - TUD_DFU_DESCRIPTOR(ITF_NUM_DFU_MODE, ALT_COUNT, 4, FUNC_ATTRS, 1000, CFG_TUD_DFU_TRANSFER_BUFSIZE), + TUD_DFU_DESCRIPTOR(ITF_NUM_DFU_MODE, ALT_COUNT, 4, FUNC_ATTRS, 1000, CFG_TUD_DFU_XFER_BUFSIZE), }; // Invoked when received GET CONFIGURATION DESCRIPTOR diff --git a/src/class/dfu/dfu_device.c b/src/class/dfu/dfu_device.c index 222795bec..ad87092e0 100644 --- a/src/class/dfu/dfu_device.c +++ b/src/class/dfu/dfu_device.c @@ -52,7 +52,7 @@ typedef struct uint16_t block; uint16_t length; - CFG_TUSB_MEM_ALIGN uint8_t transfer_buf[CFG_TUD_DFU_TRANSFER_BUFSIZE]; + CFG_TUSB_MEM_ALIGN uint8_t transfer_buf[CFG_TUD_DFU_XFER_BUFSIZE]; } dfu_state_ctx_t; // Only a single dfu state is allowed @@ -189,9 +189,9 @@ uint16_t dfu_moded_open(uint8_t rhport, tusb_desc_interface_t const * itf_desc, _dfu_ctx.attrs = func_desc->bAttributes; - // CFG_TUD_DFU_TRANSFER_BUFSIZE has to be set to the buffer size used in TUD_DFU_DESCRIPTOR + // CFG_TUD_DFU_XFER_BUFSIZE has to be set to the buffer size used in TUD_DFU_DESCRIPTOR uint16_t const transfer_size = tu_le16toh( tu_unaligned_read16(&func_desc->wTransferSize) ); - TU_ASSERT(transfer_size <= CFG_TUD_DFU_TRANSFER_BUFSIZE, drv_len); + TU_ASSERT(transfer_size <= CFG_TUD_DFU_XFER_BUFSIZE, drv_len); return drv_len; } @@ -281,7 +281,7 @@ bool dfu_moded_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_reque { TU_VERIFY(_dfu_ctx.attrs & DFU_ATTR_CAN_UPLOAD); TU_VERIFY(tud_dfu_upload_cb); - TU_VERIFY(request->wLength <= CFG_TUD_DFU_TRANSFER_BUFSIZE); + TU_VERIFY(request->wLength <= CFG_TUD_DFU_XFER_BUFSIZE); uint16_t const xfer_len = tud_dfu_upload_cb(_dfu_ctx.alt, request->wValue, _dfu_ctx.transfer_buf, request->wLength); @@ -294,7 +294,7 @@ bool dfu_moded_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_reque { TU_VERIFY(_dfu_ctx.attrs & DFU_ATTR_CAN_DOWNLOAD); TU_VERIFY(_dfu_ctx.state == DFU_IDLE || _dfu_ctx.state == DFU_DNLOAD_IDLE); - TU_VERIFY(request->wLength <= CFG_TUD_DFU_TRANSFER_BUFSIZE); + TU_VERIFY(request->wLength <= CFG_TUD_DFU_XFER_BUFSIZE); // set to true for both download and manifest _dfu_ctx.flashing_in_progress = true; @@ -455,237 +455,4 @@ static bool reply_getstatus(uint8_t rhport, tusb_control_request_t const * reque return tud_control_xfer(rhport, request, &resp, sizeof(dfu_status_response_t)); } - -#if 0 - -static void dfu_req_dnload_setup(uint8_t rhport, tusb_control_request_t const * request); -static void dfu_req_dnload_reply(uint8_t rhport, tusb_control_request_t const * request); -static bool dfu_state_machine(uint8_t rhport, tusb_control_request_t const * request); - -static void dfu_req_dnload_setup(uint8_t rhport, tusb_control_request_t const * request) -{ - // TODO: add "zero" copy mode so the buffer we read into can be provided by the user - // if they wish, there still will be the internal control buffer copy to this buffer - // but this mode would provide zero copy from the class driver to the application - - TU_VERIFY( request->wLength <= CFG_TUD_DFU_TRANSFER_BUFSIZE, ); - // setup for data phase - tud_control_xfer(rhport, request, _dfu_ctx.transfer_buf, request->wLength); -} - -static void dfu_req_dnload_reply(uint8_t rhport, tusb_control_request_t const * request) -{ - (void) rhport; - TU_VERIFY( request->wLength <= CFG_TUD_DFU_TRANSFER_BUFSIZE, ); - tud_dfu_download_cb(_dfu_ctx.alt,_dfu_ctx.block, (uint8_t *)_dfu_ctx.transfer_buf, _dfu_ctx.length); - _dfu_ctx.flashing_in_progress = false; -} - -static bool dfu_state_machine(uint8_t rhport, tusb_control_request_t const * request) -{ - TU_LOG2(" DFU Request: %s\r\n", tu_lookup_find(&_dfu_request_table, request->bRequest)); - TU_LOG2(" DFU State Machine: %s\r\n", tu_lookup_find(&_dfu_state_table, _dfu_ctx.state)); - - switch (_dfu_ctx.state) - { - case DFU_IDLE: - { - switch (request->bRequest) - { - case DFU_REQUEST_DNLOAD: - { - if( ((_dfu_ctx.attrs & DFU_ATTR_CAN_DOWNLOAD) != 0) - && (request->wLength > 0) ) - { - _dfu_ctx.state = DFU_DNLOAD_SYNC; - _dfu_ctx.flashing_in_progress = true; - dfu_req_dnload_setup(rhport, request); - } else { - _dfu_ctx.state = DFU_ERROR; - } - } - break; - - case DFU_REQUEST_GETSTATUS: - reply_getstatus(rhport, request); - break; - - default: - _dfu_ctx.state = DFU_ERROR; - return false; // stall on all other requests - break; - } - } - break; - - case DFU_DNLOAD_SYNC: - { - switch (request->bRequest) - { - case DFU_REQUEST_GETSTATUS: - { - if ( _dfu_ctx.flashing_in_progress ) - { - _dfu_ctx.state = DFU_DNBUSY; - reply_getstatus(rhport, request); - dfu_req_dnload_reply(rhport, request); - } else { - _dfu_ctx.state = DFU_DNLOAD_IDLE; - reply_getstatus(rhport, request); - } - } - break; - - default: - _dfu_ctx.state = DFU_ERROR; - return false; // stall on all other requests - break; - } - } - break; - - case DFU_DNBUSY: - { - switch (request->bRequest) - { - default: - _dfu_ctx.state = DFU_ERROR; - return false; // stall on all other requests - break; - } - } - break; - - case DFU_DNLOAD_IDLE: - { - switch (request->bRequest) - { - case DFU_REQUEST_DNLOAD: - { - if( ((_dfu_ctx.attrs & DFU_ATTR_CAN_DOWNLOAD) != 0) - && (request->wLength > 0) ) - { - _dfu_ctx.state = DFU_DNLOAD_SYNC; - _dfu_ctx.flashing_in_progress = true; - dfu_req_dnload_setup(rhport, request); - } else { - if ( tud_dfu_download_complete_cb(_dfu_ctx.alt) ) - { - _dfu_ctx.state = DFU_MANIFEST_SYNC; - tud_control_status(rhport, request); - } else { - _dfu_ctx.state = DFU_ERROR; - return false; // stall - } - } - } - break; - - case DFU_REQUEST_GETSTATUS: - reply_getstatus(rhport, request); - break; - - default: - _dfu_ctx.state = DFU_ERROR; - return false; // stall on all other requests - break; - } - } - break; - - case DFU_MANIFEST_SYNC: - { - switch (request->bRequest) - { - case DFU_REQUEST_GETSTATUS: - { - if ((_dfu_ctx.attrs & DFU_ATTR_MANIFESTATION_TOLERANT) == 0) - { - _dfu_ctx.state = DFU_MANIFEST; - reply_getstatus(rhport, request); - } else - { - if ( tud_dfu_manifest_cb(_dfu_ctx.alt) ) - { - _dfu_ctx.state = DFU_IDLE; - } - reply_getstatus(rhport, request); - } - } - break; - - default: - _dfu_ctx.state = DFU_ERROR; - return false; // stall on all other requests - break; - } - } - break; - - case DFU_MANIFEST: - { - switch (request->bRequest) - { - // stall on all other requests - default: - return false; - break; - } - } - break; - - case DFU_MANIFEST_WAIT_RESET: - { - // technically we should never even get here, but we will handle it just in case - TU_LOG2(" DFU was in DFU_MANIFEST_WAIT_RESET and got unexpected request: %u\r\n", request->bRequest); - switch (request->bRequest) - { - default: - return false; // stall on all other requests - break; - } - } - break; - - case DFU_UPLOAD_IDLE: - { - switch (request->bRequest) - { - case DFU_REQUEST_GETSTATUS: - reply_getstatus(rhport, request); - break; - - default: - return false; // stall on all other requests - break; - } - } - break; - - case DFU_ERROR: - { - switch (request->bRequest) - { - case DFU_REQUEST_GETSTATUS: - reply_getstatus(rhport, request); - break; - - default: - return false; // stall on all other requests - break; - } - } - break; - - default: - _dfu_ctx.state = DFU_ERROR; - TU_LOG2(" DFU ERROR: Unexpected state\r\nStalling control pipe\r\n"); - return false; // Unexpected state, stall and change to error - } - - return true; -} - -#endif - #endif diff --git a/src/class/dfu/dfu_device.h b/src/class/dfu/dfu_device.h index 2d398aada..fecf8596f 100644 --- a/src/class/dfu/dfu_device.h +++ b/src/class/dfu/dfu_device.h @@ -37,8 +37,8 @@ // Class Driver Default Configure & Validation //--------------------------------------------------------------------+ -#if !defined(CFG_TUD_DFU_TRANSFER_BUFSIZE) - #error "CFG_TUD_DFU_TRANSFER_BUFSIZE must be defined, it has to be set to the buffer size used in TUD_DFU_DESCRIPTOR" +#if !defined(CFG_TUD_DFU_XFER_BUFSIZE) + #error "CFG_TUD_DFU_XFER_BUFSIZE must be defined, it has to be set to the buffer size used in TUD_DFU_DESCRIPTOR" #endif //--------------------------------------------------------------------+ -- cgit v1.3.1 From 4e50ceba48c15206543fe662f098a98152ef4235 Mon Sep 17 00:00:00 2001 From: hathach Date: Thu, 22 Jul 2021 17:07:39 +0700 Subject: rename packed begin/end --- src/class/cdc/cdc.h | 20 ++++++++++---------- src/common/tusb_compiler.h | 8 ++++---- src/common/tusb_types.h | 4 ++-- src/portable/renesas/usba/dcd_usba.c | 4 ++-- 4 files changed, 18 insertions(+), 18 deletions(-) (limited to 'src/class') diff --git a/src/class/cdc/cdc.h b/src/class/cdc/cdc.h index f59690835..7a06711be 100644 --- a/src/class/cdc/cdc.h +++ b/src/class/cdc/cdc.h @@ -215,7 +215,7 @@ typedef enum // Class Specific Functional Descriptor (Communication Interface) //--------------------------------------------------------------------+ -TU_PACK_STRUCT_BEGIN // Start of definition of packed structs (used by the CCRX toolchain) +TU_ATTR_PACKED_BEGIN // Start of definition of packed structs (used by the CCRX toolchain) /// Header Functional Descriptor (Communication Interface) typedef struct TU_ATTR_PACKED @@ -236,10 +236,10 @@ typedef struct TU_ATTR_PACKED uint8_t bSubordinateInterface ; ///< Array of Interface number of Data Interface }cdc_desc_func_union_t; -TU_PACK_STRUCT_END // End of definition of packed structs (used by the CCRX toolchain) +TU_ATTR_PACKED_END // End of definition of packed structs (used by the CCRX toolchain) #define cdc_desc_func_union_n_t(no_slave)\ - TU_PACK_STRUCT_BEGIN \ + TU_ATTR_PACKED_BEGIN \ struct TU_ATTR_PACKED { \ uint8_t bLength ;\ uint8_t bDescriptorType ;\ @@ -247,10 +247,10 @@ TU_PACK_STRUCT_END // End of definition of packed structs (used by the CCRX too uint8_t bControlInterface ;\ uint8_t bSubordinateInterface[no_slave] ;\ } \ -TU_PACK_STRUCT_END +TU_ATTR_PACKED_END -TU_PACK_STRUCT_BEGIN // Start of definition of packed structs (used by the CCRX toolchain) +TU_ATTR_PACKED_BEGIN // Start of definition of packed structs (used by the CCRX toolchain) /// Country Selection Functional Descriptor (Communication Interface) typedef struct TU_ATTR_PACKED @@ -262,10 +262,10 @@ typedef struct TU_ATTR_PACKED uint16_t wCountryCode ; ///< Country code in the format as defined in [ISO3166], release date as specified inoffset 3 for the first supported country. }cdc_desc_func_country_selection_t; -TU_PACK_STRUCT_END // End of definition of packed structs (used by the CCRX toolchain) +TU_ATTR_PACKED_END // End of definition of packed structs (used by the CCRX toolchain) #define cdc_desc_func_country_selection_n_t(no_country) \ - TU_PACK_STRUCT_BEGIN \ + TU_ATTR_PACKED_BEGIN \ struct TU_ATTR_PACKED { \ uint8_t bLength ;\ uint8_t bDescriptorType ;\ @@ -273,13 +273,13 @@ TU_PACK_STRUCT_END // End of definition of packed structs (used by the CCRX too uint8_t iCountryCodeRelDate ;\ uint16_t wCountryCode[no_country] ;\ } \ -TU_PACK_STRUCT_END +TU_ATTR_PACKED_END //--------------------------------------------------------------------+ // PUBLIC SWITCHED TELEPHONE NETWORK (PSTN) SUBCLASS //--------------------------------------------------------------------+ -TU_PACK_STRUCT_BEGIN // Start of definition of packed structs (used by the CCRX toolchain) +TU_ATTR_PACKED_BEGIN // Start of definition of packed structs (used by the CCRX toolchain) /// \brief Call Management Functional Descriptor /// \details This functional descriptor describes the processing of calls for the Communications Class interface. @@ -419,7 +419,7 @@ typedef struct TU_ATTR_PACKED } cdc_line_control_state_t; TU_BIT_FIELD_ORDER_END -TU_PACK_STRUCT_END // End of definition of packed structs (used by the CCRX toolchain) +TU_ATTR_PACKED_END // End of definition of packed structs (used by the CCRX toolchain) TU_VERIFY_STATIC(sizeof(cdc_line_control_state_t) == 2, "size is not correct"); diff --git a/src/common/tusb_compiler.h b/src/common/tusb_compiler.h index 6fdd08032..1f3128e0e 100644 --- a/src/common/tusb_compiler.h +++ b/src/common/tusb_compiler.h @@ -79,8 +79,8 @@ #define TU_ATTR_UNUSED __attribute__ ((unused)) // Function/Variable is meant to be possibly unused #define TU_ATTR_USED __attribute__ ((used)) // Function/Variable is meant to be used - #define TU_PACK_STRUCT_BEGIN - #define TU_PACK_STRUCT_END + #define TU_ATTR_PACKED_BEGIN + #define TU_ATTR_PACKED_END #define TU_BIT_FIELD_ORDER_BEGIN #define TU_BIT_FIELD_ORDER_END @@ -150,8 +150,8 @@ #define TU_ATTR_UNUSED #define TU_ATTR_USED - #define TU_PACK_STRUCT_BEGIN _Pragma("pack") - #define TU_PACK_STRUCT_END _Pragma("packoption") + #define TU_ATTR_PACKED_BEGIN _Pragma("pack") + #define TU_ATTR_PACKED_END _Pragma("packoption") #define TU_BIT_FIELD_ORDER_BEGIN _Pragma("bit_order right") #define TU_BIT_FIELD_ORDER_END _Pragma("bit_order") diff --git a/src/common/tusb_types.h b/src/common/tusb_types.h index f34eb3075..34395365e 100644 --- a/src/common/tusb_types.h +++ b/src/common/tusb_types.h @@ -262,7 +262,7 @@ enum // USB Descriptors //--------------------------------------------------------------------+ -TU_PACK_STRUCT_BEGIN // Start of definition of packed structs (used by the CCRX toolchain) +TU_ATTR_PACKED_BEGIN // Start of definition of packed structs (used by the CCRX toolchain) /// USB Device Descriptor typedef struct TU_ATTR_PACKED @@ -479,7 +479,7 @@ typedef struct TU_ATTR_PACKED{ } tusb_control_request_t; TU_BIT_FIELD_ORDER_END -TU_PACK_STRUCT_END // End of definition of packed structs (used by the CCRX toolchain) +TU_ATTR_PACKED_END // End of definition of packed structs (used by the CCRX toolchain) TU_VERIFY_STATIC( sizeof(tusb_control_request_t) == 8, "size is not correct"); diff --git a/src/portable/renesas/usba/dcd_usba.c b/src/portable/renesas/usba/dcd_usba.c index 67b92dc89..0c206fdd0 100644 --- a/src/portable/renesas/usba/dcd_usba.c +++ b/src/portable/renesas/usba/dcd_usba.c @@ -120,7 +120,7 @@ typedef union { } hw_fifo_t; TU_BIT_FIELD_ORDER_END -TU_PACK_STRUCT_BEGIN // Start of definition of packed structs (used by the CCRX toolchain) +TU_ATTR_PACKED_BEGIN // Start of definition of packed structs (used by the CCRX toolchain) TU_BIT_FIELD_ORDER_BEGIN typedef struct TU_ATTR_PACKED @@ -135,7 +135,7 @@ typedef struct TU_ATTR_PACKED } pipe_state_t; TU_BIT_FIELD_ORDER_END -TU_PACK_STRUCT_END // End of definition of packed structs (used by the CCRX toolchain) +TU_ATTR_PACKED_END // End of definition of packed structs (used by the CCRX toolchain) typedef struct { -- cgit v1.3.1 From c4da1abb1eaa7aff432535878ada519d02382419 Mon Sep 17 00:00:00 2001 From: hathach Date: Thu, 22 Jul 2021 17:24:59 +0700 Subject: rename bit filed order clean up packed/bit order begin end --- src/class/cdc/cdc.h | 41 +++++++----------------------------- src/common/tusb_compiler.h | 8 +++---- src/common/tusb_types.h | 24 +++++++++------------ src/portable/renesas/usba/dcd_usba.c | 12 +++++------ 4 files changed, 28 insertions(+), 57 deletions(-) (limited to 'src/class') diff --git a/src/class/cdc/cdc.h b/src/class/cdc/cdc.h index 7a06711be..6042cefe3 100644 --- a/src/class/cdc/cdc.h +++ b/src/class/cdc/cdc.h @@ -215,7 +215,9 @@ typedef enum // Class Specific Functional Descriptor (Communication Interface) //--------------------------------------------------------------------+ -TU_ATTR_PACKED_BEGIN // Start of definition of packed structs (used by the CCRX toolchain) +// Start of all packed definitions for compiler without per-type packed +TU_ATTR_PACKED_BEGIN +TU_ATTR_BIT_FIELD_ORDER_BEGIN /// Header Functional Descriptor (Communication Interface) typedef struct TU_ATTR_PACKED @@ -236,10 +238,7 @@ typedef struct TU_ATTR_PACKED uint8_t bSubordinateInterface ; ///< Array of Interface number of Data Interface }cdc_desc_func_union_t; -TU_ATTR_PACKED_END // End of definition of packed structs (used by the CCRX toolchain) - #define cdc_desc_func_union_n_t(no_slave)\ - TU_ATTR_PACKED_BEGIN \ struct TU_ATTR_PACKED { \ uint8_t bLength ;\ uint8_t bDescriptorType ;\ @@ -247,10 +246,6 @@ TU_ATTR_PACKED_END // End of definition of packed structs (used by the CCRX too uint8_t bControlInterface ;\ uint8_t bSubordinateInterface[no_slave] ;\ } \ -TU_ATTR_PACKED_END - - -TU_ATTR_PACKED_BEGIN // Start of definition of packed structs (used by the CCRX toolchain) /// Country Selection Functional Descriptor (Communication Interface) typedef struct TU_ATTR_PACKED @@ -262,10 +257,7 @@ typedef struct TU_ATTR_PACKED uint16_t wCountryCode ; ///< Country code in the format as defined in [ISO3166], release date as specified inoffset 3 for the first supported country. }cdc_desc_func_country_selection_t; -TU_ATTR_PACKED_END // End of definition of packed structs (used by the CCRX toolchain) - #define cdc_desc_func_country_selection_n_t(no_country) \ - TU_ATTR_PACKED_BEGIN \ struct TU_ATTR_PACKED { \ uint8_t bLength ;\ uint8_t bDescriptorType ;\ @@ -273,17 +265,13 @@ TU_ATTR_PACKED_END // End of definition of packed structs (used by the CCRX too uint8_t iCountryCodeRelDate ;\ uint16_t wCountryCode[no_country] ;\ } \ -TU_ATTR_PACKED_END //--------------------------------------------------------------------+ // PUBLIC SWITCHED TELEPHONE NETWORK (PSTN) SUBCLASS //--------------------------------------------------------------------+ -TU_ATTR_PACKED_BEGIN // Start of definition of packed structs (used by the CCRX toolchain) - /// \brief Call Management Functional Descriptor /// \details This functional descriptor describes the processing of calls for the Communications Class interface. -TU_BIT_FIELD_ORDER_BEGIN typedef struct TU_ATTR_PACKED { uint8_t bLength ; ///< Size of this descriptor in bytes. @@ -298,10 +286,7 @@ typedef struct TU_ATTR_PACKED uint8_t bDataInterface; }cdc_desc_func_call_management_t; -TU_BIT_FIELD_ORDER_END - -TU_BIT_FIELD_ORDER_BEGIN typedef struct TU_ATTR_PACKED { uint8_t support_comm_request : 1; ///< Device supports the request combination of Set_Comm_Feature, Clear_Comm_Feature, and Get_Comm_Feature. @@ -310,12 +295,11 @@ typedef struct TU_ATTR_PACKED uint8_t support_notification_network_connection : 1; ///< Device supports the notification Network_Connection. uint8_t TU_RESERVED : 4; }cdc_acm_capability_t; -TU_BIT_FIELD_ORDER_END TU_VERIFY_STATIC(sizeof(cdc_acm_capability_t) == 1, "mostly problem with compiler"); -/// \brief Abstract Control Management Functional Descriptor -/// \details This functional descriptor describes the commands supported by by the Communications Class interface with SubClass code of \ref CDC_COMM_SUBCLASS_ABSTRACT_CONTROL_MODEL +/// Abstract Control Management Functional Descriptor +/// This functional descriptor describes the commands supported by by the Communications Class interface with SubClass code of \ref CDC_COMM_SUBCLASS_ABSTRACT_CONTROL_MODEL typedef struct TU_ATTR_PACKED { uint8_t bLength ; ///< Size of this descriptor in bytes. @@ -326,7 +310,6 @@ typedef struct TU_ATTR_PACKED /// \brief Direct Line Management Functional Descriptor /// \details This functional descriptor describes the commands supported by the Communications Class interface with SubClass code of \ref CDC_FUNC_DESC_DIRECT_LINE_MANAGEMENT -TU_BIT_FIELD_ORDER_BEGIN typedef struct TU_ATTR_PACKED { uint8_t bLength ; ///< Size of this descriptor in bytes. @@ -339,7 +322,6 @@ typedef struct TU_ATTR_PACKED uint8_t TU_RESERVED : 5; } bmCapabilities; }cdc_desc_func_direct_line_management_t; -TU_BIT_FIELD_ORDER_END /// \brief Telephone Ringer Functional Descriptor /// \details The Telephone Ringer functional descriptor describes the ringer capabilities supported by the Communications Class interface, @@ -356,7 +338,6 @@ typedef struct TU_ATTR_PACKED /// \brief Telephone Operational Modes Functional Descriptor /// \details The Telephone Operational Modes functional descriptor describes the operational modes supported by /// the Communications Class interface, with the SubClass code of \ref CDC_COMM_SUBCLASS_TELEPHONE_CONTROL_MODEL -TU_BIT_FIELD_ORDER_BEGIN typedef struct TU_ATTR_PACKED { uint8_t bLength ; ///< Size of this descriptor in bytes. @@ -369,12 +350,10 @@ typedef struct TU_ATTR_PACKED uint8_t TU_RESERVED : 5; } bmCapabilities; }cdc_desc_func_telephone_operational_modes_t; -TU_BIT_FIELD_ORDER_END /// \brief Telephone Call and Line State Reporting Capabilities Descriptor /// \details The Telephone Call and Line State Reporting Capabilities functional descriptor describes the abilities of a /// telephone device to report optional call and line states. -TU_BIT_FIELD_ORDER_BEGIN typedef struct TU_ATTR_PACKED { uint8_t bLength ; ///< Size of this descriptor in bytes. @@ -390,8 +369,8 @@ typedef struct TU_ATTR_PACKED uint32_t TU_RESERVED : 26; } bmCapabilities; }cdc_desc_func_telephone_call_state_reporting_capabilities_t; -TU_BIT_FIELD_ORDER_END +// TODO remove static inline uint8_t cdc_functional_desc_typeof(uint8_t const * p_desc) { return p_desc[2]; @@ -410,21 +389,17 @@ typedef struct TU_ATTR_PACKED TU_VERIFY_STATIC(sizeof(cdc_line_coding_t) == 7, "size is not correct"); -TU_BIT_FIELD_ORDER_BEGIN typedef struct TU_ATTR_PACKED { uint16_t dte_is_present : 1; ///< Indicates to DCE if DTE is presentor not. This signal corresponds to V.24 signal 108/2 and RS-232 signal DTR. uint16_t half_duplex_carrier_control : 1; uint16_t : 14; } cdc_line_control_state_t; -TU_BIT_FIELD_ORDER_END - -TU_ATTR_PACKED_END // End of definition of packed structs (used by the CCRX toolchain) - TU_VERIFY_STATIC(sizeof(cdc_line_control_state_t) == 2, "size is not correct"); -/** @} */ +TU_ATTR_PACKED_END // End of all packed definitions +TU_ATTR_BIT_FIELD_ORDER_END #ifdef __cplusplus } diff --git a/src/common/tusb_compiler.h b/src/common/tusb_compiler.h index 1f3128e0e..820782d65 100644 --- a/src/common/tusb_compiler.h +++ b/src/common/tusb_compiler.h @@ -82,8 +82,8 @@ #define TU_ATTR_PACKED_BEGIN #define TU_ATTR_PACKED_END - #define TU_BIT_FIELD_ORDER_BEGIN - #define TU_BIT_FIELD_ORDER_END + #define TU_ATTR_BIT_FIELD_ORDER_BEGIN + #define TU_ATTR_BIT_FIELD_ORDER_END // Endian conversion use well-known host to network (big endian) naming #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ @@ -153,8 +153,8 @@ #define TU_ATTR_PACKED_BEGIN _Pragma("pack") #define TU_ATTR_PACKED_END _Pragma("packoption") - #define TU_BIT_FIELD_ORDER_BEGIN _Pragma("bit_order right") - #define TU_BIT_FIELD_ORDER_END _Pragma("bit_order") + #define TU_ATTR_BIT_FIELD_ORDER_BEGIN _Pragma("bit_order right") + #define TU_ATTR_BIT_FIELD_ORDER_END _Pragma("bit_order") // Endian conversion use well-known host to network (big endian) naming #if defined(__LIT) diff --git a/src/common/tusb_types.h b/src/common/tusb_types.h index 34395365e..d23c6b2dd 100644 --- a/src/common/tusb_types.h +++ b/src/common/tusb_types.h @@ -262,7 +262,9 @@ enum // USB Descriptors //--------------------------------------------------------------------+ -TU_ATTR_PACKED_BEGIN // Start of definition of packed structs (used by the CCRX toolchain) +// Start of all packed definitions for compiler without per-type packed +TU_ATTR_PACKED_BEGIN +TU_ATTR_BIT_FIELD_ORDER_BEGIN /// USB Device Descriptor typedef struct TU_ATTR_PACKED @@ -297,6 +299,8 @@ typedef struct TU_ATTR_PACKED uint8_t bNumDeviceCaps ; ///< Number of device capability descriptors in the BOS } tusb_desc_bos_t; +TU_VERIFY_STATIC( sizeof(tusb_desc_bos_t) == 5, "size is not correct"); + /// USB Configuration Descriptor typedef struct TU_ATTR_PACKED { @@ -328,8 +332,9 @@ typedef struct TU_ATTR_PACKED uint8_t iInterface ; ///< Index of string descriptor describing this interface } tusb_desc_interface_t; +TU_VERIFY_STATIC( sizeof(tusb_desc_interface_t) == 9, "size is not correct"); + /// USB Endpoint Descriptor -TU_BIT_FIELD_ORDER_BEGIN typedef struct TU_ATTR_PACKED { uint8_t bLength ; ///< Size of this descriptor in bytes @@ -357,7 +362,6 @@ typedef struct TU_ATTR_PACKED uint8_t bInterval ; ///< Interval for polling endpoint for data transfers. Expressed in frames or microframes depending on the device operating speed (i.e., either 1 millisecond or 125 us units). \n- For full-/high-speed isochronous endpoints, this value must be in the range from 1 to 16. The bInterval value is used as the exponent for a \f$ 2^(bInterval-1) \f$ value; e.g., a bInterval of 4 means a period of 8 (\f$ 2^(4-1) \f$). \n- For full-/low-speed interrupt endpoints, the value of this field may be from 1 to 255. \n- For high-speed interrupt endpoints, the bInterval value is used as the exponent for a \f$ 2^(bInterval-1) \f$ value; e.g., a bInterval of 4 means a period of 8 (\f$ 2^(4-1) \f$) . This value must be from 1 to 16. \n- For high-speed bulk/control OUT endpoints, the bInterval must specify the maximum NAK rate of the endpoint. A value of 0 indicates the endpoint never NAKs. Other values indicate at most 1 NAK each bInterval number of microframes. This value must be in the range from 0 to 255. \n Refer to Chapter 5 of USB 2.0 specification for more information. } tusb_desc_endpoint_t; -TU_BIT_FIELD_ORDER_END /// USB Other Speed Configuration Descriptor typedef struct TU_ATTR_PACKED @@ -433,7 +437,6 @@ typedef struct TU_ATTR_PACKED } tusb_desc_webusb_url_t; // DFU Functional Descriptor -TU_BIT_FIELD_ORDER_BEGIN typedef struct TU_ATTR_PACKED { uint8_t bLength; @@ -455,12 +458,10 @@ typedef struct TU_ATTR_PACKED uint16_t wTransferSize; uint16_t bcdDFUVersion; } tusb_desc_dfu_functional_t; -TU_BIT_FIELD_ORDER_END /*------------------------------------------------------------------*/ /* Types *------------------------------------------------------------------*/ -TU_BIT_FIELD_ORDER_BEGIN typedef struct TU_ATTR_PACKED{ union { struct TU_ATTR_PACKED { @@ -477,17 +478,12 @@ typedef struct TU_ATTR_PACKED{ uint16_t wIndex; uint16_t wLength; } tusb_control_request_t; -TU_BIT_FIELD_ORDER_END - -TU_ATTR_PACKED_END // End of definition of packed structs (used by the CCRX toolchain) TU_VERIFY_STATIC( sizeof(tusb_control_request_t) == 8, "size is not correct"); -// TODO move to somewhere suitable -static inline uint8_t bm_request_type(uint8_t direction, uint8_t type, uint8_t recipient) -{ - return ((uint8_t) (direction << 7)) | ((uint8_t) (type << 5)) | (recipient); -} + +TU_ATTR_PACKED_END // End of all packed definitions +TU_ATTR_BIT_FIELD_ORDER_END //--------------------------------------------------------------------+ // Endpoint helper diff --git a/src/portable/renesas/usba/dcd_usba.c b/src/portable/renesas/usba/dcd_usba.c index 0c206fdd0..f68f97458 100644 --- a/src/portable/renesas/usba/dcd_usba.c +++ b/src/portable/renesas/usba/dcd_usba.c @@ -95,7 +95,7 @@ #define FIFO_REQ_CLR (1u) #define FIFO_COMPLETE (1u<<1) -TU_BIT_FIELD_ORDER_BEGIN +TU_ATTR_BIT_FIELD_ORDER_BEGIN typedef struct { union { struct { @@ -108,9 +108,9 @@ typedef struct { }; uint16_t TRN; } reg_pipetre_t; -TU_BIT_FIELD_ORDER_END +TU_ATTR_BIT_FIELD_ORDER_END -TU_BIT_FIELD_ORDER_BEGIN +TU_ATTR_BIT_FIELD_ORDER_BEGIN typedef union { struct { volatile uint16_t u8: 8; @@ -118,11 +118,11 @@ typedef union { }; volatile uint16_t u16; } hw_fifo_t; -TU_BIT_FIELD_ORDER_END +TU_ATTR_BIT_FIELD_ORDER_END TU_ATTR_PACKED_BEGIN // Start of definition of packed structs (used by the CCRX toolchain) -TU_BIT_FIELD_ORDER_BEGIN +TU_ATTR_BIT_FIELD_ORDER_BEGIN typedef struct TU_ATTR_PACKED { uintptr_t addr; /* the start address of a transfer data buffer */ @@ -133,7 +133,7 @@ typedef struct TU_ATTR_PACKED uint32_t : 0; }; } pipe_state_t; -TU_BIT_FIELD_ORDER_END +TU_ATTR_BIT_FIELD_ORDER_END TU_ATTR_PACKED_END // End of definition of packed structs (used by the CCRX toolchain) -- cgit v1.3.1 From 15112fdbba8cf4e9ad0d99fafd8b40f07f29fb6d Mon Sep 17 00:00:00 2001 From: hathach Date: Thu, 22 Jul 2021 22:10:48 +0700 Subject: clean up compiler --- src/class/cdc/cdc.h | 4 ++-- src/common/tusb_compiler.h | 18 +++++++++++++----- src/portable/renesas/usba/dcd_usba.c | 20 ++++---------------- 3 files changed, 19 insertions(+), 23 deletions(-) (limited to 'src/class') diff --git a/src/class/cdc/cdc.h b/src/class/cdc/cdc.h index 6042cefe3..5df47f70b 100644 --- a/src/class/cdc/cdc.h +++ b/src/class/cdc/cdc.h @@ -245,7 +245,7 @@ typedef struct TU_ATTR_PACKED uint8_t bDescriptorSubType ;\ uint8_t bControlInterface ;\ uint8_t bSubordinateInterface[no_slave] ;\ -} \ +} /// Country Selection Functional Descriptor (Communication Interface) typedef struct TU_ATTR_PACKED @@ -264,7 +264,7 @@ typedef struct TU_ATTR_PACKED uint8_t bDescriptorSubType ;\ uint8_t iCountryCodeRelDate ;\ uint16_t wCountryCode[no_country] ;\ -} \ +} //--------------------------------------------------------------------+ // PUBLIC SWITCHED TELEPHONE NETWORK (PSTN) SUBCLASS diff --git a/src/common/tusb_compiler.h b/src/common/tusb_compiler.h index 820782d65..d3adbbc2d 100644 --- a/src/common/tusb_compiler.h +++ b/src/common/tusb_compiler.h @@ -81,7 +81,6 @@ #define TU_ATTR_PACKED_BEGIN #define TU_ATTR_PACKED_END - #define TU_ATTR_BIT_FIELD_ORDER_BEGIN #define TU_ATTR_BIT_FIELD_ORDER_END @@ -109,6 +108,11 @@ #define TU_ATTR_UNUSED __attribute__ ((unused)) // Function/Variable is meant to be possibly unused #define TU_ATTR_USED __attribute__ ((used)) + #define TU_ATTR_PACKED_BEGIN + #define TU_ATTR_PACKED_END + #define TU_ATTR_BIT_FIELD_ORDER_BEGIN + #define TU_ATTR_BIT_FIELD_ORDER_END + // __BYTE_ORDER is defined in the TI ARM compiler, but not MSP430 (which is little endian) #if ((__BYTE_ORDER__) == (__ORDER_LITTLE_ENDIAN__)) || defined(__MSP430__) #define TU_BYTE_ORDER TU_LITTLE_ENDIAN @@ -130,6 +134,11 @@ #define TU_ATTR_UNUSED __attribute__ ((unused)) // Function/Variable is meant to be possibly unused #define TU_ATTR_USED __attribute__ ((used)) // Function/Variable is meant to be used + #define TU_ATTR_PACKED_BEGIN + #define TU_ATTR_PACKED_END + #define TU_ATTR_BIT_FIELD_ORDER_BEGIN + #define TU_ATTR_BIT_FIELD_ORDER_END + // Endian conversion use well-known host to network (big endian) naming #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ #define TU_BYTE_ORDER TU_LITTLE_ENDIAN @@ -150,11 +159,10 @@ #define TU_ATTR_UNUSED #define TU_ATTR_USED - #define TU_ATTR_PACKED_BEGIN _Pragma("pack") - #define TU_ATTR_PACKED_END _Pragma("packoption") - + #define TU_ATTR_PACKED_BEGIN _Pragma("pack") + #define TU_ATTR_PACKED_END _Pragma("packoption") #define TU_ATTR_BIT_FIELD_ORDER_BEGIN _Pragma("bit_order right") - #define TU_ATTR_BIT_FIELD_ORDER_END _Pragma("bit_order") + #define TU_ATTR_BIT_FIELD_ORDER_END _Pragma("bit_order") // Endian conversion use well-known host to network (big endian) naming #if defined(__LIT) diff --git a/src/portable/renesas/usba/dcd_usba.c b/src/portable/renesas/usba/dcd_usba.c index 0b78a6e46..c7eb6e15e 100644 --- a/src/portable/renesas/usba/dcd_usba.c +++ b/src/portable/renesas/usba/dcd_usba.c @@ -334,11 +334,7 @@ static bool process_edpt0_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t* buffer, pipe_state_t *pipe = &_dcd.pipe[0]; /* configure fifo direction and access unit settings */ if (ep_addr) { /* IN, 2 bytes */ -#if TU_BYTE_ORDER == TU_BIG_ENDIAN - USB0.CFIFOSEL.WORD = USB_FIFOSEL_TX | USB_FIFOSEL_MBW_16 | USB_FIFOSEL_BIGEND; -#else - USB0.CFIFOSEL.WORD = USB_FIFOSEL_TX | USB_FIFOSEL_MBW_16; -#endif + USB0.CFIFOSEL.WORD = USB_FIFOSEL_TX | USB_FIFOSEL_MBW_16 | (TU_BYTE_ORDER == TU_BIG_ENDIAN ? USB_FIFOSEL_BIGEND : 0); while (!(USB0.CFIFOSEL.WORD & USB_FIFOSEL_TX)) ; } else { /* OUT, a byte */ USB0.CFIFOSEL.WORD = USB_FIFOSEL_MBW_8; @@ -413,11 +409,7 @@ static bool process_pipe_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t* buffer, USB0.PIPESEL.WORD = num; const unsigned mps = USB0.PIPEMAXP.WORD; if (dir) { /* IN */ -#if TU_BYTE_ORDER == TU_BIG_ENDIAN - USB0.D0FIFOSEL.WORD = num | USB_FIFOSEL_MBW_16 | USB_FIFOSEL_BIGEND; -#else - USB0.D0FIFOSEL.WORD = num | USB_FIFOSEL_MBW_16; -#endif + USB0.D0FIFOSEL.WORD = num | USB_FIFOSEL_MBW_16 | (TU_BYTE_ORDER == TU_BIG_ENDIAN ? USB_FIFOSEL_BIGEND : 0); while (USB0.D0FIFOSEL.BIT.CURPIPE != num) ; int r = fifo_write((void*)&USB0.D0FIFO.WORD, pipe, mps); if (r) USB0.D0FIFOCTR.WORD = USB_FIFOCTR_BVAL; @@ -442,11 +434,7 @@ static void process_pipe_brdy(uint8_t rhport, unsigned num) { pipe_state_t *pipe = &_dcd.pipe[num]; if (tu_edpt_dir(pipe->ep)) { /* IN */ -#if TU_BYTE_ORDER == TU_BIG_ENDIAN - select_pipe(num, USB_FIFOSEL_MBW_16 | USB_FIFOSEL_BIGEND); -#else - select_pipe(num, USB_FIFOSEL_MBW_16); -#endif + select_pipe(num, USB_FIFOSEL_MBW_16 | (TU_BYTE_ORDER == TU_BIG_ENDIAN ? USB_FIFOSEL_BIGEND : 0)); const unsigned mps = USB0.PIPEMAXP.WORD; unsigned rem = pipe->remaining; rem -= TU_MIN(rem, mps); @@ -527,7 +515,7 @@ static void process_set_address(uint8_t rhport) #else .bmRequestType = 0, #endif - .bRequest = 5, + .bRequest = TUSB_REQ_SET_ADDRESS, .wValue = addr, .wIndex = 0, .wLength = 0, -- cgit v1.3.1 From 0ba4315ae559f595c0d01ab650ea924d8e9bec69 Mon Sep 17 00:00:00 2001 From: MasterPhi Date: Tue, 27 Jul 2021 18:08:52 +0200 Subject: Fix IAR warning --- src/class/dfu/dfu_device.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/class') diff --git a/src/class/dfu/dfu_device.c b/src/class/dfu/dfu_device.c index ad87092e0..28abf6e83 100644 --- a/src/class/dfu/dfu_device.c +++ b/src/class/dfu/dfu_device.c @@ -190,7 +190,7 @@ uint16_t dfu_moded_open(uint8_t rhport, tusb_desc_interface_t const * itf_desc, _dfu_ctx.attrs = func_desc->bAttributes; // CFG_TUD_DFU_XFER_BUFSIZE has to be set to the buffer size used in TUD_DFU_DESCRIPTOR - uint16_t const transfer_size = tu_le16toh( tu_unaligned_read16(&func_desc->wTransferSize) ); + uint16_t const transfer_size = tu_le16toh( tu_unaligned_read16((uint8_t*) func_desc + offsetof(tusb_desc_dfu_functional_t, wTransferSize)) ); TU_ASSERT(transfer_size <= CFG_TUD_DFU_XFER_BUFSIZE, drv_len); return drv_len; @@ -365,7 +365,7 @@ void tud_dfu_finish_flashing(uint8_t status) { // failed while flashing, move to dfuError _dfu_ctx.state = DFU_ERROR; - _dfu_ctx.status = status; + _dfu_ctx.status = (dfu_status_t)status; } } -- cgit v1.3.1 From 6b9f8e454eaf5ac3a9474d0a09f019e700532093 Mon Sep 17 00:00:00 2001 From: kkitayam <45088311+kkitayam@users.noreply.github.com> Date: Fri, 4 Jun 2021 01:22:57 +0900 Subject: add a condition regarding OPT_MCU_RX63N --- src/class/audio/audio_device.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/class') diff --git a/src/class/audio/audio_device.c b/src/class/audio/audio_device.c index 404d28817..86a00ea73 100644 --- a/src/class/audio/audio_device.c +++ b/src/class/audio/audio_device.c @@ -86,7 +86,8 @@ CFG_TUSB_MCU == OPT_MCU_STM32F4 || \ CFG_TUSB_MCU == OPT_MCU_STM32F7 || \ CFG_TUSB_MCU == OPT_MCU_STM32H7 || \ - (CFG_TUSB_MCU == OPT_MCU_STM32L4 && defined(STM32L4_SYNOPSYS)) + (CFG_TUSB_MCU == OPT_MCU_STM32L4 && defined(STM32L4_SYNOPSYS)) || \ + CFG_TUSB_MCU == OPT_MCU_RX63X #define USE_LINEAR_BUFFER 0 #else #define USE_LINEAR_BUFFER 1 -- cgit v1.3.1 From 3c3563288d643fc70ccff80c02a72d330cd65678 Mon Sep 17 00:00:00 2001 From: kkitayam <45088311+kkitayam@users.noreply.github.com> Date: Tue, 29 Jun 2021 20:41:16 +0900 Subject: add RX65N --- src/class/audio/audio_device.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/class') diff --git a/src/class/audio/audio_device.c b/src/class/audio/audio_device.c index 86a00ea73..092e5e125 100644 --- a/src/class/audio/audio_device.c +++ b/src/class/audio/audio_device.c @@ -87,7 +87,8 @@ CFG_TUSB_MCU == OPT_MCU_STM32F7 || \ CFG_TUSB_MCU == OPT_MCU_STM32H7 || \ (CFG_TUSB_MCU == OPT_MCU_STM32L4 && defined(STM32L4_SYNOPSYS)) || \ - CFG_TUSB_MCU == OPT_MCU_RX63X + CFG_TUSB_MCU == OPT_MCU_RX63X || \ + CFG_TUSB_MCU == OPT_MCU_RX65X #define USE_LINEAR_BUFFER 0 #else #define USE_LINEAR_BUFFER 1 -- cgit v1.3.1 From ff20e4d6bcffc5d66666050c57719031fa2820e8 Mon Sep 17 00:00:00 2001 From: kkitayam <45088311+kkitayam@users.noreply.github.com> Date: Thu, 29 Jul 2021 20:45:51 +0900 Subject: add the entry for RX72N --- src/class/audio/audio_device.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/class') diff --git a/src/class/audio/audio_device.c b/src/class/audio/audio_device.c index 092e5e125..de0bddcd3 100644 --- a/src/class/audio/audio_device.c +++ b/src/class/audio/audio_device.c @@ -88,7 +88,8 @@ CFG_TUSB_MCU == OPT_MCU_STM32H7 || \ (CFG_TUSB_MCU == OPT_MCU_STM32L4 && defined(STM32L4_SYNOPSYS)) || \ CFG_TUSB_MCU == OPT_MCU_RX63X || \ - CFG_TUSB_MCU == OPT_MCU_RX65X + CFG_TUSB_MCU == OPT_MCU_RX65X || \ + CFG_TUSB_MCU == OPT_MCU_RX72N #define USE_LINEAR_BUFFER 0 #else #define USE_LINEAR_BUFFER 1 -- cgit v1.3.1 From 98e4ba6a12f8ce2b060635dc01f68676b047ce25 Mon Sep 17 00:00:00 2001 From: hathach Date: Mon, 2 Aug 2021 18:55:12 +0700 Subject: correct midi available with already stream read --- src/class/midi/midi_device.c | 7 ++++++- src/common/tusb_fifo.c | 2 -- 2 files changed, 6 insertions(+), 3 deletions(-) (limited to 'src/class') diff --git a/src/class/midi/midi_device.c b/src/class/midi/midi_device.c index c39e03976..9d9619132 100644 --- a/src/class/midi/midi_device.c +++ b/src/class/midi/midi_device.c @@ -122,7 +122,12 @@ static void _prep_out_transaction (midid_interface_t* p_midi) uint32_t tud_midi_n_available(uint8_t itf, uint8_t cable_num) { (void) cable_num; - return tu_fifo_count(&_midid_itf[itf].rx_ff); + + midid_interface_t const* midi = &_midid_itf[itf]; + midid_stream_t const* stream = &midi->stream_read; + + // when using with packet API stream total & index are both zero + return tu_fifo_count(&midi->rx_ff) + (stream->total - stream->index); } uint32_t tud_midi_n_stream_read(uint8_t itf, uint8_t cable_num, void* buffer, uint32_t bufsize) diff --git a/src/common/tusb_fifo.c b/src/common/tusb_fifo.c index 73217cf75..11b8fc5f3 100644 --- a/src/common/tusb_fifo.c +++ b/src/common/tusb_fifo.c @@ -323,8 +323,6 @@ static uint16_t advance_pointer(tu_fifo_t* f, uint16_t p, uint16_t offset) // We limit the index space of p such that a correct wrap around happens // Check for a wrap around or if we are in unused index space - This has to be checked first!! // We are exploiting the wrap around to the correct index - - // TODO warning: assuming signed overflow does not occur when assuming that (X + c) < X is always false [-Wstrict-overflow] if ((p > (uint16_t)(p + offset)) || ((uint16_t)(p + offset) > f->max_pointer_idx)) { p = (p + offset) + f->non_used_index_space; -- cgit v1.3.1 From 794bbd7177dd5f3cab35eadf9a9268eddf61736f Mon Sep 17 00:00:00 2001 From: hathach Date: Mon, 2 Aug 2021 18:58:27 +0700 Subject: fix warning --- src/class/midi/midi_device.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/class') diff --git a/src/class/midi/midi_device.c b/src/class/midi/midi_device.c index 9d9619132..eb85b668c 100644 --- a/src/class/midi/midi_device.c +++ b/src/class/midi/midi_device.c @@ -123,7 +123,7 @@ uint32_t tud_midi_n_available(uint8_t itf, uint8_t cable_num) { (void) cable_num; - midid_interface_t const* midi = &_midid_itf[itf]; + midid_interface_t* midi = &_midid_itf[itf]; midid_stream_t const* stream = &midi->stream_read; // when using with packet API stream total & index are both zero -- cgit v1.3.1 From 8b78067cc1142c5915ad5fa1275996e92f91a58d Mon Sep 17 00:00:00 2001 From: Stefan Kerkmann Date: Sat, 7 Aug 2021 12:06:54 +0200 Subject: Use linear buffer for GD32VF103 As the peripheral is the same as on the STM32F1 and STM32F4 lines we do the same. --- src/class/audio/audio_device.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/class') diff --git a/src/class/audio/audio_device.c b/src/class/audio/audio_device.c index de0bddcd3..ff4e312a7 100644 --- a/src/class/audio/audio_device.c +++ b/src/class/audio/audio_device.c @@ -89,7 +89,8 @@ (CFG_TUSB_MCU == OPT_MCU_STM32L4 && defined(STM32L4_SYNOPSYS)) || \ CFG_TUSB_MCU == OPT_MCU_RX63X || \ CFG_TUSB_MCU == OPT_MCU_RX65X || \ - CFG_TUSB_MCU == OPT_MCU_RX72N + CFG_TUSB_MCU == OPT_MCU_RX72N || \ + CFG_TUSB_MCU == OPT_MCU_GD32VF103 #define USE_LINEAR_BUFFER 0 #else #define USE_LINEAR_BUFFER 1 -- cgit v1.3.1 From 2ea0ef4543ed8a3d127f6354ab3a5ae2a48ec245 Mon Sep 17 00:00:00 2001 From: hathach Date: Tue, 10 Aug 2021 16:40:43 +0700 Subject: correct newline usage keycode (ENTER 0x28) --- src/class/hid/hid.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/class') diff --git a/src/class/hid/hid.h b/src/class/hid/hid.h index ec14c9c7c..9265a2ede 100644 --- a/src/class/hid/hid.h +++ b/src/class/hid/hid.h @@ -871,10 +871,10 @@ enum {0, 0 }, /* 0x07 */ \ {0, HID_KEY_BACKSPACE }, /* 0x08 Backspace */ \ {0, HID_KEY_TAB }, /* 0x09 Tab */ \ - {0, HID_KEY_RETURN }, /* 0x0A Line Feed */ \ + {0, HID_KEY_ENTER }, /* 0x0A Line Feed */ \ {0, 0 }, /* 0x0B */ \ {0, 0 }, /* 0x0C */ \ - {0, HID_KEY_RETURN }, /* 0x0D CR */ \ + {0, HID_KEY_ENTER }, /* 0x0D CR */ \ {0, 0 }, /* 0x0E */ \ {0, 0 }, /* 0x0F */ \ {0, 0 }, /* 0x10 */ \ -- cgit v1.3.1 From a6d18c400ddc6b61f665baae5672ed46af17c99c Mon Sep 17 00:00:00 2001 From: hathach Date: Tue, 17 Aug 2021 13:29:26 +0700 Subject: fix keyboard report reserved is always 0 --- src/class/hid/hid_device.c | 1 + 1 file changed, 1 insertion(+) (limited to 'src/class') diff --git a/src/class/hid/hid_device.c b/src/class/hid/hid_device.c index a10e3a5e3..2ee80750a 100644 --- a/src/class/hid/hid_device.c +++ b/src/class/hid/hid_device.c @@ -121,6 +121,7 @@ bool tud_hid_n_keyboard_report(uint8_t instance, uint8_t report_id, uint8_t modi hid_keyboard_report_t report; report.modifier = modifier; + report.reserved = 0; if ( keycode ) { -- cgit v1.3.1 From 62f2efbe8cf1e61f70660abac28f4226bca93daf Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 20 Aug 2021 18:26:56 +0700 Subject: hid host skip get report descriptor if too large instead of assert --- examples/host/cdc_msc_hid/src/hid_app.c | 2 ++ src/class/hid/hid_host.c | 58 +++++++++++++++++++++------------ src/class/hid/hid_host.h | 2 ++ src/host/usbh.c | 2 -- 4 files changed, 41 insertions(+), 23 deletions(-) (limited to 'src/class') diff --git a/examples/host/cdc_msc_hid/src/hid_app.c b/examples/host/cdc_msc_hid/src/hid_app.c index 420600f9a..5e3ac6a72 100644 --- a/examples/host/cdc_msc_hid/src/hid_app.c +++ b/examples/host/cdc_msc_hid/src/hid_app.c @@ -61,6 +61,8 @@ void hid_app_task(void) // Invoked when device with hid interface is mounted // Report descriptor is also available for use. tuh_hid_parse_report_descriptor() // can be used to parse common/simple enough descriptor. +// Note: if report descriptor length > CFG_TUH_ENUMERATION_BUFSIZE, it will be skipped +// therefore report_desc = NULL, desc_len = 0 void tuh_hid_mount_cb(uint8_t dev_addr, uint8_t instance, uint8_t const* desc_report, uint16_t desc_len) { printf("HID device address = %d, instance = %d is mounted\r\n", dev_addr, instance); diff --git a/src/class/hid/hid_host.c b/src/class/hid/hid_host.c index 40b6f5631..a39ac8bec 100644 --- a/src/class/hid/hid_host.c +++ b/src/class/hid/hid_host.c @@ -247,6 +247,8 @@ static bool config_set_protocol (uint8_t dev_addr, tusb_control_requ static bool config_get_report_desc (uint8_t dev_addr, tusb_control_request_t const * request, xfer_result_t result); static bool config_get_report_desc_complete (uint8_t dev_addr, tusb_control_request_t const * request, xfer_result_t result); +static void config_driver_mount_complete(uint8_t dev_addr, uint8_t instance, uint8_t const* desc_report, uint16_t desc_len); + uint16_t hidh_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const *desc_itf, uint16_t max_len) { (void) max_len; @@ -367,26 +369,34 @@ static bool config_get_report_desc(uint8_t dev_addr, tusb_control_request_t cons uint8_t const instance = get_instance_id_by_itfnum(dev_addr, itf_num); hidh_interface_t* hid_itf = get_instance(dev_addr, instance); - // Get Report Descriptor + // Get Report Descriptor if possible // using usbh enumeration buffer since report descriptor can be very long - TU_ASSERT( hid_itf->report_desc_len <= CFG_TUH_ENUMERATION_BUFSIZE ); + if( hid_itf->report_desc_len > CFG_TUH_ENUMERATION_BUFSIZE ) + { + TU_LOG2("HID Skip Report Descriptor since it is too large %u bytes\r\n", hid_itf->report_desc_len); - TU_LOG2("HID Get Report Descriptor\r\n"); - tusb_control_request_t const new_request = + // Driver is mounted without report descriptor + config_driver_mount_complete(dev_addr, instance, NULL, 0); + }else { - .bmRequestType_bit = + TU_LOG2("HID Get Report Descriptor\r\n"); + tusb_control_request_t const new_request = { - .recipient = TUSB_REQ_RCPT_INTERFACE, - .type = TUSB_REQ_TYPE_STANDARD, - .direction = TUSB_DIR_IN - }, - .bRequest = TUSB_REQ_GET_DESCRIPTOR, - .wValue = tu_u16(hid_itf->report_desc_type, 0), - .wIndex = itf_num, - .wLength = hid_itf->report_desc_len - }; + .bmRequestType_bit = + { + .recipient = TUSB_REQ_RCPT_INTERFACE, + .type = TUSB_REQ_TYPE_STANDARD, + .direction = TUSB_DIR_IN + }, + .bRequest = TUSB_REQ_GET_DESCRIPTOR, + .wValue = tu_u16(hid_itf->report_desc_type, 0), + .wIndex = itf_num, + .wLength = hid_itf->report_desc_len + }; + + TU_ASSERT(tuh_control_xfer(dev_addr, &new_request, usbh_get_enum_buf(), config_get_report_desc_complete)); + } - TU_ASSERT(tuh_control_xfer(dev_addr, &new_request, usbh_get_enum_buf(), config_get_report_desc_complete)); return true; } @@ -394,13 +404,21 @@ static bool config_get_report_desc_complete(uint8_t dev_addr, tusb_control_reque { TU_ASSERT(XFER_RESULT_SUCCESS == result); - uint8_t const itf_num = (uint8_t) request->wIndex; - uint8_t const instance = get_instance_id_by_itfnum(dev_addr, itf_num); - hidh_interface_t* hid_itf = get_instance(dev_addr, instance); + uint8_t const itf_num = (uint8_t) request->wIndex; + uint8_t const instance = get_instance_id_by_itfnum(dev_addr, itf_num); uint8_t const* desc_report = usbh_get_enum_buf(); uint16_t const desc_len = request->wLength; + config_driver_mount_complete(dev_addr, instance, desc_report, desc_len); + + return true; +} + +static void config_driver_mount_complete(uint8_t dev_addr, uint8_t instance, uint8_t const* desc_report, uint16_t desc_len) +{ + hidh_interface_t* hid_itf = get_instance(dev_addr, instance); + // enumeration is complete tuh_hid_mount_cb(dev_addr, instance, desc_report, desc_len); @@ -408,9 +426,7 @@ static bool config_get_report_desc_complete(uint8_t dev_addr, tusb_control_reque hidh_get_report(dev_addr, hid_itf); // notify usbh that driver enumeration is complete - usbh_driver_set_config_complete(dev_addr, itf_num); - - return true; + usbh_driver_set_config_complete(dev_addr, hid_itf->itf_num); } //--------------------------------------------------------------------+ diff --git a/src/class/hid/hid_host.h b/src/class/hid/hid_host.h index ef203123d..bbef05e25 100644 --- a/src/class/hid/hid_host.h +++ b/src/class/hid/hid_host.h @@ -97,6 +97,8 @@ uint8_t tuh_hid_parse_report_descriptor(tuh_hid_report_info_t* reports_info_arr, // Invoked when device with hid interface is mounted // Report descriptor is also available for use. tuh_hid_parse_report_descriptor() // can be used to parse common/simple enough descriptor. +// Note: if report descriptor length > CFG_TUH_ENUMERATION_BUFSIZE, it will be skipped +// therefore report_desc = NULL, desc_len = 0 void tuh_hid_mount_cb(uint8_t dev_addr, uint8_t instance, uint8_t const* report_desc, uint16_t desc_len); // Invoked when device with hid interface is un-mounted diff --git a/src/host/usbh.c b/src/host/usbh.c index 36c2ea7c8..979fc5065 100644 --- a/src/host/usbh.c +++ b/src/host/usbh.c @@ -892,8 +892,6 @@ static bool parse_configuration_descriptor(uint8_t dev_addr, tusb_desc_configura p_desc = tu_desc_next(p_desc); } - TU_LOG_INT(2, p_desc - (uint8_t*) desc_cfg); - TU_LOG_INT(2, tu_desc_type(p_desc)); TU_ASSERT( TUSB_DESC_INTERFACE == tu_desc_type(p_desc) ); tusb_desc_interface_t const* desc_itf = (tusb_desc_interface_t const*) p_desc; -- cgit v1.3.1 From 22a5b1608c0949d46f8e346878bff730712858e4 Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 20 Aug 2021 19:31:38 +0700 Subject: change host driver open return type to bool the descriptor len used by driver will be calculated by usbh --- src/class/cdc/cdc_host.c | 12 ++++++------ src/class/cdc/cdc_host.h | 10 +++++----- src/class/hid/hid_host.c | 20 ++++++++++---------- src/class/hid/hid_host.h | 10 +++++----- src/class/msc/msc_host.c | 10 +++++----- src/class/msc/msc_host.h | 10 +++++----- src/host/hub.c | 13 +++++++------ src/host/hub.h | 10 +++++----- src/host/usbh_classdriver.h | 10 +++++----- 9 files changed, 53 insertions(+), 52 deletions(-) (limited to 'src/class') diff --git a/src/class/cdc/cdc_host.c b/src/class/cdc/cdc_host.c index fc7100e81..35b8de3b1 100644 --- a/src/class/cdc/cdc_host.c +++ b/src/class/cdc/cdc_host.c @@ -149,7 +149,7 @@ void cdch_init(void) tu_memclr(cdch_data, sizeof(cdch_data_t)*CFG_TUSB_HOST_DEVICE_MAX); } -uint16_t 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) { (void) max_len; @@ -157,7 +157,7 @@ uint16_t cdch_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const // Protocol 0xFF can be RNDIS device for windows XP TU_VERIFY( TUSB_CLASS_CDC == itf_desc->bInterfaceClass && CDC_COMM_SUBCLASS_ABSTRACT_CONTROL_MODEL == itf_desc->bInterfaceSubClass && - 0xFF != itf_desc->bInterfaceProtocol, 0); + 0xFF != itf_desc->bInterfaceProtocol); cdch_data_t * p_cdc = get_itf(dev_addr); @@ -186,7 +186,7 @@ uint16_t cdch_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const // notification endpoint tusb_desc_endpoint_t const * desc_ep = (tusb_desc_endpoint_t const *) p_desc; - TU_ASSERT( usbh_edpt_open(rhport, dev_addr, desc_ep), 0 ); + TU_ASSERT( usbh_edpt_open(rhport, dev_addr, desc_ep) ); p_cdc->ep_notif = desc_ep->bEndpointAddress; drv_len += tu_desc_len(p_desc); @@ -205,9 +205,9 @@ uint16_t cdch_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const for(uint32_t i=0; i<2; i++) { tusb_desc_endpoint_t const *desc_ep = (tusb_desc_endpoint_t const *) p_desc; - TU_ASSERT(TUSB_DESC_ENDPOINT == desc_ep->bDescriptorType && TUSB_XFER_BULK == desc_ep->bmAttributes.xfer, 0); + TU_ASSERT(TUSB_DESC_ENDPOINT == desc_ep->bDescriptorType && TUSB_XFER_BULK == desc_ep->bmAttributes.xfer); - TU_ASSERT(usbh_edpt_open(rhport, dev_addr, desc_ep), 0); + TU_ASSERT(usbh_edpt_open(rhport, dev_addr, desc_ep)); if ( tu_edpt_dir(desc_ep->bEndpointAddress) == TUSB_DIR_IN ) { @@ -222,7 +222,7 @@ uint16_t cdch_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const } } - return drv_len; + return true; } bool cdch_set_config(uint8_t dev_addr, uint8_t itf_num) diff --git a/src/class/cdc/cdc_host.h b/src/class/cdc/cdc_host.h index edcd258a8..0d435138b 100644 --- a/src/class/cdc/cdc_host.h +++ b/src/class/cdc/cdc_host.h @@ -121,11 +121,11 @@ void tuh_cdc_xfer_isr(uint8_t dev_addr, xfer_result_t event, cdc_pipeid_t pipe_i //--------------------------------------------------------------------+ // Internal Class Driver API //--------------------------------------------------------------------+ -void cdch_init (void); -uint16_t cdch_open (uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const *itf_desc, uint16_t max_len); -bool cdch_set_config (uint8_t dev_addr, uint8_t itf_num); -bool cdch_xfer_cb (uint8_t dev_addr, uint8_t ep_addr, xfer_result_t event, uint32_t xferred_bytes); -void cdch_close (uint8_t dev_addr); +void cdch_init (void); +bool cdch_open (uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const *itf_desc, uint16_t max_len); +bool cdch_set_config (uint8_t dev_addr, uint8_t itf_num); +bool cdch_xfer_cb (uint8_t dev_addr, uint8_t ep_addr, xfer_result_t event, uint32_t xferred_bytes); +void cdch_close (uint8_t dev_addr); #ifdef __cplusplus } diff --git a/src/class/hid/hid_host.c b/src/class/hid/hid_host.c index a39ac8bec..4dd198369 100644 --- a/src/class/hid/hid_host.c +++ b/src/class/hid/hid_host.c @@ -249,19 +249,22 @@ static bool config_get_report_desc_complete (uint8_t dev_addr, tusb_control_requ static void config_driver_mount_complete(uint8_t dev_addr, uint8_t instance, uint8_t const* desc_report, uint16_t desc_len); -uint16_t 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) { (void) max_len; - TU_VERIFY(TUSB_CLASS_HID == desc_itf->bInterfaceClass, 0); + TU_VERIFY(TUSB_CLASS_HID == desc_itf->bInterfaceClass); + + // len = interface + hid + n*endpoints + uint16_t const drv_len = sizeof(tusb_desc_interface_t) + sizeof(tusb_hid_descriptor_hid_t) + desc_itf->bNumEndpoints*sizeof(tusb_desc_endpoint_t); + TU_ASSERT(max_len >= drv_len); - uint16_t drv_len = sizeof(tusb_desc_interface_t); uint8_t const *p_desc = (uint8_t const *) desc_itf; //------------- HID descriptor -------------// p_desc = tu_desc_next(p_desc); tusb_hid_descriptor_hid_t const *desc_hid = (tusb_hid_descriptor_hid_t const *) p_desc; - TU_ASSERT(HID_DESC_TYPE_HID == desc_hid->bDescriptorType, 0); + TU_ASSERT(HID_DESC_TYPE_HID == desc_hid->bDescriptorType); // not enough interface, try to increase CFG_TUH_HID // TODO multiple devices @@ -269,13 +272,12 @@ uint16_t hidh_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const TU_ASSERT(hid_dev->inst_count < CFG_TUH_HID, 0); //------------- Endpoint Descriptor -------------// - drv_len += tu_desc_len(p_desc); p_desc = tu_desc_next(p_desc); tusb_desc_endpoint_t const * desc_ep = (tusb_desc_endpoint_t const *) p_desc; - TU_ASSERT(TUSB_DESC_ENDPOINT == desc_ep->bDescriptorType, 0); + TU_ASSERT(TUSB_DESC_ENDPOINT == desc_ep->bDescriptorType); // TODO also open endpoint OUT - TU_ASSERT( usbh_edpt_open(rhport, dev_addr, desc_ep), 0 ); + TU_ASSERT( usbh_edpt_open(rhport, dev_addr, desc_ep) ); hidh_interface_t* hid_itf = get_instance(dev_addr, hid_dev->inst_count); hid_dev->inst_count++; @@ -292,9 +294,7 @@ uint16_t hidh_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const hid_itf->protocol_mode = HID_PROTOCOL_BOOT; if ( HID_SUBCLASS_BOOT == desc_itf->bInterfaceSubClass ) hid_itf->itf_protocol = desc_itf->bInterfaceProtocol; - drv_len += desc_itf->bNumEndpoints*sizeof(tusb_desc_endpoint_t); - - return drv_len; + return true; } bool hidh_set_config(uint8_t dev_addr, uint8_t itf_num) diff --git a/src/class/hid/hid_host.h b/src/class/hid/hid_host.h index bbef05e25..9a498afec 100644 --- a/src/class/hid/hid_host.h +++ b/src/class/hid/hid_host.h @@ -121,11 +121,11 @@ TU_ATTR_WEAK void tuh_hid_set_protocol_complete_cb(uint8_t dev_addr, uint8_t ins //--------------------------------------------------------------------+ // Internal Class Driver API //--------------------------------------------------------------------+ -void hidh_init (void); -uint16_t hidh_open (uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const *desc_itf, uint16_t max_len); -bool hidh_set_config (uint8_t dev_addr, uint8_t itf_num); -bool hidh_xfer_cb (uint8_t dev_addr, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes); -void hidh_close (uint8_t dev_addr); +void hidh_init (void); +bool hidh_open (uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const *desc_itf, uint16_t max_len); +bool hidh_set_config (uint8_t dev_addr, uint8_t itf_num); +bool hidh_xfer_cb (uint8_t dev_addr, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes); +void hidh_close (uint8_t dev_addr); #ifdef __cplusplus } diff --git a/src/class/msc/msc_host.c b/src/class/msc/msc_host.c index 2c027deff..f02f4550a 100644 --- a/src/class/msc/msc_host.c +++ b/src/class/msc/msc_host.c @@ -360,22 +360,22 @@ static bool config_test_unit_ready_complete(uint8_t dev_addr, msc_cbw_t const* c static bool config_request_sense_complete(uint8_t dev_addr, msc_cbw_t const* cbw, msc_csw_t const* csw); static bool config_read_capacity_complete(uint8_t dev_addr, msc_cbw_t const* cbw, msc_csw_t const* csw); -uint16_t 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) { TU_VERIFY (MSC_SUBCLASS_SCSI == desc_itf->bInterfaceSubClass && MSC_PROTOCOL_BOT == desc_itf->bInterfaceProtocol); // msc driver length is fixed uint16_t const drv_len = sizeof(tusb_desc_interface_t) + desc_itf->bNumEndpoints*sizeof(tusb_desc_endpoint_t); - TU_ASSERT(drv_len <= max_len, 0); + TU_ASSERT(drv_len <= max_len); msch_interface_t* p_msc = get_itf(dev_addr); tusb_desc_endpoint_t const * ep_desc = (tusb_desc_endpoint_t const *) tu_desc_next(desc_itf); for(uint32_t i=0; i<2; i++) { - TU_ASSERT(TUSB_DESC_ENDPOINT == ep_desc->bDescriptorType && TUSB_XFER_BULK == ep_desc->bmAttributes.xfer, 0); - TU_ASSERT(usbh_edpt_open(rhport, dev_addr, ep_desc), 0); + TU_ASSERT(TUSB_DESC_ENDPOINT == ep_desc->bDescriptorType && TUSB_XFER_BULK == ep_desc->bmAttributes.xfer); + TU_ASSERT(usbh_edpt_open(rhport, dev_addr, ep_desc)); if ( tu_edpt_dir(ep_desc->bEndpointAddress) == TUSB_DIR_IN ) { @@ -390,7 +390,7 @@ uint16_t msch_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const p_msc->itf_num = desc_itf->bInterfaceNumber; - return drv_len; + return true; } bool msch_set_config(uint8_t dev_addr, uint8_t itf_num) diff --git a/src/class/msc/msc_host.h b/src/class/msc/msc_host.h index 9e4217ba5..7718ad4fe 100644 --- a/src/class/msc/msc_host.h +++ b/src/class/msc/msc_host.h @@ -106,11 +106,11 @@ TU_ATTR_WEAK void tuh_msc_umount_cb(uint8_t dev_addr); // Internal Class Driver API //--------------------------------------------------------------------+ -void msch_init (void); -uint16_t 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_xfer_cb (uint8_t dev_addr, uint8_t ep_addr, xfer_result_t event, uint32_t xferred_bytes); -void msch_close (uint8_t dev_addr); +void msch_init (void); +bool msch_open (uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const *desc_itf, uint16_t max_len); +bool msch_set_config (uint8_t dev_addr, uint8_t itf_num); +void msch_close (uint8_t dev_addr); +bool msch_xfer_cb (uint8_t dev_addr, uint8_t ep_addr, xfer_result_t event, uint32_t xferred_bytes); #ifdef __cplusplus } diff --git a/src/host/hub.c b/src/host/hub.c index 2ead5bed1..00dce4e65 100644 --- a/src/host/hub.c +++ b/src/host/hub.c @@ -147,16 +147,17 @@ void hub_init(void) tu_memclr(hub_data, CFG_TUSB_HOST_DEVICE_MAX*sizeof(hub_interface_t)); } -uint16_t 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) { - // hub driver does not support multiple TT yet TU_VERIFY(TUSB_CLASS_HUB == itf_desc->bInterfaceClass && - 0 == itf_desc->bInterfaceSubClass && - 1 <= itf_desc->bInterfaceProtocol, 0); + 0 == itf_desc->bInterfaceSubClass); + + // hub driver does not support multiple TT yet + TU_VERIFY(itf_desc->bInterfaceProtocol <= 1); // msc driver length is fixed uint16_t const drv_len = sizeof(tusb_desc_interface_t) + sizeof(tusb_desc_endpoint_t); - TU_ASSERT(drv_len <= max_len, 0); + TU_ASSERT(drv_len <= max_len); //------------- Interrupt Status endpoint -------------// tusb_desc_endpoint_t const *desc_ep = (tusb_desc_endpoint_t const *) tu_desc_next(itf_desc); @@ -169,7 +170,7 @@ uint16_t hub_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const hub_data[dev_addr-1].itf_num = itf_desc->bInterfaceNumber; hub_data[dev_addr-1].ep_in = desc_ep->bEndpointAddress; - return drv_len; + return true; } void hub_close(uint8_t dev_addr) diff --git a/src/host/hub.h b/src/host/hub.h index c9ffe4985..c4d544193 100644 --- a/src/host/hub.h +++ b/src/host/hub.h @@ -181,11 +181,11 @@ bool hub_status_pipe_queue(uint8_t dev_addr); //--------------------------------------------------------------------+ // Internal Class Driver API //--------------------------------------------------------------------+ -void hub_init (void); -uint16_t hub_open (uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const *itf_desc, uint16_t max_len); -bool hub_set_config (uint8_t dev_addr, uint8_t itf_num); -bool hub_xfer_cb (uint8_t dev_addr, uint8_t ep_addr, xfer_result_t event, uint32_t xferred_bytes); -void hub_close (uint8_t dev_addr); +void hub_init (void); +bool hub_open (uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const *itf_desc, uint16_t max_len); +bool hub_set_config (uint8_t dev_addr, uint8_t itf_num); +bool hub_xfer_cb (uint8_t dev_addr, uint8_t ep_addr, xfer_result_t event, uint32_t xferred_bytes); +void hub_close (uint8_t dev_addr); #ifdef __cplusplus } diff --git a/src/host/usbh_classdriver.h b/src/host/usbh_classdriver.h index fccb30253..8bc2622aa 100644 --- a/src/host/usbh_classdriver.h +++ b/src/host/usbh_classdriver.h @@ -43,11 +43,11 @@ typedef struct { char const* name; #endif - void (* const init )(void); - uint16_t (* const open )(uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const * itf_desc, uint16_t max_len); - bool (* const set_config )(uint8_t dev_addr, uint8_t itf_num); - bool (* const xfer_cb )(uint8_t dev_addr, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes); - void (* const close )(uint8_t dev_addr); + void (* const init )(void); + bool (* const open )(uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const * itf_desc, uint16_t max_len); + bool (* const set_config )(uint8_t dev_addr, uint8_t itf_num); + bool (* const xfer_cb )(uint8_t dev_addr, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes); + void (* const close )(uint8_t dev_addr); } usbh_class_driver_t; // Call by class driver to tell USBH that it has complete the enumeration -- cgit v1.3.1 From 4941cde175af2ef21bbe24d7d3271b46363c0759 Mon Sep 17 00:00:00 2001 From: MasterPhi Date: Sun, 22 Aug 2021 13:26:50 +0200 Subject: Fix vendor fifo deadlock, add tud_vendor_n_read_flush --- src/class/vendor/vendor_device.c | 9 +++++++++ src/class/vendor/vendor_device.h | 7 +++++++ 2 files changed, 16 insertions(+) (limited to 'src/class') diff --git a/src/class/vendor/vendor_device.c b/src/class/vendor/vendor_device.c index 6718a97bf..8c59b4ea7 100644 --- a/src/class/vendor/vendor_device.c +++ b/src/class/vendor/vendor_device.c @@ -103,6 +103,13 @@ uint32_t tud_vendor_n_read (uint8_t itf, void* buffer, uint32_t bufsize) return num_read; } +void tud_vendor_n_read_flush (uint8_t itf) +{ + vendord_interface_t* p_itf = &_vendord_itf[itf]; + tu_fifo_clear(&p_itf->rx_ff); + _prep_out_transaction(p_itf); +} + //--------------------------------------------------------------------+ // Write API //--------------------------------------------------------------------+ @@ -199,6 +206,8 @@ uint16_t vendord_open(uint8_t rhport, tusb_desc_interface_t const * itf_desc, ui TU_BREAKPOINT(); } + maybe_transmit(p_vendor); + return drv_len; } diff --git a/src/class/vendor/vendor_device.h b/src/class/vendor/vendor_device.h index 6d9c784c0..844693c68 100644 --- a/src/class/vendor/vendor_device.h +++ b/src/class/vendor/vendor_device.h @@ -45,6 +45,7 @@ bool tud_vendor_n_mounted (uint8_t itf); uint32_t tud_vendor_n_available (uint8_t itf); uint32_t tud_vendor_n_read (uint8_t itf, void* buffer, uint32_t bufsize); bool tud_vendor_n_peek (uint8_t itf, uint8_t* u8); +void tud_vendor_n_read_flush (uint8_t itf); uint32_t tud_vendor_n_write (uint8_t itf, void const* buffer, uint32_t bufsize); uint32_t tud_vendor_n_write_available (uint8_t itf); @@ -59,6 +60,7 @@ static inline bool tud_vendor_mounted (void); static inline uint32_t tud_vendor_available (void); static inline uint32_t tud_vendor_read (void* buffer, uint32_t bufsize); static inline bool tud_vendor_peek (uint8_t* u8); +static inline void tud_vendor_read_flush (void); static inline uint32_t tud_vendor_write (void const* buffer, uint32_t bufsize); static inline uint32_t tud_vendor_write_str (char const* str); static inline uint32_t tud_vendor_write_available (void); @@ -99,6 +101,11 @@ static inline bool tud_vendor_peek (uint8_t* u8) return tud_vendor_n_peek(0, u8); } +static inline void tud_vendor_read_flush(void) +{ + tud_vendor_n_read_flush(0); +} + static inline uint32_t tud_vendor_write (void const* buffer, uint32_t bufsize) { return tud_vendor_n_write(0, buffer, bufsize); -- cgit v1.3.1 From 800f85329ea21bdefc778c246c8098dea12fb402 Mon Sep 17 00:00:00 2001 From: hathach Date: Mon, 23 Aug 2021 11:00:21 +0700 Subject: add tuh_hid_receive_report() for applicaiton to explicitly request report --- examples/host/cdc_msc_hid/src/hid_app.c | 13 ++++++++++ examples/host/cdc_msc_hid/src/main.c | 29 ++------------------- examples/host/cdc_msc_hid/src/tusb_config.h | 6 ++--- src/class/hid/hid_host.c | 39 ++++++++++++++++++----------- src/class/hid/hid_host.h | 30 +++++++++++++++++----- src/host/usbh.c | 8 +++--- src/tusb.c | 3 ++- 7 files changed, 73 insertions(+), 55 deletions(-) (limited to 'src/class') diff --git a/examples/host/cdc_msc_hid/src/hid_app.c b/examples/host/cdc_msc_hid/src/hid_app.c index 5e3ac6a72..11437c2b4 100644 --- a/examples/host/cdc_msc_hid/src/hid_app.c +++ b/examples/host/cdc_msc_hid/src/hid_app.c @@ -80,6 +80,13 @@ void tuh_hid_mount_cb(uint8_t dev_addr, uint8_t instance, uint8_t const* desc_re hid_info[instance].report_count = tuh_hid_parse_report_descriptor(hid_info[instance].report_info, MAX_REPORT, desc_report, desc_len); printf("HID has %u reports \r\n", hid_info[instance].report_count); } + + // request to receive report + // tuh_hid_report_received_cb() will be invoked when report is available + if ( !tuh_hid_receive_report(dev_addr, instance) ) + { + printf("Error: cannot request to receive report\r\n"); + } } // Invoked when device with hid interface is un-mounted @@ -110,6 +117,12 @@ void tuh_hid_report_received_cb(uint8_t dev_addr, uint8_t instance, uint8_t cons process_generic_report(dev_addr, instance, report, len); break; } + + // continue to request to receive report + if ( !tuh_hid_receive_report(dev_addr, instance) ) + { + printf("Error: cannot request to receive report\r\n"); + } } //--------------------------------------------------------------------+ diff --git a/examples/host/cdc_msc_hid/src/main.c b/examples/host/cdc_msc_hid/src/main.c index 7ae814e38..a14be05ea 100644 --- a/examples/host/cdc_msc_hid/src/main.c +++ b/examples/host/cdc_msc_hid/src/main.c @@ -33,7 +33,6 @@ //--------------------------------------------------------------------+ // MACRO CONSTANT TYPEDEF PROTYPES //--------------------------------------------------------------------+ -void print_greeting(void); void led_blinking_task(void); extern void cdc_task(void); @@ -43,7 +42,8 @@ extern void hid_app_task(void); int main(void) { board_init(); - print_greeting(); + + printf("TinyUSB Host CDC MSC HID Example\r\n"); tusb_init(); @@ -126,28 +126,3 @@ void led_blinking_task(void) board_led_write(led_state); led_state = 1 - led_state; // toggle } - -//--------------------------------------------------------------------+ -// HELPER FUNCTION -//--------------------------------------------------------------------+ -void print_greeting(void) -{ - char const * const rtos_name[] = - { - [OPT_OS_NONE] = "None", - [OPT_OS_FREERTOS] = "FreeRTOS", - [OPT_OS_MYNEWT] = "Mynewt OS", - [OPT_OS_CUSTOM] = "Custom OS implemnted by application", - [OPT_OS_PICO] = "Raspberry Pi Pico SDK", - [OPT_OS_RTTHREAD] = "RT-Thread" - }; - - printf("----------------------------------------------------\r\n"); - printf("TinyUSB Host Example\r\n"); - printf("If you find any bugs or problems, feel free to open\r\n"); - printf("an issue at https://github.com/hathach/tinyusb\r\n"); - printf("----------------------------------------------------\r\n\r\n"); - - printf("This Host demo is configured to support:\r\n"); - printf(" - RTOS = %s\r\n", rtos_name[CFG_TUSB_OS]); -} diff --git a/examples/host/cdc_msc_hid/src/tusb_config.h b/examples/host/cdc_msc_hid/src/tusb_config.h index b574acf9b..80f07f446 100644 --- a/examples/host/cdc_msc_hid/src/tusb_config.h +++ b/examples/host/cdc_msc_hid/src/tusb_config.h @@ -76,15 +76,15 @@ #define CFG_TUH_HUB 1 #define CFG_TUH_CDC 1 -#define CFG_TUH_HID 4 +#define CFG_TUH_HID 4 // typical keyboard + mouse device can have 3-4 HID interfaces #define CFG_TUH_MSC 1 #define CFG_TUH_VENDOR 0 #define CFG_TUSB_HOST_DEVICE_MAX (CFG_TUH_HUB ? 5 : 1) // normal hub has 4 ports //------------- HID -------------// - -#define CFG_TUH_HID_EP_BUFSIZE 64 +#define CFG_TUH_HID_EPIN_BUFSIZE 64 +#define CFG_TUH_HID_EPOUT_BUFSIZE 64 #ifdef __cplusplus } diff --git a/src/class/hid/hid_host.c b/src/class/hid/hid_host.c index 4dd198369..2d76df588 100644 --- a/src/class/hid/hid_host.c +++ b/src/class/hid/hid_host.c @@ -52,8 +52,8 @@ typedef struct uint16_t epin_size; uint16_t epout_size; - uint8_t epin_buf[CFG_TUH_HID_EP_BUFSIZE]; - uint8_t epout_buf[CFG_TUH_HID_EP_BUFSIZE]; + uint8_t epin_buf[CFG_TUH_HID_EPIN_BUFSIZE]; + uint8_t epout_buf[CFG_TUH_HID_EPOUT_BUFSIZE]; } hidh_interface_t; typedef struct @@ -72,13 +72,8 @@ TU_ATTR_ALWAYS_INLINE static inline hidh_interface_t* get_instance(uint8_t dev_a static uint8_t get_instance_id_by_itfnum(uint8_t dev_addr, uint8_t itf); static uint8_t get_instance_id_by_epaddr(uint8_t dev_addr, uint8_t ep_addr); -TU_ATTR_ALWAYS_INLINE static inline bool hidh_get_report(uint8_t dev_addr, hidh_interface_t* hid_itf) -{ - return usbh_edpt_xfer(dev_addr, hid_itf->ep_in, hid_itf->epin_buf, hid_itf->epin_size); -} - //--------------------------------------------------------------------+ -// Application API +// Interface API //--------------------------------------------------------------------+ uint8_t tuh_hid_instance_count(uint8_t dev_addr) @@ -98,6 +93,10 @@ uint8_t tuh_hid_interface_protocol(uint8_t dev_addr, uint8_t instance) return hid_itf->itf_protocol; } +//--------------------------------------------------------------------+ +// Control Endpoint API +//--------------------------------------------------------------------+ + uint8_t tuh_hid_get_protocol(uint8_t dev_addr, uint8_t instance) { hidh_interface_t* hid_itf = get_instance(dev_addr, instance); @@ -186,6 +185,20 @@ bool tuh_hid_set_report(uint8_t dev_addr, uint8_t instance, uint8_t report_id, u return true; } +//--------------------------------------------------------------------+ +// Interrupt Endpoint API +//--------------------------------------------------------------------+ + +bool tuh_hid_receive_report(uint8_t dev_addr, uint8_t instance) +{ + hidh_interface_t* hid_itf = get_instance(dev_addr, instance); + + // claim endpoint + TU_VERIFY( usbh_edpt_claim(dev_addr, hid_itf->ep_in) ); + + return usbh_edpt_xfer(dev_addr, hid_itf->ep_in, hid_itf->epin_buf, hid_itf->epin_size); +} + //bool tuh_n_hid_n_ready(uint8_t dev_addr, uint8_t instance) //{ // TU_VERIFY(tuh_n_hid_n_mounted(dev_addr, instance)); @@ -217,9 +230,6 @@ bool hidh_xfer_cb(uint8_t dev_addr, uint8_t ep_addr, xfer_result_t result, uint3 TU_LOG2(" Get Report callback (%u, %u)\r\n", dev_addr, instance); TU_LOG1_MEM(hid_itf->epin_buf, 8, 2); tuh_hid_report_received_cb(dev_addr, instance, hid_itf->epin_buf, xferred_bytes); - - // queue next report - hidh_get_report(dev_addr, hid_itf); }else { if (tuh_hid_report_sent_cb) tuh_hid_report_sent_cb(dev_addr, instance, hid_itf->epout_buf, xferred_bytes); @@ -255,6 +265,8 @@ bool hidh_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const *de TU_VERIFY(TUSB_CLASS_HID == desc_itf->bInterfaceClass); + TU_LOG2("HID opening Interface %u (addr = %u)\r\n", desc_itf->bInterfaceNumber, dev_addr); + // len = interface + hid + n*endpoints uint16_t const drv_len = sizeof(tusb_desc_interface_t) + sizeof(tusb_hid_descriptor_hid_t) + desc_itf->bNumEndpoints*sizeof(tusb_desc_endpoint_t); TU_ASSERT(max_len >= drv_len); @@ -336,7 +348,7 @@ static bool config_set_protocol(uint8_t dev_addr, tusb_control_request_t const * uint8_t const instance = get_instance_id_by_itfnum(dev_addr, itf_num); hidh_interface_t* hid_itf = get_instance(dev_addr, instance); - TU_LOG2("HID Set Protocol\r\n"); + TU_LOG2("HID Set Protocol to Boot Mode\r\n"); hid_itf->protocol_mode = HID_PROTOCOL_BOOT; tusb_control_request_t const new_request = { @@ -422,9 +434,6 @@ static void config_driver_mount_complete(uint8_t dev_addr, uint8_t instance, uin // enumeration is complete tuh_hid_mount_cb(dev_addr, instance, desc_report, desc_len); - // queue transfer for IN endpoint - hidh_get_report(dev_addr, hid_itf); - // notify usbh that driver enumeration is complete usbh_driver_set_config_complete(dev_addr, hid_itf->itf_num); } diff --git a/src/class/hid/hid_host.h b/src/class/hid/hid_host.h index 9a498afec..fe09b03b2 100644 --- a/src/class/hid/hid_host.h +++ b/src/class/hid/hid_host.h @@ -38,10 +38,15 @@ //--------------------------------------------------------------------+ // TODO Highspeed interrupt can be up to 512 bytes -#ifndef CFG_TUH_HID_EP_BUFSIZE -#define CFG_TUH_HID_EP_BUFSIZE 64 +#ifndef CFG_TUH_HID_EPIN_BUFSIZE +#define CFG_TUH_HID_EPIN_BUFSIZE 64 #endif +#ifndef CFG_TUH_HID_EPOUT_BUFSIZE +#define CFG_TUH_HID_EPOUT_BUFSIZE 64 +#endif + + typedef struct { uint8_t report_id; @@ -54,7 +59,7 @@ typedef struct } tuh_hid_report_info_t; //--------------------------------------------------------------------+ -// Application API +// Interface API //--------------------------------------------------------------------+ // Get the number of HID instances @@ -66,6 +71,14 @@ bool tuh_hid_mounted(uint8_t dev_addr, uint8_t instance); // Get interface supported protocol (bInterfaceProtocol) check out hid_interface_protocol_enum_t for possible values uint8_t tuh_hid_interface_protocol(uint8_t dev_addr, uint8_t instance); +// Parse report descriptor into array of report_info struct and return number of reports. +// For complicated report, application should write its own parser. +uint8_t tuh_hid_parse_report_descriptor(tuh_hid_report_info_t* reports_info_arr, uint8_t arr_count, uint8_t const* desc_report, uint16_t desc_len) TU_ATTR_UNUSED; + +//--------------------------------------------------------------------+ +// Control Endpoint API +//--------------------------------------------------------------------+ + // Get current protocol: HID_PROTOCOL_BOOT (0) or HID_PROTOCOL_REPORT (1) // Note: Device will be initialized in Boot protocol for simplicity. // Application can use set_protocol() to switch back to Report protocol. @@ -79,13 +92,18 @@ bool tuh_hid_set_protocol(uint8_t dev_addr, uint8_t instance, uint8_t protocol); // report_type is either Intput, Output or Feature, (value from hid_report_type_t) bool tuh_hid_set_report(uint8_t dev_addr, uint8_t instance, uint8_t report_id, uint8_t report_type, void* report, uint16_t len); -// Parse report descriptor into array of report_info struct and return number of reports. -// For complicated report, application should write its own parser. -uint8_t tuh_hid_parse_report_descriptor(tuh_hid_report_info_t* reports_info_arr, uint8_t arr_count, uint8_t const* desc_report, uint16_t desc_len) TU_ATTR_UNUSED; +//--------------------------------------------------------------------+ +// Interrupt Endpoint API +//--------------------------------------------------------------------+ // Check if the interface is ready to use //bool tuh_n_hid_n_ready(uint8_t dev_addr, uint8_t instance); +// Try to receive next report on Interrupt Endpoint. Immediately return +// - true If succeeded, tuh_hid_report_received_cb() callback will be invoked when report is available +// - false if failed to queue the transfer e.g endpoint is busy +bool tuh_hid_receive_report(uint8_t dev_addr, uint8_t instance); + // Send report using interrupt endpoint // If report_id > 0 (composite), it will be sent as 1st byte, then report contents. Otherwise only report content is sent. //void tuh_hid_send_report(uint8_t dev_addr, uint8_t instance, uint8_t report_id, uint8_t const* report, uint16_t len); diff --git a/src/host/usbh.c b/src/host/usbh.c index 662ce2673..40c23a69d 100644 --- a/src/host/usbh.c +++ b/src/host/usbh.c @@ -186,7 +186,7 @@ bool tuh_init(uint8_t rhport) TU_LOG2("USBH init\r\n"); - tu_memclr(_usbh_devices, sizeof(usbh_device_t)*(CFG_TUSB_HOST_DEVICE_MAX+1)); + tu_memclr(_usbh_devices, sizeof(_usbh_devices)); //------------- Enumeration & Reporter Task init -------------// _usbh_q = osal_queue_create( &_usbh_qdef ); @@ -436,6 +436,7 @@ void usbh_driver_set_config_complete(uint8_t dev_addr, uint8_t itf_num) for(itf_num++; itf_num < sizeof(dev->itf2drv); itf_num++) { // continue with next valid interface + // TODO skip IAD binding interface such as CDCs uint8_t const drv_id = dev->itf2drv[itf_num]; if (drv_id != DRVID_INVALID) { @@ -474,6 +475,7 @@ static bool enum_get_config_desc_complete (uint8_t dev_addr, tusb_control_ static bool enum_set_config_complete (uint8_t dev_addr, tusb_control_request_t const * request, xfer_result_t result); static bool parse_configuration_descriptor (uint8_t dev_addr, tusb_desc_configuration_t const* desc_cfg); +#if CFG_TUH_HUB static bool enum_hub_clear_reset0_complete(uint8_t dev_addr, tusb_control_request_t const * request, xfer_result_t result) { (void) dev_addr; (void) request; @@ -540,7 +542,7 @@ static bool enum_hub_get_status0_complete(uint8_t dev_addr, tusb_control_request return true; } - +#endif static bool enum_request_set_addr(void) { @@ -889,7 +891,7 @@ static bool parse_configuration_descriptor(uint8_t dev_addr, tusb_desc_configura if ( driver->open(dev->rhport, dev_addr, desc_itf, drv_len) ) { // open successfully - TU_LOG2("%s opened\r\n", driver->name); + TU_LOG2(" Opened successfully\r\n"); // bind interface to found driver dev->itf2drv[desc_itf->bInterfaceNumber] = drv_id; diff --git a/src/tusb.c b/src/tusb.c index 1fc775399..6494287d2 100644 --- a/src/tusb.c +++ b/src/tusb.c @@ -117,10 +117,11 @@ void tu_edpt_bind_driver(uint8_t ep2drv[][2], tusb_desc_interface_t const* desc_ { 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); ep2drv[tu_edpt_number(ep_addr)][tu_edpt_dir(ep_addr)] = driver_id; } - len = (uint16_t)(len + tu_desc_len(p_desc)); + len = (uint16_t)(len + tu_desc_len(p_desc)); p_desc = tu_desc_next(p_desc); } } -- cgit v1.3.1 From 6a16f6ccddf77e1b0232aec0c89d2105e391b297 Mon Sep 17 00:00:00 2001 From: hathach Date: Mon, 23 Aug 2021 11:01:40 +0700 Subject: rename CFG_TUSB_HOST_DEVICE_MAX to CFG_TUH_DEVICE_MAX --- examples/host/cdc_msc_hid/src/msc_app.c | 2 +- examples/host/cdc_msc_hid/src/tusb_config.h | 2 +- lib/fatfs/diskio.c | 4 ++-- lib/fatfs/diskio.h | 2 +- lib/fatfs/ffconf.h | 2 +- src/class/cdc/cdc_host.c | 4 ++-- src/class/cdc/cdc_rndis_host.c | 10 +++++----- src/class/hid/hid_host.c | 2 +- src/class/msc/msc_host.c | 4 ++-- src/class/vendor/vendor_host.c | 4 ++-- src/host/hcd.h | 2 +- src/host/hub.c | 4 ++-- src/host/usbh.c | 14 +++++++------- src/host/usbh_hcd.h | 2 +- src/portable/ehci/ehci.c | 4 ++-- src/portable/ohci/ohci.h | 2 +- src/tusb_option.h | 10 +++++----- 17 files changed, 37 insertions(+), 37 deletions(-) (limited to 'src/class') diff --git a/examples/host/cdc_msc_hid/src/msc_app.c b/examples/host/cdc_msc_hid/src/msc_app.c index 3657a3d35..77a72052d 100644 --- a/examples/host/cdc_msc_hid/src/msc_app.c +++ b/examples/host/cdc_msc_hid/src/msc_app.c @@ -92,7 +92,7 @@ void tuh_msc_umount_cb(uint8_t dev_addr) // // if ( phy_disk == f_get_current_drive() ) // { // active drive is unplugged --> change to other drive -// for(uint8_t i=0; i 1 && period_1ms_addr == tu_align32(next_item.address)) && - max_loop < (HCD_MAX_ENDPOINT + EHCI_MAX_ITD + EHCI_MAX_SITD)*CFG_TUSB_HOST_DEVICE_MAX) + max_loop < (HCD_MAX_ENDPOINT + EHCI_MAX_ITD + EHCI_MAX_SITD)*CFG_TUH_DEVICE_MAX) { switch ( next_item.type ) { diff --git a/src/portable/ohci/ohci.h b/src/portable/ohci/ohci.h index 6a634592a..cd90aa45a 100644 --- a/src/portable/ohci/ohci.h +++ b/src/portable/ohci/ohci.h @@ -159,7 +159,7 @@ typedef struct TU_ATTR_ALIGNED(256) struct { ohci_ed_t ed; ohci_gtd_t gtd; - }control[CFG_TUSB_HOST_DEVICE_MAX+1]; + }control[CFG_TUH_DEVICE_MAX+1]; // ochi_itd_t itd[OHCI_MAX_ITD]; // itd requires alignment of 32 ohci_ed_t ed_pool[HCD_MAX_ENDPOINT]; diff --git a/src/tusb_option.h b/src/tusb_option.h index e189c65bb..bbbf10a84 100644 --- a/src/tusb_option.h +++ b/src/tusb_option.h @@ -266,14 +266,14 @@ // HOST OPTIONS //-------------------------------------------------------------------- #if TUSB_OPT_HOST_ENABLED - #ifndef CFG_TUSB_HOST_DEVICE_MAX - #define CFG_TUSB_HOST_DEVICE_MAX 1 - #warning CFG_TUSB_HOST_DEVICE_MAX is not defined, default value is 1 + #ifndef CFG_TUH_DEVICE_MAX + #define CFG_TUH_DEVICE_MAX 1 + #warning CFG_TUH_DEVICE_MAX is not defined, default value is 1 #endif //------------- HUB CLASS -------------// - #if CFG_TUH_HUB && (CFG_TUSB_HOST_DEVICE_MAX == 1) - #error There is no benefit enable hub with max device is 1. Please disable hub or increase CFG_TUSB_HOST_DEVICE_MAX + #if CFG_TUH_HUB && (CFG_TUH_DEVICE_MAX == 1) + #error There is no benefit enable hub with max device is 1. Please disable hub or increase CFG_TUH_DEVICE_MAX #endif #ifndef CFG_TUH_ENUMERATION_BUFSIZE -- cgit v1.3.1 From 3309425211639121ce72784405106ab22c4a426e Mon Sep 17 00:00:00 2001 From: hathach Date: Mon, 23 Aug 2021 19:56:53 +0700 Subject: sepearate CFG_TUH_DEVICE_MAX and CFG_TUH_HUB separate dev0 from _usbh_devices pool to save sram --- examples/host/cdc_msc_hid/src/tusb_config.h | 3 +- src/class/cdc/cdc_host.c | 2 + src/class/hid/hid_host.c | 4 +- src/class/msc/msc_host.c | 5 +- src/host/hub.c | 36 ++++++---- src/host/usbh.c | 104 +++++++++++++++------------- src/portable/ehci/ehci.c | 2 +- 7 files changed, 93 insertions(+), 63 deletions(-) (limited to 'src/class') diff --git a/examples/host/cdc_msc_hid/src/tusb_config.h b/examples/host/cdc_msc_hid/src/tusb_config.h index e2eb566bd..bc6c68e5b 100644 --- a/examples/host/cdc_msc_hid/src/tusb_config.h +++ b/examples/host/cdc_msc_hid/src/tusb_config.h @@ -80,7 +80,8 @@ #define CFG_TUH_MSC 1 #define CFG_TUH_VENDOR 0 -#define CFG_TUH_DEVICE_MAX (CFG_TUH_HUB ? 5 : 1) // normal hub has 4 ports +// max device support (excluding hub device) +#define CFG_TUH_DEVICE_MAX (CFG_TUH_HUB ? 4 : 1) // hub typically has 4 ports //------------- HID -------------// #define CFG_TUH_HID_EPIN_BUFSIZE 64 diff --git a/src/class/cdc/cdc_host.c b/src/class/cdc/cdc_host.c index e14cb0bab..08b9bab99 100644 --- a/src/class/cdc/cdc_host.c +++ b/src/class/cdc/cdc_host.c @@ -240,6 +240,8 @@ bool cdch_xfer_cb(uint8_t dev_addr, uint8_t ep_addr, xfer_result_t event, uint32 void cdch_close(uint8_t dev_addr) { + TU_VERIFY(dev_addr <= CFG_TUH_DEVICE_MAX, ); + cdch_data_t * p_cdc = get_itf(dev_addr); tu_memclr(p_cdc, sizeof(cdch_data_t)); } diff --git a/src/class/hid/hid_host.c b/src/class/hid/hid_host.c index 915f0b21a..a9ea03de6 100644 --- a/src/class/hid/hid_host.c +++ b/src/class/hid/hid_host.c @@ -62,7 +62,7 @@ typedef struct hidh_interface_t instances[CFG_TUH_HID]; } hidh_device_t; -static hidh_device_t _hidh_dev[CFG_TUH_DEVICE_MAX-1]; +static hidh_device_t _hidh_dev[CFG_TUH_DEVICE_MAX]; //------------- Internal prototypes -------------// @@ -240,6 +240,8 @@ bool hidh_xfer_cb(uint8_t dev_addr, uint8_t ep_addr, xfer_result_t result, uint3 void hidh_close(uint8_t dev_addr) { + TU_VERIFY(dev_addr <= CFG_TUH_DEVICE_MAX, ); + hidh_device_t* hid_dev = get_dev(dev_addr); if (tuh_hid_umount_cb) { diff --git a/src/class/msc/msc_host.c b/src/class/msc/msc_host.c index c7669aa21..8069353cd 100644 --- a/src/class/msc/msc_host.c +++ b/src/class/msc/msc_host.c @@ -76,6 +76,7 @@ CFG_TUSB_MEM_SECTION static msch_interface_t _msch_itf[CFG_TUH_DEVICE_MAX]; CFG_TUSB_MEM_SECTION TU_ATTR_ALIGNED(4) static uint8_t _msch_buffer[sizeof(scsi_inquiry_resp_t)]; +TU_ATTR_ALWAYS_INLINE static inline msch_interface_t* get_itf(uint8_t dev_addr) { return &_msch_itf[dev_addr-1]; @@ -291,11 +292,13 @@ bool tuh_msc_reset(uint8_t dev_addr) //--------------------------------------------------------------------+ void msch_init(void) { - tu_memclr(_msch_itf, sizeof(msch_interface_t)*CFG_TUH_DEVICE_MAX); + tu_memclr(_msch_itf, sizeof(_msch_itf)); } void msch_close(uint8_t dev_addr) { + TU_VERIFY(dev_addr <= CFG_TUH_DEVICE_MAX, ); + msch_interface_t* p_msc = get_itf(dev_addr); // invoke Application Callback diff --git a/src/host/hub.c b/src/host/hub.c index 65e747e41..fd4dbd04a 100644 --- a/src/host/hub.c +++ b/src/host/hub.c @@ -48,6 +48,12 @@ typedef struct CFG_TUSB_MEM_SECTION static hub_interface_t hub_data[CFG_TUH_HUB]; CFG_TUSB_MEM_SECTION TU_ATTR_ALIGNED(4) static uint8_t _hub_buffer[sizeof(descriptor_hub_desc_t)]; +TU_ATTR_ALWAYS_INLINE +static inline hub_interface_t* get_itf(uint8_t dev_addr) +{ + return &hub_data[dev_addr-1-CFG_TUH_DEVICE_MAX]; +} + #if CFG_TUSB_DEBUG static char const* const _hub_feature_str[] = { @@ -167,21 +173,26 @@ bool hub_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const *itf TU_ASSERT(usbh_edpt_open(rhport, dev_addr, desc_ep)); - hub_data[dev_addr-1].itf_num = itf_desc->bInterfaceNumber; - hub_data[dev_addr-1].ep_in = desc_ep->bEndpointAddress; + hub_interface_t* p_hub = get_itf(dev_addr); + + p_hub->itf_num = itf_desc->bInterfaceNumber; + p_hub->ep_in = desc_ep->bEndpointAddress; return true; } void hub_close(uint8_t dev_addr) { - tu_memclr(&hub_data[dev_addr-1], sizeof( hub_interface_t)); + TU_VERIFY(dev_addr > CFG_TUH_DEVICE_MAX, ); + hub_interface_t* p_hub = get_itf(dev_addr); + + if (p_hub->ep_in) tu_memclr(p_hub, sizeof( hub_interface_t)); } bool hub_status_pipe_queue(uint8_t dev_addr) { - hub_interface_t * p_hub = &hub_data[dev_addr-1]; - return usbh_edpt_xfer(dev_addr, p_hub->ep_in, &p_hub->status_change, 1); + hub_interface_t* hub_itf = get_itf(dev_addr); + return usbh_edpt_xfer(dev_addr, hub_itf->ep_in, &hub_itf->status_change, 1); } @@ -194,7 +205,7 @@ static bool config_port_power_complete (uint8_t dev_addr, tusb_control_request_t bool hub_set_config(uint8_t dev_addr, uint8_t itf_num) { - hub_interface_t* p_hub = &hub_data[dev_addr-1]; + hub_interface_t* p_hub = get_itf(dev_addr); TU_ASSERT(itf_num == p_hub->itf_num); // Get Hub Descriptor @@ -222,7 +233,7 @@ static bool config_set_port_power (uint8_t dev_addr, tusb_control_request_t cons (void) request; TU_ASSERT(XFER_RESULT_SUCCESS == result); - hub_interface_t* p_hub = &hub_data[dev_addr-1]; + hub_interface_t* p_hub = get_itf(dev_addr); // only use number of ports in hub descriptor descriptor_hub_desc_t const* desc_hub = (descriptor_hub_desc_t const*) _hub_buffer; @@ -238,7 +249,7 @@ static bool config_set_port_power (uint8_t dev_addr, tusb_control_request_t cons static bool config_port_power_complete (uint8_t dev_addr, tusb_control_request_t const * request, xfer_result_t result) { TU_ASSERT(XFER_RESULT_SUCCESS == result); - hub_interface_t* p_hub = &hub_data[dev_addr-1]; + hub_interface_t* p_hub = get_itf(dev_addr); if (request->wIndex == p_hub->port_count) { @@ -272,7 +283,7 @@ bool hub_xfer_cb(uint8_t dev_addr, uint8_t ep_addr, xfer_result_t result, uint32 (void) ep_addr; TU_ASSERT(result == XFER_RESULT_SUCCESS); - hub_interface_t * p_hub = &hub_data[dev_addr-1]; + hub_interface_t* p_hub = get_itf(dev_addr); TU_LOG2(" Port Status Change = 0x%02X\r\n", p_hub->status_change); @@ -294,7 +305,8 @@ bool hub_xfer_cb(uint8_t dev_addr, uint8_t ep_addr, xfer_result_t result, uint32 static bool connection_get_status_complete (uint8_t dev_addr, tusb_control_request_t const * request, xfer_result_t result) { TU_ASSERT(result == XFER_RESULT_SUCCESS); - hub_interface_t * p_hub = &hub_data[dev_addr-1]; + + hub_interface_t* p_hub = get_itf(dev_addr); uint8_t const port_num = (uint8_t) request->wIndex; // Connection change @@ -322,7 +334,7 @@ static bool connection_clear_conn_change_complete (uint8_t dev_addr, tusb_contro { TU_ASSERT(result == XFER_RESULT_SUCCESS); - hub_interface_t * p_hub = &hub_data[dev_addr-1]; + hub_interface_t* p_hub = get_itf(dev_addr); uint8_t const port_num = (uint8_t) request->wIndex; if ( p_hub->port_status.status.connection ) @@ -353,7 +365,7 @@ static bool connection_port_reset_complete (uint8_t dev_addr, tusb_control_reque { TU_ASSERT(result == XFER_RESULT_SUCCESS); - // usbh_hub_t * p_hub = &hub_data[dev_addr-1]; + // hub_interface_t* p_hub = get_itf(dev_addr); uint8_t const port_num = (uint8_t) request->wIndex; // submit attach event diff --git a/src/host/usbh.c b/src/host/usbh.c index 8e9628cb2..52c552408 100644 --- a/src/host/usbh.c +++ b/src/host/usbh.c @@ -99,6 +99,14 @@ typedef struct { } usbh_device_t; +typedef struct +{ + uint8_t rhport; + uint8_t hub_addr; + uint8_t hub_port; + uint8_t speed; +} usbh_dev0_t; + //--------------------------------------------------------------------+ // MACRO CONSTANT TYPEDEF @@ -106,6 +114,7 @@ typedef struct { // Invalid driver ID in itf2drv[] ep2drv[][] mapping enum { DRVID_INVALID = 0xFFu }; +enum { ADDR_INVALID = 0xFFu }; #if CFG_TUSB_DEBUG >= 2 #define DRIVER_NAME(_name) .name = _name, @@ -183,9 +192,12 @@ enum { CONFIG_NUM = 1 }; // default to use configuration 1 static bool _usbh_initialized = false; +// Device with address = 0 for enumeration +static usbh_dev0_t _dev0; + // all devices including hub and zero-address TODO exclude device0 to save space -// hub address start from CFG_TUH_DEVICE_MAX -CFG_TUSB_MEM_SECTION usbh_device_t _usbh_devices[1+CFG_TUH_DEVICE_MAX+CFG_TUH_HUB]; +// hub address start from CFG_TUH_DEVICE_MAX+1 +CFG_TUSB_MEM_SECTION usbh_device_t _usbh_devices[1 + CFG_TUH_DEVICE_MAX + CFG_TUH_HUB]; // Event queue // role device/host is used by OS NONE for mutex (disable usb isr) @@ -214,13 +226,13 @@ extern bool usbh_control_xfer_cb (uint8_t dev_addr, uint8_t ep_addr, xfer_result //--------------------------------------------------------------------+ bool tuh_device_configured(uint8_t dev_addr) { - return _usbh_devices[dev_addr].configured; + return get_device(dev_addr)->configured; } tusb_speed_t tuh_device_get_speed (uint8_t const dev_addr) { - TU_ASSERT( dev_addr <= CFG_TUH_DEVICE_MAX, TUSB_SPEED_INVALID); - return (tusb_speed_t) _usbh_devices[dev_addr].speed; + TU_ASSERT( dev_addr <= CFG_TUH_DEVICE_MAX + CFG_TUH_HUB, TUSB_SPEED_INVALID); + return (tusb_speed_t) get_device(dev_addr)->speed; } #if CFG_TUSB_OS == OPT_OS_NONE @@ -250,15 +262,16 @@ bool tuh_init(uint8_t rhport) TU_LOG2("USBH init\r\n"); tu_memclr(_usbh_devices, sizeof(_usbh_devices)); + tu_memclr(&_dev0, sizeof(_dev0)); //------------- Enumeration & Reporter Task init -------------// _usbh_q = osal_queue_create( &_usbh_qdef ); TU_ASSERT(_usbh_q != NULL); //------------- Semaphore, Mutex for Control Pipe -------------// - for(uint8_t i=0; imutex = osal_mutex_create(&dev->mutexdef); @@ -460,7 +473,7 @@ void hcd_event_device_remove(uint8_t hostid, bool in_isr) void process_device_unplugged(uint8_t rhport, uint8_t hub_addr, uint8_t hub_port) { //------------- find the all devices (star-network) under port that is unplugged -------------// - for (uint8_t dev_addr = 0; dev_addr <= CFG_TUH_DEVICE_MAX; dev_addr ++) + for (uint8_t dev_addr = 0; dev_addr < TU_ARRAY_SIZE(_usbh_devices); dev_addr ++) { usbh_device_t* dev = &_usbh_devices[dev_addr]; @@ -493,13 +506,17 @@ void process_device_unplugged(uint8_t rhport, uint8_t hub_addr, uint8_t hub_port //--------------------------------------------------------------------+ // INTERNAL HELPER //--------------------------------------------------------------------+ -static uint8_t get_new_address(void) +static uint8_t get_new_address(bool is_hub) { - for (uint8_t addr=1; addr <= CFG_TUH_DEVICE_MAX; addr++) + uint8_t const start = (is_hub ? CFG_TUH_DEVICE_MAX : 0) + 1; + uint8_t const count = (is_hub ? CFG_TUH_HUB : CFG_TUH_DEVICE_MAX); + + for (uint8_t i=0; i < count; i++) { + uint8_t const addr = start + i; if (_usbh_devices[addr].state == TUSB_DEVICE_STATE_UNPLUG) return addr; } - return CFG_TUH_DEVICE_MAX+1; + return ADDR_INVALID; } void usbh_driver_set_config_complete(uint8_t dev_addr, uint8_t itf_num) @@ -561,12 +578,11 @@ static bool enum_hub_clear_reset1_complete(uint8_t dev_addr, tusb_control_reques { (void) dev_addr; (void) request; TU_ASSERT(XFER_RESULT_SUCCESS == result); - usbh_device_t* dev0 = &_usbh_devices[0]; enum_request_set_addr(); // done with hub, waiting for next data on status pipe - (void) hub_status_pipe_queue( dev0->hub_addr ); + (void) hub_status_pipe_queue( _dev0.hub_addr ); return true; } @@ -575,7 +591,6 @@ static bool enum_hub_get_status1_complete(uint8_t dev_addr, tusb_control_request { (void) dev_addr; (void) request; TU_ASSERT(XFER_RESULT_SUCCESS == result); - usbh_device_t* dev0 = &_usbh_devices[0]; hub_port_status_response_t port_status; memcpy(&port_status, _usbh_ctrl_buf, sizeof(hub_port_status_response_t)); @@ -583,7 +598,7 @@ static bool enum_hub_get_status1_complete(uint8_t dev_addr, tusb_control_request // Acknowledge Port Reset Change if Reset Successful if (port_status.change.reset) { - TU_ASSERT( hub_port_clear_feature(dev0->hub_addr, dev0->hub_port, HUB_FEATURE_PORT_RESET_CHANGE, enum_hub_clear_reset1_complete) ); + TU_ASSERT( hub_port_clear_feature(_dev0.hub_addr, _dev0.hub_port, HUB_FEATURE_PORT_RESET_CHANGE, enum_hub_clear_reset1_complete) ); } return true; @@ -593,7 +608,6 @@ static bool enum_hub_get_status0_complete(uint8_t dev_addr, tusb_control_request { (void) dev_addr; (void) request; TU_ASSERT(XFER_RESULT_SUCCESS == result); - usbh_device_t* dev0 = &_usbh_devices[0]; hub_port_status_response_t port_status; memcpy(&port_status, _usbh_ctrl_buf, sizeof(hub_port_status_response_t)); @@ -604,13 +618,13 @@ static bool enum_hub_get_status0_complete(uint8_t dev_addr, tusb_control_request return hub_status_pipe_queue(dev_addr); } - dev0->speed = (port_status.status.high_speed) ? TUSB_SPEED_HIGH : + _dev0.speed = (port_status.status.high_speed) ? TUSB_SPEED_HIGH : (port_status.status.low_speed ) ? TUSB_SPEED_LOW : TUSB_SPEED_FULL; // Acknowledge Port Reset Change if (port_status.change.reset) { - hub_port_clear_feature(dev0->hub_addr, dev0->hub_port, HUB_FEATURE_PORT_RESET_CHANGE, enum_hub_clear_reset0_complete); + hub_port_clear_feature(_dev0.hub_addr, _dev0.hub_port, HUB_FEATURE_PORT_RESET_CHANGE, enum_hub_clear_reset0_complete); } return true; @@ -619,21 +633,22 @@ static bool enum_hub_get_status0_complete(uint8_t dev_addr, tusb_control_request static bool enum_request_set_addr(void) { - // Set Address - uint8_t const new_addr = get_new_address(); - TU_ASSERT(new_addr <= CFG_TUH_DEVICE_MAX); // TODO notify application we reach max devices + tusb_desc_device_t const * desc_device = (tusb_desc_device_t const*) _usbh_ctrl_buf; + + // Get new address + uint8_t const new_addr = get_new_address(desc_device->bDeviceClass == TUSB_CLASS_HUB); + TU_ASSERT(new_addr != ADDR_INVALID); TU_LOG2("Set Address = %d\r\n", new_addr); - usbh_device_t* dev0 = &_usbh_devices[0]; usbh_device_t* new_dev = &_usbh_devices[new_addr]; - new_dev->rhport = dev0->rhport; - new_dev->hub_addr = dev0->hub_addr; - new_dev->hub_port = dev0->hub_port; - new_dev->speed = dev0->speed; + new_dev->rhport = _dev0.rhport; + new_dev->hub_addr = _dev0.hub_addr; + new_dev->hub_port = _dev0.hub_port; + new_dev->speed = _dev0.speed; new_dev->connected = 1; - new_dev->ep0_packet_size = ((tusb_desc_device_t*) _usbh_ctrl_buf)->bMaxPacketSize0; + new_dev->ep0_packet_size = desc_device->bMaxPacketSize0; tusb_control_request_t const new_request = { @@ -656,22 +671,20 @@ static bool enum_request_set_addr(void) static bool enum_new_device(hcd_event_t* event) { - usbh_device_t* dev0 = &_usbh_devices[0]; - dev0->rhport = event->rhport; // TODO refractor integrate to device_pool - dev0->hub_addr = event->connection.hub_addr; - dev0->hub_port = event->connection.hub_port; - dev0->state = TUSB_DEVICE_STATE_UNPLUG; + _dev0.rhport = event->rhport; // TODO refractor integrate to device_pool + _dev0.hub_addr = event->connection.hub_addr; + _dev0.hub_port = event->connection.hub_port; //------------- connected/disconnected directly with roothub -------------// - if (dev0->hub_addr == 0) + if (_dev0.hub_addr == 0) { // wait until device is stable TODO non blocking osal_task_delay(RESET_DELAY); // device unplugged while delaying - if ( !hcd_port_connect_status(dev0->rhport) ) return true; + if ( !hcd_port_connect_status(_dev0.rhport) ) return true; - dev0->speed = hcd_port_speed_get( dev0->rhport ); + _dev0.speed = hcd_port_speed_get(_dev0.rhport ); enum_request_addr0_device_desc(); } @@ -681,7 +694,7 @@ static bool enum_new_device(hcd_event_t* event) { // wait until device is stable osal_task_delay(RESET_DELAY); - TU_ASSERT( hub_port_get_status(dev0->hub_addr, dev0->hub_port, _usbh_ctrl_buf, enum_hub_get_status0_complete) ); + TU_ASSERT( hub_port_get_status(_dev0.hub_addr, _dev0.hub_port, _usbh_ctrl_buf, enum_hub_get_status0_complete) ); } #endif // CFG_TUH_HUB @@ -719,27 +732,26 @@ static bool enum_get_addr0_device_desc_complete(uint8_t dev_addr, tusb_control_r (void) request; TU_ASSERT(0 == dev_addr); - usbh_device_t* dev0 = &_usbh_devices[0]; - if (XFER_RESULT_SUCCESS != result) { #if CFG_TUH_HUB // TODO remove, waiting for next data on status pipe - if (dev0->hub_addr != 0) hub_status_pipe_queue(dev0->hub_addr); + if (_dev0.hub_addr != 0) hub_status_pipe_queue(_dev0.hub_addr); #endif return false; } - TU_ASSERT(tu_desc_type(_usbh_ctrl_buf) == TUSB_DESC_DEVICE); + tusb_desc_device_t const * desc_device = (tusb_desc_device_t const*) _usbh_ctrl_buf; + TU_ASSERT( tu_desc_type(desc_device) == TUSB_DESC_DEVICE ); // Reset device again before Set Address TU_LOG2("Port reset \r\n"); - if (dev0->hub_addr == 0) + if (_dev0.hub_addr == 0) { // connected directly to roothub - hcd_port_reset( dev0->rhport ); // reset port after 8 byte descriptor + hcd_port_reset( _dev0.rhport ); // reset port after 8 byte descriptor osal_task_delay(RESET_DELAY); enum_request_set_addr(); @@ -748,12 +760,12 @@ static bool enum_get_addr0_device_desc_complete(uint8_t dev_addr, tusb_control_r else { // after RESET_DELAY the hub_port_reset() already complete - TU_ASSERT( hub_port_reset(dev0->hub_addr, dev0->hub_port, NULL) ); + TU_ASSERT( hub_port_reset(_dev0.hub_addr, _dev0.hub_port, NULL) ); osal_task_delay(RESET_DELAY); tuh_task(); // FIXME temporarily to clean up port_reset control transfer - TU_ASSERT( hub_port_get_status(dev0->hub_addr, dev0->hub_port, _usbh_ctrl_buf, enum_hub_get_status1_complete) ); + TU_ASSERT( hub_port_get_status(_dev0.hub_addr, _dev0.hub_port, _usbh_ctrl_buf, enum_hub_get_status1_complete) ); } #endif @@ -772,9 +784,7 @@ static bool enum_set_address_complete(uint8_t dev_addr, tusb_control_request_t c new_dev->addressed = 1; // TODO close device 0, may not be needed - usbh_device_t* dev0 = &_usbh_devices[0]; - hcd_device_close(dev0->rhport, 0); - dev0->state = TUSB_DEVICE_STATE_UNPLUG; + hcd_device_close(_dev0.rhport, 0); // open control pipe for new address TU_ASSERT( usbh_edpt_control_open(new_addr, new_dev->ep0_packet_size) ); diff --git a/src/portable/ehci/ehci.c b/src/portable/ehci/ehci.c index 124d88ff3..e3b7499cc 100644 --- a/src/portable/ehci/ehci.c +++ b/src/portable/ehci/ehci.c @@ -71,7 +71,7 @@ typedef struct struct { ehci_qhd_t qhd; ehci_qtd_t qtd; - }control[CFG_TUH_DEVICE_MAX+1]; + }control[CFG_TUH_DEVICE_MAX+CFG_TUH_HUB+1]; ehci_qhd_t qhd_pool[HCD_MAX_ENDPOINT]; ehci_qtd_t qtd_pool[HCD_MAX_XFER] TU_ATTR_ALIGNED(32); -- cgit v1.3.1 From 353c070d00a31ef9eed1e701d4048414fe704738 Mon Sep 17 00:00:00 2001 From: hathach Date: Tue, 24 Aug 2021 01:06:05 +0700 Subject: exclude dev0 from usbh devices pool --- src/class/cdc/cdc_host.c | 2 +- src/class/hid/hid_host.c | 3 ++- src/host/usbh.c | 41 +++++++++++++++++++++-------------------- 3 files changed, 24 insertions(+), 22 deletions(-) (limited to 'src/class') diff --git a/src/class/cdc/cdc_host.c b/src/class/cdc/cdc_host.c index 08b9bab99..e7eaf4d05 100644 --- a/src/class/cdc/cdc_host.c +++ b/src/class/cdc/cdc_host.c @@ -146,7 +146,7 @@ bool tuh_cdc_set_control_line_state(uint8_t dev_addr, bool dtr, bool rts, tuh_co //--------------------------------------------------------------------+ void cdch_init(void) { - tu_memclr(cdch_data, sizeof(cdch_data_t)*CFG_TUH_DEVICE_MAX); + tu_memclr(cdch_data, sizeof(cdch_data)); } bool cdch_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const *itf_desc, uint16_t max_len) diff --git a/src/class/hid/hid_host.c b/src/class/hid/hid_host.c index a9ea03de6..3a832a247 100644 --- a/src/class/hid/hid_host.c +++ b/src/class/hid/hid_host.c @@ -243,9 +243,10 @@ void hidh_close(uint8_t dev_addr) TU_VERIFY(dev_addr <= CFG_TUH_DEVICE_MAX, ); hidh_device_t* hid_dev = get_dev(dev_addr); + if (tuh_hid_umount_cb) { - for ( uint8_t inst = 0; inst < hid_dev->inst_count; inst++ ) tuh_hid_umount_cb(dev_addr, inst); + for (uint8_t inst = 0; inst < hid_dev->inst_count; inst++ ) tuh_hid_umount_cb(dev_addr, inst); } tu_memclr(hid_dev, sizeof(hidh_device_t)); diff --git a/src/host/usbh.c b/src/host/usbh.c index 52c552408..fde51f5c9 100644 --- a/src/host/usbh.c +++ b/src/host/usbh.c @@ -195,9 +195,9 @@ static bool _usbh_initialized = false; // Device with address = 0 for enumeration static usbh_dev0_t _dev0; -// all devices including hub and zero-address TODO exclude device0 to save space +// all devices excluding zero-address // hub address start from CFG_TUH_DEVICE_MAX+1 -CFG_TUSB_MEM_SECTION usbh_device_t _usbh_devices[1 + CFG_TUH_DEVICE_MAX + CFG_TUH_HUB]; +CFG_TUSB_MEM_SECTION usbh_device_t _usbh_devices[CFG_TUH_DEVICE_MAX + CFG_TUH_HUB]; // Event queue // role device/host is used by OS NONE for mutex (disable usb isr) @@ -211,7 +211,7 @@ CFG_TUSB_MEM_SECTION CFG_TUSB_MEM_ALIGN static uint8_t _usbh_ctrl_buf[CFG_TUH_EN TU_ATTR_ALWAYS_INLINE static inline usbh_device_t* get_device(uint8_t dev_addr) { - return &_usbh_devices[dev_addr]; + return &_usbh_devices[dev_addr-1]; } static bool enum_new_device(hcd_event_t* event); @@ -350,7 +350,7 @@ void tuh_task(void) case HCD_EVENT_XFER_COMPLETE: { - usbh_device_t* dev = &_usbh_devices[event.dev_addr]; + usbh_device_t* dev = get_device(event.dev_addr); uint8_t const ep_addr = event.xfer_complete.ep_addr; uint8_t const epnum = tu_edpt_number(ep_addr); uint8_t const ep_dir = tu_edpt_dir(ep_addr); @@ -389,7 +389,7 @@ void tuh_task(void) uint8_t usbh_get_rhport(uint8_t dev_addr) { - return _usbh_devices[dev_addr].rhport; + return get_device(dev_addr)->rhport; } uint8_t* usbh_get_enum_buf(void) @@ -473,9 +473,10 @@ void hcd_event_device_remove(uint8_t hostid, bool in_isr) void process_device_unplugged(uint8_t rhport, uint8_t hub_addr, uint8_t hub_port) { //------------- find the all devices (star-network) under port that is unplugged -------------// - for (uint8_t dev_addr = 0; dev_addr < TU_ARRAY_SIZE(_usbh_devices); dev_addr ++) + for ( uint8_t dev_id = 0; dev_id < TU_ARRAY_SIZE(_usbh_devices); dev_id++ ) { - usbh_device_t* dev = &_usbh_devices[dev_addr]; + usbh_device_t* dev = &_usbh_devices[dev_id]; + uint8_t const dev_addr = dev_id+1; // TODO Hub multiple level if (dev->rhport == rhport && @@ -514,14 +515,14 @@ static uint8_t get_new_address(bool is_hub) for (uint8_t i=0; i < count; i++) { uint8_t const addr = start + i; - if (_usbh_devices[addr].state == TUSB_DEVICE_STATE_UNPLUG) return addr; + if (get_device(addr)->state == TUSB_DEVICE_STATE_UNPLUG) return addr; } return ADDR_INVALID; } void usbh_driver_set_config_complete(uint8_t dev_addr, uint8_t itf_num) { - usbh_device_t* dev = &_usbh_devices[dev_addr]; + usbh_device_t* dev = get_device(dev_addr); for(itf_num++; itf_num < sizeof(dev->itf2drv); itf_num++) { @@ -641,7 +642,7 @@ static bool enum_request_set_addr(void) TU_LOG2("Set Address = %d\r\n", new_addr); - usbh_device_t* new_dev = &_usbh_devices[new_addr]; + usbh_device_t* new_dev = get_device(new_addr); new_dev->rhport = _dev0.rhport; new_dev->hub_addr = _dev0.hub_addr; @@ -780,7 +781,7 @@ static bool enum_set_address_complete(uint8_t dev_addr, tusb_control_request_t c uint8_t const new_addr = (uint8_t const) request->wValue; - usbh_device_t* new_dev = &_usbh_devices[new_addr]; + usbh_device_t* new_dev = get_device(new_addr); new_dev->addressed = 1; // TODO close device 0, may not be needed @@ -816,7 +817,7 @@ static bool enum_get_device_desc_complete(uint8_t dev_addr, tusb_control_request TU_ASSERT(XFER_RESULT_SUCCESS == result); tusb_desc_device_t const * desc_device = (tusb_desc_device_t const*) _usbh_ctrl_buf; - usbh_device_t* dev = &_usbh_devices[dev_addr]; + usbh_device_t* dev = get_device(dev_addr); dev->vendor_id = desc_device->idVendor; dev->product_id = desc_device->idProduct; @@ -914,7 +915,7 @@ static bool enum_set_config_complete(uint8_t dev_addr, tusb_control_request_t co TU_ASSERT(XFER_RESULT_SUCCESS == result); TU_LOG2("Device configured\r\n"); - usbh_device_t* dev = &_usbh_devices[dev_addr]; + usbh_device_t* dev = get_device(dev_addr); dev->configured = 1; dev->state = TUSB_DEVICE_STATE_CONFIGURED; @@ -929,7 +930,7 @@ static bool enum_set_config_complete(uint8_t dev_addr, tusb_control_request_t co static bool parse_configuration_descriptor(uint8_t dev_addr, tusb_desc_configuration_t const* desc_cfg) { - usbh_device_t* dev = &_usbh_devices[dev_addr]; + usbh_device_t* dev = get_device(dev_addr); uint8_t const* desc_end = ((uint8_t const*) desc_cfg) + tu_le16toh(desc_cfg->wTotalLength); uint8_t const* p_desc = tu_desc_next(desc_cfg); @@ -1023,7 +1024,7 @@ bool usbh_edpt_claim(uint8_t dev_addr, uint8_t ep_addr) uint8_t const epnum = tu_edpt_number(ep_addr); uint8_t const dir = tu_edpt_dir(ep_addr); - usbh_device_t* dev = &_usbh_devices[dev_addr]; + usbh_device_t* dev = get_device(dev_addr); #if CFG_TUSB_OS != OPT_OS_NONE // pre-check to help reducing mutex lock @@ -1051,7 +1052,7 @@ bool usbh_edpt_release(uint8_t dev_addr, uint8_t ep_addr) uint8_t const epnum = tu_edpt_number(ep_addr); uint8_t const dir = tu_edpt_dir(ep_addr); - usbh_device_t* dev = &_usbh_devices[dev_addr]; + usbh_device_t* dev = get_device(dev_addr); #if CFG_TUSB_OS != OPT_OS_NONE osal_mutex_lock(dev->mutex, OSAL_TIMEOUT_WAIT_FOREVER); @@ -1077,7 +1078,7 @@ bool usbh_edpt_xfer(uint8_t dev_addr, uint8_t ep_addr, uint8_t * buffer, uint16_ uint8_t const epnum = tu_edpt_number(ep_addr); uint8_t const dir = tu_edpt_dir(ep_addr); - usbh_device_t* dev = &_usbh_devices[dev_addr]; + usbh_device_t* dev = get_device(dev_addr); TU_LOG2(" Queue EP %02X with %u bytes ... ", ep_addr, total_bytes); @@ -1117,12 +1118,12 @@ static bool usbh_edpt_control_open(uint8_t dev_addr, uint8_t max_packet_size) .bInterval = 0 }; - return hcd_edpt_open(_usbh_devices[dev_addr].rhport, dev_addr, &ep0_desc); + return hcd_edpt_open(get_device(dev_addr)->rhport, dev_addr, &ep0_desc); } bool usbh_edpt_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_endpoint_t const * desc_ep) { - usbh_device_t* dev = &_usbh_devices[dev_addr]; + usbh_device_t* dev = get_device(dev_addr); TU_ASSERT(tu_edpt_validate(desc_ep, (tusb_speed_t) dev->speed)); return hcd_edpt_open(rhport, dev_addr, desc_ep); @@ -1133,7 +1134,7 @@ bool usbh_edpt_busy(uint8_t dev_addr, uint8_t ep_addr) uint8_t const epnum = tu_edpt_number(ep_addr); uint8_t const dir = tu_edpt_dir(ep_addr); - usbh_device_t* dev = &_usbh_devices[dev_addr]; + usbh_device_t* dev = get_device(dev_addr); return dev->ep_status[epnum][dir].busy; } -- cgit v1.3.1 From 3c0c051df182cb7261e0f5eb6c52e84f860d0ae1 Mon Sep 17 00:00:00 2001 From: hathach Date: Tue, 24 Aug 2021 19:10:23 +0700 Subject: add tuh_vid_pid_get() complete Sony PS4 dualshock controller example --- examples/host/hid_controller/.only.MCU_LPC175X_6X | 0 examples/host/hid_controller/.only.MCU_LPC177X_8X | 0 examples/host/hid_controller/.only.MCU_LPC18XX | 0 examples/host/hid_controller/.only.MCU_LPC40XX | 0 examples/host/hid_controller/.only.MCU_LPC43XX | 0 examples/host/hid_controller/.only.MCU_MIMXRT10XX | 0 examples/host/hid_controller/.only.MCU_RP2040 | 0 examples/host/hid_controller/CMakeLists.txt | 29 +++ examples/host/hid_controller/Makefile | 30 +++ examples/host/hid_controller/src/hid_app.c | 249 ++++++++++++++++++++++ examples/host/hid_controller/src/main.c | 93 ++++++++ examples/host/hid_controller/src/tusb_config.h | 95 +++++++++ src/class/hid/hid_host.c | 2 +- src/host/usbh.c | 116 ++++++---- src/host/usbh.h | 4 +- 15 files changed, 569 insertions(+), 49 deletions(-) create mode 100644 examples/host/hid_controller/.only.MCU_LPC175X_6X create mode 100644 examples/host/hid_controller/.only.MCU_LPC177X_8X create mode 100644 examples/host/hid_controller/.only.MCU_LPC18XX create mode 100644 examples/host/hid_controller/.only.MCU_LPC40XX create mode 100644 examples/host/hid_controller/.only.MCU_LPC43XX create mode 100644 examples/host/hid_controller/.only.MCU_MIMXRT10XX create mode 100644 examples/host/hid_controller/.only.MCU_RP2040 create mode 100644 examples/host/hid_controller/CMakeLists.txt create mode 100644 examples/host/hid_controller/Makefile create mode 100644 examples/host/hid_controller/src/hid_app.c create mode 100644 examples/host/hid_controller/src/main.c create mode 100644 examples/host/hid_controller/src/tusb_config.h (limited to 'src/class') diff --git a/examples/host/hid_controller/.only.MCU_LPC175X_6X b/examples/host/hid_controller/.only.MCU_LPC175X_6X new file mode 100644 index 000000000..e69de29bb diff --git a/examples/host/hid_controller/.only.MCU_LPC177X_8X b/examples/host/hid_controller/.only.MCU_LPC177X_8X new file mode 100644 index 000000000..e69de29bb diff --git a/examples/host/hid_controller/.only.MCU_LPC18XX b/examples/host/hid_controller/.only.MCU_LPC18XX new file mode 100644 index 000000000..e69de29bb diff --git a/examples/host/hid_controller/.only.MCU_LPC40XX b/examples/host/hid_controller/.only.MCU_LPC40XX new file mode 100644 index 000000000..e69de29bb diff --git a/examples/host/hid_controller/.only.MCU_LPC43XX b/examples/host/hid_controller/.only.MCU_LPC43XX new file mode 100644 index 000000000..e69de29bb diff --git a/examples/host/hid_controller/.only.MCU_MIMXRT10XX b/examples/host/hid_controller/.only.MCU_MIMXRT10XX new file mode 100644 index 000000000..e69de29bb diff --git a/examples/host/hid_controller/.only.MCU_RP2040 b/examples/host/hid_controller/.only.MCU_RP2040 new file mode 100644 index 000000000..e69de29bb diff --git a/examples/host/hid_controller/CMakeLists.txt b/examples/host/hid_controller/CMakeLists.txt new file mode 100644 index 000000000..0a99bc3a9 --- /dev/null +++ b/examples/host/hid_controller/CMakeLists.txt @@ -0,0 +1,29 @@ +cmake_minimum_required(VERSION 3.5) + +include(${CMAKE_CURRENT_SOURCE_DIR}/../../../hw/bsp/family_support.cmake) + +# gets PROJECT name for the example (e.g. -) +family_get_project_name(PROJECT ${CMAKE_CURRENT_LIST_DIR}) + +project(${PROJECT}) + +# Checks this example is valid for the family and initializes the project +family_initialize_project(${PROJECT} ${CMAKE_CURRENT_LIST_DIR}) + +add_executable(${PROJECT}) + +# Example source +target_sources(${PROJECT} PUBLIC + ${CMAKE_CURRENT_SOURCE_DIR}/src/hid_app.c + ${CMAKE_CURRENT_SOURCE_DIR}/src/main.c + ${CMAKE_CURRENT_SOURCE_DIR}/src/msc_app.c + ) + +# Example include +target_include_directories(${PROJECT} PUBLIC + ${CMAKE_CURRENT_SOURCE_DIR}/src + ) + +# Configure compilation flags and libraries for the example... see the corresponding function +# in hw/bsp/FAMILY/family.cmake for details. +family_configure_host_example(${PROJECT}) \ No newline at end of file diff --git a/examples/host/hid_controller/Makefile b/examples/host/hid_controller/Makefile new file mode 100644 index 000000000..6f59faeee --- /dev/null +++ b/examples/host/hid_controller/Makefile @@ -0,0 +1,30 @@ +include ../../../tools/top.mk +include ../../make.mk + +INC += \ + src \ + $(TOP)/hw \ + +# Example source +EXAMPLE_SOURCE += \ + src/hid_app.c \ + src/main.c + +SRC_C += $(addprefix $(CURRENT_PATH)/, $(EXAMPLE_SOURCE)) + +CFLAGS += -Wno-error=cast-align + +# TinyUSB Host Stack source +SRC_C += \ + src/class/cdc/cdc_host.c \ + src/class/hid/hid_host.c \ + src/class/msc/msc_host.c \ + src/host/hub.c \ + src/host/usbh.c \ + src/host/usbh_control.c \ + src/portable/ehci/ehci.c \ + src/portable/ohci/ohci.c \ + src/portable/nxp/transdimension/hcd_transdimension.c \ + src/portable/nxp/lpc17_40/hcd_lpc17_40.c + +include ../../rules.mk diff --git a/examples/host/hid_controller/src/hid_app.c b/examples/host/hid_controller/src/hid_app.c new file mode 100644 index 000000000..37ae94abd --- /dev/null +++ b/examples/host/hid_controller/src/hid_app.c @@ -0,0 +1,249 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2021, Ha Thach (tinyusb.org) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + +#include "bsp/board.h" +#include "tusb.h" + +/* From https://www.kernel.org/doc/html/latest/input/gamepad.html + ____________________________ __ + / [__ZL__] [__ZR__] \ | + / [__ TL __] [__ TR __] \ | Front Triggers + __/________________________________\__ __| + / _ \ | + / /\ __ (N) \ | + / || __ |MO| __ _ _ \ | Main Pad + | <===DP===> |SE| |ST| (W) -|- (E) | | + \ || ___ ___ _ / | + /\ \/ / \ / \ (S) /\ __| + / \________ | LS | ____ | RS | ________/ \ | +| / \ \___/ / \ \___/ / \ | | Control Sticks +| / \_____/ \_____/ \ | __| +| / \ | + \_____/ \_____/ + + |________|______| |______|___________| + D-Pad Left Right Action Pad + Stick Stick + + |_____________| + Menu Pad + + Most gamepads have the following features: + - Action-Pad 4 buttons in diamonds-shape (on the right side) NORTH, SOUTH, WEST and EAST. + - D-Pad (Direction-pad) 4 buttons (on the left side) that point up, down, left and right. + - Menu-Pad Different constellations, but most-times 2 buttons: SELECT - START. + - Analog-Sticks provide freely moveable sticks to control directions, Analog-sticks may also + provide a digital button if you press them. + - Triggers are located on the upper-side of the pad in vertical direction. The upper buttons + are normally named Left- and Right-Triggers, the lower buttons Z-Left and Z-Right. + - Rumble Many devices provide force-feedback features. But are mostly just simple rumble motors. + */ + +// Sony DS4 report layout detail https://www.psdevwiki.com/ps4/DS4-USB +typedef struct TU_ATTR_PACKED +{ + int8_t x, y, z, rz; // joystick + + struct { + uint8_t dpad : 4; // (hat format, 0x08 is released, 0=N, 1=NE, 2=E, 3=SE, 4=S, 5=SW, 6=W, 7=NW) + uint8_t square : 1; // west + uint8_t cross : 1; // south + uint8_t circle : 1; // east + uint8_t triangle : 1; // north + }; + + struct { + uint8_t l1 : 1; + uint8_t r1 : 1; + uint8_t l2 : 1; + uint8_t r2 : 1; + uint8_t share : 1; + uint8_t option : 1; + uint8_t l3 : 1; + uint8_t r3 : 1; + }; + + struct { + uint8_t ps : 1; // playstation button + uint8_t tpad : 1; // track pad click + uint8_t counter : 6; // +1 each report + }; + + // comment out since not used by this example + // uint8_t l2_trigger; // 0 released, 0xff fully pressed + // uint8_t r2_trigger; // as above + + // uint16_t timestamp; + // uint8_t battery; + // + // int16_t gyro[3]; // x, y, z; + // int16_t accel[3]; // x, y, z + + // there is still lots more info + +} sony_ds4_report_t; + +// check if device is Sony DualShock 4 +static inline bool is_sony_ds4(uint8_t dev_addr) +{ + uint16_t vid, pid; + tuh_vid_pid_get(dev_addr, &vid, &pid); + + return (vid == 0x054c && pid == 0x09cc); +} + +//--------------------------------------------------------------------+ +// MACRO TYPEDEF CONSTANT ENUM DECLARATION +//--------------------------------------------------------------------+ + +void hid_app_task(void) +{ + // nothing to do +} + +//--------------------------------------------------------------------+ +// TinyUSB Callbacks +//--------------------------------------------------------------------+ + +// Invoked when device with hid interface is mounted +// Report descriptor is also available for use. tuh_hid_parse_report_descriptor() +// can be used to parse common/simple enough descriptor. +// Note: if report descriptor length > CFG_TUH_ENUMERATION_BUFSIZE, it will be skipped +// therefore report_desc = NULL, desc_len = 0 +void tuh_hid_mount_cb(uint8_t dev_addr, uint8_t instance, uint8_t const* desc_report, uint16_t desc_len) +{ + uint16_t vid, pid; + tuh_vid_pid_get(dev_addr, &vid, &pid); + + printf("HID device address = %d, instance = %d is mounted\r\n", dev_addr, instance); + printf("VID = %04x, PID = %04x\r\n", vid, pid); + + // Sony DualShock 4 [CUH-ZCT2x] + if ( is_sony_ds4(dev_addr) ) + { + // request to receive report + // tuh_hid_report_received_cb() will be invoked when report is available + if ( !tuh_hid_receive_report(dev_addr, instance) ) + { + printf("Error: cannot request to receive report\r\n"); + } + } +} + +// Invoked when device with hid interface is un-mounted +void tuh_hid_umount_cb(uint8_t dev_addr, uint8_t instance) +{ + printf("HID device address = %d, instance = %d is unmounted\r\n", dev_addr, instance); + +} + +// check if different than 2 +bool diff_than_2(int8_t x, int8_t y) +{ + return (x - y > 2) || (y - x > 2); +} + +// check if 2 reports are different enough +bool diff_report(sony_ds4_report_t const* rpt1, sony_ds4_report_t const* rpt2) +{ + bool result; + + // x, y, z, rz must different than 2 to be counted + result = diff_than_2(rpt1->x, rpt2->x) || diff_than_2(rpt1->y , rpt2->y ) || + diff_than_2(rpt1->z, rpt2->z) || diff_than_2(rpt1->rz, rpt2->rz); + + // check the reset with mem compare + result |= memcmp(&rpt1->rz + 1, &rpt2->rz + 1, sizeof(sony_ds4_report_t)-4); + + return result; +} + +void process_sony_ds4(uint8_t const* report, uint16_t len) +{ + const char* dpad_str[] = { "N", "NE", "E", "SE", "S", "SW", "W", "NW", "none" }; + + // previous report used to compare for changes + static sony_ds4_report_t prev_report = { 0 }; + + uint8_t const report_id = report[0]; + report++; + len--; + + // all buttons state is stored in ID 1 + if (report_id == 1) + { + sony_ds4_report_t ds4_report; + memcpy(&ds4_report, report, sizeof(ds4_report)); + + // counter is +1, assign to make it easier to compare 2 report + prev_report.counter = ds4_report.counter; + + // only print if changes since it is polled ~ 5ms + // Since count+1 after each report and x, y, z, rz fluctuate within 1 or 2 + // We need more than memcmp to check if report is different enough + if ( diff_report(&prev_report, &ds4_report) ) + { + printf("(x, y, z, rz) = (%d, %d, %d, %d)\r\n", ds4_report.x, ds4_report.y, ds4_report.z, ds4_report.rz); + printf("DPad = %s ", dpad_str[ds4_report.dpad]); + + if (ds4_report.square ) printf("Square "); + if (ds4_report.cross ) printf("Cross "); + if (ds4_report.circle ) printf("Circle "); + if (ds4_report.triangle ) printf("Triangle "); + + if (ds4_report.l1) printf("L1 "); + if (ds4_report.r1) printf("R1 "); + if (ds4_report.l2) printf("L2 "); + if (ds4_report.r2) printf("R2 "); + + if (ds4_report.share) printf("Share "); + if (ds4_report.option) printf("Option "); + if (ds4_report.l3) printf("L3 "); + if (ds4_report.r3) printf("R3 "); + + if (ds4_report.ps ) printf("PS "); + if (ds4_report.tpad ) printf("TPad "); + + printf("\r\n"); + } + + prev_report = ds4_report; + } +} + +// Invoked when received report from device via interrupt endpoint +void tuh_hid_report_received_cb(uint8_t dev_addr, uint8_t instance, uint8_t const* report, uint16_t len) +{ + if ( is_sony_ds4(dev_addr) ) + { + process_sony_ds4(report, len); + } + + // continue to request to receive report + if ( !tuh_hid_receive_report(dev_addr, instance) ) + { + printf("Error: cannot request to receive report\r\n"); + } +} diff --git a/examples/host/hid_controller/src/main.c b/examples/host/hid_controller/src/main.c new file mode 100644 index 000000000..e13fa818a --- /dev/null +++ b/examples/host/hid_controller/src/main.c @@ -0,0 +1,93 @@ +/* + * 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 example current worked and tested with following controller + * - Sony DualShock 4 [CUH-ZCT2x] VID = 0x054c, PID = 0x09cc + */ + + +#include +#include +#include + +#include "bsp/board.h" +#include "tusb.h" + +//--------------------------------------------------------------------+ +// MACRO CONSTANT TYPEDEF PROTYPES +//--------------------------------------------------------------------+ +void led_blinking_task(void); + +extern void cdc_task(void); +extern void hid_app_task(void); + +/*------------- MAIN -------------*/ +int main(void) +{ + board_init(); + + printf("TinyUSB Host HID Controller Example\r\n"); + + tusb_init(); + + while (1) + { + // tinyusb host task + tuh_task(); + led_blinking_task(); + +#if CFG_TUH_CDC + cdc_task(); +#endif + +#if CFG_TUH_HID + hid_app_task(); +#endif + } + + return 0; +} + +//--------------------------------------------------------------------+ +// TinyUSB Callbacks +//--------------------------------------------------------------------+ + +//--------------------------------------------------------------------+ +// Blinking Task +//--------------------------------------------------------------------+ +void led_blinking_task(void) +{ + const uint32_t interval_ms = 1000; + static uint32_t start_ms = 0; + + static bool led_state = false; + + // Blink every interval ms + if ( board_millis() - start_ms < interval_ms) return; // not enough time + start_ms += interval_ms; + + board_led_write(led_state); + led_state = 1 - led_state; // toggle +} diff --git a/examples/host/hid_controller/src/tusb_config.h b/examples/host/hid_controller/src/tusb_config.h new file mode 100644 index 000000000..74b471ae4 --- /dev/null +++ b/examples/host/hid_controller/src/tusb_config.h @@ -0,0 +1,95 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2019 Ha Thach (tinyusb.org) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + +#ifndef _TUSB_CONFIG_H_ +#define _TUSB_CONFIG_H_ + +#ifdef __cplusplus + extern "C" { +#endif + +//-------------------------------------------------------------------- +// COMMON CONFIGURATION +//-------------------------------------------------------------------- + +// defined by compiler flags for flexibility +#ifndef CFG_TUSB_MCU + #error CFG_TUSB_MCU must be defined +#endif + +#if CFG_TUSB_MCU == OPT_MCU_LPC43XX || CFG_TUSB_MCU == OPT_MCU_LPC18XX || CFG_TUSB_MCU == OPT_MCU_MIMXRT10XX + #define CFG_TUSB_RHPORT0_MODE (OPT_MODE_HOST | OPT_MODE_HIGH_SPEED) +#else + #define CFG_TUSB_RHPORT0_MODE OPT_MODE_HOST +#endif + +#ifndef CFG_TUSB_OS +#define CFG_TUSB_OS OPT_OS_NONE +#endif + +// CFG_TUSB_DEBUG is defined by compiler in DEBUG build +// #define CFG_TUSB_DEBUG 0 + +/* USB DMA on some MCUs can only access a specific SRAM region with restriction on alignment. + * Tinyusb use follows macros to declare transferring memory so that they can be put + * into those specific section. + * e.g + * - CFG_TUSB_MEM SECTION : __attribute__ (( section(".usb_ram") )) + * - CFG_TUSB_MEM_ALIGN : __attribute__ ((aligned(4))) + */ +#ifndef CFG_TUSB_MEM_SECTION +#define CFG_TUSB_MEM_SECTION +#endif + +#ifndef CFG_TUSB_MEM_ALIGN +#define CFG_TUSB_MEM_ALIGN __attribute__ ((aligned(4))) +#endif + +//-------------------------------------------------------------------- +// CONFIGURATION +//-------------------------------------------------------------------- + +// Size of buffer to hold descriptors and other data used for enumeration +#define CFG_TUH_ENUMERATION_BUFSIZE 256 + +#define CFG_TUH_HUB 0 +#define CFG_TUH_CDC 0 +#define CFG_TUH_HID 4 // typical keyboard + mouse device can have 3-4 HID interfaces +#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) + +//------------- HID -------------// + +#define CFG_TUH_HID_EP_BUFSIZE 64 + +#ifdef __cplusplus + } +#endif + +#endif /* _TUSB_CONFIG_H_ */ diff --git a/src/class/hid/hid_host.c b/src/class/hid/hid_host.c index 3a832a247..8c66477b3 100644 --- a/src/class/hid/hid_host.c +++ b/src/class/hid/hid_host.c @@ -228,7 +228,7 @@ bool hidh_xfer_cb(uint8_t dev_addr, uint8_t ep_addr, xfer_result_t result, uint3 if ( dir == TUSB_DIR_IN ) { TU_LOG2(" Get Report callback (%u, %u)\r\n", dev_addr, instance); - TU_LOG1_MEM(hid_itf->epin_buf, 8, 2); + TU_LOG3_MEM(hid_itf->epin_buf, xferred_bytes, 2); tuh_hid_report_received_cb(dev_addr, instance, hid_itf->epin_buf, xferred_bytes); }else { diff --git a/src/host/usbh.c b/src/host/usbh.c index 1b5a422f4..548456a40 100644 --- a/src/host/usbh.c +++ b/src/host/usbh.c @@ -61,9 +61,13 @@ typedef struct { uint8_t speed; //------------- device descriptor -------------// - uint16_t vendor_id; - uint16_t product_id; - uint8_t ep0_packet_size; + uint16_t vid; + uint16_t pid; + + uint8_t ep0_size; + uint8_t i_manufacturer; + uint8_t i_product; + uint8_t i_serial; //------------- configuration descriptor -------------// // uint8_t interface_count; // bNumInterfaces alias @@ -105,6 +109,8 @@ typedef struct uint8_t hub_addr; uint8_t hub_port; uint8_t speed; + + volatile uint8_t connected; } usbh_dev0_t; @@ -230,9 +236,22 @@ bool tuh_mounted(uint8_t dev_addr) return get_device(dev_addr)->configured; } -tusb_speed_t tuh_speed_get (uint8_t const dev_addr) +bool tuh_vid_pid_get(uint8_t dev_addr, uint16_t* vid, uint16_t* pid) +{ + *vid = *pid = 0; + + TU_VERIFY(tuh_mounted(dev_addr)); + + usbh_device_t const* dev = get_device(dev_addr); + + *vid = dev->vid; + *pid = dev->pid; + + return true; +} + +tusb_speed_t tuh_speed_get (uint8_t dev_addr) { - TU_ASSERT( dev_addr <= CFG_TUH_DEVICE_MAX + CFG_TUH_HUB, TUSB_SPEED_INVALID); return (tusb_speed_t) get_device(dev_addr)->speed; } @@ -652,45 +671,6 @@ static bool enum_hub_get_status0_complete(uint8_t dev_addr, tusb_control_request } #endif -static bool enum_request_set_addr(void) -{ - uint8_t const addr0 = 0; - tusb_desc_device_t const * desc_device = (tusb_desc_device_t const*) _usbh_ctrl_buf; - - // Get new address - uint8_t const new_addr = get_new_address(desc_device->bDeviceClass == TUSB_CLASS_HUB); - TU_ASSERT(new_addr != ADDR_INVALID); - - TU_LOG2("Set Address = %d\r\n", new_addr); - - usbh_device_t* new_dev = get_device(new_addr); - - new_dev->rhport = _dev0.rhport; - new_dev->hub_addr = _dev0.hub_addr; - new_dev->hub_port = _dev0.hub_port; - new_dev->speed = _dev0.speed; - new_dev->connected = 1; - new_dev->ep0_packet_size = desc_device->bMaxPacketSize0; - - tusb_control_request_t const new_request = - { - .bmRequestType_bit = - { - .recipient = TUSB_REQ_RCPT_DEVICE, - .type = TUSB_REQ_TYPE_STANDARD, - .direction = TUSB_DIR_OUT - }, - .bRequest = TUSB_REQ_SET_ADDRESS, - .wValue = new_addr, - .wIndex = 0, - .wLength = 0 - }; - - TU_ASSERT( tuh_control_xfer(addr0, &new_request, NULL, enum_set_address_complete) ); - - return true; -} - static bool enum_new_device(hcd_event_t* event) { _dev0.rhport = event->rhport; // TODO refractor integrate to device_pool @@ -795,6 +775,45 @@ static bool enum_get_addr0_device_desc_complete(uint8_t dev_addr, tusb_control_r return true; } +static bool enum_request_set_addr(void) +{ + uint8_t const addr0 = 0; + tusb_desc_device_t const * desc_device = (tusb_desc_device_t const*) _usbh_ctrl_buf; + + // Get new address + uint8_t const new_addr = get_new_address(desc_device->bDeviceClass == TUSB_CLASS_HUB); + TU_ASSERT(new_addr != ADDR_INVALID); + + TU_LOG2("Set Address = %d\r\n", new_addr); + + usbh_device_t* new_dev = get_device(new_addr); + + new_dev->rhport = _dev0.rhport; + new_dev->hub_addr = _dev0.hub_addr; + new_dev->hub_port = _dev0.hub_port; + new_dev->speed = _dev0.speed; + new_dev->connected = 1; + new_dev->ep0_size = desc_device->bMaxPacketSize0; + + tusb_control_request_t const new_request = + { + .bmRequestType_bit = + { + .recipient = TUSB_REQ_RCPT_DEVICE, + .type = TUSB_REQ_TYPE_STANDARD, + .direction = TUSB_DIR_OUT + }, + .bRequest = TUSB_REQ_SET_ADDRESS, + .wValue = new_addr, + .wIndex = 0, + .wLength = 0 + }; + + TU_ASSERT( tuh_control_xfer(addr0, &new_request, NULL, enum_set_address_complete) ); + + return true; +} + // After SET_ADDRESS is complete static bool enum_set_address_complete(uint8_t dev_addr, tusb_control_request_t const * request, xfer_result_t result) { @@ -810,7 +829,7 @@ static bool enum_set_address_complete(uint8_t dev_addr, tusb_control_request_t c hcd_device_close(_dev0.rhport, 0); // open control pipe for new address - TU_ASSERT( usbh_edpt_control_open(new_addr, new_dev->ep0_packet_size) ); + TU_ASSERT( usbh_edpt_control_open(new_addr, new_dev->ep0_size) ); // Get full device descriptor TU_LOG2("Get Device Descriptor\r\n"); @@ -841,8 +860,11 @@ static bool enum_get_device_desc_complete(uint8_t dev_addr, tusb_control_request tusb_desc_device_t const * desc_device = (tusb_desc_device_t const*) _usbh_ctrl_buf; usbh_device_t* dev = get_device(dev_addr); - dev->vendor_id = desc_device->idVendor; - dev->product_id = desc_device->idProduct; + dev->vid = desc_device->idVendor; + dev->pid = desc_device->idProduct; + dev->i_manufacturer = desc_device->iManufacturer; + dev->i_product = desc_device->iProduct; + dev->i_serial = desc_device->iSerialNumber; // if (tuh_attach_cb) tuh_attach_cb((tusb_desc_device_t*) _usbh_ctrl_buf); diff --git a/src/host/usbh.h b/src/host/usbh.h index 5f7229f27..8411cad28 100644 --- a/src/host/usbh.h +++ b/src/host/usbh.h @@ -57,7 +57,8 @@ void tuh_task(void); extern void hcd_int_handler(uint8_t rhport); #define tuh_int_handler hcd_int_handler -tusb_speed_t tuh_speed_get (uint8_t dev_addr); +bool tuh_vid_pid_get(uint8_t dev_addr, uint16_t* vid, uint16_t* pid); +tusb_speed_t tuh_speed_get(uint8_t dev_addr); // Check if device is connected and configured bool tuh_mounted(uint8_t dev_addr); @@ -66,6 +67,7 @@ bool tuh_mounted(uint8_t dev_addr); static inline bool tuh_suspended(uint8_t dev_addr) { // TODO implement suspend & resume on host + (void) dev_addr; return false; } -- cgit v1.3.1 From 629da937f84854d76cd8da20daa4a80dd02e56e2 Mon Sep 17 00:00:00 2001 From: hathach Date: Thu, 26 Aug 2021 17:55:31 +0700 Subject: slightly change the keyboard descriptor template to pass usb compliant test --- src/class/hid/hid_device.h | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) (limited to 'src/class') diff --git a/src/class/hid/hid_device.h b/src/class/hid/hid_device.h index e2c950dd1..5cf4b3060 100644 --- a/src/class/hid/hid_device.h +++ b/src/class/hid/hid_device.h @@ -195,16 +195,7 @@ static inline bool tud_hid_gamepad_report(uint8_t report_id, int8_t x, int8_t y HID_REPORT_COUNT ( 1 ) ,\ HID_REPORT_SIZE ( 8 ) ,\ HID_INPUT ( HID_CONSTANT ) ,\ - /* 6-byte Keycodes */ \ - HID_USAGE_PAGE ( HID_USAGE_PAGE_KEYBOARD ) ,\ - HID_USAGE_MIN ( 0 ) ,\ - HID_USAGE_MAX_N ( 255, 2 ) ,\ - HID_LOGICAL_MIN ( 0 ) ,\ - HID_LOGICAL_MAX_N( 255, 2 ) ,\ - HID_REPORT_COUNT ( 6 ) ,\ - HID_REPORT_SIZE ( 8 ) ,\ - HID_INPUT ( HID_DATA | HID_ARRAY | HID_ABSOLUTE ) ,\ - /* 5-bit LED Indicator Kana | Compose | ScrollLock | CapsLock | NumLock */ \ + /* Output 5-bit LED Indicator Kana | Compose | ScrollLock | CapsLock | NumLock */ \ HID_USAGE_PAGE ( HID_USAGE_PAGE_LED ) ,\ HID_USAGE_MIN ( 1 ) ,\ HID_USAGE_MAX ( 5 ) ,\ @@ -215,6 +206,15 @@ static inline bool tud_hid_gamepad_report(uint8_t report_id, int8_t x, int8_t y HID_REPORT_COUNT ( 1 ) ,\ HID_REPORT_SIZE ( 3 ) ,\ HID_OUTPUT ( HID_CONSTANT ) ,\ + /* 6-byte Keycodes */ \ + HID_USAGE_PAGE ( HID_USAGE_PAGE_KEYBOARD ) ,\ + HID_USAGE_MIN ( 0 ) ,\ + HID_USAGE_MAX_N ( 255, 2 ) ,\ + HID_LOGICAL_MIN ( 0 ) ,\ + HID_LOGICAL_MAX_N( 255, 2 ) ,\ + HID_REPORT_COUNT ( 6 ) ,\ + HID_REPORT_SIZE ( 8 ) ,\ + HID_INPUT ( HID_DATA | HID_ARRAY | HID_ABSOLUTE ) ,\ HID_COLLECTION_END \ // Mouse Report Descriptor Template -- cgit v1.3.1 From 9394de6ae74cf01ba8c8f1dab57dbbdfad6d6407 Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 27 Aug 2021 12:38:41 +0700 Subject: update msc driver to pass MSC BOT error recovery compliant test --- examples/device/cdc_msc/src/msc_disk.c | 11 ++ examples/device/msc_dual_lun/src/msc_disk_dual.c | 11 ++ src/class/msc/msc_device.c | 137 +++++++++++++++++------ src/class/msc/msc_device.h | 2 +- src/common/tusb_common.h | 7 +- src/device/usbd.c | 7 +- 6 files changed, 136 insertions(+), 39 deletions(-) (limited to 'src/class') diff --git a/examples/device/cdc_msc/src/msc_disk.c b/examples/device/cdc_msc/src/msc_disk.c index 503baace9..32f2563cb 100644 --- a/examples/device/cdc_msc/src/msc_disk.c +++ b/examples/device/cdc_msc/src/msc_disk.c @@ -194,6 +194,17 @@ int32_t tud_msc_read10_cb(uint8_t lun, uint32_t lba, uint32_t offset, void* buff return bufsize; } +bool tud_msc_is_writable_cb (uint8_t lun) +{ + (void) lun; + +#ifdef CFG_EXAMPLE_MSC_READONLY + return false; +#else + return true; +#endif +} + // Callback invoked when received WRITE10 command. // Process data in buffer to disk's storage and return number of written bytes int32_t tud_msc_write10_cb(uint8_t lun, uint32_t lba, uint32_t offset, uint8_t* buffer, uint32_t bufsize) diff --git a/examples/device/msc_dual_lun/src/msc_disk_dual.c b/examples/device/msc_dual_lun/src/msc_disk_dual.c index 2ab050da8..cc7dfae0e 100644 --- a/examples/device/msc_dual_lun/src/msc_disk_dual.c +++ b/examples/device/msc_dual_lun/src/msc_disk_dual.c @@ -274,6 +274,17 @@ int32_t tud_msc_read10_cb(uint8_t lun, uint32_t lba, uint32_t offset, void* buff return bufsize; } +bool tud_msc_is_writable_cb (uint8_t lun) +{ + (void) lun; + +#ifdef CFG_EXAMPLE_MSC_READONLY + return false; +#else + return true; +#endif +} + // Callback invoked when received WRITE10 command. // Process data in buffer to disk's storage and return number of written bytes int32_t tud_msc_write10_cb(uint8_t lun, uint32_t lba, uint32_t offset, uint8_t* buffer, uint32_t bufsize) diff --git a/src/class/msc/msc_device.c b/src/class/msc/msc_device.c index 014e8b69e..9e3689d84 100644 --- a/src/class/msc/msc_device.c +++ b/src/class/msc/msc_device.c @@ -46,7 +46,8 @@ enum MSC_STAGE_CMD = 0, MSC_STAGE_DATA, MSC_STAGE_STATUS, - MSC_STAGE_STATUS_SENT + MSC_STAGE_STATUS_SENT, + MSC_STAGE_NEED_RESET, }; typedef struct @@ -174,35 +175,91 @@ uint16_t mscd_open(uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint1 TU_ASSERT( usbd_open_edpt_pair(rhport, tu_desc_next(itf_desc), 2, TUSB_XFER_BULK, &p_msc->ep_out, &p_msc->ep_in), 0 ); // Prepare for Command Block Wrapper - if ( !usbd_edpt_xfer(rhport, p_msc->ep_out, (uint8_t*) &p_msc->cbw, sizeof(msc_cbw_t)) ) - { - TU_LOG_FAILED(); - TU_BREAKPOINT(); - } + TU_ASSERT( usbd_edpt_xfer(rhport, p_msc->ep_out, (uint8_t*) &p_msc->cbw, sizeof(msc_cbw_t)), drv_len); return drv_len; } +static void process_bot_reset(mscd_interface_t* p_msc) +{ + p_msc->stage = MSC_STAGE_CMD; + p_msc->total_len = 0; + p_msc->xferred_len = 0; + + p_msc->sense_key = 0; + p_msc->add_sense_code = 0; + p_msc->add_sense_qualifier = 0; +} + + // Invoked when a control transfer occurred on an interface of this class // Driver response accordingly to the request and the transfer stage (setup/data/ack) // return false to stall control endpoint (e.g unsupported request) -bool mscd_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t const * p_request) +bool mscd_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t const * request) { // nothing to do with DATA & ACK stage if (stage != CONTROL_STAGE_SETUP) return true; - // Handle class request only - TU_VERIFY(p_request->bmRequestType_bit.type == TUSB_REQ_TYPE_CLASS); + mscd_interface_t* p_msc = &_mscd_itf; + + // Clear Endpoint Feature (stall) for recovery + if ( TUSB_REQ_TYPE_STANDARD == request->bmRequestType_bit.type && + TUSB_REQ_RCPT_ENDPOINT == request->bmRequestType_bit.recipient && + TUSB_REQ_CLEAR_FEATURE == request->bRequest && + TUSB_REQ_FEATURE_EDPT_HALT == request->wValue ) + { + uint8_t const ep_addr = tu_u16_low(request->wIndex); + + if ( p_msc->stage == MSC_STAGE_NEED_RESET ) + { + // reset recovery is required to recover from this stage + // Clear Stall request cannot resolve this -> continue to stall endpoint + usbd_edpt_stall(rhport, ep_addr); + } + else + { + if ( ep_addr == p_msc->ep_in ) + { + if ( p_msc->stage == MSC_STAGE_STATUS ) + { + // resume sending SCSI status if we are in this stage previously before stalled + p_msc->stage = MSC_STAGE_STATUS_SENT; + TU_ASSERT( usbd_edpt_xfer(rhport, p_msc->ep_in , (uint8_t*) &p_msc->csw, sizeof(msc_csw_t)) ); + } + } + else if ( ep_addr == p_msc->ep_out ) + { + if ( p_msc->stage == MSC_STAGE_CMD ) + { + // part of reset recovery (probably due to invalid CBW) -> prepare for new command + TU_ASSERT( usbd_edpt_xfer(rhport, p_msc->ep_out, (uint8_t*) &p_msc->cbw, sizeof(msc_cbw_t)) ); + } + } + } + + return true; + } + + // From this point only handle class request only + TU_VERIFY(request->bmRequestType_bit.type == TUSB_REQ_TYPE_CLASS); - switch ( p_request->bRequest ) + switch ( request->bRequest ) { case MSC_REQ_RESET: - // TODO: Actually reset interface. - tud_control_status(rhport, p_request); + TU_LOG(MSC_DEBUG, " MSC BOT Reset\r\n"); + TU_VERIFY(request->wValue == 0 && request->wLength == 0); + + // driver state reset + process_bot_reset(p_msc); + + tud_control_status(rhport, request); break; case MSC_REQ_GET_MAX_LUN: { + TU_LOG(MSC_DEBUG, " MSC Get Max Lun\r\n"); + TU_VERIFY(request->wValue == 0 && request->wLength == 1); + uint8_t maxlun = 1; if (tud_msc_get_maxlun_cb) maxlun = tud_msc_get_maxlun_cb(); TU_VERIFY(maxlun); @@ -210,7 +267,7 @@ bool mscd_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t // MAX LUN is minus 1 by specs maxlun--; - tud_control_xfer(rhport, p_request, &maxlun, 1); + tud_control_xfer(rhport, request, &maxlun, 1); } break; @@ -222,6 +279,8 @@ bool mscd_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t bool mscd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t event, uint32_t xferred_bytes) { + (void) event; + mscd_interface_t* p_msc = &_mscd_itf; msc_cbw_t const * p_cbw = &p_msc->cbw; msc_csw_t * p_csw = &p_msc->csw; @@ -233,11 +292,20 @@ bool mscd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t event, uint32_t // Complete IN while waiting for CMD is usually Status of previous SCSI op, ignore it if(ep_addr != p_msc->ep_out) return true; - TU_ASSERT( event == XFER_RESULT_SUCCESS && - xferred_bytes == sizeof(msc_cbw_t) && p_cbw->signature == MSC_CBW_SIGNATURE ); + if ( !(xferred_bytes == sizeof(msc_cbw_t) && p_cbw->signature == MSC_CBW_SIGNATURE) ) + { + // BOT 6.6.1 If CBW is not valid stall both endpoints until reset recovery + p_msc->stage = MSC_STAGE_NEED_RESET; + + // invalid CBW stall both endpoints + usbd_edpt_stall(rhport, p_msc->ep_in); + usbd_edpt_stall(rhport, p_msc->ep_out); + + return false; + } TU_LOG(MSC_DEBUG, " SCSI Command: %s\r\n", tu_lookup_find(&_msc_scsi_cmd_table, p_cbw->command[0])); - // TU_LOG_MEM(MSC_DEBUG, p_cbw, xferred_bytes, 2); + //TU_LOG_MEM(MSC_DEBUG, p_cbw, xferred_bytes, 2); p_csw->signature = MSC_CSW_SIGNATURE; p_csw->tag = p_cbw->tag; @@ -440,15 +508,8 @@ bool mscd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t event, uint32_t if ( p_msc->stage == MSC_STAGE_STATUS ) { - // Either endpoints is stalled, need to wait until it is cleared by host - if ( usbd_edpt_stalled(rhport, p_msc->ep_in) || usbd_edpt_stalled(rhport, p_msc->ep_out) ) - { - // simulate an transfer complete with adjusted parameters --> this driver callback will fired again - // and response with status phase after halted endpoints are cleared. - // note: use ep_out to prevent confusing with STATUS complete - dcd_event_xfer_complete(rhport, p_msc->ep_out, 0, XFER_RESULT_SUCCESS, false); - } - else + // skip status if epin is currently stalled, will do it when received Clear Stall request + if ( !usbd_edpt_stalled(rhport, p_msc->ep_in) ) { // Move to Status Sent stage p_msc->stage = MSC_STAGE_STATUS_SENT; @@ -600,9 +661,11 @@ static int32_t proc_builtin_scsi(uint8_t lun, uint8_t const scsi_cmd[16], uint8_ }; bool writable = true; - if (tud_msc_is_writable_cb) { - writable = tud_msc_is_writable_cb(lun); + if ( tud_msc_is_writable_cb ) + { + writable = tud_msc_is_writable_cb(lun); } + mode_resp.write_protected = !writable; resplen = sizeof(mode_resp); @@ -660,7 +723,8 @@ static void proc_read10_cmd(uint8_t rhport, mscd_interface_t* p_msc) if ( nbytes < 0 ) { - // negative means error -> pipe is stalled & status in CSW set to failed + // negative means error -> endpoint is stalled & status in CSW set to failed + p_msc->stage = MSC_STAGE_STATUS; p_csw->data_residue = p_cbw->total_bytes - p_msc->xferred_len; p_csw->status = MSC_CSW_STATUS_FAILED; @@ -682,15 +746,22 @@ static void proc_write10_cmd(uint8_t rhport, mscd_interface_t* p_msc) { msc_cbw_t const * p_cbw = &p_msc->cbw; bool writable = true; - if (tud_msc_is_writable_cb) { + + if ( tud_msc_is_writable_cb ) + { writable = tud_msc_is_writable_cb(p_cbw->lun); } - if (!writable) { - msc_csw_t* p_csw = &p_msc->csw; + + if ( !writable ) + { + // Not writable, complete this SCSI op with error + msc_csw_t *p_csw = &p_msc->csw; + + p_msc->stage = MSC_STAGE_STATUS; + p_csw->status = MSC_CSW_STATUS_FAILED; p_csw->data_residue = p_cbw->total_bytes; - p_csw->status = MSC_CSW_STATUS_FAILED; - tud_msc_set_sense(p_cbw->lun, SCSI_SENSE_DATA_PROTECT, 0x27, 0x00); // Sense = Write protected + tud_msc_set_sense(p_cbw->lun, SCSI_SENSE_DATA_PROTECT, 0x27, 0x00); // Sense = Write protected usbd_edpt_stall(rhport, p_msc->ep_out); return; } diff --git a/src/class/msc/msc_device.h b/src/class/msc/msc_device.h index 8f90ef4ad..d32694340 100644 --- a/src/class/msc/msc_device.h +++ b/src/class/msc/msc_device.h @@ -140,7 +140,7 @@ TU_ATTR_WEAK void tud_msc_write10_complete_cb(uint8_t lun); // Invoked when command in tud_msc_scsi_cb is complete TU_ATTR_WEAK void tud_msc_scsi_complete_cb(uint8_t lun, uint8_t const scsi_cmd[16]); -// Hook to make a mass storage device read-only. TODO remove +// Invoked to check if device is writable as part of SCSI WRITE10 TU_ATTR_WEAK bool tud_msc_is_writable_cb(uint8_t lun); //--------------------------------------------------------------------+ diff --git a/src/common/tusb_common.h b/src/common/tusb_common.h index c2356ffee..1452e0105 100644 --- a/src/common/tusb_common.h +++ b/src/common/tusb_common.h @@ -369,12 +369,17 @@ typedef struct static inline const char* tu_lookup_find(tu_lookup_table_t const* p_table, uint32_t key) { + static char not_found[10]; + for(uint16_t i=0; icount; i++) { if (p_table->items[i].key == key) return p_table->items[i].data; } - return NULL; + // not found return the key value in hex + sprintf(not_found, "0x%08lX", key); + + return not_found; } #endif // CFG_TUSB_DEBUG diff --git a/src/device/usbd.c b/src/device/usbd.c index b2babb7a0..7cd8fad42 100644 --- a/src/device/usbd.c +++ b/src/device/usbd.c @@ -695,7 +695,7 @@ static bool process_control_request(uint8_t rhport, tusb_control_request_t const if ( _usbd_dev.cfg_num ) { // already configured: need to clear all endpoints and driver first - TU_LOG(USBD_DBG, "Clear current config (%u) before switching\r\n", _usbd_dev.cfg_num); + TU_LOG(USBD_DBG, " Clear current Configuration (%u) before switching\r\n", _usbd_dev.cfg_num); // close all non-control endpoints, cancel all pending transfers if any dcd_edpt_close_all(rhport); @@ -1333,7 +1333,7 @@ bool usbd_edpt_busy(uint8_t rhport, uint8_t ep_addr) void usbd_edpt_stall(uint8_t rhport, uint8_t ep_addr) { - TU_LOG(USBD_DBG, " Stall EP %02X", ep_addr); + TU_LOG(USBD_DBG, " Stall EP %02X\r\n", ep_addr); uint8_t const epnum = tu_edpt_number(ep_addr); uint8_t const dir = tu_edpt_dir(ep_addr); @@ -1345,12 +1345,11 @@ void usbd_edpt_stall(uint8_t rhport, uint8_t ep_addr) void usbd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr) { - TU_LOG(USBD_DBG, " Clear Stall EP %02X", ep_addr); + TU_LOG(USBD_DBG, " Clear Stall EP %02X\r\n", ep_addr); uint8_t const epnum = tu_edpt_number(ep_addr); uint8_t const dir = tu_edpt_dir(ep_addr); - dcd_edpt_clear_stall(rhport, ep_addr); _usbd_dev.ep_status[epnum][dir].stalled = false; _usbd_dev.ep_status[epnum][dir].busy = false; -- cgit v1.3.1 From 032770682ee856a32d0087ae9fd9a04c03e2bd0e Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 27 Aug 2021 13:18:51 +0700 Subject: minor clean up --- src/class/msc/msc_device.c | 36 +++++++++++++++++++----------------- 1 file changed, 19 insertions(+), 17 deletions(-) (limited to 'src/class') diff --git a/src/class/msc/msc_device.c b/src/class/msc/msc_device.c index 9e3689d84..c0ea5ae40 100644 --- a/src/class/msc/msc_device.c +++ b/src/class/msc/msc_device.c @@ -99,6 +99,18 @@ static inline uint16_t rdwr10_get_blockcount(uint8_t const command[]) return tu_ntohs(block_count); } +static inline bool send_csw(uint8_t rhport, mscd_interface_t* p_msc) +{ + p_msc->stage = MSC_STAGE_STATUS_SENT; + return usbd_edpt_xfer(rhport, p_msc->ep_in , (uint8_t*) &p_msc->csw, sizeof(msc_csw_t)); +} + +static inline bool prepare_cbw(uint8_t rhport, mscd_interface_t* p_msc) +{ + p_msc->stage = MSC_STAGE_CMD; + return usbd_edpt_xfer(rhport, p_msc->ep_out, (uint8_t*) &p_msc->cbw, sizeof(msc_cbw_t)); +} + //--------------------------------------------------------------------+ // Debug //--------------------------------------------------------------------+ @@ -175,12 +187,12 @@ uint16_t mscd_open(uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint1 TU_ASSERT( usbd_open_edpt_pair(rhport, tu_desc_next(itf_desc), 2, TUSB_XFER_BULK, &p_msc->ep_out, &p_msc->ep_in), 0 ); // Prepare for Command Block Wrapper - TU_ASSERT( usbd_edpt_xfer(rhport, p_msc->ep_out, (uint8_t*) &p_msc->cbw, sizeof(msc_cbw_t)), drv_len); + TU_ASSERT( prepare_cbw(rhport, p_msc), drv_len); return drv_len; } -static void process_bot_reset(mscd_interface_t* p_msc) +static void proc_bot_reset(mscd_interface_t* p_msc) { p_msc->stage = MSC_STAGE_CMD; p_msc->total_len = 0; @@ -191,7 +203,6 @@ static void process_bot_reset(mscd_interface_t* p_msc) p_msc->add_sense_qualifier = 0; } - // Invoked when a control transfer occurred on an interface of this class // Driver response accordingly to the request and the transfer stage (setup/data/ack) // return false to stall control endpoint (e.g unsupported request) @@ -223,8 +234,7 @@ bool mscd_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t if ( p_msc->stage == MSC_STAGE_STATUS ) { // resume sending SCSI status if we are in this stage previously before stalled - p_msc->stage = MSC_STAGE_STATUS_SENT; - TU_ASSERT( usbd_edpt_xfer(rhport, p_msc->ep_in , (uint8_t*) &p_msc->csw, sizeof(msc_csw_t)) ); + TU_ASSERT( send_csw(rhport, p_msc) ); } } else if ( ep_addr == p_msc->ep_out ) @@ -232,7 +242,7 @@ bool mscd_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t if ( p_msc->stage == MSC_STAGE_CMD ) { // part of reset recovery (probably due to invalid CBW) -> prepare for new command - TU_ASSERT( usbd_edpt_xfer(rhport, p_msc->ep_out, (uint8_t*) &p_msc->cbw, sizeof(msc_cbw_t)) ); + TU_ASSERT( prepare_cbw(rhport, p_msc) ); } } } @@ -250,7 +260,7 @@ bool mscd_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t TU_VERIFY(request->wValue == 0 && request->wLength == 0); // driver state reset - process_bot_reset(p_msc); + proc_bot_reset(p_msc); tud_control_status(rhport, request); break; @@ -495,11 +505,7 @@ bool mscd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t event, uint32_t break; } - // Move to default CMD stage - p_msc->stage = MSC_STAGE_CMD; - - // Queue for the next CBW - TU_ASSERT( usbd_edpt_xfer(rhport, p_msc->ep_out, (uint8_t*) &p_msc->cbw, sizeof(msc_cbw_t)) ); + TU_ASSERT( prepare_cbw(rhport, p_msc) ); } break; @@ -511,11 +517,7 @@ bool mscd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t event, uint32_t // skip status if epin is currently stalled, will do it when received Clear Stall request if ( !usbd_edpt_stalled(rhport, p_msc->ep_in) ) { - // Move to Status Sent stage - p_msc->stage = MSC_STAGE_STATUS_SENT; - - // Send SCSI Status - TU_ASSERT(usbd_edpt_xfer(rhport, p_msc->ep_in , (uint8_t*) &p_msc->csw, sizeof(msc_csw_t))); + TU_ASSERT( send_csw(rhport, p_msc) ); } } -- cgit v1.3.1 From 893dceb1984d6304918a45ec8be5a63d3e9993ca Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 27 Aug 2021 17:30:02 +0700 Subject: refactor msc device --- src/class/msc/msc_device.c | 271 +++++++++++++++++++++++++++------------------ 1 file changed, 162 insertions(+), 109 deletions(-) (limited to 'src/class') diff --git a/src/class/msc/msc_device.c b/src/class/msc/msc_device.c index c0ea5ae40..716b7e503 100644 --- a/src/class/msc/msc_device.c +++ b/src/class/msc/msc_device.c @@ -79,25 +79,9 @@ CFG_TUSB_MEM_SECTION CFG_TUSB_MEM_ALIGN static uint8_t _mscd_buf[CFG_TUD_MSC_EP_ //--------------------------------------------------------------------+ static int32_t proc_builtin_scsi(uint8_t lun, uint8_t const scsi_cmd[16], uint8_t* buffer, uint32_t bufsize); static void proc_read10_cmd(uint8_t rhport, mscd_interface_t* p_msc); -static void proc_write10_cmd(uint8_t rhport, mscd_interface_t* p_msc); - -static inline uint32_t rdwr10_get_lba(uint8_t const command[]) -{ - // use offsetof to avoid pointer to the odd/unaligned address - uint32_t const lba = tu_unaligned_read32(command + offsetof(scsi_write10_t, lba)); - - // lba is in Big Endian - return tu_ntohl(lba); -} - -static inline uint16_t rdwr10_get_blockcount(uint8_t const command[]) -{ - // use offsetof to avoid pointer to the odd/misaligned address - uint16_t const block_count = tu_unaligned_read16(command + offsetof(scsi_write10_t, block_count)); - // block count is in Big Endian - return tu_ntohs(block_count); -} +static void proc_write10_cmd(uint8_t rhport, mscd_interface_t* p_msc); +static void proc_write10_new_data(uint8_t rhport, mscd_interface_t* p_msc, uint32_t xferred_bytes); static inline bool send_csw(uint8_t rhport, mscd_interface_t* p_msc) { @@ -111,6 +95,20 @@ static inline bool prepare_cbw(uint8_t rhport, mscd_interface_t* p_msc) return usbd_edpt_xfer(rhport, p_msc->ep_out, (uint8_t*) &p_msc->cbw, sizeof(msc_cbw_t)); } +static void fail_scsi_op(uint8_t rhport, mscd_interface_t* p_msc, uint8_t status) +{ + msc_cbw_t const * p_cbw = &p_msc->cbw; + msc_csw_t * p_csw = &p_msc->csw; + + p_csw->status = status; + p_csw->data_residue = p_cbw->total_bytes - p_msc->xferred_len; + + p_msc->stage = MSC_STAGE_STATUS; + + // failed but sense key is not set: default to Illegal Request + if ( p_msc->sense_key == 0 ) tud_msc_set_sense(p_cbw->lun, SCSI_SENSE_ILLEGAL_REQUEST, 0x20, 0x00); +} + //--------------------------------------------------------------------+ // Debug //--------------------------------------------------------------------+ @@ -358,12 +356,7 @@ bool mscd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t event, uint32_t if ( resplen < 0 ) { - p_msc->total_len = 0; - p_csw->status = MSC_CSW_STATUS_FAILED; - p_msc->stage = MSC_STAGE_STATUS; - - // failed but senskey is not set: default to Illegal Request - if ( p_msc->sense_key == 0 ) tud_msc_set_sense(p_cbw->lun, SCSI_SENSE_ILLEGAL_REQUEST, 0x20, 0x00); + fail_scsi_op(rhport, p_msc, MSC_CSW_STATUS_FAILED); // Stall bulk In if needed if (p_cbw->total_bytes) usbd_edpt_stall(rhport, p_msc->ep_in); @@ -390,10 +383,27 @@ bool mscd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t event, uint32_t TU_LOG(MSC_DEBUG, " SCSI Data\r\n"); //TU_LOG_MEM(MSC_DEBUG, _mscd_buf, xferred_bytes, 2); - // OUT transfer, invoke callback if needed - if ( !tu_bit_test(p_cbw->dir, 7) ) + if (SCSI_CMD_READ_10 == p_cbw->command[0]) + { + p_msc->xferred_len += xferred_bytes; + + if ( p_msc->xferred_len >= p_msc->total_len ) + { + // Data Stage is complete + p_msc->stage = MSC_STAGE_STATUS; + }else + { + proc_read10_cmd(rhport, p_msc); + } + } + else if (SCSI_CMD_WRITE_10 == p_cbw->command[0]) + { + proc_write10_new_data(rhport, p_msc, xferred_bytes); + } + else { - if ( SCSI_CMD_WRITE_10 != p_cbw->command[0] ) + // OUT transfer, invoke callback if needed + if ( !tu_bit_test(p_cbw->dir, 7) ) { int32_t cb_result = tud_msc_scsi_cb(p_cbw->lun, p_cbw->command, _mscd_buf, p_msc->total_len); @@ -406,74 +416,46 @@ bool mscd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t event, uint32_t p_csw->status = MSC_CSW_STATUS_PASSED; } } - else - { - uint16_t const block_sz = p_cbw->total_bytes / rdwr10_get_blockcount(p_cbw->command); - - // Adjust lba with transferred bytes - uint32_t const lba = rdwr10_get_lba(p_cbw->command) + (p_msc->xferred_len / block_sz); - - // Application can consume smaller bytes - int32_t nbytes = tud_msc_write10_cb(p_cbw->lun, lba, p_msc->xferred_len % block_sz, _mscd_buf, xferred_bytes); - - if ( nbytes < 0 ) - { - // negative means error -> skip to status phase, status in CSW set to failed - p_csw->data_residue = p_cbw->total_bytes - p_msc->xferred_len; - p_csw->status = MSC_CSW_STATUS_FAILED; - p_msc->stage = MSC_STAGE_STATUS; - - tud_msc_set_sense(p_cbw->lun, SCSI_SENSE_ILLEGAL_REQUEST, 0x20, 0x00); // Sense = Invalid Command Operation - break; - }else - { - // Application consume less than what we got (including zero) - if ( nbytes < (int32_t) xferred_bytes ) - { - if ( nbytes > 0 ) - { - p_msc->xferred_len += nbytes; - memmove(_mscd_buf, _mscd_buf+nbytes, xferred_bytes-nbytes); - } - - // simulate an transfer complete with adjusted parameters --> this driver callback will fired again - dcd_event_xfer_complete(rhport, p_msc->ep_out, xferred_bytes-nbytes, XFER_RESULT_SUCCESS, false); - - return true; // skip the rest - } - else - { - // Application consume all bytes in our buffer. Nothing to do, process with normal flow - } - } - } - } - // Accumulate data so far - p_msc->xferred_len += xferred_bytes; + p_msc->xferred_len += xferred_bytes; - if ( p_msc->xferred_len >= p_msc->total_len ) - { - // Data Stage is complete - p_msc->stage = MSC_STAGE_STATUS; - } - else - { - // READ10 & WRITE10 Can be executed with large bulk of data e.g write 8K bytes (several flash write) - // We break it into multiple smaller command whose data size is up to CFG_TUD_MSC_EP_BUFSIZE - if (SCSI_CMD_READ_10 == p_cbw->command[0]) + if ( p_msc->xferred_len >= p_msc->total_len ) { - proc_read10_cmd(rhport, p_msc); + // Data Stage is complete + p_msc->stage = MSC_STAGE_STATUS; } - else if (SCSI_CMD_WRITE_10 == p_cbw->command[0]) - { - proc_write10_cmd(rhport, p_msc); - }else + else { - // No other command take more than one transfer yet -> unlikely error + // No command take more than one transfer yet -> unlikely error TU_BREAKPOINT(); } } + +// // Accumulate data so far +// p_msc->xferred_len += xferred_bytes; +// +// if ( p_msc->xferred_len >= p_msc->total_len ) +// { +// // Data Stage is complete +// p_msc->stage = MSC_STAGE_STATUS; +// } +// else +// { +// // READ10 & WRITE10 Can be executed with large bulk of data e.g write 8K bytes (several flash write) +// // We break it into multiple smaller command whose data size is up to CFG_TUD_MSC_EP_BUFSIZE +// if (SCSI_CMD_READ_10 == p_cbw->command[0]) +// { +// proc_read10_cmd(rhport, p_msc); +// } +// else if (SCSI_CMD_WRITE_10 == p_cbw->command[0]) +// { +// proc_write10_cmd(rhport, p_msc); +// }else +// { +// // No other command take more than one transfer yet -> unlikely error +// TU_BREAKPOINT(); +// } +// } break; case MSC_STAGE_STATUS: @@ -535,6 +517,8 @@ static int32_t proc_builtin_scsi(uint8_t lun, uint8_t const scsi_cmd[16], uint8_ (void) bufsize; // TODO refractor later int32_t resplen; + mscd_interface_t* p_msc = &_mscd_itf; + switch ( scsi_cmd[0] ) { case SCSI_CMD_TEST_UNIT_READY: @@ -545,7 +529,7 @@ static int32_t proc_builtin_scsi(uint8_t lun, uint8_t const scsi_cmd[16], uint8_ resplen = - 1; // If sense key is not set by callback, default to Logical Unit Not Ready, Cause Not Reportable - if ( _mscd_itf.sense_key == 0 ) tud_msc_set_sense(lun, SCSI_SENSE_NOT_READY, 0x04, 0x00); + if ( p_msc->sense_key == 0 ) tud_msc_set_sense(lun, SCSI_SENSE_NOT_READY, 0x04, 0x00); } break; @@ -561,7 +545,7 @@ static int32_t proc_builtin_scsi(uint8_t lun, uint8_t const scsi_cmd[16], uint8_ resplen = - 1; // If sense key is not set by callback, default to Logical Unit Not Ready, Cause Not Reportable - if ( _mscd_itf.sense_key == 0 ) tud_msc_set_sense(lun, SCSI_SENSE_NOT_READY, 0x04, 0x00); + if ( p_msc->sense_key == 0 ) tud_msc_set_sense(lun, SCSI_SENSE_NOT_READY, 0x04, 0x00); } } break; @@ -582,7 +566,7 @@ static int32_t proc_builtin_scsi(uint8_t lun, uint8_t const scsi_cmd[16], uint8_ resplen = -1; // If sense key is not set by callback, default to Logical Unit Not Ready, Cause Not Reportable - if ( _mscd_itf.sense_key == 0 ) tud_msc_set_sense(lun, SCSI_SENSE_NOT_READY, 0x04, 0x00); + if ( p_msc->sense_key == 0 ) tud_msc_set_sense(lun, SCSI_SENSE_NOT_READY, 0x04, 0x00); }else { scsi_read_capacity10_resp_t read_capa10; @@ -618,7 +602,7 @@ static int32_t proc_builtin_scsi(uint8_t lun, uint8_t const scsi_cmd[16], uint8_ resplen = -1; // If sense key is not set by callback, default to Logical Unit Not Ready, Cause Not Reportable - if ( _mscd_itf.sense_key == 0 ) tud_msc_set_sense(lun, SCSI_SENSE_NOT_READY, 0x04, 0x00); + if ( p_msc->sense_key == 0 ) tud_msc_set_sense(lun, SCSI_SENSE_NOT_READY, 0x04, 0x00); }else { read_fmt_capa.block_num = tu_htonl(block_count); @@ -685,9 +669,9 @@ static int32_t proc_builtin_scsi(uint8_t lun, uint8_t const scsi_cmd[16], uint8_ sense_rsp.add_sense_len = sizeof(scsi_sense_fixed_resp_t) - 8; - sense_rsp.sense_key = _mscd_itf.sense_key; - sense_rsp.add_sense_code = _mscd_itf.add_sense_code; - sense_rsp.add_sense_qualifier = _mscd_itf.add_sense_qualifier; + sense_rsp.sense_key = p_msc->sense_key; + sense_rsp.add_sense_code = p_msc->add_sense_code; + sense_rsp.add_sense_qualifier = p_msc->add_sense_qualifier; resplen = sizeof(sense_rsp); memcpy(buffer, &sense_rsp, resplen); @@ -703,15 +687,33 @@ static int32_t proc_builtin_scsi(uint8_t lun, uint8_t const scsi_cmd[16], uint8_ return resplen; } + +static inline uint32_t rdwr10_get_lba(uint8_t const command[]) +{ + // use offsetof to avoid pointer to the odd/unaligned address + uint32_t const lba = tu_unaligned_read32(command + offsetof(scsi_write10_t, lba)); + + // lba is in Big Endian + return tu_ntohl(lba); +} + +static inline uint16_t rdwr10_get_blocksize(msc_cbw_t const* cbw) +{ + // first extract block count in the command + uint16_t block_count = tu_unaligned_read16(cbw->command + offsetof(scsi_write10_t, block_count)); + block_count = tu_ntohs(block_count); + + // invalid block count + if (block_count == 0) return 0; + + return cbw->total_bytes / block_count; +} + static void proc_read10_cmd(uint8_t rhport, mscd_interface_t* p_msc) { msc_cbw_t const * p_cbw = &p_msc->cbw; - msc_csw_t * p_csw = &p_msc->csw; - - uint16_t const block_cnt = rdwr10_get_blockcount(p_cbw->command); - TU_ASSERT(block_cnt, ); // prevent div by zero - uint16_t const block_sz = p_cbw->total_bytes / block_cnt; + uint16_t const block_sz = rdwr10_get_blocksize(p_cbw); TU_ASSERT(block_sz, ); // prevent div by zero // Adjust lba with transferred bytes @@ -726,11 +728,11 @@ static void proc_read10_cmd(uint8_t rhport, mscd_interface_t* p_msc) if ( nbytes < 0 ) { // negative means error -> endpoint is stalled & status in CSW set to failed - p_msc->stage = MSC_STAGE_STATUS; - p_csw->data_residue = p_cbw->total_bytes - p_msc->xferred_len; - p_csw->status = MSC_CSW_STATUS_FAILED; - tud_msc_set_sense(p_cbw->lun, SCSI_SENSE_ILLEGAL_REQUEST, 0x20, 0x00); // Sense = Invalid Command Operation + // Sense = Flash not ready for access + tud_msc_set_sense(p_cbw->lun, SCSI_SENSE_MEDIUM_ERROR, 0x33, 0x00); + + fail_scsi_op(rhport, p_msc, MSC_CSW_STATUS_FAILED); usbd_edpt_stall(rhport, p_msc->ep_in); } else if ( nbytes == 0 ) @@ -757,13 +759,10 @@ static void proc_write10_cmd(uint8_t rhport, mscd_interface_t* p_msc) if ( !writable ) { // Not writable, complete this SCSI op with error - msc_csw_t *p_csw = &p_msc->csw; - - p_msc->stage = MSC_STAGE_STATUS; - p_csw->status = MSC_CSW_STATUS_FAILED; - p_csw->data_residue = p_cbw->total_bytes; + // Sense = Write protected + tud_msc_set_sense(p_cbw->lun, SCSI_SENSE_DATA_PROTECT, 0x27, 0x00); - tud_msc_set_sense(p_cbw->lun, SCSI_SENSE_DATA_PROTECT, 0x27, 0x00); // Sense = Write protected + fail_scsi_op(rhport, p_msc, MSC_CSW_STATUS_FAILED); usbd_edpt_stall(rhport, p_msc->ep_out); return; } @@ -775,4 +774,58 @@ static void proc_write10_cmd(uint8_t rhport, mscd_interface_t* p_msc) TU_ASSERT( usbd_edpt_xfer(rhport, p_msc->ep_out, _mscd_buf, nbytes), ); } +// process new data arrived from WRITE10 +static void proc_write10_new_data(uint8_t rhport, mscd_interface_t* p_msc, uint32_t xferred_bytes) +{ + msc_cbw_t const * p_cbw = &p_msc->cbw; + + uint16_t const block_sz = rdwr10_get_blocksize(p_cbw); + TU_ASSERT(block_sz, ); // prevent div by zero + + // Adjust lba with transferred bytes + uint32_t const lba = rdwr10_get_lba(p_cbw->command) + (p_msc->xferred_len / block_sz); + + // Application can consume smaller bytes + int32_t nbytes = tud_msc_write10_cb(p_cbw->lun, lba, p_msc->xferred_len % block_sz, _mscd_buf, xferred_bytes); + + if ( nbytes < 0 ) + { + // negative means error -> failed this scsi op + + // Sense = Flash not ready for access + tud_msc_set_sense(p_cbw->lun, SCSI_SENSE_MEDIUM_ERROR, 0x33, 0x00); + + fail_scsi_op(rhport, p_msc, MSC_CSW_STATUS_FAILED); + usbd_edpt_stall(rhport, p_msc->ep_out); + }else + { + // Application consume less than what we got (including zero) + if ( nbytes < (int32_t) xferred_bytes ) + { + if ( nbytes > 0 ) + { + p_msc->xferred_len += nbytes; + memmove(_mscd_buf, _mscd_buf+nbytes, xferred_bytes-nbytes); + } + + // simulate an transfer complete with adjusted parameters --> this driver callback will fired again + dcd_event_xfer_complete(rhport, p_msc->ep_out, xferred_bytes-nbytes, XFER_RESULT_SUCCESS, false); + } + else + { + // Application consume all bytes in our buffer, prepare to receive more data from host + p_msc->xferred_len += xferred_bytes; + + if ( p_msc->xferred_len >= p_msc->total_len ) + { + // Data Stage is complete + p_msc->stage = MSC_STAGE_STATUS; + }else + { + proc_write10_cmd(rhport, p_msc); + } + } + } +} + #endif -- cgit v1.3.1 From 2667ce6981b409a0431a00d48a37f58bf3aa5875 Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 27 Aug 2021 17:50:02 +0700 Subject: fix BOT case 2 test compliant --- src/class/msc/msc_device.c | 34 +++++++--------------------------- 1 file changed, 7 insertions(+), 27 deletions(-) (limited to 'src/class') diff --git a/src/class/msc/msc_device.c b/src/class/msc/msc_device.c index 716b7e503..cc495a1c4 100644 --- a/src/class/msc/msc_device.c +++ b/src/class/msc/msc_device.c @@ -430,32 +430,6 @@ bool mscd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t event, uint32_t TU_BREAKPOINT(); } } - -// // Accumulate data so far -// p_msc->xferred_len += xferred_bytes; -// -// if ( p_msc->xferred_len >= p_msc->total_len ) -// { -// // Data Stage is complete -// p_msc->stage = MSC_STAGE_STATUS; -// } -// else -// { -// // READ10 & WRITE10 Can be executed with large bulk of data e.g write 8K bytes (several flash write) -// // We break it into multiple smaller command whose data size is up to CFG_TUD_MSC_EP_BUFSIZE -// if (SCSI_CMD_READ_10 == p_cbw->command[0]) -// { -// proc_read10_cmd(rhport, p_msc); -// } -// else if (SCSI_CMD_WRITE_10 == p_cbw->command[0]) -// { -// proc_write10_cmd(rhport, p_msc); -// }else -// { -// // No other command take more than one transfer yet -> unlikely error -// TU_BREAKPOINT(); -// } -// } break; case MSC_STAGE_STATUS: @@ -714,7 +688,13 @@ static void proc_read10_cmd(uint8_t rhport, mscd_interface_t* p_msc) msc_cbw_t const * p_cbw = &p_msc->cbw; uint16_t const block_sz = rdwr10_get_blocksize(p_cbw); - TU_ASSERT(block_sz, ); // prevent div by zero + + if ( block_sz == 0 ) + { + // 6.7.1 BOT The 13 Cases: case 2 and 3 when cbw->total_bytes == 0 + fail_scsi_op(rhport, p_msc, MSC_CSW_STATUS_FAILED); + return; + } // Adjust lba with transferred bytes uint32_t const lba = rdwr10_get_lba(p_cbw->command) + (p_msc->xferred_len / block_sz); -- cgit v1.3.1 From e01239ccc936d32cb2933dba3a78555d0e47d17c Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 27 Aug 2021 20:05:56 +0700 Subject: more msc refactoring --- src/class/msc/msc_device.c | 35 ++++++++++++++++++++++------------- 1 file changed, 22 insertions(+), 13 deletions(-) (limited to 'src/class') diff --git a/src/class/msc/msc_device.c b/src/class/msc/msc_device.c index cc495a1c4..a25fa6109 100644 --- a/src/class/msc/msc_device.c +++ b/src/class/msc/msc_device.c @@ -107,6 +107,18 @@ static void fail_scsi_op(uint8_t rhport, mscd_interface_t* p_msc, uint8_t status // failed but sense key is not set: default to Illegal Request if ( p_msc->sense_key == 0 ) tud_msc_set_sense(p_cbw->lun, SCSI_SENSE_ILLEGAL_REQUEST, 0x20, 0x00); + + // If there is data stage, stall it + if ( p_cbw->total_bytes ) + { + if ( tu_bit_test(p_cbw->dir, 7) ) + { + usbd_edpt_stall(rhport, p_msc->ep_in); + }else + { + usbd_edpt_stall(rhport, p_msc->ep_out); + } + } } //--------------------------------------------------------------------+ @@ -343,12 +355,10 @@ bool mscd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t event, uint32_t TU_ASSERT( usbd_edpt_xfer(rhport, p_msc->ep_out, _mscd_buf, p_msc->total_len) ); }else { - int32_t resplen; - // First process if it is a built-in commands - resplen = proc_builtin_scsi(p_cbw->lun, p_cbw->command, _mscd_buf, sizeof(_mscd_buf)); + int32_t resplen = proc_builtin_scsi(p_cbw->lun, p_cbw->command, _mscd_buf, sizeof(_mscd_buf)); - // Not built-in, invoke user callback + // Invoke user callback if not built-in if ( (resplen < 0) && (p_msc->sense_key == 0) ) { resplen = tud_msc_scsi_cb(p_cbw->lun, p_cbw->command, _mscd_buf, p_msc->total_len); @@ -356,10 +366,8 @@ bool mscd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t event, uint32_t if ( resplen < 0 ) { + // unsupported command fail_scsi_op(rhport, p_msc, MSC_CSW_STATUS_FAILED); - - // Stall bulk In if needed - if (p_cbw->total_bytes) usbd_edpt_stall(rhport, p_msc->ep_in); } else { @@ -692,7 +700,7 @@ static void proc_read10_cmd(uint8_t rhport, mscd_interface_t* p_msc) if ( block_sz == 0 ) { // 6.7.1 BOT The 13 Cases: case 2 and 3 when cbw->total_bytes == 0 - fail_scsi_op(rhport, p_msc, MSC_CSW_STATUS_FAILED); + fail_scsi_op(rhport, p_msc, MSC_CSW_STATUS_PHASE_ERROR); return; } @@ -713,7 +721,6 @@ static void proc_read10_cmd(uint8_t rhport, mscd_interface_t* p_msc) tud_msc_set_sense(p_cbw->lun, SCSI_SENSE_MEDIUM_ERROR, 0x33, 0x00); fail_scsi_op(rhport, p_msc, MSC_CSW_STATUS_FAILED); - usbd_edpt_stall(rhport, p_msc->ep_in); } else if ( nbytes == 0 ) { @@ -741,9 +748,7 @@ static void proc_write10_cmd(uint8_t rhport, mscd_interface_t* p_msc) // Not writable, complete this SCSI op with error // Sense = Write protected tud_msc_set_sense(p_cbw->lun, SCSI_SENSE_DATA_PROTECT, 0x27, 0x00); - fail_scsi_op(rhport, p_msc, MSC_CSW_STATUS_FAILED); - usbd_edpt_stall(rhport, p_msc->ep_out); return; } @@ -760,7 +765,12 @@ static void proc_write10_new_data(uint8_t rhport, mscd_interface_t* p_msc, uint3 msc_cbw_t const * p_cbw = &p_msc->cbw; uint16_t const block_sz = rdwr10_get_blocksize(p_cbw); - TU_ASSERT(block_sz, ); // prevent div by zero + if ( block_sz == 0 ) + { + // 6.7.1 BOT The 13 Cases: case 2 and 3 when cbw->total_bytes == 0 + fail_scsi_op(rhport, p_msc, MSC_CSW_STATUS_PHASE_ERROR); + return; + } // Adjust lba with transferred bytes uint32_t const lba = rdwr10_get_lba(p_cbw->command) + (p_msc->xferred_len / block_sz); @@ -776,7 +786,6 @@ static void proc_write10_new_data(uint8_t rhport, mscd_interface_t* p_msc, uint3 tud_msc_set_sense(p_cbw->lun, SCSI_SENSE_MEDIUM_ERROR, 0x33, 0x00); fail_scsi_op(rhport, p_msc, MSC_CSW_STATUS_FAILED); - usbd_edpt_stall(rhport, p_msc->ep_out); }else { // Application consume less than what we got (including zero) -- cgit v1.3.1 From c6b9f8a530e9dd9a6ec7e4f55016f275ddcdaa67 Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 27 Aug 2021 23:33:11 +0700 Subject: fix msc case 3 complaint test --- src/class/msc/msc_device.c | 78 ++++++++++++++++++++++------------------------ 1 file changed, 37 insertions(+), 41 deletions(-) (limited to 'src/class') diff --git a/src/class/msc/msc_device.c b/src/class/msc/msc_device.c index a25fa6109..11fc4e80f 100644 --- a/src/class/msc/msc_device.c +++ b/src/class/msc/msc_device.c @@ -121,6 +121,27 @@ static void fail_scsi_op(uint8_t rhport, mscd_interface_t* p_msc, uint8_t status } } +static inline uint32_t rdwr10_get_lba(uint8_t const command[]) +{ + // use offsetof to avoid pointer to the odd/unaligned address + uint32_t const lba = tu_unaligned_read32(command + offsetof(scsi_write10_t, lba)); + + // lba is in Big Endian + return tu_ntohl(lba); +} + +static inline uint16_t rdwr10_get_blocksize(msc_cbw_t const* cbw) +{ + // first extract block count in the command + uint16_t block_count = tu_unaligned_read16(cbw->command + offsetof(scsi_write10_t, block_count)); + block_count = tu_ntohs(block_count); + + // invalid block count + if (block_count == 0) return 0; + + return cbw->total_bytes / block_count; +} + //--------------------------------------------------------------------+ // Debug //--------------------------------------------------------------------+ @@ -336,13 +357,21 @@ bool mscd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t event, uint32_t p_msc->total_len = p_cbw->total_bytes; p_msc->xferred_len = 0; - if (SCSI_CMD_READ_10 == p_cbw->command[0]) + if (SCSI_CMD_READ_10 == p_cbw->command[0] || SCSI_CMD_WRITE_10 == p_cbw->command[0]) { - proc_read10_cmd(rhport, p_msc); - } - else if (SCSI_CMD_WRITE_10 == p_cbw->command[0]) - { - proc_write10_cmd(rhport, p_msc); + if ( rdwr10_get_blocksize(p_cbw) == 0 ) + { + // Invalid CBW length == 0 (not match SCSI command block count) + // 6.7.1 BOT The 13 Cases: case 2 and case 3 -> phase error + fail_scsi_op(rhport, p_msc, MSC_CSW_STATUS_PHASE_ERROR); + } + else if (SCSI_CMD_READ_10 == p_cbw->command[0]) + { + proc_read10_cmd(rhport, p_msc); + }else + { + proc_write10_cmd(rhport, p_msc); + } } else { @@ -669,41 +698,13 @@ static int32_t proc_builtin_scsi(uint8_t lun, uint8_t const scsi_cmd[16], uint8_ return resplen; } - -static inline uint32_t rdwr10_get_lba(uint8_t const command[]) -{ - // use offsetof to avoid pointer to the odd/unaligned address - uint32_t const lba = tu_unaligned_read32(command + offsetof(scsi_write10_t, lba)); - - // lba is in Big Endian - return tu_ntohl(lba); -} - -static inline uint16_t rdwr10_get_blocksize(msc_cbw_t const* cbw) -{ - // first extract block count in the command - uint16_t block_count = tu_unaligned_read16(cbw->command + offsetof(scsi_write10_t, block_count)); - block_count = tu_ntohs(block_count); - - // invalid block count - if (block_count == 0) return 0; - - return cbw->total_bytes / block_count; -} - static void proc_read10_cmd(uint8_t rhport, mscd_interface_t* p_msc) { msc_cbw_t const * p_cbw = &p_msc->cbw; + // block size already verified not zero uint16_t const block_sz = rdwr10_get_blocksize(p_cbw); - if ( block_sz == 0 ) - { - // 6.7.1 BOT The 13 Cases: case 2 and 3 when cbw->total_bytes == 0 - fail_scsi_op(rhport, p_msc, MSC_CSW_STATUS_PHASE_ERROR); - return; - } - // Adjust lba with transferred bytes uint32_t const lba = rdwr10_get_lba(p_cbw->command) + (p_msc->xferred_len / block_sz); @@ -764,13 +765,8 @@ static void proc_write10_new_data(uint8_t rhport, mscd_interface_t* p_msc, uint3 { msc_cbw_t const * p_cbw = &p_msc->cbw; + // block size already verified not zero uint16_t const block_sz = rdwr10_get_blocksize(p_cbw); - if ( block_sz == 0 ) - { - // 6.7.1 BOT The 13 Cases: case 2 and 3 when cbw->total_bytes == 0 - fail_scsi_op(rhport, p_msc, MSC_CSW_STATUS_PHASE_ERROR); - return; - } // Adjust lba with transferred bytes uint32_t const lba = rdwr10_get_lba(p_cbw->command) + (p_msc->xferred_len / block_sz); -- cgit v1.3.1 From 53ea1e13243eae30455cc008eda0ee5d63ccf361 Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 27 Aug 2021 23:52:59 +0700 Subject: fix msc test case 8 and 10 --- src/class/msc/msc_device.c | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) (limited to 'src/class') diff --git a/src/class/msc/msc_device.c b/src/class/msc/msc_device.c index 11fc4e80f..e29cd473a 100644 --- a/src/class/msc/msc_device.c +++ b/src/class/msc/msc_device.c @@ -357,17 +357,25 @@ bool mscd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t event, uint32_t p_msc->total_len = p_cbw->total_bytes; p_msc->xferred_len = 0; - if (SCSI_CMD_READ_10 == p_cbw->command[0] || SCSI_CMD_WRITE_10 == p_cbw->command[0]) + if ( SCSI_CMD_READ_10 == p_cbw->command[0] ) { - if ( rdwr10_get_blocksize(p_cbw) == 0 ) + // Invalid CBW length == 0 or Direction bit is incorrect + // 6.7 The 13 Cases: case 2, case 3, case 10 -> phase error + if ( rdwr10_get_blocksize(p_cbw) == 0 || !tu_bit_test(p_cbw->dir, 7) ) { - // Invalid CBW length == 0 (not match SCSI command block count) - // 6.7.1 BOT The 13 Cases: case 2 and case 3 -> phase error fail_scsi_op(rhport, p_msc, MSC_CSW_STATUS_PHASE_ERROR); - } - else if (SCSI_CMD_READ_10 == p_cbw->command[0]) + }else { proc_read10_cmd(rhport, p_msc); + } + } + else if (SCSI_CMD_WRITE_10 == p_cbw->command[0]) + { + // Invalid CBW length == 0 or Direction bit is incorrect + // 6.7 The 13 Cases: case 2, case 3, case 8 -> phase error + if ( rdwr10_get_blocksize(p_cbw) == 0 || tu_bit_test(p_cbw->dir, 7) ) + { + fail_scsi_op(rhport, p_msc, MSC_CSW_STATUS_PHASE_ERROR); }else { proc_write10_cmd(rhport, p_msc); -- cgit v1.3.1 From be98cd56c7ac3bbd8b8762e42f752c9cec7c92f0 Mon Sep 17 00:00:00 2001 From: hathach Date: Sun, 29 Aug 2021 00:29:20 +0700 Subject: update msc to be more robuse add more log, pass more complaint test --- src/class/msc/msc_device.c | 87 ++++++++++++++++++++++++++++++++++------------ 1 file changed, 65 insertions(+), 22 deletions(-) (limited to 'src/class') diff --git a/src/class/msc/msc_device.c b/src/class/msc/msc_device.c index e29cd473a..792d26dea 100644 --- a/src/class/msc/msc_device.c +++ b/src/class/msc/msc_device.c @@ -62,7 +62,7 @@ typedef struct // Bulk Only Transfer (BOT) Protocol uint8_t stage; - uint32_t total_len; + uint32_t total_len; // byte to be transferred, can be smaller than total_bytes in cbw uint32_t xferred_len; // numbered of bytes transferred so far in the Data Stage // Sense Response Data @@ -83,8 +83,16 @@ static void proc_read10_cmd(uint8_t rhport, mscd_interface_t* p_msc); static void proc_write10_cmd(uint8_t rhport, mscd_interface_t* p_msc); static void proc_write10_new_data(uint8_t rhport, mscd_interface_t* p_msc, uint32_t xferred_bytes); +TU_ATTR_ALWAYS_INLINE static inline bool is_data_in(uint8_t dir) +{ + return tu_bit_test(dir, 7); +} + static inline bool send_csw(uint8_t rhport, mscd_interface_t* p_msc) { + // Data residue is always = host expect - actual transferred + p_msc->csw.data_residue = p_msc->cbw.total_bytes - p_msc->xferred_len; + p_msc->stage = MSC_STAGE_STATUS_SENT; return usbd_edpt_xfer(rhport, p_msc->ep_in , (uint8_t*) &p_msc->csw, sizeof(msc_csw_t)); } @@ -100,10 +108,9 @@ static void fail_scsi_op(uint8_t rhport, mscd_interface_t* p_msc, uint8_t status msc_cbw_t const * p_cbw = &p_msc->cbw; msc_csw_t * p_csw = &p_msc->csw; - p_csw->status = status; - p_csw->data_residue = p_cbw->total_bytes - p_msc->xferred_len; - - p_msc->stage = MSC_STAGE_STATUS; + // data_residue will be calculated before sending out csw + p_csw->status = status; + p_msc->stage = MSC_STAGE_STATUS; // failed but sense key is not set: default to Illegal Request if ( p_msc->sense_key == 0 ) tud_msc_set_sense(p_cbw->lun, SCSI_SENSE_ILLEGAL_REQUEST, 0x20, 0x00); @@ -111,7 +118,7 @@ static void fail_scsi_op(uint8_t rhport, mscd_interface_t* p_msc, uint8_t status // If there is data stage, stall it if ( p_cbw->total_bytes ) { - if ( tu_bit_test(p_cbw->dir, 7) ) + if ( is_data_in(p_cbw->dir) ) { usbd_edpt_stall(rhport, p_msc->ep_in); }else @@ -335,6 +342,8 @@ bool mscd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t event, uint32_t if ( !(xferred_bytes == sizeof(msc_cbw_t) && p_cbw->signature == MSC_CBW_SIGNATURE) ) { + TU_LOG(MSC_DEBUG, " SCSI CBW is not valid\r\n"); + // BOT 6.6.1 If CBW is not valid stall both endpoints until reset recovery p_msc->stage = MSC_STAGE_NEED_RESET; @@ -351,6 +360,7 @@ bool mscd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t event, uint32_t p_csw->signature = MSC_CSW_SIGNATURE; p_csw->tag = p_cbw->tag; p_csw->data_residue = 0; + p_csw->status = MSC_CSW_STATUS_PASSED; /*------------- Parse command and prepare DATA -------------*/ p_msc->stage = MSC_STAGE_DATA; @@ -360,9 +370,10 @@ bool mscd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t event, uint32_t if ( SCSI_CMD_READ_10 == p_cbw->command[0] ) { // Invalid CBW length == 0 or Direction bit is incorrect - // 6.7 The 13 Cases: case 2, case 3, case 10 -> phase error - if ( rdwr10_get_blocksize(p_cbw) == 0 || !tu_bit_test(p_cbw->dir, 7) ) + // 6.7 The 13 Cases: case 2 (Hn < Di), case 3 (Hn < Do), case 10 (Ho <> Di) -> phase error + if ( rdwr10_get_blocksize(p_cbw) == 0 || !is_data_in(p_cbw->dir) ) { + TU_LOG(MSC_DEBUG, " SCSI ase 2 (Hn < Di), case 3 (Hn < Do), case 10 (Ho <> Di)\r\n"); fail_scsi_op(rhport, p_msc, MSC_CSW_STATUS_PHASE_ERROR); }else { @@ -372,9 +383,10 @@ bool mscd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t event, uint32_t else if (SCSI_CMD_WRITE_10 == p_cbw->command[0]) { // Invalid CBW length == 0 or Direction bit is incorrect - // 6.7 The 13 Cases: case 2, case 3, case 8 -> phase error - if ( rdwr10_get_blocksize(p_cbw) == 0 || tu_bit_test(p_cbw->dir, 7) ) + // 6.7 The 13 Cases: case 2 (Hn < Do), case 3 (Hn < Do), case 8 (Hi <> Do) -> phase error + if ( rdwr10_get_blocksize(p_cbw) == 0 || is_data_in(p_cbw->dir) ) { + TU_LOG(MSC_DEBUG, " SCSI ase 2 (Hn < Di), case 3 (Hn < Do), case 8 (Hi <> Do)\r\n"); fail_scsi_op(rhport, p_msc, MSC_CSW_STATUS_PHASE_ERROR); }else { @@ -386,9 +398,12 @@ bool mscd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t event, uint32_t // For other SCSI commands // 1. OUT : queue transfer (invoke app callback after done) // 2. IN & Zero: Process if is built-in, else Invoke app callback. Skip DATA if zero length - if ( (p_cbw->total_bytes > 0 ) && !tu_bit_test(p_cbw->dir, 7) ) + if ( (p_cbw->total_bytes > 0 ) && !is_data_in(p_cbw->dir) ) { - // queue transfer + // Didn't check for case 9 (Ho > Dn), which requires examining scsi command first + // but it is OK to just receive data then responded with failed status + + // Prepare for Data stage TU_ASSERT( usbd_edpt_xfer(rhport, p_msc->ep_out, _mscd_buf, p_msc->total_len) ); }else { @@ -404,22 +419,36 @@ bool mscd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t event, uint32_t if ( resplen < 0 ) { // unsupported command + TU_LOG(MSC_DEBUG, " SCSI unsupported command\r\n"); fail_scsi_op(rhport, p_msc, MSC_CSW_STATUS_FAILED); } - else + else if (resplen == 0) { - p_msc->total_len = (uint32_t) resplen; - p_csw->status = MSC_CSW_STATUS_PASSED; - - if (p_msc->total_len) + if (p_cbw->total_bytes) { - TU_ASSERT( p_cbw->total_bytes >= p_msc->total_len ); // cannot return more than host expect - TU_ASSERT( usbd_edpt_xfer(rhport, p_msc->ep_in, _mscd_buf, p_msc->total_len) ); + // 6.7 The 13 Cases: case 4 (Hi > Dn) + TU_LOG(MSC_DEBUG, " SCSI case 4 (Hi > Dn): %lu\r\n", p_cbw->total_bytes); + fail_scsi_op(rhport, p_msc, MSC_CSW_STATUS_FAILED); }else { + // case 1 Hn = Dn: all good p_msc->stage = MSC_STAGE_STATUS; } } + else + { + if ( p_cbw->total_bytes == 0 ) + { + // 6.7 The 13 Cases: case 2 (Hn < Di) + TU_LOG(MSC_DEBUG, " SCSI case 2 (Hn < Di): %lu\r\n", p_cbw->total_bytes); + fail_scsi_op(rhport, p_msc, MSC_CSW_STATUS_FAILED); + }else + { + // cannot return more than host expect + p_msc->total_len = tu_min32((uint32_t) resplen, p_cbw->total_bytes); + TU_ASSERT( usbd_edpt_xfer(rhport, p_msc->ep_in, _mscd_buf, p_msc->total_len) ); + } + } } } break; @@ -448,7 +477,7 @@ bool mscd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t event, uint32_t else { // OUT transfer, invoke callback if needed - if ( !tu_bit_test(p_cbw->dir, 7) ) + if ( !is_data_in(p_cbw->dir) ) { int32_t cb_result = tud_msc_scsi_cb(p_cbw->lun, p_cbw->command, _mscd_buf, p_msc->total_len); @@ -485,7 +514,7 @@ bool mscd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t event, uint32_t // Wait for the Status phase to complete if( (ep_addr == p_msc->ep_in) && (xferred_bytes == sizeof(msc_csw_t)) ) { - TU_LOG(MSC_DEBUG, " SCSI Status: %u\r\n", p_csw->status); + TU_LOG(MSC_DEBUG, " SCSI Status = %u\r\n", p_csw->status); // TU_LOG_MEM(MSC_DEBUG, p_csw, xferred_bytes, 2); // Invoke complete callback if defined @@ -507,6 +536,10 @@ bool mscd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t event, uint32_t } TU_ASSERT( prepare_cbw(rhport, p_msc) ); + }else + { + // Any xfer ended here is consider unknown error, ignore it + TU_LOG1(" Warning expect SCSI Status but received unknown data\r\n"); } break; @@ -518,7 +551,15 @@ bool mscd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t event, uint32_t // skip status if epin is currently stalled, will do it when received Clear Stall request if ( !usbd_edpt_stalled(rhport, p_msc->ep_in) ) { - TU_ASSERT( send_csw(rhport, p_msc) ); + if ( (p_cbw->total_bytes > p_msc->xferred_len) && is_data_in(p_cbw->dir) ) + { + // 6.7 The 13 Cases: case 5 (Hi > Di): STALL before status + TU_LOG(MSC_DEBUG, " SCSI case 5 (Hi > Di): %lu > %lu\r\n", p_cbw->total_bytes, p_msc->xferred_len); + usbd_edpt_stall(rhport, p_msc->ep_in); + }else + { + TU_ASSERT( send_csw(rhport, p_msc) ); + } } } @@ -725,6 +766,7 @@ static void proc_read10_cmd(uint8_t rhport, mscd_interface_t* p_msc) if ( nbytes < 0 ) { // negative means error -> endpoint is stalled & status in CSW set to failed + TU_LOG(MSC_DEBUG, " tud_msc_read10_cb() return -1\r\n"); // Sense = Flash not ready for access tud_msc_set_sense(p_cbw->lun, SCSI_SENSE_MEDIUM_ERROR, 0x33, 0x00); @@ -785,6 +827,7 @@ static void proc_write10_new_data(uint8_t rhport, mscd_interface_t* p_msc, uint3 if ( nbytes < 0 ) { // negative means error -> failed this scsi op + TU_LOG(MSC_DEBUG, " tud_msc_write10_cb() return -1\r\n"); // Sense = Flash not ready for access tud_msc_set_sense(p_cbw->lun, SCSI_SENSE_MEDIUM_ERROR, 0x33, 0x00); -- cgit v1.3.1 From ee18cc42f2771cb63e7e5529f9be376cd0080f5e Mon Sep 17 00:00:00 2001 From: hathach Date: Sun, 29 Aug 2021 12:06:10 +0700 Subject: msc handle more test, passed Command Self Test compliant --- src/class/msc/msc_device.c | 28 +++++++++++++++++----------- 1 file changed, 17 insertions(+), 11 deletions(-) (limited to 'src/class') diff --git a/src/class/msc/msc_device.c b/src/class/msc/msc_device.c index 792d26dea..247575ed4 100644 --- a/src/class/msc/msc_device.c +++ b/src/class/msc/msc_device.c @@ -373,7 +373,7 @@ bool mscd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t event, uint32_t // 6.7 The 13 Cases: case 2 (Hn < Di), case 3 (Hn < Do), case 10 (Ho <> Di) -> phase error if ( rdwr10_get_blocksize(p_cbw) == 0 || !is_data_in(p_cbw->dir) ) { - TU_LOG(MSC_DEBUG, " SCSI ase 2 (Hn < Di), case 3 (Hn < Do), case 10 (Ho <> Di)\r\n"); + TU_LOG(MSC_DEBUG, " SCSI case 2 (Hn < Di), case 3 (Hn < Do), case 10 (Ho <> Di)\r\n"); fail_scsi_op(rhport, p_msc, MSC_CSW_STATUS_PHASE_ERROR); }else { @@ -386,7 +386,7 @@ bool mscd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t event, uint32_t // 6.7 The 13 Cases: case 2 (Hn < Do), case 3 (Hn < Do), case 8 (Hi <> Do) -> phase error if ( rdwr10_get_blocksize(p_cbw) == 0 || is_data_in(p_cbw->dir) ) { - TU_LOG(MSC_DEBUG, " SCSI ase 2 (Hn < Di), case 3 (Hn < Do), case 8 (Hi <> Do)\r\n"); + TU_LOG(MSC_DEBUG, " SCSI case 2 (Hn < Di), case 3 (Hn < Do), case 8 (Hi <> Do)\r\n"); fail_scsi_op(rhport, p_msc, MSC_CSW_STATUS_PHASE_ERROR); }else { @@ -400,11 +400,16 @@ bool mscd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t event, uint32_t // 2. IN & Zero: Process if is built-in, else Invoke app callback. Skip DATA if zero length if ( (p_cbw->total_bytes > 0 ) && !is_data_in(p_cbw->dir) ) { - // Didn't check for case 9 (Ho > Dn), which requires examining scsi command first - // but it is OK to just receive data then responded with failed status - - // Prepare for Data stage - TU_ASSERT( usbd_edpt_xfer(rhport, p_msc->ep_out, _mscd_buf, p_msc->total_len) ); + if (p_cbw->total_bytes > sizeof(_mscd_buf)) + { + TU_LOG(MSC_DEBUG, " SCSI reject non READ10/WRITE10 with large data\r\n"); + fail_scsi_op(rhport, p_msc, MSC_CSW_STATUS_FAILED); + }else + { + // Didn't check for case 9 (Ho > Dn), which requires examining scsi command first + // but it is OK to just receive data then responded with failed status + TU_ASSERT( usbd_edpt_xfer(rhport, p_msc->ep_out, _mscd_buf, p_msc->total_len) ); + } }else { // First process if it is a built-in commands @@ -483,11 +488,12 @@ bool mscd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t event, uint32_t if ( cb_result < 0 ) { - p_csw->status = MSC_CSW_STATUS_FAILED; - tud_msc_set_sense(p_cbw->lun, SCSI_SENSE_ILLEGAL_REQUEST, 0x20, 0x00); // Sense = Invalid Command Operation + // unsupported command + TU_LOG(MSC_DEBUG, " SCSI unsupported command\r\n"); + fail_scsi_op(rhport, p_msc, MSC_CSW_STATUS_FAILED); }else { - p_csw->status = MSC_CSW_STATUS_PASSED; + // TODO haven't implement this scenario any further yet } } @@ -500,7 +506,7 @@ bool mscd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t event, uint32_t } else { - // No command take more than one transfer yet -> unlikely error + // This scenario with command that take more than one transfer is already rejected at Command stage TU_BREAKPOINT(); } } -- cgit v1.3.1 From 4e3ed8159e420b80aa3d558d0ed728460ba4506f Mon Sep 17 00:00:00 2001 From: hathach Date: Sun, 29 Aug 2021 13:34:47 +0700 Subject: passed all USBCV bot complaince test --- src/class/msc/msc_device.c | 35 +++++++++++++++++++++-------------- 1 file changed, 21 insertions(+), 14 deletions(-) (limited to 'src/class') diff --git a/src/class/msc/msc_device.c b/src/class/msc/msc_device.c index 247575ed4..52dfcb836 100644 --- a/src/class/msc/msc_device.c +++ b/src/class/msc/msc_device.c @@ -108,20 +108,21 @@ static void fail_scsi_op(uint8_t rhport, mscd_interface_t* p_msc, uint8_t status msc_cbw_t const * p_cbw = &p_msc->cbw; msc_csw_t * p_csw = &p_msc->csw; - // data_residue will be calculated before sending out csw - p_csw->status = status; - p_msc->stage = MSC_STAGE_STATUS; + p_csw->status = status; + p_csw->data_residue = p_msc->cbw.total_bytes - p_msc->xferred_len; + p_msc->stage = MSC_STAGE_STATUS; // failed but sense key is not set: default to Illegal Request if ( p_msc->sense_key == 0 ) tud_msc_set_sense(p_cbw->lun, SCSI_SENSE_ILLEGAL_REQUEST, 0x20, 0x00); - // If there is data stage, stall it - if ( p_cbw->total_bytes ) + // If there is data stage and not yet complete, stall it + if ( p_cbw->total_bytes && p_csw->data_residue ) { if ( is_data_in(p_cbw->dir) ) { usbd_edpt_stall(rhport, p_msc->ep_in); - }else + } + else { usbd_edpt_stall(rhport, p_msc->ep_out); } @@ -481,6 +482,8 @@ bool mscd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t event, uint32_t } else { + p_msc->xferred_len += xferred_bytes; + // OUT transfer, invoke callback if needed if ( !is_data_in(p_cbw->dir) ) { @@ -497,8 +500,6 @@ bool mscd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t event, uint32_t } } - p_msc->xferred_len += xferred_bytes; - if ( p_msc->xferred_len >= p_msc->total_len ) { // Data Stage is complete @@ -767,7 +768,8 @@ static void proc_read10_cmd(uint8_t rhport, mscd_interface_t* p_msc) int32_t nbytes = (int32_t) tu_min32(sizeof(_mscd_buf), p_cbw->total_bytes-p_msc->xferred_len); // Application can consume smaller bytes - nbytes = tud_msc_read10_cb(p_cbw->lun, lba, p_msc->xferred_len % block_sz, _mscd_buf, (uint32_t) nbytes); + uint32_t const offset = p_msc->xferred_len % block_sz; + nbytes = tud_msc_read10_cb(p_cbw->lun, lba, offset, _mscd_buf, (uint32_t) nbytes); if ( nbytes < 0 ) { @@ -827,14 +829,18 @@ static void proc_write10_new_data(uint8_t rhport, mscd_interface_t* p_msc, uint3 // Adjust lba with transferred bytes uint32_t const lba = rdwr10_get_lba(p_cbw->command) + (p_msc->xferred_len / block_sz); - // Application can consume smaller bytes - int32_t nbytes = tud_msc_write10_cb(p_cbw->lun, lba, p_msc->xferred_len % block_sz, _mscd_buf, xferred_bytes); + // Invoke callback to consume new data + uint32_t const offset = p_msc->xferred_len % block_sz; + int32_t nbytes = tud_msc_write10_cb(p_cbw->lun, lba, offset, _mscd_buf, xferred_bytes); if ( nbytes < 0 ) { // negative means error -> failed this scsi op TU_LOG(MSC_DEBUG, " tud_msc_write10_cb() return -1\r\n"); + // update actual byte before failed + p_msc->xferred_len += xferred_bytes; + // Sense = Flash not ready for access tud_msc_set_sense(p_cbw->lun, SCSI_SENSE_MEDIUM_ERROR, 0x33, 0x00); @@ -842,7 +848,7 @@ static void proc_write10_new_data(uint8_t rhport, mscd_interface_t* p_msc, uint3 }else { // Application consume less than what we got (including zero) - if ( nbytes < (int32_t) xferred_bytes ) + if ( (uint32_t) nbytes < xferred_bytes ) { if ( nbytes > 0 ) { @@ -850,12 +856,12 @@ static void proc_write10_new_data(uint8_t rhport, mscd_interface_t* p_msc, uint3 memmove(_mscd_buf, _mscd_buf+nbytes, xferred_bytes-nbytes); } - // simulate an transfer complete with adjusted parameters --> this driver callback will fired again + // simulate an transfer complete with adjusted parameters --> callback will be invoked with adjusted parameter dcd_event_xfer_complete(rhport, p_msc->ep_out, xferred_bytes-nbytes, XFER_RESULT_SUCCESS, false); } else { - // Application consume all bytes in our buffer, prepare to receive more data from host + // Application consume all bytes in our buffer p_msc->xferred_len += xferred_bytes; if ( p_msc->xferred_len >= p_msc->total_len ) @@ -864,6 +870,7 @@ static void proc_write10_new_data(uint8_t rhport, mscd_interface_t* p_msc, uint3 p_msc->stage = MSC_STAGE_STATUS; }else { + // prepare to receive more data from host proc_write10_cmd(rhport, p_msc); } } -- cgit v1.3.1 From fdf1ff545f41c23f63e86d6debaa852e731d7644 Mon Sep 17 00:00:00 2001 From: hathach Date: Sun, 29 Aug 2021 15:44:27 +0700 Subject: responding with status per-spec in test case 4 --- src/class/msc/msc_device.c | 81 ++++++++++++++++++++++++++++++++++------------ 1 file changed, 60 insertions(+), 21 deletions(-) (limited to 'src/class') diff --git a/src/class/msc/msc_device.c b/src/class/msc/msc_device.c index 52dfcb836..7dcd4983e 100644 --- a/src/class/msc/msc_device.c +++ b/src/class/msc/msc_device.c @@ -138,11 +138,16 @@ static inline uint32_t rdwr10_get_lba(uint8_t const command[]) return tu_ntohl(lba); } +static inline uint16_t rdwr10_get_blockcount(msc_cbw_t const* cbw) +{ + uint16_t const block_count = tu_unaligned_read16(cbw->command + offsetof(scsi_write10_t, block_count)); + return tu_ntohs(block_count); +} + static inline uint16_t rdwr10_get_blocksize(msc_cbw_t const* cbw) { // first extract block count in the command - uint16_t block_count = tu_unaligned_read16(cbw->command + offsetof(scsi_write10_t, block_count)); - block_count = tu_ntohs(block_count); + uint16_t const block_count = rdwr10_get_blockcount(cbw); // invalid block count if (block_count == 0) return 0; @@ -150,6 +155,43 @@ static inline uint16_t rdwr10_get_blocksize(msc_cbw_t const* cbw) return cbw->total_bytes / block_count; } +uint8_t rdwr10_validate_cmd(msc_cbw_t const* cbw) +{ + uint8_t status = MSC_CSW_STATUS_PASSED; + uint16_t const block_count = rdwr10_get_blockcount(cbw); + + if ( cbw->total_bytes == 0 ) + { + if ( block_count ) + { + TU_LOG(MSC_DEBUG, " SCSI case 2 (Hn < Di) or case 3 (Hn < Do) \r\n"); + status = MSC_CSW_STATUS_PHASE_ERROR; + }else + { + // no data transfer, only exist in complaint test suite + } + }else + { + if ( SCSI_CMD_READ_10 == cbw->command[0] && !is_data_in(cbw->dir) ) + { + TU_LOG(MSC_DEBUG, " SCSI case 10 (Ho <> Di)\r\n"); + status = MSC_CSW_STATUS_PHASE_ERROR; + } + else if ( SCSI_CMD_WRITE_10 == cbw->command[0] && is_data_in(cbw->dir) ) + { + TU_LOG(MSC_DEBUG, " SCSI case 8 (Hi <> Do)\r\n"); + status = MSC_CSW_STATUS_PHASE_ERROR; + } + else if ( !block_count ) + { + TU_LOG(MSC_DEBUG, " SCSI case 4 Hi > Dn\r\n"); + status = MSC_CSW_STATUS_FAILED; + } + } + + return status; +} + //--------------------------------------------------------------------+ // Debug //--------------------------------------------------------------------+ @@ -368,30 +410,27 @@ bool mscd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t event, uint32_t p_msc->total_len = p_cbw->total_bytes; p_msc->xferred_len = 0; - if ( SCSI_CMD_READ_10 == p_cbw->command[0] ) + // Read10 or Write10 + if ( (SCSI_CMD_READ_10 == p_cbw->command[0]) || (SCSI_CMD_WRITE_10 == p_cbw->command[0]) ) { - // Invalid CBW length == 0 or Direction bit is incorrect - // 6.7 The 13 Cases: case 2 (Hn < Di), case 3 (Hn < Do), case 10 (Ho <> Di) -> phase error - if ( rdwr10_get_blocksize(p_cbw) == 0 || !is_data_in(p_cbw->dir) ) + uint8_t const status = rdwr10_validate_cmd(p_cbw); + + if ( status != MSC_CSW_STATUS_PASSED) { - TU_LOG(MSC_DEBUG, " SCSI case 2 (Hn < Di), case 3 (Hn < Do), case 10 (Ho <> Di)\r\n"); - fail_scsi_op(rhport, p_msc, MSC_CSW_STATUS_PHASE_ERROR); - }else + fail_scsi_op(rhport, p_msc, status); + }else if ( p_cbw->total_bytes ) { - proc_read10_cmd(rhport, p_msc); - } - } - else if (SCSI_CMD_WRITE_10 == p_cbw->command[0]) - { - // Invalid CBW length == 0 or Direction bit is incorrect - // 6.7 The 13 Cases: case 2 (Hn < Do), case 3 (Hn < Do), case 8 (Hi <> Do) -> phase error - if ( rdwr10_get_blocksize(p_cbw) == 0 || is_data_in(p_cbw->dir) ) - { - TU_LOG(MSC_DEBUG, " SCSI case 2 (Hn < Di), case 3 (Hn < Do), case 8 (Hi <> Do)\r\n"); - fail_scsi_op(rhport, p_msc, MSC_CSW_STATUS_PHASE_ERROR); + if (SCSI_CMD_READ_10 == p_cbw->command[0]) + { + proc_read10_cmd(rhport, p_msc); + }else + { + proc_write10_cmd(rhport, p_msc); + } }else { - proc_write10_cmd(rhport, p_msc); + // no data transfer, only exist in complaint test suite + p_msc->stage = MSC_STAGE_STATUS; } } else -- cgit v1.3.1 From 8305766afe909a6f1b3be6a88cd4e6c4017255a8 Mon Sep 17 00:00:00 2001 From: MasterPhi Date: Tue, 31 Aug 2021 11:27:43 +0200 Subject: fix HID_LOGICAL_MAX overflow. --- src/class/hid/hid_device.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/class') diff --git a/src/class/hid/hid_device.h b/src/class/hid/hid_device.h index 5cf4b3060..7f67fa9cf 100644 --- a/src/class/hid/hid_device.h +++ b/src/class/hid/hid_device.h @@ -364,14 +364,14 @@ static inline bool tud_hid_gamepad_report(uint8_t report_id, int8_t x, int8_t y /* Input */ \ HID_USAGE ( 0x02 ),\ HID_LOGICAL_MIN ( 0x00 ),\ - HID_LOGICAL_MAX ( 0xff ),\ + HID_LOGICAL_MAX_N ( 0xff, 2 ),\ HID_REPORT_SIZE ( 8 ),\ HID_REPORT_COUNT( report_size ),\ HID_INPUT ( HID_DATA | HID_VARIABLE | HID_ABSOLUTE ),\ /* Output */ \ HID_USAGE ( 0x03 ),\ HID_LOGICAL_MIN ( 0x00 ),\ - HID_LOGICAL_MAX ( 0xff ),\ + HID_LOGICAL_MAX_N ( 0xff, 2 ),\ HID_REPORT_SIZE ( 8 ),\ HID_REPORT_COUNT( report_size ),\ HID_OUTPUT ( HID_DATA | HID_VARIABLE | HID_ABSOLUTE ),\ -- cgit v1.3.1 From ab0c3e8dd00e8baed6c0a233dd5377ef4497531d Mon Sep 17 00:00:00 2001 From: hathach Date: Tue, 31 Aug 2021 17:41:08 +0700 Subject: fix rp2040 chapter 9 TD 9.6 test --- src/class/msc/msc_device.c | 6 +++++- src/portable/raspberrypi/rp2040/dcd_rp2040.c | 10 ++++------ 2 files changed, 9 insertions(+), 7 deletions(-) (limited to 'src/class') diff --git a/src/class/msc/msc_device.c b/src/class/msc/msc_device.c index 7dcd4983e..6b3a392a8 100644 --- a/src/class/msc/msc_device.c +++ b/src/class/msc/msc_device.c @@ -323,7 +323,11 @@ bool mscd_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t if ( p_msc->stage == MSC_STAGE_CMD ) { // part of reset recovery (probably due to invalid CBW) -> prepare for new command - TU_ASSERT( prepare_cbw(rhport, p_msc) ); + // Note: skip if already queued previously + if ( usbd_edpt_ready(rhport, p_msc->ep_out) ) + { + TU_ASSERT( prepare_cbw(rhport, p_msc) ); + } } } } diff --git a/src/portable/raspberrypi/rp2040/dcd_rp2040.c b/src/portable/raspberrypi/rp2040/dcd_rp2040.c index e81681d4f..0cd3e97de 100644 --- a/src/portable/raspberrypi/rp2040/dcd_rp2040.c +++ b/src/portable/raspberrypi/rp2040/dcd_rp2040.c @@ -389,17 +389,15 @@ void dcd_remote_wakeup(uint8_t rhport) // disconnect by disabling internal pull-up resistor on D+/D- void dcd_disconnect(uint8_t rhport) { - pico_info("dcd_disconnect %d\n", rhport); - assert(rhport == 0); - usb_hw_clear->sie_ctrl = USB_SIE_CTRL_PULLUP_EN_BITS; + (void) rhport; + usb_hw_clear->sie_ctrl = USB_SIE_CTRL_PULLUP_EN_BITS; } // connect by enabling internal pull-up resistor on D+/D- void dcd_connect(uint8_t rhport) { - pico_info("dcd_connect %d\n", rhport); - assert(rhport == 0); - usb_hw_set->sie_ctrl = USB_SIE_CTRL_PULLUP_EN_BITS; + (void) rhport; + usb_hw_set->sie_ctrl = USB_SIE_CTRL_PULLUP_EN_BITS; } /*------------------------------------------------------------------*/ -- cgit v1.3.1 From 90dc9bc289e12950fba9ea5dafe20e1b0777d0ba Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 1 Sep 2021 12:42:45 +0700 Subject: revert previous changes, edpt stall also clear any pending (not complete) transfer --- src/class/msc/msc_device.c | 6 +----- src/device/usbd.c | 6 ++++-- 2 files changed, 5 insertions(+), 7 deletions(-) (limited to 'src/class') diff --git a/src/class/msc/msc_device.c b/src/class/msc/msc_device.c index 6b3a392a8..7dcd4983e 100644 --- a/src/class/msc/msc_device.c +++ b/src/class/msc/msc_device.c @@ -323,11 +323,7 @@ bool mscd_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t if ( p_msc->stage == MSC_STAGE_CMD ) { // part of reset recovery (probably due to invalid CBW) -> prepare for new command - // Note: skip if already queued previously - if ( usbd_edpt_ready(rhport, p_msc->ep_out) ) - { - TU_ASSERT( prepare_cbw(rhport, p_msc) ); - } + TU_ASSERT( prepare_cbw(rhport, p_msc) ); } } } diff --git a/src/device/usbd.c b/src/device/usbd.c index 4f5a2f8ed..9af9b2a6e 100644 --- a/src/device/usbd.c +++ b/src/device/usbd.c @@ -1214,12 +1214,12 @@ bool usbd_edpt_claim(uint8_t rhport, uint8_t ep_addr) #if CFG_TUSB_OS != OPT_OS_NONE // pre-check to help reducing mutex lock - TU_VERIFY( usbd_edpt_ready(rhport, ep_addr) && (_usbd_dev.ep_status[epnum][dir].claimed == 0)); + TU_VERIFY( (_usbd_dev.ep_status[epnum][dir].busy == 0) && (_usbd_dev.ep_status[epnum][dir].claimed == 0)); osal_mutex_lock(_usbd_mutex, OSAL_TIMEOUT_WAIT_FOREVER); #endif // can only claim the endpoint if it is not busy and not claimed yet. - bool const ret = usbd_edpt_ready(rhport, ep_addr) && (_usbd_dev.ep_status[epnum][dir].claimed == 0); + bool const ret = (_usbd_dev.ep_status[epnum][dir].busy == 0) && (_usbd_dev.ep_status[epnum][dir].claimed == 0); if (ret) { _usbd_dev.ep_status[epnum][dir].claimed = 1; @@ -1340,6 +1340,7 @@ void usbd_edpt_stall(uint8_t rhport, uint8_t ep_addr) dcd_edpt_stall(rhport, ep_addr); _usbd_dev.ep_status[epnum][dir].stalled = true; + _usbd_dev.ep_status[epnum][dir].busy = true; } void usbd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr) @@ -1351,6 +1352,7 @@ void usbd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr) dcd_edpt_clear_stall(rhport, ep_addr); _usbd_dev.ep_status[epnum][dir].stalled = false; + _usbd_dev.ep_status[epnum][dir].busy = false; } bool usbd_edpt_stalled(uint8_t rhport, uint8_t ep_addr) -- cgit v1.3.1 From 15fa2f447b9187f2cef5dd5ba904449bd4c6703e Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 1 Sep 2021 16:53:12 +0700 Subject: add back edpt check before cbw, since bot reset can occurred any time --- src/class/msc/msc_device.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'src/class') diff --git a/src/class/msc/msc_device.c b/src/class/msc/msc_device.c index 7dcd4983e..6b3a392a8 100644 --- a/src/class/msc/msc_device.c +++ b/src/class/msc/msc_device.c @@ -323,7 +323,11 @@ bool mscd_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t if ( p_msc->stage == MSC_STAGE_CMD ) { // part of reset recovery (probably due to invalid CBW) -> prepare for new command - TU_ASSERT( prepare_cbw(rhport, p_msc) ); + // Note: skip if already queued previously + if ( usbd_edpt_ready(rhport, p_msc->ep_out) ) + { + TU_ASSERT( prepare_cbw(rhport, p_msc) ); + } } } } -- cgit v1.3.1 From 2e23f3dd7287186445aeab39108f81c51644ed77 Mon Sep 17 00:00:00 2001 From: Kamil Tomaszewski Date: Fri, 3 Sep 2021 18:13:45 +0200 Subject: Fix for MSC during stage STATUS --- src/class/msc/msc_device.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/class') diff --git a/src/class/msc/msc_device.c b/src/class/msc/msc_device.c index 6b3a392a8..71875b014 100644 --- a/src/class/msc/msc_device.c +++ b/src/class/msc/msc_device.c @@ -601,10 +601,10 @@ bool mscd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t event, uint32_t // skip status if epin is currently stalled, will do it when received Clear Stall request if ( !usbd_edpt_stalled(rhport, p_msc->ep_in) ) { - if ( (p_cbw->total_bytes > p_msc->xferred_len) && is_data_in(p_cbw->dir) ) + if ( (p_msc->total_len > p_msc->xferred_len) && is_data_in(p_cbw->dir) ) { // 6.7 The 13 Cases: case 5 (Hi > Di): STALL before status - TU_LOG(MSC_DEBUG, " SCSI case 5 (Hi > Di): %lu > %lu\r\n", p_cbw->total_bytes, p_msc->xferred_len); + TU_LOG(MSC_DEBUG, " SCSI case 5 (Hi > Di): %lu > %lu\r\n", p_msc->total_len, p_msc->xferred_len); usbd_edpt_stall(rhport, p_msc->ep_in); }else { -- cgit v1.3.1 From fa030075c228390741e450664506892d317c0038 Mon Sep 17 00:00:00 2001 From: hathach Date: Mon, 6 Sep 2021 19:26:28 +0700 Subject: Revert "Fix for MSC during stage STATUS" This reverts commit 2e23f3dd7287186445aeab39108f81c51644ed77. --- src/class/msc/msc_device.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/class') diff --git a/src/class/msc/msc_device.c b/src/class/msc/msc_device.c index 71875b014..6b3a392a8 100644 --- a/src/class/msc/msc_device.c +++ b/src/class/msc/msc_device.c @@ -601,10 +601,10 @@ bool mscd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t event, uint32_t // skip status if epin is currently stalled, will do it when received Clear Stall request if ( !usbd_edpt_stalled(rhport, p_msc->ep_in) ) { - if ( (p_msc->total_len > p_msc->xferred_len) && is_data_in(p_cbw->dir) ) + if ( (p_cbw->total_bytes > p_msc->xferred_len) && is_data_in(p_cbw->dir) ) { // 6.7 The 13 Cases: case 5 (Hi > Di): STALL before status - TU_LOG(MSC_DEBUG, " SCSI case 5 (Hi > Di): %lu > %lu\r\n", p_msc->total_len, p_msc->xferred_len); + TU_LOG(MSC_DEBUG, " SCSI case 5 (Hi > Di): %lu > %lu\r\n", p_cbw->total_bytes, p_msc->xferred_len); usbd_edpt_stall(rhport, p_msc->ep_in); }else { -- cgit v1.3.1 From f47e5402fa928c5a0cd581c894e9e18c3dfcbdfb Mon Sep 17 00:00:00 2001 From: hathach Date: Tue, 7 Sep 2021 13:30:51 +0700 Subject: add msc workaround for cxd56 --- examples/make.mk | 1 + hw/bsp/spresense/board.mk | 3 ++- src/class/msc/msc_device.c | 11 +++++++++++ 3 files changed, 14 insertions(+), 1 deletion(-) (limited to 'src/class') diff --git a/examples/make.mk b/examples/make.mk index 9daf60e35..24f8c5572 100644 --- a/examples/make.mk +++ b/examples/make.mk @@ -61,6 +61,7 @@ GDB = $(CROSS_COMPILE)gdb OBJCOPY = $(CROSS_COMPILE)objcopy SIZE = $(CROSS_COMPILE)size MKDIR = mkdir +PYTHON = python ifeq ($(CMDEXE),1) CP = copy diff --git a/hw/bsp/spresense/board.mk b/hw/bsp/spresense/board.mk index a46c42bd6..ba291e817 100644 --- a/hw/bsp/spresense/board.mk +++ b/hw/bsp/spresense/board.mk @@ -70,4 +70,5 @@ $(BUILD)/$(PROJECT).spk: $(MKSPK) # flash flash: $(BUILD)/$(PROJECT).spk - @$(TOP)/hw/mcu/sony/cxd56/tools/flash_writer.py -s -c $(SERIAL) -d -b 115200 -n $< + @echo FLASH $< + @$(PYTHON) $(TOP)/hw/mcu/sony/cxd56/tools/flash_writer.py -s -c $(SERIAL) -d -b 115200 -n $< diff --git a/src/class/msc/msc_device.c b/src/class/msc/msc_device.c index 6b3a392a8..0fd592129 100644 --- a/src/class/msc/msc_device.c +++ b/src/class/msc/msc_device.c @@ -611,6 +611,17 @@ bool mscd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t event, uint32_t TU_ASSERT( send_csw(rhport, p_msc) ); } } + + #if TU_CHECK_MCU(CXD56) + // WORKAROUND: cxd56 has its own nuttx usb stack which does not forward Set/ClearFeature(Endpoint) to DCD. + // There is no way for us to know when EP is un-stall, therefore we will unconditionally un-stall here and + // hope everything will work + if ( usbd_edpt_stalled(rhport, p_msc->ep_in) ) + { + usbd_edpt_clear_stall(rhport, p_msc->ep_in); + send_csw(rhport, p_msc); + } + #endif } return true; -- cgit v1.3.1 From d5f2c34eaa3e840b32817829031b95c6b7780314 Mon Sep 17 00:00:00 2001 From: szymonh <12231135+szymonh@users.noreply.github.com> Date: Sun, 12 Sep 2021 20:09:58 +0200 Subject: Prevent buffer overflow in bth_device.c --- src/class/bth/bth_device.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/class') diff --git a/src/class/bth/bth_device.c b/src/class/bth/bth_device.c index 1d27ae7c5..09fab953e 100755 --- a/src/class/bth/bth_device.c +++ b/src/class/bth/bth_device.c @@ -214,7 +214,7 @@ bool btd_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t c } else return false; - return tud_control_xfer(rhport, request, &_btd_itf.hci_cmd, request->wLength); + return tud_control_xfer(rhport, request, &_btd_itf.hci_cmd, sizeof(_btd_itf.hci_cmd)); } else if ( stage == CONTROL_STAGE_DATA ) { -- cgit v1.3.1 From 50e3c0054f8d26340863667a50aae5a798f6aefc Mon Sep 17 00:00:00 2001 From: szymonh <12231135+szymonh@users.noreply.github.com> Date: Mon, 13 Sep 2021 10:23:03 +0200 Subject: Add size check to tud_bt_hci_cmd_cb call in bth_device.c --- src/class/bth/bth_device.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/class') diff --git a/src/class/bth/bth_device.c b/src/class/bth/bth_device.c index 09fab953e..b73f829cc 100755 --- a/src/class/bth/bth_device.c +++ b/src/class/bth/bth_device.c @@ -221,7 +221,7 @@ bool btd_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t c // Handle class request only TU_VERIFY(request->bmRequestType_bit.type == TUSB_REQ_TYPE_CLASS); - if (tud_bt_hci_cmd_cb) tud_bt_hci_cmd_cb(&_btd_itf.hci_cmd, request->wLength); + if (tud_bt_hci_cmd_cb) tud_bt_hci_cmd_cb(&_btd_itf.hci_cmd, tu_min16(request->wLength, sizeof(_btd_itf.hci_cmd))); } return true; -- cgit v1.3.1