diff --git a/README.md b/README.md index 8cd2c1ea..d5f45f18 100644 --- a/README.md +++ b/README.md @@ -27,6 +27,8 @@ Support multiple device configurations by dynamically changing usb descriptors. - Human Interface Device (HID): Generic (In & Out), Keyboard, Mouse, Gamepad etc ... - Mass Storage Class (MSC): with multiple LUNs - Musical Instrument Digital Interface (MIDI) +- Vendor-specific class support with generic In & Out endpoints. Can be used with MS OS 2.0 compatible descriptor to load winUSB driver without INF file. +- [WebUSB](https://github.com/WICG/webusb) with vendor-specific class ## Host Stack @@ -42,7 +44,7 @@ Currently the following OS are supported with tinyusb out of the box with a simp - **No OS** - **FreeRTOS** -- **MyNewt** (work in progress) +- **Mynewt** Due to the newt package build system, Mynewt examples are better to be on its [own repo](https://github.com/hathach/mynewt-tinyusb-example) ## Supported MCUs @@ -81,4 +83,4 @@ TinyUSB is currently used by these other projects: * [CircuitPython](https://github.com/adafruit/circuitpython) * [TinyUSB Arduino Library](https://github.com/adafruit/Adafruit_TinyUSB_Arduino) -If your project also uses TinyUSB and want to share, feel free to create a pull request. +Let's me know if your project also uses TinyUSB and want to share. diff --git a/examples/device/cdc_msc_hid/src/msc_disk.c b/examples/device/cdc_msc_hid/src/msc_disk.c index be99a239..406baf71 100644 --- a/examples/device/cdc_msc_hid/src/msc_disk.c +++ b/examples/device/cdc_msc_hid/src/msc_disk.c @@ -63,7 +63,7 @@ uint8_t msc_disk[DISK_BLOCK_NUM][DISK_BLOCK_SIZE] = 0x01, 0x10, 0x00, 0x10, 0x00, 0xF8, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x29, 0x34, 0x12, 0x00, 0x00, 'T' , 'i' , 'n' , 'y' , 'U' , 'S' , 'B' , ' ' , 'M' , 'S' , 'C' , 0x46, 0x41, 0x54, 0x31, 0x32, 0x20, 0x20, 0x20, 0x00, 0x00, - + // Zero up to 2 last bytes of FAT magic code 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -91,7 +91,7 @@ uint8_t msc_disk[DISK_BLOCK_NUM][DISK_BLOCK_SIZE] = 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, diff --git a/examples/device/cdc_msc_hid/src/usb_descriptors.c b/examples/device/cdc_msc_hid/src/usb_descriptors.c index ee79f4ec..34f391df 100644 --- a/examples/device/cdc_msc_hid/src/usb_descriptors.c +++ b/examples/device/cdc_msc_hid/src/usb_descriptors.c @@ -209,8 +209,8 @@ uint16_t const* tud_descriptor_string_cb(uint8_t index) } } - // first byte is len, second byte is string type - _desc_str[0] = TUD_DESC_STR_HEADER(chr_count); + // first byte is length (including header), second byte is string type + _desc_str[0] = (TUSB_DESC_STRING << 8 ) | (2*chr_count + 2); return _desc_str; } diff --git a/examples/device/cdc_msc_hid_freertos/src/usb_descriptors.c b/examples/device/cdc_msc_hid_freertos/src/usb_descriptors.c index 699067f7..5d93cc2f 100644 --- a/examples/device/cdc_msc_hid_freertos/src/usb_descriptors.c +++ b/examples/device/cdc_msc_hid_freertos/src/usb_descriptors.c @@ -210,8 +210,8 @@ uint16_t const* tud_descriptor_string_cb(uint8_t index) } } - // first byte is len, second byte is string type - _desc_str[0] = TUD_DESC_STR_HEADER(chr_count); + // first byte is length (including header), second byte is string type + _desc_str[0] = (TUSB_DESC_STRING << 8 ) | (2*chr_count + 2); return _desc_str; } diff --git a/examples/device/hid_generic_inout/src/usb_descriptors.c b/examples/device/hid_generic_inout/src/usb_descriptors.c index 7578a8b7..c9493c4e 100644 --- a/examples/device/hid_generic_inout/src/usb_descriptors.c +++ b/examples/device/hid_generic_inout/src/usb_descriptors.c @@ -162,8 +162,8 @@ uint16_t const* tud_descriptor_string_cb(uint8_t index) } } - // first byte is len, second byte is string type - _desc_str[0] = TUD_DESC_STR_HEADER(chr_count); + // first byte is length (including header), second byte is string type + _desc_str[0] = (TUSB_DESC_STRING << 8 ) | (2*chr_count + 2); return _desc_str; } diff --git a/examples/device/midi_test/src/usb_descriptors.c b/examples/device/midi_test/src/usb_descriptors.c index 95d3cca2..7cebc6a1 100644 --- a/examples/device/midi_test/src/usb_descriptors.c +++ b/examples/device/midi_test/src/usb_descriptors.c @@ -149,8 +149,8 @@ uint16_t const* tud_descriptor_string_cb(uint8_t index) } } - // first byte is len, second byte is string type - _desc_str[0] = TUD_DESC_STR_HEADER(chr_count); + // first byte is length (including header), second byte is string type + _desc_str[0] = (TUSB_DESC_STRING << 8 ) | (2*chr_count + 2); return _desc_str; } diff --git a/examples/device/msc_dual_lun/src/usb_descriptors.c b/examples/device/msc_dual_lun/src/usb_descriptors.c index 6064d8d7..cab37cf1 100644 --- a/examples/device/msc_dual_lun/src/usb_descriptors.c +++ b/examples/device/msc_dual_lun/src/usb_descriptors.c @@ -147,8 +147,8 @@ uint16_t const* tud_descriptor_string_cb(uint8_t index) } } - // first byte is len, second byte is string type - _desc_str[0] = TUD_DESC_STR_HEADER(chr_count); + // first byte is length (including header), second byte is string type + _desc_str[0] = (TUSB_DESC_STRING << 8 ) | (2*chr_count + 2); return _desc_str; } diff --git a/examples/device/webusb_serial/src/usb_descriptors.c b/examples/device/webusb_serial/src/usb_descriptors.c index a61c62c9..a1d5cd9b 100644 --- a/examples/device/webusb_serial/src/usb_descriptors.c +++ b/examples/device/webusb_serial/src/usb_descriptors.c @@ -230,8 +230,8 @@ uint16_t const* tud_descriptor_string_cb(uint8_t index) } } - // first byte is len, second byte is string type - _desc_str[0] = TUD_DESC_STR_HEADER(chr_count); + // first byte is length (including header), second byte is string type + _desc_str[0] = (TUSB_DESC_STRING << 8 ) | (2*chr_count + 2); return _desc_str; } diff --git a/src/class/cdc/cdc_device.c b/src/class/cdc/cdc_device.c index d4952d11..6da9157b 100644 --- a/src/class/cdc/cdc_device.c +++ b/src/class/cdc/cdc_device.c @@ -121,12 +121,6 @@ uint32_t tud_cdc_n_available(uint8_t itf) return tu_fifo_count(&_cdcd_itf[itf].rx_ff); } -signed char tud_cdc_n_read_char(uint8_t itf) -{ - signed char ch; - return tud_cdc_n_read(itf, &ch, 1) ? ch : (-1); -} - uint32_t tud_cdc_n_read(uint8_t itf, void* buffer, uint32_t bufsize) { uint32_t num_read = tu_fifo_read_n(&_cdcd_itf[itf].rx_ff, buffer, bufsize); @@ -134,10 +128,9 @@ uint32_t tud_cdc_n_read(uint8_t itf, void* buffer, uint32_t bufsize) return num_read; } -signed char tud_cdc_n_peek(uint8_t itf, int pos) +bool tud_cdc_n_peek(uint8_t itf, int pos, uint8_t* chr) { - signed char ch; - return tu_fifo_peek_at(&_cdcd_itf[itf].rx_ff, pos, &ch) ? ch : (-1); + return tu_fifo_peek_at(&_cdcd_itf[itf].rx_ff, pos, chr); } void tud_cdc_n_read_flush (uint8_t itf) @@ -149,17 +142,6 @@ void tud_cdc_n_read_flush (uint8_t itf) //--------------------------------------------------------------------+ // WRITE API //--------------------------------------------------------------------+ - -uint32_t tud_cdc_n_write_char(uint8_t itf, char ch) -{ - return tud_cdc_n_write(itf, &ch, 1); -} - -uint32_t tud_cdc_n_write_str (uint8_t itf, char const* str) -{ - return tud_cdc_n_write(itf, str, strlen(str)); -} - uint32_t tud_cdc_n_write(uint8_t itf, void const* buffer, uint32_t bufsize) { uint16_t ret = tu_fifo_write_n(&_cdcd_itf[itf].tx_ff, buffer, bufsize); @@ -190,6 +172,11 @@ bool tud_cdc_n_write_flush (uint8_t itf) return true; } +uint32_t tud_cdc_n_write_available (uint8_t itf) +{ + return tu_fifo_remaining(&_cdcd_itf[itf].tx_ff); +} + //--------------------------------------------------------------------+ // USBD Driver API diff --git a/src/class/cdc/cdc_device.h b/src/class/cdc/cdc_device.h index f1ac08e7..82932ef7 100644 --- a/src/class/cdc/cdc_device.h +++ b/src/class/cdc/cdc_device.h @@ -51,40 +51,42 @@ // Application API (Multiple Interfaces) // CFG_TUD_CDC > 1 //--------------------------------------------------------------------+ -bool tud_cdc_n_connected (uint8_t itf); -uint8_t tud_cdc_n_get_line_state (uint8_t itf); -void tud_cdc_n_get_line_coding (uint8_t itf, cdc_line_coding_t* coding); -void tud_cdc_n_set_wanted_char (uint8_t itf, char wanted); +bool tud_cdc_n_connected (uint8_t itf); +uint8_t tud_cdc_n_get_line_state (uint8_t itf); +void tud_cdc_n_get_line_coding (uint8_t itf, cdc_line_coding_t* coding); +void tud_cdc_n_set_wanted_char (uint8_t itf, char wanted); -uint32_t tud_cdc_n_available (uint8_t itf); -signed char tud_cdc_n_read_char (uint8_t itf); -uint32_t tud_cdc_n_read (uint8_t itf, void* buffer, uint32_t bufsize); -void tud_cdc_n_read_flush (uint8_t itf); -signed char tud_cdc_n_peek (uint8_t itf, int pos); +uint32_t tud_cdc_n_available (uint8_t itf); +uint32_t tud_cdc_n_read (uint8_t itf, void* buffer, uint32_t bufsize); +void tud_cdc_n_read_flush (uint8_t itf); +bool tud_cdc_n_peek (uint8_t itf, int pos, uint8_t* u8); +static inline int32_t tud_cdc_n_read_char (uint8_t itf); -uint32_t tud_cdc_n_write_char (uint8_t itf, char ch); -uint32_t tud_cdc_n_write (uint8_t itf, void const* buffer, uint32_t bufsize); -uint32_t tud_cdc_n_write_str (uint8_t itf, char const* str); -bool tud_cdc_n_write_flush (uint8_t itf); +uint32_t tud_cdc_n_write (uint8_t itf, void const* buffer, uint32_t bufsize); +bool tud_cdc_n_write_flush (uint8_t itf); +uint32_t tud_cdc_n_write_available (uint8_t itf); +static inline uint32_t tud_cdc_n_write_char (uint8_t itf, char ch); +static inline uint32_t tud_cdc_n_write_str (uint8_t itf, char const* str); //--------------------------------------------------------------------+ // Application API (Interface0) //--------------------------------------------------------------------+ -static inline bool tud_cdc_connected (void); -static inline uint8_t tud_cdc_get_line_state (void); -static inline void tud_cdc_get_line_coding (cdc_line_coding_t* coding); -static inline void tud_cdc_set_wanted_char (char wanted); +static inline bool tud_cdc_connected (void); +static inline uint8_t tud_cdc_get_line_state (void); +static inline void tud_cdc_get_line_coding (cdc_line_coding_t* coding); +static inline void tud_cdc_set_wanted_char (char wanted); -static inline uint32_t tud_cdc_available (void); -static inline signed char tud_cdc_read_char (void); -static inline uint32_t tud_cdc_read (void* buffer, uint32_t bufsize); -static inline void tud_cdc_read_flush (void); -static inline signed char tud_cdc_peek (int pos); +static inline uint32_t tud_cdc_available (void); +static inline int32_t tud_cdc_read_char (void); +static inline uint32_t tud_cdc_read (void* buffer, uint32_t bufsize); +static inline void tud_cdc_read_flush (void); +static inline bool tud_cdc_peek (int pos, uint8_t* u8); -static inline uint32_t tud_cdc_write_char (char ch); -static inline uint32_t tud_cdc_write (void const* buffer, uint32_t bufsize); -static inline uint32_t tud_cdc_write_str (char const* str); -static inline bool tud_cdc_write_flush (void); +static inline uint32_t tud_cdc_write_char (char ch); +static inline uint32_t tud_cdc_write (void const* buffer, uint32_t bufsize); +static inline uint32_t tud_cdc_write_str (char const* str); +static inline bool tud_cdc_write_flush (void); +static inline uint32_t tud_cdc_write_available (void); //--------------------------------------------------------------------+ // Application Callback API (weak is optional) @@ -105,6 +107,22 @@ TU_ATTR_WEAK void tud_cdc_line_coding_cb(uint8_t itf, cdc_line_coding_t const* p //--------------------------------------------------------------------+ // Inline Functions //--------------------------------------------------------------------+ +static inline int32_t tud_cdc_n_read_char (uint8_t itf) +{ + uint8_t ch; + return tud_cdc_n_read(itf, &ch, 1) ? (int32_t) ch : -1; +} + +static inline uint32_t tud_cdc_n_write_char(uint8_t itf, char ch) +{ + return tud_cdc_n_write(itf, &ch, 1); +} + +static inline uint32_t tud_cdc_n_write_str (uint8_t itf, char const* str) +{ + return tud_cdc_n_write(itf, str, strlen(str)); +} + static inline bool tud_cdc_connected (void) { return tud_cdc_n_connected(0); @@ -130,7 +148,7 @@ static inline uint32_t tud_cdc_available (void) return tud_cdc_n_available(0); } -static inline signed char tud_cdc_read_char (void) +static inline int32_t tud_cdc_read_char (void) { return tud_cdc_n_read_char(0); } @@ -145,9 +163,9 @@ static inline void tud_cdc_read_flush (void) tud_cdc_n_read_flush(0); } -static inline signed char tud_cdc_peek (int pos) +static inline bool tud_cdc_peek (int pos, uint8_t* u8) { - return tud_cdc_n_peek(0, pos); + return tud_cdc_n_peek(0, pos, u8); } static inline uint32_t tud_cdc_write_char (char ch) @@ -170,6 +188,11 @@ static inline bool tud_cdc_write_flush (void) return tud_cdc_n_write_flush(0); } +static inline uint32_t tud_cdc_write_available(void) +{ + return tud_cdc_n_write_available(0); +} + /** @} */ /** @} */ diff --git a/src/class/vendor/vendor_device.c b/src/class/vendor/vendor_device.c index 33fb9847..d1ba63a9 100644 --- a/src/class/vendor/vendor_device.c +++ b/src/class/vendor/vendor_device.c @@ -62,7 +62,6 @@ CFG_TUSB_MEM_SECTION static vendord_interface_t _vendord_itf[CFG_TUD_VENDOR]; #define ITF_MEM_RESET_SIZE offsetof(vendord_interface_t, rx_ff) - bool tud_vendor_n_mounted (uint8_t itf) { return _vendord_itf[itf].ep_in && _vendord_itf[itf].ep_out; @@ -73,6 +72,11 @@ uint32_t tud_vendor_n_available (uint8_t itf) return tu_fifo_count(&_vendord_itf[itf].rx_ff); } +bool tud_vendor_n_peek(uint8_t itf, int pos, uint8_t* u8) +{ + return tu_fifo_peek_at(&_vendord_itf[itf].rx_ff, pos, u8); +} + //--------------------------------------------------------------------+ // Read API //--------------------------------------------------------------------+ diff --git a/src/class/vendor/vendor_device.h b/src/class/vendor/vendor_device.h index d214c29e..17fbc54e 100644 --- a/src/class/vendor/vendor_device.h +++ b/src/class/vendor/vendor_device.h @@ -34,14 +34,6 @@ #define CFG_TUD_VENDOR_EPSIZE 64 #endif -#ifndef CFG_TUD_VENDOR_RX_BUFSIZE -#define CFG_TUD_VENDOR_RX_BUFSIZE 0 -#endif - -#ifndef CFG_TUD_VENDOR_TX_BUFSIZE -#define CFG_TUD_VENDOR_TX_BUFSIZE 0 -#endif - #ifdef __cplusplus extern "C" { #endif @@ -49,21 +41,24 @@ //--------------------------------------------------------------------+ // Application API (Multiple Interfaces) //--------------------------------------------------------------------+ -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); -uint32_t tud_vendor_n_write (uint8_t itf, void const* buffer, uint32_t bufsize); +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, int pos, uint8_t* u8); +uint32_t tud_vendor_n_write (uint8_t itf, void const* buffer, uint32_t bufsize); -static inline uint32_t tud_vendor_n_write_str (uint8_t itf, char const* str); +static inline +uint32_t tud_vendor_n_write_str (uint8_t itf, char const* str); //--------------------------------------------------------------------+ // Application API (Single Port) //--------------------------------------------------------------------+ -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 uint32_t tud_vendor_write (void const* buffer, uint32_t bufsize); -static inline uint32_t tud_vendor_write_str (char const* str); +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 (int pos, uint8_t* u8); +static inline uint32_t tud_vendor_write (void const* buffer, uint32_t bufsize); +static inline uint32_t tud_vendor_write_str (char const* str); //--------------------------------------------------------------------+ // Application Callback API (weak is optional) @@ -96,6 +91,11 @@ static inline uint32_t tud_vendor_read (void* buffer, uint32_t bufsize) return tud_vendor_n_read(0, buffer, bufsize); } +static inline bool tud_vendor_peek (int pos, uint8_t* u8) +{ + return tud_vendor_n_peek(0, pos, u8); +} + static inline uint32_t tud_vendor_write (void const* buffer, uint32_t bufsize) { return tud_vendor_n_write(0, buffer, bufsize); diff --git a/src/common/tusb_types.h b/src/common/tusb_types.h index e7c0c93e..9aea2d77 100644 --- a/src/common/tusb_types.h +++ b/src/common/tusb_types.h @@ -469,15 +469,6 @@ static inline uint8_t tu_desc_len(void const* desc) return ((uint8_t const*) desc)[DESC_OFFSET_LEN]; } -// Length of the string descriptors in bytes with slen characters -#define TUD_DESC_STRLEN(_chr_count) (2*(_chr_count) + 2) - -// Header of string descriptors with len + string type -#define TUD_DESC_STR_HEADER(_chr_count) ( (uint16_t) ( (TUSB_DESC_STRING << 8 ) | TUD_DESC_STRLEN(_chr_count)) ) - -// Convert comma-separated string to descriptor unicode format -#define TUD_DESC_STRCONV( ... ) (const uint16_t[]) { TUD_DESC_STR_HEADER(TU_ARGS_NUM(__VA_ARGS__)), __VA_ARGS__ } - #ifdef __cplusplus } #endif diff --git a/src/device/usbd.h b/src/device/usbd.h index 6e781f18..396964e0 100644 --- a/src/device/usbd.h +++ b/src/device/usbd.h @@ -133,7 +133,6 @@ TU_ATTR_WEAK bool tud_vendor_control_complete_cb(uint8_t rhport, tusb_control_re 0x8B, 0xFD, 0xA0, 0x76, 0x88, 0x15, 0xB6, 0x65 //------------- Microsoft OS 2.0 Platform -------------// - #define TUD_BOS_MICROSOFT_OS_DESC_LEN 28 // Total Length of descriptor set, vendor code @@ -144,7 +143,6 @@ TU_ATTR_WEAK bool tud_vendor_control_complete_cb(uint8_t rhport, tusb_control_re 0xDF, 0x60, 0xDD, 0xD8, 0x89, 0x45, 0xC7, 0x4C, \ 0x9C, 0xD2, 0x65, 0x9D, 0x9E, 0x64, 0x8A, 0x9F - //--------------------------------------------------------------------+ // Configuration & Interface Descriptor Templates //--------------------------------------------------------------------+