summaryrefslogtreecommitdiff
path: root/examples/device/webusb_serial
diff options
context:
space:
mode:
Diffstat (limited to 'examples/device/webusb_serial')
-rw-r--r--examples/device/webusb_serial/CMakeLists.txt2
-rw-r--r--examples/device/webusb_serial/CMakePresets.json6
-rw-r--r--examples/device/webusb_serial/src/main.c130
-rw-r--r--examples/device/webusb_serial/src/tusb_config.h2
-rw-r--r--examples/device/webusb_serial/src/usb_descriptors.c55
5 files changed, 92 insertions, 103 deletions
diff --git a/examples/device/webusb_serial/CMakeLists.txt b/examples/device/webusb_serial/CMakeLists.txt
index e92a57148..ced98a909 100644
--- a/examples/device/webusb_serial/CMakeLists.txt
+++ b/examples/device/webusb_serial/CMakeLists.txt
@@ -1,4 +1,4 @@
-cmake_minimum_required(VERSION 3.17)
+cmake_minimum_required(VERSION 3.20)
include(${CMAKE_CURRENT_SOURCE_DIR}/../../../hw/bsp/family_support.cmake)
diff --git a/examples/device/webusb_serial/CMakePresets.json b/examples/device/webusb_serial/CMakePresets.json
new file mode 100644
index 000000000..5cd8971e9
--- /dev/null
+++ b/examples/device/webusb_serial/CMakePresets.json
@@ -0,0 +1,6 @@
+{
+ "version": 6,
+ "include": [
+ "../../../hw/bsp/BoardPresets.json"
+ ]
+}
diff --git a/examples/device/webusb_serial/src/main.c b/examples/device/webusb_serial/src/main.c
index 800d435b8..d189af91f 100644
--- a/examples/device/webusb_serial/src/main.c
+++ b/examples/device/webusb_serial/src/main.c
@@ -73,8 +73,7 @@ static uint32_t blink_interval_ms = BLINK_NOT_MOUNTED;
#define URL "example.tinyusb.org/webusb-serial/index.html"
-const tusb_desc_webusb_url_t desc_url =
-{
+const tusb_desc_webusb_url_t desc_url = {
.bLength = 3 + sizeof(URL) - 1,
.bDescriptorType = 3, // WEBUSB URL type
.bScheme = 1, // 0: http, 1: https
@@ -86,47 +85,44 @@ static bool web_serial_connected = false;
//------------- prototypes -------------//
void led_blinking_task(void);
void cdc_task(void);
-void webserial_task(void);
/*------------- MAIN -------------*/
-int main(void)
-{
+int main(void) {
board_init();
// init device stack on configured roothub port
- tud_init(BOARD_TUD_RHPORT);
+ tusb_rhport_init_t dev_init = {
+ .role = TUSB_ROLE_DEVICE,
+ .speed = TUSB_SPEED_AUTO
+ };
+ tusb_init(BOARD_TUD_RHPORT, &dev_init);
if (board_init_after_tusb) {
board_init_after_tusb();
}
- while (1)
- {
+ while (1) {
tud_task(); // tinyusb device task
cdc_task();
- webserial_task();
led_blinking_task();
}
}
// send characters to both CDC and WebUSB
-void echo_all(uint8_t buf[], uint32_t count)
-{
+void echo_all(const uint8_t buf[], uint32_t count) {
// echo to web serial
- if ( web_serial_connected )
- {
+ if (web_serial_connected) {
tud_vendor_write(buf, count);
tud_vendor_write_flush();
}
// echo to cdc
- if ( tud_cdc_connected() )
- {
- for(uint32_t i=0; i<count; i++)
- {
+ if (tud_cdc_connected()) {
+ for (uint32_t i = 0; i < count; i++) {
tud_cdc_write_char(buf[i]);
-
- if ( buf[i] == '\r' ) tud_cdc_write_char('\n');
+ if (buf[i] == '\r') {
+ tud_cdc_write_char('\n');
+ }
}
tud_cdc_write_flush();
}
@@ -137,29 +133,25 @@ void echo_all(uint8_t buf[], uint32_t count)
//--------------------------------------------------------------------+
// Invoked when device is mounted
-void tud_mount_cb(void)
-{
+void tud_mount_cb(void) {
blink_interval_ms = BLINK_MOUNTED;
}
// Invoked when device is unmounted
-void tud_umount_cb(void)
-{
+void tud_umount_cb(void) {
blink_interval_ms = BLINK_NOT_MOUNTED;
}
// Invoked when usb bus is suspended
// remote_wakeup_en : if host allow us to perform remote wakeup
// Within 7ms, device must draw an average of current less than 2.5 mA from bus
-void tud_suspend_cb(bool remote_wakeup_en)
-{
- (void) remote_wakeup_en;
+void tud_suspend_cb(bool remote_wakeup_en) {
+ (void)remote_wakeup_en;
blink_interval_ms = BLINK_SUSPENDED;
}
// Invoked when usb bus is resumed
-void tud_resume_cb(void)
-{
+void tud_resume_cb(void) {
blink_interval_ms = tud_mounted() ? BLINK_MOUNTED : BLINK_NOT_MOUNTED;
}
@@ -170,61 +162,53 @@ void tud_resume_cb(void)
// 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 tud_vendor_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t const * request)
-{
+bool tud_vendor_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t const* request) {
// nothing to with DATA & ACK stage
if (stage != CONTROL_STAGE_SETUP) return true;
- switch (request->bmRequestType_bit.type)
- {
+ switch (request->bmRequestType_bit.type) {
case TUSB_REQ_TYPE_VENDOR:
- switch (request->bRequest)
- {
+ switch (request->bRequest) {
case VENDOR_REQUEST_WEBUSB:
// match vendor request in BOS descriptor
// Get landing page url
- return tud_control_xfer(rhport, request, (void*)(uintptr_t) &desc_url, desc_url.bLength);
+ return tud_control_xfer(rhport, request, (void*)(uintptr_t)&desc_url, desc_url.bLength);
case VENDOR_REQUEST_MICROSOFT:
- if ( request->wIndex == 7 )
- {
+ if (request->wIndex == 7) {
// Get Microsoft OS 2.0 compatible descriptor
uint16_t total_len;
- memcpy(&total_len, desc_ms_os_20+8, 2);
+ memcpy(&total_len, desc_ms_os_20 + 8, 2);
- return tud_control_xfer(rhport, request, (void*)(uintptr_t) desc_ms_os_20, total_len);
- }else
- {
+ return tud_control_xfer(rhport, request, (void*)(uintptr_t)desc_ms_os_20, total_len);
+ } else {
return false;
}
default: break;
}
- break;
+ break;
case TUSB_REQ_TYPE_CLASS:
- if (request->bRequest == 0x22)
- {
+ if (request->bRequest == 0x22) {
// Webserial simulate the CDC_REQUEST_SET_CONTROL_LINE_STATE (0x22) to connect and disconnect.
web_serial_connected = (request->wValue != 0);
// Always lit LED if connected
- if ( web_serial_connected )
- {
+ if (web_serial_connected) {
board_led_write(true);
blink_interval_ms = BLINK_ALWAYS_ON;
tud_vendor_write_str("\r\nWebUSB interface connected\r\n");
tud_vendor_write_flush();
- }else
- {
+ } else {
blink_interval_ms = BLINK_MOUNTED;
}
// response with status OK
return tud_control_status(rhport, request);
}
- break;
+ break;
default: break;
}
@@ -233,32 +217,24 @@ bool tud_vendor_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_requ
return false;
}
-void webserial_task(void)
-{
- if ( web_serial_connected )
- {
- if ( tud_vendor_available() )
- {
- uint8_t buf[64];
- uint32_t count = tud_vendor_read(buf, sizeof(buf));
+void tud_vendor_rx_cb(uint8_t itf, uint8_t const* buffer, uint16_t bufsize) {
+ (void) itf;
- // echo back to both web serial and cdc
- echo_all(buf, count);
- }
- }
-}
+ echo_all(buffer, bufsize);
+ // if using RX buffered is enabled, we need to flush the buffer to make room for new data
+ #if CFG_TUD_VENDOR_RX_BUFSIZE > 0
+ tud_vendor_read_flush();
+ #endif
+}
//--------------------------------------------------------------------+
// USB CDC
//--------------------------------------------------------------------+
-void cdc_task(void)
-{
- if ( tud_cdc_connected() )
- {
+void cdc_task(void) {
+ if (tud_cdc_connected()) {
// connected and there are data available
- if ( tud_cdc_available() )
- {
+ if (tud_cdc_available()) {
uint8_t buf[64];
uint32_t count = tud_cdc_read(buf, sizeof(buf));
@@ -270,34 +246,30 @@ void cdc_task(void)
}
// Invoked when cdc when line state changed e.g connected/disconnected
-void tud_cdc_line_state_cb(uint8_t itf, bool dtr, bool rts)
-{
- (void) itf;
+void tud_cdc_line_state_cb(uint8_t itf, bool dtr, bool rts) {
+ (void)itf;
// connected
- if ( dtr && rts )
- {
+ if (dtr && rts) {
// print initial message when connected
tud_cdc_write_str("\r\nTinyUSB WebUSB device example\r\n");
}
}
// Invoked when CDC interface received data from host
-void tud_cdc_rx_cb(uint8_t itf)
-{
- (void) itf;
+void tud_cdc_rx_cb(uint8_t itf) {
+ (void)itf;
}
//--------------------------------------------------------------------+
// BLINKING TASK
//--------------------------------------------------------------------+
-void led_blinking_task(void)
-{
+void led_blinking_task(void) {
static uint32_t start_ms = 0;
static bool led_state = false;
// Blink every interval ms
- if ( board_millis() - start_ms < blink_interval_ms) return; // not enough time
+ if (board_millis() - start_ms < blink_interval_ms) return; // not enough time
start_ms += blink_interval_ms;
board_led_write(led_state);
diff --git a/examples/device/webusb_serial/src/tusb_config.h b/examples/device/webusb_serial/src/tusb_config.h
index fde732b9e..b86ad3752 100644
--- a/examples/device/webusb_serial/src/tusb_config.h
+++ b/examples/device/webusb_serial/src/tusb_config.h
@@ -102,7 +102,7 @@
#define CFG_TUD_CDC_TX_BUFSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64)
// Vendor FIFO size of TX and RX
-// If not configured vendor endpoints will not be buffered
+// If zero: vendor endpoints will not be buffered
#define CFG_TUD_VENDOR_RX_BUFSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64)
#define CFG_TUD_VENDOR_TX_BUFSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64)
diff --git a/examples/device/webusb_serial/src/usb_descriptors.c b/examples/device/webusb_serial/src/usb_descriptors.c
index b01fae8e3..2b69a5b56 100644
--- a/examples/device/webusb_serial/src/usb_descriptors.c
+++ b/examples/device/webusb_serial/src/usb_descriptors.c
@@ -87,29 +87,40 @@ enum
#if CFG_TUSB_MCU == OPT_MCU_LPC175X_6X || CFG_TUSB_MCU == OPT_MCU_LPC177X_8X || CFG_TUSB_MCU == OPT_MCU_LPC40XX
// LPC 17xx and 40xx endpoint type (bulk/interrupt/iso) are fixed by its number
// 0 control, 1 In, 2 Bulk, 3 Iso, 4 In etc ...
- #define EPNUM_CDC_IN 2
- #define EPNUM_CDC_OUT 2
- #define EPNUM_VENDOR_IN 5
- #define EPNUM_VENDOR_OUT 5
-#elif CFG_TUSB_MCU == OPT_MCU_SAMG || CFG_TUSB_MCU == OPT_MCU_SAMX7X
- // SAMG & SAME70 don't support a same endpoint number with different direction IN and OUT
- // e.g EP1 OUT & EP1 IN cannot exist together
- #define EPNUM_CDC_IN 2
- #define EPNUM_CDC_OUT 3
- #define EPNUM_VENDOR_IN 4
- #define EPNUM_VENDOR_OUT 5
-#elif CFG_TUSB_MCU == OPT_MCU_FT90X || CFG_TUSB_MCU == OPT_MCU_FT93X
- // FT9XX doesn't support a same endpoint number with different direction IN and OUT
+ #define EPNUM_CDC_NOTIF 0x81
+ #define EPNUM_CDC_OUT 0x02
+ #define EPNUM_CDC_IN 0x82
+
+ #define EPNUM_VENDOR_OUT 0x05
+ #define EPNUM_VENDOR_IN 0x85
+
+#elif CFG_TUSB_MCU == OPT_MCU_CXD56
+ // CXD56 USB driver has fixed endpoint type (bulk/interrupt/iso) and direction (IN/OUT) by its number
+ // 0 control (IN/OUT), 1 Bulk (IN), 2 Bulk (OUT), 3 In (IN), 4 Bulk (IN), 5 Bulk (OUT), 6 In (IN)
+ #define EPNUM_CDC_NOTIF 0x83
+ #define EPNUM_CDC_OUT 0x02
+ #define EPNUM_CDC_IN 0x81
+
+ #define EPNUM_VENDOR_OUT 0x05
+ #define EPNUM_VENDOR_IN 0x84
+
+#elif defined(TUD_ENDPOINT_ONE_DIRECTION_ONLY)
+ // MCUs that don't support a same endpoint number with different direction IN and OUT defined in tusb_mcu.h
// e.g EP1 OUT & EP1 IN cannot exist together
- #define EPNUM_CDC_IN 2
- #define EPNUM_CDC_OUT 3
- #define EPNUM_VENDOR_IN 4
- #define EPNUM_VENDOR_OUT 5
+ #define EPNUM_CDC_NOTIF 0x81
+ #define EPNUM_CDC_OUT 0x02
+ #define EPNUM_CDC_IN 0x83
+
+ #define EPNUM_VENDOR_OUT 0x04
+ #define EPNUM_VENDOR_IN 0x85
+
#else
- #define EPNUM_CDC_IN 2
- #define EPNUM_CDC_OUT 2
- #define EPNUM_VENDOR_IN 3
- #define EPNUM_VENDOR_OUT 3
+ #define EPNUM_CDC_NOTIF 0x81
+ #define EPNUM_CDC_OUT 0x02
+ #define EPNUM_CDC_IN 0x82
+
+ #define EPNUM_VENDOR_OUT 0x03
+ #define EPNUM_VENDOR_IN 0x83
#endif
uint8_t const desc_configuration[] =
@@ -118,7 +129,7 @@ uint8_t const desc_configuration[] =
TUD_CONFIG_DESCRIPTOR(1, ITF_NUM_TOTAL, 0, CONFIG_TOTAL_LEN, 0x00, 100),
// Interface number, string index, EP notification address and size, EP data address (out, in) and size.
- TUD_CDC_DESCRIPTOR(ITF_NUM_CDC, 4, 0x81, 8, EPNUM_CDC_OUT, 0x80 | EPNUM_CDC_IN, TUD_OPT_HIGH_SPEED ? 512 : 64),
+ TUD_CDC_DESCRIPTOR(ITF_NUM_CDC, 4, EPNUM_CDC_NOTIF, 8, EPNUM_CDC_OUT, 0x80 | EPNUM_CDC_IN, TUD_OPT_HIGH_SPEED ? 512 : 64),
// Interface number, string index, EP Out & IN address, EP size
TUD_VENDOR_DESCRIPTOR(ITF_NUM_VENDOR, 5, EPNUM_VENDOR_OUT, 0x80 | EPNUM_VENDOR_IN, TUD_OPT_HIGH_SPEED ? 512 : 64)