From 340dcb81bfc7074ca01bbee6177ea52562aa3b51 Mon Sep 17 00:00:00 2001 From: Nathan Conrad Date: Thu, 12 Sep 2019 15:39:51 -0400 Subject: For control transfers, compare the transmitted length against the requested length to know if a ZLP needs to happen. (fixes #139) --- src/device/usbd_control.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/device/usbd_control.c b/src/device/usbd_control.c index 4ec432185..e54d04456 100644 --- a/src/device/usbd_control.c +++ b/src/device/usbd_control.c @@ -43,8 +43,9 @@ typedef struct tusb_control_request_t request; void* buffer; - uint16_t total_len; + uint16_t len; uint16_t total_transferred; + uint16_t requested_len; bool (*complete_cb) (uint8_t, tusb_control_request_t const *); } usbd_control_xfer_t; @@ -68,7 +69,7 @@ bool tud_control_status(uint8_t rhport, tusb_control_request_t const * request) // Each transaction is up to endpoint0's max packet size static bool start_control_data_xact(uint8_t rhport) { - uint16_t const xact_len = tu_min16(_control_state.total_len - _control_state.total_transferred, CFG_TUD_ENDPOINT0_SIZE); + uint16_t const xact_len = tu_min16(_control_state.len - _control_state.total_transferred, CFG_TUD_ENDPOINT0_SIZE); uint8_t ep_addr = EDPT_CTRL_OUT; @@ -89,10 +90,16 @@ void usbd_control_set_complete_callback( bool (*fp) (uint8_t, tusb_control_reque bool tud_control_xfer(uint8_t rhport, tusb_control_request_t const * request, void* buffer, uint16_t len) { + // transmitted length must be <= requested length (USB 2.0 spec: 8.5.3.1 ) + // FIXME: Should logic be here or in place that calls this function? + if(len > request->wLength) + len = request->wLength; + _control_state.request = (*request); _control_state.buffer = buffer; - _control_state.total_len = tu_min16(len, request->wLength); _control_state.total_transferred = 0; + _control_state.requested_len = request->wLength; + _control_state.len = len; if ( len ) { @@ -124,7 +131,7 @@ bool usbd_control_xfer_cb (uint8_t rhport, uint8_t ep_addr, xfer_result_t result _control_state.total_transferred += xferred_bytes; _control_state.buffer += xferred_bytes; - if ( _control_state.total_len == _control_state.total_transferred || xferred_bytes < CFG_TUD_ENDOINT0_SIZE ) + if ( (_control_state.requested_len == _control_state.total_transferred) || xferred_bytes < CFG_TUD_ENDOINT0_SIZE ) { // DATA stage is complete bool is_ok = true; -- cgit v1.3.1 From 8cca287683a4376f7483b579dcf36c2d1daf8fab Mon Sep 17 00:00:00 2001 From: Nathan Conrad Date: Thu, 12 Sep 2019 16:03:45 -0400 Subject: Add verification that there is enough buffer space for HID OUT control transfer. --- src/class/hid/hid_device.c | 1 + 1 file changed, 1 insertion(+) (limited to 'src') diff --git a/src/class/hid/hid_device.c b/src/class/hid/hid_device.c index 572f2cad2..7270904ca 100644 --- a/src/class/hid/hid_device.c +++ b/src/class/hid/hid_device.c @@ -230,6 +230,7 @@ bool hidd_control_request(uint8_t rhport, tusb_control_request_t const * p_reque break; case HID_REQ_CONTROL_SET_REPORT: + TU_VERIFY(p_request->wLength <=sizeof(p_hid->epout_buf)); tud_control_xfer(rhport, p_request, p_hid->epout_buf, p_request->wLength); break; -- cgit v1.3.1 From 4ea2a4ed60c41c8b55bfb40459e5f54615e2dc72 Mon Sep 17 00:00:00 2001 From: Nathan Conrad Date: Sun, 29 Sep 2019 10:45:13 -0400 Subject: Github's web interface changed line endings without asking me. Oops. --- src/device/usbd_control.c | 334 +++++++++++++++++++++++----------------------- 1 file changed, 167 insertions(+), 167 deletions(-) (limited to 'src') diff --git a/src/device/usbd_control.c b/src/device/usbd_control.c index de1075033..e8bb648c9 100644 --- a/src/device/usbd_control.c +++ b/src/device/usbd_control.c @@ -1,167 +1,167 @@ -/* - * The MIT License (MIT) - * - * Copyright (c) 2019 Ha Thach (tinyusb.org) - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - * This file is part of the TinyUSB stack. - */ - -#include "tusb_option.h" - -#if TUSB_OPT_DEVICE_ENABLED - -#include "tusb.h" -#include "device/usbd_pvt.h" -#include "dcd.h" - -enum -{ - EDPT_CTRL_OUT = 0x00, - EDPT_CTRL_IN = 0x80 -}; - -typedef struct -{ - tusb_control_request_t request; - - void* buffer; - uint16_t len; - uint16_t total_transferred; - uint16_t requested_len; - - bool (*complete_cb) (uint8_t, tusb_control_request_t const *); -} usbd_control_xfer_t; - -static usbd_control_xfer_t _control_state; - -CFG_TUSB_MEM_SECTION CFG_TUSB_MEM_ALIGN uint8_t _usbd_ctrl_buf[CFG_TUD_ENDPOINT0_SIZE]; - -void usbd_control_reset (uint8_t rhport) -{ - (void) rhport; - tu_varclr(&_control_state); -} - -bool tud_control_status(uint8_t rhport, tusb_control_request_t const * request) -{ - // status direction is reversed to one in the setup packet - return dcd_edpt_xfer(rhport, request->bmRequestType_bit.direction ? EDPT_CTRL_OUT : EDPT_CTRL_IN, NULL, 0); -} - -// Each transaction is up to endpoint0's max packet size -static bool start_control_data_xact(uint8_t rhport) -{ - uint16_t const xact_len = tu_min16(_control_state.len - _control_state.total_transferred, CFG_TUD_ENDPOINT0_SIZE); - - uint8_t ep_addr = EDPT_CTRL_OUT; - - if ( _control_state.request.bmRequestType_bit.direction == TUSB_DIR_IN ) - { - ep_addr = EDPT_CTRL_IN; - memcpy(_usbd_ctrl_buf, _control_state.buffer, xact_len); - } - - return dcd_edpt_xfer(rhport, ep_addr, _usbd_ctrl_buf, xact_len); -} - -// TODO may find a better way -void usbd_control_set_complete_callback( bool (*fp) (uint8_t, tusb_control_request_t const * ) ) -{ - _control_state.complete_cb = fp; -} - -bool tud_control_xfer(uint8_t rhport, tusb_control_request_t const * request, void* buffer, uint16_t len) -{ - // transmitted length must be <= requested length (USB 2.0 spec: 8.5.3.1 ) - // FIXME: Should logic be here or in place that calls this function? - if(len > request->wLength) - len = request->wLength; - - _control_state.request = (*request); - _control_state.buffer = buffer; - _control_state.total_transferred = 0; - _control_state.requested_len = request->wLength; - _control_state.len = len; - - if ( len ) - { - TU_ASSERT(buffer); - - // Data stage - TU_ASSERT( start_control_data_xact(rhport) ); - }else - { - // Status stage - TU_ASSERT( tud_control_status(rhport, request) ); - } - - return true; -} - -// callback when a transaction complete on DATA stage of control endpoint -bool usbd_control_xfer_cb (uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes) -{ - (void) result; - (void) ep_addr; - - if ( _control_state.request.bmRequestType_bit.direction == TUSB_DIR_OUT ) - { - TU_VERIFY(_control_state.buffer); - memcpy(_control_state.buffer, _usbd_ctrl_buf, xferred_bytes); - } - - _control_state.total_transferred += xferred_bytes; - _control_state.buffer = ((uint8_t*)_control_state.buffer) + xferred_bytes; - - if ( (_control_state.requested_len == _control_state.total_transferred) || xferred_bytes < CFG_TUD_ENDPOINT0_SIZE ) - - { - // DATA stage is complete - bool is_ok = true; - - // invoke complete callback if set - // callback can still stall control in status phase e.g out data does not make sense - if ( _control_state.complete_cb ) - { - is_ok = _control_state.complete_cb(rhport, &_control_state.request); - } - - if ( is_ok ) - { - // Send status - TU_ASSERT( tud_control_status(rhport, &_control_state.request) ); - }else - { - // Stall both IN and OUT control endpoint - dcd_edpt_stall(rhport, EDPT_CTRL_OUT); - dcd_edpt_stall(rhport, EDPT_CTRL_IN); - } - } - else - { - // More data to transfer - TU_ASSERT( start_control_data_xact(rhport) ); - } - - return true; -} - -#endif +/* + * The MIT License (MIT) + * + * Copyright (c) 2019 Ha Thach (tinyusb.org) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + +#include "tusb_option.h" + +#if TUSB_OPT_DEVICE_ENABLED + +#include "tusb.h" +#include "device/usbd_pvt.h" +#include "dcd.h" + +enum +{ + EDPT_CTRL_OUT = 0x00, + EDPT_CTRL_IN = 0x80 +}; + +typedef struct +{ + tusb_control_request_t request; + + void* buffer; + uint16_t len; + uint16_t total_transferred; + uint16_t requested_len; + + bool (*complete_cb) (uint8_t, tusb_control_request_t const *); +} usbd_control_xfer_t; + +static usbd_control_xfer_t _control_state; + +CFG_TUSB_MEM_SECTION CFG_TUSB_MEM_ALIGN uint8_t _usbd_ctrl_buf[CFG_TUD_ENDPOINT0_SIZE]; + +void usbd_control_reset (uint8_t rhport) +{ + (void) rhport; + tu_varclr(&_control_state); +} + +bool tud_control_status(uint8_t rhport, tusb_control_request_t const * request) +{ + // status direction is reversed to one in the setup packet + return dcd_edpt_xfer(rhport, request->bmRequestType_bit.direction ? EDPT_CTRL_OUT : EDPT_CTRL_IN, NULL, 0); +} + +// Each transaction is up to endpoint0's max packet size +static bool start_control_data_xact(uint8_t rhport) +{ + uint16_t const xact_len = tu_min16(_control_state.len - _control_state.total_transferred, CFG_TUD_ENDPOINT0_SIZE); + + uint8_t ep_addr = EDPT_CTRL_OUT; + + if ( _control_state.request.bmRequestType_bit.direction == TUSB_DIR_IN ) + { + ep_addr = EDPT_CTRL_IN; + memcpy(_usbd_ctrl_buf, _control_state.buffer, xact_len); + } + + return dcd_edpt_xfer(rhport, ep_addr, _usbd_ctrl_buf, xact_len); +} + +// TODO may find a better way +void usbd_control_set_complete_callback( bool (*fp) (uint8_t, tusb_control_request_t const * ) ) +{ + _control_state.complete_cb = fp; +} + +bool tud_control_xfer(uint8_t rhport, tusb_control_request_t const * request, void* buffer, uint16_t len) +{ + // transmitted length must be <= requested length (USB 2.0 spec: 8.5.3.1 ) + // FIXME: Should logic be here or in place that calls this function? + if(len > request->wLength) + len = request->wLength; + + _control_state.request = (*request); + _control_state.buffer = buffer; + _control_state.total_transferred = 0; + _control_state.requested_len = request->wLength; + _control_state.len = len; + + if ( len ) + { + TU_ASSERT(buffer); + + // Data stage + TU_ASSERT( start_control_data_xact(rhport) ); + }else + { + // Status stage + TU_ASSERT( tud_control_status(rhport, request) ); + } + + return true; +} + +// callback when a transaction complete on DATA stage of control endpoint +bool usbd_control_xfer_cb (uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes) +{ + (void) result; + (void) ep_addr; + + if ( _control_state.request.bmRequestType_bit.direction == TUSB_DIR_OUT ) + { + TU_VERIFY(_control_state.buffer); + memcpy(_control_state.buffer, _usbd_ctrl_buf, xferred_bytes); + } + + _control_state.total_transferred += xferred_bytes; + _control_state.buffer = ((uint8_t*)_control_state.buffer) + xferred_bytes; + + if ( (_control_state.requested_len == _control_state.total_transferred) || xferred_bytes < CFG_TUD_ENDPOINT0_SIZE ) + + { + // DATA stage is complete + bool is_ok = true; + + // invoke complete callback if set + // callback can still stall control in status phase e.g out data does not make sense + if ( _control_state.complete_cb ) + { + is_ok = _control_state.complete_cb(rhport, &_control_state.request); + } + + if ( is_ok ) + { + // Send status + TU_ASSERT( tud_control_status(rhport, &_control_state.request) ); + }else + { + // Stall both IN and OUT control endpoint + dcd_edpt_stall(rhport, EDPT_CTRL_OUT); + dcd_edpt_stall(rhport, EDPT_CTRL_IN); + } + } + else + { + // More data to transfer + TU_ASSERT( start_control_data_xact(rhport) ); + } + + return true; +} + +#endif -- cgit v1.3.1 From e6857d8ee087c8185dda2901646fbec1352e2292 Mon Sep 17 00:00:00 2001 From: hathach Date: Thu, 31 Oct 2019 11:25:41 +0700 Subject: clean up --- src/device/usbd_control.c | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) (limited to 'src') diff --git a/src/device/usbd_control.c b/src/device/usbd_control.c index e8bb648c9..8b1c92d81 100644 --- a/src/device/usbd_control.c +++ b/src/device/usbd_control.c @@ -45,7 +45,6 @@ typedef struct void* buffer; uint16_t len; uint16_t total_transferred; - uint16_t requested_len; bool (*complete_cb) (uint8_t, tusb_control_request_t const *); } usbd_control_xfer_t; @@ -90,16 +89,10 @@ void usbd_control_set_complete_callback( bool (*fp) (uint8_t, tusb_control_reque bool tud_control_xfer(uint8_t rhport, tusb_control_request_t const * request, void* buffer, uint16_t len) { - // transmitted length must be <= requested length (USB 2.0 spec: 8.5.3.1 ) - // FIXME: Should logic be here or in place that calls this function? - if(len > request->wLength) - len = request->wLength; - _control_state.request = (*request); _control_state.buffer = buffer; _control_state.total_transferred = 0; - _control_state.requested_len = request->wLength; - _control_state.len = len; + _control_state.len = tu_min16(len, request->wLength); if ( len ) { @@ -131,7 +124,7 @@ bool usbd_control_xfer_cb (uint8_t rhport, uint8_t ep_addr, xfer_result_t result _control_state.total_transferred += xferred_bytes; _control_state.buffer = ((uint8_t*)_control_state.buffer) + xferred_bytes; - if ( (_control_state.requested_len == _control_state.total_transferred) || xferred_bytes < CFG_TUD_ENDPOINT0_SIZE ) + if ( (_control_state.request.wLength == _control_state.total_transferred) || xferred_bytes < CFG_TUD_ENDPOINT0_SIZE ) { // DATA stage is complete -- cgit v1.3.1 From 0029b584177174ba6269a76151b029a03d8c09fc Mon Sep 17 00:00:00 2001 From: hathach Date: Thu, 31 Oct 2019 12:15:16 +0700 Subject: rename --- src/device/usbd_control.c | 39 +++++++++++++++++++-------------------- 1 file changed, 19 insertions(+), 20 deletions(-) (limited to 'src') diff --git a/src/device/usbd_control.c b/src/device/usbd_control.c index 8b1c92d81..7c970d605 100644 --- a/src/device/usbd_control.c +++ b/src/device/usbd_control.c @@ -49,14 +49,14 @@ typedef struct bool (*complete_cb) (uint8_t, tusb_control_request_t const *); } usbd_control_xfer_t; -static usbd_control_xfer_t _control_state; +static usbd_control_xfer_t _ctrl_xfer; CFG_TUSB_MEM_SECTION CFG_TUSB_MEM_ALIGN uint8_t _usbd_ctrl_buf[CFG_TUD_ENDPOINT0_SIZE]; void usbd_control_reset (uint8_t rhport) { (void) rhport; - tu_varclr(&_control_state); + tu_varclr(&_ctrl_xfer); } bool tud_control_status(uint8_t rhport, tusb_control_request_t const * request) @@ -68,14 +68,14 @@ bool tud_control_status(uint8_t rhport, tusb_control_request_t const * request) // Each transaction is up to endpoint0's max packet size static bool start_control_data_xact(uint8_t rhport) { - uint16_t const xact_len = tu_min16(_control_state.len - _control_state.total_transferred, CFG_TUD_ENDPOINT0_SIZE); + uint16_t const xact_len = tu_min16(_ctrl_xfer.len - _ctrl_xfer.total_transferred, CFG_TUD_ENDPOINT0_SIZE); uint8_t ep_addr = EDPT_CTRL_OUT; - if ( _control_state.request.bmRequestType_bit.direction == TUSB_DIR_IN ) + if ( _ctrl_xfer.request.bmRequestType_bit.direction == TUSB_DIR_IN ) { ep_addr = EDPT_CTRL_IN; - memcpy(_usbd_ctrl_buf, _control_state.buffer, xact_len); + memcpy(_usbd_ctrl_buf, _ctrl_xfer.buffer, xact_len); } return dcd_edpt_xfer(rhport, ep_addr, _usbd_ctrl_buf, xact_len); @@ -84,15 +84,15 @@ static bool start_control_data_xact(uint8_t rhport) // TODO may find a better way void usbd_control_set_complete_callback( bool (*fp) (uint8_t, tusb_control_request_t const * ) ) { - _control_state.complete_cb = fp; + _ctrl_xfer.complete_cb = fp; } bool tud_control_xfer(uint8_t rhport, tusb_control_request_t const * request, void* buffer, uint16_t len) { - _control_state.request = (*request); - _control_state.buffer = buffer; - _control_state.total_transferred = 0; - _control_state.len = tu_min16(len, request->wLength); + _ctrl_xfer.request = (*request); + _ctrl_xfer.buffer = buffer; + _ctrl_xfer.total_transferred = 0; + _ctrl_xfer.len = tu_min16(len, request->wLength); if ( len ) { @@ -115,32 +115,31 @@ bool usbd_control_xfer_cb (uint8_t rhport, uint8_t ep_addr, xfer_result_t result (void) result; (void) ep_addr; - if ( _control_state.request.bmRequestType_bit.direction == TUSB_DIR_OUT ) + if ( _ctrl_xfer.request.bmRequestType_bit.direction == TUSB_DIR_OUT ) { - TU_VERIFY(_control_state.buffer); - memcpy(_control_state.buffer, _usbd_ctrl_buf, xferred_bytes); + TU_VERIFY(_ctrl_xfer.buffer); + memcpy(_ctrl_xfer.buffer, _usbd_ctrl_buf, xferred_bytes); } - _control_state.total_transferred += xferred_bytes; - _control_state.buffer = ((uint8_t*)_control_state.buffer) + xferred_bytes; - - if ( (_control_state.request.wLength == _control_state.total_transferred) || xferred_bytes < CFG_TUD_ENDPOINT0_SIZE ) + _ctrl_xfer.total_transferred += xferred_bytes; + _ctrl_xfer.buffer = ((uint8_t*)_ctrl_xfer.buffer) + xferred_bytes; + if ( (_ctrl_xfer.request.wLength == _ctrl_xfer.total_transferred) || xferred_bytes < CFG_TUD_ENDPOINT0_SIZE ) { // DATA stage is complete bool is_ok = true; // invoke complete callback if set // callback can still stall control in status phase e.g out data does not make sense - if ( _control_state.complete_cb ) + if ( _ctrl_xfer.complete_cb ) { - is_ok = _control_state.complete_cb(rhport, &_control_state.request); + is_ok = _ctrl_xfer.complete_cb(rhport, &_ctrl_xfer.request); } if ( is_ok ) { // Send status - TU_ASSERT( tud_control_status(rhport, &_control_state.request) ); + TU_ASSERT( tud_control_status(rhport, &_ctrl_xfer.request) ); }else { // Stall both IN and OUT control endpoint -- cgit v1.3.1 From d9ba4d90a8e8e59c111de814acdc7b2cc7ca5bf8 Mon Sep 17 00:00:00 2001 From: hathach Date: Thu, 31 Oct 2019 12:26:36 +0700 Subject: move function around, more rename --- src/device/usbd_control.c | 37 +++++++++++++++++++++++-------------- 1 file changed, 23 insertions(+), 14 deletions(-) (limited to 'src') diff --git a/src/device/usbd_control.c b/src/device/usbd_control.c index 7c970d605..7636f459d 100644 --- a/src/device/usbd_control.c +++ b/src/device/usbd_control.c @@ -53,11 +53,10 @@ static usbd_control_xfer_t _ctrl_xfer; CFG_TUSB_MEM_SECTION CFG_TUSB_MEM_ALIGN uint8_t _usbd_ctrl_buf[CFG_TUD_ENDPOINT0_SIZE]; -void usbd_control_reset (uint8_t rhport) -{ - (void) rhport; - tu_varclr(&_ctrl_xfer); -} + +//--------------------------------------------------------------------+ +// Application API +//--------------------------------------------------------------------+ bool tud_control_status(uint8_t rhport, tusb_control_request_t const * request) { @@ -66,7 +65,7 @@ bool tud_control_status(uint8_t rhport, tusb_control_request_t const * request) } // Each transaction is up to endpoint0's max packet size -static bool start_control_data_xact(uint8_t rhport) +static bool _ctrl_data_xact(uint8_t rhport) { uint16_t const xact_len = tu_min16(_ctrl_xfer.len - _ctrl_xfer.total_transferred, CFG_TUD_ENDPOINT0_SIZE); @@ -81,12 +80,6 @@ static bool start_control_data_xact(uint8_t rhport) return dcd_edpt_xfer(rhport, ep_addr, _usbd_ctrl_buf, xact_len); } -// TODO may find a better way -void usbd_control_set_complete_callback( bool (*fp) (uint8_t, tusb_control_request_t const * ) ) -{ - _ctrl_xfer.complete_cb = fp; -} - bool tud_control_xfer(uint8_t rhport, tusb_control_request_t const * request, void* buffer, uint16_t len) { _ctrl_xfer.request = (*request); @@ -99,7 +92,7 @@ bool tud_control_xfer(uint8_t rhport, tusb_control_request_t const * request, vo TU_ASSERT(buffer); // Data stage - TU_ASSERT( start_control_data_xact(rhport) ); + TU_ASSERT( _ctrl_data_xact(rhport) ); }else { // Status stage @@ -109,6 +102,22 @@ bool tud_control_xfer(uint8_t rhport, tusb_control_request_t const * request, vo return true; } +//--------------------------------------------------------------------+ +// USBD API +//--------------------------------------------------------------------+ + +void usbd_control_reset (uint8_t rhport) +{ + (void) rhport; + tu_varclr(&_ctrl_xfer); +} + +// TODO may find a better way +void usbd_control_set_complete_callback( bool (*fp) (uint8_t, tusb_control_request_t const * ) ) +{ + _ctrl_xfer.complete_cb = fp; +} + // callback when a transaction complete on DATA stage of control endpoint bool usbd_control_xfer_cb (uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes) { @@ -150,7 +159,7 @@ bool usbd_control_xfer_cb (uint8_t rhport, uint8_t ep_addr, xfer_result_t result else { // More data to transfer - TU_ASSERT( start_control_data_xact(rhport) ); + TU_ASSERT( _ctrl_data_xact(rhport) ); } return true; -- cgit v1.3.1 From 6de9eb4b1a6bb84832ce4a55f050763d05f8a6b3 Mon Sep 17 00:00:00 2001 From: hathach Date: Thu, 31 Oct 2019 13:06:57 +0700 Subject: add more tests, fix an issue with tud_descriptor_configuration_cb() return NULL --- src/device/usbd.c | 2 ++ test/test/device/usbd/test_usbd.c | 72 +++++++++++++++++++++++++++++++++------ 2 files changed, 63 insertions(+), 11 deletions(-) (limited to 'src') diff --git a/src/device/usbd.c b/src/device/usbd.c index 46affdab4..2d2f1cafd 100644 --- a/src/device/usbd.c +++ b/src/device/usbd.c @@ -785,6 +785,8 @@ static bool process_get_descriptor(uint8_t rhport, tusb_control_request_t const case TUSB_DESC_CONFIGURATION: { tusb_desc_configuration_t const* desc_config = (tusb_desc_configuration_t const*) tud_descriptor_configuration_cb(desc_index); + TU_ASSERT(desc_config); + uint16_t total_len; memcpy(&total_len, &desc_config->wTotalLength, 2); // possibly mis-aligned memory diff --git a/test/test/device/usbd/test_usbd.c b/test/test/device/usbd/test_usbd.c index d4b3f806b..b58a79a8f 100644 --- a/test/test/device/usbd/test_usbd.c +++ b/test/test/device/usbd/test_usbd.c @@ -40,7 +40,7 @@ TEST_FILE("usbd_control.c") uint8_t const rhport = 0; -tusb_desc_device_t const desc_device = +tusb_desc_device_t const data_desc_device = { .bLength = sizeof(tusb_desc_device_t), .bDescriptorType = TUSB_DESC_DEVICE, @@ -65,6 +65,12 @@ tusb_desc_device_t const desc_device = .bNumConfigurations = 0x01 }; +uint8_t const data_desc_configuration[] = +{ + // Interface count, string index, total length, attribute, power in mA + TUD_CONFIG_DESCRIPTOR(0, 0, TUD_CONFIG_DESC_LEN, TUSB_DESC_CONFIG_ATT_REMOTE_WAKEUP, 100), +}; + tusb_control_request_t const req_get_desc_device = { .bmRequestType = 0x80, @@ -74,20 +80,29 @@ tusb_control_request_t const req_get_desc_device = .wLength = 64 }; +tusb_control_request_t const req_get_desc_configuration = +{ + .bmRequestType = 0x80, + .bRequest = TUSB_REQ_GET_DESCRIPTOR, + .wValue = (TUSB_DESC_CONFIGURATION << 8), + .wIndex = 0x0000, + .wLength = 256 +}; + +uint8_t const* desc_device; +uint8_t const* desc_configuration; + //--------------------------------------------------------------------+ // //--------------------------------------------------------------------+ -uint8_t const * ptr_desc_device; - uint8_t const * tud_descriptor_device_cb(void) { - return ptr_desc_device; + return desc_device; } uint8_t const * tud_descriptor_configuration_cb(uint8_t index) { - TEST_FAIL(); - return NULL; + return desc_configuration; } uint16_t const* tud_descriptor_string_cb(uint8_t index) @@ -105,8 +120,6 @@ void setUp(void) dcd_init_Expect(rhport); tusb_init(); } - - ptr_desc_device = (uint8_t const *) &desc_device; } void tearDown(void) @@ -114,20 +127,23 @@ void tearDown(void) } //--------------------------------------------------------------------+ -// +// Get Descriptor //--------------------------------------------------------------------+ + +//------------- Device -------------// void test_usbd_get_device_descriptor(void) { + desc_device = (uint8_t const *) &data_desc_device; dcd_event_setup_received(rhport, (uint8_t*) &req_get_desc_device, false); - dcd_edpt_xfer_ExpectWithArrayAndReturn(rhport, 0x80, (uint8_t*)&desc_device, sizeof(tusb_desc_device_t), sizeof(tusb_desc_device_t), true); + dcd_edpt_xfer_ExpectWithArrayAndReturn(rhport, 0x80, (uint8_t*)&data_desc_device, sizeof(tusb_desc_device_t), sizeof(tusb_desc_device_t), true); tud_task(); } void test_usbd_get_device_descriptor_null(void) { - ptr_desc_device = NULL; + desc_device = NULL; dcd_event_setup_received(rhport, (uint8_t*) &req_get_desc_device, false); @@ -136,3 +152,37 @@ void test_usbd_get_device_descriptor_null(void) tud_task(); } + +//------------- Configuration -------------// + +void test_usbd_get_configuration_descriptor(void) +{ + desc_configuration = data_desc_configuration; + uint16_t total_len = ((tusb_desc_configuration_t const*) data_desc_configuration)->wTotalLength; + + dcd_event_setup_received(rhport, (uint8_t*) &req_get_desc_configuration, false); + + dcd_edpt_xfer_ExpectWithArrayAndReturn(rhport, 0x80, (uint8_t*) data_desc_configuration, total_len, total_len, true); + + tud_task(); +} + +void test_usbd_get_configuration_descriptor_null(void) +{ + desc_configuration = NULL; + dcd_event_setup_received(rhport, (uint8_t*) &req_get_desc_configuration, false); + + dcd_edpt_stall_Expect(rhport, 0); + dcd_edpt_stall_Expect(rhport, 0x80); + + tud_task(); +} + +//--------------------------------------------------------------------+ +// Control ZLP +//--------------------------------------------------------------------+ + +//void test_control_zlp(void) +//{ +// +//} -- cgit v1.3.1 From cacbb80a9031662074c12652cbec32b491d78507 Mon Sep 17 00:00:00 2001 From: hathach Date: Thu, 31 Oct 2019 21:14:06 +0700 Subject: zlp should work with control in, tested with Unity framework --- src/device/usbd.c | 5 ---- src/device/usbd_control.c | 48 +++++++++++++++++++++++---------------- test/test/device/usbd/test_usbd.c | 2 +- 3 files changed, 30 insertions(+), 25 deletions(-) (limited to 'src') diff --git a/src/device/usbd.c b/src/device/usbd.c index 2d2f1cafd..0b9713e94 100644 --- a/src/device/usbd.c +++ b/src/device/usbd.c @@ -404,7 +404,6 @@ void tud_task (void) if ( 0 == epnum ) { - // control transfer DATA stage callback usbd_control_xfer_cb(event.rhport, ep_addr, event.xfer_complete.result, event.xfer_complete.len); } else @@ -869,10 +868,6 @@ void dcd_event_handler(dcd_event_t const * event, bool in_isr) break; case DCD_EVENT_XFER_COMPLETE: - // skip zero-length control status complete event, should DCD notify us. - // TODO could cause issue with actual zero length data used by class such as DFU - if ( (0 == tu_edpt_number(event->xfer_complete.ep_addr)) && (event->xfer_complete.len == 0) ) break; - osal_queue_send(_usbd_q, event, in_isr); TU_ASSERT(event->xfer_complete.result == XFER_RESULT_SUCCESS,); break; diff --git a/src/device/usbd_control.c b/src/device/usbd_control.c index 7636f459d..27e2a8214 100644 --- a/src/device/usbd_control.c +++ b/src/device/usbd_control.c @@ -42,9 +42,9 @@ typedef struct { tusb_control_request_t request; - void* buffer; - uint16_t len; - uint16_t total_transferred; + uint8_t* buffer; + uint16_t data_len; + uint16_t total_xferred; bool (*complete_cb) (uint8_t, tusb_control_request_t const *); } usbd_control_xfer_t; @@ -64,35 +64,37 @@ bool tud_control_status(uint8_t rhport, tusb_control_request_t const * request) return dcd_edpt_xfer(rhport, request->bmRequestType_bit.direction ? EDPT_CTRL_OUT : EDPT_CTRL_IN, NULL, 0); } -// Each transaction is up to endpoint0's max packet size -static bool _ctrl_data_xact(uint8_t rhport) +// Transfer an transaction in Data Stage +// Each transaction has up to Endpoint0's max packet size. +// This function can also transfer an zero-length packet +static bool _data_stage_xact(uint8_t rhport) { - uint16_t const xact_len = tu_min16(_ctrl_xfer.len - _ctrl_xfer.total_transferred, CFG_TUD_ENDPOINT0_SIZE); + uint16_t const xact_len = tu_min16(_ctrl_xfer.data_len - _ctrl_xfer.total_xferred, CFG_TUD_ENDPOINT0_SIZE); uint8_t ep_addr = EDPT_CTRL_OUT; if ( _ctrl_xfer.request.bmRequestType_bit.direction == TUSB_DIR_IN ) { ep_addr = EDPT_CTRL_IN; - memcpy(_usbd_ctrl_buf, _ctrl_xfer.buffer, xact_len); + if ( xact_len ) memcpy(_usbd_ctrl_buf, _ctrl_xfer.buffer, xact_len); } - return dcd_edpt_xfer(rhport, ep_addr, _usbd_ctrl_buf, xact_len); + return dcd_edpt_xfer(rhport, ep_addr, xact_len ? _usbd_ctrl_buf : NULL, xact_len); } bool tud_control_xfer(uint8_t rhport, tusb_control_request_t const * request, void* buffer, uint16_t len) { - _ctrl_xfer.request = (*request); - _ctrl_xfer.buffer = buffer; - _ctrl_xfer.total_transferred = 0; - _ctrl_xfer.len = tu_min16(len, request->wLength); + _ctrl_xfer.request = (*request); + _ctrl_xfer.buffer = (uint8_t*) buffer; + _ctrl_xfer.total_xferred = 0; + _ctrl_xfer.data_len = tu_min16(len, request->wLength); - if ( len ) + if ( _ctrl_xfer.data_len ) { TU_ASSERT(buffer); // Data stage - TU_ASSERT( _ctrl_data_xact(rhport) ); + TU_ASSERT( _data_stage_xact(rhport) ); }else { // Status stage @@ -122,7 +124,13 @@ void usbd_control_set_complete_callback( bool (*fp) (uint8_t, tusb_control_reque bool usbd_control_xfer_cb (uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes) { (void) result; - (void) ep_addr; + + // Endpoint Address is opposite to direction bit, this is Status Stage complete event + if ( tu_edpt_dir(ep_addr) != _ctrl_xfer.request.bmRequestType_bit.direction ) + { + TU_ASSERT(0 == xferred_bytes); + return true; + } if ( _ctrl_xfer.request.bmRequestType_bit.direction == TUSB_DIR_OUT ) { @@ -130,10 +138,12 @@ bool usbd_control_xfer_cb (uint8_t rhport, uint8_t ep_addr, xfer_result_t result memcpy(_ctrl_xfer.buffer, _usbd_ctrl_buf, xferred_bytes); } - _ctrl_xfer.total_transferred += xferred_bytes; - _ctrl_xfer.buffer = ((uint8_t*)_ctrl_xfer.buffer) + xferred_bytes; + _ctrl_xfer.total_xferred += xferred_bytes; + _ctrl_xfer.buffer += xferred_bytes; - if ( (_ctrl_xfer.request.wLength == _ctrl_xfer.total_transferred) || xferred_bytes < CFG_TUD_ENDPOINT0_SIZE ) + // Data Stage is complete when all request's length are transferred or + // a short packet is sent including zero-length packet. + if ( (_ctrl_xfer.request.wLength == _ctrl_xfer.total_xferred) || xferred_bytes < CFG_TUD_ENDPOINT0_SIZE ) { // DATA stage is complete bool is_ok = true; @@ -159,7 +169,7 @@ bool usbd_control_xfer_cb (uint8_t rhport, uint8_t ep_addr, xfer_result_t result else { // More data to transfer - TU_ASSERT( _ctrl_data_xact(rhport) ); + TU_ASSERT( _data_stage_xact(rhport) ); } return true; diff --git a/test/test/device/usbd/test_usbd.c b/test/test/device/usbd/test_usbd.c index ea813ea43..71d15dbca 100644 --- a/test/test/device/usbd/test_usbd.c +++ b/test/test/device/usbd/test_usbd.c @@ -202,7 +202,7 @@ void test_usbd_control_zlp(void) { // 128 byte total len, with EP0 size = 64, and request length = 256 // ZLP must be return - uint8_t zlp_desc_configuration[] = + uint8_t zlp_desc_configuration[CFG_TUD_ENDOINT0_SIZE*2] = { // Interface count, string index, total length, attribute, power in mA TUD_CONFIG_DESCRIPTOR(0, 0, CFG_TUD_ENDOINT0_SIZE*2, TUSB_DESC_CONFIG_ATT_REMOTE_WAKEUP, 100), -- cgit v1.3.1 From f58726887a58fe60d7384136f78b5b147fb08fbd Mon Sep 17 00:00:00 2001 From: hathach Date: Thu, 31 Oct 2019 21:28:46 +0700 Subject: update doc, hid set report --- docs/porting.md | 10 +++------- src/class/hid/hid_device.c | 3 +-- test/test/support/tusb_config.h | 10 +++++----- 3 files changed, 9 insertions(+), 14 deletions(-) (limited to 'src') diff --git a/docs/porting.md b/docs/porting.md index ded35e7b0..7fdeaeba7 100644 --- a/docs/porting.md +++ b/docs/porting.md @@ -123,17 +123,13 @@ Also make sure to enable endpoint specific interrupts. ##### dcd_edpt_xfer -`dcd_edpt_xfer` is responsible for configuring the peripheral to send or receive data from the host. "xfer" is short for "transfer". **This is one of the core methods you must implement for TinyUSB to work (one other is the interrupt handler).** Data from the host is the OUT direction and data to the host is IN. In other words, direction is relative to the host. - -`dcd_edpt_xfer` is used for all endpoints including the control endpoint 0. Make sure to handle the zero-length packet STATUS packet on endpoint 0 correctly. It may be a special transaction to the peripheral. +`dcd_edpt_xfer` is responsible for configuring the peripheral to send or receive data from the host. "xfer" is short for "transfer". **This is one of the core methods you must implement for TinyUSB to work (one other is the interrupt handler).** Data from the host is the OUT direction and data to the host is IN. It is used for all endpoints including the control endpoint 0. Make sure to handle the zero-length packet STATUS packet on endpoint 0 correctly. It may be a special transaction to the peripheral. Besides that, all other transactions are relatively straight-forward. The endpoint address provides the endpoint number and direction which usually determines where to write the buffer info. The buffer and its length are usually written to a specific location in memory and the peripheral is told the data is valid. (Maybe by writing a 1 to a register or setting a counter register to 0 for OUT or length for IN.) -The transmit buffer is NOT guarenteed to be word-aligned. - One potential pitfall is that the buffer may be longer than the maximum endpoint size of one USB packet. Some peripherals can handle transmitting multiple USB packets for a provided buffer (like the SAMD21). Others (like the nRF52) may need each USB packet queued individually. To make this work you'll need to track @@ -143,11 +139,11 @@ Once the transaction is going, the interrupt handler will notify TinyUSB of tran During transmission, the IN data buffer is guarenteed to remain unchanged in memory until the `dcd_xfer_complete` function is called. The dcd_edpt_xfer function must never add zero-length-packets (ZLP) on its own to a transfer. If a ZLP is required, -then it must be explicitly sent by the module calling dcd_edpt_xfer(), by calling dcd_edpt_xfer() a second time with len=0. +then it must be explicitly sent by the stack calling dcd_edpt_xfer(), by calling dcd_edpt_xfer() a second time with len=0. For control transfers, this is automatically done in `usbd_control.c`. At the moment, only a single buffer can be transmitted at once. There is no provision for double-buffering. new dcd_edpt_xfer() will not -be called again until the driver calls dcd_xfer_complete() (except in cases of USB resets). +be called again on the same endpoint address until the driver calls dcd_xfer_complete() (except in cases of USB resets). ##### dcd_xfer_complete diff --git a/src/class/hid/hid_device.c b/src/class/hid/hid_device.c index 9e7bad976..558adc2bb 100644 --- a/src/class/hid/hid_device.c +++ b/src/class/hid/hid_device.c @@ -241,8 +241,7 @@ bool hidd_control_request(uint8_t rhport, tusb_control_request_t const * p_reque break; case HID_REQ_CONTROL_SET_REPORT: - TU_VERIFY(p_request->wLength <=sizeof(p_hid->epout_buf)); - tud_control_xfer(rhport, p_request, p_hid->epout_buf, p_request->wLength); + tud_control_xfer(rhport, p_request, p_hid->epout_buf, tu_min16(sizeof(p_hid->epout_buf), p_request->wLength)); break; case HID_REQ_CONTROL_SET_IDLE: diff --git a/test/test/support/tusb_config.h b/test/test/support/tusb_config.h index e0ab0c68b..0a1608a64 100644 --- a/test/test/support/tusb_config.h +++ b/test/test/support/tusb_config.h @@ -74,11 +74,11 @@ #define CFG_TUD_ENDOINT0_SIZE 64 //------------- CLASS -------------// -#define CFG_TUD_CDC 0 -#define CFG_TUD_MSC 0 -#define CFG_TUD_HID 0 -#define CFG_TUD_MIDI 0 -#define CFG_TUD_VENDOR 0 +//#define CFG_TUD_CDC 0 +//#define CFG_TUD_MSC 0 +//#define CFG_TUD_HID 0 +//#define CFG_TUD_MIDI 0 +//#define CFG_TUD_VENDOR 0 //------------- CDC -------------// -- cgit v1.3.1 From 981e64d8a175463d8788c8bf2cb98ce97b630814 Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 1 Nov 2019 10:07:56 +0700 Subject: implement pigrew review --- src/class/hid/hid_device.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/class/hid/hid_device.c b/src/class/hid/hid_device.c index 558adc2bb..fc2e6b35a 100644 --- a/src/class/hid/hid_device.c +++ b/src/class/hid/hid_device.c @@ -241,7 +241,8 @@ bool hidd_control_request(uint8_t rhport, tusb_control_request_t const * p_reque break; case HID_REQ_CONTROL_SET_REPORT: - tud_control_xfer(rhport, p_request, p_hid->epout_buf, tu_min16(sizeof(p_hid->epout_buf), p_request->wLength)); + TU_VERIFY(p_request->wLength <= sizeof(p_hid->epout_buf)); + tud_control_xfer(rhport, p_request, p_hid->epout_buf, p_request->wLength); break; case HID_REQ_CONTROL_SET_IDLE: -- cgit v1.3.1 From 7bf01e218d8325bda8f33ab1bf0649b33282c5b5 Mon Sep 17 00:00:00 2001 From: hathach Date: Sun, 3 Nov 2019 11:43:07 +0700 Subject: make control buf static --- src/device/usbd_control.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/device/usbd_control.c b/src/device/usbd_control.c index d9eb25195..80648fd75 100644 --- a/src/device/usbd_control.c +++ b/src/device/usbd_control.c @@ -51,7 +51,7 @@ typedef struct static usbd_control_xfer_t _ctrl_xfer; -CFG_TUSB_MEM_SECTION CFG_TUSB_MEM_ALIGN uint8_t _usbd_ctrl_buf[CFG_TUD_ENDPOINT0_SIZE]; +CFG_TUSB_MEM_SECTION CFG_TUSB_MEM_ALIGN static uint8_t _usbd_ctrl_buf[CFG_TUD_ENDPOINT0_SIZE]; //--------------------------------------------------------------------+ -- cgit v1.3.1 From 62f8c14fae1c7c2f7d5cd5246e18f305d638f5f6 Mon Sep 17 00:00:00 2001 From: hathach Date: Sun, 3 Nov 2019 14:08:38 +0700 Subject: add a bit of log1 for debugging --- src/device/usbd.c | 4 +++- src/osal/osal_none.h | 2 ++ 2 files changed, 5 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/device/usbd.c b/src/device/usbd.c index 0b9713e94..997416901 100644 --- a/src/device/usbd.c +++ b/src/device/usbd.c @@ -376,7 +376,7 @@ void tud_task (void) case DCD_EVENT_SETUP_RECEIVED: TU_LOG2(" "); - TU_LOG2_MEM(&event.setup_received, 1, 8); + TU_LOG1_MEM(&event.setup_received, 1, 8); // Mark as connected after receiving 1st setup packet. // But it is easier to set it every time instead of wasting time to check then set @@ -385,6 +385,7 @@ void tud_task (void) // Process control request if ( !process_control_request(event.rhport, &event.setup_received) ) { + TU_LOG1(" Stall EP0\r\n"); // Failed -> stall both control endpoint IN and OUT dcd_edpt_stall(event.rhport, 0); dcd_edpt_stall(event.rhport, 0 | TUSB_DIR_IN_MASK); @@ -404,6 +405,7 @@ void tud_task (void) if ( 0 == epnum ) { + TU_LOG1(" EP Addr = 0x%02X, len = %ld\r\n", ep_addr, event.xfer_complete.len); usbd_control_xfer_cb(event.rhport, ep_addr, event.xfer_complete.result, event.xfer_complete.len); } else diff --git a/src/osal/osal_none.h b/src/osal/osal_none.h index fa581215d..5868dfb36 100644 --- a/src/osal/osal_none.h +++ b/src/osal/osal_none.h @@ -198,6 +198,8 @@ static inline bool osal_queue_send(osal_queue_t const qhdl, void const * data, b _osal_q_unlock(qhdl); } + TU_ASSERT(success); + return success; } -- cgit v1.3.1 From 44ad683bd6151fd297404bc59f2f7f2ccf792aab Mon Sep 17 00:00:00 2001 From: hathach Date: Mon, 4 Nov 2019 11:21:57 +0700 Subject: fix tud_control_status() didn't update request --- src/device/usbd_control.c | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/device/usbd_control.c b/src/device/usbd_control.c index 80648fd75..967864138 100644 --- a/src/device/usbd_control.c +++ b/src/device/usbd_control.c @@ -58,12 +58,22 @@ CFG_TUSB_MEM_SECTION CFG_TUSB_MEM_ALIGN static uint8_t _usbd_ctrl_buf[CFG_TUD_EN // Application API //--------------------------------------------------------------------+ -bool tud_control_status(uint8_t rhport, tusb_control_request_t const * request) +static inline bool _status_stage_xact(uint8_t rhport, tusb_control_request_t const * request) { // status direction is reversed to one in the setup packet return dcd_edpt_xfer(rhport, request->bmRequestType_bit.direction ? EDPT_CTRL_OUT : EDPT_CTRL_IN, NULL, 0); } +bool tud_control_status(uint8_t rhport, tusb_control_request_t const * request) +{ + _ctrl_xfer.request = (*request); + _ctrl_xfer.buffer = NULL; + _ctrl_xfer.total_xferred = 0; + _ctrl_xfer.data_len = 0; + + return _status_stage_xact(rhport, request); +} + // Transfer an transaction in Data Stage // Each transaction has up to Endpoint0's max packet size. // This function can also transfer an zero-length packet @@ -98,7 +108,7 @@ bool tud_control_xfer(uint8_t rhport, tusb_control_request_t const * request, vo }else { // Status stage - TU_ASSERT( tud_control_status(rhport, request) ); + TU_ASSERT( _status_stage_xact(rhport, request) ); } return true; @@ -158,7 +168,7 @@ bool usbd_control_xfer_cb (uint8_t rhport, uint8_t ep_addr, xfer_result_t result if ( is_ok ) { // Send status - TU_ASSERT( tud_control_status(rhport, &_ctrl_xfer.request) ); + TU_ASSERT( _status_stage_xact(rhport, &_ctrl_xfer.request) ); }else { // Stall both IN and OUT control endpoint -- cgit v1.3.1 From c98acd387364604746f0f3eb32fcf5e12685ea23 Mon Sep 17 00:00:00 2001 From: Nathan Conrad Date: Mon, 4 Nov 2019 08:54:18 -0500 Subject: Use control transfer function to send control data (in usbtmc) --- src/class/usbtmc/usbtmc_device.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/class/usbtmc/usbtmc_device.c b/src/class/usbtmc/usbtmc_device.c index c8e742fc5..916422752 100644 --- a/src/class/usbtmc/usbtmc_device.c +++ b/src/class/usbtmc/usbtmc_device.c @@ -656,7 +656,7 @@ bool usbtmcd_control_request_cb(uint8_t rhport, tusb_control_request_t const * r TU_VERIFY(request->wLength == sizeof(rsp)); TU_VERIFY(request->wIndex == usbtmc_state.ep_bulk_out); TU_VERIFY(tud_usbtmc_check_abort_bulk_out_cb(&rsp)); - TU_VERIFY(usbd_edpt_xfer(rhport, 0u, (void*)&rsp,sizeof(rsp))); + TU_VERIFY(tud_control_xfer(rhport, request, (void*)&rsp,sizeof(rsp))); return true; } -- cgit v1.3.1 From a94fe05ecb9e093dcb019a610c49d6b2f8f7255e Mon Sep 17 00:00:00 2001 From: Nathan Conrad Date: Mon, 4 Nov 2019 08:59:29 -0500 Subject: usbd: Change TU_ASSERT to TU_VERIFY as the assertion can be hit when bad data is sent from host. --- src/device/usbd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/device/usbd.c b/src/device/usbd.c index 997416901..337425256 100644 --- a/src/device/usbd.c +++ b/src/device/usbd.c @@ -599,7 +599,7 @@ static bool process_control_request(uint8_t rhport, tusb_control_request_t const // stall control endpoint if driver return false usbd_control_set_complete_callback(usbd_class_drivers[drvid].control_complete); TU_LOG2(" %s control request\r\n", _usbd_driver_str[drvid]); - TU_ASSERT(usbd_class_drivers[drvid].control_request != NULL && + TU_VERIFY(usbd_class_drivers[drvid].control_request != NULL && usbd_class_drivers[drvid].control_request(rhport, p_request)); } } -- cgit v1.3.1 From 2727983a2d20ab586d5e2cd905f2c712f1d95db6 Mon Sep 17 00:00:00 2001 From: hathach Date: Mon, 4 Nov 2019 22:52:29 +0700 Subject: fix #211 --- src/device/dcd.h | 38 ++++---------------------------------- src/device/usbd.c | 25 +++++++++++++++++++++++++ 2 files changed, 29 insertions(+), 34 deletions(-) (limited to 'src') diff --git a/src/device/dcd.h b/src/device/dcd.h index 9fa98c669..6e43ab3e9 100644 --- a/src/device/dcd.h +++ b/src/device/dcd.h @@ -120,50 +120,20 @@ void dcd_edpt_stall (uint8_t rhport, uint8_t ep_addr); void dcd_edpt_clear_stall (uint8_t rhport, uint8_t ep_addr); //--------------------------------------------------------------------+ -// Event API +// Event API (Implemented by device stack) //--------------------------------------------------------------------+ // Called by DCD to notify device stack extern void dcd_event_handler(dcd_event_t const * event, bool in_isr); // helper to send bus signal event -static inline void dcd_event_bus_signal (uint8_t rhport, dcd_eventid_t eid, bool in_isr); +extern void dcd_event_bus_signal (uint8_t rhport, dcd_eventid_t eid, bool in_isr); // helper to send setup received -static inline void dcd_event_setup_received(uint8_t rhport, uint8_t const * setup, bool in_isr); +extern void dcd_event_setup_received(uint8_t rhport, uint8_t const * setup, bool in_isr); // helper to send transfer complete event -static inline void dcd_event_xfer_complete (uint8_t rhport, uint8_t ep_addr, uint32_t xferred_bytes, uint8_t result, bool in_isr); - - -//--------------------------------------------------------------------+ -// Inline helper -//--------------------------------------------------------------------+ - -static inline void dcd_event_bus_signal (uint8_t rhport, dcd_eventid_t eid, bool in_isr) -{ - dcd_event_t event = { .rhport = rhport, .event_id = eid, }; - dcd_event_handler(&event, in_isr); -} - -static inline void dcd_event_setup_received(uint8_t rhport, uint8_t const * setup, bool in_isr) -{ - dcd_event_t event = { .rhport = rhport, .event_id = DCD_EVENT_SETUP_RECEIVED }; - memcpy(&event.setup_received, setup, 8); - - dcd_event_handler(&event, in_isr); -} - -static inline void dcd_event_xfer_complete (uint8_t rhport, uint8_t ep_addr, uint32_t xferred_bytes, uint8_t result, bool in_isr) -{ - dcd_event_t event = { .rhport = rhport, .event_id = DCD_EVENT_XFER_COMPLETE }; - - event.xfer_complete.ep_addr = ep_addr; - event.xfer_complete.len = xferred_bytes; - event.xfer_complete.result = result; - - dcd_event_handler(&event, in_isr); -} +extern void dcd_event_xfer_complete (uint8_t rhport, uint8_t ep_addr, uint32_t xferred_bytes, uint8_t result, bool in_isr); #ifdef __cplusplus } diff --git a/src/device/usbd.c b/src/device/usbd.c index 46affdab4..e306bc121 100644 --- a/src/device/usbd.c +++ b/src/device/usbd.c @@ -884,6 +884,31 @@ void dcd_event_handler(dcd_event_t const * event, bool in_isr) } } +void dcd_event_bus_signal (uint8_t rhport, dcd_eventid_t eid, bool in_isr) +{ + dcd_event_t event = { .rhport = rhport, .event_id = eid, }; + dcd_event_handler(&event, in_isr); +} + +void dcd_event_setup_received(uint8_t rhport, uint8_t const * setup, bool in_isr) +{ + dcd_event_t event = { .rhport = rhport, .event_id = DCD_EVENT_SETUP_RECEIVED }; + memcpy(&event.setup_received, setup, 8); + + dcd_event_handler(&event, in_isr); +} + +void dcd_event_xfer_complete (uint8_t rhport, uint8_t ep_addr, uint32_t xferred_bytes, uint8_t result, bool in_isr) +{ + dcd_event_t event = { .rhport = rhport, .event_id = DCD_EVENT_XFER_COMPLETE }; + + event.xfer_complete.ep_addr = ep_addr; + event.xfer_complete.len = xferred_bytes; + event.xfer_complete.result = result; + + dcd_event_handler(&event, in_isr); +} + //--------------------------------------------------------------------+ // Helper //--------------------------------------------------------------------+ -- cgit v1.3.1 From 8d0fa158d77ad833eec7e1d8ea4abbec31072893 Mon Sep 17 00:00:00 2001 From: Nathan Conrad Date: Mon, 4 Nov 2019 11:33:14 -0500 Subject: Change one more TU_ASSERT to TU_VERIFY in usbd. --- src/device/usbd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/device/usbd.c b/src/device/usbd.c index 337425256..b64636ee2 100644 --- a/src/device/usbd.c +++ b/src/device/usbd.c @@ -589,7 +589,7 @@ static bool process_control_request(uint8_t rhport, tusb_control_request_t const // stall control endpoint if driver return false usbd_control_set_complete_callback(usbd_class_drivers[drvid].control_complete); TU_LOG2(" %s control request\r\n", _usbd_driver_str[drvid]); - TU_ASSERT(usbd_class_drivers[drvid].control_request != NULL && + TU_VERIFY(usbd_class_drivers[drvid].control_request != NULL && usbd_class_drivers[drvid].control_request(rhport, p_request)); break; } -- cgit v1.3.1