From 986beda9ebc5f772a6c172ad8b2f3193506b4d23 Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 13 Sep 2019 11:22:44 +0700 Subject: adding stm32l4 support, board test run with stm32l476disco, usb doens't work yet --- src/portable/st/synopsys/dcd_synopsys.c | 30 ++++++++++++++++++++++-------- src/tusb_option.h | 10 ++++++++-- 2 files changed, 30 insertions(+), 10 deletions(-) (limited to 'src') diff --git a/src/portable/st/synopsys/dcd_synopsys.c b/src/portable/st/synopsys/dcd_synopsys.c index 71c691223..b0e7e04bd 100644 --- a/src/portable/st/synopsys/dcd_synopsys.c +++ b/src/portable/st/synopsys/dcd_synopsys.c @@ -27,10 +27,20 @@ #include "tusb_option.h" -#if TUSB_OPT_DEVICE_ENABLED && ( CFG_TUSB_MCU == OPT_MCU_STM32F2 || \ - CFG_TUSB_MCU == OPT_MCU_STM32F4 || \ - CFG_TUSB_MCU == OPT_MCU_STM32H7 || \ - CFG_TUSB_MCU == OPT_MCU_STM32F7) +#define STM32L4_SYNOPSYS ( \ + defined (STM32L475xx) || defined (STM32L476xx) || \ + defined (STM32L485xx) || defined (STM32L486xx) || defined (STM32L496xx) || \ + defined (STM32L4R5xx) || defined (STM32L4R7xx) || defined (STM32L4R9xx) || \ + defined (STM32L4S5xx) || defined (STM32L4S7xx) || defined (STM32L4S9xx) \ +) + +#if TUSB_OPT_DEVICE_ENABLED && \ + ( CFG_TUSB_MCU == OPT_MCU_STM32F2 || \ + CFG_TUSB_MCU == OPT_MCU_STM32F4 || \ + CFG_TUSB_MCU == OPT_MCU_STM32F7 || \ + CFG_TUSB_MCU == OPT_MCU_STM32H7 || \ + (CFG_TUSB_MCU == OPT_MCU_STM32L4 && STM32L4_SYNOPSYS) \ + ) // TODO Support OTG_HS // EP_MAX : Max number of bi-directional endpoints including EP0 @@ -52,6 +62,10 @@ #include "stm32f7xx.h" #define EP_MAX 6 #define EP_FIFO_SIZE 1280 +#elif CFG_TUSB_MCU == OPT_MCU_STM32L4 + #include "stm32l4xx.h" + #define EP_MAX 6 + #define EP_FIFO_SIZE 1280 #else #error "Unsupported MCUs" #endif @@ -61,10 +75,10 @@ /*------------------------------------------------------------------*/ /* MACRO TYPEDEF CONSTANT ENUM *------------------------------------------------------------------*/ -#define DEVICE_BASE (USB_OTG_DeviceTypeDef *) (USB_OTG_FS_PERIPH_BASE + USB_OTG_DEVICE_BASE) -#define OUT_EP_BASE (USB_OTG_OUTEndpointTypeDef *) (USB_OTG_FS_PERIPH_BASE + USB_OTG_OUT_ENDPOINT_BASE) -#define IN_EP_BASE (USB_OTG_INEndpointTypeDef *) (USB_OTG_FS_PERIPH_BASE + USB_OTG_IN_ENDPOINT_BASE) -#define FIFO_BASE(_x) (volatile uint32_t *) (USB_OTG_FS_PERIPH_BASE + USB_OTG_FIFO_BASE + (_x) * USB_OTG_FIFO_SIZE) +#define DEVICE_BASE (USB_OTG_DeviceTypeDef *) (USB_OTG_FS_PERIPH_BASE + USB_OTG_DEVICE_BASE) +#define OUT_EP_BASE (USB_OTG_OUTEndpointTypeDef *) (USB_OTG_FS_PERIPH_BASE + USB_OTG_OUT_ENDPOINT_BASE) +#define IN_EP_BASE (USB_OTG_INEndpointTypeDef *) (USB_OTG_FS_PERIPH_BASE + USB_OTG_IN_ENDPOINT_BASE) +#define FIFO_BASE(_x) ((volatile uint32_t *) (USB_OTG_FS_PERIPH_BASE + USB_OTG_FIFO_BASE + (_x) * USB_OTG_FIFO_SIZE)) static TU_ATTR_ALIGNED(4) uint32_t _setup_packet[6]; static uint8_t _setup_offs; // We store up to 3 setup packets. diff --git a/src/tusb_option.h b/src/tusb_option.h index eccb4245c..9aacb558f 100644 --- a/src/tusb_option.h +++ b/src/tusb_option.h @@ -35,6 +35,8 @@ /** \defgroup group_mcu Supported MCU * \ref CFG_TUSB_MCU must be defined to one of these * @{ */ + +// LPC #define OPT_MCU_LPC11UXX 1 ///< NXP LPC11Uxx #define OPT_MCU_LPC13XX 3 ///< NXP LPC13xx #define OPT_MCU_LPC175X_6X 4 ///< NXP LPC175x, LPC176x @@ -46,12 +48,14 @@ #define OPT_MCU_LPC54XXX 10 ///< NXP LPC54xxx #define OPT_MCU_LPC55XX 11 ///< NXP LPC55xx +// NRF #define OPT_MCU_NRF5X 100 ///< Nordic nRF5x series +// SAM #define OPT_MCU_SAMD21 200 ///< MicroChip SAMD21 #define OPT_MCU_SAMD51 201 ///< MicroChip SAMD51 -// ST Synopsis OTG devices +// STM32 #define OPT_MCU_STM32F0 300 ///< ST STM32F0 #define OPT_MCU_STM32F1 301 ///< ST STM32F1 #define OPT_MCU_STM32F2 302 ///< ST STM32F2 @@ -59,7 +63,9 @@ #define OPT_MCU_STM32F4 304 ///< ST STM32F4 #define OPT_MCU_STM32F7 305 ///< ST STM32F7 #define OPT_MCU_STM32H7 306 ///< ST STM32H7 - +#define OPT_MCU_STM32L0 307 ///< ST STM32L0 +#define OPT_MCU_STM32L1 308 ///< ST STM32L1 +#define OPT_MCU_STM32L4 309 ///< ST STM32L4 /** @} */ -- cgit v1.3.1 From c3598f030158cf32f571a3c11b833a3a910d63c8 Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 13 Sep 2019 13:03:11 +0700 Subject: fix #139, correct usbd request intepreting, Non-STD request to Interface must be forward to class driver --- src/device/usbd.c | 51 +++++++++++++++++++++++++++++++-------------------- 1 file changed, 31 insertions(+), 20 deletions(-) (limited to 'src') diff --git a/src/device/usbd.c b/src/device/usbd.c index a6eda79de..53f0226bc 100644 --- a/src/device/usbd.c +++ b/src/device/usbd.c @@ -439,33 +439,44 @@ static bool process_control_request(uint8_t rhport, tusb_control_request_t const TU_VERIFY(drvid < USBD_CLASS_DRIVER_COUNT); - switch ( p_request->bRequest ) + if (p_request->bmRequestType_bit.type == TUSB_REQ_TYPE_STANDARD) { - case TUSB_REQ_GET_INTERFACE: + switch ( p_request->bRequest ) { - // TODO not support alternate interface yet - uint8_t alternate = 0; - tud_control_xfer(rhport, p_request, &alternate, 1); - } - break; + case TUSB_REQ_GET_INTERFACE: + { + // TODO not support alternate interface yet + uint8_t alternate = 0; + tud_control_xfer(rhport, p_request, &alternate, 1); + } + break; - case TUSB_REQ_SET_INTERFACE: - { - uint8_t alternate = (uint8_t) p_request->wValue; + case TUSB_REQ_SET_INTERFACE: + { + uint8_t const alternate = (uint8_t) p_request->wValue; - // TODO not support alternate interface yet - TU_ASSERT(alternate == 0); + // TODO not support alternate interface yet + TU_ASSERT(alternate == 0); + tud_control_status(rhport, p_request); + } + break; - tud_control_status(rhport, p_request); + default: + // forward to class driver: "STD request to Interface" + // GET HID REPORT DESCRIPTOR falls into this case + usbd_control_set_complete_callback(usbd_class_drivers[drvid].control_complete); + + // stall control endpoint if driver return false + TU_ASSERT(usbd_class_drivers[drvid].control_request(rhport, p_request)); + break; } - break; + }else + { + // forward to class driver: "non-STD request to Interface" + usbd_control_set_complete_callback(usbd_class_drivers[drvid].control_complete); - default: - // forward to class driver - // stall control endpoint if driver return false - usbd_control_set_complete_callback(usbd_class_drivers[drvid].control_complete); - TU_ASSERT(usbd_class_drivers[drvid].control_request(rhport, p_request)); - break; + // stall control endpoint if driver return false + TU_ASSERT(usbd_class_drivers[drvid].control_request(rhport, p_request)); } } break; -- cgit v1.3.1 From 064adebbd0c6e35e6a18d5dda3deba232db2690d Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 13 Sep 2019 14:03:59 +0700 Subject: fix #152, potential memory issue --- src/device/usbd.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/device/usbd.c b/src/device/usbd.c index 53f0226bc..184702f1a 100644 --- a/src/device/usbd.c +++ b/src/device/usbd.c @@ -435,8 +435,9 @@ static bool process_control_request(uint8_t rhport, tusb_control_request_t const case TUSB_REQ_RCPT_INTERFACE: { uint8_t const itf = tu_u16_low(p_request->wIndex); - uint8_t const drvid = _usbd_dev.itf2drv[itf]; + TU_VERIFY(itf < TU_ARRAY_SZIE(_usbd_dev.itf2drv)); + uint8_t const drvid = _usbd_dev.itf2drv[itf]; TU_VERIFY(drvid < USBD_CLASS_DRIVER_COUNT); if (p_request->bmRequestType_bit.type == TUSB_REQ_TYPE_STANDARD) -- cgit v1.3.1 From ac8c343fef785c9aa19ba628f746e72774b9e8c8 Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 13 Sep 2019 22:16:24 +0700 Subject: fix #154 forward all endpoint recipeint request to class driver fix typo remove magic number 0xff of driver id --- src/common/tusb_common.h | 2 +- src/device/usbd.c | 107 +++++++++++++++++++++++++++++++---------------- 2 files changed, 71 insertions(+), 38 deletions(-) (limited to 'src') diff --git a/src/common/tusb_common.h b/src/common/tusb_common.h index 4f0105d13..57c6e2fcf 100644 --- a/src/common/tusb_common.h +++ b/src/common/tusb_common.h @@ -38,7 +38,7 @@ //--------------------------------------------------------------------+ // Macros Helper //--------------------------------------------------------------------+ -#define TU_ARRAY_SZIE(_arr) ( sizeof(_arr) / sizeof(_arr[0]) ) +#define TU_ARRAY_SIZE(_arr) ( sizeof(_arr) / sizeof(_arr[0]) ) #define TU_MIN(_x, _y) ( (_x) < (_y) ) ? (_x) : (_y) ) #define TU_MAX(_x, _y) ( (_x) > (_y) ) ? (_x) : (_y) ) diff --git a/src/device/usbd.c b/src/device/usbd.c index 184702f1a..c92884334 100644 --- a/src/device/usbd.c +++ b/src/device/usbd.c @@ -61,6 +61,9 @@ typedef struct { static usbd_device_t _usbd_dev = { 0 }; +// Invalid driver ID in itf2drv[] ep2drv[][] mapping +enum { DRVID_INVALID = 0xff }; + //--------------------------------------------------------------------+ // Class Driver //--------------------------------------------------------------------+ @@ -144,7 +147,7 @@ static usbd_class_driver_t const usbd_class_drivers[] = #endif }; -enum { USBD_CLASS_DRIVER_COUNT = TU_ARRAY_SZIE(usbd_class_drivers) }; +enum { USBD_CLASS_DRIVER_COUNT = TU_ARRAY_SIZE(usbd_class_drivers) }; //--------------------------------------------------------------------+ // DCD Event @@ -213,8 +216,8 @@ static void usbd_reset(uint8_t rhport) { tu_varclr(&_usbd_dev); - memset(_usbd_dev.itf2drv, 0xff, sizeof(_usbd_dev.itf2drv)); // invalid mapping - memset(_usbd_dev.ep2drv , 0xff, sizeof(_usbd_dev.ep2drv )); // invalid mapping + memset(_usbd_dev.itf2drv, DRVID_INVALID, sizeof(_usbd_dev.itf2drv)); // invalid mapping + memset(_usbd_dev.ep2drv , DRVID_INVALID, sizeof(_usbd_dev.ep2drv )); // invalid mapping usbd_control_reset(rhport); @@ -287,19 +290,19 @@ void tud_task (void) { // Invoke the class callback associated with the endpoint address uint8_t const ep_addr = event.xfer_complete.ep_addr; - uint8_t const epnum = tu_edpt_number(ep_addr); - uint8_t const dir = tu_edpt_dir(ep_addr); + uint8_t const epnum = tu_edpt_number(ep_addr); + uint8_t const ep_dir = tu_edpt_dir(ep_addr); - _usbd_dev.ep_busy_map[dir] = (uint8_t) tu_bit_clear(_usbd_dev.ep_busy_map[dir], epnum); + _usbd_dev.ep_busy_map[ep_dir] = (uint8_t) tu_bit_clear(_usbd_dev.ep_busy_map[ep_dir], epnum); - if ( 0 == tu_edpt_number(ep_addr) ) + 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 { - uint8_t const drv_id = _usbd_dev.ep2drv[tu_edpt_number(ep_addr)][tu_edpt_dir(ep_addr)]; + uint8_t const drv_id = _usbd_dev.ep2drv[epnum][ep_dir]; TU_ASSERT(drv_id < USBD_CLASS_DRIVER_COUNT,); usbd_class_drivers[drv_id].xfer_cb(event.rhport, ep_addr, event.xfer_complete.result, event.xfer_complete.len); @@ -435,7 +438,7 @@ static bool process_control_request(uint8_t rhport, tusb_control_request_t const case TUSB_REQ_RCPT_INTERFACE: { uint8_t const itf = tu_u16_low(p_request->wIndex); - TU_VERIFY(itf < TU_ARRAY_SZIE(_usbd_dev.itf2drv)); + TU_VERIFY(itf < TU_ARRAY_SIZE(_usbd_dev.itf2drv)); uint8_t const drvid = _usbd_dev.itf2drv[itf]; TU_VERIFY(drvid < USBD_CLASS_DRIVER_COUNT); @@ -465,18 +468,16 @@ static bool process_control_request(uint8_t rhport, tusb_control_request_t const default: // forward to class driver: "STD request to Interface" // GET HID REPORT DESCRIPTOR falls into this case - usbd_control_set_complete_callback(usbd_class_drivers[drvid].control_complete); - // stall control endpoint if driver return false + usbd_control_set_complete_callback(usbd_class_drivers[drvid].control_complete); TU_ASSERT(usbd_class_drivers[drvid].control_request(rhport, p_request)); break; } }else { // forward to class driver: "non-STD request to Interface" - usbd_control_set_complete_callback(usbd_class_drivers[drvid].control_complete); - // stall control endpoint if driver return false + usbd_control_set_complete_callback(usbd_class_drivers[drvid].control_complete); TU_ASSERT(usbd_class_drivers[drvid].control_request(rhport, p_request)); } } @@ -484,37 +485,69 @@ static bool process_control_request(uint8_t rhport, tusb_control_request_t const //------------- Endpoint Request -------------// case TUSB_REQ_RCPT_ENDPOINT: - // Non standard request is not supported - TU_VERIFY( TUSB_REQ_TYPE_STANDARD == p_request->bmRequestType_bit.type ); + { + uint8_t const ep_addr = tu_u16_low(p_request->wIndex); + uint8_t const ep_num = tu_edpt_number(ep_addr); + uint8_t const ep_dir = tu_edpt_dir(ep_addr); - switch ( p_request->bRequest ) + TU_ASSERT(ep_num < TU_ARRAY_SIZE(_usbd_dev.ep2drv) ); + + uint8_t const drv_id = _usbd_dev.ep2drv[ep_num][ep_dir]; + TU_ASSERT(drv_id < USBD_CLASS_DRIVER_COUNT); + + // Some classes such as TMC needs to clear/re-init its buffer when receiving CLEAR_FEATURE request + // We will forward all request targeted endpoint to its class driver + // - For non-standard request: driver can ACK or Stall the request by return true/false + // - For standard request: usbd decide the ACK stage regardless of driver return value + bool ret; + + if ( TUSB_REQ_TYPE_STANDARD != p_request->bmRequestType_bit.type ) { - case TUSB_REQ_GET_STATUS: - { - uint16_t status = usbd_edpt_stalled(rhport, tu_u16_low(p_request->wIndex)) ? 0x0001 : 0x0000; - tud_control_xfer(rhport, p_request, &status, 2); - } - break; + // complete callback is also capable of stalling/acking the request + usbd_control_set_complete_callback(usbd_class_drivers[drv_id].control_complete); + } - case TUSB_REQ_CLEAR_FEATURE: - if ( TUSB_REQ_FEATURE_EDPT_HALT == p_request->wValue ) - { - usbd_edpt_clear_stall(rhport, tu_u16_low(p_request->wIndex)); - } - tud_control_status(rhport, p_request); - break; + // Invoke class driver first + ret = usbd_class_drivers[drv_id].control_request(rhport, p_request); - case TUSB_REQ_SET_FEATURE: - if ( TUSB_REQ_FEATURE_EDPT_HALT == p_request->wValue ) + // Then handle if it is standard request + if ( TUSB_REQ_TYPE_STANDARD == p_request->bmRequestType_bit.type ) + { + // force return true for standard request + ret = true; + + switch ( p_request->bRequest ) + { + case TUSB_REQ_GET_STATUS: { - usbd_edpt_stall(rhport, tu_u16_low(p_request->wIndex)); + uint16_t status = usbd_edpt_stalled(rhport, ep_addr) ? 0x0001 : 0x0000; + tud_control_xfer(rhport, p_request, &status, 2); } - tud_control_status(rhport, p_request); - break; + break; - // Unknown/Unsupported request - default: TU_BREAKPOINT(); return false; + case TUSB_REQ_CLEAR_FEATURE: + if ( TUSB_REQ_FEATURE_EDPT_HALT == p_request->wValue ) + { + usbd_edpt_clear_stall(rhport, ep_addr); + } + tud_control_status(rhport, p_request); + break; + + case TUSB_REQ_SET_FEATURE: + if ( TUSB_REQ_FEATURE_EDPT_HALT == p_request->wValue ) + { + usbd_edpt_stall(rhport, ep_addr); + } + tud_control_status(rhport, p_request); + break; + + // Unknown/Unsupported request + default: TU_BREAKPOINT(); return false; + } } + + return ret; + } break; // Unknown recipient @@ -560,7 +593,7 @@ static bool process_set_config(uint8_t rhport, uint8_t cfg_num) TU_ASSERT( drv_id < USBD_CLASS_DRIVER_COUNT ); // Interface number must not be used already TODO alternate interface - TU_ASSERT( 0xff == _usbd_dev.itf2drv[desc_itf->bInterfaceNumber] ); + TU_ASSERT( DRVID_INVALID == _usbd_dev.itf2drv[desc_itf->bInterfaceNumber] ); _usbd_dev.itf2drv[desc_itf->bInterfaceNumber] = drv_id; uint16_t itf_len=0; -- cgit v1.3.1 From bb7f581b6d046c1c358fab70f3640d0312527804 Mon Sep 17 00:00:00 2001 From: Nathan Conrad Date: Fri, 13 Sep 2019 20:28:26 -0400 Subject: TI compiler quirks, and le byte swapping functions. --- src/common/tusb_compiler.h | 83 ++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 73 insertions(+), 10 deletions(-) (limited to 'src') diff --git a/src/common/tusb_compiler.h b/src/common/tusb_compiler.h index 09768ef88..ca294c20f 100644 --- a/src/common/tusb_compiler.h +++ b/src/common/tusb_compiler.h @@ -53,6 +53,9 @@ // for declaration of reserved field, make use of _TU_COUNTER_ #define TU_RESERVED TU_XSTRCAT(reserved, _TU_COUNTER_) +#define TU_LITTLE_ENDIAN (0x12u) +#define TU_BIG_ENDIAN (0x21u) + //--------------------------------------------------------------------+ // Compiler porting with Attribute and Endian //--------------------------------------------------------------------+ @@ -67,20 +70,80 @@ // Endian conversion use well-known host to network (big endian) naming #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ - #define tu_htonl(u32) __builtin_bswap32(u32) - #define tu_ntohl(u32) __builtin_bswap32(u32) - - #define tu_htons(u16) __builtin_bswap16(u16) - #define tu_ntohs(u16) __builtin_bswap16(u16) + #define TU_BYTE_ORDER TU_LITTLE_ENDIAN #else - #define tu_htonl(u32) (u32) - #define tu_ntohl(u32) (u32) + #define TU_BYTE_ORDER TU_BIG_ENDIAN + #endif + + static inline uint16_t tu_bswap16(uint16_t u16) + { + return __builtin_bswap16(u16); + } + + static inline uint16_t tu_bswap32(uint16_t u32) + { + return __builtin_bswap32(u32); + } + + #define TU_BSWAP16 + +#elif defined(__TI_COMPILER_VERSION__) + #define TU_ATTR_ALIGNED(Bytes) __attribute__ ((aligned(Bytes))) + #define TU_ATTR_SECTION(sec_name) __attribute__ ((section(#sec_name))) + #define TU_ATTR_PACKED __attribute__ ((packed)) + #define TU_ATTR_PREPACKED + #define TU_ATTR_WEAK __attribute__ ((weak)) + #define TU_ATTR_DEPRECATED(mess) __attribute__ ((deprecated(mess))) // warn if function with this attribute is used + #define TU_ATTR_UNUSED __attribute__ ((unused)) // Function/Variable is meant to be possibly unused - #define tu_htons(u16) (u16) - #define tu_ntohs(u16) (u16) + // __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 + #else + #define TU_BYTE_ORDER TU_BIG_ENDIAN #endif + + static inline uint16_t tu_bswap16(uint16_t u16) + { + return __builtin_bswap16(u16); + } + + static inline uint16_t tu_bswap32(uint16_t u32) + { + return __builtin_bswap32(u32); + } +#else + #error "Compiler attribute porting is required" +#endif + +#if (TU_BYTE_ORDER == TU_LITTLE_ENDIAN) + #define tu_htonl(u32) tu_bswap32(u32) + #define tu_ntohl(u32) tu_bswap32(u32) + + #define tu_htons(u16) tu_bswap16(u16) + #define tu_ntohs(u16) tu_bswap16(u16) + + #define tu_htole16(x) (x) + #define tu_le16toh(x) (x) + + #define tu_htole32(x) (x) + #define tu_le32toh(x) (x) + +#elif (TU_BYTE_ORDER == TU_BIG_ENDIAN) + #define tu_htonl(u32) (x) + #define tu_ntohl(u32) (x) + + #define tu_htons(u16) (x) + #define tu_ntohs(u16) (x) + + #define tu_htole16(x) tu_bswap16(u32) + #define tu_le16toh(x) tu_bswap16(u32) + + #define tu_htole32(x) tu_bswap32(u32) + #define tu_le32toh(x) tu_bswap32(u32) + #else - #error "Compiler attribute porting are required" + #error Byte order is undefined #endif #endif /* _TUSB_COMPILER_H_ */ -- cgit v1.3.1 From c831311a12a42d27690c830cc9cefd4d4e6efe2d Mon Sep 17 00:00:00 2001 From: Nathan Conrad Date: Fri, 13 Sep 2019 23:37:47 -0400 Subject: Off-by-one error in Synopsys assertions. (and move some braces to their own lines. --- src/portable/st/synopsys/dcd_synopsys.c | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/src/portable/st/synopsys/dcd_synopsys.c b/src/portable/st/synopsys/dcd_synopsys.c index b0e7e04bd..2daa16a26 100644 --- a/src/portable/st/synopsys/dcd_synopsys.c +++ b/src/portable/st/synopsys/dcd_synopsys.c @@ -268,21 +268,22 @@ bool dcd_edpt_open (uint8_t rhport, tusb_desc_endpoint_t const * desc_edpt) uint8_t const epnum = tu_edpt_number(desc_edpt->bEndpointAddress); uint8_t const dir = tu_edpt_dir(desc_edpt->bEndpointAddress); - - // Unsupported endpoint numbers/size. - if((desc_edpt->wMaxPacketSize.size > 64) || (epnum > EP_MAX)) { - return false; - } - + + TU_ASSERT((desc_edpt->wMaxPacketSize.size <= 64); + TU_ASSERT(epnum < EP_MAX); + xfer_ctl_t * xfer = XFER_CTL_BASE(epnum, dir); xfer->max_size = desc_edpt->wMaxPacketSize.size; - if(dir == TUSB_DIR_OUT) { + if(dir == TUSB_DIR_OUT) + { out_ep[epnum].DOEPCTL |= (1 << USB_OTG_DOEPCTL_USBAEP_Pos) | \ desc_edpt->bmAttributes.xfer << USB_OTG_DOEPCTL_EPTYP_Pos | \ desc_edpt->wMaxPacketSize.size << USB_OTG_DOEPCTL_MPSIZ_Pos; dev->DAINTMSK |= (1 << (USB_OTG_DAINTMSK_OEPM_Pos + epnum)); - } else { + } + else + { // "USB Data FIFOs" section in reference manual // Peripheral FIFO architecture // -- cgit v1.3.1 From 4ea212a432c32dedfefa79d995d2190462a27a5f Mon Sep 17 00:00:00 2001 From: Nathan Conrad Date: Fri, 13 Sep 2019 23:52:43 -0400 Subject: This demonstrates that I don't pre-build things before committing them... oops. --- src/portable/st/synopsys/dcd_synopsys.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/portable/st/synopsys/dcd_synopsys.c b/src/portable/st/synopsys/dcd_synopsys.c index 2daa16a26..f15b92edc 100644 --- a/src/portable/st/synopsys/dcd_synopsys.c +++ b/src/portable/st/synopsys/dcd_synopsys.c @@ -269,7 +269,7 @@ bool dcd_edpt_open (uint8_t rhport, tusb_desc_endpoint_t const * desc_edpt) uint8_t const epnum = tu_edpt_number(desc_edpt->bEndpointAddress); uint8_t const dir = tu_edpt_dir(desc_edpt->bEndpointAddress); - TU_ASSERT((desc_edpt->wMaxPacketSize.size <= 64); + TU_ASSERT(desc_edpt->wMaxPacketSize.size <= 64); TU_ASSERT(epnum < EP_MAX); xfer_ctl_t * xfer = XFER_CTL_BASE(epnum, dir); -- cgit v1.3.1 From 21ba37aec64aa8e436062aaa43be898ece993907 Mon Sep 17 00:00:00 2001 From: Nathan Conrad Date: Sat, 14 Sep 2019 09:02:21 -0400 Subject: Interpretation of assert vs verify. --- src/common/tusb_verify.h | 30 +++++++++++++++++++++++++++--- 1 file changed, 27 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/common/tusb_verify.h b/src/common/tusb_verify.h index 2727ce043..fae0c88ae 100644 --- a/src/common/tusb_verify.h +++ b/src/common/tusb_verify.h @@ -36,10 +36,34 @@ * as C++ for the sake of code simplicity. Beware of a headache macro * manipulation that you are told to stay away. * - * e.g * - * - TU_VERIFY( cond ) will return false if cond is false - * - TU_VERIFY( cond, err) will return err instead if cond is false + * This contains macros for both VERIFY and ASSERT: + * + * VERIFY: Used when there is an error condition which is not the + * fault of the MCU. For example, bounds checking on data + * sent to the micro over USB should use this function. + * Another example is checking for buffer overflows, where + * returning from the active function causes a NAK. + * + * ASSERT: Used for error conditions that are caused by MCU firmware + * bugs. This is used to discover bugs in the code more + * quickly. One example would be adding assertions in library + * function calls to confirm a function's (untainted) + * parameters are valid. + * + * + * The difference in behaviour is that ASSERT triggers a breakpoint while + * verify does not. + * + * #define TU_VERIFY(cond) if(cond) return false; + * #define TU_VERIFY(cond,ret) if(cond) return ret; + * + * #define TU_VERIFY_HDLR(cond,handler) if(cond) {handler; return false;} + * #define TU_VERIFY_HDLR(cond,ret,handler) if(cond) {handler; return ret;} + * + * #define TU_ASSERT(cond) if(cond) {_MESS_FAILED(); TU_BREAKPOINT(), return false;} + * #define TU_ASSERT(cond,ret) if(cond) {_MESS_FAILED(); TU_BREAKPOINT(), return ret;} + * *------------------------------------------------------------------*/ #ifdef __cplusplus -- cgit v1.3.1 From 1cae96951f59e7549ff1a2d5643cda66784c22a1 Mon Sep 17 00:00:00 2001 From: Nathan Conrad Date: Sat, 14 Sep 2019 12:13:11 -0400 Subject: Add usbtmc class driver. --- examples/device/usbtmc/Makefile | 12 + examples/device/usbtmc/src/main.c | 113 +++++++ examples/device/usbtmc/src/tusb_config.h | 66 +++++ examples/device/usbtmc/src/usb_descriptors.c | 254 ++++++++++++++++ examples/device/usbtmc/src/usbtmc_app.c | 133 +++++++++ examples/rules.mk | 1 + src/class/usbtmc/usbtmc.h | 267 +++++++++++++++++ src/class/usbtmc/usbtmc_device.c | 420 +++++++++++++++++++++++++++ src/class/usbtmc/usbtmc_device.h | 130 +++++++++ src/device/usbd.c | 16 + src/tusb.h | 4 + src/tusb_option.h | 4 + 12 files changed, 1420 insertions(+) create mode 100644 examples/device/usbtmc/Makefile create mode 100644 examples/device/usbtmc/src/main.c create mode 100644 examples/device/usbtmc/src/tusb_config.h create mode 100644 examples/device/usbtmc/src/usb_descriptors.c create mode 100644 examples/device/usbtmc/src/usbtmc_app.c create mode 100644 src/class/usbtmc/usbtmc.h create mode 100644 src/class/usbtmc/usbtmc_device.c create mode 100644 src/class/usbtmc/usbtmc_device.h (limited to 'src') diff --git a/examples/device/usbtmc/Makefile b/examples/device/usbtmc/Makefile new file mode 100644 index 000000000..69b633fea --- /dev/null +++ b/examples/device/usbtmc/Makefile @@ -0,0 +1,12 @@ +include ../../../tools/top.mk +include ../../make.mk + +INC += \ + src \ + $(TOP)/hw \ + +# Example source +EXAMPLE_SOURCE += $(wildcard src/*.c) +SRC_C += $(addprefix $(CURRENT_PATH)/, $(EXAMPLE_SOURCE)) + +include ../../rules.mk diff --git a/examples/device/usbtmc/src/main.c b/examples/device/usbtmc/src/main.c new file mode 100644 index 000000000..0293261ad --- /dev/null +++ b/examples/device/usbtmc/src/main.c @@ -0,0 +1,113 @@ +/* + * 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. + * + */ + +#include +#include +#include + +#include "bsp/board.h" +#include "tusb.h" + +//--------------------------------------------------------------------+ +// MACRO CONSTANT TYPEDEF PROTYPES +//--------------------------------------------------------------------+ + +/* Blink pattern + * - 250 ms : device not mounted + * - 1000 ms : device mounted + * - 2500 ms : device is suspended + */ +enum { + BLINK_NOT_MOUNTED = 250, + BLINK_MOUNTED = 1000, + BLINK_SUSPENDED = 2500, +}; + +static uint32_t blink_interval_ms = BLINK_NOT_MOUNTED; + +void led_blinking_task(void); + +/*------------- MAIN -------------*/ +int main(void) +{ + board_init(); + + tusb_init(); + + while (1) + { + tud_task(); // tinyusb device task + led_blinking_task(); + } + + return 0; +} + +//--------------------------------------------------------------------+ +// Device callbacks +//--------------------------------------------------------------------+ + +// Invoked when device is mounted +void tud_mount_cb(void) +{ + blink_interval_ms = BLINK_MOUNTED; +} + +// Invoked when device is unmounted +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; + blink_interval_ms = BLINK_SUSPENDED; +} + +// Invoked when usb bus is resumed +void tud_resume_cb(void) +{ + blink_interval_ms = BLINK_MOUNTED; +} + +//--------------------------------------------------------------------+ +// BLINKING TASK +//--------------------------------------------------------------------+ +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 + start_ms += blink_interval_ms; + + board_led_write(led_state); + led_state = 1 - led_state; // toggle +} diff --git a/examples/device/usbtmc/src/tusb_config.h b/examples/device/usbtmc/src/tusb_config.h new file mode 100644 index 000000000..022dc7691 --- /dev/null +++ b/examples/device/usbtmc/src/tusb_config.h @@ -0,0 +1,66 @@ +/* + * tusb_config.h + * + * Created on: Sep 5, 2019 + * Author: nconrad + */ + +#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 +#define CFG_TUSB_RHPORT0_MODE (OPT_MODE_DEVICE | OPT_MODE_HIGH_SPEED) +#else +#define CFG_TUSB_RHPORT0_MODE OPT_MODE_DEVICE +#endif + +#define CFG_TUSB_OS OPT_OS_NONE + +// 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 + +//-------------------------------------------------------------------- +// DEVICE CONFIGURATION +//-------------------------------------------------------------------- + +#define CFG_TUD_ENDOINT0_SIZE 64 + +//------------- CLASS -------------// + +#define CFG_TUD_USBTMC 1 +#define CFG_TUD_USBTMC_ENABLE_INT_EP +//#define USBTMC_CFG_ENABLE_488 0 + +#ifdef __cplusplus + } +#endif + +#endif /* TUSB_CONFIG_H_ */ diff --git a/examples/device/usbtmc/src/usb_descriptors.c b/examples/device/usbtmc/src/usb_descriptors.c new file mode 100644 index 000000000..296636359 --- /dev/null +++ b/examples/device/usbtmc/src/usb_descriptors.c @@ -0,0 +1,254 @@ +/* + * 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. + * + */ + +#include "tusb.h" +#include "class/usbtmc/usbtmc.h" +#include "class/usbtmc/usbtmc_device.h" + +/* A combination of interfaces must have a unique product id, since PC will save device driver after the first plug. + * Same VID/PID with different interface e.g MSC (first), then CDC (later) will possibly cause system error on PC. + * + * Auto ProductID layout's Bitmap: + * [MSB] HID | MSC | CDC [LSB] + */ +#define _PID_MAP(itf, n) ( (CFG_TUD_##itf) << (n) ) +#define USB_PID (0x4000 | _PID_MAP(CDC, 0) | _PID_MAP(MSC, 1) | _PID_MAP(HID, 2) | \ + _PID_MAP(MIDI, 3) | _PID_MAP(VENDOR, 4) ) + +//--------------------------------------------------------------------+ +// Device Descriptors +//--------------------------------------------------------------------+ +tusb_desc_device_t const desc_device = +{ + .bLength = sizeof(tusb_desc_device_t), + .bDescriptorType = TUSB_DESC_DEVICE, + .bcdUSB = 0x0200, + + #if CFG_TUD_CDC + // Use Interface Association Descriptor (IAD) for CDC + // As required by USB Specs IAD's subclass must be common class (2) and protocol must be IAD (1) + .bDeviceClass = TUSB_CLASS_MISC, + .bDeviceSubClass = MISC_SUBCLASS_COMMON, + .bDeviceProtocol = MISC_PROTOCOL_IAD, + #else + .bDeviceClass = 0x00, + .bDeviceSubClass = 0x00, + .bDeviceProtocol = 0x00, + #endif + + .bMaxPacketSize0 = CFG_TUD_ENDOINT0_SIZE, + + .idVendor = 0xCafe, + .idProduct = USB_PID, + .bcdDevice = 0x0100, + + .iManufacturer = 0x01, + .iProduct = 0x02, + .iSerialNumber = 0x03, + + .bNumConfigurations = 0x01 +}; + +// Invoked when received GET DEVICE DESCRIPTOR +// Application return pointer to descriptor +uint8_t const * tud_descriptor_device_cb(void) +{ + return (uint8_t const *) &desc_device; +} + +//--------------------------------------------------------------------+ +// HID Report Descriptor +//--------------------------------------------------------------------+ +#if CFG_TUD_HID + +uint8_t const desc_hid_report[] = +{ + TUD_HID_REPORT_DESC_KEYBOARD( HID_REPORT_ID(REPORT_ID_KEYBOARD), ), + TUD_HID_REPORT_DESC_MOUSE ( HID_REPORT_ID(REPORT_ID_MOUSE), ) +}; + +// Invoked when received GET HID REPORT DESCRIPTOR +// Application return pointer to descriptor +// Descriptor contents must exist long enough for transfer to complete +uint8_t const * tud_hid_descriptor_report_cb(void) +{ + return desc_hid_report; +} + +#endif + +//--------------------------------------------------------------------+ +// Configuration Descriptor +//--------------------------------------------------------------------+ + +#if defined(CFG_TUD_USBTMC) + +# define USBTMC_DESC_MAIN(_itfnum,_bNumEndpoints) \ + USBTMC_IF_DESCRIPTOR(_itfnum, _bNumEndpoints, /*_stridx = */ 7u, USBTMC_PROTOCOL_USB488), \ + USBTMC_BULK_DESCRIPTORS(/* OUT = */0x03, /* IN = */ 0x83) + +#if defined(CFG_TUD_USBTMC_ENABLE_INT_EP) + +# define USBTMC_DESC(_itfnum) \ + USBTMC_DESC_MAIN(_itfnum, /* _epCount = */ 3), \ + USBTMC_INT_DESCRIPTOR(/* INT ep # */ 0x84, /* epMaxSize = */ 64, /* bInterval = */16u ) +# define USBTMC_DESC_LEN (USBTMC_IF_DESCRIPTOR_LEN + USBTMC_BULK_DESCRIPTORS_LEN + USBTMC_INT_DESCRIPTOR_LEN) + +#else + +# define USBTMC_DESC(_itfnum) \ + USBTMC_DESC_MAIN(_itfnum, /* _epCount = */ 2u) +# define USBTMC_DESC_LEN (USBTMC_IF_DESCRIPTOR_LEN + USBTMC_BULK_DESCRIPTORS_LEN) + +#endif /* CFG_TUD_USBTMC_ENABLE_INT_EP */ + +#else +# define USBTMC_DESC_LEN (0) +#endif /* CFG_TUD_USBTMC */ + +enum +{ +#if CFG_TUD_CDC + ITF_NUM_CDC = 0, + ITF_NUM_CDC_DATA, +#endif + +#if CFG_TUD_MSC + ITF_NUM_MSC, +#endif + +#if CFG_TUD_HID + ITF_NUM_HID, +#endif +#if CFG_TUD_USBTMC + ITF_NUM_USBTMC, +#endif + ITF_NUM_TOTAL +}; + + +#define CONFIG_TOTAL_LEN (TUD_CONFIG_DESC_LEN + CFG_TUD_CDC*TUD_CDC_DESC_LEN + CFG_TUD_MSC*TUD_MSC_DESC_LEN + \ + CFG_TUD_HID*TUD_HID_DESC_LEN + (CFG_TUD_USBTMC)*USBTMC_DESC_LEN) + +#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 ... + // Note: since CDC EP ( 1 & 2), HID (4) are spot-on, thus we only need to force + // endpoint number for MSC to 5 + #define EPNUM_MSC 0x05 +#else + #define EPNUM_MSC 0x03 +#endif + + +uint8_t const desc_configuration[] = +{ + // Interface count, string index, total length, attribute, power in mA + TUD_CONFIG_DESCRIPTOR(ITF_NUM_TOTAL, 0, CONFIG_TOTAL_LEN, TUSB_DESC_CONFIG_ATT_REMOTE_WAKEUP, 100), + +#if CFG_TUD_CDC + // Interface number, string index, EP notification address and size, EP data address (out, in) and size. + TUD_CDC_DESCRIPTOR(ITF_NUM_CDC, 1, 0x81, 8, 0x02, 0x82, 64), +#endif + +#if CFG_TUD_USBTMC + USBTMC_DESC(ITF_NUM_USBTMC), +#endif + +#if CFG_TUD_MSC + // Interface number, string index, EP Out & EP In address, EP size + TUD_MSC_DESCRIPTOR(ITF_NUM_MSC, 5, EPNUM_MSC, 0x80 | EPNUM_MSC, (CFG_TUSB_RHPORT0_MODE & OPT_MODE_HIGH_SPEED) ? 512 : 64), +#endif + +#if CFG_TUD_HID + // Interface number, string index, protocol, report descriptor len, EP In address, size & polling interval + TUD_HID_DESCRIPTOR(ITF_NUM_HID, 6, HID_PROTOCOL_NONE, sizeof(desc_hid_report), 0x84, 16, 10) +#endif +}; + + +// Invoked when received GET CONFIGURATION DESCRIPTOR +// Application return pointer to descriptor +// Descriptor contents must exist long enough for transfer to complete +uint8_t const * tud_descriptor_configuration_cb(uint8_t index) +{ + (void) index; // for multiple configurations + return desc_configuration; +} + +//--------------------------------------------------------------------+ +// String Descriptors +//--------------------------------------------------------------------+ + +// array of pointer to string descriptors +char const* string_desc_arr [] = +{ + (const char[]) { 0x09, 0x04 }, // 0: is supported language is English (0x0409) + "TinyUSB", // 1: Manufacturer + "TinyUSB Device", // 2: Product + "123456", // 3: Serials, should use chip ID + "TinyUSB CDC", // 4: CDC Interface + "TinyUSB MSC", // 5: MSC Interface + "TinyUSB HID", // 6: HID + "TinyUSB USBTMC", // 7: USBTMC +}; + +static uint16_t _desc_str[32]; + +// Invoked when received GET STRING DESCRIPTOR request +// 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) +{ + uint8_t chr_count; + + if ( index == 0) + { + memcpy(&_desc_str[1], string_desc_arr[0], 2); + chr_count = 1; + }else + { + // Convert ASCII string into UTF-16 + + if ( !(index < sizeof(string_desc_arr)/sizeof(string_desc_arr[0])) ) return NULL; + + const char* str = string_desc_arr[index]; + + // Cap at max char + chr_count = strlen(str); + if ( chr_count > 31 ) { + chr_count = 31; + } + + for(uint8_t i=0; i +#include "class/usbtmc/usbtmc_device.h" + +#if (USBTMC_CFG_ENABLE_488) +usbtmc_response_capabilities_488_t const +#else +usbtmc_response_capabilities_t const +#endif +usbtmcd_app_capabilities = +{ + .USBTMC_status = USBTMC_STATUS_SUCCESS, + .bcdUSBTMC = USBTMC_VERSION, + .bmIntfcCapabilities = + { + .listenOnly = 0, + .talkOnly = 0, + .supportsIndicatorPulse = 0 + }, + .bmDevCapabilities = { + .canEndBulkInOnTermChar = 0 + }, + +#if (USBTMC_CFG_ENABLE_488) + .bcdUSB488 = USBTMC_488_VERSION, + .bmIntfcCapabilities488 = + { + .supportsTrigger = 0, + .supportsREN_GTL_LLO = 0, + .is488_2 = 1 + }, + .bmDevCapabilities488 = + { + .SCPI = 1, + .SR1 = 0, + .RL1 = 0, + .DT1 =0, + } +#endif +}; + +static const char idn[] = "TinyUSB,ModelNumber,SerialNumber,FirmwareVer"; +static uint8_t status; +static bool queryReceived = false; + + +bool usbtmcd_app_msgBulkOut_start(usbtmc_msg_request_dev_dep_out const * msgHeader) +{ + (void)msgHeader; + return true; +} + + +bool usbtmcd_app_msg_data(void *data, size_t len, bool transfer_complete) +{ + (void)transfer_complete; + if(transfer_complete && (len >=4) && !strncasecmp("*idn?",data,4)) { + queryReceived = true; + } + return true; +} + +bool usbtmcd_app_msgBulkIn_complete(uint8_t rhport) +{ + (void)rhport; + return true; +} + +static uint8_t noQueryMsg[] = "ERR: No query"; +bool usbtmcd_app_msgBulkIn_request(uint8_t rhport, usbtmc_msg_request_dev_dep_in const * request) +{ + usbtmc_msg_dev_dep_msg_in_header_t hdr = { + .header = + { + .MsgID = request->header.MsgID, + .bTag = request->header.bTag, + .bTagInverse = request->header.bTagInverse + }, + .TransferSize = sizeof(idn)-1, + .bmTransferAttributes = + { + .EOM = 1, + .UsingTermChar = 0 + } + }; + if(queryReceived) + { + usbtmcd_transmit_dev_msg_data(rhport, &hdr, idn); + } + else + { + hdr.TransferSize = sizeof(noQueryMsg)-1; + usbtmcd_transmit_dev_msg_data(rhport, &hdr, noQueryMsg); + } + queryReceived = false; + return true; +} + +// Return status byte, but put the transfer result status code in the rspResult argument. +uint8_t usbtmcd_app_get_stb(uint8_t rhport, uint8_t *rspResult) +{ + (void)rhport; + *rspResult = USBTMC_STATUS_SUCCESS; + // Increment status so that we see different results on each read... + status++; + + return status; +} + diff --git a/examples/rules.mk b/examples/rules.mk index 478a5907a..c3daf9dac 100644 --- a/examples/rules.mk +++ b/examples/rules.mk @@ -15,6 +15,7 @@ SRC_C += \ src/class/cdc/cdc_device.c \ src/class/hid/hid_device.c \ src/class/midi/midi_device.c \ + src/class/usbtmc/usbtmc_device.c \ src/class/vendor/vendor_device.c \ src/portable/$(VENDOR)/$(CHIP_FAMILY)/dcd_$(CHIP_FAMILY).c diff --git a/src/class/usbtmc/usbtmc.h b/src/class/usbtmc/usbtmc.h new file mode 100644 index 000000000..846c0e38d --- /dev/null +++ b/src/class/usbtmc/usbtmc.h @@ -0,0 +1,267 @@ + +/* + * The MIT License (MIT) + * + * Copyright (c) 2019 N Conrad + * + * 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. + */ + +#ifndef _TUSB_USBTMC_H__ +#define _TUSB_USBTMC_H__ + +#include "common/tusb_common.h" + + +/* Implements USBTMC Revision 1.0, April 14, 2003 + + String descriptors must have a "LANGID=0x409"/US English string. + Characters must be 0x20 (' ') to 0x7E ('~') ASCII, + But MUST not contain: "/:?\* + Also must not have leading or trailing space (' ') + Device descriptor must state USB version 0x0200 or greater + + If USB488DeviceCapabilites.D2 = 1 (SR1), then there must be a INT endpoint. +*/ + +#define USBTMC_VERSION 0x0100 +#define USBTMC_488_VERSION 0x0100 + +typedef enum { + USBTMC_MSGID_DEV_DEP_MSG_OUT = 1u, + USBTMC_MSGID_DEV_DEP_MSG_IN = 2u, + USBTMC_MSGID_VENDOR_SPECIFIC_MSG_OUT = 126u, + USBTMC_MSGID_VENDOR_SPECIFIC_IN = 127u, + USBTMC_MSGID_USB488_TRIGGER = 128u, +} usbtmc_msgid_enum; + +/// \brief Message header (For BULK OUT and BULK IN); 4 bytes +typedef struct TU_ATTR_PACKED +{ + uint8_t MsgID ; ///< Message type ID (usbtmc_msgid_enum) + uint8_t bTag ; ///< Transfer ID 1<=bTag<=255 + uint8_t bTagInverse ; ///< Complement of the tag + uint8_t _reserved ; ///< Must be 0x00 +} usbtmc_msg_header_t; + +typedef struct TU_ATTR_PACKED +{ + usbtmc_msg_header_t header; + uint8_t data[8]; +} usbtmc_msg_generic_t; + +/* Uses on the bulk-out endpoint: */ +// Next 8 bytes are message-specific +typedef struct TU_ATTR_PACKED { + usbtmc_msg_header_t header ; ///< Header + uint32_t TransferSize ; ///< Transfer size; LSB first + struct { + uint8_t EOM : 1 ; ///< EOM set on last byte + } bmTransferAttributes; + uint8_t _reserved[3]; +} usbtmc_msg_request_dev_dep_out; + +// Next 8 bytes are message-specific +typedef struct TU_ATTR_PACKED { + usbtmc_msg_header_t header ; ///< Header + uint32_t TransferSize ; ///< Transfer size; LSB first + struct { + uint8_t : 0; + uint8_t TermCharEnabled : 1 ; ///< "The Bulk-IN transfer must terminate on the specified TermChar."; CAPABILITIES must list TermChar + } bmTransferAttributes; + uint8_t TermChar; + uint8_t _reserved[2]; +} usbtmc_msg_request_dev_dep_in; + +/* Bulk-in headers */ + +typedef struct TU_ATTR_PACKED +{ + usbtmc_msg_header_t header; + uint32_t TransferSize; + struct { + uint8_t EOM: 1; ///< Last byte of transfer is the end of the message + uint8_t UsingTermChar: 1; ///< Support TermChar && Request.TermCharEnabled && last char in transfer is TermChar + } bmTransferAttributes; + uint8_t _reserved[3]; +} usbtmc_msg_dev_dep_msg_in_header_t; + + +/* Unsupported vendor things.... Are these ever used?*/ + +typedef struct TU_ATTR_PACKED { + usbtmc_msg_header_t header ; ///< Header + uint32_t TransferSize ; ///< Transfer size; LSB first + uint8_t _reserved[4]; +} usbtmc_msg_request_vendor_specific_out; + + +typedef struct TU_ATTR_PACKED { + usbtmc_msg_header_t header ; ///< Header + uint32_t TransferSize ; ///< Transfer size; LSB first + uint8_t _reserved[4]; +} usbtmc_msg_request_vendor_specific_in; + +// Control request type should use tusb_control_request_t + +/* +typedef struct TU_ATTR_PACKED { + struct { + uint8_t Recipient : 5 ; ///< EOM set on last byte + uint8_t Type : 2 ; ///< EOM set on last byte + uint8_t DirectionToHost : 1 ; ///< 0 is OUT, 1 is IN + } bmRequestType; + uint8_t bRequest ; ///< If bmRequestType.Type = Class, see usmtmc_request_type_enum + uint16_t wValue ; + uint16_t wIndex ; + uint16_t wLength ; // Number of bytes in data stage +} usbtmc_class_specific_control_req; + +*/ +// bulk-in protocol errors +enum { + USBTMC_BULK_IN_ERR_INCOMPLETE_HEADER = 1u, + USBTMC_BULK_IN_ERR_UNSUPPORTED = 2u, + USBTMC_BULK_IN_ERR_BAD_PARAMETER = 3u, + USBTMC_BULK_IN_ERR_DATA_TOO_SHORT = 4u, + USBTMC_BULK_IN_ERR_DATA_TOO_LONG = 5u, +}; +// bult-in halt errors +enum { + USBTMC_BULK_IN_ERR = 1u, ///< receives a USBTMC command message that expects a response while a + /// Bulk-IN transfer is in progress +}; + +typedef enum { + USBTMC_bREQUEST_INITIATE_ABORT_BULK_OUT = 1u, + USBTMC_bREQUEST_CHECK_ABORT_BULK_OUT_STATUS = 2u, + USBTMC_bREQUEST_INITIATE_ABORT_BULK_IN = 3u, + USBTMC_bREQUEST_CHECK_ABORT_BULK_IN_STATUS = 4u, + USBTMC_bREQUEST_INITIATE_CLEAR = 5u, + USBTMC_bREQUEST_CHECK_CLEAR_STATUS = 6u, + USBTMC_bREQUEST_GET_CAPABILITIES = 7u, + + USBTMC_bREQUEST_INDICATOR_PULSE = 64u, // Optional +} usmtmc_request_type_enum; + +typedef enum { + USBTMC488_bREQUEST_READ_STATUS_BYTE = 128u, + USBTMC488_bREQUEST_REN_CONTROL = 160u, + USBTMC488_bREQUEST_GO_TO_LOCAL = 161u, + USBTMC488_bREQUEST_LOCAL_LOCKOUT = 162u, +} usbtmc_request_type_488_enum; + +typedef enum { + USBTMC_STATUS_SUCCESS = 0x01, + USBTMC_STATUS_PENDING = 0x02, + USBTMC_STATUS_FAILED = 0x80, + USBTMC_STATUS_TRANSFER_NOT_IN_PROGRESS = 0x81, + USBTMC_STATUS_SPLIT_NOT_IN_PROGRESS = 0x82, + USBTMC_STATUS_SPLIT_IN_PROGRESS = 0x83 +} usbtmc_status_enum; + +/************************************************************ + * Control Responses + */ + +typedef struct TU_ATTR_PACKED { + uint8_t USBTMC_status; ///< usbtmc_status_enum + uint8_t _reserved; + uint16_t bcdUSBTMC; ///< USBTMC_VERSION + + struct { + uint8_t listenOnly :1; + uint8_t talkOnly :1; + uint8_t supportsIndicatorPulse :1; + } bmIntfcCapabilities; + struct { + uint8_t canEndBulkInOnTermChar :1; + } bmDevCapabilities; + uint8_t _reserved2[6]; + uint8_t _reserved3[12]; +} usbtmc_response_capabilities_t; + +TU_VERIFY_STATIC(sizeof(usbtmc_response_capabilities_t) == 0x18, "struct wrong length"); + +typedef struct TU_ATTR_PACKED +{ + uint8_t USBTMC_status; ///< usbtmc_status_enum + uint8_t _reserved; + uint16_t bcdUSBTMC; ///< USBTMC_VERSION + + struct + { + uint8_t listenOnly :1; + uint8_t talkOnly :1; + uint8_t supportsIndicatorPulse :1; + } bmIntfcCapabilities; + + struct + { + uint8_t canEndBulkInOnTermChar :1; + } bmDevCapabilities; + + uint8_t _reserved2[6]; + uint16_t bcdUSB488; + + struct + { + uint8_t is488_2 :1; + uint8_t supportsREN_GTL_LLO :1; + uint8_t supportsTrigger :1; + } bmIntfcCapabilities488; + + struct + { + uint8_t SCPI :1; + uint8_t SR1 :1; + uint8_t RL1 :1; + uint8_t DT1 :1; + } bmDevCapabilities488; + uint8_t _reserved3[8]; +} usbtmc_response_capabilities_488_t; + +TU_VERIFY_STATIC(sizeof(usbtmc_response_capabilities_488_t) == 0x18, "struct wrong length"); + +typedef struct TU_ATTR_PACKED +{ + uint8_t USBTMC_status; + uint8_t bTag; + uint8_t statusByte; +} usbtmc_read_stb_rsp_488_t; + +TU_VERIFY_STATIC(sizeof(usbtmc_read_stb_rsp_488_t) == 3u, "struct wrong length"); + +typedef struct TU_ATTR_PACKET +{ + union { + struct { + uint8_t bTag : 7; + uint8_t one : 1; + } bNotify1Struct; + uint8_t bNotify1; + }; + uint8_t StatusByte; +} usbtmc_read_stb_interrupt_488_t; +TU_VERIFY_STATIC(sizeof(usbtmc_read_stb_interrupt_488_t) == 2u, "struct wrong length"); + +#endif + diff --git a/src/class/usbtmc/usbtmc_device.c b/src/class/usbtmc/usbtmc_device.c new file mode 100644 index 000000000..4bb21f354 --- /dev/null +++ b/src/class/usbtmc/usbtmc_device.c @@ -0,0 +1,420 @@ +/* + * usbtmc.c + * + * Created on: Sep 9, 2019 + * Author: nconrad + */ + +/* + * The MIT License (MIT) + * + * Copyright (c) 2019 N Conrad + * + * 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" + +// We don't do any cross-task anything here (everything is in tud or interrupt context). +// You must ensure thread safety in your own app. + + +//Limitations (not planned to be implemented): +// "vendor-specific" commands are not handled + +// TODO: +// USBTMC 3.2.2 error conditions not strictly followed +// No local lock-out, REN, or GTL. +// Cannot issue clear. +// No "capabilities" supported +// Interrupt-IN endpoint +// 488 MsgID=Trigger +// Clear message available status byte at the correct time? (488 4.3.1.3) +// Split transfers +// No CLEAR_FEATURE/HALT (yet) + +#if (TUSB_OPT_DEVICE_ENABLED && CFG_TUD_USBTMC) + +#include "usbtmc.h" +#include "usbtmc_device.h" +#include "device/dcd.h" +#include "device/usbd.h" + +// FIXME: I shouldn't need to include _pvt headers. +#include "device/usbd_pvt.h" + +typedef enum +{ + STATE_IDLE, + STATE_RCV, + STATE_TX_REQUESTED, + STATE_TX_INITIATED +} usbtmcd_state_enum; + +typedef struct +{ + usbtmcd_state_enum state; + uint8_t itf_id; + uint8_t ep_bulk_in; + uint8_t ep_bulk_out; + uint8_t ep_int_in; + uint8_t ep_bulk_in_buf[64]; + uint8_t ep_bulk_out_buf[64]; + uint8_t lastTag; + + uint32_t transfer_size_remaining; + uint8_t const * devInBuffer; +} usbtmc_interface_state_t; + +static usbtmc_interface_state_t usbtmc_state = +{ + .state = STATE_IDLE, + .itf_id = 0xFF, + .ep_bulk_in = 0, + .ep_bulk_out = 0, + .ep_int_in = 0 +}; + +// We want everything to fit nicely in a single packet, so lets require EP size >32 +// I'm not sure if this is really necessary, though. +TU_VERIFY_STATIC(USBTMCD_MAX_PACKET_SIZE >= 32u,"USBTMC dev EP packet size too small"); + +// called from app +// We keep a reference to the buffer, so it MUST not change until the app is +// notified that the transfer is complete. +// length of data is specified in the hdr. +bool usbtmcd_transmit_dev_msg_data( + uint8_t rhport, + usbtmc_msg_dev_dep_msg_in_header_t const * hdr, + const void *data) +{ + TU_ASSERT(usbtmc_state.state == STATE_TX_REQUESTED); + TU_ASSERT(hdr->TransferSize > 0u); + + // Copy in the header + memcpy(usbtmc_state.ep_bulk_in_buf, hdr, sizeof(*hdr)); + uint packetLen = sizeof(*hdr); + // Single-packet transfer + if((packetLen + hdr->TransferSize) <= USBTMCD_MAX_PACKET_SIZE) + { + memcpy((uint8_t*)(usbtmc_state.ep_bulk_in_buf) + packetLen, data, hdr->TransferSize); + packetLen = (uint16_t)(packetLen+ hdr->TransferSize); + // Pad up to multiple of 4 bytes + while((packetLen % 4) != 0) + { + usbtmc_state.ep_bulk_in_buf[packetLen] = 0; + packetLen++; + } + usbtmc_state.transfer_size_remaining = 0; + usbtmc_state.devInBuffer = NULL; + } + else + { + memcpy((uint8_t*)(usbtmc_state.ep_bulk_in_buf) + packetLen, data, USBTMCD_MAX_PACKET_SIZE - packetLen); + usbtmc_state.transfer_size_remaining = hdr->TransferSize - (USBTMCD_MAX_PACKET_SIZE - packetLen); + usbtmc_state.devInBuffer += (USBTMCD_MAX_PACKET_SIZE - packetLen); + packetLen = USBTMCD_MAX_PACKET_SIZE; + } + usbtmc_state.state = STATE_TX_INITIATED; + TU_VERIFY( usbd_edpt_xfer(rhport, usbtmc_state.ep_bulk_in, usbtmc_state.ep_bulk_in_buf,(uint16_t)packetLen)); + return true; +} + +void usbtmcd_init(void) +{ + +} + +bool usbtmcd_open(uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint16_t *p_length) +{ + (void)rhport; + uint8_t const * p_desc; + uint8_t found_endpoints = 0; + + // Perhaps there are other application specific class drivers, so don't assert here. + if( itf_desc->bInterfaceClass != USBTMC_APP_CLASS) + return false; + if( itf_desc->bInterfaceSubClass != USBTMC_APP_SUBCLASS) + return false; + + // Only 2 or 3 endpoints are allowed for USBTMC. + TU_ASSERT((itf_desc->bNumEndpoints == 2) || (itf_desc->bNumEndpoints ==3)); + + // Interface + (*p_length) = 0u; + p_desc = (uint8_t const *) itf_desc; + + usbtmc_state.itf_id = itf_desc->bInterfaceNumber; + + while (found_endpoints < itf_desc->bNumEndpoints) + { + if ( TUSB_DESC_ENDPOINT == p_desc[DESC_OFFSET_TYPE]) + { + tusb_desc_endpoint_t const *ep_desc = (tusb_desc_endpoint_t const *)p_desc; + switch(ep_desc->bmAttributes.xfer) { + case TUSB_XFER_BULK: + if (tu_edpt_dir(ep_desc->bEndpointAddress) == TUSB_DIR_IN) + { + usbtmc_state.ep_bulk_in = ep_desc->bEndpointAddress; + } else { + usbtmc_state.ep_bulk_out = ep_desc->bEndpointAddress; + } + + break; + case TUSB_XFER_INTERRUPT: + TU_ASSERT(tu_edpt_dir(ep_desc->bEndpointAddress) == TUSB_DIR_IN); + TU_ASSERT(usbtmc_state.ep_int_in == 0); + usbtmc_state.ep_int_in = ep_desc->bEndpointAddress; + break; + default: + TU_ASSERT(false); + } + TU_VERIFY( dcd_edpt_open(rhport, ep_desc)); + found_endpoints++; + } + (*p_length) = (uint8_t)((*p_length) + p_desc[DESC_OFFSET_LEN]); + p_desc = tu_desc_next(p_desc); + } + + // bulk endpoints are required, but interrupt IN is optional + TU_ASSERT(usbtmc_state.ep_bulk_in != 0); + TU_ASSERT(usbtmc_state.ep_bulk_out != 0); + if (itf_desc->bNumEndpoints == 2) { + TU_ASSERT(usbtmc_state.ep_int_in == 0); + } + else if (itf_desc->bNumEndpoints == 2) + { + TU_ASSERT(usbtmc_state.ep_int_in != 0); + } + TU_VERIFY( usbd_edpt_xfer(rhport, usbtmc_state.ep_bulk_out, usbtmc_state.ep_bulk_out_buf, 64)); + + return true; +} +void usbtmcd_reset(uint8_t rhport) +{ + // FIXME: Do endpoints need to be closed here? + (void)rhport; +} +static bool handle_devMsgOut(uint8_t rhport, void *data, size_t len) +{ + (void)rhport; + bool shortPacket = (len < USBTMCD_MAX_PACKET_SIZE); + if(usbtmc_state.state == STATE_IDLE) + { + // must be a header, should have been confirmed before calling here. + usbtmc_msg_request_dev_dep_out *msg = (usbtmc_msg_request_dev_dep_out*)data; + usbtmc_state.transfer_size_remaining = msg->TransferSize; + TU_VERIFY(usbtmcd_app_msgBulkOut_start(msg)); + len -= sizeof(*msg); + data = (uint8_t*)data + sizeof(*msg); + } + // Packet is to be considered complete when we get enough data or at a short packet. + bool atEnd = false; + if(len >= usbtmc_state.transfer_size_remaining || shortPacket) + atEnd = true; + if(len > usbtmc_state.transfer_size_remaining) + len = usbtmc_state.transfer_size_remaining; + usbtmcd_app_msg_data(data, len, atEnd); + if(atEnd) + usbtmc_state.state = STATE_IDLE; + else + usbtmc_state.state = STATE_RCV; + return true; +} +static bool handle_devMsgIn(uint8_t rhport, void *data, size_t len) +{ + TU_VERIFY(len == sizeof(usbtmc_msg_request_dev_dep_in)); + usbtmc_msg_request_dev_dep_in *msg = (usbtmc_msg_request_dev_dep_in*)data; + TU_VERIFY(usbtmc_state.state == STATE_IDLE); + usbtmc_state.state = STATE_TX_REQUESTED; + usbtmc_state.transfer_size_remaining = msg->TransferSize; + TU_VERIFY(usbtmcd_app_msgBulkIn_request(rhport, msg)); + return true; +} + +bool usbtmcd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes) +{ + TU_VERIFY(result == XFER_RESULT_SUCCESS); + if(ep_addr == usbtmc_state.ep_bulk_out) + { + switch(usbtmc_state.state) + { + case STATE_IDLE: + TU_VERIFY(xferred_bytes >= sizeof(usbtmc_msg_generic_t)); + usbtmc_msg_generic_t *msg = (usbtmc_msg_generic_t*)(usbtmc_state.ep_bulk_out_buf); + uint8_t invInvTag = (uint8_t)~(msg->header.bTagInverse); + TU_VERIFY(msg->header.bTag == invInvTag); + TU_VERIFY(msg->header.bTag != 0x00); + usbtmc_state.lastTag = msg->header.bTag; + + switch(msg->header.MsgID) { + case USBTMC_MSGID_DEV_DEP_MSG_OUT: + TU_VERIFY(handle_devMsgOut(rhport, msg, xferred_bytes)); + TU_VERIFY(usbd_edpt_xfer(rhport, usbtmc_state.ep_bulk_out, usbtmc_state.ep_bulk_out_buf, 64)); + break; + case USBTMC_MSGID_DEV_DEP_MSG_IN: + TU_VERIFY(handle_devMsgIn(rhport, msg, xferred_bytes)); + break; + case USBTMC_MSGID_VENDOR_SPECIFIC_MSG_OUT: + case USBTMC_MSGID_VENDOR_SPECIFIC_IN: + case USBTMC_MSGID_USB488_TRIGGER: + default: + TU_VERIFY(false); + } + return true; + + case STATE_RCV: + TU_VERIFY(handle_devMsgOut(rhport, usbtmc_state.ep_bulk_out_buf, xferred_bytes)); + TU_VERIFY( usbd_edpt_xfer(rhport, usbtmc_state.ep_bulk_out, usbtmc_state.ep_bulk_out_buf, 64)); + return true; + break; + + default: + TU_VERIFY(false); + } + } + else if(ep_addr == usbtmc_state.ep_bulk_in) + { + TU_ASSERT(usbtmc_state.state == STATE_TX_INITIATED); + if(usbtmc_state.transfer_size_remaining == 0) + { + usbtmc_state.state = STATE_IDLE; + TU_VERIFY(usbtmcd_app_msgBulkIn_complete(rhport)); + TU_VERIFY( usbd_edpt_xfer(rhport, usbtmc_state.ep_bulk_out, usbtmc_state.ep_bulk_out_buf, 64)); + } + else if(usbtmc_state.transfer_size_remaining >= USBTMCD_MAX_PACKET_SIZE) + { + memcpy(usbtmc_state.ep_bulk_in_buf, usbtmc_state.devInBuffer, USBTMCD_MAX_PACKET_SIZE); + usbtmc_state.devInBuffer += USBTMCD_MAX_PACKET_SIZE; + usbtmc_state.transfer_size_remaining -= USBTMCD_MAX_PACKET_SIZE; + TU_VERIFY( usbd_edpt_xfer(rhport, usbtmc_state.ep_bulk_in, usbtmc_state.ep_bulk_in_buf,USBTMCD_MAX_PACKET_SIZE)); + } + else // short packet + { + uint packetLen = usbtmc_state.transfer_size_remaining; + memcpy(usbtmc_state.ep_bulk_in_buf, usbtmc_state.devInBuffer, usbtmc_state.transfer_size_remaining); + while((packetLen % 4) != 0) + { + usbtmc_state.ep_bulk_in_buf[packetLen] = 0; + packetLen++; + } + usbtmc_state.transfer_size_remaining = 0; + usbtmc_state.devInBuffer = NULL; + TU_VERIFY( usbd_edpt_xfer(rhport, usbtmc_state.ep_bulk_in, usbtmc_state.ep_bulk_in_buf,(uint16_t)packetLen)); + } + return true; + } + else if (ep_addr == usbtmc_state.ep_int_in) { + // Good? + return true; + } + return false; +} + +bool usbtmcd_control_request(uint8_t rhport, tusb_control_request_t const * request) { + +#if (USBTMC_CFG_ENABLE_488) + ushort bTag; +#endif + // We only handle class requests. + if(request->bmRequestType_bit.type != TUSB_REQ_TYPE_CLASS) + return false; + + switch(request->bRequest) + { + // USBTMC required requests + case USBTMC_bREQUEST_INITIATE_ABORT_BULK_OUT: + case USBTMC_bREQUEST_CHECK_ABORT_BULK_OUT_STATUS: + case USBTMC_bREQUEST_INITIATE_ABORT_BULK_IN: + case USBTMC_bREQUEST_CHECK_ABORT_BULK_IN_STATUS: + case USBTMC_bREQUEST_INITIATE_CLEAR: + case USBTMC_bREQUEST_CHECK_CLEAR_STATUS: + TU_VERIFY(false); + break; + + case USBTMC_bREQUEST_GET_CAPABILITIES: + TU_VERIFY(request->bmRequestType == 0xA1); + TU_VERIFY(request->wValue == 0x0000); + TU_VERIFY(request->wIndex == usbtmc_state.itf_id); + TU_VERIFY(request->wLength == sizeof(usbtmcd_app_capabilities)); + TU_VERIFY(tud_control_xfer(rhport, request, (void*)&usbtmcd_app_capabilities, sizeof(usbtmcd_app_capabilities))); + return true; + // USBTMC Optional Requests + case USBTMC_bREQUEST_INDICATOR_PULSE: // Optional + TU_VERIFY(false); + return false; + +#if (USBTMC_CFG_ENABLE_488) + // USB488 required requests + case USBTMC488_bREQUEST_READ_STATUS_BYTE: + + bTag = request->wValue & 0x7F; + TU_VERIFY(request->bmRequestType == 0xA1); + TU_VERIFY((request->wValue & (~0x7F)) == 0u); // Other bits are required to be zero + TU_VERIFY(bTag >= 0x02 && bTag <= 127); + TU_VERIFY(request->wIndex == usbtmc_state.itf_id); + TU_VERIFY(request->wLength == 0x0003); + usbtmc_read_stb_rsp_488_t rsp; + rsp.bTag = (uint8_t)bTag; + if(usbtmc_state.ep_int_in != 0) + { + rsp.USBTMC_status = USBTMC_STATUS_SUCCESS; + rsp.statusByte = 0x00; // Use interrupt endpoint, instead. + + usbtmc_read_stb_interrupt_488_t intMsg = + { + .bNotify1 = (uint8_t)(0x80 | bTag), + .StatusByte = usbtmcd_app_get_stb(rhport, &(rsp.USBTMC_status)) + }; + usbd_edpt_xfer(rhport, usbtmc_state.ep_int_in, (void*)&intMsg,sizeof(intMsg)); + + } + else + { + rsp.statusByte = usbtmcd_app_get_stb(rhport, &(rsp.USBTMC_status)); + } + TU_VERIFY(tud_control_xfer(rhport, request, (void*)&rsp, sizeof(rsp))); + return true; + + // USB488 optional requests + case USBTMC488_bREQUEST_REN_CONTROL: + case USBTMC488_bREQUEST_GO_TO_LOCAL: + case USBTMC488_bREQUEST_LOCAL_LOCKOUT: + TU_VERIFY(false); + return false; +#endif + + default: + TU_VERIFY(false); + } + TU_VERIFY(false); +} + +bool usbtmcd_control_complete(uint8_t rhport, tusb_control_request_t const * request) +{ + (void)rhport; + //------------- Class Specific Request -------------// + TU_VERIFY (request->bmRequestType_bit.type == TUSB_REQ_TYPE_CLASS); + + return true; +} + +#endif /* CFG_TUD_TSMC */ diff --git a/src/class/usbtmc/usbtmc_device.h b/src/class/usbtmc/usbtmc_device.h new file mode 100644 index 000000000..c03ca9461 --- /dev/null +++ b/src/class/usbtmc/usbtmc_device.h @@ -0,0 +1,130 @@ +/* + * usbtmc_device.h + * + * Created on: Sep 10, 2019 + * Author: nconrad + */ +/* + * The MIT License (MIT) + * + * Copyright (c) 2019 N Conrad + * + * 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. + */ + + +#ifndef CLASS_USBTMC_USBTMC_DEVICE_H_ +#define CLASS_USBTMC_USBTMC_DEVICE_H_ + +#include "usbtmc.h" + +// Enable 488 mode by default +#if !defined(USBTMC_CFG_ENABLE_488) +#define USBTMC_CFG_ENABLE_488 (1) +#endif + +// USB spec says that full-speed must be 8,16,32, or 64. +// However, this driver implementation requires it to be >=32 +#define USBTMCD_MAX_PACKET_SIZE (64u) + +/*********************************************** + * Functions to be implemeted by the class implementation + */ + +#if (USBTMC_CFG_ENABLE_488) +extern usbtmc_response_capabilities_488_t const usbtmcd_app_capabilities; +#else +extern usbtmc_response_capabilities_t const usbtmcd_app_capabilities; +#endif + +bool usbtmcd_app_msgBulkOut_start(usbtmc_msg_request_dev_dep_out const * msgHeader); + +// transfer_complete does not imply that a message is complete. +bool usbtmcd_app_msg_data(void *data, size_t len, bool transfer_complete); + +bool usbtmcd_app_msgBulkIn_request(uint8_t rhport, usbtmc_msg_request_dev_dep_in const * request); + +bool usbtmcd_app_msgBulkIn_complete(uint8_t rhport); + +#if (USBTMC_CFG_ENABLE_488) +uint8_t usbtmcd_app_get_stb(uint8_t rhport, uint8_t *rspResult); + +//TU_ATTR_WEAK bool usbtmcd_app_go_to_local(uint8_t rhport); +#endif + +/******************************************* + * Called from app + * + * We keep a reference to the buffer, so it MUST not change until the app is + * notified that the transfer is complete. + ******************************************/ + +bool usbtmcd_transmit_dev_msg_data( + uint8_t rhport, + usbtmc_msg_dev_dep_msg_in_header_t const * hdr, + const void *data); + + +/* "callbacks" from USB device core */ + +bool usbtmcd_open(uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint16_t *p_length); +void usbtmcd_reset(uint8_t rhport); +bool usbtmcd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes); +bool usbtmcd_control_request(uint8_t rhport, tusb_control_request_t const * request); +bool usbtmcd_control_complete(uint8_t rhport, tusb_control_request_t const * request); +void usbtmcd_init(void); + +/************************************************************ + * USBTMC Descriptor Templates + *************************************************************/ + +#define USBTMC_APP_CLASS TUSB_CLASS_APPLICATION_SPECIFIC +#define USBTMC_APP_SUBCLASS 0x03 + +#define USBTMC_PROTOCOL_STD 0x00 +#define USBTMC_PROTOCOL_USB488 0x01 + +// Interface number, number of endpoints, EP string index, USB_TMC_PROTOCOL*, bulk-out endpoint ID, +// bulk-in endpoint ID +#define USBTMC_IF_DESCRIPTOR(_itfnum, _bNumEndpoints, _stridx, _itfProtocol) \ +/* Interface */ \ + 0x09, TUSB_DESC_INTERFACE, _itfnum, 0x00, _bNumEndpoints, USBTMC_APP_CLASS, USBTMC_APP_SUBCLASS, _itfProtocol, _stridx + +#define USBTMC_IF_DESCRIPTOR_LEN 9u + +// bulk-out Size must be a multiple of 4 bytes +#define USBTMC_BULK_DESCRIPTORS(_epout, _epin) \ +/* Endpoint Out */ \ +7, TUSB_DESC_ENDPOINT, _epout, TUSB_XFER_BULK, U16_TO_U8S_LE(USBTMCD_MAX_PACKET_SIZE), 0u, \ +/* Endpoint In */ \ +7, TUSB_DESC_ENDPOINT, _epin, TUSB_XFER_BULK, U16_TO_U8S_LE(USBTMCD_MAX_PACKET_SIZE), 0u + +#define USBTMC_BULK_DESCRIPTORS_LEN (7u+7u) + +/* optional interrupt endpoint */ \ +// _int_pollingInterval : for LS/FS, expressed in frames (1ms each). 16 may be a good number? +#define USBTMC_INT_DESCRIPTOR(_ep_interrupt, _ep_interrupt_size, _int_pollingInterval ) \ +7, TUSB_DESC_ENDPOINT, _ep_interrupt, TUSB_XFER_INTERRUPT, U16_TO_U8S_LE(_ep_interrupt_size), 0x16 + +#define USBTMC_INT_DESCRIPTOR_LEN (7u) + + +#endif /* CLASS_USBTMC_USBTMC_DEVICE_H_ */ diff --git a/src/device/usbd.c b/src/device/usbd.c index c92884334..572708f7d 100644 --- a/src/device/usbd.c +++ b/src/device/usbd.c @@ -145,6 +145,22 @@ static usbd_class_driver_t const usbd_class_drivers[] = .sof = NULL }, #endif + + #if CFG_TUD_USBTMC + // Presently USBTMC is the only defined class with the APP_SPECIFIC class code. + // We maybe need to add subclass codes here, or a callback to ask if a driver can + // handle a particular interface. + { + .class_code = TUSB_CLASS_APPLICATION_SPECIFIC, + .init = usbtmcd_init, + .reset = usbtmcd_reset, + .open = usbtmcd_open, + .control_request = usbtmcd_control_request, + .control_complete = usbtmcd_control_complete, + .xfer_cb = usbtmcd_xfer_cb, + .sof = NULL + }, + #endif }; enum { USBD_CLASS_DRIVER_COUNT = TU_ARRAY_SIZE(usbd_class_drivers) }; diff --git a/src/tusb.h b/src/tusb.h index fe8673726..1a6ff0b10 100644 --- a/src/tusb.h +++ b/src/tusb.h @@ -83,6 +83,10 @@ #if CFG_TUD_VENDOR #include "class/vendor/vendor_device.h" #endif + + #if CFG_TUD_USBTMC + #include "class/usbtmc/usbtmc_device.h" + #endif #endif diff --git a/src/tusb_option.h b/src/tusb_option.h index 9aacb558f..76ea59758 100644 --- a/src/tusb_option.h +++ b/src/tusb_option.h @@ -181,6 +181,10 @@ #define CFG_TUD_VENDOR 0 #endif +#ifndef CFG_TUD_USBTMC + #define CFG_TUD_USBTMC 0 +#endif + //-------------------------------------------------------------------- // HOST OPTIONS -- cgit v1.3.1 From e74c6b0874a54b86fee61692484e0407d6a97508 Mon Sep 17 00:00:00 2001 From: Nathan Conrad Date: Sat, 14 Sep 2019 15:38:11 -0400 Subject: Combined status response enum (std with 488), support trigger. --- src/class/usbtmc/usbtmc.h | 6 ++-- src/class/usbtmc/usbtmc_device.c | 63 +++++++++++++++++++++++++++------------- src/class/usbtmc/usbtmc_device.h | 8 ++--- 3 files changed, 50 insertions(+), 27 deletions(-) (limited to 'src') diff --git a/src/class/usbtmc/usbtmc.h b/src/class/usbtmc/usbtmc.h index 846c0e38d..ecc16a315 100644 --- a/src/class/usbtmc/usbtmc.h +++ b/src/class/usbtmc/usbtmc.h @@ -160,14 +160,14 @@ typedef enum { USBTMC_bREQUEST_GET_CAPABILITIES = 7u, USBTMC_bREQUEST_INDICATOR_PULSE = 64u, // Optional -} usmtmc_request_type_enum; -typedef enum { + /****** USBTMC 488 *************/ USBTMC488_bREQUEST_READ_STATUS_BYTE = 128u, USBTMC488_bREQUEST_REN_CONTROL = 160u, USBTMC488_bREQUEST_GO_TO_LOCAL = 161u, USBTMC488_bREQUEST_LOCAL_LOCKOUT = 162u, -} usbtmc_request_type_488_enum; + +} usmtmc_request_type_enum; typedef enum { USBTMC_STATUS_SUCCESS = 0x01, diff --git a/src/class/usbtmc/usbtmc_device.c b/src/class/usbtmc/usbtmc_device.c index 4bb21f354..25f943598 100644 --- a/src/class/usbtmc/usbtmc_device.c +++ b/src/class/usbtmc/usbtmc_device.c @@ -97,6 +97,10 @@ static usbtmc_interface_state_t usbtmc_state = // I'm not sure if this is really necessary, though. TU_VERIFY_STATIC(USBTMCD_MAX_PACKET_SIZE >= 32u,"USBTMC dev EP packet size too small"); + +static bool handle_devMsgOutStart(uint8_t rhport, void *data, size_t len); +static bool handle_devMsgOut(uint8_t rhport, void *data, size_t len, size_t packetLen); + // called from app // We keep a reference to the buffer, so it MUST not change until the app is // notified that the transfer is complete. @@ -140,7 +144,10 @@ bool usbtmcd_transmit_dev_msg_data( void usbtmcd_init(void) { - +#if USBTMC_CFG_ENABLE_488 + if(usbtmcd_app_capabilities.bmIntfcCapabilities488.supportsTrigger) + TU_ASSERT(usbtmcd_app_msg_trigger != NULL,); +#endif } bool usbtmcd_open(uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint16_t *p_length) @@ -213,32 +220,39 @@ void usbtmcd_reset(uint8_t rhport) // FIXME: Do endpoints need to be closed here? (void)rhport; } -static bool handle_devMsgOut(uint8_t rhport, void *data, size_t len) + +static bool handle_devMsgOutStart(uint8_t rhport, void *data, size_t len) { (void)rhport; - bool shortPacket = (len < USBTMCD_MAX_PACKET_SIZE); - if(usbtmc_state.state == STATE_IDLE) - { - // must be a header, should have been confirmed before calling here. - usbtmc_msg_request_dev_dep_out *msg = (usbtmc_msg_request_dev_dep_out*)data; - usbtmc_state.transfer_size_remaining = msg->TransferSize; - TU_VERIFY(usbtmcd_app_msgBulkOut_start(msg)); - len -= sizeof(*msg); - data = (uint8_t*)data + sizeof(*msg); - } + TU_VERIFY(usbtmc_state.state == STATE_IDLE); + // must be a header, should have been confirmed before calling here. + usbtmc_msg_request_dev_dep_out *msg = (usbtmc_msg_request_dev_dep_out*)data; + usbtmc_state.transfer_size_remaining = msg->TransferSize; + TU_VERIFY(usbtmcd_app_msgBulkOut_start(rhport,msg)); + + TU_VERIFY(handle_devMsgOut(rhport, (uint8_t*)data + sizeof(*msg), len - sizeof(*msg), len)); + return true; +} + +static bool handle_devMsgOut(uint8_t rhport, void *data, size_t len, size_t packetLen) +{ + (void)rhport; + bool shortPacket = (packetLen < USBTMCD_MAX_PACKET_SIZE); + // Packet is to be considered complete when we get enough data or at a short packet. bool atEnd = false; if(len >= usbtmc_state.transfer_size_remaining || shortPacket) atEnd = true; if(len > usbtmc_state.transfer_size_remaining) len = usbtmc_state.transfer_size_remaining; - usbtmcd_app_msg_data(data, len, atEnd); + usbtmcd_app_msg_data(rhport,data, len, atEnd); if(atEnd) usbtmc_state.state = STATE_IDLE; else usbtmc_state.state = STATE_RCV; return true; } + static bool handle_devMsgIn(uint8_t rhport, void *data, size_t len) { TU_VERIFY(len == sizeof(usbtmc_msg_request_dev_dep_in)); @@ -267,25 +281,34 @@ bool usbtmcd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint switch(msg->header.MsgID) { case USBTMC_MSGID_DEV_DEP_MSG_OUT: - TU_VERIFY(handle_devMsgOut(rhport, msg, xferred_bytes)); - TU_VERIFY(usbd_edpt_xfer(rhport, usbtmc_state.ep_bulk_out, usbtmc_state.ep_bulk_out_buf, 64)); + TU_VERIFY(handle_devMsgOutStart(rhport, msg, xferred_bytes)); + TU_VERIFY(usbd_edpt_xfer(rhport, usbtmc_state.ep_bulk_out, usbtmc_state.ep_bulk_out_buf, USBTMCD_MAX_PACKET_SIZE)); break; + case USBTMC_MSGID_DEV_DEP_MSG_IN: TU_VERIFY(handle_devMsgIn(rhport, msg, xferred_bytes)); break; + +#ifdef USBTMC_CFG_ENABLE_488 + case USBTMC_MSGID_USB488_TRIGGER: + // Spec says we halt the EP if we didn't declare we support it. + TU_VERIFY(usbtmcd_app_capabilities.bmIntfcCapabilities488.supportsTrigger); + TU_VERIFY(usbtmcd_app_msg_trigger(rhport, msg)); + TU_VERIFY(usbd_edpt_xfer(rhport, usbtmc_state.ep_bulk_out, usbtmc_state.ep_bulk_out_buf, USBTMCD_MAX_PACKET_SIZE)); + + break; +#endif case USBTMC_MSGID_VENDOR_SPECIFIC_MSG_OUT: case USBTMC_MSGID_VENDOR_SPECIFIC_IN: - case USBTMC_MSGID_USB488_TRIGGER: default: TU_VERIFY(false); + return false; } return true; case STATE_RCV: - TU_VERIFY(handle_devMsgOut(rhport, usbtmc_state.ep_bulk_out_buf, xferred_bytes)); - TU_VERIFY( usbd_edpt_xfer(rhport, usbtmc_state.ep_bulk_out, usbtmc_state.ep_bulk_out_buf, 64)); + TU_VERIFY(handle_devMsgOut(rhport, usbtmc_state.ep_bulk_out_buf, xferred_bytes, xferred_bytes)); return true; - break; default: TU_VERIFY(false); @@ -298,7 +321,7 @@ bool usbtmcd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint { usbtmc_state.state = STATE_IDLE; TU_VERIFY(usbtmcd_app_msgBulkIn_complete(rhport)); - TU_VERIFY( usbd_edpt_xfer(rhport, usbtmc_state.ep_bulk_out, usbtmc_state.ep_bulk_out_buf, 64)); + TU_VERIFY( usbd_edpt_xfer(rhport, usbtmc_state.ep_bulk_out, usbtmc_state.ep_bulk_out_buf, USBTMCD_MAX_PACKET_SIZE)); } else if(usbtmc_state.transfer_size_remaining >= USBTMCD_MAX_PACKET_SIZE) { diff --git a/src/class/usbtmc/usbtmc_device.h b/src/class/usbtmc/usbtmc_device.h index c03ca9461..1246d11d1 100644 --- a/src/class/usbtmc/usbtmc_device.h +++ b/src/class/usbtmc/usbtmc_device.h @@ -55,18 +55,18 @@ extern usbtmc_response_capabilities_488_t const usbtmcd_app_capabilities; extern usbtmc_response_capabilities_t const usbtmcd_app_capabilities; #endif -bool usbtmcd_app_msgBulkOut_start(usbtmc_msg_request_dev_dep_out const * msgHeader); +bool usbtmcd_app_msgBulkOut_start(uint8_t rhport, usbtmc_msg_request_dev_dep_out const * msgHeader); // transfer_complete does not imply that a message is complete. -bool usbtmcd_app_msg_data(void *data, size_t len, bool transfer_complete); +bool usbtmcd_app_msg_data(uint8_t rhport, void *data, size_t len, bool transfer_complete); bool usbtmcd_app_msgBulkIn_request(uint8_t rhport, usbtmc_msg_request_dev_dep_in const * request); bool usbtmcd_app_msgBulkIn_complete(uint8_t rhport); #if (USBTMC_CFG_ENABLE_488) -uint8_t usbtmcd_app_get_stb(uint8_t rhport, uint8_t *rspResult); - +uint8_t usbtmcd_app_get_stb(uint8_t rhport, usbtmc_status_enum *rspResult); +TU_ATTR_WEAK bool usbtmcd_app_msg_trigger(uint8_t rhport, usbtmc_msg_generic_t* msg); //TU_ATTR_WEAK bool usbtmcd_app_go_to_local(uint8_t rhport); #endif -- cgit v1.3.1 From 6e00886ffbbc552cf91be73d57fe8ad0a4842d0b Mon Sep 17 00:00:00 2001 From: Nathan Conrad Date: Sat, 14 Sep 2019 17:15:34 -0400 Subject: Handle USBTMC TermChar. --- src/class/usbtmc/usbtmc_device.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) (limited to 'src') diff --git a/src/class/usbtmc/usbtmc_device.c b/src/class/usbtmc/usbtmc_device.c index 25f943598..909f8251f 100644 --- a/src/class/usbtmc/usbtmc_device.c +++ b/src/class/usbtmc/usbtmc_device.c @@ -61,6 +61,9 @@ // FIXME: I shouldn't need to include _pvt headers. #include "device/usbd_pvt.h" +static uint8_t termChar; +static uint8_t termCharRequested = false; + typedef enum { STATE_IDLE, @@ -113,6 +116,13 @@ bool usbtmcd_transmit_dev_msg_data( TU_ASSERT(usbtmc_state.state == STATE_TX_REQUESTED); TU_ASSERT(hdr->TransferSize > 0u); + if(hdr->bmTransferAttributes.UsingTermChar) + { + TU_ASSERT(usbtmcd_app_capabilities.bmDevCapabilities.canEndBulkInOnTermChar); + TU_ASSERT(termCharRequested); + TU_ASSERT(((uint8_t*)data)[hdr->TransferSize-1] == termChar); + } + // Copy in the header memcpy(usbtmc_state.ep_bulk_in_buf, hdr, sizeof(*hdr)); uint packetLen = sizeof(*hdr); @@ -260,6 +270,12 @@ static bool handle_devMsgIn(uint8_t rhport, void *data, size_t len) TU_VERIFY(usbtmc_state.state == STATE_IDLE); usbtmc_state.state = STATE_TX_REQUESTED; usbtmc_state.transfer_size_remaining = msg->TransferSize; + + termCharRequested = msg->bmTransferAttributes.TermCharEnabled; + termChar = msg->TermChar; + if(termCharRequested) + TU_VERIFY(usbtmcd_app_capabilities.bmDevCapabilities.canEndBulkInOnTermChar); + TU_VERIFY(usbtmcd_app_msgBulkIn_request(rhport, msg)); return true; } @@ -310,6 +326,8 @@ bool usbtmcd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint TU_VERIFY(handle_devMsgOut(rhport, usbtmc_state.ep_bulk_out_buf, xferred_bytes, xferred_bytes)); return true; + case STATE_TX_REQUESTED: + case STATE_TX_INITIATED: default: TU_VERIFY(false); } -- cgit v1.3.1 From 64bfec79b2d1d75b5c06be2dc2fff83ee385a720 Mon Sep 17 00:00:00 2001 From: Nathan Conrad Date: Sat, 14 Sep 2019 18:07:12 -0400 Subject: Change requset type parameter back to uint8_t (fix type cast), support USB indicator pulse --- examples/device/usbtmc/src/main.c | 47 ++++++++++++++++++++++++++------- examples/device/usbtmc/src/main.h | 5 ++++ examples/device/usbtmc/src/usbtmc_app.c | 13 ++++++--- src/class/usbtmc/usbtmc_device.c | 21 +++++++++------ src/class/usbtmc/usbtmc_device.h | 4 ++- 5 files changed, 68 insertions(+), 22 deletions(-) create mode 100644 examples/device/usbtmc/src/main.h (limited to 'src') diff --git a/examples/device/usbtmc/src/main.c b/examples/device/usbtmc/src/main.c index 0293261ad..8bc2a8398 100644 --- a/examples/device/usbtmc/src/main.c +++ b/examples/device/usbtmc/src/main.c @@ -36,12 +36,12 @@ /* Blink pattern * - 250 ms : device not mounted - * - 1000 ms : device mounted + * - 0 ms : device mounted * - 2500 ms : device is suspended */ enum { BLINK_NOT_MOUNTED = 250, - BLINK_MOUNTED = 1000, + BLINK_MOUNTED = 0, BLINK_SUSPENDED = 2500, }; @@ -97,17 +97,46 @@ void tud_resume_cb(void) } //--------------------------------------------------------------------+ -// BLINKING TASK +// BLINKING TASK + Indicator pulse //--------------------------------------------------------------------+ + + +volatile uint8_t doPulse = false; +// called from USB context +void led_indicator_pulse(void) { + doPulse = true; +} + void led_blinking_task(void) { static uint32_t start_ms = 0; static bool led_state = false; + if(blink_interval_ms == BLINK_MOUNTED) // Mounted + { + if(doPulse) + { + led_state = true; + board_led_write(true); + start_ms = board_millis(); + doPulse = false; + } + else if (led_state == true) + { + if ( board_millis() - start_ms < 750) //Spec says blink must be between 500 and 1000 ms. + { + return; // not enough time + } + led_state = false; + board_led_write(false); + } + } + else + { + // Blink every interval ms + if ( board_millis() - start_ms < blink_interval_ms) return; // not enough time + start_ms += blink_interval_ms; - // Blink every interval ms - if ( board_millis() - start_ms < blink_interval_ms) return; // not enough time - start_ms += blink_interval_ms; - - board_led_write(led_state); - led_state = 1 - led_state; // toggle + board_led_write(led_state); + led_state = 1 - led_state; // toggle + } } diff --git a/examples/device/usbtmc/src/main.h b/examples/device/usbtmc/src/main.h new file mode 100644 index 000000000..673247ec7 --- /dev/null +++ b/examples/device/usbtmc/src/main.h @@ -0,0 +1,5 @@ +#ifndef MAIN_H +#define MAIN_H +void led_indicator_pulse(void); + +#endif diff --git a/examples/device/usbtmc/src/usbtmc_app.c b/examples/device/usbtmc/src/usbtmc_app.c index 4ec6ad90c..6b72bb360 100644 --- a/examples/device/usbtmc/src/usbtmc_app.c +++ b/examples/device/usbtmc/src/usbtmc_app.c @@ -25,6 +25,7 @@ #include #include "class/usbtmc/usbtmc_device.h" +#include "main.h" #if (USBTMC_CFG_ENABLE_488) usbtmc_response_capabilities_488_t const @@ -39,7 +40,7 @@ usbtmcd_app_capabilities = { .listenOnly = 0, .talkOnly = 0, - .supportsIndicatorPulse = 0 + .supportsIndicatorPulse = 1 }, .bmDevCapabilities = { .canEndBulkInOnTermChar = 0 @@ -63,7 +64,7 @@ usbtmcd_app_capabilities = #endif }; -static const char idn[] = "TinyUSB,ModelNumber,SerialNumber,FirmwareVer"; +static const char idn[] = "TinyUSB,ModelNumber,SerialNumber,FirmwareVer\n"; static uint8_t status; static bool queryReceived = false; @@ -96,7 +97,7 @@ bool usbtmcd_app_msgBulkIn_complete(uint8_t rhport) return true; } -static uint8_t noQueryMsg[] = "ERR: No query"; +static uint8_t noQueryMsg[] = "ERR: No query\n"; bool usbtmcd_app_msgBulkIn_request(uint8_t rhport, usbtmc_msg_request_dev_dep_in const * request) { usbtmc_msg_dev_dep_msg_in_header_t hdr = { @@ -127,7 +128,7 @@ bool usbtmcd_app_msgBulkIn_request(uint8_t rhport, usbtmc_msg_request_dev_dep_in } // Return status byte, but put the transfer result status code in the rspResult argument. -uint8_t usbtmcd_app_get_stb(uint8_t rhport, usbtmc_status_enum *rspResult) +uint8_t usbtmcd_app_get_stb(uint8_t rhport, uint8_t *rspResult) { (void)rhport; *rspResult = USBTMC_STATUS_SUCCESS; @@ -137,3 +138,7 @@ uint8_t usbtmcd_app_get_stb(uint8_t rhport, usbtmc_status_enum *rspResult) return status; } +bool usbtmcd_app_indicator_pluse(uint8_t rhport, tusb_control_request_t const * msg) +{ + led_indicator_pulse(); +} diff --git a/src/class/usbtmc/usbtmc_device.c b/src/class/usbtmc/usbtmc_device.c index 909f8251f..7bc768a58 100644 --- a/src/class/usbtmc/usbtmc_device.c +++ b/src/class/usbtmc/usbtmc_device.c @@ -39,17 +39,18 @@ //Limitations (not planned to be implemented): // "vendor-specific" commands are not handled +// Dealing with "termchar" must be handled by the application layer, +// though additional error checking is does in this module. // TODO: // USBTMC 3.2.2 error conditions not strictly followed // No local lock-out, REN, or GTL. -// Cannot issue clear. -// No "capabilities" supported -// Interrupt-IN endpoint -// 488 MsgID=Trigger +// Cannot handle clear. +// Not all "capabilities" supported // Clear message available status byte at the correct time? (488 4.3.1.3) // Split transfers -// No CLEAR_FEATURE/HALT (yet) +// No CLEAR_FEATURE/HALT no EP (yet) +// No aborting transfers. #if (TUSB_OPT_DEVICE_ENABLED && CFG_TUD_USBTMC) @@ -156,8 +157,11 @@ void usbtmcd_init(void) { #if USBTMC_CFG_ENABLE_488 if(usbtmcd_app_capabilities.bmIntfcCapabilities488.supportsTrigger) - TU_ASSERT(usbtmcd_app_msg_trigger != NULL,); + TU_ASSERT(&usbtmcd_app_msg_trigger != NULL,); #endif + if(usbtmcd_app_capabilities.bmIntfcCapabilities.supportsIndicatorPulse) + TU_ASSERT(&usbtmcd_app_indicator_pluse != NULL,); + } bool usbtmcd_open(uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint16_t *p_length) @@ -400,8 +404,9 @@ bool usbtmcd_control_request(uint8_t rhport, tusb_control_request_t const * requ return true; // USBTMC Optional Requests case USBTMC_bREQUEST_INDICATOR_PULSE: // Optional - TU_VERIFY(false); - return false; + TU_VERIFY(usbtmcd_app_capabilities.bmIntfcCapabilities.supportsIndicatorPulse); + TU_VERIFY(usbtmcd_app_indicator_pluse(rhport, request)); + return true; #if (USBTMC_CFG_ENABLE_488) // USB488 required requests diff --git a/src/class/usbtmc/usbtmc_device.h b/src/class/usbtmc/usbtmc_device.h index 1246d11d1..09cda7c67 100644 --- a/src/class/usbtmc/usbtmc_device.h +++ b/src/class/usbtmc/usbtmc_device.h @@ -64,8 +64,10 @@ bool usbtmcd_app_msgBulkIn_request(uint8_t rhport, usbtmc_msg_request_dev_dep_in bool usbtmcd_app_msgBulkIn_complete(uint8_t rhport); +TU_ATTR_WEAK bool usbtmcd_app_indicator_pluse(uint8_t rhport, tusb_control_request_t const * msg); + #if (USBTMC_CFG_ENABLE_488) -uint8_t usbtmcd_app_get_stb(uint8_t rhport, usbtmc_status_enum *rspResult); +uint8_t usbtmcd_app_get_stb(uint8_t rhport, uint8_t *rspResult); TU_ATTR_WEAK bool usbtmcd_app_msg_trigger(uint8_t rhport, usbtmc_msg_generic_t* msg); //TU_ATTR_WEAK bool usbtmcd_app_go_to_local(uint8_t rhport); #endif -- cgit v1.3.1 From e53e9bd4f0749e53740c9c33e740998ac202dd8a Mon Sep 17 00:00:00 2001 From: Nathan Conrad Date: Sat, 14 Sep 2019 21:24:52 -0400 Subject: Simulate query delay; getting to a point where implementing clear/aborts makes sense. Probably adding too many concurance issues; need to figure out semaphores. --- examples/device/usbtmc/src/main.c | 3 +- examples/device/usbtmc/src/usb_descriptors.c | 6 +- examples/device/usbtmc/src/usbtmc_app.c | 91 ++++++++++++++++++++-------- examples/device/usbtmc/src/usbtmc_app.h | 7 +++ src/class/usbtmc/usbtmc_device.c | 20 +++++- src/class/usbtmc/usbtmc_device.h | 5 +- 6 files changed, 97 insertions(+), 35 deletions(-) create mode 100644 examples/device/usbtmc/src/usbtmc_app.h (limited to 'src') diff --git a/examples/device/usbtmc/src/main.c b/examples/device/usbtmc/src/main.c index 8bc2a8398..1fce48f45 100644 --- a/examples/device/usbtmc/src/main.c +++ b/examples/device/usbtmc/src/main.c @@ -29,7 +29,7 @@ #include "bsp/board.h" #include "tusb.h" - +#include "usbtmc_app.h" //--------------------------------------------------------------------+ // MACRO CONSTANT TYPEDEF PROTYPES //--------------------------------------------------------------------+ @@ -60,6 +60,7 @@ int main(void) { tud_task(); // tinyusb device task led_blinking_task(); + usbtmc_app_task_iter(); } return 0; diff --git a/examples/device/usbtmc/src/usb_descriptors.c b/examples/device/usbtmc/src/usb_descriptors.c index 296636359..9567bcab5 100644 --- a/examples/device/usbtmc/src/usb_descriptors.c +++ b/examples/device/usbtmc/src/usb_descriptors.c @@ -110,10 +110,10 @@ uint8_t const * tud_hid_descriptor_report_cb(void) USBTMC_BULK_DESCRIPTORS(/* OUT = */0x03, /* IN = */ 0x83) #if defined(CFG_TUD_USBTMC_ENABLE_INT_EP) - +// Interrupt endpoint should be 2 bytes on a FS USB link # define USBTMC_DESC(_itfnum) \ USBTMC_DESC_MAIN(_itfnum, /* _epCount = */ 3), \ - USBTMC_INT_DESCRIPTOR(/* INT ep # */ 0x84, /* epMaxSize = */ 64, /* bInterval = */16u ) + USBTMC_INT_DESCRIPTOR(/* INT ep # */ 0x84, /* epMaxSize = */ 2, /* bInterval = */16u ) # define USBTMC_DESC_LEN (USBTMC_IF_DESCRIPTOR_LEN + USBTMC_BULK_DESCRIPTORS_LEN + USBTMC_INT_DESCRIPTOR_LEN) #else @@ -248,7 +248,7 @@ uint16_t const* tud_descriptor_string_cb(uint8_t index) } // first byte is length (including header), second byte is string type - _desc_str[0] = (TUSB_DESC_STRING << 8 ) | (2*chr_count + 2); + _desc_str[0] = (((uint16_t)TUSB_DESC_STRING) << 8 ) | (2u*chr_count + 2u); return _desc_str; } diff --git a/examples/device/usbtmc/src/usbtmc_app.c b/examples/device/usbtmc/src/usbtmc_app.c index 6b72bb360..af97939b9 100644 --- a/examples/device/usbtmc/src/usbtmc_app.c +++ b/examples/device/usbtmc/src/usbtmc_app.c @@ -25,6 +25,7 @@ #include #include "class/usbtmc/usbtmc_device.h" +#include "bsp/board.h" #include "main.h" #if (USBTMC_CFG_ENABLE_488) @@ -65,9 +66,21 @@ usbtmcd_app_capabilities = }; static const char idn[] = "TinyUSB,ModelNumber,SerialNumber,FirmwareVer\n"; -static uint8_t status; -static bool queryReceived = false; +static volatile uint8_t status; +// 0=not query, 1=queried, 2=delay,set(MAV), 3=delay 4=ready? +// (to simulate delay) +static volatile uint16_t queryState = 0; +static volatile uint32_t queryDelayStart; +static volatile uint32_t bulkInStarted; + +static usbtmc_msg_dev_dep_msg_in_header_t rspMsg = { + .bmTransferAttributes = + { + .EOM = 1, + .UsingTermChar = 0 + } +}; bool usbtmcd_app_msgBulkOut_start(uint8_t rhport, usbtmc_msg_request_dev_dep_out const * msgHeader) { @@ -86,7 +99,7 @@ bool usbtmcd_app_msg_data(uint8_t rhport, void *data, size_t len, bool transfer_ (void)rhport; (void)transfer_complete; if(transfer_complete && (len >=4) && !strncasecmp("*idn?",data,4)) { - queryReceived = true; + queryState = 1; } return true; } @@ -98,47 +111,73 @@ bool usbtmcd_app_msgBulkIn_complete(uint8_t rhport) } static uint8_t noQueryMsg[] = "ERR: No query\n"; + bool usbtmcd_app_msgBulkIn_request(uint8_t rhport, usbtmc_msg_request_dev_dep_in const * request) { - usbtmc_msg_dev_dep_msg_in_header_t hdr = { - .header = - { - .MsgID = request->header.MsgID, - .bTag = request->header.bTag, - .bTagInverse = request->header.bTagInverse - }, - .TransferSize = sizeof(idn)-1, - .bmTransferAttributes = - { - .EOM = 1, - .UsingTermChar = 0 - } - }; - if(queryReceived) + rspMsg.header.MsgID = request->header.MsgID, + rspMsg.header.bTag = request->header.bTag, + rspMsg.header.bTagInverse = request->header.bTagInverse; + if(queryState != 0) { - usbtmcd_transmit_dev_msg_data(rhport, &hdr, idn); + TU_ASSERT(bulkInStarted == 0); + bulkInStarted = 1; } else { - hdr.TransferSize = sizeof(noQueryMsg)-1; - usbtmcd_transmit_dev_msg_data(rhport, &hdr, noQueryMsg); + rspMsg.TransferSize = sizeof(noQueryMsg)-1; + usbtmcd_transmit_dev_msg_data(rhport, &rspMsg, noQueryMsg); } - queryReceived = false; + // Always return true indicating not to stall the EP. return true; } +void usbtmc_app_task_iter(void) { + uint8_t const rhport = 0; + + switch(queryState) { + case 1: + queryDelayStart = board_millis(); + queryState = 2; + break; + case 2: + if( (board_millis() - queryDelayStart) > 1000u) { + queryDelayStart = board_millis(); + queryState=3; + status |= 0x10u; // MAV + } + break; + case 3: + if( (board_millis() - queryDelayStart) > 1000u) { + queryState = 4; + } + break; + case 4: // time to transmit; + if(bulkInStarted) { + queryState = 0; + bulkInStarted = 0; + rspMsg.TransferSize = sizeof(idn)-1; + usbtmcd_transmit_dev_msg_data(rhport, &rspMsg, idn); + status &= ~(0x10u); // MAV + } + break; + } +} + // Return status byte, but put the transfer result status code in the rspResult argument. -uint8_t usbtmcd_app_get_stb(uint8_t rhport, uint8_t *rspResult) +uint8_t usbtmcd_app_get_stb(uint8_t rhport, uint8_t *tmcResult) { (void)rhport; - *rspResult = USBTMC_STATUS_SUCCESS; + *tmcResult = USBTMC_STATUS_SUCCESS; // Increment status so that we see different results on each read... - status++; return status; } -bool usbtmcd_app_indicator_pluse(uint8_t rhport, tusb_control_request_t const * msg) +bool usbtmcd_app_indicator_pluse(uint8_t rhport, tusb_control_request_t const * msg, uint8_t *tmcResult) { + (void)rhport; + (void)msg; led_indicator_pulse(); + *tmcResult = USBTMC_STATUS_SUCCESS; + return true; } diff --git a/examples/device/usbtmc/src/usbtmc_app.h b/examples/device/usbtmc/src/usbtmc_app.h new file mode 100644 index 000000000..4de30c2ba --- /dev/null +++ b/examples/device/usbtmc/src/usbtmc_app.h @@ -0,0 +1,7 @@ + +#ifndef USBTMC_APP_H +#define USBTMC_APP_H + +void usbtmc_app_task_iter(void); + +#endif diff --git a/src/class/usbtmc/usbtmc_device.c b/src/class/usbtmc/usbtmc_device.c index 7bc768a58..db0c95a32 100644 --- a/src/class/usbtmc/usbtmc_device.c +++ b/src/class/usbtmc/usbtmc_device.c @@ -379,9 +379,11 @@ bool usbtmcd_control_request(uint8_t rhport, tusb_control_request_t const * requ #if (USBTMC_CFG_ENABLE_488) ushort bTag; #endif - // We only handle class requests. + // We only handle class requests, IN direction. if(request->bmRequestType_bit.type != TUSB_REQ_TYPE_CLASS) + { return false; + } switch(request->bRequest) { @@ -390,27 +392,38 @@ bool usbtmcd_control_request(uint8_t rhport, tusb_control_request_t const * requ case USBTMC_bREQUEST_CHECK_ABORT_BULK_OUT_STATUS: case USBTMC_bREQUEST_INITIATE_ABORT_BULK_IN: case USBTMC_bREQUEST_CHECK_ABORT_BULK_IN_STATUS: + TU_VERIFY(request->bmRequestType == 0xA2); // in,class,EP + TU_VERIFY(false); + break; + case USBTMC_bREQUEST_INITIATE_CLEAR: case USBTMC_bREQUEST_CHECK_CLEAR_STATUS: + TU_VERIFY(request->bmRequestType == 0xA1); // in,class,interface TU_VERIFY(false); break; case USBTMC_bREQUEST_GET_CAPABILITIES: - TU_VERIFY(request->bmRequestType == 0xA1); + TU_VERIFY(request->bmRequestType == 0xA1); // in,class,interface TU_VERIFY(request->wValue == 0x0000); TU_VERIFY(request->wIndex == usbtmc_state.itf_id); TU_VERIFY(request->wLength == sizeof(usbtmcd_app_capabilities)); TU_VERIFY(tud_control_xfer(rhport, request, (void*)&usbtmcd_app_capabilities, sizeof(usbtmcd_app_capabilities))); return true; // USBTMC Optional Requests + case USBTMC_bREQUEST_INDICATOR_PULSE: // Optional + TU_VERIFY(request->bmRequestType == 0xA1); // in,class,interface TU_VERIFY(usbtmcd_app_capabilities.bmIntfcCapabilities.supportsIndicatorPulse); - TU_VERIFY(usbtmcd_app_indicator_pluse(rhport, request)); + uint8_t tmcResult; + TU_VERIFY(usbtmcd_app_indicator_pluse(rhport, request, &tmcResult)); + TU_VERIFY(tud_control_xfer(rhport, request, (void*)&tmcResult, sizeof(tmcResult))); + return true; #if (USBTMC_CFG_ENABLE_488) // USB488 required requests case USBTMC488_bREQUEST_READ_STATUS_BYTE: + TU_VERIFY(request->bmRequestType == 0xA1); // in,class,interface bTag = request->wValue & 0x7F; TU_VERIFY(request->bmRequestType == 0xA1); @@ -444,6 +457,7 @@ bool usbtmcd_control_request(uint8_t rhport, tusb_control_request_t const * requ case USBTMC488_bREQUEST_REN_CONTROL: case USBTMC488_bREQUEST_GO_TO_LOCAL: case USBTMC488_bREQUEST_LOCAL_LOCKOUT: + TU_VERIFY(request->bmRequestType == 0xA1); // in,class,interface TU_VERIFY(false); return false; #endif diff --git a/src/class/usbtmc/usbtmc_device.h b/src/class/usbtmc/usbtmc_device.h index 09cda7c67..84640b136 100644 --- a/src/class/usbtmc/usbtmc_device.h +++ b/src/class/usbtmc/usbtmc_device.h @@ -64,10 +64,11 @@ bool usbtmcd_app_msgBulkIn_request(uint8_t rhport, usbtmc_msg_request_dev_dep_in bool usbtmcd_app_msgBulkIn_complete(uint8_t rhport); -TU_ATTR_WEAK bool usbtmcd_app_indicator_pluse(uint8_t rhport, tusb_control_request_t const * msg); +// Indicator pulse should be 0.5 to 1.0 seconds long +TU_ATTR_WEAK bool usbtmcd_app_indicator_pluse(uint8_t rhport, tusb_control_request_t const * msg, uint8_t *tmcResult); #if (USBTMC_CFG_ENABLE_488) -uint8_t usbtmcd_app_get_stb(uint8_t rhport, uint8_t *rspResult); +uint8_t usbtmcd_app_get_stb(uint8_t rhport, uint8_t *tmcResult); TU_ATTR_WEAK bool usbtmcd_app_msg_trigger(uint8_t rhport, usbtmc_msg_generic_t* msg); //TU_ATTR_WEAK bool usbtmcd_app_go_to_local(uint8_t rhport); #endif -- cgit v1.3.1 From 9593463367cca64acc7732013efdc634e84c2a81 Mon Sep 17 00:00:00 2001 From: Nathan Conrad Date: Sun, 15 Sep 2019 15:20:01 -0400 Subject: Massive copy&paste typo of mine in the 32-bit byte swapping function.... --- src/common/tusb_compiler.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/common/tusb_compiler.h b/src/common/tusb_compiler.h index ca294c20f..df0326afd 100644 --- a/src/common/tusb_compiler.h +++ b/src/common/tusb_compiler.h @@ -80,7 +80,7 @@ return __builtin_bswap16(u16); } - static inline uint16_t tu_bswap32(uint16_t u32) + static inline uint32_t tu_bswap32(uint32_t u32) { return __builtin_bswap32(u32); } @@ -108,7 +108,7 @@ return __builtin_bswap16(u16); } - static inline uint16_t tu_bswap32(uint16_t u32) + static inline uint32_t tu_bswap32(uint32_t u32) { return __builtin_bswap32(u32); } -- cgit v1.3.1 From ae873a709e21738fecba561e7d57a402f8bf3f2c Mon Sep 17 00:00:00 2001 From: Nathan Conrad Date: Sun, 15 Sep 2019 23:33:36 -0400 Subject: Wrote TX instead of RX. --- src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c index 96579c75b..6e46afdbb 100644 --- a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c +++ b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c @@ -595,7 +595,7 @@ bool dcd_edpt_open (uint8_t rhport, tusb_desc_endpoint_t const * p_endpoint_desc if(dir == TUSB_DIR_IN) { *PCD_EP_TX_ADDRESS_PTR(USB, epnum) = ep_buf_ptr; - PCD_SET_EP_RX_CNT(USB, epnum, p_endpoint_desc->wMaxPacketSize.size); + PCD_SET_EP_TX_CNT(USB, epnum, p_endpoint_desc->wMaxPacketSize.size); PCD_CLEAR_TX_DTOG(USB, epnum); PCD_SET_EP_TX_STATUS(USB,epnum,USB_EP_TX_NAK); } -- cgit v1.3.1 From 18303e742ee3c7897e28ce9960069e362dae38d2 Mon Sep 17 00:00:00 2001 From: Nathan Conrad Date: Sun, 15 Sep 2019 23:37:57 -0400 Subject: Covert macros to inline functions. --- .gitignore | 4 + src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c | 141 ++++++---- .../st/stm32_fsdev/dcd_stm32_fsdev_pvt_st.h | 310 ++++++++++++++------- 3 files changed, 290 insertions(+), 165 deletions(-) (limited to 'src') diff --git a/.gitignore b/.gitignore index 9864ea6be..772f5d8ee 100644 --- a/.gitignore +++ b/.gitignore @@ -15,3 +15,7 @@ latex test_old/ tests_obsolete/ _build +# coverity intermediate files +cov-int +# cppcheck build directories +*-build-dir diff --git a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c index 6e46afdbb..452c9a92e 100644 --- a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c +++ b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c @@ -147,7 +147,7 @@ * Checks, structs, defines, function definitions, etc. */ -TU_VERIFY_STATIC((MAX_EP_COUNT) <= STFSDEV_EP_COUNT,"Only 8 endpoints supported on the hardware"); +TU_VERIFY_STATIC((MAX_EP_COUNT) <= STFSDEV_EP_COUNT, "Only 8 endpoints supported on the hardware"); TU_VERIFY_STATIC(((DCD_STM32_BTABLE_BASE) + (DCD_STM32_BTABLE_LENGTH))<=(PMA_LENGTH), "BTABLE does not fit in PMA RAM"); @@ -166,8 +166,17 @@ typedef struct uint16_t queued_len; } xfer_ctl_t; -static xfer_ctl_t xfer_status[MAX_EP_COUNT][2]; -#define XFER_CTL_BASE(_epnum, _dir) &xfer_status[_epnum][_dir] +static xfer_ctl_t xfer_status[MAX_EP_COUNT][2]; + +static xfer_ctl_t* xfer_ctl_ptr(unsigned int epnum, unsigned int dir) +{ +#ifndef NDEBUG + TU_ASSERT(epnum < MAX_EP_COUNT); + TU_ASSERT(dir < 2u); +#endif + + return &xfer_status[epnum][dir]; +} static TU_ATTR_ALIGNED(4) uint32_t _setup_packet[6]; @@ -224,7 +233,7 @@ void dcd_init (uint8_t rhport) for(uint32_t i=0; iDADDR = USB_DADDR_EF; // Set enable flag, and leaving the device address as zero. - PCD_SET_EP_RX_STATUS(USB, 0, USB_EP_RX_VALID); // And start accepting SETUP on EP0 + pcd_set_ep_rx_status(USB, 0, USB_EP_RX_VALID); // And start accepting SETUP on EP0 } // FIXME: Defined to return uint16 so that ASSERT can be used, even though a return value is not needed. @@ -370,9 +379,9 @@ static uint16_t dcd_ep_ctr_handler(void) { /* DIR = 0 => IN int */ /* DIR = 0 implies that (EP_CTR_TX = 1) always */ - PCD_CLEAR_TX_EP_CTR(USB, 0); + pcd_clear_tx_ep_ctr(USB, 0); - xfer_ctl_t * xfer = XFER_CTL_BASE(EPindex,TUSB_DIR_IN); + xfer_ctl_t * xfer = xfer_ctl_ptr(EPindex,TUSB_DIR_IN); if((xfer->total_len == xfer->queued_len)) { @@ -386,7 +395,7 @@ static uint16_t dcd_ep_ctr_handler(void) } if(xfer->total_len == 0) // Probably a status message? { - PCD_CLEAR_RX_DTOG(USB,EPindex); + pcd_clear_rx_dtog(USB,EPindex); } } else @@ -399,10 +408,10 @@ static uint16_t dcd_ep_ctr_handler(void) /* DIR = 1 & CTR_RX => SETUP or OUT int */ /* DIR = 1 & (CTR_TX | CTR_RX) => 2 int pending */ - xfer_ctl_t *xfer = XFER_CTL_BASE(EPindex,TUSB_DIR_OUT); + xfer_ctl_t *xfer = xfer_ctl_ptr(EPindex,TUSB_DIR_OUT); //ep = &hpcd->OUT_ep[0]; - wEPVal = PCD_GET_ENDPOINT(USB, EPindex); + wEPVal = pcd_get_endpoint(USB, EPindex); if ((wEPVal & USB_EP_SETUP) != 0U) // SETUP { @@ -410,38 +419,38 @@ static uint16_t dcd_ep_ctr_handler(void) // user memory, to allow for the 32-bit access that memcpy performs. uint8_t userMemBuf[8]; /* Get SETUP Packet*/ - count = PCD_GET_EP_RX_CNT(USB, EPindex); + count = pcd_get_ep_rx_cnt(USB, EPindex); //TU_ASSERT_ERR(count == 8); - dcd_read_packet_memory(userMemBuf, *PCD_EP_RX_ADDRESS_PTR(USB,EPindex), 8); + dcd_read_packet_memory(userMemBuf, *pcd_ep_rx_address_ptr(USB,EPindex), 8); /* SETUP bit kept frozen while CTR_RX = 1*/ dcd_event_setup_received(0, (uint8_t*)userMemBuf, true); - PCD_CLEAR_RX_EP_CTR(USB, EPindex); + pcd_clear_rx_ep_ctr(USB, EPindex); } else if ((wEPVal & USB_EP_CTR_RX) != 0U) // OUT { - PCD_CLEAR_RX_EP_CTR(USB, EPindex); + pcd_clear_rx_ep_ctr(USB, EPindex); /* Get Control Data OUT Packet */ - count = PCD_GET_EP_RX_CNT(USB,EPindex); + count = pcd_get_ep_rx_cnt(USB,EPindex); if (count != 0U) { - dcd_read_packet_memory(xfer->buffer, *PCD_EP_RX_ADDRESS_PTR(USB,EPindex), count); + dcd_read_packet_memory(xfer->buffer, *pcd_ep_rx_address_ptr(USB,EPindex), count); xfer->queued_len = (uint16_t)(xfer->queued_len + count); } /* Process Control Data OUT status Packet*/ if(EPindex == 0u && xfer->total_len == 0u) { - PCD_CLEAR_EP_KIND(USB,0); // Good, so allow non-zero length packets now. + pcd_clear_ep_kind(USB,0); // Good, so allow non-zero length packets now. } dcd_event_xfer_complete(0, EPindex, xfer->total_len, XFER_RESULT_SUCCESS, true); - PCD_SET_EP_RX_CNT(USB, EPindex, CFG_TUD_ENDPOINT0_SIZE); + pcd_set_ep_rx_cnt(USB, EPindex, CFG_TUD_ENDPOINT0_SIZE); if(EPindex == 0u && xfer->total_len == 0u) { - PCD_SET_EP_RX_STATUS(USB, EPindex, USB_EP_RX_VALID);// Await next SETUP + pcd_set_ep_rx_status(USB, EPindex, USB_EP_RX_VALID);// Await next SETUP } } @@ -452,21 +461,21 @@ static uint16_t dcd_ep_ctr_handler(void) { /* process related endpoint register */ - wEPVal = PCD_GET_ENDPOINT(USB, EPindex); + wEPVal = pcd_get_endpoint(USB, EPindex); if ((wEPVal & USB_EP_CTR_RX) != 0U) // OUT { /* clear int flag */ - PCD_CLEAR_RX_EP_CTR(USB, EPindex); + pcd_clear_rx_ep_ctr(USB, EPindex); - xfer_ctl_t * xfer = XFER_CTL_BASE(EPindex,TUSB_DIR_OUT); + xfer_ctl_t * xfer = xfer_ctl_ptr(EPindex,TUSB_DIR_OUT); //ep = &hpcd->OUT_ep[EPindex]; - count = PCD_GET_EP_RX_CNT(USB, EPindex); + count = pcd_get_ep_rx_cnt(USB, EPindex); if (count != 0U) { dcd_read_packet_memory(&(xfer->buffer[xfer->queued_len]), - *PCD_EP_RX_ADDRESS_PTR(USB,EPindex), count); + *pcd_ep_rx_address_ptr(USB,EPindex), count); } /*multi-packet on the NON control OUT endpoint */ @@ -483,12 +492,12 @@ static uint16_t dcd_ep_ctr_handler(void) { uint16_t remaining = (uint16_t)(xfer->total_len - xfer->queued_len); if(remaining >=64) { - PCD_SET_EP_RX_CNT(USB, EPindex,64); + pcd_set_ep_rx_cnt(USB, EPindex,64); } else { - PCD_SET_EP_RX_CNT(USB, EPindex,remaining); + pcd_set_ep_rx_cnt(USB, EPindex,remaining); } - PCD_SET_EP_RX_STATUS(USB, EPindex, USB_EP_RX_VALID); + pcd_set_ep_rx_status(USB, EPindex, USB_EP_RX_VALID); } } /* if((wEPVal & EP_CTR_RX) */ @@ -496,9 +505,9 @@ static uint16_t dcd_ep_ctr_handler(void) if ((wEPVal & USB_EP_CTR_TX) != 0U) // IN { /* clear int flag */ - PCD_CLEAR_TX_EP_CTR(USB, EPindex); + pcd_clear_tx_ep_ctr(USB, EPindex); - xfer_ctl_t * xfer = XFER_CTL_BASE(EPindex,TUSB_DIR_IN); + xfer_ctl_t * xfer = xfer_ctl_ptr(EPindex,TUSB_DIR_IN); if (xfer->queued_len != xfer->total_len) // data remaining in transfer? { @@ -578,33 +587,43 @@ bool dcd_edpt_open (uint8_t rhport, tusb_desc_endpoint_t const * p_endpoint_desc // Set type switch(p_endpoint_desc->bmAttributes.xfer) { case TUSB_XFER_CONTROL: - PCD_SET_EPTYPE(USB, epnum, USB_EP_CONTROL); break; - case TUSB_XFER_ISOCHRONOUS: - PCD_SET_EPTYPE(USB, epnum, USB_EP_ISOCHRONOUS); break; + pcd_set_eptype(USB, epnum, USB_EP_CONTROL); + break; +#if (0) + case TUSB_XFER_ISOCHRONOUS: // FIXME: Not yet supported + pcd_set_eptype(USB, epnum, USB_EP_ISOCHRONOUS); break; + break; +#endif + case TUSB_XFER_BULK: - PCD_SET_EPTYPE(USB, epnum, USB_EP_BULK); break; + pcd_set_eptype(USB, epnum, USB_EP_BULK); + break; + case TUSB_XFER_INTERRUPT: - PCD_SET_EPTYPE(USB, epnum, USB_EP_INTERRUPT); break; + pcd_set_eptype(USB, epnum, USB_EP_INTERRUPT); + break; + default: TU_ASSERT(false); + return false; } - PCD_SET_EP_ADDRESS(USB, epnum, epnum); - PCD_CLEAR_EP_KIND(USB,0); // Be normal, for now, instead of only accepting zero-byte packets + pcd_set_ep_address(USB, epnum, epnum); + pcd_clear_ep_kind(USB,0); // Be normal, for now, instead of only accepting zero-byte packets if(dir == TUSB_DIR_IN) { - *PCD_EP_TX_ADDRESS_PTR(USB, epnum) = ep_buf_ptr; - PCD_SET_EP_TX_CNT(USB, epnum, p_endpoint_desc->wMaxPacketSize.size); - PCD_CLEAR_TX_DTOG(USB, epnum); - PCD_SET_EP_TX_STATUS(USB,epnum,USB_EP_TX_NAK); + *pcd_ep_tx_address_ptr(USB, epnum) = ep_buf_ptr; + pcd_set_ep_tx_cnt(USB, epnum, p_endpoint_desc->wMaxPacketSize.size); + pcd_clear_tx_dtog(USB, epnum); + pcd_set_ep_tx_status(USB,epnum,USB_EP_TX_NAK); } else { - *PCD_EP_RX_ADDRESS_PTR(USB, epnum) = ep_buf_ptr; - PCD_SET_EP_RX_CNT(USB, epnum, p_endpoint_desc->wMaxPacketSize.size); - PCD_CLEAR_RX_DTOG(USB, epnum); - PCD_SET_EP_RX_STATUS(USB, epnum, USB_EP_RX_NAK); + *pcd_ep_rx_address_ptr(USB, epnum) = ep_buf_ptr; + pcd_set_ep_rx_cnt(USB, epnum, p_endpoint_desc->wMaxPacketSize.size); + pcd_clear_rx_dtog(USB, epnum); + pcd_set_ep_rx_status(USB, epnum, USB_EP_RX_NAK); } ep_buf_ptr = (uint16_t)(ep_buf_ptr + p_endpoint_desc->wMaxPacketSize.size); // increment buffer pointer @@ -622,11 +641,11 @@ static void dcd_transmit_packet(xfer_ctl_t * xfer, uint16_t ep_ix) { len = 64u; } - dcd_write_packet_memory(*PCD_EP_TX_ADDRESS_PTR(USB,ep_ix), &(xfer->buffer[xfer->queued_len]), len); + dcd_write_packet_memory(*pcd_ep_tx_address_ptr(USB,ep_ix), &(xfer->buffer[xfer->queued_len]), len); xfer->queued_len = (uint16_t)(xfer->queued_len + len); - PCD_SET_EP_TX_CNT(USB,ep_ix,len); - PCD_SET_EP_TX_STATUS(USB, ep_ix, USB_EP_TX_VALID); + pcd_set_ep_tx_cnt(USB,ep_ix,len); + pcd_set_ep_tx_status(USB, ep_ix, USB_EP_TX_VALID); } bool dcd_edpt_xfer (uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t total_bytes) @@ -636,7 +655,7 @@ bool dcd_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); - xfer_ctl_t * xfer = XFER_CTL_BASE(epnum,dir); + xfer_ctl_t * xfer = xfer_ctl_ptr(epnum,dir); xfer->buffer = buffer; xfer->total_len = total_bytes; @@ -649,15 +668,15 @@ bool dcd_edpt_xfer (uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t if (epnum == 0 && buffer == NULL) { xfer->buffer = (uint8_t*)_setup_packet; - PCD_SET_EP_KIND(USB,0); // Expect a zero-byte INPUT + pcd_set_ep_kind(USB,0); // Expect a zero-byte INPUT } if(total_bytes > 64) { - PCD_SET_EP_RX_CNT(USB,epnum,64); + pcd_set_ep_rx_cnt(USB,epnum,64); } else { - PCD_SET_EP_RX_CNT(USB,epnum,total_bytes); + pcd_set_ep_rx_cnt(USB,epnum,total_bytes); } - PCD_SET_EP_RX_STATUS(USB, epnum, USB_EP_RX_VALID); + pcd_set_ep_rx_status(USB, epnum, USB_EP_RX_VALID); } else // IN { @@ -671,14 +690,14 @@ void dcd_edpt_stall (uint8_t rhport, uint8_t ep_addr) (void)rhport; if (ep_addr == 0) { // CTRL EP0 (OUT for setup) - PCD_SET_EP_TX_STATUS(USB,ep_addr, USB_EP_TX_STALL); + pcd_set_ep_tx_status(USB,ep_addr, USB_EP_TX_STALL); } if (ep_addr & 0x80) { // IN ep_addr &= 0x7F; - PCD_SET_EP_TX_STATUS(USB,ep_addr, USB_EP_TX_STALL); + pcd_set_ep_tx_status(USB,ep_addr, USB_EP_TX_STALL); } else { // OUT - PCD_SET_EP_RX_STATUS(USB,ep_addr, USB_EP_RX_STALL); + pcd_set_ep_rx_status(USB,ep_addr, USB_EP_RX_STALL); } } @@ -687,24 +706,24 @@ void dcd_edpt_clear_stall (uint8_t rhport, uint8_t ep_addr) (void)rhport; if (ep_addr == 0) { - PCD_SET_EP_TX_STATUS(USB,ep_addr, USB_EP_TX_NAK); + pcd_set_ep_tx_status(USB,ep_addr, USB_EP_TX_NAK); } if (ep_addr & 0x80) { // IN ep_addr &= 0x7F; - PCD_SET_EP_TX_STATUS(USB,ep_addr, USB_EP_TX_NAK); + pcd_set_ep_tx_status(USB,ep_addr, USB_EP_TX_NAK); /* Reset to DATA0 if clearing stall condition. */ - PCD_CLEAR_TX_DTOG(USB,ep_addr); + pcd_clear_tx_dtog(USB,ep_addr); } else { // OUT /* Reset to DATA0 if clearing stall condition. */ - PCD_CLEAR_RX_DTOG(USB,ep_addr); + pcd_clear_rx_dtog(USB,ep_addr); - PCD_SET_EP_RX_STATUS(USB,ep_addr, USB_EP_RX_VALID); + pcd_set_ep_rx_status(USB,ep_addr, USB_EP_RX_VALID); } } diff --git a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev_pvt_st.h b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev_pvt_st.h index 586d94abf..2b9de4440 100644 --- a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev_pvt_st.h +++ b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev_pvt_st.h @@ -83,9 +83,9 @@ // For purposes of accessing the packet #if ((PMA_LENGTH) == 512u) -# define PMA_STRIDE (2u) +const size_t PMA_STRIDE = 2u; #elif ((PMA_LENGTH) == 1024u) -# define PMA_STRIDE (1u) +const size_t PMA_STRIDE = 1u; #endif // And for type-safety create a new macro for the volatile address of PMAADDR @@ -93,32 +93,75 @@ // Volatile is also needed to prevent the optimizer from changing access to 32-bit (as 32-bit access is forbidden) static __IO uint16_t * const pma = (__IO uint16_t*)USB_PMAADDR; +// prototypes +static inline __IO uint16_t* pcd_ep_rx_cnt_ptr(USB_TypeDef * USBx, unsigned int bEpNum); +static inline __IO uint16_t* pcd_ep_tx_cnt_ptr(USB_TypeDef * USBx, unsigned int bEpNum); +static inline void pcd_set_endpoint(USB_TypeDef * USBx, unsigned int bEpNum, unsigned int wRegValue); + + /* SetENDPOINT */ -#define PCD_SET_ENDPOINT(USBx, bEpNum,wRegValue) (*((__IO uint16_t *)(((uint32_t)(&(USBx)->EP0R + (bEpNum) * 2U))))= (uint16_t)(wRegValue)) +static inline void pcd_set_endpoint(USB_TypeDef * USBx, unsigned int bEpNum, unsigned int wRegValue) +{ + __O uint16_t *reg = (__O uint16_t *)((&USBx->EP0R) + bEpNum*2u); + *reg = (uint16_t)wRegValue; +} + /* GetENDPOINT */ -#define PCD_GET_ENDPOINT(USBx, bEpNum) (*((__IO uint16_t *)(((uint32_t)(&(USBx)->EP0R + (bEpNum) * 2U))))) -#define PCD_SET_EPTYPE(USBx, bEpNum,wType) (PCD_SET_ENDPOINT((USBx), (bEpNum),\ - (((((uint32_t)(PCD_GET_ENDPOINT((USBx), (bEpNum)))) & ((uint32_t)(USB_EP_T_MASK))) | ((uint32_t)(wType))) | USB_EP_CTR_RX | USB_EP_CTR_TX))) -#define PCD_GET_EPTYPE(USBx, bEpNum) (((uint16_t)(PCD_GET_ENDPOINT((USBx), (bEpNum)))) & USB_EP_T_FIELD) +static inline uint16_t pcd_get_endpoint(USB_TypeDef * USBx, unsigned int bEpNum) { + __I uint16_t *reg = (__I uint16_t *)((&USBx->EP0R) + bEpNum*2u); + return *reg; +} + +static inline void pcd_set_eptype(USB_TypeDef * USBx, unsigned int bEpNum, unsigned int wType) +{ + unsigned int regVal = pcd_get_endpoint(USBx, bEpNum); + regVal &= (uint32_t)USB_EP_T_MASK; + regVal |= wType; + regVal |= USB_EP_CTR_RX | USB_EP_CTR_TX; // These clear on write0, so must set high + pcd_set_endpoint(USBx, bEpNum, regVal); +} +static inline unsigned int pcd_get_eptype(USB_TypeDef * USBx, unsigned int bEpNum) +{ + unsigned int regVal = pcd_get_endpoint(USBx, bEpNum); + regVal &= USB_EP_T_FIELD; + return regVal; +} /** * @brief Clears bit CTR_RX / CTR_TX in the endpoint register. * @param USBx USB peripheral instance register address. * @param bEpNum Endpoint Number. * @retval None */ -#define PCD_CLEAR_RX_EP_CTR(USBx, bEpNum) (PCD_SET_ENDPOINT((USBx), (bEpNum),\ - PCD_GET_ENDPOINT((USBx), (bEpNum)) & 0x7FFFU & USB_EPREG_MASK)) -#define PCD_CLEAR_TX_EP_CTR(USBx, bEpNum) (PCD_SET_ENDPOINT((USBx), (bEpNum),\ - PCD_GET_ENDPOINT((USBx), (bEpNum)) & 0xFF7FU & USB_EPREG_MASK)) +static inline void pcd_clear_rx_ep_ctr(USB_TypeDef * USBx, unsigned int bEpNum) +{ + unsigned int regVal = pcd_get_endpoint(USBx, bEpNum); + regVal &= 0x7FFFu & USB_EPREG_MASK; + pcd_set_endpoint(USBx, bEpNum, regVal); +} +static inline void pcd_clear_tx_ep_ctr(USB_TypeDef * USBx, unsigned int bEpNum) +{ + unsigned int regVal = pcd_get_endpoint(USBx, bEpNum); + regVal &= regVal & 0xFF7FU & USB_EPREG_MASK; + pcd_set_endpoint(USBx, bEpNum,regVal); +} /** * @brief gets counter of the tx buffer. * @param USBx USB peripheral instance register address. * @param bEpNum Endpoint Number. * @retval Counter value */ -#define PCD_GET_EP_TX_CNT(USBx, bEpNum)((uint16_t)(*PCD_EP_TX_CNT_PTR((USBx), (bEpNum))) & 0x3ffU) -#define PCD_GET_EP_RX_CNT(USBx, bEpNum)((uint16_t)(*PCD_EP_RX_CNT_PTR((USBx), (bEpNum))) & 0x3ffU) +static inline unsigned int pcd_get_ep_tx_cnt(USB_TypeDef * USBx, unsigned int bEpNum) +{ + __I uint16_t *regPtr = pcd_ep_tx_cnt_ptr(USBx, bEpNum); + return *regPtr & 0x3ffU; +} + +static inline unsigned int pcd_get_ep_rx_cnt(USB_TypeDef * USBx, unsigned int bEpNum) +{ + __I uint16_t *regPtr = pcd_ep_rx_cnt_ptr(USBx, bEpNum); + return *regPtr & 0x3ffU; +} /** * @brief Sets counter of rx buffer with no. of blocks. @@ -127,38 +170,30 @@ static __IO uint16_t * const pma = (__IO uint16_t*)USB_PMAADDR; * @param wNBlocks no. of Blocks. * @retval None */ -#define PCD_CALC_BLK32(dwReg,wCount,wNBlocks) {\ - (wNBlocks) = (uint32_t)((wCount) >> 5U);\ - if(((wCount) & 0x1fU) == 0U)\ - { \ - (wNBlocks)--;\ - } \ - *pdwReg = (uint16_t)((uint16_t)((wNBlocks) << 10U) | (uint16_t)0x8000U); \ - }/* PCD_CALC_BLK32 */ - - -#define PCD_CALC_BLK2(dwReg,wCount,wNBlocks) {\ - (wNBlocks) = (uint32_t)((wCount) >> 1U); \ - if(((wCount) & 0x1U) != 0U)\ - { \ - (wNBlocks)++;\ - } \ - *pdwReg = (uint16_t)((wNBlocks) << 10U);\ - }/* PCD_CALC_BLK2 */ - - -#define PCD_SET_EP_CNT_RX_REG(dwReg,wCount) {\ - uint32_t wNBlocks;\ - if((wCount) > 62U) \ - { \ - PCD_CALC_BLK32((dwReg),(wCount),wNBlocks) \ - } \ - else \ - { \ - PCD_CALC_BLK2((dwReg),(wCount),wNBlocks) \ - } \ - }/* PCD_SET_EP_CNT_RX_REG */ +static inline void pcd_set_ep_cnt_rx_reg(__O uint16_t * pdwReg, size_t wCount) { + unsigned int wNBlocks; + if(wCount > 62u) + { + wNBlocks = wCount >> 5u; + if((wCount & 0x1fU) == 0u) + { + wNBlocks--; + } + wNBlocks = wNBlocks << 10u; + wNBlocks |= 0x8000u; // Mark block size as 32byte + *pdwReg = (uint16_t)wNBlocks; + } + else + { + wNBlocks = wCount >> 1u; + if((wCount & 0x1U) != 0u) + { + wNBlocks++; + } + *pdwReg = (uint16_t)((wNBlocks) << 10u); + } +} /** @@ -168,23 +203,52 @@ static __IO uint16_t * const pma = (__IO uint16_t*)USB_PMAADDR; * @param bAddr Address. * @retval None */ -#define PCD_SET_EP_ADDRESS(USBx, bEpNum,bAddr) PCD_SET_ENDPOINT((USBx), (bEpNum),\ - USB_EP_CTR_RX|USB_EP_CTR_TX|(((uint32_t)(PCD_GET_ENDPOINT((USBx), (bEpNum)))) & USB_EPREG_MASK) | (bAddr)) +static inline void pcd_set_ep_address(USB_TypeDef * USBx, unsigned int bEpNum, unsigned int bAddr) +{ + unsigned int regVal = pcd_get_endpoint(USBx, bEpNum); + regVal &= USB_EPREG_MASK; + regVal |= bAddr; + regVal |= USB_EP_CTR_RX|USB_EP_CTR_TX; + pcd_set_endpoint(USBx, bEpNum,regVal); +} -#define PCD_BTABLE_WORD_PTR(USBx,x) (&(pma[PMA_STRIDE*((((USBx)->BTABLE)>>1) + x)])) +static inline __IO uint16_t * pcd_btable_word_ptr(USB_TypeDef * USBx, size_t x) +{ + size_t total_word_offset = (((USBx)->BTABLE)>>1) + x; + total_word_offset *= PMA_STRIDE; + return &(pma[total_word_offset]); +} // Pointers to the PMA table entries (using the ARM address space) -#define PCD_EP_TX_ADDRESS_PTR(USBx, bEpNum) (PCD_BTABLE_WORD_PTR(USBx,(bEpNum)*4u + 0u)) -#define PCD_EP_TX_CNT_PTR(USBx, bEpNum) (PCD_BTABLE_WORD_PTR(USBx,(bEpNum)*4u + 1u)) +static inline __IO uint16_t* pcd_ep_tx_address_ptr(USB_TypeDef * USBx, unsigned int bEpNum) +{ + return pcd_btable_word_ptr(USBx,(bEpNum)*4u + 0u); +} +static inline __IO uint16_t* pcd_ep_tx_cnt_ptr(USB_TypeDef * USBx, unsigned int bEpNum) +{ + return pcd_btable_word_ptr(USBx,(bEpNum)*4u + 1u); +} + +static inline __IO uint16_t* pcd_ep_rx_address_ptr(USB_TypeDef * USBx, unsigned int bEpNum) +{ + return pcd_btable_word_ptr(USBx,(bEpNum)*4u + 2u); +} + +static inline __IO uint16_t* pcd_ep_rx_cnt_ptr(USB_TypeDef * USBx, unsigned int bEpNum) +{ + return pcd_btable_word_ptr(USBx,(bEpNum)*4u + 3u); +} -#define PCD_EP_RX_ADDRESS_PTR(USBx, bEpNum) (PCD_BTABLE_WORD_PTR(USBx,(bEpNum)*4u + 2u)) -#define PCD_EP_RX_CNT_PTR(USBx, bEpNum) (PCD_BTABLE_WORD_PTR(USBx,(bEpNum)*4u + 3u)) +static inline void pcd_set_ep_tx_cnt(USB_TypeDef * USBx, unsigned int bEpNum, unsigned int wCount) +{ + *pcd_ep_tx_cnt_ptr(USBx, bEpNum) = (uint16_t)wCount; +} -#define PCD_SET_EP_TX_CNT(USBx, bEpNum,wCount) (*PCD_EP_TX_CNT_PTR((USBx), (bEpNum)) = (wCount)) -#define PCD_SET_EP_RX_CNT(USBx, bEpNum,wCount) do {\ - __IO uint16_t *pdwReg =PCD_EP_RX_CNT_PTR((USBx),(bEpNum)); \ - PCD_SET_EP_CNT_RX_REG((pdwReg), (wCount))\ - } while(0) +static inline void pcd_set_ep_rx_cnt(USB_TypeDef * USBx, unsigned int bEpNum, unsigned int wCount) +{ + __IO uint16_t *pdwReg = pcd_ep_rx_cnt_ptr((USBx),(bEpNum)); + pcd_set_ep_cnt_rx_reg(pdwReg, wCount); +} /** * @brief sets the status for tx transfer (bits STAT_TX[1:0]). @@ -193,21 +257,24 @@ static __IO uint16_t * const pma = (__IO uint16_t*)USB_PMAADDR; * @param wState new state * @retval None */ -#define PCD_SET_EP_TX_STATUS(USBx, bEpNum, wState) { register uint16_t _wRegVal;\ - \ - _wRegVal = (uint32_t) (((uint32_t)(PCD_GET_ENDPOINT((USBx), (bEpNum)))) & USB_EPTX_DTOGMASK);\ - /* toggle first bit ? */ \ - if((USB_EPTX_DTOG1 & (wState))!= 0U)\ - { \ - _wRegVal ^=(uint16_t) USB_EPTX_DTOG1; \ - } \ - /* toggle second bit ? */ \ - if((USB_EPTX_DTOG2 & ((uint32_t)(wState)))!= 0U) \ - { \ - _wRegVal ^=(uint16_t) USB_EPTX_DTOG2; \ - } \ - PCD_SET_ENDPOINT((USBx), (bEpNum), (((uint32_t)(_wRegVal)) | USB_EP_CTR_RX|USB_EP_CTR_TX));\ - } /* PCD_SET_EP_TX_STATUS */ +static inline void pcd_set_ep_tx_status(USB_TypeDef * USBx, unsigned int bEpNum, unsigned int wState) +{ + uint32_t regVal = pcd_get_endpoint(USBx, bEpNum); + regVal &= USB_EPTX_DTOGMASK; + + /* toggle first bit ? */ + if((USB_EPTX_DTOG1 & (wState))!= 0U) + { + regVal ^= USB_EPTX_DTOG1; + } + /* toggle second bit ? */ + if((USB_EPTX_DTOG2 & ((uint32_t)(wState)))!= 0U) + { + regVal ^= USB_EPTX_DTOG2; + } + regVal |= USB_EP_CTR_RX|USB_EP_CTR_TX; + pcd_set_endpoint(USBx, bEpNum, regVal); +} /* pcd_set_ep_tx_status */ /** * @brief sets the status for rx transfer (bits STAT_TX[1:0]) @@ -216,22 +283,25 @@ static __IO uint16_t * const pma = (__IO uint16_t*)USB_PMAADDR; * @param wState new state * @retval None */ -#define PCD_SET_EP_RX_STATUS(USBx, bEpNum,wState) {\ - register uint16_t _wRegVal; \ - \ - _wRegVal = (uint32_t) (((uint32_t)(PCD_GET_ENDPOINT((USBx), (bEpNum)))) & USB_EPRX_DTOGMASK);\ - /* toggle first bit ? */ \ - if((USB_EPRX_DTOG1 & (wState))!= 0U) \ - { \ - _wRegVal ^= (uint16_t) USB_EPRX_DTOG1; \ - } \ - /* toggle second bit ? */ \ - if((USB_EPRX_DTOG2 & ((uint32_t)(wState)))!= 0U) \ - { \ - _wRegVal ^= (uint16_t) USB_EPRX_DTOG2; \ - } \ - PCD_SET_ENDPOINT((USBx), (bEpNum), (((uint32_t)(_wRegVal)) | USB_EP_CTR_RX|USB_EP_CTR_TX)); \ - } /* PCD_SET_EP_RX_STATUS */ + +static inline void pcd_set_ep_rx_status(USB_TypeDef * USBx, unsigned int bEpNum, unsigned int wState) +{ + uint32_t regVal = pcd_get_endpoint(USBx, bEpNum); + regVal &= USB_EPRX_DTOGMASK; + + /* toggle first bit ? */ + if((USB_EPRX_DTOG1 & wState)!= 0U) + { + regVal ^= USB_EPRX_DTOG1; + } + /* toggle second bit ? */ + if((USB_EPRX_DTOG2 & wState)!= 0U) + { + regVal ^= USB_EPRX_DTOG2; + } + regVal |= USB_EP_CTR_RX|USB_EP_CTR_TX; + pcd_set_endpoint(USBx, bEpNum, regVal); +} /* pcd_set_ep_rx_status */ /** * @brief Toggles DTOG_RX / DTOG_TX bit in the endpoint register. @@ -239,10 +309,21 @@ static __IO uint16_t * const pma = (__IO uint16_t*)USB_PMAADDR; * @param bEpNum Endpoint Number. * @retval None */ -#define PCD_RX_DTOG(USBx, bEpNum) (PCD_SET_ENDPOINT((USBx), (bEpNum), \ - USB_EP_CTR_RX|USB_EP_CTR_TX|USB_EP_DTOG_RX | (((uint32_t)(PCD_GET_ENDPOINT((USBx), (bEpNum)))) & USB_EPREG_MASK))) -#define PCD_TX_DTOG(USBx, bEpNum) (PCD_SET_ENDPOINT((USBx), (bEpNum), \ - USB_EP_CTR_RX|USB_EP_CTR_TX|USB_EP_DTOG_TX | (((uint32_t)(PCD_GET_ENDPOINT((USBx), (bEpNum)))) & USB_EPREG_MASK))) +static inline void pcd_rx_dtog(USB_TypeDef * USBx, unsigned int bEpNum) +{ + unsigned int regVal = pcd_get_endpoint(USBx, bEpNum); + regVal &= USB_EPREG_MASK; + regVal |= USB_EP_CTR_RX|USB_EP_CTR_TX|USB_EP_DTOG_RX; + pcd_set_endpoint(USBx, bEpNum, regVal); +} + +static inline void pcd_tx_dtog(USB_TypeDef * USBx, unsigned int bEpNum) +{ + unsigned int regVal = pcd_get_endpoint(USBx, bEpNum); + regVal &= USB_EPREG_MASK; + regVal |= USB_EP_CTR_RX|USB_EP_CTR_TX|USB_EP_DTOG_TX; + pcd_set_endpoint(USBx, bEpNum, regVal); +} /** * @brief Clears DTOG_RX / DTOG_TX bit in the endpoint register. @@ -250,14 +331,24 @@ static __IO uint16_t * const pma = (__IO uint16_t*)USB_PMAADDR; * @param bEpNum Endpoint Number. * @retval None */ -#define PCD_CLEAR_RX_DTOG(USBx, bEpNum) if((((uint32_t)(PCD_GET_ENDPOINT((USBx), (bEpNum)))) & USB_EP_DTOG_RX) != 0)\ - { \ - PCD_RX_DTOG((USBx),(bEpNum));\ - } -#define PCD_CLEAR_TX_DTOG(USBx, bEpNum) if((((uint32_t)(PCD_GET_ENDPOINT((USBx), (bEpNum)))) & USB_EP_DTOG_TX) != 0)\ - {\ - PCD_TX_DTOG((USBx),(bEpNum));\ - } + +static inline void pcd_clear_rx_dtog(USB_TypeDef * USBx, unsigned int bEpNum) +{ + unsigned int regVal = pcd_get_endpoint(USBx, bEpNum); + if((regVal & USB_EP_DTOG_RX) != 0) + { + pcd_rx_dtog(USBx,bEpNum); + } +} + +static inline void pcd_clear_tx_dtog(USB_TypeDef * USBx, unsigned int bEpNum) +{ + unsigned int regVal = pcd_get_endpoint(USBx, bEpNum); + if((regVal & USB_EP_DTOG_TX) != 0) + { + pcd_tx_dtog(USBx,bEpNum); + } +} /** * @brief set & clear EP_KIND bit. @@ -265,11 +356,22 @@ static __IO uint16_t * const pma = (__IO uint16_t*)USB_PMAADDR; * @param bEpNum Endpoint Number. * @retval None */ -#define PCD_SET_EP_KIND(USBx, bEpNum) (PCD_SET_ENDPOINT((USBx), (bEpNum), \ - (USB_EP_CTR_RX|USB_EP_CTR_TX|((((uint32_t)(PCD_GET_ENDPOINT((USBx), (bEpNum)))) | USB_EP_KIND) & USB_EPREG_MASK)))) -#define PCD_CLEAR_EP_KIND(USBx, bEpNum) (PCD_SET_ENDPOINT((USBx), (bEpNum), \ - (USB_EP_CTR_RX|USB_EP_CTR_TX|((((uint32_t)(PCD_GET_ENDPOINT((USBx), (bEpNum)))) & USB_EPKIND_MASK))))) +static inline void pcd_set_ep_kind(USB_TypeDef * USBx, unsigned int bEpNum) +{ + unsigned int regVal = pcd_get_endpoint(USBx, bEpNum); + regVal |= USB_EP_KIND; + regVal &= USB_EPREG_MASK; + regVal |= USB_EP_CTR_RX|USB_EP_CTR_TX; + pcd_set_endpoint(USBx, bEpNum, regVal); +} +static inline void pcd_clear_ep_kind(USB_TypeDef * USBx, unsigned int bEpNum) +{ + unsigned int regVal = pcd_get_endpoint(USBx, bEpNum); + regVal &= USB_EPKIND_MASK; + regVal |= USB_EP_CTR_RX|USB_EP_CTR_TX; + pcd_set_endpoint(USBx, bEpNum, regVal); +} // This checks if the device has "LPM" #if defined(USB_ISTR_L1REQ) @@ -282,6 +384,6 @@ static __IO uint16_t * const pma = (__IO uint16_t*)USB_PMAADDR; USB_ISTR_RESET | USB_ISTR_SOF | USB_ISTR_ESOF | USB_ISTR_L1REQ_FORCED ) // Number of endpoints in hardware -#define STFSDEV_EP_COUNT (8) +#define STFSDEV_EP_COUNT (8u) #endif /* PORTABLE_ST_STM32F0_DCD_STM32F0_FSDEV_PVT_ST_H_ */ -- cgit v1.3.1 From 05c13342a3e176f36532b1d2a9e39fa8318a8094 Mon Sep 17 00:00:00 2001 From: Nathan Conrad Date: Sun, 15 Sep 2019 23:51:42 -0400 Subject: Implement EP with size <64. --- src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c | 68 +++++++++++++++++---------- 1 file changed, 44 insertions(+), 24 deletions(-) (limited to 'src') diff --git a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c index 452c9a92e..cafdd578e 100644 --- a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c +++ b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c @@ -154,16 +154,13 @@ TU_VERIFY_STATIC(((DCD_STM32_BTABLE_BASE) + (DCD_STM32_BTABLE_LENGTH))<=(PMA_LEN TU_VERIFY_STATIC(((DCD_STM32_BTABLE_BASE) % 8) == 0, "BTABLE base must be aligned to 8 bytes"); -// Max size of a USB FS packet is 64... -#define MAX_PACKET_SIZE 64 - - // One of these for every EP IN & OUT, uses a bit of RAM.... typedef struct { uint8_t * buffer; uint16_t total_len; uint16_t queued_len; + uint16_t max_packet_size; } xfer_ctl_t; static xfer_ctl_t xfer_status[MAX_EP_COUNT][2]; @@ -357,7 +354,7 @@ static void dcd_handle_bus_reset(void) // FIXME: Defined to return uint16 so that ASSERT can be used, even though a return value is not needed. static uint16_t dcd_ep_ctr_handler(void) { - uint16_t count=0U; + unsigned int count=0U; uint8_t EPindex; __IO uint16_t wIstr; __IO uint16_t wEPVal = 0U; @@ -390,7 +387,7 @@ static uint16_t dcd_ep_ctr_handler(void) { // Delayed setting of the DADDR after the 0-len DATA packet acking the request is sent. reg16_clear_bits(&USB->DADDR, USB_DADDR_ADD); - USB->DADDR |= (uint16_t)newDADDR; // leave the enable bit set + USB->DADDR = (uint16_t)(USB->DADDR | newDADDR); // leave the enable bit set newDADDR = 0; } if(xfer->total_len == 0) // Probably a status message? @@ -481,7 +478,7 @@ static uint16_t dcd_ep_ctr_handler(void) /*multi-packet on the NON control OUT endpoint */ xfer->queued_len = (uint16_t)(xfer->queued_len + count); - if ((count < 64) || (xfer->queued_len == xfer->total_len)) + if ((count < xfer->max_packet_size) || (xfer->queued_len == xfer->total_len)) { /* RX COMPLETE */ dcd_event_xfer_complete(0, EPindex, xfer->queued_len, XFER_RESULT_SUCCESS, true); @@ -490,9 +487,9 @@ static uint16_t dcd_ep_ctr_handler(void) } else { - uint16_t remaining = (uint16_t)(xfer->total_len - xfer->queued_len); - if(remaining >=64) { - pcd_set_ep_rx_cnt(USB, EPindex,64); + uint32_t remaining = (uint32_t)xfer->total_len - (uint32_t)xfer->queued_len; + if(remaining >= xfer->max_packet_size) { + pcd_set_ep_rx_cnt(USB, EPindex,xfer->max_packet_size); } else { pcd_set_ep_rx_cnt(USB, EPindex,remaining); } @@ -575,14 +572,33 @@ bool dcd_edpt_open (uint8_t rhport, tusb_desc_endpoint_t const * p_endpoint_desc (void)rhport; uint8_t const epnum = tu_edpt_number(p_endpoint_desc->bEndpointAddress); uint8_t const dir = tu_edpt_dir(p_endpoint_desc->bEndpointAddress); - + const uint16_t epMaxPktSize = p_endpoint_desc->wMaxPacketSize.size; // Isochronous not supported (yet), and some other driver assumptions. +#ifndef NDEBUG TU_ASSERT(p_endpoint_desc->bmAttributes.xfer != TUSB_XFER_ISOCHRONOUS); - TU_ASSERT(p_endpoint_desc->wMaxPacketSize.size <= MAX_PACKET_SIZE); TU_ASSERT(epnum < MAX_EP_COUNT); - TU_ASSERT((p_endpoint_desc->wMaxPacketSize.size %2) == 0); - // __IO uint16_t * const epreg = &(EPREG(epnum)); + switch(p_endpoint_desc->bmAttributes.xfer) { + case TUSB_XFER_CONTROL: + // USB 2.0 spec on FS packets, 5.5.3 (control) + TU_ASSERT((epMaxPktSize == 8) ||(epMaxPktSize == 16) || (epMaxPktSize == 32) || (epMaxPktSize == 64)); + break; + case TUSB_XFER_ISOCHRONOUS: // FIXME: Not yet supported + TU_ASSERT(epMaxPktSize <= 1023); + break; + case TUSB_XFER_BULK: + // USB 2.0 spec on FS packets, 5.8.3 (bulk) + TU_ASSERT((epMaxPktSize == 8) ||(epMaxPktSize == 16) ||(epMaxPktSize == 32) ||(epMaxPktSize == 64)); + break; + case TUSB_XFER_INTERRUPT: + // USB 2.0 spec on FS packets, 5.5.3 (interrupt); interestingly 0 is allowed. + TU_ASSERT(epMaxPktSize <= 64); + break; + default: + TU_ASSERT(false); + return false; + } +#endif // Set type switch(p_endpoint_desc->bmAttributes.xfer) { @@ -626,6 +642,7 @@ bool dcd_edpt_open (uint8_t rhport, tusb_desc_endpoint_t const * p_endpoint_desc pcd_set_ep_rx_status(USB, epnum, USB_EP_RX_NAK); } + xfer_ctl_ptr(epnum, dir)->max_packet_size = epMaxPktSize; ep_buf_ptr = (uint16_t)(ep_buf_ptr + p_endpoint_desc->wMaxPacketSize.size); // increment buffer pointer return true; @@ -637,11 +654,12 @@ static void dcd_transmit_packet(xfer_ctl_t * xfer, uint16_t ep_ix) { uint16_t len = (uint16_t)(xfer->total_len - xfer->queued_len); - if(len > 64u) // max packet size for FS transfer + if(len > xfer->max_packet_size) // max packet size for FS transfer { - len = 64u; + len = xfer->max_packet_size; } - dcd_write_packet_memory(*pcd_ep_tx_address_ptr(USB,ep_ix), &(xfer->buffer[xfer->queued_len]), len); + uint16_t oldAddr = *pcd_ep_tx_address_ptr(USB,ep_ix); + dcd_write_packet_memory(oldAddr, &(xfer->buffer[xfer->queued_len]), len); xfer->queued_len = (uint16_t)(xfer->queued_len + len); pcd_set_ep_tx_cnt(USB,ep_ix,len); @@ -670,9 +688,9 @@ bool dcd_edpt_xfer (uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t xfer->buffer = (uint8_t*)_setup_packet; pcd_set_ep_kind(USB,0); // Expect a zero-byte INPUT } - if(total_bytes > 64) + if(total_bytes > xfer->max_packet_size) { - pcd_set_ep_rx_cnt(USB,epnum,64); + pcd_set_ep_rx_cnt(USB,epnum,xfer->max_packet_size); } else { pcd_set_ep_rx_cnt(USB,epnum,total_bytes); } @@ -740,16 +758,17 @@ void dcd_edpt_clear_stall (uint8_t rhport, uint8_t ep_addr) */ static bool dcd_write_packet_memory(uint16_t dst, const void *__restrict src, size_t wNBytes) { - uint32_t n = ((uint32_t)((uint32_t)wNBytes + 1U)) >> 1U; + uint32_t n = ((uint32_t)wNBytes + 1U) >> 1U; uint32_t i; uint16_t temp1, temp2; const uint8_t * srcVal; -#ifdef DEBUG +#ifndef NDEBUG # if (DCD_STM32_BTABLE_BASE > 0u) TU_ASSERT(dst >= DCD_STM32_BTABLE_BASE); # endif - TU_ASSERT(((dst%2) == 0) && (dst + wNBytes) <= (DCD_STM32_BTABLE_BASE + DCD_STM32_BTABLE_LENGTH)); + TU_ASSERT((dst%2) == 0); + TU_ASSERT((dst + wNBytes) <= (DCD_STM32_BTABLE_BASE + DCD_STM32_BTABLE_LENGTH)); #endif // The GCC optimizer will combine access to 32-bit sizes if we let it. Force @@ -786,11 +805,12 @@ static bool dcd_read_packet_memory(void *__restrict dst, uint16_t src, size_t wN __IO const uint16_t *pdwVal; uint32_t temp; -#ifdef DEBUG +#ifndef NDEBUG # if (DCD_STM32_BTABLE_BASE > 0u) TU_ASSERT(src >= DCD_STM32_BTABLE_BASE); # endif - TU_ASSERT(((src%2) == 0) && (src + wNBytes) <= (DCD_STM32_BTABLE_BASE + DCD_STM32_BTABLE_LENGTH)); + TU_ASSERT((src%2) == 0); + TU_ASSERT((src + wNBytes) <= (DCD_STM32_BTABLE_BASE + DCD_STM32_BTABLE_LENGTH)); #endif -- cgit v1.3.1 From 9c5ae0369b2113ca3c7c8ac1240315ac1e7f1190 Mon Sep 17 00:00:00 2001 From: hathach Date: Mon, 16 Sep 2019 11:13:17 +0700 Subject: follow up to suggestion to pr 155 --- src/common/tusb_types.h | 3 ++- src/device/usbd.c | 19 +++++++++++++------ 2 files changed, 15 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/common/tusb_types.h b/src/common/tusb_types.h index a50e89934..ad42baad7 100644 --- a/src/common/tusb_types.h +++ b/src/common/tusb_types.h @@ -125,7 +125,8 @@ typedef enum { TUSB_REQ_TYPE_STANDARD = 0, TUSB_REQ_TYPE_CLASS, - TUSB_REQ_TYPE_VENDOR + TUSB_REQ_TYPE_VENDOR, + TUSB_REQ_TYPE_INVALID } tusb_request_type_t; typedef enum diff --git a/src/device/usbd.c b/src/device/usbd.c index c92884334..0366d1ece 100644 --- a/src/device/usbd.c +++ b/src/device/usbd.c @@ -62,7 +62,7 @@ typedef struct { static usbd_device_t _usbd_dev = { 0 }; // Invalid driver ID in itf2drv[] ep2drv[][] mapping -enum { DRVID_INVALID = 0xff }; +enum { DRVID_INVALID = 0xFFu }; //--------------------------------------------------------------------+ // Class Driver @@ -349,6 +349,8 @@ static bool process_control_request(uint8_t rhport, tusb_control_request_t const { usbd_control_set_complete_callback(NULL); + TU_ASSERT(p_request->bmRequestType_bit.type < TUSB_REQ_TYPE_INVALID); + // Vendor request if ( p_request->bmRequestType_bit.type == TUSB_REQ_TYPE_VENDOR ) { @@ -470,7 +472,8 @@ static bool process_control_request(uint8_t rhport, tusb_control_request_t const // GET HID REPORT DESCRIPTOR falls into this case // stall control endpoint if driver return false usbd_control_set_complete_callback(usbd_class_drivers[drvid].control_complete); - TU_ASSERT(usbd_class_drivers[drvid].control_request(rhport, p_request)); + TU_ASSERT(usbd_class_drivers[drvid].control_request != NULL && + usbd_class_drivers[drvid].control_request(rhport, p_request)); break; } }else @@ -478,7 +481,8 @@ static bool process_control_request(uint8_t rhport, tusb_control_request_t const // forward to class driver: "non-STD request to Interface" // stall control endpoint if driver return false usbd_control_set_complete_callback(usbd_class_drivers[drvid].control_complete); - TU_ASSERT(usbd_class_drivers[drvid].control_request(rhport, p_request)); + TU_ASSERT(usbd_class_drivers[drvid].control_request != NULL && + usbd_class_drivers[drvid].control_request(rhport, p_request)); } } break; @@ -499,7 +503,7 @@ static bool process_control_request(uint8_t rhport, tusb_control_request_t const // We will forward all request targeted endpoint to its class driver // - For non-standard request: driver can ACK or Stall the request by return true/false // - For standard request: usbd decide the ACK stage regardless of driver return value - bool ret; + bool ret = false; if ( TUSB_REQ_TYPE_STANDARD != p_request->bmRequestType_bit.type ) { @@ -507,8 +511,11 @@ static bool process_control_request(uint8_t rhport, tusb_control_request_t const usbd_control_set_complete_callback(usbd_class_drivers[drv_id].control_complete); } - // Invoke class driver first - ret = usbd_class_drivers[drv_id].control_request(rhport, p_request); + // Invoke class driver first if available + if ( usbd_class_drivers[drv_id].control_request ) + { + ret = usbd_class_drivers[drv_id].control_request(rhport, p_request); + } // Then handle if it is standard request if ( TUSB_REQ_TYPE_STANDARD == p_request->bmRequestType_bit.type ) -- cgit v1.3.1 From a37d2d64beaea07d17b24d8b61bfa09b89ee5bba Mon Sep 17 00:00:00 2001 From: hathach Date: Mon, 16 Sep 2019 13:32:47 +0700 Subject: fix #143 --- src/portable/nxp/lpc17_40/dcd_lpc17_40.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/portable/nxp/lpc17_40/dcd_lpc17_40.c b/src/portable/nxp/lpc17_40/dcd_lpc17_40.c index 2b49f52e9..d5f90d2a7 100644 --- a/src/portable/nxp/lpc17_40/dcd_lpc17_40.c +++ b/src/portable/nxp/lpc17_40/dcd_lpc17_40.c @@ -293,7 +293,7 @@ bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const * p_endpoint_desc) break; case TUSB_XFER_ISOCHRONOUS: - TU_ASSERT((epnum % 3) == 3 && (epnum != 15)); + TU_ASSERT((epnum % 3) == 0 && (epnum != 0) && (epnum != 15)); break; default: -- cgit v1.3.1 From 6b9783ceadf36d6507a624b8413adf9686d6e541 Mon Sep 17 00:00:00 2001 From: Nathan Conrad Date: Mon, 16 Sep 2019 09:20:15 -0400 Subject: s/unsigned int/uint32_t/ --- src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c | 4 +- .../st/stm32_fsdev/dcd_stm32_fsdev_pvt_st.h | 76 +++++++++++----------- 2 files changed, 40 insertions(+), 40 deletions(-) (limited to 'src') diff --git a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c index cafdd578e..d3cbef43c 100644 --- a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c +++ b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c @@ -165,7 +165,7 @@ typedef struct static xfer_ctl_t xfer_status[MAX_EP_COUNT][2]; -static xfer_ctl_t* xfer_ctl_ptr(unsigned int epnum, unsigned int dir) +static xfer_ctl_t* xfer_ctl_ptr(uint32_t epnum, uint32_t dir) { #ifndef NDEBUG TU_ASSERT(epnum < MAX_EP_COUNT); @@ -354,7 +354,7 @@ static void dcd_handle_bus_reset(void) // FIXME: Defined to return uint16 so that ASSERT can be used, even though a return value is not needed. static uint16_t dcd_ep_ctr_handler(void) { - unsigned int count=0U; + uint32_t count=0U; uint8_t EPindex; __IO uint16_t wIstr; __IO uint16_t wEPVal = 0U; diff --git a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev_pvt_st.h b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev_pvt_st.h index 2b9de4440..e205979fc 100644 --- a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev_pvt_st.h +++ b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev_pvt_st.h @@ -94,36 +94,36 @@ const size_t PMA_STRIDE = 1u; static __IO uint16_t * const pma = (__IO uint16_t*)USB_PMAADDR; // prototypes -static inline __IO uint16_t* pcd_ep_rx_cnt_ptr(USB_TypeDef * USBx, unsigned int bEpNum); -static inline __IO uint16_t* pcd_ep_tx_cnt_ptr(USB_TypeDef * USBx, unsigned int bEpNum); -static inline void pcd_set_endpoint(USB_TypeDef * USBx, unsigned int bEpNum, unsigned int wRegValue); +static inline __IO uint16_t* pcd_ep_rx_cnt_ptr(USB_TypeDef * USBx, uint32_t bEpNum); +static inline __IO uint16_t* pcd_ep_tx_cnt_ptr(USB_TypeDef * USBx, uint32_t bEpNum); +static inline void pcd_set_endpoint(USB_TypeDef * USBx, uint32_t bEpNum, uint32_t wRegValue); /* SetENDPOINT */ -static inline void pcd_set_endpoint(USB_TypeDef * USBx, unsigned int bEpNum, unsigned int wRegValue) +static inline void pcd_set_endpoint(USB_TypeDef * USBx, uint32_t bEpNum, uint32_t wRegValue) { __O uint16_t *reg = (__O uint16_t *)((&USBx->EP0R) + bEpNum*2u); *reg = (uint16_t)wRegValue; } /* GetENDPOINT */ -static inline uint16_t pcd_get_endpoint(USB_TypeDef * USBx, unsigned int bEpNum) { +static inline uint16_t pcd_get_endpoint(USB_TypeDef * USBx, uint32_t bEpNum) { __I uint16_t *reg = (__I uint16_t *)((&USBx->EP0R) + bEpNum*2u); return *reg; } -static inline void pcd_set_eptype(USB_TypeDef * USBx, unsigned int bEpNum, unsigned int wType) +static inline void pcd_set_eptype(USB_TypeDef * USBx, uint32_t bEpNum, uint32_t wType) { - unsigned int regVal = pcd_get_endpoint(USBx, bEpNum); + uint32_t regVal = pcd_get_endpoint(USBx, bEpNum); regVal &= (uint32_t)USB_EP_T_MASK; regVal |= wType; regVal |= USB_EP_CTR_RX | USB_EP_CTR_TX; // These clear on write0, so must set high pcd_set_endpoint(USBx, bEpNum, regVal); } -static inline unsigned int pcd_get_eptype(USB_TypeDef * USBx, unsigned int bEpNum) +static inline uint32_t pcd_get_eptype(USB_TypeDef * USBx, uint32_t bEpNum) { - unsigned int regVal = pcd_get_endpoint(USBx, bEpNum); + uint32_t regVal = pcd_get_endpoint(USBx, bEpNum); regVal &= USB_EP_T_FIELD; return regVal; } @@ -133,15 +133,15 @@ static inline unsigned int pcd_get_eptype(USB_TypeDef * USBx, unsigned int bEpNu * @param bEpNum Endpoint Number. * @retval None */ -static inline void pcd_clear_rx_ep_ctr(USB_TypeDef * USBx, unsigned int bEpNum) +static inline void pcd_clear_rx_ep_ctr(USB_TypeDef * USBx, uint32_t bEpNum) { - unsigned int regVal = pcd_get_endpoint(USBx, bEpNum); + uint32_t regVal = pcd_get_endpoint(USBx, bEpNum); regVal &= 0x7FFFu & USB_EPREG_MASK; pcd_set_endpoint(USBx, bEpNum, regVal); } -static inline void pcd_clear_tx_ep_ctr(USB_TypeDef * USBx, unsigned int bEpNum) +static inline void pcd_clear_tx_ep_ctr(USB_TypeDef * USBx, uint32_t bEpNum) { - unsigned int regVal = pcd_get_endpoint(USBx, bEpNum); + uint32_t regVal = pcd_get_endpoint(USBx, bEpNum); regVal &= regVal & 0xFF7FU & USB_EPREG_MASK; pcd_set_endpoint(USBx, bEpNum,regVal); } @@ -151,13 +151,13 @@ static inline void pcd_clear_tx_ep_ctr(USB_TypeDef * USBx, unsigned int bEpNum) * @param bEpNum Endpoint Number. * @retval Counter value */ -static inline unsigned int pcd_get_ep_tx_cnt(USB_TypeDef * USBx, unsigned int bEpNum) +static inline uint32_t pcd_get_ep_tx_cnt(USB_TypeDef * USBx, uint32_t bEpNum) { __I uint16_t *regPtr = pcd_ep_tx_cnt_ptr(USBx, bEpNum); return *regPtr & 0x3ffU; } -static inline unsigned int pcd_get_ep_rx_cnt(USB_TypeDef * USBx, unsigned int bEpNum) +static inline uint32_t pcd_get_ep_rx_cnt(USB_TypeDef * USBx, uint32_t bEpNum) { __I uint16_t *regPtr = pcd_ep_rx_cnt_ptr(USBx, bEpNum); return *regPtr & 0x3ffU; @@ -172,7 +172,7 @@ static inline unsigned int pcd_get_ep_rx_cnt(USB_TypeDef * USBx, unsigned int bE */ static inline void pcd_set_ep_cnt_rx_reg(__O uint16_t * pdwReg, size_t wCount) { - unsigned int wNBlocks; + uint32_t wNBlocks; if(wCount > 62u) { wNBlocks = wCount >> 5u; @@ -203,9 +203,9 @@ static inline void pcd_set_ep_cnt_rx_reg(__O uint16_t * pdwReg, size_t wCount) * @param bAddr Address. * @retval None */ -static inline void pcd_set_ep_address(USB_TypeDef * USBx, unsigned int bEpNum, unsigned int bAddr) +static inline void pcd_set_ep_address(USB_TypeDef * USBx, uint32_t bEpNum, uint32_t bAddr) { - unsigned int regVal = pcd_get_endpoint(USBx, bEpNum); + uint32_t regVal = pcd_get_endpoint(USBx, bEpNum); regVal &= USB_EPREG_MASK; regVal |= bAddr; regVal |= USB_EP_CTR_RX|USB_EP_CTR_TX; @@ -220,31 +220,31 @@ static inline __IO uint16_t * pcd_btable_word_ptr(USB_TypeDef * USBx, size_t x) } // Pointers to the PMA table entries (using the ARM address space) -static inline __IO uint16_t* pcd_ep_tx_address_ptr(USB_TypeDef * USBx, unsigned int bEpNum) +static inline __IO uint16_t* pcd_ep_tx_address_ptr(USB_TypeDef * USBx, uint32_t bEpNum) { return pcd_btable_word_ptr(USBx,(bEpNum)*4u + 0u); } -static inline __IO uint16_t* pcd_ep_tx_cnt_ptr(USB_TypeDef * USBx, unsigned int bEpNum) +static inline __IO uint16_t* pcd_ep_tx_cnt_ptr(USB_TypeDef * USBx, uint32_t bEpNum) { return pcd_btable_word_ptr(USBx,(bEpNum)*4u + 1u); } -static inline __IO uint16_t* pcd_ep_rx_address_ptr(USB_TypeDef * USBx, unsigned int bEpNum) +static inline __IO uint16_t* pcd_ep_rx_address_ptr(USB_TypeDef * USBx, uint32_t bEpNum) { return pcd_btable_word_ptr(USBx,(bEpNum)*4u + 2u); } -static inline __IO uint16_t* pcd_ep_rx_cnt_ptr(USB_TypeDef * USBx, unsigned int bEpNum) +static inline __IO uint16_t* pcd_ep_rx_cnt_ptr(USB_TypeDef * USBx, uint32_t bEpNum) { return pcd_btable_word_ptr(USBx,(bEpNum)*4u + 3u); } -static inline void pcd_set_ep_tx_cnt(USB_TypeDef * USBx, unsigned int bEpNum, unsigned int wCount) +static inline void pcd_set_ep_tx_cnt(USB_TypeDef * USBx, uint32_t bEpNum, uint32_t wCount) { *pcd_ep_tx_cnt_ptr(USBx, bEpNum) = (uint16_t)wCount; } -static inline void pcd_set_ep_rx_cnt(USB_TypeDef * USBx, unsigned int bEpNum, unsigned int wCount) +static inline void pcd_set_ep_rx_cnt(USB_TypeDef * USBx, uint32_t bEpNum, uint32_t wCount) { __IO uint16_t *pdwReg = pcd_ep_rx_cnt_ptr((USBx),(bEpNum)); pcd_set_ep_cnt_rx_reg(pdwReg, wCount); @@ -257,7 +257,7 @@ static inline void pcd_set_ep_rx_cnt(USB_TypeDef * USBx, unsigned int bEpNum, u * @param wState new state * @retval None */ -static inline void pcd_set_ep_tx_status(USB_TypeDef * USBx, unsigned int bEpNum, unsigned int wState) +static inline void pcd_set_ep_tx_status(USB_TypeDef * USBx, uint32_t bEpNum, uint32_t wState) { uint32_t regVal = pcd_get_endpoint(USBx, bEpNum); regVal &= USB_EPTX_DTOGMASK; @@ -284,7 +284,7 @@ static inline void pcd_set_ep_tx_status(USB_TypeDef * USBx, unsigned int bEpNum * @retval None */ -static inline void pcd_set_ep_rx_status(USB_TypeDef * USBx, unsigned int bEpNum, unsigned int wState) +static inline void pcd_set_ep_rx_status(USB_TypeDef * USBx, uint32_t bEpNum, uint32_t wState) { uint32_t regVal = pcd_get_endpoint(USBx, bEpNum); regVal &= USB_EPRX_DTOGMASK; @@ -309,17 +309,17 @@ static inline void pcd_set_ep_rx_status(USB_TypeDef * USBx, unsigned int bEpNum * @param bEpNum Endpoint Number. * @retval None */ -static inline void pcd_rx_dtog(USB_TypeDef * USBx, unsigned int bEpNum) +static inline void pcd_rx_dtog(USB_TypeDef * USBx, uint32_t bEpNum) { - unsigned int regVal = pcd_get_endpoint(USBx, bEpNum); + uint32_t regVal = pcd_get_endpoint(USBx, bEpNum); regVal &= USB_EPREG_MASK; regVal |= USB_EP_CTR_RX|USB_EP_CTR_TX|USB_EP_DTOG_RX; pcd_set_endpoint(USBx, bEpNum, regVal); } -static inline void pcd_tx_dtog(USB_TypeDef * USBx, unsigned int bEpNum) +static inline void pcd_tx_dtog(USB_TypeDef * USBx, uint32_t bEpNum) { - unsigned int regVal = pcd_get_endpoint(USBx, bEpNum); + uint32_t regVal = pcd_get_endpoint(USBx, bEpNum); regVal &= USB_EPREG_MASK; regVal |= USB_EP_CTR_RX|USB_EP_CTR_TX|USB_EP_DTOG_TX; pcd_set_endpoint(USBx, bEpNum, regVal); @@ -332,18 +332,18 @@ static inline void pcd_tx_dtog(USB_TypeDef * USBx, unsigned int bEpNum) * @retval None */ -static inline void pcd_clear_rx_dtog(USB_TypeDef * USBx, unsigned int bEpNum) +static inline void pcd_clear_rx_dtog(USB_TypeDef * USBx, uint32_t bEpNum) { - unsigned int regVal = pcd_get_endpoint(USBx, bEpNum); + uint32_t regVal = pcd_get_endpoint(USBx, bEpNum); if((regVal & USB_EP_DTOG_RX) != 0) { pcd_rx_dtog(USBx,bEpNum); } } -static inline void pcd_clear_tx_dtog(USB_TypeDef * USBx, unsigned int bEpNum) +static inline void pcd_clear_tx_dtog(USB_TypeDef * USBx, uint32_t bEpNum) { - unsigned int regVal = pcd_get_endpoint(USBx, bEpNum); + uint32_t regVal = pcd_get_endpoint(USBx, bEpNum); if((regVal & USB_EP_DTOG_TX) != 0) { pcd_tx_dtog(USBx,bEpNum); @@ -357,17 +357,17 @@ static inline void pcd_clear_tx_dtog(USB_TypeDef * USBx, unsigned int bEpNum) * @retval None */ -static inline void pcd_set_ep_kind(USB_TypeDef * USBx, unsigned int bEpNum) +static inline void pcd_set_ep_kind(USB_TypeDef * USBx, uint32_t bEpNum) { - unsigned int regVal = pcd_get_endpoint(USBx, bEpNum); + uint32_t regVal = pcd_get_endpoint(USBx, bEpNum); regVal |= USB_EP_KIND; regVal &= USB_EPREG_MASK; regVal |= USB_EP_CTR_RX|USB_EP_CTR_TX; pcd_set_endpoint(USBx, bEpNum, regVal); } -static inline void pcd_clear_ep_kind(USB_TypeDef * USBx, unsigned int bEpNum) +static inline void pcd_clear_ep_kind(USB_TypeDef * USBx, uint32_t bEpNum) { - unsigned int regVal = pcd_get_endpoint(USBx, bEpNum); + uint32_t regVal = pcd_get_endpoint(USBx, bEpNum); regVal &= USB_EPKIND_MASK; regVal |= USB_EP_CTR_RX|USB_EP_CTR_TX; pcd_set_endpoint(USBx, bEpNum, regVal); -- cgit v1.3.1 From dfe92542e63af0032c5f9b0fcd14a5f5971f78fe Mon Sep 17 00:00:00 2001 From: Nathan Conrad Date: Mon, 16 Sep 2019 11:27:05 -0400 Subject: Change inline functions to macros, and make all parameter names uniform. --- src/common/tusb_compiler.h | 58 ++++++++++++++++++---------------------------- 1 file changed, 23 insertions(+), 35 deletions(-) (limited to 'src') diff --git a/src/common/tusb_compiler.h b/src/common/tusb_compiler.h index df0326afd..58732b871 100644 --- a/src/common/tusb_compiler.h +++ b/src/common/tusb_compiler.h @@ -75,17 +75,8 @@ #define TU_BYTE_ORDER TU_BIG_ENDIAN #endif - static inline uint16_t tu_bswap16(uint16_t u16) - { - return __builtin_bswap16(u16); - } - - static inline uint32_t tu_bswap32(uint32_t u32) - { - return __builtin_bswap32(u32); - } - - #define TU_BSWAP16 +#define TU_BSWAP16(u16) (__builtin_bswap16(u16)) +#define TU_BSWAP32(u32) (__builtin_bswap32(u32)) #elif defined(__TI_COMPILER_VERSION__) #define TU_ATTR_ALIGNED(Bytes) __attribute__ ((aligned(Bytes))) @@ -103,44 +94,41 @@ #define TU_BYTE_ORDER TU_BIG_ENDIAN #endif - static inline uint16_t tu_bswap16(uint16_t u16) - { - return __builtin_bswap16(u16); - } + #define TU_BSWAP16(u16) (__builtin_bswap16(u16)) + #define TU_BSWAP32(u32) (__builtin_bswap32(u32)) - static inline uint32_t tu_bswap32(uint32_t u32) - { - return __builtin_bswap32(u32); - } #else #error "Compiler attribute porting is required" #endif #if (TU_BYTE_ORDER == TU_LITTLE_ENDIAN) - #define tu_htonl(u32) tu_bswap32(u32) - #define tu_ntohl(u32) tu_bswap32(u32) - #define tu_htons(u16) tu_bswap16(u16) - #define tu_ntohs(u16) tu_bswap16(u16) + #define tu_htons(u16) (TU_BSWAP16(u16)) + #define tu_ntohs(u16) (TU_BSWAP16(u16)) + + #define tu_htonl(u32) (TU_BSWAP32(u32)) + #define tu_ntohl(u32) (TU_BSWAP32(u32)) - #define tu_htole16(x) (x) - #define tu_le16toh(x) (x) + #define tu_htole16(u16) (u16) + #define tu_le16toh(u16) (u16) - #define tu_htole32(x) (x) - #define tu_le32toh(x) (x) + #define tu_htole32(u32) (u32) + #define tu_le32toh(u32) (u32) #elif (TU_BYTE_ORDER == TU_BIG_ENDIAN) - #define tu_htonl(u32) (x) - #define tu_ntohl(u32) (x) - #define tu_htons(u16) (x) - #define tu_ntohs(u16) (x) + #define tu_htons(u16) (u16) + #define tu_ntohs(u16) (u16) + + #define tu_htonl(u32) (u32) + #define tu_ntohl(u32) (u32) + - #define tu_htole16(x) tu_bswap16(u32) - #define tu_le16toh(x) tu_bswap16(u32) + #define tu_htole16(u16) (tu_bswap16(u16)) + #define tu_le16toh(u16) (tu_bswap16(u16)) - #define tu_htole32(x) tu_bswap32(u32) - #define tu_le32toh(x) tu_bswap32(u32) + #define tu_htole32(u32) (tu_bswap32(u32)) + #define tu_le32toh(u32) (tu_bswap32(u32)) #else #error Byte order is undefined -- cgit v1.3.1 From d341337c6a80622c22fc002b35a65b40bdf15b4b Mon Sep 17 00:00:00 2001 From: Nathan Conrad Date: Mon, 16 Sep 2019 20:25:50 -0400 Subject: Implement remote wakeup + perhaps better sleep? --- src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c index d3cbef43c..0559a4087 100644 --- a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c +++ b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c @@ -308,6 +308,17 @@ void dcd_set_config (uint8_t rhport, uint8_t config_num) void dcd_remote_wakeup(uint8_t rhport) { (void) rhport; + uint32_t start; + + USB->CNTR |= (uint16_t)USB_CNTR_RESUME; + /* Wait 1 to 15 ms */ + /* Busy loop is bad, but the osal_task_delay() isn't implemented for the "none" OSAL */ + start = board_millis(); + while ((board_millis() - start) < 2) + { + ; + } + USB->CNTR &= (uint16_t)(~USB_CNTR_RESUME); } // I'm getting a weird warning about missing braces here that I don't @@ -538,10 +549,10 @@ static void dcd_fs_irqHandler(void) { } if (int_status & USB_ISTR_WKUP) { - reg16_clear_bits(&USB->CNTR, USB_CNTR_LPMODE); reg16_clear_bits(&USB->CNTR, USB_CNTR_FSUSP); reg16_clear_bits(&USB->ISTR, USB_ISTR_WKUP); + dcd_event_bus_signal(0, DCD_EVENT_RESUME, true); } if (int_status & USB_ISTR_SUSP) @@ -552,6 +563,7 @@ static void dcd_fs_irqHandler(void) { /* clear of the ISTR bit must be done after setting of CNTR_FSUSP */ reg16_clear_bits(&USB->ISTR, USB_ISTR_SUSP); + dcd_event_bus_signal(0, DCD_EVENT_SUSPEND, true); } if(int_status & USB_ISTR_SOF) { -- cgit v1.3.1 From a33a8547936ccea0cfcbba8823c44cae8a887269 Mon Sep 17 00:00:00 2001 From: Nathan Conrad Date: Mon, 16 Sep 2019 20:56:57 -0400 Subject: Include board header file... :X --- src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c | 1 + 1 file changed, 1 insertion(+) (limited to 'src') diff --git a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c index 0559a4087..00a016e3b 100644 --- a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c +++ b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c @@ -121,6 +121,7 @@ #undef USE_HAL_DRIVER #include "device/dcd.h" +#include "bsp/board.h" #include "portable/st/stm32_fsdev/dcd_stm32_fsdev_pvt_st.h" -- cgit v1.3.1 From 89ffe78f84fe9771f23b51e60e539cec236a1704 Mon Sep 17 00:00:00 2001 From: Nathan Conrad Date: Mon, 16 Sep 2019 22:56:17 -0400 Subject: ST FSDEV: No need to always reset the interrupt priority, also add some synchronization primitives after disabling interrupts. --- src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c index 00a016e3b..e2df2abe4 100644 --- a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c +++ b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c @@ -258,12 +258,8 @@ void dcd_int_enable (uint8_t rhport) { (void)rhport; #if defined(STM32F0) - NVIC_SetPriority(USB_IRQn, 0); NVIC_EnableIRQ(USB_IRQn); #elif defined(STM32F3) - NVIC_SetPriority(USB_HP_CAN_TX_IRQn, 0); - NVIC_SetPriority(USB_LP_CAN_RX0_IRQn, 0); - NVIC_SetPriority(USBWakeUp_IRQn, 0); NVIC_EnableIRQ(USB_HP_CAN_TX_IRQn); NVIC_EnableIRQ(USB_LP_CAN_RX0_IRQn); NVIC_EnableIRQ(USBWakeUp_IRQn); @@ -283,6 +279,10 @@ void dcd_int_disable(uint8_t rhport) #else #error Unknown arch in USB driver #endif + // I'm not convinced that memory synchronization is completely necessary, but + // it isn't a bad idea. + __DSB(); + __ISB(); } // Receive Set Address request, mcu port must also include status IN response -- cgit v1.3.1 From 915f52730d4bd91642bfcf74a8ebfb18536517e9 Mon Sep 17 00:00:00 2001 From: Nathan Conrad Date: Tue, 17 Sep 2019 11:28:29 -0400 Subject: Implement HID desc request. --- src/class/hid/hid_device.c | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/class/hid/hid_device.c b/src/class/hid/hid_device.c index 572f2cad2..2d579f475 100644 --- a/src/class/hid/hid_device.c +++ b/src/class/hid/hid_device.c @@ -202,7 +202,29 @@ bool hidd_control_request(uint8_t rhport, tusb_control_request_t const * p_reque uint8_t const desc_index = tu_u16_low (p_request->wValue); (void) desc_index; - if (p_request->bRequest == TUSB_REQ_GET_DESCRIPTOR && desc_type == HID_DESC_TYPE_REPORT) + if (p_request->bRequest == TUSB_REQ_GET_DESCRIPTOR && desc_type == HID_DESC_TYPE_HID) + { + // FIXME: Should check which is the active configuration, but no callback in usbd currently exists to do that + tusb_desc_configuration_t const* desc_cfg = + (tusb_desc_configuration_t const*) tud_descriptor_configuration_cb(0); + uint8_t const * p_desc = ((uint8_t const*) desc_cfg) + sizeof(tusb_desc_configuration_t); + uint8_t const * desc_end = ((uint8_t const*) desc_cfg) + desc_cfg->wTotalLength; + + while( p_desc < desc_end ) + { + tusb_hid_descriptor_hid_t *p_desc_hid =(tusb_hid_descriptor_hid_t*)p_desc; + if(p_desc_hid->bDescriptorType == HID_DESC_TYPE_HID) { + tud_control_xfer(rhport, p_request, (void*) p_desc_hid, p_desc_hid->bLength); + break; + } + p_desc += p_desc_hid->bLength; // next desc + } + if(p_desc >= desc_end) + { + return false; + } + } + else if (p_request->bRequest == TUSB_REQ_GET_DESCRIPTOR && desc_type == HID_DESC_TYPE_REPORT) { uint8_t const * desc_report = tud_hid_descriptor_report_cb(); tud_control_xfer(rhport, p_request, (void*) desc_report, p_hid->reprot_desc_len); -- cgit v1.3.1 From c755aee7d0c1e2486055e02ac353878d8da3ba59 Mon Sep 17 00:00:00 2001 From: Nathan Conrad Date: Sat, 14 Sep 2019 22:55:42 -0400 Subject: Clear --- examples/device/usbtmc/src/usbtmc_app.c | 44 ++++++---- src/class/usbtmc/usbtmc.h | 94 ++++++++++++++-------- src/class/usbtmc/usbtmc_device.c | 137 ++++++++++++++++++++------------ src/class/usbtmc/usbtmc_device.h | 4 + 4 files changed, 183 insertions(+), 96 deletions(-) (limited to 'src') diff --git a/examples/device/usbtmc/src/usbtmc_app.c b/examples/device/usbtmc/src/usbtmc_app.c index af97939b9..a41d911d2 100644 --- a/examples/device/usbtmc/src/usbtmc_app.c +++ b/examples/device/usbtmc/src/usbtmc_app.c @@ -97,7 +97,9 @@ bool usbtmcd_app_msg_trigger(uint8_t rhport, usbtmc_msg_generic_t* msg) { bool usbtmcd_app_msg_data(uint8_t rhport, void *data, size_t len, bool transfer_complete) { (void)rhport; - (void)transfer_complete; + + // If transfer isn't finished, we just ignore it (for now) + if(transfer_complete && (len >=4) && !strncasecmp("*idn?",data,4)) { queryState = 1; } @@ -107,26 +109,24 @@ bool usbtmcd_app_msg_data(uint8_t rhport, void *data, size_t len, bool transfer_ bool usbtmcd_app_msgBulkIn_complete(uint8_t rhport) { (void)rhport; + + status &= (uint8_t)~(0x10u); // clear MAV + return true; } -static uint8_t noQueryMsg[] = "ERR: No query\n"; - bool usbtmcd_app_msgBulkIn_request(uint8_t rhport, usbtmc_msg_request_dev_dep_in const * request) { rspMsg.header.MsgID = request->header.MsgID, rspMsg.header.bTag = request->header.bTag, rspMsg.header.bTagInverse = request->header.bTagInverse; - if(queryState != 0) - { - TU_ASSERT(bulkInStarted == 0); - bulkInStarted = 1; - } - else - { - rspMsg.TransferSize = sizeof(noQueryMsg)-1; - usbtmcd_transmit_dev_msg_data(rhport, &rspMsg, noQueryMsg); - } + + TU_ASSERT(bulkInStarted == 0); + bulkInStarted = 1; + + // > If a USBTMC interface receives a Bulk-IN request prior to receiving a USBTMC command message + // that expects a response, the device must NAK the request + // Always return true indicating not to stall the EP. return true; } @@ -157,12 +157,28 @@ void usbtmc_app_task_iter(void) { bulkInStarted = 0; rspMsg.TransferSize = sizeof(idn)-1; usbtmcd_transmit_dev_msg_data(rhport, &rspMsg, idn); - status &= ~(0x10u); // MAV + // MAV is cleared in the transfer complete callback. } break; + default: + TU_ASSERT(false,); + return; } } +bool usbtmcd_app_initiate_clear(uint8_t rhport, uint8_t *tmcResult) { + (void)rhport; + *tmcResult = USBTMC_STATUS_SUCCESS; + return true; +} + +bool usbtmcd_app_get_clear_status(uint8_t rhport, usbtmc_get_clear_status_rsp_t *rsp) { + (void)rhport; + rsp->USBTMC_status = USBTMC_STATUS_SUCCESS; + rsp->bmClear.BulkInFifoBytes = 0u; + return true; +} + // Return status byte, but put the transfer result status code in the rspResult argument. uint8_t usbtmcd_app_get_stb(uint8_t rhport, uint8_t *tmcResult) { diff --git a/src/class/usbtmc/usbtmc.h b/src/class/usbtmc/usbtmc.h index ecc16a315..d24a72cb6 100644 --- a/src/class/usbtmc/usbtmc.h +++ b/src/class/usbtmc/usbtmc.h @@ -73,53 +73,67 @@ typedef struct TU_ATTR_PACKED typedef struct TU_ATTR_PACKED { usbtmc_msg_header_t header ; ///< Header uint32_t TransferSize ; ///< Transfer size; LSB first - struct { - uint8_t EOM : 1 ; ///< EOM set on last byte + struct TU_ATTR_PACKED + { + unsigned int EOM : 1 ; ///< EOM set on last byte } bmTransferAttributes; uint8_t _reserved[3]; } usbtmc_msg_request_dev_dep_out; +TU_VERIFY_STATIC(sizeof(usbtmc_msg_request_dev_dep_out) == 12u, "struct wrong length"); + // Next 8 bytes are message-specific -typedef struct TU_ATTR_PACKED { +typedef struct TU_ATTR_PACKED +{ usbtmc_msg_header_t header ; ///< Header uint32_t TransferSize ; ///< Transfer size; LSB first - struct { - uint8_t : 0; - uint8_t TermCharEnabled : 1 ; ///< "The Bulk-IN transfer must terminate on the specified TermChar."; CAPABILITIES must list TermChar + struct TU_ATTR_PACKED + { + unsigned int TermCharEnabled : 1 ; ///< "The Bulk-IN transfer must terminate on the specified TermChar."; CAPABILITIES must list TermChar } bmTransferAttributes; uint8_t TermChar; uint8_t _reserved[2]; } usbtmc_msg_request_dev_dep_in; +TU_VERIFY_STATIC(sizeof(usbtmc_msg_request_dev_dep_in) == 12u, "struct wrong length"); + /* Bulk-in headers */ typedef struct TU_ATTR_PACKED { usbtmc_msg_header_t header; uint32_t TransferSize; - struct { + struct TU_ATTR_PACKED + { uint8_t EOM: 1; ///< Last byte of transfer is the end of the message uint8_t UsingTermChar: 1; ///< Support TermChar && Request.TermCharEnabled && last char in transfer is TermChar } bmTransferAttributes; uint8_t _reserved[3]; } usbtmc_msg_dev_dep_msg_in_header_t; +TU_VERIFY_STATIC(sizeof(usbtmc_msg_dev_dep_msg_in_header_t) == 12u, "struct wrong length"); /* Unsupported vendor things.... Are these ever used?*/ -typedef struct TU_ATTR_PACKED { +typedef struct TU_ATTR_PACKED +{ usbtmc_msg_header_t header ; ///< Header uint32_t TransferSize ; ///< Transfer size; LSB first uint8_t _reserved[4]; } usbtmc_msg_request_vendor_specific_out; -typedef struct TU_ATTR_PACKED { +TU_VERIFY_STATIC(sizeof(usbtmc_msg_request_vendor_specific_out) == 12u, "struct wrong length"); + +typedef struct TU_ATTR_PACKED +{ usbtmc_msg_header_t header ; ///< Header uint32_t TransferSize ; ///< Transfer size; LSB first uint8_t _reserved[4]; } usbtmc_msg_request_vendor_specific_in; +TU_VERIFY_STATIC(sizeof(usbtmc_msg_request_vendor_specific_in) == 12u, "struct wrong length"); + // Control request type should use tusb_control_request_t /* @@ -187,13 +201,15 @@ typedef struct TU_ATTR_PACKED { uint8_t _reserved; uint16_t bcdUSBTMC; ///< USBTMC_VERSION - struct { - uint8_t listenOnly :1; - uint8_t talkOnly :1; - uint8_t supportsIndicatorPulse :1; + struct TU_ATTR_PACKED + { + unsigned int listenOnly :1; + unsigned int talkOnly :1; + unsigned int supportsIndicatorPulse :1; } bmIntfcCapabilities; - struct { - uint8_t canEndBulkInOnTermChar :1; + struct TU_ATTR_PACKED + { + unsigned int canEndBulkInOnTermChar :1; } bmDevCapabilities; uint8_t _reserved2[6]; uint8_t _reserved3[12]; @@ -201,40 +217,51 @@ typedef struct TU_ATTR_PACKED { TU_VERIFY_STATIC(sizeof(usbtmc_response_capabilities_t) == 0x18, "struct wrong length"); +typedef struct TU_ATTR_PACKED +{ + uint8_t USBTMC_status; + struct TU_ATTR_PACKED + { + unsigned int BulkInFifoBytes :1; + } bmClear; +} usbtmc_get_clear_status_rsp_t; + +TU_VERIFY_STATIC(sizeof(usbtmc_get_clear_status_rsp_t) == 2u, "struct wrong length"); + typedef struct TU_ATTR_PACKED { uint8_t USBTMC_status; ///< usbtmc_status_enum uint8_t _reserved; uint16_t bcdUSBTMC; ///< USBTMC_VERSION - struct + struct TU_ATTR_PACKED { - uint8_t listenOnly :1; - uint8_t talkOnly :1; - uint8_t supportsIndicatorPulse :1; + unsigned int listenOnly :1; + unsigned int talkOnly :1; + unsigned int supportsIndicatorPulse :1; } bmIntfcCapabilities; - struct + struct TU_ATTR_PACKED { - uint8_t canEndBulkInOnTermChar :1; + unsigned int canEndBulkInOnTermChar :1; } bmDevCapabilities; uint8_t _reserved2[6]; uint16_t bcdUSB488; - struct + struct TU_ATTR_PACKED { - uint8_t is488_2 :1; - uint8_t supportsREN_GTL_LLO :1; - uint8_t supportsTrigger :1; + unsigned int is488_2 :1; + unsigned int supportsREN_GTL_LLO :1; + unsigned int supportsTrigger :1; } bmIntfcCapabilities488; - struct + struct TU_ATTR_PACKED { - uint8_t SCPI :1; - uint8_t SR1 :1; - uint8_t RL1 :1; - uint8_t DT1 :1; + unsigned int SCPI :1; + unsigned int SR1 :1; + unsigned int RL1 :1; + unsigned int DT1 :1; } bmDevCapabilities488; uint8_t _reserved3[8]; } usbtmc_response_capabilities_488_t; @@ -253,14 +280,15 @@ TU_VERIFY_STATIC(sizeof(usbtmc_read_stb_rsp_488_t) == 3u, "struct wrong length") typedef struct TU_ATTR_PACKET { union { - struct { - uint8_t bTag : 7; - uint8_t one : 1; + struct TU_ATTR_PACKED { + unsigned int bTag : 7; + unsigned int one : 1; } bNotify1Struct; uint8_t bNotify1; }; uint8_t StatusByte; } usbtmc_read_stb_interrupt_488_t; + TU_VERIFY_STATIC(sizeof(usbtmc_read_stb_interrupt_488_t) == 2u, "struct wrong length"); #endif diff --git a/src/class/usbtmc/usbtmc_device.c b/src/class/usbtmc/usbtmc_device.c index db0c95a32..7264125bb 100644 --- a/src/class/usbtmc/usbtmc_device.c +++ b/src/class/usbtmc/usbtmc_device.c @@ -170,6 +170,9 @@ bool usbtmcd_open(uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint16 uint8_t const * p_desc; uint8_t found_endpoints = 0; + + usbtmcd_reset(rhport); + // Perhaps there are other application specific class drivers, so don't assert here. if( itf_desc->bInterfaceClass != USBTMC_APP_CLASS) return false; @@ -232,6 +235,12 @@ bool usbtmcd_open(uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint16 void usbtmcd_reset(uint8_t rhport) { // FIXME: Do endpoints need to be closed here? + usbtmc_state.state = STATE_IDLE; + usbtmc_state.itf_id = 0xFF; + usbtmc_state.ep_bulk_in = 0; + usbtmc_state.ep_bulk_out = 0; + usbtmc_state.ep_int_in = 0; + (void)rhport; } @@ -376,15 +385,19 @@ bool usbtmcd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint bool usbtmcd_control_request(uint8_t rhport, tusb_control_request_t const * request) { + uint8_t tmcStatusCode = USBTMC_STATUS_FAILED; #if (USBTMC_CFG_ENABLE_488) ushort bTag; #endif // We only handle class requests, IN direction. + // (for now) if(request->bmRequestType_bit.type != TUSB_REQ_TYPE_CLASS) { return false; } + // Verification that we own the interface is unneeded since it's been routed to us specifically. + switch(request->bRequest) { // USBTMC required requests @@ -392,74 +405,100 @@ bool usbtmcd_control_request(uint8_t rhport, tusb_control_request_t const * requ case USBTMC_bREQUEST_CHECK_ABORT_BULK_OUT_STATUS: case USBTMC_bREQUEST_INITIATE_ABORT_BULK_IN: case USBTMC_bREQUEST_CHECK_ABORT_BULK_IN_STATUS: - TU_VERIFY(request->bmRequestType == 0xA2); // in,class,EP - TU_VERIFY(false); - break; + { + TU_VERIFY(request->bmRequestType == 0xA2); // in,class,EP + TU_VERIFY(request->wLength == 1u); + tmcStatusCode = USBTMC_STATUS_FAILED; + usbd_edpt_xfer(rhport, usbtmc_state.ep_int_in, (void*)&tmcStatusCode,sizeof(tmcStatusCode)); + return true; + } case USBTMC_bREQUEST_INITIATE_CLEAR: + { + TU_VERIFY(request->bmRequestType == 0xA1); // in,class,interface + TU_VERIFY(request->wLength == sizeof(tmcStatusCode)); + // After receiving an INITIATE_CLEAR request, the device must Halt the Bulk-OUT endpoint, queue the + // control endpoint response shown in Table 31, and clear all input buffers and output buffers. + usbd_edpt_stall(rhport, usbtmc_state.ep_bulk_out); + TU_VERIFY(usbtmcd_app_initiate_clear(rhport, &tmcStatusCode)); + TU_VERIFY(usbd_edpt_xfer(rhport, usbtmc_state.ep_int_in, (void*)&tmcStatusCode,sizeof(tmcStatusCode))); + return true; + } + case USBTMC_bREQUEST_CHECK_CLEAR_STATUS: - TU_VERIFY(request->bmRequestType == 0xA1); // in,class,interface - TU_VERIFY(false); - break; + { + usbtmc_get_clear_status_rsp_t clearStatusRsp = {0}; + TU_VERIFY(request->bmRequestType == 0xA1); // in,class,interface + TU_VERIFY(request->wLength == sizeof(clearStatusRsp)); + TU_VERIFY(usbtmcd_app_get_clear_status(rhport, &clearStatusRsp)); + + TU_VERIFY(usbd_edpt_xfer(rhport, usbtmc_state.ep_int_in, (void*)&clearStatusRsp,sizeof(clearStatusRsp))); + return true; + } case USBTMC_bREQUEST_GET_CAPABILITIES: - TU_VERIFY(request->bmRequestType == 0xA1); // in,class,interface - TU_VERIFY(request->wValue == 0x0000); - TU_VERIFY(request->wIndex == usbtmc_state.itf_id); - TU_VERIFY(request->wLength == sizeof(usbtmcd_app_capabilities)); - TU_VERIFY(tud_control_xfer(rhport, request, (void*)&usbtmcd_app_capabilities, sizeof(usbtmcd_app_capabilities))); - return true; + { + TU_VERIFY(request->bmRequestType == 0xA1); // in,class,interface + TU_VERIFY(request->wLength == sizeof(usbtmcd_app_capabilities)); + TU_VERIFY(tud_control_xfer(rhport, request, (void*)&usbtmcd_app_capabilities, sizeof(usbtmcd_app_capabilities))); + return true; + } // USBTMC Optional Requests case USBTMC_bREQUEST_INDICATOR_PULSE: // Optional - TU_VERIFY(request->bmRequestType == 0xA1); // in,class,interface - TU_VERIFY(usbtmcd_app_capabilities.bmIntfcCapabilities.supportsIndicatorPulse); - uint8_t tmcResult; - TU_VERIFY(usbtmcd_app_indicator_pluse(rhport, request, &tmcResult)); - TU_VERIFY(tud_control_xfer(rhport, request, (void*)&tmcResult, sizeof(tmcResult))); - - return true; - + { + TU_VERIFY(request->bmRequestType == 0xA1); // in,class,interface + TU_VERIFY(request->wLength == sizeof(tmcStatusCode)); + TU_VERIFY(usbtmcd_app_capabilities.bmIntfcCapabilities.supportsIndicatorPulse); + TU_VERIFY(usbtmcd_app_indicator_pluse(rhport, request, &tmcStatusCode)); + TU_VERIFY(tud_control_xfer(rhport, request, (void*)&tmcStatusCode, sizeof(tmcStatusCode))); + return true; + } #if (USBTMC_CFG_ENABLE_488) + // USB488 required requests case USBTMC488_bREQUEST_READ_STATUS_BYTE: - TU_VERIFY(request->bmRequestType == 0xA1); // in,class,interface - - bTag = request->wValue & 0x7F; - TU_VERIFY(request->bmRequestType == 0xA1); - TU_VERIFY((request->wValue & (~0x7F)) == 0u); // Other bits are required to be zero - TU_VERIFY(bTag >= 0x02 && bTag <= 127); - TU_VERIFY(request->wIndex == usbtmc_state.itf_id); - TU_VERIFY(request->wLength == 0x0003); - usbtmc_read_stb_rsp_488_t rsp; - rsp.bTag = (uint8_t)bTag; - if(usbtmc_state.ep_int_in != 0) { - rsp.USBTMC_status = USBTMC_STATUS_SUCCESS; - rsp.statusByte = 0x00; // Use interrupt endpoint, instead. - - usbtmc_read_stb_interrupt_488_t intMsg = + usbtmc_read_stb_rsp_488_t rsp; + TU_VERIFY(request->bmRequestType == 0xA1); // in,class,interface + TU_VERIFY(request->wLength == sizeof(rsp)); // in,class,interface + + bTag = request->wValue & 0x7F; + TU_VERIFY(request->bmRequestType == 0xA1); + TU_VERIFY((request->wValue & (~0x7F)) == 0u); // Other bits are required to be zero + TU_VERIFY(bTag >= 0x02 && bTag <= 127); + TU_VERIFY(request->wIndex == usbtmc_state.itf_id); + TU_VERIFY(request->wLength == 0x0003); + rsp.bTag = (uint8_t)bTag; + if(usbtmc_state.ep_int_in != 0) { - .bNotify1 = (uint8_t)(0x80 | bTag), - .StatusByte = usbtmcd_app_get_stb(rhport, &(rsp.USBTMC_status)) - }; - usbd_edpt_xfer(rhport, usbtmc_state.ep_int_in, (void*)&intMsg,sizeof(intMsg)); + rsp.USBTMC_status = USBTMC_STATUS_SUCCESS; + rsp.statusByte = 0x00; // Use interrupt endpoint, instead. - } - else - { - rsp.statusByte = usbtmcd_app_get_stb(rhport, &(rsp.USBTMC_status)); - } - TU_VERIFY(tud_control_xfer(rhport, request, (void*)&rsp, sizeof(rsp))); - return true; + usbtmc_read_stb_interrupt_488_t intMsg = + { + .bNotify1 = (uint8_t)(0x80 | bTag), + .StatusByte = usbtmcd_app_get_stb(rhport, &(rsp.USBTMC_status)) + }; + usbd_edpt_xfer(rhport, usbtmc_state.ep_int_in, (void*)&intMsg,sizeof(intMsg)); + } + else + { + rsp.statusByte = usbtmcd_app_get_stb(rhport, &(rsp.USBTMC_status)); + } + TU_VERIFY(tud_control_xfer(rhport, request, (void*)&rsp, sizeof(rsp))); + return true; + } // USB488 optional requests case USBTMC488_bREQUEST_REN_CONTROL: case USBTMC488_bREQUEST_GO_TO_LOCAL: case USBTMC488_bREQUEST_LOCAL_LOCKOUT: - TU_VERIFY(request->bmRequestType == 0xA1); // in,class,interface - TU_VERIFY(false); - return false; + { + TU_VERIFY(request->bmRequestType == 0xA1); // in,class,interface + TU_VERIFY(false); + return false; + } #endif default: diff --git a/src/class/usbtmc/usbtmc_device.h b/src/class/usbtmc/usbtmc_device.h index 84640b136..702f595e6 100644 --- a/src/class/usbtmc/usbtmc_device.h +++ b/src/class/usbtmc/usbtmc_device.h @@ -64,6 +64,10 @@ bool usbtmcd_app_msgBulkIn_request(uint8_t rhport, usbtmc_msg_request_dev_dep_in bool usbtmcd_app_msgBulkIn_complete(uint8_t rhport); +bool usbtmcd_app_initiate_clear(uint8_t rhport, uint8_t *tmcResult); + +bool usbtmcd_app_get_clear_status(uint8_t rhport, usbtmc_get_clear_status_rsp_t *rsp); + // Indicator pulse should be 0.5 to 1.0 seconds long TU_ATTR_WEAK bool usbtmcd_app_indicator_pluse(uint8_t rhport, tusb_control_request_t const * msg, uint8_t *tmcResult); -- cgit v1.3.1 From e234998c6c8eeedd3ae2e28a3015afd6e910952d Mon Sep 17 00:00:00 2001 From: Nathan Conrad Date: Sun, 15 Sep 2019 14:57:02 -0400 Subject: More proper handling of clear. --- examples/device/usbtmc/src/usbtmc_app.c | 23 +++++++++++-- src/class/usbtmc/usbtmc.h | 8 ++--- src/class/usbtmc/usbtmc_device.c | 58 ++++++++++++++++++++++++--------- src/class/usbtmc/usbtmc_device.h | 10 +++--- 4 files changed, 71 insertions(+), 28 deletions(-) (limited to 'src') diff --git a/examples/device/usbtmc/src/usbtmc_app.c b/examples/device/usbtmc/src/usbtmc_app.c index a41d911d2..7328b6598 100644 --- a/examples/device/usbtmc/src/usbtmc_app.c +++ b/examples/device/usbtmc/src/usbtmc_app.c @@ -117,6 +117,7 @@ bool usbtmcd_app_msgBulkIn_complete(uint8_t rhport) bool usbtmcd_app_msgBulkIn_request(uint8_t rhport, usbtmc_msg_request_dev_dep_in const * request) { + (void)rhport; rspMsg.header.MsgID = request->header.MsgID, rspMsg.header.bTag = request->header.bTag, rspMsg.header.bTagInverse = request->header.bTagInverse; @@ -135,6 +136,8 @@ void usbtmc_app_task_iter(void) { uint8_t const rhport = 0; switch(queryState) { + case 0: + break; case 1: queryDelayStart = board_millis(); queryState = 2; @@ -166,18 +169,34 @@ void usbtmc_app_task_iter(void) { } } -bool usbtmcd_app_initiate_clear(uint8_t rhport, uint8_t *tmcResult) { +bool usbtmcd_app_initiate_clear(uint8_t rhport, uint8_t *tmcResult) +{ (void)rhport; *tmcResult = USBTMC_STATUS_SUCCESS; + queryState = 0; + bulkInStarted = false; + status = 0; return true; } -bool usbtmcd_app_get_clear_status(uint8_t rhport, usbtmc_get_clear_status_rsp_t *rsp) { +bool usbtmcd_app_get_clear_status(uint8_t rhport, usbtmc_get_clear_status_rsp_t *rsp) +{ (void)rhport; + queryState = 0; + bulkInStarted = false; + status = 0; rsp->USBTMC_status = USBTMC_STATUS_SUCCESS; rsp->bmClear.BulkInFifoBytes = 0u; return true; } +void usmtmcd_app_bulkIn_clearFeature(uint8_t rhport) +{ + (void)rhport; +} +void usmtmcd_app_bulkOut_clearFeature(uint8_t rhport) +{ + (void)rhport; +} // Return status byte, but put the transfer result status code in the rspResult argument. uint8_t usbtmcd_app_get_stb(uint8_t rhport, uint8_t *tmcResult) diff --git a/src/class/usbtmc/usbtmc.h b/src/class/usbtmc/usbtmc.h index d24a72cb6..2e4999c2d 100644 --- a/src/class/usbtmc/usbtmc.h +++ b/src/class/usbtmc/usbtmc.h @@ -279,13 +279,11 @@ TU_VERIFY_STATIC(sizeof(usbtmc_read_stb_rsp_488_t) == 3u, "struct wrong length") typedef struct TU_ATTR_PACKET { - union { - struct TU_ATTR_PACKED { + struct TU_ATTR_PACKED + { unsigned int bTag : 7; unsigned int one : 1; - } bNotify1Struct; - uint8_t bNotify1; - }; + } bNotify1; uint8_t StatusByte; } usbtmc_read_stb_interrupt_488_t; diff --git a/src/class/usbtmc/usbtmc_device.c b/src/class/usbtmc/usbtmc_device.c index 7264125bb..cf8a5069a 100644 --- a/src/class/usbtmc/usbtmc_device.c +++ b/src/class/usbtmc/usbtmc_device.c @@ -115,18 +115,19 @@ bool usbtmcd_transmit_dev_msg_data( const void *data) { TU_ASSERT(usbtmc_state.state == STATE_TX_REQUESTED); +#ifndef NDEBUG TU_ASSERT(hdr->TransferSize > 0u); - if(hdr->bmTransferAttributes.UsingTermChar) { TU_ASSERT(usbtmcd_app_capabilities.bmDevCapabilities.canEndBulkInOnTermChar); TU_ASSERT(termCharRequested); TU_ASSERT(((uint8_t*)data)[hdr->TransferSize-1] == termChar); } +#endif // Copy in the header memcpy(usbtmc_state.ep_bulk_in_buf, hdr, sizeof(*hdr)); - uint packetLen = sizeof(*hdr); + size_t packetLen = sizeof(*hdr); // Single-packet transfer if((packetLen + hdr->TransferSize) <= USBTMCD_MAX_PACKET_SIZE) { @@ -155,13 +156,14 @@ bool usbtmcd_transmit_dev_msg_data( void usbtmcd_init(void) { -#if USBTMC_CFG_ENABLE_488 - if(usbtmcd_app_capabilities.bmIntfcCapabilities488.supportsTrigger) - TU_ASSERT(&usbtmcd_app_msg_trigger != NULL,); +#ifndef NDEBUG +# if USBTMC_CFG_ENABLE_488 + if(usbtmcd_app_capabilities.bmIntfcCapabilities488.supportsTrigger) + TU_ASSERT(&usbtmcd_app_msg_trigger != NULL,); +# endif + if(usbtmcd_app_capabilities.bmIntfcCapabilities.supportsIndicatorPulse) + TU_ASSERT(&usbtmcd_app_indicator_pluse != NULL,); #endif - if(usbtmcd_app_capabilities.bmIntfcCapabilities.supportsIndicatorPulse) - TU_ASSERT(&usbtmcd_app_indicator_pluse != NULL,); - } bool usbtmcd_open(uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint16_t *p_length) @@ -204,8 +206,10 @@ bool usbtmcd_open(uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint16 break; case TUSB_XFER_INTERRUPT: +#ifndef NDEBUG TU_ASSERT(tu_edpt_dir(ep_desc->bEndpointAddress) == TUSB_DIR_IN); TU_ASSERT(usbtmc_state.ep_int_in == 0); +#endif usbtmc_state.ep_int_in = ep_desc->bEndpointAddress; break; default: @@ -219,6 +223,7 @@ bool usbtmcd_open(uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint16 } // bulk endpoints are required, but interrupt IN is optional +#ifndef NDEBUG TU_ASSERT(usbtmc_state.ep_bulk_in != 0); TU_ASSERT(usbtmc_state.ep_bulk_out != 0); if (itf_desc->bNumEndpoints == 2) { @@ -228,6 +233,7 @@ bool usbtmcd_open(uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint16 { TU_ASSERT(usbtmc_state.ep_int_in != 0); } +#endif TU_VERIFY( usbd_edpt_xfer(rhport, usbtmc_state.ep_bulk_out, usbtmc_state.ep_bulk_out_buf, 64)); return true; @@ -363,7 +369,7 @@ bool usbtmcd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint } else // short packet { - uint packetLen = usbtmc_state.transfer_size_remaining; + size_t packetLen = usbtmc_state.transfer_size_remaining; memcpy(usbtmc_state.ep_bulk_in_buf, usbtmc_state.devInBuffer, usbtmc_state.transfer_size_remaining); while((packetLen % 4) != 0) { @@ -387,8 +393,25 @@ bool usbtmcd_control_request(uint8_t rhport, tusb_control_request_t const * requ uint8_t tmcStatusCode = USBTMC_STATUS_FAILED; #if (USBTMC_CFG_ENABLE_488) - ushort bTag; + uint8_t bTag; #endif + + if((request->bmRequestType_bit.type == TUSB_REQ_TYPE_STANDARD) && + (request->bmRequestType_bit.recipient == TUSB_REQ_RCPT_ENDPOINT) && + (request->bRequest == TUSB_REQ_CLEAR_FEATURE) && + (request->wValue == TUSB_REQ_FEATURE_EDPT_HALT)) + { + if((request->wIndex) == usbtmc_state.ep_bulk_out) + { + usmtmcd_app_bulkOut_clearFeature(rhport); + } + else if ((request->wIndex) == usbtmc_state.ep_bulk_in) + { + usmtmcd_app_bulkIn_clearFeature(rhport); + } + return false; // We want USBD core to handle sending the status response, and clear the stall condition + } + // We only handle class requests, IN direction. // (for now) if(request->bmRequestType_bit.type != TUSB_REQ_TYPE_CLASS) @@ -409,7 +432,7 @@ bool usbtmcd_control_request(uint8_t rhport, tusb_control_request_t const * requ TU_VERIFY(request->bmRequestType == 0xA2); // in,class,EP TU_VERIFY(request->wLength == 1u); tmcStatusCode = USBTMC_STATUS_FAILED; - usbd_edpt_xfer(rhport, usbtmc_state.ep_int_in, (void*)&tmcStatusCode,sizeof(tmcStatusCode)); + usbd_edpt_xfer(rhport, 0u, (void*)&tmcStatusCode,sizeof(tmcStatusCode)); return true; } @@ -421,7 +444,7 @@ bool usbtmcd_control_request(uint8_t rhport, tusb_control_request_t const * requ // control endpoint response shown in Table 31, and clear all input buffers and output buffers. usbd_edpt_stall(rhport, usbtmc_state.ep_bulk_out); TU_VERIFY(usbtmcd_app_initiate_clear(rhport, &tmcStatusCode)); - TU_VERIFY(usbd_edpt_xfer(rhport, usbtmc_state.ep_int_in, (void*)&tmcStatusCode,sizeof(tmcStatusCode))); + TU_VERIFY(tud_control_xfer(rhport, request, (void*)&tmcStatusCode,sizeof(tmcStatusCode))); return true; } @@ -432,7 +455,7 @@ bool usbtmcd_control_request(uint8_t rhport, tusb_control_request_t const * requ TU_VERIFY(request->wLength == sizeof(clearStatusRsp)); TU_VERIFY(usbtmcd_app_get_clear_status(rhport, &clearStatusRsp)); - TU_VERIFY(usbd_edpt_xfer(rhport, usbtmc_state.ep_int_in, (void*)&clearStatusRsp,sizeof(clearStatusRsp))); + TU_VERIFY(tud_control_xfer(rhport, request, (void*)&clearStatusRsp,sizeof(clearStatusRsp))); return true; } @@ -477,11 +500,13 @@ bool usbtmcd_control_request(uint8_t rhport, tusb_control_request_t const * requ usbtmc_read_stb_interrupt_488_t intMsg = { - .bNotify1 = (uint8_t)(0x80 | bTag), - .StatusByte = usbtmcd_app_get_stb(rhport, &(rsp.USBTMC_status)) + .bNotify1 = { + .one = 1, + .bTag = bTag & 0x7Fu, + }, + .StatusByte = usbtmcd_app_get_stb(rhport, &(rsp.USBTMC_status)) }; usbd_edpt_xfer(rhport, usbtmc_state.ep_int_in, (void*)&intMsg,sizeof(intMsg)); - } else { @@ -503,6 +528,7 @@ bool usbtmcd_control_request(uint8_t rhport, tusb_control_request_t const * requ default: TU_VERIFY(false); + return false; } TU_VERIFY(false); } diff --git a/src/class/usbtmc/usbtmc_device.h b/src/class/usbtmc/usbtmc_device.h index 702f595e6..35d4da438 100644 --- a/src/class/usbtmc/usbtmc_device.h +++ b/src/class/usbtmc/usbtmc_device.h @@ -56,13 +56,13 @@ extern usbtmc_response_capabilities_t const usbtmcd_app_capabilities; #endif bool usbtmcd_app_msgBulkOut_start(uint8_t rhport, usbtmc_msg_request_dev_dep_out const * msgHeader); - // transfer_complete does not imply that a message is complete. bool usbtmcd_app_msg_data(uint8_t rhport, void *data, size_t len, bool transfer_complete); +void usmtmcd_app_bulkOut_clearFeature(uint8_t rhport); // Notice to clear and abort the pending BULK out transfer bool usbtmcd_app_msgBulkIn_request(uint8_t rhport, usbtmc_msg_request_dev_dep_in const * request); - bool usbtmcd_app_msgBulkIn_complete(uint8_t rhport); +void usmtmcd_app_bulkIn_clearFeature(uint8_t rhport); // Notice to clear and abort the pending BULK out transfer bool usbtmcd_app_initiate_clear(uint8_t rhport, uint8_t *tmcResult); @@ -104,10 +104,10 @@ void usbtmcd_init(void); *************************************************************/ #define USBTMC_APP_CLASS TUSB_CLASS_APPLICATION_SPECIFIC -#define USBTMC_APP_SUBCLASS 0x03 +#define USBTMC_APP_SUBCLASS 0x03u -#define USBTMC_PROTOCOL_STD 0x00 -#define USBTMC_PROTOCOL_USB488 0x01 +#define USBTMC_PROTOCOL_STD 0x00u +#define USBTMC_PROTOCOL_USB488 0x01u // Interface number, number of endpoints, EP string index, USB_TMC_PROTOCOL*, bulk-out endpoint ID, // bulk-in endpoint ID -- cgit v1.3.1 From 45871001e6d18503f05733ae770538e622313584 Mon Sep 17 00:00:00 2001 From: Nathan Conrad Date: Tue, 17 Sep 2019 13:24:43 -0400 Subject: Changes1... --- src/class/usbtmc/usbtmc.h | 9 ++ src/class/usbtmc/usbtmc_device.c | 268 ++++++++++++++++++++++++++++++--------- 2 files changed, 220 insertions(+), 57 deletions(-) (limited to 'src') diff --git a/src/class/usbtmc/usbtmc.h b/src/class/usbtmc/usbtmc.h index 2e4999c2d..6893c3743 100644 --- a/src/class/usbtmc/usbtmc.h +++ b/src/class/usbtmc/usbtmc.h @@ -228,6 +228,15 @@ typedef struct TU_ATTR_PACKED TU_VERIFY_STATIC(sizeof(usbtmc_get_clear_status_rsp_t) == 2u, "struct wrong length"); +// Used for both abort bulk IN and bulk OUT +typedef struct TU_ATTR_PACKED +{ + uint8_t USBTMC_status; + uint8_t bTag; +} usbtmc_initiate_abort_rsp_t; + +TU_VERIFY_STATIC(sizeof(usbtmc_get_clear_status_rsp_t) == 2u, "struct wrong length"); + typedef struct TU_ATTR_PACKED { uint8_t USBTMC_status; ///< usbtmc_status_enum diff --git a/src/class/usbtmc/usbtmc_device.c b/src/class/usbtmc/usbtmc_device.c index cf8a5069a..6d562641e 100644 --- a/src/class/usbtmc/usbtmc_device.c +++ b/src/class/usbtmc/usbtmc_device.c @@ -8,7 +8,7 @@ /* * The MIT License (MIT) * - * Copyright (c) 2019 N Conrad + * Copyright (c) 2019 Nathan Conrad * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -33,31 +33,53 @@ #include "tusb_option.h" -// We don't do any cross-task anything here (everything is in tud or interrupt context). -// You must ensure thread safety in your own app. +// Synchronization is needed in some spots. +// These functions should NOT be called from interrupts. + +/* The library is designed that its functions can be called by any user task, with need for + * additional locking. In the case of "no OS", this task is never preempted other than by + * interrupts, and the USBTMC code isn't called by interrupts, so all is OK. In the case + * of an OS, this class driver uses the OSAL to perform locking. The code uses a single lock + * and does not call outside of this class with a lock held, so deadlocks won't happen. + * + * This module's application-facing functions are not reentrant. The application must + * only call them from a single thread (or implement its own locking). + */ -//Limitations (not planned to be implemented): -// "vendor-specific" commands are not handled +//Limitations: +// "vendor-specific" commands are not handled. // Dealing with "termchar" must be handled by the application layer, // though additional error checking is does in this module. +// talkOnly and listenOnly are NOT supported. They're no permitted +// in USB488, anyway. + +/* Supported: + * + * Notification pulse + * Trigger + * Read status byte (both by interrupt endpoint and control message) + * + */ + // TODO: // USBTMC 3.2.2 error conditions not strictly followed // No local lock-out, REN, or GTL. // Cannot handle clear. -// Not all "capabilities" supported // Clear message available status byte at the correct time? (488 4.3.1.3) -// Split transfers +// Abort bulk in/out // No CLEAR_FEATURE/HALT no EP (yet) -// No aborting transfers. #if (TUSB_OPT_DEVICE_ENABLED && CFG_TUD_USBTMC) +#include #include "usbtmc.h" #include "usbtmc_device.h" #include "device/dcd.h" #include "device/usbd.h" +#include "uart_util.h" +static char logMsg[150]; // FIXME: I shouldn't need to include _pvt headers. #include "device/usbd_pvt.h" @@ -70,21 +92,31 @@ typedef enum STATE_IDLE, STATE_RCV, STATE_TX_REQUESTED, - STATE_TX_INITIATED + STATE_TX_INITIATED, + STATE_CLEARING, + STATE_ABORTING_BULK_IN, + STATE_ABORTING_BULK_OUT, + STATE_NUM_STATES } usbtmcd_state_enum; typedef struct { - usbtmcd_state_enum state; + volatile usbtmcd_state_enum state; + uint8_t itf_id; uint8_t ep_bulk_in; uint8_t ep_bulk_out; uint8_t ep_int_in; - uint8_t ep_bulk_in_buf[64]; - uint8_t ep_bulk_out_buf[64]; - uint8_t lastTag; + // IN buffer is only used for first packet, not the remainder + // in order to deal with prepending header + uint8_t ep_bulk_in_buf[USBTMCD_MAX_PACKET_SIZE]; + // OUT buffer receives one packet at a time + uint8_t ep_bulk_out_buf[USBTMCD_MAX_PACKET_SIZE]; + uint32_t transfer_size_remaining; // also used for requested length for bulk IN. + + uint8_t lastBulkOutTag; // used for aborts (mostly) + uint8_t lastBulkInTag; // used for aborts (mostly) - uint32_t transfer_size_remaining; uint8_t const * devInBuffer; } usbtmc_interface_state_t; @@ -97,39 +129,63 @@ static usbtmc_interface_state_t usbtmc_state = .ep_int_in = 0 }; -// We want everything to fit nicely in a single packet, so lets require EP size >32 -// I'm not sure if this is really necessary, though. +// We need all headers to fit in a single packet in this implementation. TU_VERIFY_STATIC(USBTMCD_MAX_PACKET_SIZE >= 32u,"USBTMC dev EP packet size too small"); - +TU_VERIFY_STATIC( + (sizeof(usbtmc_state.ep_bulk_in_buf) % USBTMCD_MAX_PACKET_SIZE) == 0, + "packet buffer must be a multiple of the packet size"); static bool handle_devMsgOutStart(uint8_t rhport, void *data, size_t len); static bool handle_devMsgOut(uint8_t rhport, void *data, size_t len, size_t packetLen); + +osal_mutex_def_t usbtmcLockBuffer; +static osal_mutex_t usbtmcLock; + +// Our own private lock, mostly for the state variable. +#define criticalEnter() do {osal_mutex_lock(usbtmcLock,OSAL_TIMEOUT_WAIT_FOREVER); } while (0) +#define criticalLeave() do {osal_mutex_unlock(usbtmcLock); } while (0) + // called from app // We keep a reference to the buffer, so it MUST not change until the app is // notified that the transfer is complete. // length of data is specified in the hdr. + +// We can't just send the whole thing at once because we need to concatanate the +// header with the data. bool usbtmcd_transmit_dev_msg_data( uint8_t rhport, - usbtmc_msg_dev_dep_msg_in_header_t const * hdr, - const void *data) + const void * data, size_t len, + bool usingTermChar) { - TU_ASSERT(usbtmc_state.state == STATE_TX_REQUESTED); + const unsigned int txBufLen = sizeof(usbtmc_state.ep_bulk_in_buf); + #ifndef NDEBUG - TU_ASSERT(hdr->TransferSize > 0u); - if(hdr->bmTransferAttributes.UsingTermChar) + TU_ASSERT(len > 0u); + TU_ASSERT(len <= usbtmc_state.transfer_size_remaining); + if(usingTermChar) { TU_ASSERT(usbtmcd_app_capabilities.bmDevCapabilities.canEndBulkInOnTermChar); TU_ASSERT(termCharRequested); - TU_ASSERT(((uint8_t*)data)[hdr->TransferSize-1] == termChar); + TU_ASSERT(((uint8_t*)data)[len-1] == termChar); } #endif + TU_VERIFY(usbtmc_state.state == STATE_TX_REQUESTED); + usbtmc_msg_dev_dep_msg_in_header_t *hdr = (usbtmc_msg_dev_dep_msg_in_header_t*)usbtmc_state.ep_bulk_in_buf; + memset(hdr, 0x00, sizeof(*hdr)); + hdr->header.MsgID = USBTMC_MSGID_DEV_DEP_MSG_IN; + hdr->header.bTag = usbtmc_state.lastBulkInTag; + hdr->header.bTagInverse = (uint8_t)~(usbtmc_state.lastBulkInTag); + hdr->TransferSize = len; + hdr->bmTransferAttributes.EOM = 1u; + hdr->bmTransferAttributes.UsingTermChar = usingTermChar; + // Copy in the header - memcpy(usbtmc_state.ep_bulk_in_buf, hdr, sizeof(*hdr)); size_t packetLen = sizeof(*hdr); - // Single-packet transfer - if((packetLen + hdr->TransferSize) <= USBTMCD_MAX_PACKET_SIZE) + + // If it fits in a single trasnmission: + if((packetLen + hdr->TransferSize) <= txBufLen) { memcpy((uint8_t*)(usbtmc_state.ep_bulk_in_buf) + packetLen, data, hdr->TransferSize); packetLen = (uint16_t)(packetLen+ hdr->TransferSize); @@ -142,15 +198,23 @@ bool usbtmcd_transmit_dev_msg_data( usbtmc_state.transfer_size_remaining = 0; usbtmc_state.devInBuffer = NULL; } - else + else /* partial packet */ { - memcpy((uint8_t*)(usbtmc_state.ep_bulk_in_buf) + packetLen, data, USBTMCD_MAX_PACKET_SIZE - packetLen); - usbtmc_state.transfer_size_remaining = hdr->TransferSize - (USBTMCD_MAX_PACKET_SIZE - packetLen); - usbtmc_state.devInBuffer += (USBTMCD_MAX_PACKET_SIZE - packetLen); - packetLen = USBTMCD_MAX_PACKET_SIZE; + memcpy((uint8_t*)(usbtmc_state.ep_bulk_in_buf) + packetLen, data, txBufLen - packetLen); + usbtmc_state.devInBuffer += txBufLen - packetLen; + usbtmc_state.transfer_size_remaining = hdr->TransferSize - (txBufLen - packetLen); + packetLen = txBufLen; } - usbtmc_state.state = STATE_TX_INITIATED; - TU_VERIFY( usbd_edpt_xfer(rhport, usbtmc_state.ep_bulk_in, usbtmc_state.ep_bulk_in_buf,(uint16_t)packetLen)); + + + criticalEnter(); + { + TU_VERIFY(usbtmc_state.state == STATE_TX_REQUESTED); + usbtmc_state.state = STATE_TX_INITIATED; + } + criticalLeave(); + + TU_VERIFY( usbd_edpt_xfer(rhport, usbtmc_state.ep_bulk_in, usbtmc_state.ep_bulk_in_buf, (uint16_t)packetLen)); return true; } @@ -158,12 +222,17 @@ void usbtmcd_init(void) { #ifndef NDEBUG # if USBTMC_CFG_ENABLE_488 - if(usbtmcd_app_capabilities.bmIntfcCapabilities488.supportsTrigger) - TU_ASSERT(&usbtmcd_app_msg_trigger != NULL,); + if(usbtmcd_app_capabilities.bmIntfcCapabilities488.supportsTrigger) + TU_ASSERT(&usbtmcd_app_msg_trigger != NULL,); + // Per USB488 spec: table 8 + TU_ASSERT(!usbtmcd_app_capabilities.bmIntfcCapabilities.listenOnly,); + TU_ASSERT(!usbtmcd_app_capabilities.bmIntfcCapabilities.talkOnly,); # endif if(usbtmcd_app_capabilities.bmIntfcCapabilities.supportsIndicatorPulse) TU_ASSERT(&usbtmcd_app_indicator_pluse != NULL,); #endif + + usbtmcLock = osal_mutex_create(&usbtmcLockBuffer); } bool usbtmcd_open(uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint16_t *p_length) @@ -226,10 +295,17 @@ bool usbtmcd_open(uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint16 #ifndef NDEBUG TU_ASSERT(usbtmc_state.ep_bulk_in != 0); TU_ASSERT(usbtmc_state.ep_bulk_out != 0); - if (itf_desc->bNumEndpoints == 2) { + if (itf_desc->bNumEndpoints == 2) + { TU_ASSERT(usbtmc_state.ep_int_in == 0); } - else if (itf_desc->bNumEndpoints == 2) + else if (itf_desc->bNumEndpoints == 3) + { + TU_ASSERT(usbtmc_state.ep_int_in != 0); + } + + if(usbtmcd_app_capabilities.bmIntfcCapabilities488.is488_2 || + usbtmcd_app_capabilities.bmDevCapabilities488.SR1) { TU_ASSERT(usbtmc_state.ep_int_in != 0); } @@ -286,12 +362,22 @@ static bool handle_devMsgIn(uint8_t rhport, void *data, size_t len) { TU_VERIFY(len == sizeof(usbtmc_msg_request_dev_dep_in)); usbtmc_msg_request_dev_dep_in *msg = (usbtmc_msg_request_dev_dep_in*)data; - TU_VERIFY(usbtmc_state.state == STATE_IDLE); - usbtmc_state.state = STATE_TX_REQUESTED; - usbtmc_state.transfer_size_remaining = msg->TransferSize; + + sprintf(logMsg," handle_devMsgIn len=%ul\r\n",len); + uart_tx_str_sync(logMsg); + + criticalEnter(); + { + TU_VERIFY(usbtmc_state.state == STATE_IDLE); + usbtmc_state.state = STATE_TX_REQUESTED; + usbtmc_state.lastBulkInTag = msg->header.bTag; + usbtmc_state.transfer_size_remaining = msg->TransferSize; + } + criticalLeave(); termCharRequested = msg->bmTransferAttributes.TermCharEnabled; termChar = msg->TermChar; + if(termCharRequested) TU_VERIFY(usbtmcd_app_capabilities.bmDevCapabilities.canEndBulkInOnTermChar); @@ -302,8 +388,17 @@ static bool handle_devMsgIn(uint8_t rhport, void *data, size_t len) bool usbtmcd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes) { TU_VERIFY(result == XFER_RESULT_SUCCESS); + uart_tx_str_sync("USBTMC Xfer CB" ); + sprintf(logMsg," STATE=%lu ", (uint32_t)usbtmc_state.state); + uart_tx_str_sync(logMsg); + + if(usbtmc_state.state == STATE_CLEARING) { + return true; /* I think we can ignore everything here */ + } + if(ep_addr == usbtmc_state.ep_bulk_out) { + uart_tx_str_sync("OUT"); switch(usbtmc_state.state) { case STATE_IDLE: @@ -312,15 +407,19 @@ bool usbtmcd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint uint8_t invInvTag = (uint8_t)~(msg->header.bTagInverse); TU_VERIFY(msg->header.bTag == invInvTag); TU_VERIFY(msg->header.bTag != 0x00); - usbtmc_state.lastTag = msg->header.bTag; + + sprintf(logMsg," type=%lu\r\n",(uint32_t)msg->header.MsgID); + uart_tx_str_sync(logMsg); switch(msg->header.MsgID) { case USBTMC_MSGID_DEV_DEP_MSG_OUT: TU_VERIFY(handle_devMsgOutStart(rhport, msg, xferred_bytes)); TU_VERIFY(usbd_edpt_xfer(rhport, usbtmc_state.ep_bulk_out, usbtmc_state.ep_bulk_out_buf, USBTMCD_MAX_PACKET_SIZE)); + usbtmc_state.lastBulkOutTag = msg->header.bTag; break; case USBTMC_MSGID_DEV_DEP_MSG_IN: + uart_tx_sync("Handling msg in req\r\n", 21); TU_VERIFY(handle_devMsgIn(rhport, msg, xferred_bytes)); break; @@ -336,6 +435,7 @@ bool usbtmcd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint case USBTMC_MSGID_VENDOR_SPECIFIC_MSG_OUT: case USBTMC_MSGID_VENDOR_SPECIFIC_IN: default: + TU_VERIFY(false); return false; } @@ -347,12 +447,22 @@ bool usbtmcd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint case STATE_TX_REQUESTED: case STATE_TX_INITIATED: + case STATE_ABORTING_BULK_IN: + case STATE_ABORTING_BULK_OUT: default: + if(msg == NULL) + sprintf(logMsg," Unknown received control?\r\n "); + else { + sprintf(logMsg," msg=%lu\r\n ", (uint32_t)msg->header.MsgID); + } + uart_tx_str_sync(logMsg); TU_VERIFY(false); } } else if(ep_addr == usbtmc_state.ep_bulk_in) { + sprintf(logMsg,"IN\r\n"); + uart_tx_str_sync(logMsg); TU_ASSERT(usbtmc_state.state == STATE_TX_INITIATED); if(usbtmc_state.transfer_size_remaining == 0) { @@ -360,14 +470,14 @@ bool usbtmcd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint TU_VERIFY(usbtmcd_app_msgBulkIn_complete(rhport)); TU_VERIFY( usbd_edpt_xfer(rhport, usbtmc_state.ep_bulk_out, usbtmc_state.ep_bulk_out_buf, USBTMCD_MAX_PACKET_SIZE)); } - else if(usbtmc_state.transfer_size_remaining >= USBTMCD_MAX_PACKET_SIZE) + else if(usbtmc_state.transfer_size_remaining > sizeof(usbtmc_state.devInBuffer)) { - memcpy(usbtmc_state.ep_bulk_in_buf, usbtmc_state.devInBuffer, USBTMCD_MAX_PACKET_SIZE); - usbtmc_state.devInBuffer += USBTMCD_MAX_PACKET_SIZE; - usbtmc_state.transfer_size_remaining -= USBTMCD_MAX_PACKET_SIZE; - TU_VERIFY( usbd_edpt_xfer(rhport, usbtmc_state.ep_bulk_in, usbtmc_state.ep_bulk_in_buf,USBTMCD_MAX_PACKET_SIZE)); + memcpy(usbtmc_state.ep_bulk_in_buf, usbtmc_state.devInBuffer, sizeof(usbtmc_state.ep_bulk_in_buf)); + usbtmc_state.devInBuffer += sizeof(usbtmc_state.devInBuffer); + usbtmc_state.transfer_size_remaining -= sizeof(usbtmc_state.devInBuffer); + TU_VERIFY( usbd_edpt_xfer(rhport, usbtmc_state.ep_bulk_in, usbtmc_state.ep_bulk_in_buf,sizeof(usbtmc_state.devInBuffer))); } - else // short packet + else // last packet { size_t packetLen = usbtmc_state.transfer_size_remaining; memcpy(usbtmc_state.ep_bulk_in_buf, usbtmc_state.devInBuffer, usbtmc_state.transfer_size_remaining); @@ -401,6 +511,7 @@ bool usbtmcd_control_request(uint8_t rhport, tusb_control_request_t const * requ (request->bRequest == TUSB_REQ_CLEAR_FEATURE) && (request->wValue == TUSB_REQ_FEATURE_EDPT_HALT)) { + uart_tx_str_sync("feature clear\r\n"); if((request->wIndex) == usbtmc_state.ep_bulk_out) { usmtmcd_app_bulkOut_clearFeature(rhport); @@ -426,23 +537,48 @@ bool usbtmcd_control_request(uint8_t rhport, tusb_control_request_t const * requ // USBTMC required requests case USBTMC_bREQUEST_INITIATE_ABORT_BULK_OUT: case USBTMC_bREQUEST_CHECK_ABORT_BULK_OUT_STATUS: - case USBTMC_bREQUEST_INITIATE_ABORT_BULK_IN: + { + TU_VERIFY(request->bmRequestType == 0xA2); // in,class,EP + TU_VERIFY(request->wLength == 1u); + tmcStatusCode = USBTMC_STATUS_FAILED; + usbd_edpt_xfer(rhport, 0u, (void*)&tmcStatusCode,sizeof(tmcStatusCode)); + return true; + } case USBTMC_bREQUEST_CHECK_ABORT_BULK_IN_STATUS: - { - TU_VERIFY(request->bmRequestType == 0xA2); // in,class,EP - TU_VERIFY(request->wLength == 1u); - tmcStatusCode = USBTMC_STATUS_FAILED; - usbd_edpt_xfer(rhport, 0u, (void*)&tmcStatusCode,sizeof(tmcStatusCode)); - return true; - } + { + TU_VERIFY(request->bmRequestType == 0xA2); // in,class,EP + TU_VERIFY(request->wLength == 1u); + usbtmc_get_clear_status_rsp_t clearStatusRsp = {0}; + tmcStatusCode = USBTMC_STATUS_FAILED; + usbd_edpt_xfer(rhport, 0u, (void*)&tmcStatusCode,sizeof(tmcStatusCode)); + return true; + } + + case USBTMC_bREQUEST_INITIATE_ABORT_BULK_IN: + { + usbtmc_initiate_abort_rsp_t rsp = {0}; + uart_tx_str_sync("init abort bulk in\r\n"); + TU_VERIFY(request->bmRequestType == 0xA1); // in,class,interface + TU_VERIFY(request->wLength == sizeof(tmcStatusCode)); + TU_VERIFY(request->wIndex == usbtmc_state.ep_int_in); + // wValue is the requested bTag to abort + usbtmc_state.transfer_size_remaining = 0; + usbtmc_state.state = STATE_ABORTING_BULK_IN; + TU_VERIFY(usbtmcd_app_initiate_clear(rhport, &tmcStatusCode)); + TU_VERIFY(tud_control_xfer(rhport, request, (void*)&tmcStatusCode,sizeof(tmcStatusCode))); + return true; + } case USBTMC_bREQUEST_INITIATE_CLEAR: { + uart_tx_str_sync("init clear\r\n"); TU_VERIFY(request->bmRequestType == 0xA1); // in,class,interface TU_VERIFY(request->wLength == sizeof(tmcStatusCode)); // After receiving an INITIATE_CLEAR request, the device must Halt the Bulk-OUT endpoint, queue the // control endpoint response shown in Table 31, and clear all input buffers and output buffers. usbd_edpt_stall(rhport, usbtmc_state.ep_bulk_out); + usbtmc_state.transfer_size_remaining = 0; + usbtmc_state.state = STATE_CLEARING; TU_VERIFY(usbtmcd_app_initiate_clear(rhport, &tmcStatusCode)); TU_VERIFY(tud_control_xfer(rhport, request, (void*)&tmcStatusCode,sizeof(tmcStatusCode))); return true; @@ -450,17 +586,31 @@ bool usbtmcd_control_request(uint8_t rhport, tusb_control_request_t const * requ case USBTMC_bREQUEST_CHECK_CLEAR_STATUS: { - usbtmc_get_clear_status_rsp_t clearStatusRsp = {0}; + uart_tx_str_sync("check clear\r\n"); TU_VERIFY(request->bmRequestType == 0xA1); // in,class,interface + usbtmc_get_clear_status_rsp_t clearStatusRsp = {0}; TU_VERIFY(request->wLength == sizeof(clearStatusRsp)); - TU_VERIFY(usbtmcd_app_get_clear_status(rhport, &clearStatusRsp)); + if(usbd_edpt_busy(rhport, usbtmc_state.ep_bulk_in)) + { + // Stuff stuck in TX buffer? + clearStatusRsp.bmClear.BulkInFifoBytes = 1; + clearStatusRsp.USBTMC_status = USBTMC_STATUS_PENDING; + } + else + { + // Let app check if it's clear + TU_VERIFY(usbtmcd_app_get_clear_status(rhport, &clearStatusRsp)); + } + if(clearStatusRsp.USBTMC_status == USBTMC_STATUS_SUCCESS) + usbtmc_state.state = STATE_IDLE; TU_VERIFY(tud_control_xfer(rhport, request, (void*)&clearStatusRsp,sizeof(clearStatusRsp))); return true; } case USBTMC_bREQUEST_GET_CAPABILITIES: { + uart_tx_str_sync("get capabilities\r\n"); TU_VERIFY(request->bmRequestType == 0xA1); // in,class,interface TU_VERIFY(request->wLength == sizeof(usbtmcd_app_capabilities)); TU_VERIFY(tud_control_xfer(rhport, request, (void*)&usbtmcd_app_capabilities, sizeof(usbtmcd_app_capabilities))); @@ -470,6 +620,7 @@ bool usbtmcd_control_request(uint8_t rhport, tusb_control_request_t const * requ case USBTMC_bREQUEST_INDICATOR_PULSE: // Optional { + uart_tx_str_sync("indicate\r\n"); TU_VERIFY(request->bmRequestType == 0xA1); // in,class,interface TU_VERIFY(request->wLength == sizeof(tmcStatusCode)); TU_VERIFY(usbtmcd_app_capabilities.bmIntfcCapabilities.supportsIndicatorPulse); @@ -482,6 +633,7 @@ bool usbtmcd_control_request(uint8_t rhport, tusb_control_request_t const * requ // USB488 required requests case USBTMC488_bREQUEST_READ_STATUS_BYTE: { + uart_tx_str_sync("read stb\r\n"); usbtmc_read_stb_rsp_488_t rsp; TU_VERIFY(request->bmRequestType == 0xA1); // in,class,interface TU_VERIFY(request->wLength == sizeof(rsp)); // in,class,interface @@ -520,6 +672,7 @@ bool usbtmcd_control_request(uint8_t rhport, tusb_control_request_t const * requ case USBTMC488_bREQUEST_GO_TO_LOCAL: case USBTMC488_bREQUEST_LOCAL_LOCKOUT: { + uart_tx_str_sync("Unsupported REN/GTL/LLO\r\n"); TU_VERIFY(request->bmRequestType == 0xA1); // in,class,interface TU_VERIFY(false); return false; @@ -527,6 +680,7 @@ bool usbtmcd_control_request(uint8_t rhport, tusb_control_request_t const * requ #endif default: + uart_tx_str_sync("Default CTRL handler\r\n"); TU_VERIFY(false); return false; } -- cgit v1.3.1 From 91cd247c97a7376133638d960b6c650c0f71d376 Mon Sep 17 00:00:00 2001 From: Nathan Conrad Date: Tue, 17 Sep 2019 13:26:10 -0400 Subject: changes 2 --- examples/device/usbtmc/src/usb_descriptors.c | 10 ++++------ examples/device/usbtmc/src/usbtmc_app.c | 23 +++++++++++++++++------ src/class/usbtmc/usbtmc_device.h | 4 ++-- 3 files changed, 23 insertions(+), 14 deletions(-) (limited to 'src') diff --git a/examples/device/usbtmc/src/usb_descriptors.c b/examples/device/usbtmc/src/usb_descriptors.c index 9567bcab5..792fff87c 100644 --- a/examples/device/usbtmc/src/usb_descriptors.c +++ b/examples/device/usbtmc/src/usb_descriptors.c @@ -106,7 +106,7 @@ uint8_t const * tud_hid_descriptor_report_cb(void) #if defined(CFG_TUD_USBTMC) # define USBTMC_DESC_MAIN(_itfnum,_bNumEndpoints) \ - USBTMC_IF_DESCRIPTOR(_itfnum, _bNumEndpoints, /*_stridx = */ 7u, USBTMC_PROTOCOL_USB488), \ + USBTMC_IF_DESCRIPTOR(_itfnum, _bNumEndpoints, /*_stridx = */ 4u, USBTMC_PROTOCOL_USB488), \ USBTMC_BULK_DESCRIPTORS(/* OUT = */0x03, /* IN = */ 0x83) #if defined(CFG_TUD_USBTMC_ENABLE_INT_EP) @@ -209,10 +209,7 @@ char const* string_desc_arr [] = "TinyUSB", // 1: Manufacturer "TinyUSB Device", // 2: Product "123456", // 3: Serials, should use chip ID - "TinyUSB CDC", // 4: CDC Interface - "TinyUSB MSC", // 5: MSC Interface - "TinyUSB HID", // 6: HID - "TinyUSB USBTMC", // 7: USBTMC + "TinyUSB USBTMC", // 4: USBTMC }; static uint16_t _desc_str[32]; @@ -227,7 +224,8 @@ uint16_t const* tud_descriptor_string_cb(uint8_t index) { memcpy(&_desc_str[1], string_desc_arr[0], 2); chr_count = 1; - }else + } + else { // Convert ASCII string into UTF-16 diff --git a/examples/device/usbtmc/src/usbtmc_app.c b/examples/device/usbtmc/src/usbtmc_app.c index 7328b6598..e21c3ca22 100644 --- a/examples/device/usbtmc/src/usbtmc_app.c +++ b/examples/device/usbtmc/src/usbtmc_app.c @@ -64,8 +64,8 @@ usbtmcd_app_capabilities = } #endif }; - -static const char idn[] = "TinyUSB,ModelNumber,SerialNumber,FirmwareVer\n"; +//static const char idn[] = "TinyUSB,ModelNumber,SerialNumber,FirmwareVer"; +static const char idn[] = "TinyUSB,ModelNumber,SerialNumber,FirmwareVer and a bunch of other text to make it longer than a packet, perhaps?\n"; static volatile uint8_t status; // 0=not query, 1=queried, 2=delay,set(MAV), 3=delay 4=ready? @@ -86,6 +86,7 @@ bool usbtmcd_app_msgBulkOut_start(uint8_t rhport, usbtmc_msg_request_dev_dep_out { (void)rhport; (void)msgHeader; + uart_tx_str_sync("MSG_OUT_DATA: start\r\n"); return true; } bool usbtmcd_app_msg_trigger(uint8_t rhport, usbtmc_msg_generic_t* msg) { @@ -99,6 +100,11 @@ bool usbtmcd_app_msg_data(uint8_t rhport, void *data, size_t len, bool transfer_ (void)rhport; // If transfer isn't finished, we just ignore it (for now) + uart_tx_str_sync("MSG_OUT_DATA: <<<"); + uart_tx_sync(data,len); + uart_tx_str_sync(">>>\r\n"); + if(transfer_complete) + uart_tx_str_sync("MSG_OUT_DATA: Complete\r\n"); if(transfer_complete && (len >=4) && !strncasecmp("*idn?",data,4)) { queryState = 1; @@ -115,13 +121,18 @@ bool usbtmcd_app_msgBulkIn_complete(uint8_t rhport) return true; } +static unsigned int msgReqLen; + bool usbtmcd_app_msgBulkIn_request(uint8_t rhport, usbtmc_msg_request_dev_dep_in const * request) { (void)rhport; + rspMsg.header.MsgID = request->header.MsgID, rspMsg.header.bTag = request->header.bTag, rspMsg.header.bTagInverse = request->header.bTagInverse; + msgReqLen = request->TransferSize; + uart_tx_str_sync("MSG_IN_DATA: Requested!\r\n"); TU_ASSERT(bulkInStarted == 0); bulkInStarted = 1; @@ -143,14 +154,14 @@ void usbtmc_app_task_iter(void) { queryState = 2; break; case 2: - if( (board_millis() - queryDelayStart) > 1000u) { + if( (board_millis() - queryDelayStart) > 5u) { queryDelayStart = board_millis(); queryState=3; status |= 0x10u; // MAV } break; case 3: - if( (board_millis() - queryDelayStart) > 1000u) { + if( (board_millis() - queryDelayStart) > 10u) { queryState = 4; } break; @@ -158,8 +169,7 @@ void usbtmc_app_task_iter(void) { if(bulkInStarted) { queryState = 0; bulkInStarted = 0; - rspMsg.TransferSize = sizeof(idn)-1; - usbtmcd_transmit_dev_msg_data(rhport, &rspMsg, idn); + usbtmcd_transmit_dev_msg_data(rhport, idn, tu_min32(sizeof(idn)-1,msgReqLen),false); // MAV is cleared in the transfer complete callback. } break; @@ -189,6 +199,7 @@ bool usbtmcd_app_get_clear_status(uint8_t rhport, usbtmc_get_clear_status_rsp_t rsp->bmClear.BulkInFifoBytes = 0u; return true; } + void usmtmcd_app_bulkIn_clearFeature(uint8_t rhport) { (void)rhport; diff --git a/src/class/usbtmc/usbtmc_device.h b/src/class/usbtmc/usbtmc_device.h index 35d4da438..a0ba82e30 100644 --- a/src/class/usbtmc/usbtmc_device.h +++ b/src/class/usbtmc/usbtmc_device.h @@ -86,8 +86,8 @@ TU_ATTR_WEAK bool usbtmcd_app_msg_trigger(uint8_t rhport, usbtmc_msg_generic_t* bool usbtmcd_transmit_dev_msg_data( uint8_t rhport, - usbtmc_msg_dev_dep_msg_in_header_t const * hdr, - const void *data); + const void * data, size_t len, + bool usingTermChar); /* "callbacks" from USB device core */ -- cgit v1.3.1 From a0b6b8187c036b386f09188a9017301f730096b8 Mon Sep 17 00:00:00 2001 From: Nathan Conrad Date: Fri, 13 Sep 2019 20:28:26 -0400 Subject: TI compiler quirks, and le byte swapping functions. --- src/common/tusb_compiler.h | 83 ++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 73 insertions(+), 10 deletions(-) (limited to 'src') diff --git a/src/common/tusb_compiler.h b/src/common/tusb_compiler.h index 09768ef88..ca294c20f 100644 --- a/src/common/tusb_compiler.h +++ b/src/common/tusb_compiler.h @@ -53,6 +53,9 @@ // for declaration of reserved field, make use of _TU_COUNTER_ #define TU_RESERVED TU_XSTRCAT(reserved, _TU_COUNTER_) +#define TU_LITTLE_ENDIAN (0x12u) +#define TU_BIG_ENDIAN (0x21u) + //--------------------------------------------------------------------+ // Compiler porting with Attribute and Endian //--------------------------------------------------------------------+ @@ -67,20 +70,80 @@ // Endian conversion use well-known host to network (big endian) naming #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ - #define tu_htonl(u32) __builtin_bswap32(u32) - #define tu_ntohl(u32) __builtin_bswap32(u32) - - #define tu_htons(u16) __builtin_bswap16(u16) - #define tu_ntohs(u16) __builtin_bswap16(u16) + #define TU_BYTE_ORDER TU_LITTLE_ENDIAN #else - #define tu_htonl(u32) (u32) - #define tu_ntohl(u32) (u32) + #define TU_BYTE_ORDER TU_BIG_ENDIAN + #endif + + static inline uint16_t tu_bswap16(uint16_t u16) + { + return __builtin_bswap16(u16); + } + + static inline uint16_t tu_bswap32(uint16_t u32) + { + return __builtin_bswap32(u32); + } + + #define TU_BSWAP16 + +#elif defined(__TI_COMPILER_VERSION__) + #define TU_ATTR_ALIGNED(Bytes) __attribute__ ((aligned(Bytes))) + #define TU_ATTR_SECTION(sec_name) __attribute__ ((section(#sec_name))) + #define TU_ATTR_PACKED __attribute__ ((packed)) + #define TU_ATTR_PREPACKED + #define TU_ATTR_WEAK __attribute__ ((weak)) + #define TU_ATTR_DEPRECATED(mess) __attribute__ ((deprecated(mess))) // warn if function with this attribute is used + #define TU_ATTR_UNUSED __attribute__ ((unused)) // Function/Variable is meant to be possibly unused - #define tu_htons(u16) (u16) - #define tu_ntohs(u16) (u16) + // __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 + #else + #define TU_BYTE_ORDER TU_BIG_ENDIAN #endif + + static inline uint16_t tu_bswap16(uint16_t u16) + { + return __builtin_bswap16(u16); + } + + static inline uint16_t tu_bswap32(uint16_t u32) + { + return __builtin_bswap32(u32); + } +#else + #error "Compiler attribute porting is required" +#endif + +#if (TU_BYTE_ORDER == TU_LITTLE_ENDIAN) + #define tu_htonl(u32) tu_bswap32(u32) + #define tu_ntohl(u32) tu_bswap32(u32) + + #define tu_htons(u16) tu_bswap16(u16) + #define tu_ntohs(u16) tu_bswap16(u16) + + #define tu_htole16(x) (x) + #define tu_le16toh(x) (x) + + #define tu_htole32(x) (x) + #define tu_le32toh(x) (x) + +#elif (TU_BYTE_ORDER == TU_BIG_ENDIAN) + #define tu_htonl(u32) (x) + #define tu_ntohl(u32) (x) + + #define tu_htons(u16) (x) + #define tu_ntohs(u16) (x) + + #define tu_htole16(x) tu_bswap16(u32) + #define tu_le16toh(x) tu_bswap16(u32) + + #define tu_htole32(x) tu_bswap32(u32) + #define tu_le32toh(x) tu_bswap32(u32) + #else - #error "Compiler attribute porting are required" + #error Byte order is undefined #endif #endif /* _TUSB_COMPILER_H_ */ -- cgit v1.3.1 From 41e8b8752e421ccb63a48eec316f353854abc8a0 Mon Sep 17 00:00:00 2001 From: Nathan Conrad Date: Sun, 15 Sep 2019 15:20:01 -0400 Subject: Massive copy&paste typo of mine in the 32-bit byte swapping function.... --- src/common/tusb_compiler.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/common/tusb_compiler.h b/src/common/tusb_compiler.h index ca294c20f..df0326afd 100644 --- a/src/common/tusb_compiler.h +++ b/src/common/tusb_compiler.h @@ -80,7 +80,7 @@ return __builtin_bswap16(u16); } - static inline uint16_t tu_bswap32(uint16_t u32) + static inline uint32_t tu_bswap32(uint32_t u32) { return __builtin_bswap32(u32); } @@ -108,7 +108,7 @@ return __builtin_bswap16(u16); } - static inline uint16_t tu_bswap32(uint16_t u32) + static inline uint32_t tu_bswap32(uint32_t u32) { return __builtin_bswap32(u32); } -- cgit v1.3.1 From 8d05b70a72d8132eb67523c789499cd4cdf5d562 Mon Sep 17 00:00:00 2001 From: Nathan Conrad Date: Fri, 13 Sep 2019 23:37:47 -0400 Subject: Off-by-one error in Synopsys assertions. (and move some braces to their own lines. --- src/portable/st/synopsys/dcd_synopsys.c | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/src/portable/st/synopsys/dcd_synopsys.c b/src/portable/st/synopsys/dcd_synopsys.c index b0e7e04bd..2daa16a26 100644 --- a/src/portable/st/synopsys/dcd_synopsys.c +++ b/src/portable/st/synopsys/dcd_synopsys.c @@ -268,21 +268,22 @@ bool dcd_edpt_open (uint8_t rhport, tusb_desc_endpoint_t const * desc_edpt) uint8_t const epnum = tu_edpt_number(desc_edpt->bEndpointAddress); uint8_t const dir = tu_edpt_dir(desc_edpt->bEndpointAddress); - - // Unsupported endpoint numbers/size. - if((desc_edpt->wMaxPacketSize.size > 64) || (epnum > EP_MAX)) { - return false; - } - + + TU_ASSERT((desc_edpt->wMaxPacketSize.size <= 64); + TU_ASSERT(epnum < EP_MAX); + xfer_ctl_t * xfer = XFER_CTL_BASE(epnum, dir); xfer->max_size = desc_edpt->wMaxPacketSize.size; - if(dir == TUSB_DIR_OUT) { + if(dir == TUSB_DIR_OUT) + { out_ep[epnum].DOEPCTL |= (1 << USB_OTG_DOEPCTL_USBAEP_Pos) | \ desc_edpt->bmAttributes.xfer << USB_OTG_DOEPCTL_EPTYP_Pos | \ desc_edpt->wMaxPacketSize.size << USB_OTG_DOEPCTL_MPSIZ_Pos; dev->DAINTMSK |= (1 << (USB_OTG_DAINTMSK_OEPM_Pos + epnum)); - } else { + } + else + { // "USB Data FIFOs" section in reference manual // Peripheral FIFO architecture // -- cgit v1.3.1 From 1ceeab2702c6f5407c00dab8deeade338d176a45 Mon Sep 17 00:00:00 2001 From: Nathan Conrad Date: Fri, 13 Sep 2019 23:52:43 -0400 Subject: This demonstrates that I don't pre-build things before committing them... oops. --- src/portable/st/synopsys/dcd_synopsys.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/portable/st/synopsys/dcd_synopsys.c b/src/portable/st/synopsys/dcd_synopsys.c index 2daa16a26..f15b92edc 100644 --- a/src/portable/st/synopsys/dcd_synopsys.c +++ b/src/portable/st/synopsys/dcd_synopsys.c @@ -269,7 +269,7 @@ bool dcd_edpt_open (uint8_t rhport, tusb_desc_endpoint_t const * desc_edpt) uint8_t const epnum = tu_edpt_number(desc_edpt->bEndpointAddress); uint8_t const dir = tu_edpt_dir(desc_edpt->bEndpointAddress); - TU_ASSERT((desc_edpt->wMaxPacketSize.size <= 64); + TU_ASSERT(desc_edpt->wMaxPacketSize.size <= 64); TU_ASSERT(epnum < EP_MAX); xfer_ctl_t * xfer = XFER_CTL_BASE(epnum, dir); -- cgit v1.3.1 From 8e17fb49106eeb291a36ff5f82ead624e867e6b0 Mon Sep 17 00:00:00 2001 From: hathach Date: Mon, 16 Sep 2019 11:13:17 +0700 Subject: follow up to suggestion to pr 155 --- src/common/tusb_types.h | 3 ++- src/device/usbd.c | 19 +++++++++++++------ 2 files changed, 15 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/common/tusb_types.h b/src/common/tusb_types.h index a50e89934..ad42baad7 100644 --- a/src/common/tusb_types.h +++ b/src/common/tusb_types.h @@ -125,7 +125,8 @@ typedef enum { TUSB_REQ_TYPE_STANDARD = 0, TUSB_REQ_TYPE_CLASS, - TUSB_REQ_TYPE_VENDOR + TUSB_REQ_TYPE_VENDOR, + TUSB_REQ_TYPE_INVALID } tusb_request_type_t; typedef enum diff --git a/src/device/usbd.c b/src/device/usbd.c index 572708f7d..2f8967fae 100644 --- a/src/device/usbd.c +++ b/src/device/usbd.c @@ -62,7 +62,7 @@ typedef struct { static usbd_device_t _usbd_dev = { 0 }; // Invalid driver ID in itf2drv[] ep2drv[][] mapping -enum { DRVID_INVALID = 0xff }; +enum { DRVID_INVALID = 0xFFu }; //--------------------------------------------------------------------+ // Class Driver @@ -365,6 +365,8 @@ static bool process_control_request(uint8_t rhport, tusb_control_request_t const { usbd_control_set_complete_callback(NULL); + TU_ASSERT(p_request->bmRequestType_bit.type < TUSB_REQ_TYPE_INVALID); + // Vendor request if ( p_request->bmRequestType_bit.type == TUSB_REQ_TYPE_VENDOR ) { @@ -486,7 +488,8 @@ static bool process_control_request(uint8_t rhport, tusb_control_request_t const // GET HID REPORT DESCRIPTOR falls into this case // stall control endpoint if driver return false usbd_control_set_complete_callback(usbd_class_drivers[drvid].control_complete); - TU_ASSERT(usbd_class_drivers[drvid].control_request(rhport, p_request)); + TU_ASSERT(usbd_class_drivers[drvid].control_request != NULL && + usbd_class_drivers[drvid].control_request(rhport, p_request)); break; } }else @@ -494,7 +497,8 @@ static bool process_control_request(uint8_t rhport, tusb_control_request_t const // forward to class driver: "non-STD request to Interface" // stall control endpoint if driver return false usbd_control_set_complete_callback(usbd_class_drivers[drvid].control_complete); - TU_ASSERT(usbd_class_drivers[drvid].control_request(rhport, p_request)); + TU_ASSERT(usbd_class_drivers[drvid].control_request != NULL && + usbd_class_drivers[drvid].control_request(rhport, p_request)); } } break; @@ -515,7 +519,7 @@ static bool process_control_request(uint8_t rhport, tusb_control_request_t const // We will forward all request targeted endpoint to its class driver // - For non-standard request: driver can ACK or Stall the request by return true/false // - For standard request: usbd decide the ACK stage regardless of driver return value - bool ret; + bool ret = false; if ( TUSB_REQ_TYPE_STANDARD != p_request->bmRequestType_bit.type ) { @@ -523,8 +527,11 @@ static bool process_control_request(uint8_t rhport, tusb_control_request_t const usbd_control_set_complete_callback(usbd_class_drivers[drv_id].control_complete); } - // Invoke class driver first - ret = usbd_class_drivers[drv_id].control_request(rhport, p_request); + // Invoke class driver first if available + if ( usbd_class_drivers[drv_id].control_request ) + { + ret = usbd_class_drivers[drv_id].control_request(rhport, p_request); + } // Then handle if it is standard request if ( TUSB_REQ_TYPE_STANDARD == p_request->bmRequestType_bit.type ) -- cgit v1.3.1 From 5a2e510af73e84284343420fd76388369e70f7f5 Mon Sep 17 00:00:00 2001 From: Nathan Conrad Date: Sat, 14 Sep 2019 09:02:21 -0400 Subject: Interpretation of assert vs verify. --- src/common/tusb_verify.h | 30 +++++++++++++++++++++++++++--- 1 file changed, 27 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/common/tusb_verify.h b/src/common/tusb_verify.h index 2727ce043..fae0c88ae 100644 --- a/src/common/tusb_verify.h +++ b/src/common/tusb_verify.h @@ -36,10 +36,34 @@ * as C++ for the sake of code simplicity. Beware of a headache macro * manipulation that you are told to stay away. * - * e.g * - * - TU_VERIFY( cond ) will return false if cond is false - * - TU_VERIFY( cond, err) will return err instead if cond is false + * This contains macros for both VERIFY and ASSERT: + * + * VERIFY: Used when there is an error condition which is not the + * fault of the MCU. For example, bounds checking on data + * sent to the micro over USB should use this function. + * Another example is checking for buffer overflows, where + * returning from the active function causes a NAK. + * + * ASSERT: Used for error conditions that are caused by MCU firmware + * bugs. This is used to discover bugs in the code more + * quickly. One example would be adding assertions in library + * function calls to confirm a function's (untainted) + * parameters are valid. + * + * + * The difference in behaviour is that ASSERT triggers a breakpoint while + * verify does not. + * + * #define TU_VERIFY(cond) if(cond) return false; + * #define TU_VERIFY(cond,ret) if(cond) return ret; + * + * #define TU_VERIFY_HDLR(cond,handler) if(cond) {handler; return false;} + * #define TU_VERIFY_HDLR(cond,ret,handler) if(cond) {handler; return ret;} + * + * #define TU_ASSERT(cond) if(cond) {_MESS_FAILED(); TU_BREAKPOINT(), return false;} + * #define TU_ASSERT(cond,ret) if(cond) {_MESS_FAILED(); TU_BREAKPOINT(), return ret;} + * *------------------------------------------------------------------*/ #ifdef __cplusplus -- cgit v1.3.1 From 237c32b976d605087dd0b2c5013f7f2ae4bae46f Mon Sep 17 00:00:00 2001 From: hathach Date: Mon, 16 Sep 2019 13:32:47 +0700 Subject: fix #143 --- src/portable/nxp/lpc17_40/dcd_lpc17_40.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/portable/nxp/lpc17_40/dcd_lpc17_40.c b/src/portable/nxp/lpc17_40/dcd_lpc17_40.c index 2b49f52e9..d5f90d2a7 100644 --- a/src/portable/nxp/lpc17_40/dcd_lpc17_40.c +++ b/src/portable/nxp/lpc17_40/dcd_lpc17_40.c @@ -293,7 +293,7 @@ bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const * p_endpoint_desc) break; case TUSB_XFER_ISOCHRONOUS: - TU_ASSERT((epnum % 3) == 3 && (epnum != 15)); + TU_ASSERT((epnum % 3) == 0 && (epnum != 0) && (epnum != 15)); break; default: -- cgit v1.3.1 From 6dd2296cfc1b2cd871e577c42de96ee444d4a1d3 Mon Sep 17 00:00:00 2001 From: Nathan Conrad Date: Mon, 16 Sep 2019 11:27:05 -0400 Subject: Change inline functions to macros, and make all parameter names uniform. --- src/common/tusb_compiler.h | 58 ++++++++++++++++++---------------------------- 1 file changed, 23 insertions(+), 35 deletions(-) (limited to 'src') diff --git a/src/common/tusb_compiler.h b/src/common/tusb_compiler.h index df0326afd..58732b871 100644 --- a/src/common/tusb_compiler.h +++ b/src/common/tusb_compiler.h @@ -75,17 +75,8 @@ #define TU_BYTE_ORDER TU_BIG_ENDIAN #endif - static inline uint16_t tu_bswap16(uint16_t u16) - { - return __builtin_bswap16(u16); - } - - static inline uint32_t tu_bswap32(uint32_t u32) - { - return __builtin_bswap32(u32); - } - - #define TU_BSWAP16 +#define TU_BSWAP16(u16) (__builtin_bswap16(u16)) +#define TU_BSWAP32(u32) (__builtin_bswap32(u32)) #elif defined(__TI_COMPILER_VERSION__) #define TU_ATTR_ALIGNED(Bytes) __attribute__ ((aligned(Bytes))) @@ -103,44 +94,41 @@ #define TU_BYTE_ORDER TU_BIG_ENDIAN #endif - static inline uint16_t tu_bswap16(uint16_t u16) - { - return __builtin_bswap16(u16); - } + #define TU_BSWAP16(u16) (__builtin_bswap16(u16)) + #define TU_BSWAP32(u32) (__builtin_bswap32(u32)) - static inline uint32_t tu_bswap32(uint32_t u32) - { - return __builtin_bswap32(u32); - } #else #error "Compiler attribute porting is required" #endif #if (TU_BYTE_ORDER == TU_LITTLE_ENDIAN) - #define tu_htonl(u32) tu_bswap32(u32) - #define tu_ntohl(u32) tu_bswap32(u32) - #define tu_htons(u16) tu_bswap16(u16) - #define tu_ntohs(u16) tu_bswap16(u16) + #define tu_htons(u16) (TU_BSWAP16(u16)) + #define tu_ntohs(u16) (TU_BSWAP16(u16)) + + #define tu_htonl(u32) (TU_BSWAP32(u32)) + #define tu_ntohl(u32) (TU_BSWAP32(u32)) - #define tu_htole16(x) (x) - #define tu_le16toh(x) (x) + #define tu_htole16(u16) (u16) + #define tu_le16toh(u16) (u16) - #define tu_htole32(x) (x) - #define tu_le32toh(x) (x) + #define tu_htole32(u32) (u32) + #define tu_le32toh(u32) (u32) #elif (TU_BYTE_ORDER == TU_BIG_ENDIAN) - #define tu_htonl(u32) (x) - #define tu_ntohl(u32) (x) - #define tu_htons(u16) (x) - #define tu_ntohs(u16) (x) + #define tu_htons(u16) (u16) + #define tu_ntohs(u16) (u16) + + #define tu_htonl(u32) (u32) + #define tu_ntohl(u32) (u32) + - #define tu_htole16(x) tu_bswap16(u32) - #define tu_le16toh(x) tu_bswap16(u32) + #define tu_htole16(u16) (tu_bswap16(u16)) + #define tu_le16toh(u16) (tu_bswap16(u16)) - #define tu_htole32(x) tu_bswap32(u32) - #define tu_le32toh(x) tu_bswap32(u32) + #define tu_htole32(u32) (tu_bswap32(u32)) + #define tu_le32toh(u32) (tu_bswap32(u32)) #else #error Byte order is undefined -- cgit v1.3.1 From eea71a8b3b080299ad95ac79a7d45b2dc0d5b6f6 Mon Sep 17 00:00:00 2001 From: Nathan Conrad Date: Wed, 18 Sep 2019 19:24:54 -0400 Subject: usbtmc updates.... --- examples/device/usbtmc/src/tusb_config.h | 4 +- examples/device/usbtmc/src/usbtmc_app.c | 32 +++- src/class/usbtmc/usbtmc.h | 14 ++ src/class/usbtmc/usbtmc_device.c | 279 +++++++++++++++++++++++-------- src/class/usbtmc/usbtmc_device.h | 6 +- 5 files changed, 261 insertions(+), 74 deletions(-) (limited to 'src') diff --git a/examples/device/usbtmc/src/tusb_config.h b/examples/device/usbtmc/src/tusb_config.h index 022dc7691..16484424a 100644 --- a/examples/device/usbtmc/src/tusb_config.h +++ b/examples/device/usbtmc/src/tusb_config.h @@ -56,8 +56,8 @@ //------------- CLASS -------------// #define CFG_TUD_USBTMC 1 -#define CFG_TUD_USBTMC_ENABLE_INT_EP -//#define USBTMC_CFG_ENABLE_488 0 +#define CFG_TUD_USBTMC_ENABLE_INT_EP 1 +#define USBTMC_CFG_ENABLE_488 1 #ifdef __cplusplus } diff --git a/examples/device/usbtmc/src/usbtmc_app.c b/examples/device/usbtmc/src/usbtmc_app.c index e21c3ca22..03800ab17 100644 --- a/examples/device/usbtmc/src/usbtmc_app.c +++ b/examples/device/usbtmc/src/usbtmc_app.c @@ -64,8 +64,8 @@ usbtmcd_app_capabilities = } #endif }; -//static const char idn[] = "TinyUSB,ModelNumber,SerialNumber,FirmwareVer"; -static const char idn[] = "TinyUSB,ModelNumber,SerialNumber,FirmwareVer and a bunch of other text to make it longer than a packet, perhaps?\n"; +static const char idn[] = "TinyUSB,ModelNumber,SerialNumber,FirmwareVer123456\r\n"; +//static const char idn[] = "TinyUSB,ModelNumber,SerialNumber,FirmwareVer and a bunch of other text to make it longer than a packet, perhaps? lets make it three transfers...\n"; static volatile uint8_t status; // 0=not query, 1=queried, 2=delay,set(MAV), 3=delay 4=ready? @@ -154,14 +154,14 @@ void usbtmc_app_task_iter(void) { queryState = 2; break; case 2: - if( (board_millis() - queryDelayStart) > 5u) { + if( (board_millis() - queryDelayStart) > 200u) { queryDelayStart = board_millis(); queryState=3; status |= 0x10u; // MAV } break; case 3: - if( (board_millis() - queryDelayStart) > 10u) { + if( (board_millis() - queryDelayStart) > 400u) { queryState = 4; } break; @@ -169,6 +169,7 @@ void usbtmc_app_task_iter(void) { if(bulkInStarted) { queryState = 0; bulkInStarted = 0; + uart_tx_str_sync("usbtmc_app_task_iter: sending rsp!\r\n"); usbtmcd_transmit_dev_msg_data(rhport, idn, tu_min32(sizeof(idn)-1,msgReqLen),false); // MAV is cleared in the transfer complete callback. } @@ -189,7 +190,7 @@ bool usbtmcd_app_initiate_clear(uint8_t rhport, uint8_t *tmcResult) return true; } -bool usbtmcd_app_get_clear_status(uint8_t rhport, usbtmc_get_clear_status_rsp_t *rsp) +bool usbtmcd_app_check_clear(uint8_t rhport, usbtmc_get_clear_status_rsp_t *rsp) { (void)rhport; queryState = 0; @@ -199,6 +200,27 @@ bool usbtmcd_app_get_clear_status(uint8_t rhport, usbtmc_get_clear_status_rsp_t rsp->bmClear.BulkInFifoBytes = 0u; return true; } +bool usbtmcd_app_initiate_abort_bulk_in(uint8_t rhport, uint8_t *tmcResult) +{ + bulkInStarted = 0; + *tmcResult = USBTMC_STATUS_SUCCESS; + return true; +} +bool usbtmcd_app_check_abort_bulk_in(uint8_t rhport, usbtmc_check_abort_bulk_rsp_t *rsp) +{ + return true; +} + +bool usbtmcd_app_initiate_abort_bulk_out(uint8_t rhport, uint8_t *tmcResult) +{ + *tmcResult = USBTMC_STATUS_SUCCESS; + return true; + +} +bool usbtmcd_app_check_abort_bulk_out(uint8_t rhport, usbtmc_check_abort_bulk_rsp_t *rsp) +{ + return true; +} void usmtmcd_app_bulkIn_clearFeature(uint8_t rhport) { diff --git a/src/class/usbtmc/usbtmc.h b/src/class/usbtmc/usbtmc.h index 6893c3743..0944c907a 100644 --- a/src/class/usbtmc/usbtmc.h +++ b/src/class/usbtmc/usbtmc.h @@ -237,6 +237,20 @@ typedef struct TU_ATTR_PACKED TU_VERIFY_STATIC(sizeof(usbtmc_get_clear_status_rsp_t) == 2u, "struct wrong length"); +// Used for both check_abort_bulk_in_status and check_abort_bulk_out_status +typedef struct TU_ATTR_PACKED +{ + uint8_t USBTMC_status; + struct TU_ATTR_PACKED + { + unsigned int BulkInFifoBytes : 1; ///< Has queued data or a short packet that is queued + } bmAbortBulkIn; + uint8_t _reserved[2]; ///< Must be zero + uint32_t NBYTES_RXD_TXD; +} usbtmc_check_abort_bulk_rsp_t; + +TU_VERIFY_STATIC(sizeof(usbtmc_check_abort_bulk_rsp_t) == 8u, "struct wrong length"); + typedef struct TU_ATTR_PACKED { uint8_t USBTMC_status; ///< usbtmc_status_enum diff --git a/src/class/usbtmc/usbtmc_device.c b/src/class/usbtmc/usbtmc_device.c index 6d562641e..c71d4d963 100644 --- a/src/class/usbtmc/usbtmc_device.c +++ b/src/class/usbtmc/usbtmc_device.c @@ -93,8 +93,11 @@ typedef enum STATE_RCV, STATE_TX_REQUESTED, STATE_TX_INITIATED, + STATE_TX_SHORTED, STATE_CLEARING, STATE_ABORTING_BULK_IN, + STATE_ABORTING_BULK_IN_SHORTED, // aborting, and short packet has been queued for transmission + STATE_ABORTING_BULK_IN_ABORTED, // aborting, and short packet has been queued for transmission STATE_ABORTING_BULK_OUT, STATE_NUM_STATES } usbtmcd_state_enum; @@ -113,6 +116,7 @@ typedef struct // OUT buffer receives one packet at a time uint8_t ep_bulk_out_buf[USBTMCD_MAX_PACKET_SIZE]; uint32_t transfer_size_remaining; // also used for requested length for bulk IN. + uint32_t transfer_size_sent; // To keep track of data bytes that have been queued in FIFO (not header bytes) uint8_t lastBulkOutTag; // used for aborts (mostly) uint8_t lastBulkInTag; // used for aborts (mostly) @@ -128,6 +132,11 @@ static usbtmc_interface_state_t usbtmc_state = .ep_bulk_out = 0, .ep_int_in = 0 }; +#ifdef xDEBUG +#define TRACE(str) uart_tx_str_sync(str) +#else +#define TRACE(STR) do {} while (0) +#endif // We need all headers to fit in a single packet in this implementation. TU_VERIFY_STATIC(USBTMCD_MAX_PACKET_SIZE >= 32u,"USBTMC dev EP packet size too small"); @@ -188,7 +197,7 @@ bool usbtmcd_transmit_dev_msg_data( if((packetLen + hdr->TransferSize) <= txBufLen) { memcpy((uint8_t*)(usbtmc_state.ep_bulk_in_buf) + packetLen, data, hdr->TransferSize); - packetLen = (uint16_t)(packetLen+ hdr->TransferSize); + packetLen = (uint16_t)(packetLen + hdr->TransferSize); // Pad up to multiple of 4 bytes while((packetLen % 4) != 0) { @@ -196,13 +205,15 @@ bool usbtmcd_transmit_dev_msg_data( packetLen++; } usbtmc_state.transfer_size_remaining = 0; + usbtmc_state.transfer_size_sent = len; usbtmc_state.devInBuffer = NULL; } else /* partial packet */ { memcpy((uint8_t*)(usbtmc_state.ep_bulk_in_buf) + packetLen, data, txBufLen - packetLen); - usbtmc_state.devInBuffer += txBufLen - packetLen; - usbtmc_state.transfer_size_remaining = hdr->TransferSize - (txBufLen - packetLen); + usbtmc_state.devInBuffer = (uint8_t*)data + (txBufLen - packetLen); + usbtmc_state.transfer_size_remaining = len - (txBufLen - packetLen); + usbtmc_state.transfer_size_sent = txBufLen - packetLen; packetLen = txBufLen; } @@ -210,7 +221,8 @@ bool usbtmcd_transmit_dev_msg_data( criticalEnter(); { TU_VERIFY(usbtmc_state.state == STATE_TX_REQUESTED); - usbtmc_state.state = STATE_TX_INITIATED; + // We used packetlen as a max, not the buffer size, so this is OK here, no need for modulus + usbtmc_state.state = (packetLen >= txBufLen) ? STATE_TX_INITIATED : STATE_TX_SHORTED; } criticalLeave(); @@ -322,6 +334,8 @@ void usbtmcd_reset(uint8_t rhport) usbtmc_state.ep_bulk_in = 0; usbtmc_state.ep_bulk_out = 0; usbtmc_state.ep_int_in = 0; + usbtmc_state.lastBulkInTag = 0; + usbtmc_state.lastBulkOutTag = 0; (void)rhport; } @@ -351,10 +365,16 @@ static bool handle_devMsgOut(uint8_t rhport, void *data, size_t len, size_t pack if(len > usbtmc_state.transfer_size_remaining) len = usbtmc_state.transfer_size_remaining; usbtmcd_app_msg_data(rhport,data, len, atEnd); + + usbtmc_state.transfer_size_sent += len; if(atEnd) + { usbtmc_state.state = STATE_IDLE; + } else + { usbtmc_state.state = STATE_RCV; + } return true; } @@ -363,8 +383,10 @@ static bool handle_devMsgIn(uint8_t rhport, void *data, size_t len) TU_VERIFY(len == sizeof(usbtmc_msg_request_dev_dep_in)); usbtmc_msg_request_dev_dep_in *msg = (usbtmc_msg_request_dev_dep_in*)data; +#ifdef xDebug sprintf(logMsg," handle_devMsgIn len=%ul\r\n",len); - uart_tx_str_sync(logMsg); + TRACE(logMsg); +#endif criticalEnter(); { @@ -387,10 +409,13 @@ static bool handle_devMsgIn(uint8_t rhport, void *data, size_t len) bool usbtmcd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes) { + TRACE("USBTMC Xfer CB" ); TU_VERIFY(result == XFER_RESULT_SUCCESS); - uart_tx_str_sync("USBTMC Xfer CB" ); + +#ifdef xDebug sprintf(logMsg," STATE=%lu ", (uint32_t)usbtmc_state.state); - uart_tx_str_sync(logMsg); + TRACE(logMsg); +#endif if(usbtmc_state.state == STATE_CLEARING) { return true; /* I think we can ignore everything here */ @@ -398,23 +423,26 @@ bool usbtmcd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint if(ep_addr == usbtmc_state.ep_bulk_out) { - uart_tx_str_sync("OUT"); + usbtmc_msg_generic_t *msg = NULL; + TRACE("OUT"); switch(usbtmc_state.state) { case STATE_IDLE: TU_VERIFY(xferred_bytes >= sizeof(usbtmc_msg_generic_t)); - usbtmc_msg_generic_t *msg = (usbtmc_msg_generic_t*)(usbtmc_state.ep_bulk_out_buf); + msg = (usbtmc_msg_generic_t*)(usbtmc_state.ep_bulk_out_buf); uint8_t invInvTag = (uint8_t)~(msg->header.bTagInverse); TU_VERIFY(msg->header.bTag == invInvTag); TU_VERIFY(msg->header.bTag != 0x00); +#ifdef xDebug sprintf(logMsg," type=%lu\r\n",(uint32_t)msg->header.MsgID); - uart_tx_str_sync(logMsg); + TRACE(logMsg); +#endif switch(msg->header.MsgID) { case USBTMC_MSGID_DEV_DEP_MSG_OUT: + usbtmc_state.transfer_size_sent = 0u; TU_VERIFY(handle_devMsgOutStart(rhport, msg, xferred_bytes)); - TU_VERIFY(usbd_edpt_xfer(rhport, usbtmc_state.ep_bulk_out, usbtmc_state.ep_bulk_out_buf, USBTMCD_MAX_PACKET_SIZE)); usbtmc_state.lastBulkOutTag = msg->header.bTag; break; @@ -428,7 +456,6 @@ bool usbtmcd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint // Spec says we halt the EP if we didn't declare we support it. TU_VERIFY(usbtmcd_app_capabilities.bmIntfcCapabilities488.supportsTrigger); TU_VERIFY(usbtmcd_app_msg_trigger(rhport, msg)); - TU_VERIFY(usbd_edpt_xfer(rhport, usbtmc_state.ep_bulk_out, usbtmc_state.ep_bulk_out_buf, USBTMCD_MAX_PACKET_SIZE)); break; #endif @@ -439,58 +466,95 @@ bool usbtmcd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint TU_VERIFY(false); return false; } + TU_VERIFY(usbd_edpt_xfer(rhport, usbtmc_state.ep_bulk_out, usbtmc_state.ep_bulk_out_buf, USBTMCD_MAX_PACKET_SIZE)); return true; case STATE_RCV: TU_VERIFY(handle_devMsgOut(rhport, usbtmc_state.ep_bulk_out_buf, xferred_bytes, xferred_bytes)); return true; + case STATE_ABORTING_BULK_OUT: + TU_VERIFY(false); + return false; // Shold be stalled by now... case STATE_TX_REQUESTED: case STATE_TX_INITIATED: case STATE_ABORTING_BULK_IN: - case STATE_ABORTING_BULK_OUT: + case STATE_ABORTING_BULK_IN_SHORTED: + case STATE_ABORTING_BULK_IN_ABORTED: default: + +#ifdef xDebug if(msg == NULL) sprintf(logMsg," Unknown received control?\r\n "); else { sprintf(logMsg," msg=%lu\r\n ", (uint32_t)msg->header.MsgID); } - uart_tx_str_sync(logMsg); + TRACE(logMsg); +#endif TU_VERIFY(false); } } else if(ep_addr == usbtmc_state.ep_bulk_in) { +#ifdef xDebug sprintf(logMsg,"IN\r\n"); - uart_tx_str_sync(logMsg); - TU_ASSERT(usbtmc_state.state == STATE_TX_INITIATED); - if(usbtmc_state.transfer_size_remaining == 0) - { + TRACE(logMsg); +#endif + switch(usbtmc_state.state) { + case STATE_TX_SHORTED: + + TRACE("IN TX shorted done\r\n"); + usbtmc_state.state = STATE_IDLE; TU_VERIFY(usbtmcd_app_msgBulkIn_complete(rhport)); - TU_VERIFY( usbd_edpt_xfer(rhport, usbtmc_state.ep_bulk_out, usbtmc_state.ep_bulk_out_buf, USBTMCD_MAX_PACKET_SIZE)); - } - else if(usbtmc_state.transfer_size_remaining > sizeof(usbtmc_state.devInBuffer)) - { - memcpy(usbtmc_state.ep_bulk_in_buf, usbtmc_state.devInBuffer, sizeof(usbtmc_state.ep_bulk_in_buf)); - usbtmc_state.devInBuffer += sizeof(usbtmc_state.devInBuffer); - usbtmc_state.transfer_size_remaining -= sizeof(usbtmc_state.devInBuffer); - TU_VERIFY( usbd_edpt_xfer(rhport, usbtmc_state.ep_bulk_in, usbtmc_state.ep_bulk_in_buf,sizeof(usbtmc_state.devInBuffer))); - } - else // last packet - { - size_t packetLen = usbtmc_state.transfer_size_remaining; - memcpy(usbtmc_state.ep_bulk_in_buf, usbtmc_state.devInBuffer, usbtmc_state.transfer_size_remaining); - while((packetLen % 4) != 0) + break; + + case STATE_TX_INITIATED: + if(usbtmc_state.transfer_size_remaining >=sizeof(usbtmc_state.ep_bulk_in_buf)) { - usbtmc_state.ep_bulk_in_buf[packetLen] = 0; - packetLen++; + TRACE("IN TX continuing\r\n"); + memcpy(usbtmc_state.ep_bulk_in_buf, usbtmc_state.devInBuffer, sizeof(usbtmc_state.ep_bulk_in_buf)); + usbtmc_state.devInBuffer += sizeof(usbtmc_state.devInBuffer); + usbtmc_state.transfer_size_remaining -= sizeof(usbtmc_state.devInBuffer); + usbtmc_state.transfer_size_sent += sizeof(usbtmc_state.devInBuffer); + TU_VERIFY( usbd_edpt_xfer(rhport, usbtmc_state.ep_bulk_in, usbtmc_state.ep_bulk_in_buf,sizeof(usbtmc_state.devInBuffer))); } - usbtmc_state.transfer_size_remaining = 0; - usbtmc_state.devInBuffer = NULL; - TU_VERIFY( usbd_edpt_xfer(rhport, usbtmc_state.ep_bulk_in, usbtmc_state.ep_bulk_in_buf,(uint16_t)packetLen)); + else // last packet + { + TRACE("IN TX last packet\r\n"); + size_t packetLen = usbtmc_state.transfer_size_remaining; + memcpy(usbtmc_state.ep_bulk_in_buf, usbtmc_state.devInBuffer, usbtmc_state.transfer_size_remaining); + while((packetLen % 4) != 0) + { + usbtmc_state.ep_bulk_in_buf[packetLen] = 0u; + packetLen++; + } + usbtmc_state.transfer_size_sent += sizeof(usbtmc_state.transfer_size_remaining); + usbtmc_state.transfer_size_remaining = 0; + usbtmc_state.devInBuffer = NULL; + TU_VERIFY( usbd_edpt_xfer(rhport, usbtmc_state.ep_bulk_in, usbtmc_state.ep_bulk_in_buf,(uint16_t)packetLen)); + if(((packetLen % USBTMCD_MAX_PACKET_SIZE) != 0) || (packetLen == 0 )) + { + usbtmc_state.state = STATE_TX_SHORTED; + } + } + return true; + case STATE_ABORTING_BULK_IN: + // need to send short packet (ZLP?) + TRACE("IN aborting\r\n"); + TU_VERIFY( usbd_edpt_xfer(rhport, usbtmc_state.ep_bulk_in, usbtmc_state.ep_bulk_in_buf,(uint16_t)0u)); + usbtmc_state.state = STATE_ABORTING_BULK_IN_SHORTED; + return true; + case STATE_ABORTING_BULK_IN_SHORTED: + /* Done. :)*/ + TRACE("IN shorted\r\n"); + usbtmc_state.state = STATE_ABORTING_BULK_IN_ABORTED; + return true; + default: + TRACE("IN unknown\r\n"); + TU_ASSERT(false); + return false; } - return true; } else if (ep_addr == usbtmc_state.ep_int_in) { // Good? @@ -505,13 +569,14 @@ bool usbtmcd_control_request(uint8_t rhport, tusb_control_request_t const * requ #if (USBTMC_CFG_ENABLE_488) uint8_t bTag; #endif + TRACE("xfer cb\r\n"); if((request->bmRequestType_bit.type == TUSB_REQ_TYPE_STANDARD) && (request->bmRequestType_bit.recipient == TUSB_REQ_RCPT_ENDPOINT) && (request->bRequest == TUSB_REQ_CLEAR_FEATURE) && (request->wValue == TUSB_REQ_FEATURE_EDPT_HALT)) { - uart_tx_str_sync("feature clear\r\n"); + TRACE("feature clear\r\n"); if((request->wIndex) == usbtmc_state.ep_bulk_out) { usmtmcd_app_bulkOut_clearFeature(rhport); @@ -536,42 +601,124 @@ bool usbtmcd_control_request(uint8_t rhport, tusb_control_request_t const * requ { // USBTMC required requests case USBTMC_bREQUEST_INITIATE_ABORT_BULK_OUT: - case USBTMC_bREQUEST_CHECK_ABORT_BULK_OUT_STATUS: { - TU_VERIFY(request->bmRequestType == 0xA2); // in,class,EP - TU_VERIFY(request->wLength == 1u); - tmcStatusCode = USBTMC_STATUS_FAILED; - usbd_edpt_xfer(rhport, 0u, (void*)&tmcStatusCode,sizeof(tmcStatusCode)); + usbtmc_initiate_abort_rsp_t rsp = { + .bTag = usbtmc_state.lastBulkOutTag, + }; + TRACE("init abort bulk out\r\n"); + TU_VERIFY(request->bmRequestType == 0xA2); // in,class,interface + TU_VERIFY(request->wLength == sizeof(rsp)); + TU_VERIFY(request->wIndex == usbtmc_state.ep_bulk_out); + + // wValue is the requested bTag to abort + if(usbtmc_state.state != STATE_RCV) + { + rsp.USBTMC_status = USBTMC_STATUS_FAILED; + TRACE("init abort bulk out failed\r\n"); + } + else if(usbtmc_state.lastBulkOutTag == (request->wValue & 0xf7u)) + { + rsp.USBTMC_status = USBTMC_STATUS_TRANSFER_NOT_IN_PROGRESS; + TRACE("init abort bulk out not inprogress\r\n"); + } + else + { + rsp.USBTMC_status = USBTMC_STATUS_SUCCESS; + // Check if we've queued a short packet + usbtmc_state.state = STATE_ABORTING_BULK_OUT; + TU_VERIFY(usbtmcd_app_initiate_abort_bulk_out(rhport, &(rsp.USBTMC_status))); + usbd_edpt_stall(rhport, usbtmc_state.ep_bulk_out); + TRACE("init abort bulk out success\r\n"); + } + TU_VERIFY(tud_control_xfer(rhport, request, (void*)&rsp,sizeof(rsp))); return true; } - case USBTMC_bREQUEST_CHECK_ABORT_BULK_IN_STATUS: + case USBTMC_bREQUEST_CHECK_ABORT_BULK_OUT_STATUS: { + TRACE("init check abort bulk out\r\n"); + usbtmc_check_abort_bulk_rsp_t rsp = { + .USBTMC_status = USBTMC_STATUS_SUCCESS, + .NBYTES_RXD_TXD = usbtmc_state.transfer_size_sent + }; TU_VERIFY(request->bmRequestType == 0xA2); // in,class,EP - TU_VERIFY(request->wLength == 1u); - usbtmc_get_clear_status_rsp_t clearStatusRsp = {0}; - tmcStatusCode = USBTMC_STATUS_FAILED; - usbd_edpt_xfer(rhport, 0u, (void*)&tmcStatusCode,sizeof(tmcStatusCode)); + TU_VERIFY(request->wLength == sizeof(rsp)); + TU_VERIFY(request->wIndex == usbtmc_state.ep_bulk_out); + TU_VERIFY(usbtmcd_app_check_abort_bulk_out(rhport, &(rsp.USBTMC_status))); + TU_VERIFY(usbd_edpt_xfer(rhport, 0u, (void*)&rsp,sizeof(rsp))); return true; } case USBTMC_bREQUEST_INITIATE_ABORT_BULK_IN: { - usbtmc_initiate_abort_rsp_t rsp = {0}; - uart_tx_str_sync("init abort bulk in\r\n"); - TU_VERIFY(request->bmRequestType == 0xA1); // in,class,interface - TU_VERIFY(request->wLength == sizeof(tmcStatusCode)); - TU_VERIFY(request->wIndex == usbtmc_state.ep_int_in); + usbtmc_initiate_abort_rsp_t rsp = { + .bTag = usbtmc_state.lastBulkInTag, + }; + TRACE("init abort bulk in\r\n"); + TU_VERIFY(request->bmRequestType == 0xA2); // in,class,interface + TU_VERIFY(request->wLength == sizeof(rsp)); + TU_VERIFY(request->wIndex == usbtmc_state.ep_bulk_in); // wValue is the requested bTag to abort - usbtmc_state.transfer_size_remaining = 0; - usbtmc_state.state = STATE_ABORTING_BULK_IN; - TU_VERIFY(usbtmcd_app_initiate_clear(rhport, &tmcStatusCode)); - TU_VERIFY(tud_control_xfer(rhport, request, (void*)&tmcStatusCode,sizeof(tmcStatusCode))); + if((usbtmc_state.state == STATE_TX_REQUESTED || usbtmc_state.state == STATE_TX_INITIATED) && + usbtmc_state.lastBulkInTag == (request->wValue & 0xf7u)) + { + rsp.USBTMC_status = USBTMC_STATUS_SUCCESS; + usbtmc_state.transfer_size_remaining = 0; + // Check if we've queued a short packet + usbtmc_state.state = ((usbtmc_state.transfer_size_sent % USBTMCD_MAX_PACKET_SIZE) != 0) ? + STATE_ABORTING_BULK_IN : STATE_ABORTING_BULK_IN_SHORTED; + TU_VERIFY(usbtmcd_app_initiate_abort_bulk_in(rhport, &(rsp.USBTMC_status))); + TRACE("init abort bulk success\r\n"); + } + else if((usbtmc_state.state == STATE_TX_REQUESTED || usbtmc_state.state == STATE_TX_INITIATED)) + { // FIXME: Unsure how to check if the OUT endpoint fifo is non-empty.... + rsp.USBTMC_status = USBTMC_STATUS_TRANSFER_NOT_IN_PROGRESS; + TRACE("init abort bulk in not in progress\r\n"); + } + else + { + rsp.USBTMC_status = USBTMC_STATUS_FAILED; + TRACE("init abort bulk in failed\r\n"); + } + TU_VERIFY(tud_control_xfer(rhport, request, (void*)&rsp,sizeof(rsp))); + return true; + } + + case USBTMC_bREQUEST_CHECK_ABORT_BULK_IN_STATUS: + { + TRACE("xfer check abort in\r\n"); + TU_VERIFY(request->bmRequestType == 0xA2); // in,class,EP + TU_VERIFY(request->wLength == 8u); + + usbtmc_check_abort_bulk_rsp_t rsp = + { + .USBTMC_status = USBTMC_STATUS_FAILED, + .bmAbortBulkIn = + { + .BulkInFifoBytes = (usbtmc_state.state == STATE_ABORTING_BULK_IN_ABORTED) + }, + .NBYTES_RXD_TXD = usbtmc_state.transfer_size_sent, + }; + TU_VERIFY(usbtmcd_app_check_abort_bulk_in(rhport, &rsp)); + switch(usbtmc_state.state) + { + case STATE_ABORTING_BULK_IN_ABORTED: + rsp.USBTMC_status = USBTMC_STATUS_SUCCESS; + break; + case STATE_ABORTING_BULK_IN: + case STATE_ABORTING_BULK_OUT: + rsp.USBTMC_status = USBTMC_STATUS_PENDING; + break; + default: + break; + } + TU_VERIFY(tud_control_xfer(rhport, request, (void*)&rsp,sizeof(rsp))); + return true; } case USBTMC_bREQUEST_INITIATE_CLEAR: { - uart_tx_str_sync("init clear\r\n"); + TRACE("init clear\r\n"); TU_VERIFY(request->bmRequestType == 0xA1); // in,class,interface TU_VERIFY(request->wLength == sizeof(tmcStatusCode)); // After receiving an INITIATE_CLEAR request, the device must Halt the Bulk-OUT endpoint, queue the @@ -586,7 +733,7 @@ bool usbtmcd_control_request(uint8_t rhport, tusb_control_request_t const * requ case USBTMC_bREQUEST_CHECK_CLEAR_STATUS: { - uart_tx_str_sync("check clear\r\n"); + TRACE("check clear\r\n"); TU_VERIFY(request->bmRequestType == 0xA1); // in,class,interface usbtmc_get_clear_status_rsp_t clearStatusRsp = {0}; TU_VERIFY(request->wLength == sizeof(clearStatusRsp)); @@ -600,7 +747,7 @@ bool usbtmcd_control_request(uint8_t rhport, tusb_control_request_t const * requ else { // Let app check if it's clear - TU_VERIFY(usbtmcd_app_get_clear_status(rhport, &clearStatusRsp)); + TU_VERIFY(usbtmcd_app_check_clear(rhport, &clearStatusRsp)); } if(clearStatusRsp.USBTMC_status == USBTMC_STATUS_SUCCESS) usbtmc_state.state = STATE_IDLE; @@ -610,7 +757,7 @@ bool usbtmcd_control_request(uint8_t rhport, tusb_control_request_t const * requ case USBTMC_bREQUEST_GET_CAPABILITIES: { - uart_tx_str_sync("get capabilities\r\n"); + TRACE("get capabilities\r\n"); TU_VERIFY(request->bmRequestType == 0xA1); // in,class,interface TU_VERIFY(request->wLength == sizeof(usbtmcd_app_capabilities)); TU_VERIFY(tud_control_xfer(rhport, request, (void*)&usbtmcd_app_capabilities, sizeof(usbtmcd_app_capabilities))); @@ -620,7 +767,7 @@ bool usbtmcd_control_request(uint8_t rhport, tusb_control_request_t const * requ case USBTMC_bREQUEST_INDICATOR_PULSE: // Optional { - uart_tx_str_sync("indicate\r\n"); + TRACE("indicate\r\n"); TU_VERIFY(request->bmRequestType == 0xA1); // in,class,interface TU_VERIFY(request->wLength == sizeof(tmcStatusCode)); TU_VERIFY(usbtmcd_app_capabilities.bmIntfcCapabilities.supportsIndicatorPulse); @@ -633,7 +780,7 @@ bool usbtmcd_control_request(uint8_t rhport, tusb_control_request_t const * requ // USB488 required requests case USBTMC488_bREQUEST_READ_STATUS_BYTE: { - uart_tx_str_sync("read stb\r\n"); + TRACE("read stb\r\n"); usbtmc_read_stb_rsp_488_t rsp; TU_VERIFY(request->bmRequestType == 0xA1); // in,class,interface TU_VERIFY(request->wLength == sizeof(rsp)); // in,class,interface @@ -672,7 +819,7 @@ bool usbtmcd_control_request(uint8_t rhport, tusb_control_request_t const * requ case USBTMC488_bREQUEST_GO_TO_LOCAL: case USBTMC488_bREQUEST_LOCAL_LOCKOUT: { - uart_tx_str_sync("Unsupported REN/GTL/LLO\r\n"); + TRACE("Unsupported REN/GTL/LLO\r\n"); TU_VERIFY(request->bmRequestType == 0xA1); // in,class,interface TU_VERIFY(false); return false; @@ -680,7 +827,7 @@ bool usbtmcd_control_request(uint8_t rhport, tusb_control_request_t const * requ #endif default: - uart_tx_str_sync("Default CTRL handler\r\n"); + TRACE("Default CTRL handler\r\n"); TU_VERIFY(false); return false; } diff --git a/src/class/usbtmc/usbtmc_device.h b/src/class/usbtmc/usbtmc_device.h index a0ba82e30..4c991d5ff 100644 --- a/src/class/usbtmc/usbtmc_device.h +++ b/src/class/usbtmc/usbtmc_device.h @@ -64,9 +64,13 @@ bool usbtmcd_app_msgBulkIn_request(uint8_t rhport, usbtmc_msg_request_dev_dep_in bool usbtmcd_app_msgBulkIn_complete(uint8_t rhport); void usmtmcd_app_bulkIn_clearFeature(uint8_t rhport); // Notice to clear and abort the pending BULK out transfer +bool usbtmcd_app_initiate_abort_bulk_in(uint8_t rhport, uint8_t *tmcResult); +bool usbtmcd_app_initiate_abort_bulk_out(uint8_t rhport, uint8_t *tmcResult); bool usbtmcd_app_initiate_clear(uint8_t rhport, uint8_t *tmcResult); -bool usbtmcd_app_get_clear_status(uint8_t rhport, usbtmc_get_clear_status_rsp_t *rsp); +bool usbtmcd_app_check_abort_bulk_in(uint8_t rhport, usbtmc_check_abort_bulk_rsp_t *rsp); +bool usbtmcd_app_check_abort_bulk_out(uint8_t rhport, usbtmc_check_abort_bulk_rsp_t *rsp); +bool usbtmcd_app_check_clear(uint8_t rhport, usbtmc_get_clear_status_rsp_t *rsp); // Indicator pulse should be 0.5 to 1.0 seconds long TU_ATTR_WEAK bool usbtmcd_app_indicator_pluse(uint8_t rhport, tusb_control_request_t const * msg, uint8_t *tmcResult); -- cgit v1.3.1 From 99d03fcaee64104df96e332a2347aa7ecc1b6172 Mon Sep 17 00:00:00 2001 From: Nathan Conrad Date: Wed, 18 Sep 2019 19:30:44 -0400 Subject: small fixes --- examples/device/usbtmc/src/usbtmc_app.c | 10 +++++----- src/class/usbtmc/usbtmc_device.c | 13 +++++++++---- 2 files changed, 14 insertions(+), 9 deletions(-) (limited to 'src') diff --git a/examples/device/usbtmc/src/usbtmc_app.c b/examples/device/usbtmc/src/usbtmc_app.c index 03800ab17..7132f5143 100644 --- a/examples/device/usbtmc/src/usbtmc_app.c +++ b/examples/device/usbtmc/src/usbtmc_app.c @@ -86,7 +86,7 @@ bool usbtmcd_app_msgBulkOut_start(uint8_t rhport, usbtmc_msg_request_dev_dep_out { (void)rhport; (void)msgHeader; - uart_tx_str_sync("MSG_OUT_DATA: start\r\n"); + //uart_tx_str_sync("MSG_OUT_DATA: start\r\n"); return true; } bool usbtmcd_app_msg_trigger(uint8_t rhport, usbtmc_msg_generic_t* msg) { @@ -100,12 +100,12 @@ bool usbtmcd_app_msg_data(uint8_t rhport, void *data, size_t len, bool transfer_ (void)rhport; // If transfer isn't finished, we just ignore it (for now) - uart_tx_str_sync("MSG_OUT_DATA: <<<"); + /*uart_tx_str_sync("MSG_OUT_DATA: <<<"); uart_tx_sync(data,len); uart_tx_str_sync(">>>\r\n"); if(transfer_complete) uart_tx_str_sync("MSG_OUT_DATA: Complete\r\n"); - +*/ if(transfer_complete && (len >=4) && !strncasecmp("*idn?",data,4)) { queryState = 1; } @@ -132,7 +132,7 @@ bool usbtmcd_app_msgBulkIn_request(uint8_t rhport, usbtmc_msg_request_dev_dep_in rspMsg.header.bTagInverse = request->header.bTagInverse; msgReqLen = request->TransferSize; - uart_tx_str_sync("MSG_IN_DATA: Requested!\r\n"); + //uart_tx_str_sync("MSG_IN_DATA: Requested!\r\n"); TU_ASSERT(bulkInStarted == 0); bulkInStarted = 1; @@ -169,7 +169,7 @@ void usbtmc_app_task_iter(void) { if(bulkInStarted) { queryState = 0; bulkInStarted = 0; - uart_tx_str_sync("usbtmc_app_task_iter: sending rsp!\r\n"); + //uart_tx_str_sync("usbtmc_app_task_iter: sending rsp!\r\n"); usbtmcd_transmit_dev_msg_data(rhport, idn, tu_min32(sizeof(idn)-1,msgReqLen),false); // MAV is cleared in the transfer complete callback. } diff --git a/src/class/usbtmc/usbtmc_device.c b/src/class/usbtmc/usbtmc_device.c index c71d4d963..0f14fdfb4 100644 --- a/src/class/usbtmc/usbtmc_device.c +++ b/src/class/usbtmc/usbtmc_device.c @@ -31,8 +31,6 @@ * This file is part of the TinyUSB stack. */ -#include "tusb_option.h" - // Synchronization is needed in some spots. // These functions should NOT be called from interrupts. @@ -71,6 +69,9 @@ // Abort bulk in/out // No CLEAR_FEATURE/HALT no EP (yet) + +#include "tusb_option.h" + #if (TUSB_OPT_DEVICE_ENABLED && CFG_TUD_USBTMC) #include @@ -78,8 +79,12 @@ #include "usbtmc_device.h" #include "device/dcd.h" #include "device/usbd.h" + +#ifdef xDEBUG #include "uart_util.h" static char logMsg[150]; +#endif + // FIXME: I shouldn't need to include _pvt headers. #include "device/usbd_pvt.h" @@ -447,7 +452,7 @@ bool usbtmcd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint break; case USBTMC_MSGID_DEV_DEP_MSG_IN: - uart_tx_sync("Handling msg in req\r\n", 21); + TRACE("Handling msg in req\r\n"); TU_VERIFY(handle_devMsgIn(rhport, msg, xferred_bytes)); break; @@ -643,7 +648,7 @@ bool usbtmcd_control_request(uint8_t rhport, tusb_control_request_t const * requ TU_VERIFY(request->bmRequestType == 0xA2); // in,class,EP TU_VERIFY(request->wLength == sizeof(rsp)); TU_VERIFY(request->wIndex == usbtmc_state.ep_bulk_out); - TU_VERIFY(usbtmcd_app_check_abort_bulk_out(rhport, &(rsp.USBTMC_status))); + TU_VERIFY(usbtmcd_app_check_abort_bulk_out(rhport, &rsp)); TU_VERIFY(usbd_edpt_xfer(rhport, 0u, (void*)&rsp,sizeof(rsp))); return true; } -- cgit v1.3.1 From 9a726dc7ed9af8f9b035b18a667105a48d8d6d8a Mon Sep 17 00:00:00 2001 From: Nathan Conrad Date: Wed, 18 Sep 2019 21:31:38 -0400 Subject: More fixes, and a bit of SRQ. --- examples/device/usbtmc/src/usbtmc_app.c | 78 ++++++++++++++++++++++++--------- examples/device/usbtmc/visaQuery.py | 69 +++++++++++++++++++++++++++++ src/class/usbtmc/usbtmc_device.c | 44 ++++++++++--------- 3 files changed, 150 insertions(+), 41 deletions(-) create mode 100644 examples/device/usbtmc/visaQuery.py (limited to 'src') diff --git a/examples/device/usbtmc/src/usbtmc_app.c b/examples/device/usbtmc/src/usbtmc_app.c index 7132f5143..024f7de10 100644 --- a/examples/device/usbtmc/src/usbtmc_app.c +++ b/examples/device/usbtmc/src/usbtmc_app.c @@ -1,7 +1,7 @@ /* * The MIT License (MIT) * - * Copyright (c) 2019 N Conrad + * Copyright (c) 2019 Nathan Conrad * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -73,6 +73,11 @@ static volatile uint8_t status; static volatile uint16_t queryState = 0; static volatile uint32_t queryDelayStart; static volatile uint32_t bulkInStarted; +static volatile uint32_t idnQuery; + +static size_t buffer_len; +static uint8_t buffer[225]; // A few packets long should be enough. + static usbtmc_msg_dev_dep_msg_in_header_t rspMsg = { .bmTransferAttributes = @@ -82,16 +87,20 @@ static usbtmc_msg_dev_dep_msg_in_header_t rspMsg = { } }; -bool usbtmcd_app_msgBulkOut_start(uint8_t rhport, usbtmc_msg_request_dev_dep_out const * msgHeader) -{ +bool usbtmcd_app_msg_trigger(uint8_t rhport, usbtmc_msg_generic_t* msg) { (void)rhport; - (void)msgHeader; - //uart_tx_str_sync("MSG_OUT_DATA: start\r\n"); + (void)msg; return true; } -bool usbtmcd_app_msg_trigger(uint8_t rhport, usbtmc_msg_generic_t* msg) { + +bool usbtmcd_app_msgBulkOut_start(uint8_t rhport, usbtmc_msg_request_dev_dep_out const * msgHeader) +{ (void)rhport; - (void)msg; + (void)msgHeader; +#ifdef xDEBUG + uart_tx_str_sync("MSG_OUT_DATA: start\r\n"); +#endif + buffer_len = 0; return true; } @@ -100,14 +109,25 @@ bool usbtmcd_app_msg_data(uint8_t rhport, void *data, size_t len, bool transfer_ (void)rhport; // If transfer isn't finished, we just ignore it (for now) - /*uart_tx_str_sync("MSG_OUT_DATA: <<<"); +#ifdef xDEBUG + uart_tx_str_sync("MSG_OUT_DATA: <<<"); uart_tx_sync(data,len); uart_tx_str_sync(">>>\r\n"); if(transfer_complete) uart_tx_str_sync("MSG_OUT_DATA: Complete\r\n"); -*/ - if(transfer_complete && (len >=4) && !strncasecmp("*idn?",data,4)) { - queryState = 1; +#endif + + if(len + buffer_len < sizeof(buffer)) + { + memcpy(&(buffer[buffer_len]), data, len); + buffer_len += len; + } + queryState = transfer_complete; + idnQuery = 0; + + if(transfer_complete && (len >=4) && !strncasecmp("*idn?",data,4)) + { + idnQuery = 1; } return true; } @@ -116,7 +136,7 @@ bool usbtmcd_app_msgBulkIn_complete(uint8_t rhport) { (void)rhport; - status &= (uint8_t)~(0x10u); // clear MAV + status &= (uint8_t)~(0x50u); // clear MAV and SRQ return true; } @@ -131,8 +151,9 @@ bool usbtmcd_app_msgBulkIn_request(uint8_t rhport, usbtmc_msg_request_dev_dep_in rspMsg.header.bTag = request->header.bTag, rspMsg.header.bTagInverse = request->header.bTagInverse; msgReqLen = request->TransferSize; - - //uart_tx_str_sync("MSG_IN_DATA: Requested!\r\n"); +#ifdef xDEBUG + uart_tx_str_sync("MSG_IN_DATA: Requested!\r\n"); +#endif TU_ASSERT(bulkInStarted == 0); bulkInStarted = 1; @@ -145,7 +166,11 @@ bool usbtmcd_app_msgBulkIn_request(uint8_t rhport, usbtmc_msg_request_dev_dep_in void usbtmc_app_task_iter(void) { uint8_t const rhport = 0; - + uint32_t board_delay = 5u; + if(idnQuery) + { + board_delay = 350u; + } switch(queryState) { case 0: break; @@ -154,14 +179,15 @@ void usbtmc_app_task_iter(void) { queryState = 2; break; case 2: - if( (board_millis() - queryDelayStart) > 200u) { + if( (board_millis() - queryDelayStart) > board_delay) { queryDelayStart = board_millis(); queryState=3; status |= 0x10u; // MAV + status |= 0x40u; // SRQ } break; case 3: - if( (board_millis() - queryDelayStart) > 400u) { + if( (board_millis() - queryDelayStart) > board_delay) { queryState = 4; } break; @@ -169,8 +195,17 @@ void usbtmc_app_task_iter(void) { if(bulkInStarted) { queryState = 0; bulkInStarted = 0; - //uart_tx_str_sync("usbtmc_app_task_iter: sending rsp!\r\n"); - usbtmcd_transmit_dev_msg_data(rhport, idn, tu_min32(sizeof(idn)-1,msgReqLen),false); +#ifdef xDEBUG + uart_tx_str_sync("usbtmc_app_task_iter: sending rsp!\r\n"); +#endif + if(idnQuery) + { + usbtmcd_transmit_dev_msg_data(rhport, idn, tu_min32(sizeof(idn)-1,msgReqLen),false); + } + else + { + usbtmcd_transmit_dev_msg_data(rhport, buffer, tu_min32(buffer_len,msgReqLen),false); + } // MAV is cleared in the transfer complete callback. } break; @@ -235,10 +270,13 @@ void usmtmcd_app_bulkOut_clearFeature(uint8_t rhport) uint8_t usbtmcd_app_get_stb(uint8_t rhport, uint8_t *tmcResult) { (void)rhport; + uint8_t old_status = status; + status = status & ~(0x40); // clear SRQ + *tmcResult = USBTMC_STATUS_SUCCESS; // Increment status so that we see different results on each read... - return status; + return old_status; } bool usbtmcd_app_indicator_pluse(uint8_t rhport, tusb_control_request_t const * msg, uint8_t *tmcResult) diff --git a/examples/device/usbtmc/visaQuery.py b/examples/device/usbtmc/visaQuery.py new file mode 100644 index 000000000..fa3d7f5e8 --- /dev/null +++ b/examples/device/usbtmc/visaQuery.py @@ -0,0 +1,69 @@ +import visa +import time +import sys + + +def test_idn(): + idn = inst.query("*idn?"); + assert idn == "TinyUSB,ModelNumber,SerialNumber,FirmwareVer123456\r\n" + +def test_echo(): + longstr = "0123456789abcdef" * 50 + + #Next try echo from 1 to 175 characters (200 is max buffer size on DUT) + for i in range(49,175): + x = longstr[0:i] + xt = x + inst.write_termination + y = inst.query(x) + assert(xt == y), f"echo {i}" + +def test_mav(): + assert (inst.read_stb() == 0) + inst.write("123") + time.sleep(0.3) + assert (inst.read_stb() & 0x10), "MAV not set after 0.5 seconds" + + rsp = inst.read() + assert(rsp == "123\r\n") + + +def test_srq(): + assert (inst.read_stb() == 0) + inst.write("123") + + #inst.enable_event(visa.constants.VI_EVENT_SERVICE_REQ, visa.constants.VI_QUEUE) + #waitrsp = inst.wait_on_event(visa.constants.VI_EVENT_SERVICE_REQ, 5000) + #inst.discard_events(visa.constants.VI_EVENT_SERVICE_REQ, visa.constants.VI_QUEUE) + #inst.wait_for_srq() + time.sleep(0.3) + stb = inst.read_stb() + msg = "SRQ not set after 0.5 seconds, was {:02x}".format(stb) + assert (stb == 0x50),msg + + assert (inst.read_stb() == 0x10), "SRQ set at second read!" + + rsp = inst.read() + assert(rsp == "123\r\n") + + +rm = visa.ResourceManager("/c/Windows/system32/visa64.dll") +reslist = rm.list_resources("USB?::?*::INSTR") +print(reslist) + +if (len(reslist) == 0): + sys.exit() + +inst = rm.open_resource(reslist[0]); +inst.timeout = 3000 +inst.clear() + +#print(idn); +inst.clear() + +test_idn() +test_echo() +test_mav() +test_srq() + +inst.close() +print("Test complete") diff --git a/src/class/usbtmc/usbtmc_device.c b/src/class/usbtmc/usbtmc_device.c index 0f14fdfb4..27876852d 100644 --- a/src/class/usbtmc/usbtmc_device.c +++ b/src/class/usbtmc/usbtmc_device.c @@ -371,6 +371,7 @@ static bool handle_devMsgOut(uint8_t rhport, void *data, size_t len, size_t pack len = usbtmc_state.transfer_size_remaining; usbtmcd_app_msg_data(rhport,data, len, atEnd); + usbtmc_state.transfer_size_remaining -= len; usbtmc_state.transfer_size_sent += len; if(atEnd) { @@ -476,11 +477,12 @@ bool usbtmcd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint case STATE_RCV: TU_VERIFY(handle_devMsgOut(rhport, usbtmc_state.ep_bulk_out_buf, xferred_bytes, xferred_bytes)); + TU_VERIFY(usbd_edpt_xfer(rhport, usbtmc_state.ep_bulk_out, usbtmc_state.ep_bulk_out_buf, USBTMCD_MAX_PACKET_SIZE)); return true; case STATE_ABORTING_BULK_OUT: TU_VERIFY(false); - return false; // Shold be stalled by now... + return false; // Should be stalled by now... case STATE_TX_REQUESTED: case STATE_TX_INITIATED: case STATE_ABORTING_BULK_IN: @@ -516,32 +518,32 @@ bool usbtmcd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint case STATE_TX_INITIATED: if(usbtmc_state.transfer_size_remaining >=sizeof(usbtmc_state.ep_bulk_in_buf)) - { + { TRACE("IN TX continuing\r\n"); - memcpy(usbtmc_state.ep_bulk_in_buf, usbtmc_state.devInBuffer, sizeof(usbtmc_state.ep_bulk_in_buf)); - usbtmc_state.devInBuffer += sizeof(usbtmc_state.devInBuffer); - usbtmc_state.transfer_size_remaining -= sizeof(usbtmc_state.devInBuffer); + memcpy(usbtmc_state.ep_bulk_in_buf, usbtmc_state.devInBuffer, sizeof(usbtmc_state.ep_bulk_in_buf)); + usbtmc_state.devInBuffer += sizeof(usbtmc_state.devInBuffer); + usbtmc_state.transfer_size_remaining -= sizeof(usbtmc_state.devInBuffer); usbtmc_state.transfer_size_sent += sizeof(usbtmc_state.devInBuffer); - TU_VERIFY( usbd_edpt_xfer(rhport, usbtmc_state.ep_bulk_in, usbtmc_state.ep_bulk_in_buf,sizeof(usbtmc_state.devInBuffer))); - } - else // last packet - { + TU_VERIFY( usbd_edpt_xfer(rhport, usbtmc_state.ep_bulk_in, usbtmc_state.ep_bulk_in_buf,sizeof(usbtmc_state.devInBuffer))); + } + else // last packet + { TRACE("IN TX last packet\r\n"); - size_t packetLen = usbtmc_state.transfer_size_remaining; - memcpy(usbtmc_state.ep_bulk_in_buf, usbtmc_state.devInBuffer, usbtmc_state.transfer_size_remaining); - while((packetLen % 4) != 0) - { + size_t packetLen = usbtmc_state.transfer_size_remaining; + memcpy(usbtmc_state.ep_bulk_in_buf, usbtmc_state.devInBuffer, usbtmc_state.transfer_size_remaining); + while((packetLen % 4) != 0) + { usbtmc_state.ep_bulk_in_buf[packetLen] = 0u; - packetLen++; - } + packetLen++; + } usbtmc_state.transfer_size_sent += sizeof(usbtmc_state.transfer_size_remaining); - usbtmc_state.transfer_size_remaining = 0; - usbtmc_state.devInBuffer = NULL; - TU_VERIFY( usbd_edpt_xfer(rhport, usbtmc_state.ep_bulk_in, usbtmc_state.ep_bulk_in_buf,(uint16_t)packetLen)); + usbtmc_state.transfer_size_remaining = 0; + usbtmc_state.devInBuffer = NULL; + TU_VERIFY( usbd_edpt_xfer(rhport, usbtmc_state.ep_bulk_in, usbtmc_state.ep_bulk_in_buf,(uint16_t)packetLen)); if(((packetLen % USBTMCD_MAX_PACKET_SIZE) != 0) || (packetLen == 0 )) { usbtmc_state.state = STATE_TX_SHORTED; - } + } } return true; case STATE_ABORTING_BULK_IN: @@ -554,7 +556,7 @@ bool usbtmcd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint /* Done. :)*/ TRACE("IN shorted\r\n"); usbtmc_state.state = STATE_ABORTING_BULK_IN_ABORTED; - return true; + return true; default: TRACE("IN unknown\r\n"); TU_ASSERT(false); @@ -667,7 +669,7 @@ bool usbtmcd_control_request(uint8_t rhport, tusb_control_request_t const * requ usbtmc_state.lastBulkInTag == (request->wValue & 0xf7u)) { rsp.USBTMC_status = USBTMC_STATUS_SUCCESS; - usbtmc_state.transfer_size_remaining = 0; + usbtmc_state.transfer_size_remaining = 0; // Check if we've queued a short packet usbtmc_state.state = ((usbtmc_state.transfer_size_sent % USBTMCD_MAX_PACKET_SIZE) != 0) ? STATE_ABORTING_BULK_IN : STATE_ABORTING_BULK_IN_SHORTED; -- cgit v1.3.1 From d4b2dff7c40f005be3ce4d383efcb59182a9a228 Mon Sep 17 00:00:00 2001 From: Nathan Conrad Date: Wed, 18 Sep 2019 23:53:28 -0400 Subject: Fix more TX bugs... and add variable response delay to the example project. --- examples/device/usbtmc/src/usbtmc_app.c | 27 ++++++++++++++------- examples/device/usbtmc/visaQuery.py | 37 ++++++++++++++++++++++------- src/class/usbtmc/usbtmc_device.c | 42 +++++++++++++-------------------- 3 files changed, 63 insertions(+), 43 deletions(-) (limited to 'src') diff --git a/examples/device/usbtmc/src/usbtmc_app.c b/examples/device/usbtmc/src/usbtmc_app.c index 024f7de10..7c7431928 100644 --- a/examples/device/usbtmc/src/usbtmc_app.c +++ b/examples/device/usbtmc/src/usbtmc_app.c @@ -24,6 +24,7 @@ */ #include +#include /* atoi */ #include "class/usbtmc/usbtmc_device.h" #include "bsp/board.h" #include "main.h" @@ -75,6 +76,7 @@ static volatile uint32_t queryDelayStart; static volatile uint32_t bulkInStarted; static volatile uint32_t idnQuery; +static uint32_t resp_delay = 125u; // Adjustable delay, to allow for better testing static size_t buffer_len; static uint8_t buffer[225]; // A few packets long should be enough. @@ -115,6 +117,8 @@ bool usbtmcd_app_msg_data(uint8_t rhport, void *data, size_t len, bool transfer_ uart_tx_str_sync(">>>\r\n"); if(transfer_complete) uart_tx_str_sync("MSG_OUT_DATA: Complete\r\n"); + sprintf(bigMsg, "len=%u complete=%u\r\n",len,(uint32_t)transfer_complete); + uart_tx_str_sync(bigMsg); #endif if(len + buffer_len < sizeof(buffer)) @@ -129,6 +133,13 @@ bool usbtmcd_app_msg_data(uint8_t rhport, void *data, size_t len, bool transfer_ { idnQuery = 1; } + if(transfer_complete && !strncasecmp("delay ",data,5)) + { + queryState = 0; + resp_delay = atoi((char*)data + 5); + if(resp_delay > 10000u) + resp_delay = 10000u; + } return true; } @@ -166,11 +177,6 @@ bool usbtmcd_app_msgBulkIn_request(uint8_t rhport, usbtmc_msg_request_dev_dep_in void usbtmc_app_task_iter(void) { uint8_t const rhport = 0; - uint32_t board_delay = 5u; - if(idnQuery) - { - board_delay = 350u; - } switch(queryState) { case 0: break; @@ -179,7 +185,7 @@ void usbtmc_app_task_iter(void) { queryState = 2; break; case 2: - if( (board_millis() - queryDelayStart) > board_delay) { + if( (board_millis() - queryDelayStart) > resp_delay) { queryDelayStart = board_millis(); queryState=3; status |= 0x10u; // MAV @@ -187,7 +193,7 @@ void usbtmc_app_task_iter(void) { } break; case 3: - if( (board_millis() - queryDelayStart) > board_delay) { + if( (board_millis() - queryDelayStart) > resp_delay) { queryState = 4; } break; @@ -200,7 +206,7 @@ void usbtmc_app_task_iter(void) { #endif if(idnQuery) { - usbtmcd_transmit_dev_msg_data(rhport, idn, tu_min32(sizeof(idn)-1,msgReqLen),false); + usbtmcd_transmit_dev_msg_data(rhport, idn, tu_min32(sizeof(idn)-1,msgReqLen),false); } else { @@ -237,17 +243,20 @@ bool usbtmcd_app_check_clear(uint8_t rhport, usbtmc_get_clear_status_rsp_t *rsp) } bool usbtmcd_app_initiate_abort_bulk_in(uint8_t rhport, uint8_t *tmcResult) { + (void)rhport; bulkInStarted = 0; *tmcResult = USBTMC_STATUS_SUCCESS; return true; } bool usbtmcd_app_check_abort_bulk_in(uint8_t rhport, usbtmc_check_abort_bulk_rsp_t *rsp) { + (void)rhport; return true; } bool usbtmcd_app_initiate_abort_bulk_out(uint8_t rhport, uint8_t *tmcResult) { + (void)rhport; *tmcResult = USBTMC_STATUS_SUCCESS; return true; @@ -271,7 +280,7 @@ uint8_t usbtmcd_app_get_stb(uint8_t rhport, uint8_t *tmcResult) { (void)rhport; uint8_t old_status = status; - status = status & ~(0x40); // clear SRQ + status = status & ~(0x40u); // clear SRQ *tmcResult = USBTMC_STATUS_SUCCESS; // Increment status so that we see different results on each read... diff --git a/examples/device/usbtmc/visaQuery.py b/examples/device/usbtmc/visaQuery.py index fa3d7f5e8..2034e6ff7 100644 --- a/examples/device/usbtmc/visaQuery.py +++ b/examples/device/usbtmc/visaQuery.py @@ -7,15 +7,20 @@ def test_idn(): idn = inst.query("*idn?"); assert idn == "TinyUSB,ModelNumber,SerialNumber,FirmwareVer123456\r\n" -def test_echo(): - longstr = "0123456789abcdef" * 50 +def test_echo(m,n): + longstr = "0123456789abcdefghijklmnopqrstuvwxyz" * 50 #Next try echo from 1 to 175 characters (200 is max buffer size on DUT) - for i in range(49,175): + for i in range(m,n): + #print(i) x = longstr[0:i] xt = x + inst.write_termination y = inst.query(x) - assert(xt == y), f"echo {i}" + #print(x) + #print (":".join("{:02x}".format(ord(c)) for c in xt)) + #print (":".join("{:02x}".format(ord(c)) for c in y)) + assert(xt == y), f"failed i={i}" + inst.read_stb();# Just to make USB logging easier by sending a control query def test_mav(): assert (inst.read_stb() == 0) @@ -57,12 +62,28 @@ inst = rm.open_resource(reslist[0]); inst.timeout = 3000 inst.clear() -#print(idn); -inst.clear() +#print("+ IDN") +#test_idn() + +print("+ random trigger") +#inst.assert_trigger(); + +print("+ echo delay=0") +inst.write("delay 0") +test_echo(1,175) + +print("+ echo delay=2") +inst.write("delay 2") +test_echo(1,175) + +print("+ echo delay=200") +inst.write("delay 200") +test_echo(50,90) +test_echo(165,170) -test_idn() -test_echo() +print("+ MAV") test_mav() +print("+ SRQ") test_srq() inst.close() diff --git a/src/class/usbtmc/usbtmc_device.c b/src/class/usbtmc/usbtmc_device.c index 27876852d..eab4397ba 100644 --- a/src/class/usbtmc/usbtmc_device.c +++ b/src/class/usbtmc/usbtmc_device.c @@ -203,12 +203,6 @@ bool usbtmcd_transmit_dev_msg_data( { memcpy((uint8_t*)(usbtmc_state.ep_bulk_in_buf) + packetLen, data, hdr->TransferSize); packetLen = (uint16_t)(packetLen + hdr->TransferSize); - // Pad up to multiple of 4 bytes - while((packetLen % 4) != 0) - { - usbtmc_state.ep_bulk_in_buf[packetLen] = 0; - packetLen++; - } usbtmc_state.transfer_size_remaining = 0; usbtmc_state.transfer_size_sent = len; usbtmc_state.devInBuffer = NULL; @@ -518,32 +512,28 @@ bool usbtmcd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint case STATE_TX_INITIATED: if(usbtmc_state.transfer_size_remaining >=sizeof(usbtmc_state.ep_bulk_in_buf)) - { - TRACE("IN TX continuing\r\n"); - memcpy(usbtmc_state.ep_bulk_in_buf, usbtmc_state.devInBuffer, sizeof(usbtmc_state.ep_bulk_in_buf)); - usbtmc_state.devInBuffer += sizeof(usbtmc_state.devInBuffer); - usbtmc_state.transfer_size_remaining -= sizeof(usbtmc_state.devInBuffer); - usbtmc_state.transfer_size_sent += sizeof(usbtmc_state.devInBuffer); - TU_VERIFY( usbd_edpt_xfer(rhport, usbtmc_state.ep_bulk_in, usbtmc_state.ep_bulk_in_buf,sizeof(usbtmc_state.devInBuffer))); - } - else // last packet - { - TRACE("IN TX last packet\r\n"); - size_t packetLen = usbtmc_state.transfer_size_remaining; - memcpy(usbtmc_state.ep_bulk_in_buf, usbtmc_state.devInBuffer, usbtmc_state.transfer_size_remaining); - while((packetLen % 4) != 0) { - usbtmc_state.ep_bulk_in_buf[packetLen] = 0u; - packetLen++; + TRACE("IN TX continuing\r\n"); + // FIXME! This removes const below! + TU_VERIFY( usbd_edpt_xfer(rhport, usbtmc_state.ep_bulk_in, + (void*)usbtmc_state.devInBuffer,sizeof(usbtmc_state.ep_bulk_in_buf))); + usbtmc_state.devInBuffer += sizeof(usbtmc_state.ep_bulk_in_buf); + usbtmc_state.transfer_size_remaining -= sizeof(usbtmc_state.ep_bulk_in_buf); + usbtmc_state.transfer_size_sent += sizeof(usbtmc_state.ep_bulk_in_buf); } + else // last packet + { + TRACE("IN TX last packet\r\n"); + size_t packetLen = usbtmc_state.transfer_size_remaining; + memcpy(usbtmc_state.ep_bulk_in_buf, usbtmc_state.devInBuffer, usbtmc_state.transfer_size_remaining); usbtmc_state.transfer_size_sent += sizeof(usbtmc_state.transfer_size_remaining); - usbtmc_state.transfer_size_remaining = 0; - usbtmc_state.devInBuffer = NULL; - TU_VERIFY( usbd_edpt_xfer(rhport, usbtmc_state.ep_bulk_in, usbtmc_state.ep_bulk_in_buf,(uint16_t)packetLen)); + usbtmc_state.transfer_size_remaining = 0; + usbtmc_state.devInBuffer = NULL; + TU_VERIFY( usbd_edpt_xfer(rhport, usbtmc_state.ep_bulk_in, usbtmc_state.ep_bulk_in_buf,(uint16_t)packetLen)); if(((packetLen % USBTMCD_MAX_PACKET_SIZE) != 0) || (packetLen == 0 )) { usbtmc_state.state = STATE_TX_SHORTED; - } + } } return true; case STATE_ABORTING_BULK_IN: -- cgit v1.3.1 From 85623584f99dfa0a974ffe62639e58a0f2589674 Mon Sep 17 00:00:00 2001 From: Nathan Conrad Date: Thu, 19 Sep 2019 09:24:52 -0400 Subject: Remove debug assertions. --- src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c | 46 +-------------------------- 1 file changed, 1 insertion(+), 45 deletions(-) (limited to 'src') diff --git a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c index e2df2abe4..71c7ff7ce 100644 --- a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c +++ b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c @@ -168,11 +168,6 @@ static xfer_ctl_t xfer_status[MAX_EP_COUNT][2]; static xfer_ctl_t* xfer_ctl_ptr(uint32_t epnum, uint32_t dir) { -#ifndef NDEBUG - TU_ASSERT(epnum < MAX_EP_COUNT); - TU_ASSERT(dir < 2u); -#endif - return &xfer_status[epnum][dir]; } @@ -587,32 +582,10 @@ bool dcd_edpt_open (uint8_t rhport, tusb_desc_endpoint_t const * p_endpoint_desc uint8_t const dir = tu_edpt_dir(p_endpoint_desc->bEndpointAddress); const uint16_t epMaxPktSize = p_endpoint_desc->wMaxPacketSize.size; // Isochronous not supported (yet), and some other driver assumptions. -#ifndef NDEBUG + TU_ASSERT(p_endpoint_desc->bmAttributes.xfer != TUSB_XFER_ISOCHRONOUS); TU_ASSERT(epnum < MAX_EP_COUNT); - switch(p_endpoint_desc->bmAttributes.xfer) { - case TUSB_XFER_CONTROL: - // USB 2.0 spec on FS packets, 5.5.3 (control) - TU_ASSERT((epMaxPktSize == 8) ||(epMaxPktSize == 16) || (epMaxPktSize == 32) || (epMaxPktSize == 64)); - break; - case TUSB_XFER_ISOCHRONOUS: // FIXME: Not yet supported - TU_ASSERT(epMaxPktSize <= 1023); - break; - case TUSB_XFER_BULK: - // USB 2.0 spec on FS packets, 5.8.3 (bulk) - TU_ASSERT((epMaxPktSize == 8) ||(epMaxPktSize == 16) ||(epMaxPktSize == 32) ||(epMaxPktSize == 64)); - break; - case TUSB_XFER_INTERRUPT: - // USB 2.0 spec on FS packets, 5.5.3 (interrupt); interestingly 0 is allowed. - TU_ASSERT(epMaxPktSize <= 64); - break; - default: - TU_ASSERT(false); - return false; - } -#endif - // Set type switch(p_endpoint_desc->bmAttributes.xfer) { case TUSB_XFER_CONTROL: @@ -776,14 +749,6 @@ static bool dcd_write_packet_memory(uint16_t dst, const void *__restrict src, si uint16_t temp1, temp2; const uint8_t * srcVal; -#ifndef NDEBUG -# if (DCD_STM32_BTABLE_BASE > 0u) - TU_ASSERT(dst >= DCD_STM32_BTABLE_BASE); -# endif - TU_ASSERT((dst%2) == 0); - TU_ASSERT((dst + wNBytes) <= (DCD_STM32_BTABLE_BASE + DCD_STM32_BTABLE_LENGTH)); -#endif - // The GCC optimizer will combine access to 32-bit sizes if we let it. Force // it volatile so that it won't do that. __IO uint16_t *pdwVal; @@ -818,15 +783,6 @@ static bool dcd_read_packet_memory(void *__restrict dst, uint16_t src, size_t wN __IO const uint16_t *pdwVal; uint32_t temp; -#ifndef NDEBUG -# if (DCD_STM32_BTABLE_BASE > 0u) - TU_ASSERT(src >= DCD_STM32_BTABLE_BASE); -# endif - TU_ASSERT((src%2) == 0); - TU_ASSERT((src + wNBytes) <= (DCD_STM32_BTABLE_BASE + DCD_STM32_BTABLE_LENGTH)); -#endif - - pdwVal = &pma[PMA_STRIDE*(src>>1)]; uint8_t *dstVal = (uint8_t*)dst; -- cgit v1.3.1 From 642afeea8b7189cd37e2bbf87427df95f5587c72 Mon Sep 17 00:00:00 2001 From: Nathan Conrad Date: Thu, 19 Sep 2019 09:28:19 -0400 Subject: s/static const/define/ --- src/portable/st/stm32_fsdev/dcd_stm32_fsdev_pvt_st.h | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev_pvt_st.h b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev_pvt_st.h index e205979fc..ff25df048 100644 --- a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev_pvt_st.h +++ b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev_pvt_st.h @@ -46,7 +46,7 @@ defined(STM32F072xB) | \ defined(STM32F078xx) #include "stm32f0xx.h" -#define PMA_LENGTH 1024 +#define PMA_LENGTH (1024u) // F0x2 models are crystal-less // All have internal D+ pull-up // 070RB: 2 x 16 bits/word memory LPM Support, BCD Support @@ -55,7 +55,7 @@ defined(STM32F103x6) | defined(STM32F103xB) | \ defined(STM32F103xE) | defined(STM32F103xB) #include "stm32f1xx.h" -#define PMA_LENGTH 512u +#define PMA_LENGTH (512u) // NO internal Pull-ups // *B, and *C: 2 x 16 bits/word #error The F102/F103 driver is expected not to work, but it might? Try it? @@ -64,7 +64,7 @@ defined(STM32F303xB) | defined(STM32F303xC) | \ defined(STM32F373xC) #include "stm32f3xx.h" -#define PMA_LENGTH 512u +#define PMA_LENGTH (512u) // NO internal Pull-ups // *B, and *C: 1 x 16 bits/word // PMA dedicated to USB (no sharing with CAN) @@ -72,7 +72,7 @@ defined(STM32F302xD) | defined(STM32F302xE) | \ defined(STM32F303xD) | defined(STM32F303xE) | \ #include "stm32f3xx.h" -#define PMA_LENGTH 1024u +#define PMA_LENGTH (1024u) // NO internal Pull-ups // *6, *8, *D, and *E: 2 x 16 bits/word LPM Support // When CAN clock is enabled, USB can use first 768 bytes ONLY. @@ -83,9 +83,9 @@ // For purposes of accessing the packet #if ((PMA_LENGTH) == 512u) -const size_t PMA_STRIDE = 2u; +#define PMA_STRIDE (2u) #elif ((PMA_LENGTH) == 1024u) -const size_t PMA_STRIDE = 1u; +#define PMA_STRIDE (1u) #endif // And for type-safety create a new macro for the volatile address of PMAADDR -- cgit v1.3.1 From 525b4cdb720d79836d80be2664037bf89961111a Mon Sep 17 00:00:00 2001 From: Nathan Conrad Date: Thu, 19 Sep 2019 09:51:40 -0400 Subject: Use ESOF for wakeup timing. --- src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-) (limited to 'src') diff --git a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c index 71c7ff7ce..aec8ea0c7 100644 --- a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c +++ b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c @@ -121,7 +121,6 @@ #undef USE_HAL_DRIVER #include "device/dcd.h" -#include "bsp/board.h" #include "portable/st/stm32_fsdev/dcd_stm32_fsdev_pvt_st.h" @@ -174,6 +173,7 @@ static xfer_ctl_t* xfer_ctl_ptr(uint32_t epnum, uint32_t dir) static TU_ATTR_ALIGNED(4) uint32_t _setup_packet[6]; static uint8_t newDADDR; // Used to set the new device address during the CTR IRQ handler +static uint8_t remoteWakeCountdown; // When wake is requested // EP Buffers assigned from end of memory location, to minimize their chance of crashing // into the stack. @@ -235,7 +235,7 @@ void dcd_init (uint8_t rhport) { pma[PMA_STRIDE*(DCD_STM32_BTABLE_BASE + i)] = 0u; } - USB->CNTR |= USB_CNTR_RESETM | USB_CNTR_SOFM | USB_CNTR_CTRM | USB_CNTR_SUSPM | USB_CNTR_WKUPM; + USB->CNTR |= USB_CNTR_RESETM | USB_CNTR_SOFM | USB_CNTR_ESOFM | USB_CNTR_CTRM | USB_CNTR_SUSPM | USB_CNTR_WKUPM; dcd_handle_bus_reset(); // And finally enable pull-up, which may trigger the RESET IRQ if the host is connected. @@ -304,17 +304,9 @@ void dcd_set_config (uint8_t rhport, uint8_t config_num) void dcd_remote_wakeup(uint8_t rhport) { (void) rhport; - uint32_t start; USB->CNTR |= (uint16_t)USB_CNTR_RESUME; - /* Wait 1 to 15 ms */ - /* Busy loop is bad, but the osal_task_delay() isn't implemented for the "none" OSAL */ - start = board_millis(); - while ((board_millis() - start) < 2) - { - ; - } - USB->CNTR &= (uint16_t)(~USB_CNTR_RESUME); + remoteWakeCountdown = 4u; // required to be 1 to 15 ms, ESOF should trigger every 1ms. } // I'm getting a weird warning about missing braces here that I don't @@ -566,6 +558,18 @@ static void dcd_fs_irqHandler(void) { reg16_clear_bits(&USB->ISTR, USB_ISTR_SOF); dcd_event_bus_signal(0, DCD_EVENT_SOF, true); } + + if(int_status & USB_ISTR_ESOF) { + if(remoteWakeCountdown == 1u) + { + USB->CNTR &= (uint16_t)(~USB_CNTR_RESUME); + } + if(remoteWakeCountdown > 0u) + { + remoteWakeCountdown--; + } + reg16_clear_bits(&USB->ISTR, USB_ISTR_ESOF); + } } //--------------------------------------------------------------------+ -- cgit v1.3.1 From 0548f97d3300edb4d57f6920f6307211833917f2 Mon Sep 17 00:00:00 2001 From: Nathan Conrad Date: Thu, 19 Sep 2019 16:25:59 -0400 Subject: Remove debug printf. --- examples/device/usbtmc/src/usbtmc_app.c | 16 +------ src/class/usbtmc/usbtmc_device.c | 82 +++++---------------------------- 2 files changed, 12 insertions(+), 86 deletions(-) (limited to 'src') diff --git a/examples/device/usbtmc/src/usbtmc_app.c b/examples/device/usbtmc/src/usbtmc_app.c index 7c7431928..8ce468561 100644 --- a/examples/device/usbtmc/src/usbtmc_app.c +++ b/examples/device/usbtmc/src/usbtmc_app.c @@ -99,9 +99,6 @@ bool usbtmcd_app_msgBulkOut_start(uint8_t rhport, usbtmc_msg_request_dev_dep_out { (void)rhport; (void)msgHeader; -#ifdef xDEBUG - uart_tx_str_sync("MSG_OUT_DATA: start\r\n"); -#endif buffer_len = 0; return true; } @@ -111,15 +108,6 @@ bool usbtmcd_app_msg_data(uint8_t rhport, void *data, size_t len, bool transfer_ (void)rhport; // If transfer isn't finished, we just ignore it (for now) -#ifdef xDEBUG - uart_tx_str_sync("MSG_OUT_DATA: <<<"); - uart_tx_sync(data,len); - uart_tx_str_sync(">>>\r\n"); - if(transfer_complete) - uart_tx_str_sync("MSG_OUT_DATA: Complete\r\n"); - sprintf(bigMsg, "len=%u complete=%u\r\n",len,(uint32_t)transfer_complete); - uart_tx_str_sync(bigMsg); -#endif if(len + buffer_len < sizeof(buffer)) { @@ -201,9 +189,7 @@ void usbtmc_app_task_iter(void) { if(bulkInStarted) { queryState = 0; bulkInStarted = 0; -#ifdef xDEBUG - uart_tx_str_sync("usbtmc_app_task_iter: sending rsp!\r\n"); -#endif + if(idnQuery) { usbtmcd_transmit_dev_msg_data(rhport, idn, tu_min32(sizeof(idn)-1,msgReqLen),false); diff --git a/src/class/usbtmc/usbtmc_device.c b/src/class/usbtmc/usbtmc_device.c index eab4397ba..3a4e9e3e0 100644 --- a/src/class/usbtmc/usbtmc_device.c +++ b/src/class/usbtmc/usbtmc_device.c @@ -137,11 +137,6 @@ static usbtmc_interface_state_t usbtmc_state = .ep_bulk_out = 0, .ep_int_in = 0 }; -#ifdef xDEBUG -#define TRACE(str) uart_tx_str_sync(str) -#else -#define TRACE(STR) do {} while (0) -#endif // We need all headers to fit in a single packet in this implementation. TU_VERIFY_STATIC(USBTMCD_MAX_PACKET_SIZE >= 32u,"USBTMC dev EP packet size too small"); @@ -383,11 +378,6 @@ static bool handle_devMsgIn(uint8_t rhport, void *data, size_t len) TU_VERIFY(len == sizeof(usbtmc_msg_request_dev_dep_in)); usbtmc_msg_request_dev_dep_in *msg = (usbtmc_msg_request_dev_dep_in*)data; -#ifdef xDebug - sprintf(logMsg," handle_devMsgIn len=%ul\r\n",len); - TRACE(logMsg); -#endif - criticalEnter(); { TU_VERIFY(usbtmc_state.state == STATE_IDLE); @@ -409,14 +399,8 @@ static bool handle_devMsgIn(uint8_t rhport, void *data, size_t len) bool usbtmcd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes) { - TRACE("USBTMC Xfer CB" ); TU_VERIFY(result == XFER_RESULT_SUCCESS); -#ifdef xDebug - sprintf(logMsg," STATE=%lu ", (uint32_t)usbtmc_state.state); - TRACE(logMsg); -#endif - if(usbtmc_state.state == STATE_CLEARING) { return true; /* I think we can ignore everything here */ } @@ -424,7 +408,7 @@ bool usbtmcd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint if(ep_addr == usbtmc_state.ep_bulk_out) { usbtmc_msg_generic_t *msg = NULL; - TRACE("OUT"); + switch(usbtmc_state.state) { case STATE_IDLE: @@ -434,11 +418,6 @@ bool usbtmcd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint TU_VERIFY(msg->header.bTag == invInvTag); TU_VERIFY(msg->header.bTag != 0x00); -#ifdef xDebug - sprintf(logMsg," type=%lu\r\n",(uint32_t)msg->header.MsgID); - TRACE(logMsg); -#endif - switch(msg->header.MsgID) { case USBTMC_MSGID_DEV_DEP_MSG_OUT: usbtmc_state.transfer_size_sent = 0u; @@ -447,7 +426,6 @@ bool usbtmcd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint break; case USBTMC_MSGID_DEV_DEP_MSG_IN: - TRACE("Handling msg in req\r\n"); TU_VERIFY(handle_devMsgIn(rhport, msg, xferred_bytes)); break; @@ -484,71 +462,52 @@ bool usbtmcd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint case STATE_ABORTING_BULK_IN_ABORTED: default: -#ifdef xDebug - if(msg == NULL) - sprintf(logMsg," Unknown received control?\r\n "); - else { - sprintf(logMsg," msg=%lu\r\n ", (uint32_t)msg->header.MsgID); - } - TRACE(logMsg); -#endif TU_VERIFY(false); } } else if(ep_addr == usbtmc_state.ep_bulk_in) { -#ifdef xDebug - sprintf(logMsg,"IN\r\n"); - TRACE(logMsg); -#endif switch(usbtmc_state.state) { case STATE_TX_SHORTED: - TRACE("IN TX shorted done\r\n"); - usbtmc_state.state = STATE_IDLE; TU_VERIFY(usbtmcd_app_msgBulkIn_complete(rhport)); break; case STATE_TX_INITIATED: if(usbtmc_state.transfer_size_remaining >=sizeof(usbtmc_state.ep_bulk_in_buf)) - { - TRACE("IN TX continuing\r\n"); + { // FIXME! This removes const below! TU_VERIFY( usbd_edpt_xfer(rhport, usbtmc_state.ep_bulk_in, (void*)usbtmc_state.devInBuffer,sizeof(usbtmc_state.ep_bulk_in_buf))); usbtmc_state.devInBuffer += sizeof(usbtmc_state.ep_bulk_in_buf); usbtmc_state.transfer_size_remaining -= sizeof(usbtmc_state.ep_bulk_in_buf); usbtmc_state.transfer_size_sent += sizeof(usbtmc_state.ep_bulk_in_buf); - } - else // last packet - { - TRACE("IN TX last packet\r\n"); - size_t packetLen = usbtmc_state.transfer_size_remaining; - memcpy(usbtmc_state.ep_bulk_in_buf, usbtmc_state.devInBuffer, usbtmc_state.transfer_size_remaining); + } + else // last packet + { + size_t packetLen = usbtmc_state.transfer_size_remaining; + memcpy(usbtmc_state.ep_bulk_in_buf, usbtmc_state.devInBuffer, usbtmc_state.transfer_size_remaining); usbtmc_state.transfer_size_sent += sizeof(usbtmc_state.transfer_size_remaining); - usbtmc_state.transfer_size_remaining = 0; - usbtmc_state.devInBuffer = NULL; - TU_VERIFY( usbd_edpt_xfer(rhport, usbtmc_state.ep_bulk_in, usbtmc_state.ep_bulk_in_buf,(uint16_t)packetLen)); + usbtmc_state.transfer_size_remaining = 0; + usbtmc_state.devInBuffer = NULL; + TU_VERIFY( usbd_edpt_xfer(rhport, usbtmc_state.ep_bulk_in, usbtmc_state.ep_bulk_in_buf,(uint16_t)packetLen)); if(((packetLen % USBTMCD_MAX_PACKET_SIZE) != 0) || (packetLen == 0 )) { usbtmc_state.state = STATE_TX_SHORTED; - } + } } return true; case STATE_ABORTING_BULK_IN: // need to send short packet (ZLP?) - TRACE("IN aborting\r\n"); TU_VERIFY( usbd_edpt_xfer(rhport, usbtmc_state.ep_bulk_in, usbtmc_state.ep_bulk_in_buf,(uint16_t)0u)); usbtmc_state.state = STATE_ABORTING_BULK_IN_SHORTED; return true; case STATE_ABORTING_BULK_IN_SHORTED: /* Done. :)*/ - TRACE("IN shorted\r\n"); usbtmc_state.state = STATE_ABORTING_BULK_IN_ABORTED; return true; default: - TRACE("IN unknown\r\n"); TU_ASSERT(false); return false; } @@ -566,14 +525,12 @@ bool usbtmcd_control_request(uint8_t rhport, tusb_control_request_t const * requ #if (USBTMC_CFG_ENABLE_488) uint8_t bTag; #endif - TRACE("xfer cb\r\n"); if((request->bmRequestType_bit.type == TUSB_REQ_TYPE_STANDARD) && (request->bmRequestType_bit.recipient == TUSB_REQ_RCPT_ENDPOINT) && (request->bRequest == TUSB_REQ_CLEAR_FEATURE) && (request->wValue == TUSB_REQ_FEATURE_EDPT_HALT)) { - TRACE("feature clear\r\n"); if((request->wIndex) == usbtmc_state.ep_bulk_out) { usmtmcd_app_bulkOut_clearFeature(rhport); @@ -602,7 +559,6 @@ bool usbtmcd_control_request(uint8_t rhport, tusb_control_request_t const * requ usbtmc_initiate_abort_rsp_t rsp = { .bTag = usbtmc_state.lastBulkOutTag, }; - TRACE("init abort bulk out\r\n"); TU_VERIFY(request->bmRequestType == 0xA2); // in,class,interface TU_VERIFY(request->wLength == sizeof(rsp)); TU_VERIFY(request->wIndex == usbtmc_state.ep_bulk_out); @@ -611,12 +567,10 @@ bool usbtmcd_control_request(uint8_t rhport, tusb_control_request_t const * requ if(usbtmc_state.state != STATE_RCV) { rsp.USBTMC_status = USBTMC_STATUS_FAILED; - TRACE("init abort bulk out failed\r\n"); } else if(usbtmc_state.lastBulkOutTag == (request->wValue & 0xf7u)) { rsp.USBTMC_status = USBTMC_STATUS_TRANSFER_NOT_IN_PROGRESS; - TRACE("init abort bulk out not inprogress\r\n"); } else { @@ -625,14 +579,12 @@ bool usbtmcd_control_request(uint8_t rhport, tusb_control_request_t const * requ usbtmc_state.state = STATE_ABORTING_BULK_OUT; TU_VERIFY(usbtmcd_app_initiate_abort_bulk_out(rhport, &(rsp.USBTMC_status))); usbd_edpt_stall(rhport, usbtmc_state.ep_bulk_out); - TRACE("init abort bulk out success\r\n"); } TU_VERIFY(tud_control_xfer(rhport, request, (void*)&rsp,sizeof(rsp))); return true; } case USBTMC_bREQUEST_CHECK_ABORT_BULK_OUT_STATUS: { - TRACE("init check abort bulk out\r\n"); usbtmc_check_abort_bulk_rsp_t rsp = { .USBTMC_status = USBTMC_STATUS_SUCCESS, .NBYTES_RXD_TXD = usbtmc_state.transfer_size_sent @@ -650,7 +602,6 @@ bool usbtmcd_control_request(uint8_t rhport, tusb_control_request_t const * requ usbtmc_initiate_abort_rsp_t rsp = { .bTag = usbtmc_state.lastBulkInTag, }; - TRACE("init abort bulk in\r\n"); TU_VERIFY(request->bmRequestType == 0xA2); // in,class,interface TU_VERIFY(request->wLength == sizeof(rsp)); TU_VERIFY(request->wIndex == usbtmc_state.ep_bulk_in); @@ -664,17 +615,14 @@ bool usbtmcd_control_request(uint8_t rhport, tusb_control_request_t const * requ usbtmc_state.state = ((usbtmc_state.transfer_size_sent % USBTMCD_MAX_PACKET_SIZE) != 0) ? STATE_ABORTING_BULK_IN : STATE_ABORTING_BULK_IN_SHORTED; TU_VERIFY(usbtmcd_app_initiate_abort_bulk_in(rhport, &(rsp.USBTMC_status))); - TRACE("init abort bulk success\r\n"); } else if((usbtmc_state.state == STATE_TX_REQUESTED || usbtmc_state.state == STATE_TX_INITIATED)) { // FIXME: Unsure how to check if the OUT endpoint fifo is non-empty.... rsp.USBTMC_status = USBTMC_STATUS_TRANSFER_NOT_IN_PROGRESS; - TRACE("init abort bulk in not in progress\r\n"); } else { rsp.USBTMC_status = USBTMC_STATUS_FAILED; - TRACE("init abort bulk in failed\r\n"); } TU_VERIFY(tud_control_xfer(rhport, request, (void*)&rsp,sizeof(rsp))); return true; @@ -682,7 +630,6 @@ bool usbtmcd_control_request(uint8_t rhport, tusb_control_request_t const * requ case USBTMC_bREQUEST_CHECK_ABORT_BULK_IN_STATUS: { - TRACE("xfer check abort in\r\n"); TU_VERIFY(request->bmRequestType == 0xA2); // in,class,EP TU_VERIFY(request->wLength == 8u); @@ -715,7 +662,6 @@ bool usbtmcd_control_request(uint8_t rhport, tusb_control_request_t const * requ case USBTMC_bREQUEST_INITIATE_CLEAR: { - TRACE("init clear\r\n"); TU_VERIFY(request->bmRequestType == 0xA1); // in,class,interface TU_VERIFY(request->wLength == sizeof(tmcStatusCode)); // After receiving an INITIATE_CLEAR request, the device must Halt the Bulk-OUT endpoint, queue the @@ -730,7 +676,6 @@ bool usbtmcd_control_request(uint8_t rhport, tusb_control_request_t const * requ case USBTMC_bREQUEST_CHECK_CLEAR_STATUS: { - TRACE("check clear\r\n"); TU_VERIFY(request->bmRequestType == 0xA1); // in,class,interface usbtmc_get_clear_status_rsp_t clearStatusRsp = {0}; TU_VERIFY(request->wLength == sizeof(clearStatusRsp)); @@ -754,7 +699,6 @@ bool usbtmcd_control_request(uint8_t rhport, tusb_control_request_t const * requ case USBTMC_bREQUEST_GET_CAPABILITIES: { - TRACE("get capabilities\r\n"); TU_VERIFY(request->bmRequestType == 0xA1); // in,class,interface TU_VERIFY(request->wLength == sizeof(usbtmcd_app_capabilities)); TU_VERIFY(tud_control_xfer(rhport, request, (void*)&usbtmcd_app_capabilities, sizeof(usbtmcd_app_capabilities))); @@ -764,7 +708,6 @@ bool usbtmcd_control_request(uint8_t rhport, tusb_control_request_t const * requ case USBTMC_bREQUEST_INDICATOR_PULSE: // Optional { - TRACE("indicate\r\n"); TU_VERIFY(request->bmRequestType == 0xA1); // in,class,interface TU_VERIFY(request->wLength == sizeof(tmcStatusCode)); TU_VERIFY(usbtmcd_app_capabilities.bmIntfcCapabilities.supportsIndicatorPulse); @@ -777,7 +720,6 @@ bool usbtmcd_control_request(uint8_t rhport, tusb_control_request_t const * requ // USB488 required requests case USBTMC488_bREQUEST_READ_STATUS_BYTE: { - TRACE("read stb\r\n"); usbtmc_read_stb_rsp_488_t rsp; TU_VERIFY(request->bmRequestType == 0xA1); // in,class,interface TU_VERIFY(request->wLength == sizeof(rsp)); // in,class,interface @@ -816,7 +758,6 @@ bool usbtmcd_control_request(uint8_t rhport, tusb_control_request_t const * requ case USBTMC488_bREQUEST_GO_TO_LOCAL: case USBTMC488_bREQUEST_LOCAL_LOCKOUT: { - TRACE("Unsupported REN/GTL/LLO\r\n"); TU_VERIFY(request->bmRequestType == 0xA1); // in,class,interface TU_VERIFY(false); return false; @@ -824,7 +765,6 @@ bool usbtmcd_control_request(uint8_t rhport, tusb_control_request_t const * requ #endif default: - TRACE("Default CTRL handler\r\n"); TU_VERIFY(false); return false; } -- cgit v1.3.1 From 346443118fa9f22611ca1382ff999e43b6a40b43 Mon Sep 17 00:00:00 2001 From: Nathan Conrad Date: Thu, 19 Sep 2019 18:58:15 -0400 Subject: Add testcase for aborting bulk in with no data queued (and fix aborting bulk in) --- examples/device/usbtmc/src/usbtmc_app.c | 2 +- examples/device/usbtmc/visaQuery.py | 29 +++++++++++++++++++++++++++-- src/class/usbtmc/usbtmc_device.c | 14 +++++++++++--- 3 files changed, 39 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/examples/device/usbtmc/src/usbtmc_app.c b/examples/device/usbtmc/src/usbtmc_app.c index ea6e6aa6f..0d03a5ef1 100644 --- a/examples/device/usbtmc/src/usbtmc_app.c +++ b/examples/device/usbtmc/src/usbtmc_app.c @@ -203,7 +203,7 @@ void usbtmc_app_task_iter(void) { if(idnQuery) { - usbtmcd_transmit_dev_msg_data(rhport, idn, tu_min32(sizeof(idn)-1,msgReqLen),false); + usbtmcd_transmit_dev_msg_data(rhport, idn, tu_min32(sizeof(idn)-1,msgReqLen),false); } else { diff --git a/examples/device/usbtmc/visaQuery.py b/examples/device/usbtmc/visaQuery.py index 9610cbc8f..368b66053 100644 --- a/examples/device/usbtmc/visaQuery.py +++ b/examples/device/usbtmc/visaQuery.py @@ -3,6 +3,7 @@ import time import sys + def test_idn(): idn = inst.query("*idn?"); assert idn == "TinyUSB,ModelNumber,SerialNumber,FirmwareVer123456\r\n" @@ -60,6 +61,24 @@ def test_srq(): rsp = inst.read() assert(rsp == "123\r\n") + + +def test_read_timeout(): + inst.timeout = 500 + # First read with no MAV + inst.read_stb() + assert (inst.read_stb() == 0) + inst.write("delay 500") + t0 = time.time() + try: + rsp = inst.read() + assert(false), "Read should have resulted in timeout" + except visa.VisaIOError: + print("Got expected exception") + t = time.time() - t0 + assert ((t*1000.0) > (inst.timeout - 300)) + assert ((t*1000.0) < (inst.timeout + 300)) + print(f"Delay was {t}") rm = visa.ResourceManager("/c/Windows/system32/visa64.dll") reslist = rm.list_resources("USB?::?*::INSTR") @@ -72,8 +91,11 @@ inst = rm.open_resource(reslist[0]); inst.timeout = 3000 inst.clear() -#print("+ IDN") -#test_idn() +print("+ IDN") +test_idn() + +inst.timeout = 3000 + print("+ echo delay=0") inst.write("delay 0") @@ -88,6 +110,9 @@ inst.write("delay 150") test_echo(53,76) test_echo(165,170) +print("+ Read timeout (no MAV") +test_read_timeout() + print("+ MAV") test_mav() diff --git a/src/class/usbtmc/usbtmc_device.c b/src/class/usbtmc/usbtmc_device.c index 3a4e9e3e0..db00b841f 100644 --- a/src/class/usbtmc/usbtmc_device.c +++ b/src/class/usbtmc/usbtmc_device.c @@ -102,7 +102,7 @@ typedef enum STATE_CLEARING, STATE_ABORTING_BULK_IN, STATE_ABORTING_BULK_IN_SHORTED, // aborting, and short packet has been queued for transmission - STATE_ABORTING_BULK_IN_ABORTED, // aborting, and short packet has been queued for transmission + STATE_ABORTING_BULK_IN_ABORTED, // aborting, and short packet has been transmitted STATE_ABORTING_BULK_OUT, STATE_NUM_STATES } usbtmcd_state_enum; @@ -384,6 +384,7 @@ static bool handle_devMsgIn(uint8_t rhport, void *data, size_t len) usbtmc_state.state = STATE_TX_REQUESTED; usbtmc_state.lastBulkInTag = msg->header.bTag; usbtmc_state.transfer_size_remaining = msg->TransferSize; + usbtmc_state.transfer_size_sent = 0u; } criticalLeave(); @@ -612,8 +613,14 @@ bool usbtmcd_control_request(uint8_t rhport, tusb_control_request_t const * requ rsp.USBTMC_status = USBTMC_STATUS_SUCCESS; usbtmc_state.transfer_size_remaining = 0; // Check if we've queued a short packet - usbtmc_state.state = ((usbtmc_state.transfer_size_sent % USBTMCD_MAX_PACKET_SIZE) != 0) ? + usbtmc_state.state = ((usbtmc_state.transfer_size_sent % USBTMCD_MAX_PACKET_SIZE) == 0) ? STATE_ABORTING_BULK_IN : STATE_ABORTING_BULK_IN_SHORTED; + if(usbtmc_state.transfer_size_sent == 0) + { + // Send short packet, nothing is in the buffer yet + TU_VERIFY( usbd_edpt_xfer(rhport, usbtmc_state.ep_bulk_in, usbtmc_state.ep_bulk_in_buf,(uint16_t)0u)); + usbtmc_state.state = STATE_ABORTING_BULK_IN_SHORTED; + } TU_VERIFY(usbtmcd_app_initiate_abort_bulk_in(rhport, &(rsp.USBTMC_status))); } else if((usbtmc_state.state == STATE_TX_REQUESTED || usbtmc_state.state == STATE_TX_INITIATED)) @@ -638,7 +645,7 @@ bool usbtmcd_control_request(uint8_t rhport, tusb_control_request_t const * requ .USBTMC_status = USBTMC_STATUS_FAILED, .bmAbortBulkIn = { - .BulkInFifoBytes = (usbtmc_state.state == STATE_ABORTING_BULK_IN_ABORTED) + .BulkInFifoBytes = (usbtmc_state.state != STATE_ABORTING_BULK_IN_ABORTED) }, .NBYTES_RXD_TXD = usbtmc_state.transfer_size_sent, }; @@ -647,6 +654,7 @@ bool usbtmcd_control_request(uint8_t rhport, tusb_control_request_t const * requ { case STATE_ABORTING_BULK_IN_ABORTED: rsp.USBTMC_status = USBTMC_STATUS_SUCCESS; + usbtmc_state.state = STATE_IDLE; break; case STATE_ABORTING_BULK_IN: case STATE_ABORTING_BULK_OUT: -- cgit v1.3.1 From 7e0490bbf32ed4a25e1917a1e5856338b9dc9346 Mon Sep 17 00:00:00 2001 From: Nathan Conrad Date: Thu, 19 Sep 2019 19:51:37 -0400 Subject: Move descriptors to usbd.h --- examples/device/usbtmc/src/usb_descriptors.c | 20 +++++++++--------- src/class/usbtmc/usbtmc_device.c | 5 +++-- src/class/usbtmc/usbtmc_device.h | 30 --------------------------- src/device/usbd.c | 3 ++- src/device/usbd.h | 31 ++++++++++++++++++++++++++++ 5 files changed, 46 insertions(+), 43 deletions(-) (limited to 'src') diff --git a/examples/device/usbtmc/src/usb_descriptors.c b/examples/device/usbtmc/src/usb_descriptors.c index 792fff87c..45e1001ea 100644 --- a/examples/device/usbtmc/src/usb_descriptors.c +++ b/examples/device/usbtmc/src/usb_descriptors.c @@ -105,16 +105,16 @@ uint8_t const * tud_hid_descriptor_report_cb(void) #if defined(CFG_TUD_USBTMC) -# define USBTMC_DESC_MAIN(_itfnum,_bNumEndpoints) \ - USBTMC_IF_DESCRIPTOR(_itfnum, _bNumEndpoints, /*_stridx = */ 4u, USBTMC_PROTOCOL_USB488), \ - USBTMC_BULK_DESCRIPTORS(/* OUT = */0x03, /* IN = */ 0x83) +# define TUD_USBTMC_DESC_MAIN(_itfnum,_bNumEndpoints) \ + TUD_USBTMC_IF_DESCRIPTOR(_itfnum, _bNumEndpoints, /*_stridx = */ 4u, TUD_USBTMC_PROTOCOL_USB488), \ + TUD_USBTMC_BULK_DESCRIPTORS(/* OUT = */0x03, /* IN = */ 0x83, /* packet size = */USBTMCD_MAX_PACKET_SIZE) #if defined(CFG_TUD_USBTMC_ENABLE_INT_EP) // Interrupt endpoint should be 2 bytes on a FS USB link -# define USBTMC_DESC(_itfnum) \ - USBTMC_DESC_MAIN(_itfnum, /* _epCount = */ 3), \ - USBTMC_INT_DESCRIPTOR(/* INT ep # */ 0x84, /* epMaxSize = */ 2, /* bInterval = */16u ) -# define USBTMC_DESC_LEN (USBTMC_IF_DESCRIPTOR_LEN + USBTMC_BULK_DESCRIPTORS_LEN + USBTMC_INT_DESCRIPTOR_LEN) +# define TUD_USBTMC_DESC(_itfnum) \ + TUD_USBTMC_DESC_MAIN(_itfnum, /* _epCount = */ 3), \ + TUD_USBTMC_INT_DESCRIPTOR(/* INT ep # */ 0x84, /* epMaxSize = */ 2, /* bInterval = */16u ) +# define USBTMC_DESC_LEN (TUD_USBTMC_IF_DESCRIPTOR_LEN + TUD_USBTMC_BULK_DESCRIPTORS_LEN + TUD_USBTMC_INT_DESCRIPTOR_LEN) #else @@ -174,7 +174,7 @@ uint8_t const desc_configuration[] = #endif #if CFG_TUD_USBTMC - USBTMC_DESC(ITF_NUM_USBTMC), + TUD_USBTMC_DESC(ITF_NUM_USBTMC), #endif #if CFG_TUD_MSC @@ -218,7 +218,7 @@ static uint16_t _desc_str[32]; // 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) { - uint8_t chr_count; + size_t chr_count; if ( index == 0) { @@ -246,7 +246,7 @@ uint16_t const* tud_descriptor_string_cb(uint8_t index) } // first byte is length (including header), second byte is string type - _desc_str[0] = (((uint16_t)TUSB_DESC_STRING) << 8 ) | (2u*chr_count + 2u); + _desc_str[0] = (uint16_t)((((uint16_t)TUSB_DESC_STRING) << 8 ) | (2u*chr_count + 2u)); return _desc_str; } diff --git a/src/class/usbtmc/usbtmc_device.c b/src/class/usbtmc/usbtmc_device.c index db00b841f..f62bcd2b7 100644 --- a/src/class/usbtmc/usbtmc_device.c +++ b/src/class/usbtmc/usbtmc_device.c @@ -251,9 +251,9 @@ bool usbtmcd_open(uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint16 usbtmcd_reset(rhport); // Perhaps there are other application specific class drivers, so don't assert here. - if( itf_desc->bInterfaceClass != USBTMC_APP_CLASS) + if( itf_desc->bInterfaceClass != TUD_USBTMC_APP_CLASS) return false; - if( itf_desc->bInterfaceSubClass != USBTMC_APP_SUBCLASS) + if( itf_desc->bInterfaceSubClass != TUD_USBTMC_APP_SUBCLASS) return false; // Only 2 or 3 endpoints are allowed for USBTMC. @@ -272,6 +272,7 @@ bool usbtmcd_open(uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint16 tusb_desc_endpoint_t const *ep_desc = (tusb_desc_endpoint_t const *)p_desc; switch(ep_desc->bmAttributes.xfer) { case TUSB_XFER_BULK: + TU_ASSERT(ep_desc->wMaxPacketSize.size == USBTMCD_MAX_PACKET_SIZE); if (tu_edpt_dir(ep_desc->bEndpointAddress) == TUSB_DIR_IN) { usbtmc_state.ep_bulk_in = ep_desc->bEndpointAddress; diff --git a/src/class/usbtmc/usbtmc_device.h b/src/class/usbtmc/usbtmc_device.h index 4c991d5ff..1e28563dd 100644 --- a/src/class/usbtmc/usbtmc_device.h +++ b/src/class/usbtmc/usbtmc_device.h @@ -107,35 +107,5 @@ void usbtmcd_init(void); * USBTMC Descriptor Templates *************************************************************/ -#define USBTMC_APP_CLASS TUSB_CLASS_APPLICATION_SPECIFIC -#define USBTMC_APP_SUBCLASS 0x03u - -#define USBTMC_PROTOCOL_STD 0x00u -#define USBTMC_PROTOCOL_USB488 0x01u - -// Interface number, number of endpoints, EP string index, USB_TMC_PROTOCOL*, bulk-out endpoint ID, -// bulk-in endpoint ID -#define USBTMC_IF_DESCRIPTOR(_itfnum, _bNumEndpoints, _stridx, _itfProtocol) \ -/* Interface */ \ - 0x09, TUSB_DESC_INTERFACE, _itfnum, 0x00, _bNumEndpoints, USBTMC_APP_CLASS, USBTMC_APP_SUBCLASS, _itfProtocol, _stridx - -#define USBTMC_IF_DESCRIPTOR_LEN 9u - -// bulk-out Size must be a multiple of 4 bytes -#define USBTMC_BULK_DESCRIPTORS(_epout, _epin) \ -/* Endpoint Out */ \ -7, TUSB_DESC_ENDPOINT, _epout, TUSB_XFER_BULK, U16_TO_U8S_LE(USBTMCD_MAX_PACKET_SIZE), 0u, \ -/* Endpoint In */ \ -7, TUSB_DESC_ENDPOINT, _epin, TUSB_XFER_BULK, U16_TO_U8S_LE(USBTMCD_MAX_PACKET_SIZE), 0u - -#define USBTMC_BULK_DESCRIPTORS_LEN (7u+7u) - -/* optional interrupt endpoint */ \ -// _int_pollingInterval : for LS/FS, expressed in frames (1ms each). 16 may be a good number? -#define USBTMC_INT_DESCRIPTOR(_ep_interrupt, _ep_interrupt_size, _int_pollingInterval ) \ -7, TUSB_DESC_ENDPOINT, _ep_interrupt, TUSB_XFER_INTERRUPT, U16_TO_U8S_LE(_ep_interrupt_size), 0x16 - -#define USBTMC_INT_DESCRIPTOR_LEN (7u) - #endif /* CLASS_USBTMC_USBTMC_DEVICE_H_ */ diff --git a/src/device/usbd.c b/src/device/usbd.c index 2f8967fae..f8f1da82e 100644 --- a/src/device/usbd.c +++ b/src/device/usbd.c @@ -151,7 +151,8 @@ static usbd_class_driver_t const usbd_class_drivers[] = // We maybe need to add subclass codes here, or a callback to ask if a driver can // handle a particular interface. { - .class_code = TUSB_CLASS_APPLICATION_SPECIFIC, + .class_code = TUD_USBTMC_APP_CLASS, + //.subclass_code = TUD_USBTMC_APP_SUBCLASS .init = usbtmcd_init, .reset = usbtmcd_reset, .open = usbtmcd_open, diff --git a/src/device/usbd.h b/src/device/usbd.h index 5f96e55a4..f0887f0db 100644 --- a/src/device/usbd.h +++ b/src/device/usbd.h @@ -261,6 +261,37 @@ TU_ATTR_WEAK bool tud_vendor_control_complete_cb(uint8_t rhport, tusb_control_re /* MS Endpoint (connected to embedded jack out) */\ 5, TUSB_DESC_CS_ENDPOINT, MIDI_CS_ENDPOINT_GENERAL, 1, 3 +//------------- TUD_USBTMC/USB488 -------------// +#define TUD_USBTMC_APP_CLASS (TUSB_CLASS_APPLICATION_SPECIFIC) +#define TUD_USBTMC_APP_SUBCLASS 0x03u + +#define TUD_USBTMC_PROTOCOL_STD 0x00u +#define TUD_USBTMC_PROTOCOL_USB488 0x01u + +// Interface number, number of endpoints, EP string index, USB_TMC_PROTOCOL*, bulk-out endpoint ID, +// bulk-in endpoint ID +#define TUD_USBTMC_IF_DESCRIPTOR(_itfnum, _bNumEndpoints, _stridx, _itfProtocol) \ +/* Interface */ \ + 0x09, TUSB_DESC_INTERFACE, _itfnum, 0x00, _bNumEndpoints, TUD_USBTMC_APP_CLASS, TUD_USBTMC_APP_SUBCLASS, _itfProtocol, _stridx + +#define TUD_USBTMC_IF_DESCRIPTOR_LEN 9u + +#define TUD_USBTMC_BULK_DESCRIPTORS(_epout, _epin, _bulk_epsize) \ +/* Endpoint Out */ \ +7, TUSB_DESC_ENDPOINT, _epout, TUSB_XFER_BULK, U16_TO_U8S_LE(_bulk_epsize), 0u, \ +/* Endpoint In */ \ +7, TUSB_DESC_ENDPOINT, _epin, TUSB_XFER_BULK, U16_TO_U8S_LE(_bulk_epsize), 0u + +#define TUD_USBTMC_BULK_DESCRIPTORS_LEN (7u+7u) + +/* optional interrupt endpoint */ \ +// _int_pollingInterval : for LS/FS, expressed in frames (1ms each). 16 may be a good number? +#define TUD_USBTMC_INT_DESCRIPTOR(_ep_interrupt, _ep_interrupt_size, _int_pollingInterval ) \ +7, TUSB_DESC_ENDPOINT, _ep_interrupt, TUSB_XFER_INTERRUPT, U16_TO_U8S_LE(_ep_interrupt_size), 0x16 + +#define TUD_USBTMC_INT_DESCRIPTOR_LEN (7u) + + //------------- Vendor -------------// #define TUD_VENDOR_DESC_LEN (9+7+7) -- cgit v1.3.1 From d742c3e15cb2233e927d6fdc4702863dc41eb65a Mon Sep 17 00:00:00 2001 From: Nathan Conrad Date: Thu, 19 Sep 2019 19:54:37 -0400 Subject: s/USBTMC488/USB488/ ; fix types in bitfield --- src/class/usbtmc/usbtmc.h | 14 +++++++------- src/class/usbtmc/usbtmc_device.c | 8 ++++---- 2 files changed, 11 insertions(+), 11 deletions(-) (limited to 'src') diff --git a/src/class/usbtmc/usbtmc.h b/src/class/usbtmc/usbtmc.h index 0944c907a..810b523c5 100644 --- a/src/class/usbtmc/usbtmc.h +++ b/src/class/usbtmc/usbtmc.h @@ -139,9 +139,9 @@ TU_VERIFY_STATIC(sizeof(usbtmc_msg_request_vendor_specific_in) == 12u, "struct w /* typedef struct TU_ATTR_PACKED { struct { - uint8_t Recipient : 5 ; ///< EOM set on last byte - uint8_t Type : 2 ; ///< EOM set on last byte - uint8_t DirectionToHost : 1 ; ///< 0 is OUT, 1 is IN + unsigned int Recipient : 5 ; ///< EOM set on last byte + unsigned int Type : 2 ; ///< EOM set on last byte + unsigned int DirectionToHost : 1 ; ///< 0 is OUT, 1 is IN } bmRequestType; uint8_t bRequest ; ///< If bmRequestType.Type = Class, see usmtmc_request_type_enum uint16_t wValue ; @@ -176,10 +176,10 @@ typedef enum { USBTMC_bREQUEST_INDICATOR_PULSE = 64u, // Optional /****** USBTMC 488 *************/ - USBTMC488_bREQUEST_READ_STATUS_BYTE = 128u, - USBTMC488_bREQUEST_REN_CONTROL = 160u, - USBTMC488_bREQUEST_GO_TO_LOCAL = 161u, - USBTMC488_bREQUEST_LOCAL_LOCKOUT = 162u, + USB488_bREQUEST_READ_STATUS_BYTE = 128u, + USB488_bREQUEST_REN_CONTROL = 160u, + USB488_bREQUEST_GO_TO_LOCAL = 161u, + USB488_bREQUEST_LOCAL_LOCKOUT = 162u, } usmtmc_request_type_enum; diff --git a/src/class/usbtmc/usbtmc_device.c b/src/class/usbtmc/usbtmc_device.c index f62bcd2b7..6306ab074 100644 --- a/src/class/usbtmc/usbtmc_device.c +++ b/src/class/usbtmc/usbtmc_device.c @@ -727,7 +727,7 @@ bool usbtmcd_control_request(uint8_t rhport, tusb_control_request_t const * requ #if (USBTMC_CFG_ENABLE_488) // USB488 required requests - case USBTMC488_bREQUEST_READ_STATUS_BYTE: + case USB488_bREQUEST_READ_STATUS_BYTE: { usbtmc_read_stb_rsp_488_t rsp; TU_VERIFY(request->bmRequestType == 0xA1); // in,class,interface @@ -763,9 +763,9 @@ bool usbtmcd_control_request(uint8_t rhport, tusb_control_request_t const * requ return true; } // USB488 optional requests - case USBTMC488_bREQUEST_REN_CONTROL: - case USBTMC488_bREQUEST_GO_TO_LOCAL: - case USBTMC488_bREQUEST_LOCAL_LOCKOUT: + case USB488_bREQUEST_REN_CONTROL: + case USB488_bREQUEST_GO_TO_LOCAL: + case USB488_bREQUEST_LOCAL_LOCKOUT: { TU_VERIFY(request->bmRequestType == 0xA1); // in,class,interface TU_VERIFY(false); -- cgit v1.3.1 From f3d6d0127b4e4f1c7d986e27b5c8b42378dda999 Mon Sep 17 00:00:00 2001 From: Nathan Conrad Date: Thu, 19 Sep 2019 19:59:44 -0400 Subject: Rename USBTMC_CFG_ENABLE_488, and fix build with it off. --- examples/device/usbtmc/src/tusb_config.h | 2 +- examples/device/usbtmc/src/usbtmc_app.c | 4 ++-- src/class/usbtmc/usbtmc_device.c | 11 ++++++----- src/class/usbtmc/usbtmc_device.h | 8 ++++---- 4 files changed, 13 insertions(+), 12 deletions(-) (limited to 'src') diff --git a/examples/device/usbtmc/src/tusb_config.h b/examples/device/usbtmc/src/tusb_config.h index 16484424a..688fb02be 100644 --- a/examples/device/usbtmc/src/tusb_config.h +++ b/examples/device/usbtmc/src/tusb_config.h @@ -57,7 +57,7 @@ #define CFG_TUD_USBTMC 1 #define CFG_TUD_USBTMC_ENABLE_INT_EP 1 -#define USBTMC_CFG_ENABLE_488 1 +#define CFG_USBTMC_CFG_ENABLE_488 1 #ifdef __cplusplus } diff --git a/examples/device/usbtmc/src/usbtmc_app.c b/examples/device/usbtmc/src/usbtmc_app.c index 0d03a5ef1..895c65b26 100644 --- a/examples/device/usbtmc/src/usbtmc_app.c +++ b/examples/device/usbtmc/src/usbtmc_app.c @@ -29,7 +29,7 @@ #include "bsp/board.h" #include "main.h" -#if (USBTMC_CFG_ENABLE_488) +#if (CFG_USBTMC_CFG_ENABLE_488) usbtmc_response_capabilities_488_t const #else usbtmc_response_capabilities_t const @@ -48,7 +48,7 @@ usbtmcd_app_capabilities = .canEndBulkInOnTermChar = 0 }, -#if (USBTMC_CFG_ENABLE_488) +#if (CFG_USBTMC_CFG_ENABLE_488) .bcdUSB488 = USBTMC_488_VERSION, .bmIntfcCapabilities488 = { diff --git a/src/class/usbtmc/usbtmc_device.c b/src/class/usbtmc/usbtmc_device.c index 6306ab074..d4a6a0db0 100644 --- a/src/class/usbtmc/usbtmc_device.c +++ b/src/class/usbtmc/usbtmc_device.c @@ -227,7 +227,7 @@ bool usbtmcd_transmit_dev_msg_data( void usbtmcd_init(void) { #ifndef NDEBUG -# if USBTMC_CFG_ENABLE_488 +# if CFG_USBTMC_CFG_ENABLE_488 if(usbtmcd_app_capabilities.bmIntfcCapabilities488.supportsTrigger) TU_ASSERT(&usbtmcd_app_msg_trigger != NULL,); // Per USB488 spec: table 8 @@ -310,12 +310,13 @@ bool usbtmcd_open(uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint16 { TU_ASSERT(usbtmc_state.ep_int_in != 0); } - +#if (USBTMC_CFG_ENABLE_488) if(usbtmcd_app_capabilities.bmIntfcCapabilities488.is488_2 || usbtmcd_app_capabilities.bmDevCapabilities488.SR1) { TU_ASSERT(usbtmc_state.ep_int_in != 0); } +#endif #endif TU_VERIFY( usbd_edpt_xfer(rhport, usbtmc_state.ep_bulk_out, usbtmc_state.ep_bulk_out_buf, 64)); @@ -431,7 +432,7 @@ bool usbtmcd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint TU_VERIFY(handle_devMsgIn(rhport, msg, xferred_bytes)); break; -#ifdef USBTMC_CFG_ENABLE_488 +#if (CFG_USBTMC_CFG_ENABLE_488) case USBTMC_MSGID_USB488_TRIGGER: // Spec says we halt the EP if we didn't declare we support it. TU_VERIFY(usbtmcd_app_capabilities.bmIntfcCapabilities488.supportsTrigger); @@ -524,7 +525,7 @@ bool usbtmcd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint bool usbtmcd_control_request(uint8_t rhport, tusb_control_request_t const * request) { uint8_t tmcStatusCode = USBTMC_STATUS_FAILED; -#if (USBTMC_CFG_ENABLE_488) +#if (CFG_USBTMC_CFG_ENABLE_488) uint8_t bTag; #endif @@ -724,7 +725,7 @@ bool usbtmcd_control_request(uint8_t rhport, tusb_control_request_t const * requ TU_VERIFY(tud_control_xfer(rhport, request, (void*)&tmcStatusCode, sizeof(tmcStatusCode))); return true; } -#if (USBTMC_CFG_ENABLE_488) +#if (CFG_USBTMC_CFG_ENABLE_488) // USB488 required requests case USB488_bREQUEST_READ_STATUS_BYTE: diff --git a/src/class/usbtmc/usbtmc_device.h b/src/class/usbtmc/usbtmc_device.h index 1e28563dd..3c8d10572 100644 --- a/src/class/usbtmc/usbtmc_device.h +++ b/src/class/usbtmc/usbtmc_device.h @@ -37,8 +37,8 @@ #include "usbtmc.h" // Enable 488 mode by default -#if !defined(USBTMC_CFG_ENABLE_488) -#define USBTMC_CFG_ENABLE_488 (1) +#if !defined(CFG_USBTMC_CFG_ENABLE_488) +#define CFG_CFG_USBTMC_CFG_ENABLE_488 (1) #endif // USB spec says that full-speed must be 8,16,32, or 64. @@ -49,7 +49,7 @@ * Functions to be implemeted by the class implementation */ -#if (USBTMC_CFG_ENABLE_488) +#if (CFG_USBTMC_CFG_ENABLE_488) extern usbtmc_response_capabilities_488_t const usbtmcd_app_capabilities; #else extern usbtmc_response_capabilities_t const usbtmcd_app_capabilities; @@ -75,7 +75,7 @@ bool usbtmcd_app_check_clear(uint8_t rhport, usbtmc_get_clear_status_rsp_t *rsp) // Indicator pulse should be 0.5 to 1.0 seconds long TU_ATTR_WEAK bool usbtmcd_app_indicator_pluse(uint8_t rhport, tusb_control_request_t const * msg, uint8_t *tmcResult); -#if (USBTMC_CFG_ENABLE_488) +#if (CFG_USBTMC_CFG_ENABLE_488) uint8_t usbtmcd_app_get_stb(uint8_t rhport, uint8_t *tmcResult); TU_ATTR_WEAK bool usbtmcd_app_msg_trigger(uint8_t rhport, usbtmc_msg_generic_t* msg); //TU_ATTR_WEAK bool usbtmcd_app_go_to_local(uint8_t rhport); -- cgit v1.3.1 From 2a7ca15e2ce7df5f0271438bd58007ccf558eb4d Mon Sep 17 00:00:00 2001 From: Nathan Conrad Date: Thu, 19 Sep 2019 20:08:45 -0400 Subject: Rename functions to include tud_ and _cb --- examples/device/usbtmc/src/usbtmc_app.c | 34 ++++++++-------- src/class/usbtmc/usbtmc.h | 2 +- src/class/usbtmc/usbtmc_device.c | 72 ++++++++++++++++----------------- src/class/usbtmc/usbtmc_device.h | 46 ++++++++++----------- src/device/usbd.c | 10 ++--- 5 files changed, 82 insertions(+), 82 deletions(-) (limited to 'src') diff --git a/examples/device/usbtmc/src/usbtmc_app.c b/examples/device/usbtmc/src/usbtmc_app.c index 895c65b26..f8c350f68 100644 --- a/examples/device/usbtmc/src/usbtmc_app.c +++ b/examples/device/usbtmc/src/usbtmc_app.c @@ -25,7 +25,7 @@ #include #include /* atoi */ -#include "class/usbtmc/usbtmc_device.h" +#include "tusb.h" #include "bsp/board.h" #include "main.h" @@ -34,7 +34,7 @@ usbtmc_response_capabilities_488_t const #else usbtmc_response_capabilities_t const #endif -usbtmcd_app_capabilities = +tud_usbtmc_app_capabilities = { .USBTMC_status = USBTMC_STATUS_SUCCESS, .bcdUSBTMC = USBTMC_VERSION, @@ -95,7 +95,7 @@ static usbtmc_msg_dev_dep_msg_in_header_t rspMsg = { } }; -bool usbtmcd_app_msg_trigger(uint8_t rhport, usbtmc_msg_generic_t* msg) { +bool tud_usbtmc_app_msg_trigger_cb(uint8_t rhport, usbtmc_msg_generic_t* msg) { (void)rhport; (void)msg; // Let trigger set the SRQ @@ -103,7 +103,7 @@ bool usbtmcd_app_msg_trigger(uint8_t rhport, usbtmc_msg_generic_t* msg) { return true; } -bool usbtmcd_app_msgBulkOut_start(uint8_t rhport, usbtmc_msg_request_dev_dep_out const * msgHeader) +bool tud_usbtmc_app_msgBulkOut_start_cb(uint8_t rhport, usbtmc_msg_request_dev_dep_out const * msgHeader) { (void)rhport; (void)msgHeader; @@ -111,7 +111,7 @@ bool usbtmcd_app_msgBulkOut_start(uint8_t rhport, usbtmc_msg_request_dev_dep_out return true; } -bool usbtmcd_app_msg_data(uint8_t rhport, void *data, size_t len, bool transfer_complete) +bool tud_usbtmc_app_msg_data_cb(uint8_t rhport, void *data, size_t len, bool transfer_complete) { (void)rhport; @@ -142,7 +142,7 @@ bool usbtmcd_app_msg_data(uint8_t rhport, void *data, size_t len, bool transfer_ return true; } -bool usbtmcd_app_msgBulkIn_complete(uint8_t rhport) +bool tud_usbtmc_app_msgBulkIn_complete_cb(uint8_t rhport) { (void)rhport; @@ -153,7 +153,7 @@ bool usbtmcd_app_msgBulkIn_complete(uint8_t rhport) static unsigned int msgReqLen; -bool usbtmcd_app_msgBulkIn_request(uint8_t rhport, usbtmc_msg_request_dev_dep_in const * request) +bool tud_usbtmc_app_msgBulkIn_request_cb(uint8_t rhport, usbtmc_msg_request_dev_dep_in const * request) { (void)rhport; @@ -218,7 +218,7 @@ void usbtmc_app_task_iter(void) { } } -bool usbtmcd_app_initiate_clear(uint8_t rhport, uint8_t *tmcResult) +bool tud_usbtmc_app_initiate_clear_cb(uint8_t rhport, uint8_t *tmcResult) { (void)rhport; *tmcResult = USBTMC_STATUS_SUCCESS; @@ -228,7 +228,7 @@ bool usbtmcd_app_initiate_clear(uint8_t rhport, uint8_t *tmcResult) return true; } -bool usbtmcd_app_check_clear(uint8_t rhport, usbtmc_get_clear_status_rsp_t *rsp) +bool tud_usbtmc_app_check_clear_cb(uint8_t rhport, usbtmc_get_clear_status_rsp_t *rsp) { (void)rhport; queryState = 0; @@ -238,45 +238,45 @@ bool usbtmcd_app_check_clear(uint8_t rhport, usbtmc_get_clear_status_rsp_t *rsp) rsp->bmClear.BulkInFifoBytes = 0u; return true; } -bool usbtmcd_app_initiate_abort_bulk_in(uint8_t rhport, uint8_t *tmcResult) +bool tud_usbtmc_app_initiate_abort_bulk_in_cb(uint8_t rhport, uint8_t *tmcResult) { (void)rhport; bulkInStarted = 0; *tmcResult = USBTMC_STATUS_SUCCESS; return true; } -bool usbtmcd_app_check_abort_bulk_in(uint8_t rhport, usbtmc_check_abort_bulk_rsp_t *rsp) +bool tud_usbtmc_app_check_abort_bulk_in_cb(uint8_t rhport, usbtmc_check_abort_bulk_rsp_t *rsp) { (void)rhport; (void)rsp; return true; } -bool usbtmcd_app_initiate_abort_bulk_out(uint8_t rhport, uint8_t *tmcResult) +bool tud_usbtmc_app_initiate_abort_bulk_out_cb(uint8_t rhport, uint8_t *tmcResult) { (void)rhport; *tmcResult = USBTMC_STATUS_SUCCESS; return true; } -bool usbtmcd_app_check_abort_bulk_out(uint8_t rhport, usbtmc_check_abort_bulk_rsp_t *rsp) +bool tud_usbtmc_app_check_abort_bulk_out_cb(uint8_t rhport, usbtmc_check_abort_bulk_rsp_t *rsp) { (void)rhport; (void)rsp; return true; } -void usmtmcd_app_bulkIn_clearFeature(uint8_t rhport) +void usmtmcd_app_bulkIn_clearFeature_cb(uint8_t rhport) { (void)rhport; } -void usmtmcd_app_bulkOut_clearFeature(uint8_t rhport) +void usmtmcd_app_bulkOut_clearFeature_cb(uint8_t rhport) { (void)rhport; } // Return status byte, but put the transfer result status code in the rspResult argument. -uint8_t usbtmcd_app_get_stb(uint8_t rhport, uint8_t *tmcResult) +uint8_t tud_usbtmc_app_get_stb_cb(uint8_t rhport, uint8_t *tmcResult) { (void)rhport; uint8_t old_status = status; @@ -288,7 +288,7 @@ uint8_t usbtmcd_app_get_stb(uint8_t rhport, uint8_t *tmcResult) return old_status; } -bool usbtmcd_app_indicator_pluse(uint8_t rhport, tusb_control_request_t const * msg, uint8_t *tmcResult) +bool tud_usbtmc_app_indicator_pluse_cb(uint8_t rhport, tusb_control_request_t const * msg, uint8_t *tmcResult) { (void)rhport; (void)msg; diff --git a/src/class/usbtmc/usbtmc.h b/src/class/usbtmc/usbtmc.h index 810b523c5..7d7005c2e 100644 --- a/src/class/usbtmc/usbtmc.h +++ b/src/class/usbtmc/usbtmc.h @@ -300,7 +300,7 @@ typedef struct TU_ATTR_PACKED TU_VERIFY_STATIC(sizeof(usbtmc_read_stb_rsp_488_t) == 3u, "struct wrong length"); -typedef struct TU_ATTR_PACKET +typedef struct TU_ATTR_PACKED { struct TU_ATTR_PACKED { diff --git a/src/class/usbtmc/usbtmc_device.c b/src/class/usbtmc/usbtmc_device.c index d4a6a0db0..d550a716f 100644 --- a/src/class/usbtmc/usbtmc_device.c +++ b/src/class/usbtmc/usbtmc_device.c @@ -174,7 +174,7 @@ bool usbtmcd_transmit_dev_msg_data( TU_ASSERT(len <= usbtmc_state.transfer_size_remaining); if(usingTermChar) { - TU_ASSERT(usbtmcd_app_capabilities.bmDevCapabilities.canEndBulkInOnTermChar); + TU_ASSERT(tud_usbtmc_app_capabilities.bmDevCapabilities.canEndBulkInOnTermChar); TU_ASSERT(termCharRequested); TU_ASSERT(((uint8_t*)data)[len-1] == termChar); } @@ -224,31 +224,31 @@ bool usbtmcd_transmit_dev_msg_data( return true; } -void usbtmcd_init(void) +void usbtmcd_init_cb(void) { #ifndef NDEBUG # if CFG_USBTMC_CFG_ENABLE_488 - if(usbtmcd_app_capabilities.bmIntfcCapabilities488.supportsTrigger) - TU_ASSERT(&usbtmcd_app_msg_trigger != NULL,); + if(tud_usbtmc_app_capabilities.bmIntfcCapabilities488.supportsTrigger) + TU_ASSERT(&tud_usbtmc_app_msg_trigger_cb != NULL,); // Per USB488 spec: table 8 - TU_ASSERT(!usbtmcd_app_capabilities.bmIntfcCapabilities.listenOnly,); - TU_ASSERT(!usbtmcd_app_capabilities.bmIntfcCapabilities.talkOnly,); + TU_ASSERT(!tud_usbtmc_app_capabilities.bmIntfcCapabilities.listenOnly,); + TU_ASSERT(!tud_usbtmc_app_capabilities.bmIntfcCapabilities.talkOnly,); # endif - if(usbtmcd_app_capabilities.bmIntfcCapabilities.supportsIndicatorPulse) - TU_ASSERT(&usbtmcd_app_indicator_pluse != NULL,); + if(tud_usbtmc_app_capabilities.bmIntfcCapabilities.supportsIndicatorPulse) + TU_ASSERT(&tud_usbtmc_app_indicator_pluse_cb != NULL,); #endif usbtmcLock = osal_mutex_create(&usbtmcLockBuffer); } -bool usbtmcd_open(uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint16_t *p_length) +bool usbtmcd_open_cb(uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint16_t *p_length) { (void)rhport; uint8_t const * p_desc; uint8_t found_endpoints = 0; - usbtmcd_reset(rhport); + usbtmcd_reset_cb(rhport); // Perhaps there are other application specific class drivers, so don't assert here. if( itf_desc->bInterfaceClass != TUD_USBTMC_APP_CLASS) @@ -311,8 +311,8 @@ bool usbtmcd_open(uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint16 TU_ASSERT(usbtmc_state.ep_int_in != 0); } #if (USBTMC_CFG_ENABLE_488) - if(usbtmcd_app_capabilities.bmIntfcCapabilities488.is488_2 || - usbtmcd_app_capabilities.bmDevCapabilities488.SR1) + if(tud_usbtmc_app_capabilities.bmIntfcCapabilities488.is488_2 || + tud_usbtmc_app_capabilities.bmDevCapabilities488.SR1) { TU_ASSERT(usbtmc_state.ep_int_in != 0); } @@ -322,7 +322,7 @@ bool usbtmcd_open(uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint16 return true; } -void usbtmcd_reset(uint8_t rhport) +void usbtmcd_reset_cb(uint8_t rhport) { // FIXME: Do endpoints need to be closed here? usbtmc_state.state = STATE_IDLE; @@ -343,7 +343,7 @@ static bool handle_devMsgOutStart(uint8_t rhport, void *data, size_t len) // must be a header, should have been confirmed before calling here. usbtmc_msg_request_dev_dep_out *msg = (usbtmc_msg_request_dev_dep_out*)data; usbtmc_state.transfer_size_remaining = msg->TransferSize; - TU_VERIFY(usbtmcd_app_msgBulkOut_start(rhport,msg)); + TU_VERIFY(tud_usbtmc_app_msgBulkOut_start_cb(rhport,msg)); TU_VERIFY(handle_devMsgOut(rhport, (uint8_t*)data + sizeof(*msg), len - sizeof(*msg), len)); return true; @@ -360,7 +360,7 @@ static bool handle_devMsgOut(uint8_t rhport, void *data, size_t len, size_t pack atEnd = true; if(len > usbtmc_state.transfer_size_remaining) len = usbtmc_state.transfer_size_remaining; - usbtmcd_app_msg_data(rhport,data, len, atEnd); + tud_usbtmc_app_msg_data_cb(rhport,data, len, atEnd); usbtmc_state.transfer_size_remaining -= len; usbtmc_state.transfer_size_sent += len; @@ -394,9 +394,9 @@ static bool handle_devMsgIn(uint8_t rhport, void *data, size_t len) termChar = msg->TermChar; if(termCharRequested) - TU_VERIFY(usbtmcd_app_capabilities.bmDevCapabilities.canEndBulkInOnTermChar); + TU_VERIFY(tud_usbtmc_app_capabilities.bmDevCapabilities.canEndBulkInOnTermChar); - TU_VERIFY(usbtmcd_app_msgBulkIn_request(rhport, msg)); + TU_VERIFY(tud_usbtmc_app_msgBulkIn_request_cb(rhport, msg)); return true; } @@ -435,8 +435,8 @@ bool usbtmcd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint #if (CFG_USBTMC_CFG_ENABLE_488) case USBTMC_MSGID_USB488_TRIGGER: // Spec says we halt the EP if we didn't declare we support it. - TU_VERIFY(usbtmcd_app_capabilities.bmIntfcCapabilities488.supportsTrigger); - TU_VERIFY(usbtmcd_app_msg_trigger(rhport, msg)); + TU_VERIFY(tud_usbtmc_app_capabilities.bmIntfcCapabilities488.supportsTrigger); + TU_VERIFY(tud_usbtmc_app_msg_trigger_cb(rhport, msg)); break; #endif @@ -474,7 +474,7 @@ bool usbtmcd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint case STATE_TX_SHORTED: usbtmc_state.state = STATE_IDLE; - TU_VERIFY(usbtmcd_app_msgBulkIn_complete(rhport)); + TU_VERIFY(tud_usbtmc_app_msgBulkIn_complete_cb(rhport)); break; case STATE_TX_INITIATED: @@ -522,7 +522,7 @@ bool usbtmcd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint return false; } -bool usbtmcd_control_request(uint8_t rhport, tusb_control_request_t const * request) { +bool usbtmcd_control_request_cb(uint8_t rhport, tusb_control_request_t const * request) { uint8_t tmcStatusCode = USBTMC_STATUS_FAILED; #if (CFG_USBTMC_CFG_ENABLE_488) @@ -536,11 +536,11 @@ bool usbtmcd_control_request(uint8_t rhport, tusb_control_request_t const * requ { if((request->wIndex) == usbtmc_state.ep_bulk_out) { - usmtmcd_app_bulkOut_clearFeature(rhport); + usmtmcd_app_bulkOut_clearFeature_cb(rhport); } else if ((request->wIndex) == usbtmc_state.ep_bulk_in) { - usmtmcd_app_bulkIn_clearFeature(rhport); + usmtmcd_app_bulkIn_clearFeature_cb(rhport); } return false; // We want USBD core to handle sending the status response, and clear the stall condition } @@ -580,7 +580,7 @@ bool usbtmcd_control_request(uint8_t rhport, tusb_control_request_t const * requ rsp.USBTMC_status = USBTMC_STATUS_SUCCESS; // Check if we've queued a short packet usbtmc_state.state = STATE_ABORTING_BULK_OUT; - TU_VERIFY(usbtmcd_app_initiate_abort_bulk_out(rhport, &(rsp.USBTMC_status))); + TU_VERIFY(tud_usbtmc_app_initiate_abort_bulk_out_cb(rhport, &(rsp.USBTMC_status))); usbd_edpt_stall(rhport, usbtmc_state.ep_bulk_out); } TU_VERIFY(tud_control_xfer(rhport, request, (void*)&rsp,sizeof(rsp))); @@ -595,7 +595,7 @@ bool usbtmcd_control_request(uint8_t rhport, tusb_control_request_t const * requ TU_VERIFY(request->bmRequestType == 0xA2); // in,class,EP TU_VERIFY(request->wLength == sizeof(rsp)); TU_VERIFY(request->wIndex == usbtmc_state.ep_bulk_out); - TU_VERIFY(usbtmcd_app_check_abort_bulk_out(rhport, &rsp)); + TU_VERIFY(tud_usbtmc_app_check_abort_bulk_out_cb(rhport, &rsp)); TU_VERIFY(usbd_edpt_xfer(rhport, 0u, (void*)&rsp,sizeof(rsp))); return true; } @@ -623,7 +623,7 @@ bool usbtmcd_control_request(uint8_t rhport, tusb_control_request_t const * requ TU_VERIFY( usbd_edpt_xfer(rhport, usbtmc_state.ep_bulk_in, usbtmc_state.ep_bulk_in_buf,(uint16_t)0u)); usbtmc_state.state = STATE_ABORTING_BULK_IN_SHORTED; } - TU_VERIFY(usbtmcd_app_initiate_abort_bulk_in(rhport, &(rsp.USBTMC_status))); + TU_VERIFY(tud_usbtmc_app_initiate_abort_bulk_in_cb(rhport, &(rsp.USBTMC_status))); } else if((usbtmc_state.state == STATE_TX_REQUESTED || usbtmc_state.state == STATE_TX_INITIATED)) { // FIXME: Unsure how to check if the OUT endpoint fifo is non-empty.... @@ -651,7 +651,7 @@ bool usbtmcd_control_request(uint8_t rhport, tusb_control_request_t const * requ }, .NBYTES_RXD_TXD = usbtmc_state.transfer_size_sent, }; - TU_VERIFY(usbtmcd_app_check_abort_bulk_in(rhport, &rsp)); + TU_VERIFY(tud_usbtmc_app_check_abort_bulk_in_cb(rhport, &rsp)); switch(usbtmc_state.state) { case STATE_ABORTING_BULK_IN_ABORTED: @@ -679,7 +679,7 @@ bool usbtmcd_control_request(uint8_t rhport, tusb_control_request_t const * requ usbd_edpt_stall(rhport, usbtmc_state.ep_bulk_out); usbtmc_state.transfer_size_remaining = 0; usbtmc_state.state = STATE_CLEARING; - TU_VERIFY(usbtmcd_app_initiate_clear(rhport, &tmcStatusCode)); + TU_VERIFY(tud_usbtmc_app_initiate_clear_cb(rhport, &tmcStatusCode)); TU_VERIFY(tud_control_xfer(rhport, request, (void*)&tmcStatusCode,sizeof(tmcStatusCode))); return true; } @@ -699,7 +699,7 @@ bool usbtmcd_control_request(uint8_t rhport, tusb_control_request_t const * requ else { // Let app check if it's clear - TU_VERIFY(usbtmcd_app_check_clear(rhport, &clearStatusRsp)); + TU_VERIFY(tud_usbtmc_app_check_clear_cb(rhport, &clearStatusRsp)); } if(clearStatusRsp.USBTMC_status == USBTMC_STATUS_SUCCESS) usbtmc_state.state = STATE_IDLE; @@ -710,8 +710,8 @@ bool usbtmcd_control_request(uint8_t rhport, tusb_control_request_t const * requ case USBTMC_bREQUEST_GET_CAPABILITIES: { TU_VERIFY(request->bmRequestType == 0xA1); // in,class,interface - TU_VERIFY(request->wLength == sizeof(usbtmcd_app_capabilities)); - TU_VERIFY(tud_control_xfer(rhport, request, (void*)&usbtmcd_app_capabilities, sizeof(usbtmcd_app_capabilities))); + TU_VERIFY(request->wLength == sizeof(tud_usbtmc_app_capabilities)); + TU_VERIFY(tud_control_xfer(rhport, request, (void*)&tud_usbtmc_app_capabilities, sizeof(tud_usbtmc_app_capabilities))); return true; } // USBTMC Optional Requests @@ -720,8 +720,8 @@ bool usbtmcd_control_request(uint8_t rhport, tusb_control_request_t const * requ { TU_VERIFY(request->bmRequestType == 0xA1); // in,class,interface TU_VERIFY(request->wLength == sizeof(tmcStatusCode)); - TU_VERIFY(usbtmcd_app_capabilities.bmIntfcCapabilities.supportsIndicatorPulse); - TU_VERIFY(usbtmcd_app_indicator_pluse(rhport, request, &tmcStatusCode)); + TU_VERIFY(tud_usbtmc_app_capabilities.bmIntfcCapabilities.supportsIndicatorPulse); + TU_VERIFY(tud_usbtmc_app_indicator_pluse_cb(rhport, request, &tmcStatusCode)); TU_VERIFY(tud_control_xfer(rhport, request, (void*)&tmcStatusCode, sizeof(tmcStatusCode))); return true; } @@ -752,13 +752,13 @@ bool usbtmcd_control_request(uint8_t rhport, tusb_control_request_t const * requ .one = 1, .bTag = bTag & 0x7Fu, }, - .StatusByte = usbtmcd_app_get_stb(rhport, &(rsp.USBTMC_status)) + .StatusByte = tud_usbtmc_app_get_stb_cb(rhport, &(rsp.USBTMC_status)) }; usbd_edpt_xfer(rhport, usbtmc_state.ep_int_in, (void*)&intMsg,sizeof(intMsg)); } else { - rsp.statusByte = usbtmcd_app_get_stb(rhport, &(rsp.USBTMC_status)); + rsp.statusByte = tud_usbtmc_app_get_stb_cb(rhport, &(rsp.USBTMC_status)); } TU_VERIFY(tud_control_xfer(rhport, request, (void*)&rsp, sizeof(rsp))); return true; @@ -781,7 +781,7 @@ bool usbtmcd_control_request(uint8_t rhport, tusb_control_request_t const * requ TU_VERIFY(false); } -bool usbtmcd_control_complete(uint8_t rhport, tusb_control_request_t const * request) +bool usbtmcd_control_complete_cb(uint8_t rhport, tusb_control_request_t const * request) { (void)rhport; //------------- Class Specific Request -------------// diff --git a/src/class/usbtmc/usbtmc_device.h b/src/class/usbtmc/usbtmc_device.h index 3c8d10572..5c6ee2a8d 100644 --- a/src/class/usbtmc/usbtmc_device.h +++ b/src/class/usbtmc/usbtmc_device.h @@ -50,35 +50,35 @@ */ #if (CFG_USBTMC_CFG_ENABLE_488) -extern usbtmc_response_capabilities_488_t const usbtmcd_app_capabilities; +extern usbtmc_response_capabilities_488_t const tud_usbtmc_app_capabilities; #else -extern usbtmc_response_capabilities_t const usbtmcd_app_capabilities; +extern usbtmc_response_capabilities_t const tud_usbtmc_app_capabilities; #endif -bool usbtmcd_app_msgBulkOut_start(uint8_t rhport, usbtmc_msg_request_dev_dep_out const * msgHeader); +bool tud_usbtmc_app_msgBulkOut_start_cb(uint8_t rhport, usbtmc_msg_request_dev_dep_out const * msgHeader); // transfer_complete does not imply that a message is complete. -bool usbtmcd_app_msg_data(uint8_t rhport, void *data, size_t len, bool transfer_complete); -void usmtmcd_app_bulkOut_clearFeature(uint8_t rhport); // Notice to clear and abort the pending BULK out transfer +bool tud_usbtmc_app_msg_data_cb(uint8_t rhport, void *data, size_t len, bool transfer_complete); +void usmtmcd_app_bulkOut_clearFeature_cb(uint8_t rhport); // Notice to clear and abort the pending BULK out transfer -bool usbtmcd_app_msgBulkIn_request(uint8_t rhport, usbtmc_msg_request_dev_dep_in const * request); -bool usbtmcd_app_msgBulkIn_complete(uint8_t rhport); -void usmtmcd_app_bulkIn_clearFeature(uint8_t rhport); // Notice to clear and abort the pending BULK out transfer +bool tud_usbtmc_app_msgBulkIn_request_cb(uint8_t rhport, usbtmc_msg_request_dev_dep_in const * request); +bool tud_usbtmc_app_msgBulkIn_complete_cb(uint8_t rhport); +void usmtmcd_app_bulkIn_clearFeature_cb(uint8_t rhport); // Notice to clear and abort the pending BULK out transfer -bool usbtmcd_app_initiate_abort_bulk_in(uint8_t rhport, uint8_t *tmcResult); -bool usbtmcd_app_initiate_abort_bulk_out(uint8_t rhport, uint8_t *tmcResult); -bool usbtmcd_app_initiate_clear(uint8_t rhport, uint8_t *tmcResult); +bool tud_usbtmc_app_initiate_abort_bulk_in_cb(uint8_t rhport, uint8_t *tmcResult); +bool tud_usbtmc_app_initiate_abort_bulk_out_cb(uint8_t rhport, uint8_t *tmcResult); +bool tud_usbtmc_app_initiate_clear_cb(uint8_t rhport, uint8_t *tmcResult); -bool usbtmcd_app_check_abort_bulk_in(uint8_t rhport, usbtmc_check_abort_bulk_rsp_t *rsp); -bool usbtmcd_app_check_abort_bulk_out(uint8_t rhport, usbtmc_check_abort_bulk_rsp_t *rsp); -bool usbtmcd_app_check_clear(uint8_t rhport, usbtmc_get_clear_status_rsp_t *rsp); +bool tud_usbtmc_app_check_abort_bulk_in_cb(uint8_t rhport, usbtmc_check_abort_bulk_rsp_t *rsp); +bool tud_usbtmc_app_check_abort_bulk_out_cb(uint8_t rhport, usbtmc_check_abort_bulk_rsp_t *rsp); +bool tud_usbtmc_app_check_clear_cb(uint8_t rhport, usbtmc_get_clear_status_rsp_t *rsp); // Indicator pulse should be 0.5 to 1.0 seconds long -TU_ATTR_WEAK bool usbtmcd_app_indicator_pluse(uint8_t rhport, tusb_control_request_t const * msg, uint8_t *tmcResult); +TU_ATTR_WEAK bool tud_usbtmc_app_indicator_pluse_cb(uint8_t rhport, tusb_control_request_t const * msg, uint8_t *tmcResult); #if (CFG_USBTMC_CFG_ENABLE_488) -uint8_t usbtmcd_app_get_stb(uint8_t rhport, uint8_t *tmcResult); -TU_ATTR_WEAK bool usbtmcd_app_msg_trigger(uint8_t rhport, usbtmc_msg_generic_t* msg); -//TU_ATTR_WEAK bool usbtmcd_app_go_to_local(uint8_t rhport); +uint8_t tud_usbtmc_app_get_stb_cb(uint8_t rhport, uint8_t *tmcResult); +TU_ATTR_WEAK bool tud_usbtmc_app_msg_trigger_cb(uint8_t rhport, usbtmc_msg_generic_t* msg); +//TU_ATTR_WEAK bool tud_usbtmc_app_go_to_local_cb(uint8_t rhport); #endif /******************************************* @@ -96,12 +96,12 @@ bool usbtmcd_transmit_dev_msg_data( /* "callbacks" from USB device core */ -bool usbtmcd_open(uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint16_t *p_length); -void usbtmcd_reset(uint8_t rhport); +bool usbtmcd_open_cb(uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint16_t *p_length); +void usbtmcd_reset_cb(uint8_t rhport); bool usbtmcd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes); -bool usbtmcd_control_request(uint8_t rhport, tusb_control_request_t const * request); -bool usbtmcd_control_complete(uint8_t rhport, tusb_control_request_t const * request); -void usbtmcd_init(void); +bool usbtmcd_control_request_cb(uint8_t rhport, tusb_control_request_t const * request); +bool usbtmcd_control_complete_cb(uint8_t rhport, tusb_control_request_t const * request); +void usbtmcd_init_cb(void); /************************************************************ * USBTMC Descriptor Templates diff --git a/src/device/usbd.c b/src/device/usbd.c index f8f1da82e..8125d0093 100644 --- a/src/device/usbd.c +++ b/src/device/usbd.c @@ -153,11 +153,11 @@ static usbd_class_driver_t const usbd_class_drivers[] = { .class_code = TUD_USBTMC_APP_CLASS, //.subclass_code = TUD_USBTMC_APP_SUBCLASS - .init = usbtmcd_init, - .reset = usbtmcd_reset, - .open = usbtmcd_open, - .control_request = usbtmcd_control_request, - .control_complete = usbtmcd_control_complete, + .init = usbtmcd_init_cb, + .reset = usbtmcd_reset_cb, + .open = usbtmcd_open_cb, + .control_request = usbtmcd_control_request_cb, + .control_complete = usbtmcd_control_complete_cb, .xfer_cb = usbtmcd_xfer_cb, .sof = NULL }, -- cgit v1.3.1 From 05164c5a27eaad25f28a4fc8926297d6cd32e3fc Mon Sep 17 00:00:00 2001 From: Nathan Conrad Date: Thu, 19 Sep 2019 21:04:51 -0400 Subject: Cache pointer to HID descriptor. --- src/class/hid/hid_device.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/class/hid/hid_device.c b/src/class/hid/hid_device.c index 2d579f475..7dabdbc17 100644 --- a/src/class/hid/hid_device.c +++ b/src/class/hid/hid_device.c @@ -46,12 +46,13 @@ typedef struct uint8_t boot_protocol; // Boot mouse or keyboard bool boot_mode; // default = false (Report) uint8_t idle_rate; // up to application to handle idle rate - uint16_t reprot_desc_len; + uint16_t report_desc_len; CFG_TUSB_MEM_ALIGN uint8_t epin_buf[CFG_TUD_HID_BUFSIZE]; CFG_TUSB_MEM_ALIGN uint8_t epout_buf[CFG_TUD_HID_BUFSIZE]; -}hidd_interface_t; + tusb_hid_descriptor_hid_t const * hid_descriptor; +} hidd_interface_t; CFG_TUSB_MEM_SECTION static hidd_interface_t _hidd_itf[CFG_TUD_HID]; @@ -167,8 +168,8 @@ bool hidd_open(uint8_t rhport, tusb_desc_interface_t const * desc_itf, uint16_t //------------- 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); + p_hid->hid_descriptor = (tusb_hid_descriptor_hid_t const *) p_desc; + TU_ASSERT(HID_DESC_TYPE_HID == p_hid->hid_descriptor->bDescriptorType); //------------- Endpoint Descriptor -------------// p_desc = tu_desc_next(p_desc); @@ -178,7 +179,7 @@ bool hidd_open(uint8_t rhport, tusb_desc_interface_t const * desc_itf, uint16_t p_hid->boot_mode = false; // default mode is REPORT p_hid->itf_num = desc_itf->bInterfaceNumber; - memcpy(&p_hid->reprot_desc_len, &desc_hid->wReportLength, 2); + memcpy(&p_hid->report_desc_len, &(p_hid->hid_descriptor->wReportLength), 2); *p_len = sizeof(tusb_desc_interface_t) + sizeof(tusb_hid_descriptor_hid_t) + desc_itf->bNumEndpoints*sizeof(tusb_desc_endpoint_t); @@ -205,6 +206,7 @@ bool hidd_control_request(uint8_t rhport, tusb_control_request_t const * p_reque if (p_request->bRequest == TUSB_REQ_GET_DESCRIPTOR && desc_type == HID_DESC_TYPE_HID) { // FIXME: Should check which is the active configuration, but no callback in usbd currently exists to do that + TU_VERIFY(p_hid->hid_descriptor != NULL); tusb_desc_configuration_t const* desc_cfg = (tusb_desc_configuration_t const*) tud_descriptor_configuration_cb(0); uint8_t const * p_desc = ((uint8_t const*) desc_cfg) + sizeof(tusb_desc_configuration_t); @@ -227,7 +229,7 @@ bool hidd_control_request(uint8_t rhport, tusb_control_request_t const * p_reque else if (p_request->bRequest == TUSB_REQ_GET_DESCRIPTOR && desc_type == HID_DESC_TYPE_REPORT) { uint8_t const * desc_report = tud_hid_descriptor_report_cb(); - tud_control_xfer(rhport, p_request, (void*) desc_report, p_hid->reprot_desc_len); + tud_control_xfer(rhport, p_request, (void*) desc_report, p_hid->report_desc_len); }else { return false; // stall unsupported request @@ -273,7 +275,7 @@ bool hidd_control_request(uint8_t rhport, tusb_control_request_t const * p_reque case HID_REQ_CONTROL_GET_PROTOCOL: { - uint8_t protocol = 1-p_hid->boot_mode; // 0 is Boot, 1 is Report protocol + uint8_t protocol = (uint8_t)(1-p_hid->boot_mode); // 0 is Boot, 1 is Report protocol tud_control_xfer(rhport, p_request, &protocol, 1); } break; -- cgit v1.3.1 From 02b468f56a883ee81d1f635f0548cf43ce454c0d Mon Sep 17 00:00:00 2001 From: Nathan Conrad Date: Thu, 19 Sep 2019 21:20:04 -0400 Subject: (little typo fix) --- 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 d550a716f..fcd3376f3 100644 --- a/src/class/usbtmc/usbtmc_device.c +++ b/src/class/usbtmc/usbtmc_device.c @@ -310,7 +310,7 @@ bool usbtmcd_open_cb(uint8_t rhport, tusb_desc_interface_t const * itf_desc, uin { TU_ASSERT(usbtmc_state.ep_int_in != 0); } -#if (USBTMC_CFG_ENABLE_488) +#if (CFG_USBTMC_CFG_ENABLE_488) if(tud_usbtmc_app_capabilities.bmIntfcCapabilities488.is488_2 || tud_usbtmc_app_capabilities.bmDevCapabilities488.SR1) { -- cgit v1.3.1 From 7b2f8cc73a758eefc2a308813d0081f08ddfeb2b Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 20 Sep 2019 13:49:33 +0700 Subject: added stm32 L0 support close #125 --- examples/device/board_test/Makefile | 3 - examples/make.mk | 1 + hw/bsp/stm32l0538disco/board.mk | 2 +- src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c | 38 ++++++----- .../st/stm32_fsdev/dcd_stm32_fsdev_pvt_st.h | 79 ++++++++++++---------- 5 files changed, 64 insertions(+), 59 deletions(-) (limited to 'src') diff --git a/examples/device/board_test/Makefile b/examples/device/board_test/Makefile index e0c6d6ce2..5a455078e 100644 --- a/examples/device/board_test/Makefile +++ b/examples/device/board_test/Makefile @@ -5,9 +5,6 @@ INC += \ src \ $(TOP)/hw \ -# stop on the first build error, which is quite a lot of porting new board -CFLAGS += -Wfatal-errors - # Example source EXAMPLE_SOURCE += $(wildcard src/*.c) SRC_C += $(addprefix $(CURRENT_PATH)/, $(EXAMPLE_SOURCE)) diff --git a/examples/make.mk b/examples/make.mk index b0aa5659e..f35195fde 100644 --- a/examples/make.mk +++ b/examples/make.mk @@ -58,6 +58,7 @@ CFLAGS += \ -Wall \ -Werror \ -Werror-implicit-function-declaration \ + -Wfatal-errors \ -Wfloat-equal \ -Wundef \ -Wshadow \ diff --git a/hw/bsp/stm32l0538disco/board.mk b/hw/bsp/stm32l0538disco/board.mk index f4088ba77..3b84159d1 100644 --- a/hw/bsp/stm32l0538disco/board.mk +++ b/hw/bsp/stm32l0538disco/board.mk @@ -6,9 +6,9 @@ CFLAGS += \ -mcpu=cortex-m0plus \ -mfloat-abi=soft \ -nostdlib -nostartfiles \ + -DCFG_EXAMPLE_MSC_READONLY \ -DCFG_TUSB_MCU=OPT_MCU_STM32L0 -# -DCFG_EXAMPLE_MSC_READONLY \ ST_HAL_DRIVER = hw/mcu/st/st_driver/STM32L0xx_HAL_Driver ST_CMSIS = hw/mcu/st/st_driver/CMSIS/Device/ST/STM32L0xx diff --git a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c index aec8ea0c7..d83098fd9 100644 --- a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c +++ b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c @@ -106,14 +106,17 @@ #include "tusb_option.h" +#define STM32F1_FSDEV ( \ + defined(STM32F102x6) || defined(STM32F102xB) || \ + defined(STM32F103x6) || defined(STM32F103xB) || \ + defined(STM32F103xE) || defined(STM32F103xG) \ +) + #if (TUSB_OPT_DEVICE_ENABLED) && ( \ - ((CFG_TUSB_MCU) == OPT_MCU_STM32F0) || \ - (((CFG_TUSB_MCU) == OPT_MCU_STM32F1) && ( \ - defined(stm32f102x6) || defined(stm32f102xb) || \ - defined(stm32f103x6) || defined(stm32f103xb) || \ - defined(stm32f103xe) || defined(stm32f103xg) \ - )) || \ - ((CFG_TUSB_MCU) == OPT_MCU_STM32F3) \ + (CFG_TUSB_MCU == OPT_MCU_STM32F0 ) || \ + (CFG_TUSB_MCU == OPT_MCU_STM32F1 && STM32F1_FSDEV ) || \ + (CFG_TUSB_MCU == OPT_MCU_STM32F3 ) || \ + (CFG_TUSB_MCU == OPT_MCU_STM32L0 ) \ ) // In order to reduce the dependance on HAL, we undefine this. @@ -165,7 +168,7 @@ typedef struct static xfer_ctl_t xfer_status[MAX_EP_COUNT][2]; -static xfer_ctl_t* xfer_ctl_ptr(uint32_t epnum, uint32_t dir) +static inline xfer_ctl_t* xfer_ctl_ptr(uint32_t epnum, uint32_t dir) { return &xfer_status[epnum][dir]; } @@ -252,9 +255,10 @@ void dcd_init (uint8_t rhport) void dcd_int_enable (uint8_t rhport) { (void)rhport; -#if defined(STM32F0) + +#if CFG_TUSB_MCU == OPT_MCU_STM32F0 || CFG_TUSB_MCU == OPT_MCU_STM32L0 NVIC_EnableIRQ(USB_IRQn); -#elif defined(STM32F3) +#elif CFG_TUSB_MCU == OPT_MCU_STM32F3 NVIC_EnableIRQ(USB_HP_CAN_TX_IRQn); NVIC_EnableIRQ(USB_LP_CAN_RX0_IRQn); NVIC_EnableIRQ(USBWakeUp_IRQn); @@ -265,14 +269,15 @@ void dcd_int_enable (uint8_t rhport) void dcd_int_disable(uint8_t rhport) { (void)rhport; -#if defined(STM32F0) + +#if CFG_TUSB_MCU == OPT_MCU_STM32F0 || CFG_TUSB_MCU == OPT_MCU_STM32L0 NVIC_DisableIRQ(USB_IRQn); -#elif defined(STM32F3) +#elif CFG_TUSB_MCU == OPT_MCU_STM32F3 NVIC_DisableIRQ(USB_HP_CAN_TX_IRQn); NVIC_DisableIRQ(USB_LP_CAN_RX0_IRQn); NVIC_DisableIRQ(USBWakeUp_IRQn); #else -#error Unknown arch in USB driver + #error Unknown arch in USB driver #endif // I'm not convinced that memory synchronization is completely necessary, but // it isn't a bad idea. @@ -305,7 +310,7 @@ void dcd_remote_wakeup(uint8_t rhport) { (void) rhport; - USB->CNTR |= (uint16_t)USB_CNTR_RESUME; + USB->CNTR |= (uint16_t) USB_CNTR_RESUME; remoteWakeCountdown = 4u; // required to be 1 to 15 ms, ESOF should trigger every 1ms. } @@ -448,14 +453,11 @@ static uint16_t dcd_ep_ctr_handler(void) { pcd_set_ep_rx_status(USB, EPindex, USB_EP_RX_VALID);// Await next SETUP } - } - } } else /* Decode and service non control endpoints interrupt */ { - /* process related endpoint register */ wEPVal = pcd_get_endpoint(USB, EPindex); if ((wEPVal & USB_EP_CTR_RX) != 0U) // OUT @@ -809,7 +811,7 @@ static bool dcd_read_packet_memory(void *__restrict dst, uint16_t src, size_t wN // Interrupt handlers -#if (CFG_TUSB_MCU) == (OPT_MCU_STM32F0) +#if CFG_TUSB_MCU == OPT_MCU_STM32F0 || CFG_TUSB_MCU == OPT_MCU_STM32L0 void USB_IRQHandler(void) { dcd_fs_irqHandler(); diff --git a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev_pvt_st.h b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev_pvt_st.h index ff25df048..30538541a 100644 --- a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev_pvt_st.h +++ b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev_pvt_st.h @@ -41,51 +41,56 @@ #ifndef PORTABLE_ST_STM32F0_DCD_STM32F0_FSDEV_PVT_ST_H_ #define PORTABLE_ST_STM32F0_DCD_STM32F0_FSDEV_PVT_ST_H_ -#if defined(STM32F042x6) | \ - defined(STM32F070x6) | defined(STM32F070xB) | \ - defined(STM32F072xB) | \ +#if defined(STM32F042x6) || \ + defined(STM32F070x6) || defined(STM32F070xB) || \ + defined(STM32F072xB) || \ defined(STM32F078xx) -#include "stm32f0xx.h" -#define PMA_LENGTH (1024u) -// F0x2 models are crystal-less -// All have internal D+ pull-up -// 070RB: 2 x 16 bits/word memory LPM Support, BCD Support -// PMA dedicated to USB (no sharing with CAN) -#elif defined(STM32F102x6) | defined(STM32F102x6) | \ - defined(STM32F103x6) | defined(STM32F103xB) | \ - defined(STM32F103xE) | defined(STM32F103xB) -#include "stm32f1xx.h" -#define PMA_LENGTH (512u) -// NO internal Pull-ups -// *B, and *C: 2 x 16 bits/word -#error The F102/F103 driver is expected not to work, but it might? Try it? - -#elif defined(STM32F302xB) | defined(STM32F302xC) | \ - defined(STM32F303xB) | defined(STM32F303xC) | \ + #include "stm32f0xx.h" + #define PMA_LENGTH (1024u) + // F0x2 models are crystal-less + // All have internal D+ pull-up + // 070RB: 2 x 16 bits/word memory LPM Support, BCD Support + // PMA dedicated to USB (no sharing with CAN) + +#elif STM32F1_FSDEV + #include "stm32f1xx.h" + #define PMA_LENGTH (512u) + // NO internal Pull-ups + // *B, and *C: 2 x 16 bits/word + #error The F102/F103 driver is expected not to work, but it might? Try it? + +#elif defined(STM32F302xB) || defined(STM32F302xC) || \ + defined(STM32F303xB) || defined(STM32F303xC) || \ defined(STM32F373xC) -#include "stm32f3xx.h" -#define PMA_LENGTH (512u) -// NO internal Pull-ups -// *B, and *C: 1 x 16 bits/word -// PMA dedicated to USB (no sharing with CAN) -#elif defined(STM32F302x6) | defined(STM32F302x8) | \ - defined(STM32F302xD) | defined(STM32F302xE) | \ - defined(STM32F303xD) | defined(STM32F303xE) | \ -#include "stm32f3xx.h" -#define PMA_LENGTH (1024u) -// NO internal Pull-ups -// *6, *8, *D, and *E: 2 x 16 bits/word LPM Support -// When CAN clock is enabled, USB can use first 768 bytes ONLY. + #include "stm32f3xx.h" + #define PMA_LENGTH (512u) + // NO internal Pull-ups + // *B, and *C: 1 x 16 bits/word + // PMA dedicated to USB (no sharing with CAN) + +#elif defined(STM32F302x6) || defined(STM32F302x8) || \ + defined(STM32F302xD) || defined(STM32F302xE) || \ + defined(STM32F303xD) || defined(STM32F303xE) + #include "stm32f3xx.h" + #define PMA_LENGTH (1024u) + // NO internal Pull-ups + // *6, *8, *D, and *E: 2 x 16 bits/word LPM Support + // When CAN clock is enabled, USB can use first 768 bytes ONLY. + +#elif CFG_TUSB_MCU == OPT_MCU_STM32L0 + #include "stm32l0xx.h" + #define PMA_LENGTH (1024u) + #else -#error You are using an untested or unimplemented STM32 variant. Please update the driver. -// This includes L0x2, L0x3, L1x0, L1x1, L1x2, L4x2 and L4x3, G1x1, G1x3, and G1x4 + #error You are using an untested or unimplemented STM32 variant. Please update the driver. + // This includes L1x0, L1x1, L1x2, L4x2 and L4x3, G1x1, G1x3, and G1x4 #endif // For purposes of accessing the packet #if ((PMA_LENGTH) == 512u) -#define PMA_STRIDE (2u) + #define PMA_STRIDE (2u) #elif ((PMA_LENGTH) == 1024u) -#define PMA_STRIDE (1u) + #define PMA_STRIDE (1u) #endif // And for type-safety create a new macro for the volatile address of PMAADDR -- cgit v1.3.1 From 94c9cf0eff7973475e4f6d93cc96c2c86b541b08 Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 20 Sep 2019 16:14:35 +0700 Subject: doc update --- README.md | 26 +++++++++++++------------- docs/boards.md | 1 + src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c | 5 +---- 3 files changed, 15 insertions(+), 17 deletions(-) (limited to 'src') diff --git a/README.md b/README.md index 0fbfaec37..a811e3b49 100644 --- a/README.md +++ b/README.md @@ -21,6 +21,17 @@ TinyUSB is an open-source cross-platform USB Host/Device stack for embedded syst └── tools # Files used internally ``` +## Supported MCUs + +The stack supports the following MCUs + +- **Nordic:** nRF52840 +- **NXP:** LPC11Uxx, LPC13xx, LPC175x_6x, LPC177x_8x, LPC18xx, LPC40xx, LPC43xx, LPC51Uxx +- **MicroChip:** SAMD21, SAMD51 (device only) +- **ST:** STM32 series: L0, F0, F2, F3, F4, F7, H7 (device only) + +[Here is the list of supported Boards](docs/boards.md) that can be used with provided examples. + ## Device Stack Support multiple device configurations by dynamically changing usb descriptors. Low power functions such as suspend, resume and remote wakeup. Following device classes are supported: @@ -42,23 +53,12 @@ Support multiple device configurations by dynamically changing usb descriptors. ## OS Abtraction layer -Currently the following OS are supported with tinyusb out of the box with a simple change of **CFG_TUSB_OS** macro. +TinyUSB is completely thread-safe by pushing all ISR events into a central queue, then process it later in the non-ISR context. It also uses semphore/mutex to access shared resource such as CDC fifo. Therefore the stack needs to use some of OS's basic APIs. Following OSes are already supported out of the box. -- **No OS** +- **No OS** : Disabling USB IRQ is used as way to provide mutex - **FreeRTOS** - **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 - -The stack supports the following MCUs - -- **Nordic:** nRF52840 -- **NXP:** LPC11Uxx, LPC13xx, LPC175x_6x, LPC177x_8x, LPC18xx, LPC40xx, LPC43xx, LPC51Uxx -- **MicroChip:** SAMD21, SAMD51 (device only) -- **ST:** STM32F0, STM32F2, STM32F3, STM32F4, STM32F7, STM32H7 (device only) - -[Here is the list of supported Boards](docs/boards.md) - ## Compiler & IDE The stack is developed with GCC compiler, and should be compilable with others. Folder `examples` provide Makefile and Segger Embedded Studio build support. [Here is instruction to build example](examples/readme.md). diff --git a/docs/boards.md b/docs/boards.md index fef682f48..b6b48a7f1 100644 --- a/docs/boards.md +++ b/docs/boards.md @@ -43,6 +43,7 @@ This code base already had supported for a handful of following boards - Adafruit Feather STM32F405 - [Micro Python PyBoard v1.1](https://store.micropython.org/product/PYBv1.1) +- [STM32 L035c8 Discovery](https://www.st.com/en/evaluation-tools/32l0538discovery.html) - [STM32 F070rb Nucleo](https://www.st.com/en/evaluation-tools/nucleo-f070rb.html) - [STM32 F072rb Discovery](https://www.st.com/en/evaluation-tools/32f072bdiscovery.html) - [STM32 F207zg Nucleo](https://www.st.com/en/evaluation-tools/nucleo-f207zg.html) diff --git a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c index d83098fd9..9bd4d2362 100644 --- a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c +++ b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c @@ -30,10 +30,7 @@ /********************************************** * This driver has been tested with the following MCUs: - * - * - * STM32F070RB - * + * - F070, F072, L053 * * It also should work with minimal changes for any ST MCU with an "USB A"/"PCD"/"HCD" peripheral. This * covers: -- cgit v1.3.1 From a8a65d6ceae244971405a13bc493ee923861be1f Mon Sep 17 00:00:00 2001 From: Nathan Conrad Date: Fri, 20 Sep 2019 08:46:17 -0400 Subject: Use cached HID descriptor. --- src/class/hid/hid_device.c | 23 +++-------------------- 1 file changed, 3 insertions(+), 20 deletions(-) (limited to 'src') diff --git a/src/class/hid/hid_device.c b/src/class/hid/hid_device.c index 7dabdbc17..fee44e30c 100644 --- a/src/class/hid/hid_device.c +++ b/src/class/hid/hid_device.c @@ -205,32 +205,15 @@ bool hidd_control_request(uint8_t rhport, tusb_control_request_t const * p_reque if (p_request->bRequest == TUSB_REQ_GET_DESCRIPTOR && desc_type == HID_DESC_TYPE_HID) { - // FIXME: Should check which is the active configuration, but no callback in usbd currently exists to do that TU_VERIFY(p_hid->hid_descriptor != NULL); - tusb_desc_configuration_t const* desc_cfg = - (tusb_desc_configuration_t const*) tud_descriptor_configuration_cb(0); - uint8_t const * p_desc = ((uint8_t const*) desc_cfg) + sizeof(tusb_desc_configuration_t); - uint8_t const * desc_end = ((uint8_t const*) desc_cfg) + desc_cfg->wTotalLength; - - while( p_desc < desc_end ) - { - tusb_hid_descriptor_hid_t *p_desc_hid =(tusb_hid_descriptor_hid_t*)p_desc; - if(p_desc_hid->bDescriptorType == HID_DESC_TYPE_HID) { - tud_control_xfer(rhport, p_request, (void*) p_desc_hid, p_desc_hid->bLength); - break; - } - p_desc += p_desc_hid->bLength; // next desc - } - if(p_desc >= desc_end) - { - return false; - } + TU_VERIFY(tud_control_xfer(rhport, p_request, (void*) p_hid->hid_descriptor, p_hid->hid_descriptor->bLength)); } else if (p_request->bRequest == TUSB_REQ_GET_DESCRIPTOR && desc_type == HID_DESC_TYPE_REPORT) { uint8_t const * desc_report = tud_hid_descriptor_report_cb(); tud_control_xfer(rhport, p_request, (void*) desc_report, p_hid->report_desc_len); - }else + } + else { return false; // stall unsupported request } -- cgit v1.3.1 From f241ff389f9494836cdc45e621726c0b69b8daed Mon Sep 17 00:00:00 2001 From: Nathan Conrad Date: Fri, 20 Sep 2019 08:56:46 -0400 Subject: Also need to just return false in the case that it isn't an interface control event. We shouldn't assert. This normally isn't an error, either, so I don't want to use TU_VERIFY. --- src/class/hid/hid_device.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src') diff --git a/src/class/hid/hid_device.c b/src/class/hid/hid_device.c index fee44e30c..b57d6219f 100644 --- a/src/class/hid/hid_device.c +++ b/src/class/hid/hid_device.c @@ -193,6 +193,10 @@ bool hidd_open(uint8_t rhport, tusb_desc_interface_t const * desc_itf, uint16_t // return false to stall control endpoint (e.g unsupported request) bool hidd_control_request(uint8_t rhport, tusb_control_request_t const * p_request) { + if (p_request->bmRequestType_bit.recipient != TUSB_REQ_RCPT_INTERFACE) + { + return false; + } hidd_interface_t* p_hid = get_interface_by_itfnum( (uint8_t) p_request->wIndex ); TU_ASSERT(p_hid); -- cgit v1.3.1 From 2281a514846402af68aa4c97fcd206611c0969a1 Mon Sep 17 00:00:00 2001 From: Nathan Conrad Date: Fri, 20 Sep 2019 12:27:41 -0400 Subject: Revert "Also need to just return false in the case that it isn't an interface control event. We shouldn't assert. This normally isn't an" This reverts commit f241ff389f9494836cdc45e621726c0b69b8daed. --- src/class/hid/hid_device.c | 4 ---- 1 file changed, 4 deletions(-) (limited to 'src') diff --git a/src/class/hid/hid_device.c b/src/class/hid/hid_device.c index b57d6219f..fee44e30c 100644 --- a/src/class/hid/hid_device.c +++ b/src/class/hid/hid_device.c @@ -193,10 +193,6 @@ bool hidd_open(uint8_t rhport, tusb_desc_interface_t const * desc_itf, uint16_t // return false to stall control endpoint (e.g unsupported request) bool hidd_control_request(uint8_t rhport, tusb_control_request_t const * p_request) { - if (p_request->bmRequestType_bit.recipient != TUSB_REQ_RCPT_INTERFACE) - { - return false; - } hidd_interface_t* p_hid = get_interface_by_itfnum( (uint8_t) p_request->wIndex ); TU_ASSERT(p_hid); -- cgit v1.3.1 From 8a688cd8d0fed2325aaacdfbb5159a04dfe03ac1 Mon Sep 17 00:00:00 2001 From: Nathan Conrad Date: Fri, 20 Sep 2019 12:58:26 -0400 Subject: Revert "Revert "Also need to just return false in the case that it isn't an interface control event. We shouldn't assert. This normally isn't an"" This reverts commit 2281a514846402af68aa4c97fcd206611c0969a1. --- src/class/hid/hid_device.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src') diff --git a/src/class/hid/hid_device.c b/src/class/hid/hid_device.c index fee44e30c..b57d6219f 100644 --- a/src/class/hid/hid_device.c +++ b/src/class/hid/hid_device.c @@ -193,6 +193,10 @@ bool hidd_open(uint8_t rhport, tusb_desc_interface_t const * desc_itf, uint16_t // return false to stall control endpoint (e.g unsupported request) bool hidd_control_request(uint8_t rhport, tusb_control_request_t const * p_request) { + if (p_request->bmRequestType_bit.recipient != TUSB_REQ_RCPT_INTERFACE) + { + return false; + } hidd_interface_t* p_hid = get_interface_by_itfnum( (uint8_t) p_request->wIndex ); TU_ASSERT(p_hid); -- cgit v1.3.1 From ce9f133d258fe173211063b06c87c7c5d1384986 Mon Sep 17 00:00:00 2001 From: Nathan Conrad Date: Sat, 21 Sep 2019 12:00:04 -0400 Subject: FSDEV: go to NAK when unstalling; on reset, set EP0 to NAK, prioritize reset interrupt, fix small typos. --- src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c | 51 +++++++++++++++------------ 1 file changed, 29 insertions(+), 22 deletions(-) (limited to 'src') diff --git a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c index 9bd4d2362..00f5b1239 100644 --- a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c +++ b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c @@ -331,7 +331,9 @@ static const tusb_desc_endpoint_t ep0IN_desc = .bEndpointAddress = 0x80 }; +#if defined(__GNUC__) && (__GNUC__ >= 7) #pragma GCC diagnostic pop +#endif static void dcd_handle_bus_reset(void) { @@ -349,7 +351,6 @@ static void dcd_handle_bus_reset(void) dcd_edpt_open (0, &ep0IN_desc); newDADDR = 0u; USB->DADDR = USB_DADDR_EF; // Set enable flag, and leaving the device address as zero. - pcd_set_ep_rx_status(USB, 0, USB_EP_RX_VALID); // And start accepting SETUP on EP0 } // FIXME: Defined to return uint16 so that ASSERT can be used, even though a return value is not needed. @@ -518,8 +519,22 @@ static uint16_t dcd_ep_ctr_handler(void) static void dcd_fs_irqHandler(void) { - uint16_t int_status = USB->ISTR; - // unused IRQs: (USB_ISTR_PMAOVR | USB_ISTR_ERR | USB_ISTR_WKUP | USB_ISTR_SUSP | USB_ISTR_ESOF | USB_ISTR_L1REQ ) + uint32_t int_status = USB->ISTR; + //const uint32_t handled_ints = USB_ISTR_CTR | USB_ISTR_RESET | USB_ISTR_WKUP + // | USB_ISTR_SUSP | USB_ISTR_SOF | USB_ISTR_ESOF; + // unused IRQs: (USB_ISTR_PMAOVR | USB_ISTR_ERR | USB_ISTR_L1REQ ) + + // The ST driver loops here on the CTR bit, but that loop has been moved into the + // dcd_ep_ctr_handler(), so less need to loop here. The other interrupts shouldn't + // be triggered repeatedly. + + if(int_status & USB_ISTR_RESET) { + // USBRST is start of reset. + reg16_clear_bits(&USB->ISTR, USB_ISTR_RESET); + dcd_handle_bus_reset(); + dcd_event_bus_signal(0, DCD_EVENT_BUS_RESET, true); + return; // Don't do the rest of the things here; perhaps they've been cleared? + } if (int_status & USB_ISTR_CTR) { @@ -528,12 +543,7 @@ static void dcd_fs_irqHandler(void) { dcd_ep_ctr_handler(); reg16_clear_bits(&USB->ISTR, USB_ISTR_CTR); } - if(int_status & USB_ISTR_RESET) { - // USBRST is start of reset. - reg16_clear_bits(&USB->ISTR, USB_ISTR_RESET); - dcd_handle_bus_reset(); - dcd_event_bus_signal(0, DCD_EVENT_BUS_RESET, true); - } + if (int_status & USB_ISTR_WKUP) { reg16_clear_bits(&USB->CNTR, USB_CNTR_LPMODE); @@ -544,6 +554,9 @@ static void dcd_fs_irqHandler(void) { if (int_status & USB_ISTR_SUSP) { + /* Suspend is asserted for both suspend and unplug events. without Vbus monitoring, + * these events cannot be differentiated, so we only trigger suspend. */ + /* Force low-power mode in the macrocell */ USB->CNTR |= USB_CNTR_FSUSP; USB->CNTR |= USB_CNTR_LPMODE; @@ -696,25 +709,19 @@ void dcd_edpt_stall (uint8_t rhport, uint8_t ep_addr) { (void)rhport; - if (ep_addr == 0) { // CTRL EP0 (OUT for setup) - pcd_set_ep_tx_status(USB,ep_addr, USB_EP_TX_STALL); + if (ep_addr & 0x80) + { // IN + pcd_set_ep_tx_status(USB, ep_addr & 0x7F, USB_EP_TX_STALL); } - - if (ep_addr & 0x80) { // IN - ep_addr &= 0x7F; - pcd_set_ep_tx_status(USB,ep_addr, USB_EP_TX_STALL); - } else { // OUT - pcd_set_ep_rx_status(USB,ep_addr, USB_EP_RX_STALL); + else + { // OUT + pcd_set_ep_rx_status(USB, ep_addr, USB_EP_RX_STALL); } } void dcd_edpt_clear_stall (uint8_t rhport, uint8_t ep_addr) { (void)rhport; - if (ep_addr == 0) - { - pcd_set_ep_tx_status(USB,ep_addr, USB_EP_TX_NAK); - } if (ep_addr & 0x80) { // IN @@ -730,7 +737,7 @@ void dcd_edpt_clear_stall (uint8_t rhport, uint8_t ep_addr) /* Reset to DATA0 if clearing stall condition. */ pcd_clear_rx_dtog(USB,ep_addr); - pcd_set_ep_rx_status(USB,ep_addr, USB_EP_RX_VALID); + pcd_set_ep_rx_status(USB,ep_addr, USB_EP_RX_NAK); } } -- cgit v1.3.1 From b6590490a8e2ad3debac4508f65af001dc1753af Mon Sep 17 00:00:00 2001 From: Nathan Conrad Date: Sat, 21 Sep 2019 12:00:36 -0400 Subject: USB Control: Pointer arithmetic on void* is forbiden --- 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 4ec432185..eecc95edb 100644 --- a/src/device/usbd_control.c +++ b/src/device/usbd_control.c @@ -122,7 +122,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; + _control_state.buffer = ((uint8_t*)_control_state.buffer) + xferred_bytes; if ( _control_state.total_len == _control_state.total_transferred || xferred_bytes < CFG_TUD_ENDOINT0_SIZE ) { -- cgit v1.3.1 From aebecf169abff62b022da2c0e70f7416d62c91ef Mon Sep 17 00:00:00 2001 From: Nathan Conrad Date: Sat, 21 Sep 2019 12:02:06 -0400 Subject: Reorder handling of EP control requests, --- src/device/usbd.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) (limited to 'src') diff --git a/src/device/usbd.c b/src/device/usbd.c index 0366d1ece..146da5420 100644 --- a/src/device/usbd.c +++ b/src/device/usbd.c @@ -499,10 +499,6 @@ static bool process_control_request(uint8_t rhport, tusb_control_request_t const uint8_t const drv_id = _usbd_dev.ep2drv[ep_num][ep_dir]; TU_ASSERT(drv_id < USBD_CLASS_DRIVER_COUNT); - // Some classes such as TMC needs to clear/re-init its buffer when receiving CLEAR_FEATURE request - // We will forward all request targeted endpoint to its class driver - // - For non-standard request: driver can ACK or Stall the request by return true/false - // - For standard request: usbd decide the ACK stage regardless of driver return value bool ret = false; if ( TUSB_REQ_TYPE_STANDARD != p_request->bmRequestType_bit.type ) @@ -511,12 +507,6 @@ static bool process_control_request(uint8_t rhport, tusb_control_request_t const usbd_control_set_complete_callback(usbd_class_drivers[drv_id].control_complete); } - // Invoke class driver first if available - if ( usbd_class_drivers[drv_id].control_request ) - { - ret = usbd_class_drivers[drv_id].control_request(rhport, p_request); - } - // Then handle if it is standard request if ( TUSB_REQ_TYPE_STANDARD == p_request->bmRequestType_bit.type ) { @@ -552,7 +542,17 @@ static bool process_control_request(uint8_t rhport, tusb_control_request_t const default: TU_BREAKPOINT(); return false; } } + // Some classes such as TMC needs to clear/re-init its buffer when receiving CLEAR_FEATURE request + // We will forward all request targeted endpoint to its class driver + // For class-type requests: must (call tud_control_status(); return true) or (return false) + // For std-type requests: non-std requests codes are already discarded. + // must not call tud_control_status(), and return value will have no effect + // Invoke class driver last, so that EP is already stalled + if ( usbd_class_drivers[drv_id].control_request ) + { + ret = ret | usbd_class_drivers[drv_id].control_request(rhport, p_request); + } return ret; } break; -- cgit v1.3.1 From 55abb3d71763037ffcc4a55c5ecd72c1ef8e47b5 Mon Sep 17 00:00:00 2001 From: Nathan Conrad Date: Sat, 21 Sep 2019 12:02:52 -0400 Subject: Calling EP open with bad parameters should be considered a bug. --- 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 146da5420..67c5bdebc 100644 --- a/src/device/usbd.c +++ b/src/device/usbd.c @@ -804,7 +804,7 @@ bool usbd_open_edpt_pair(uint8_t rhport, uint8_t const* p_desc, uint8_t ep_count { tusb_desc_endpoint_t const * desc_ep = (tusb_desc_endpoint_t const *) p_desc; - TU_VERIFY(TUSB_DESC_ENDPOINT == desc_ep->bDescriptorType && xfer_type == desc_ep->bmAttributes.xfer); + TU_ASSERT(TUSB_DESC_ENDPOINT == desc_ep->bDescriptorType && xfer_type == desc_ep->bmAttributes.xfer); TU_ASSERT(dcd_edpt_open(rhport, desc_ep)); if ( tu_edpt_dir(desc_ep->bEndpointAddress) == TUSB_DIR_IN ) -- cgit v1.3.1 From be28a05409f80f9fe983306b1fc60e1ea30da0bc Mon Sep 17 00:00:00 2001 From: Nathan Conrad Date: Sat, 21 Sep 2019 12:03:36 -0400 Subject: Make type casting explicit --- 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 67c5bdebc..b7a44d24e 100644 --- a/src/device/usbd.c +++ b/src/device/usbd.c @@ -633,7 +633,7 @@ static void mark_interface_endpoint(uint8_t ep2drv[8][2], uint8_t const* p_desc, ep2drv[tu_edpt_number(ep_addr)][tu_edpt_dir(ep_addr)] = driver_id; } - 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 a187f0268c9c42bfbfb22338692dfffed3f9bac5 Mon Sep 17 00:00:00 2001 From: Nathan Conrad Date: Sat, 21 Sep 2019 12:04:49 -0400 Subject: When unstalling, EP must be marked as not busy. Also, mark EP as busy when stalling as xfer requests should fail. --- src/device/usbd.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src') diff --git a/src/device/usbd.c b/src/device/usbd.c index b7a44d24e..e0148dc97 100644 --- a/src/device/usbd.c +++ b/src/device/usbd.c @@ -870,6 +870,7 @@ void usbd_edpt_stall(uint8_t rhport, uint8_t ep_addr) dcd_edpt_stall(rhport, ep_addr); _usbd_dev.ep_stall_map[dir] = (uint8_t) tu_bit_set(_usbd_dev.ep_stall_map[dir], epnum); + _usbd_dev.ep_busy_map[dir] = (uint8_t) tu_bit_set(_usbd_dev.ep_busy_map[dir], epnum); } void usbd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr) @@ -878,6 +879,7 @@ void usbd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr) uint8_t const dir = tu_edpt_dir(ep_addr); dcd_edpt_clear_stall(rhport, ep_addr); + _usbd_dev.ep_busy_map[dir] = (uint8_t) tu_bit_clear(_usbd_dev.ep_busy_map[dir], epnum); _usbd_dev.ep_stall_map[dir] = (uint8_t) tu_bit_clear(_usbd_dev.ep_stall_map[dir], epnum); } -- cgit v1.3.1 From 37b52e354fe4089be04e167e2a5483ae31383274 Mon Sep 17 00:00:00 2001 From: Nathan Conrad Date: Sat, 21 Sep 2019 12:17:17 -0400 Subject: Correct wording of comment on handling EP requests. --- src/device/usbd.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/device/usbd.c b/src/device/usbd.c index e0148dc97..6401a2d9e 100644 --- a/src/device/usbd.c +++ b/src/device/usbd.c @@ -545,9 +545,9 @@ static bool process_control_request(uint8_t rhport, tusb_control_request_t const // Some classes such as TMC needs to clear/re-init its buffer when receiving CLEAR_FEATURE request // We will forward all request targeted endpoint to its class driver // For class-type requests: must (call tud_control_status(); return true) or (return false) - // For std-type requests: non-std requests codes are already discarded. + // For std-type requests: non-std request codes are already discarded. // must not call tud_control_status(), and return value will have no effect - // Invoke class driver last, so that EP is already stalled + // class driver is invoked last, so that EP already has EP stall cleared (in event of clear feature EP halt) if ( usbd_class_drivers[drv_id].control_request ) { -- cgit v1.3.1 From fbb8520acdb7137ef695c03b05e1a3d6c4d33ba2 Mon Sep 17 00:00:00 2001 From: Nathan Conrad Date: Sat, 21 Sep 2019 14:34:29 -0400 Subject: logical or. --- 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 6401a2d9e..fb28ff0e6 100644 --- a/src/device/usbd.c +++ b/src/device/usbd.c @@ -551,7 +551,7 @@ static bool process_control_request(uint8_t rhport, tusb_control_request_t const if ( usbd_class_drivers[drv_id].control_request ) { - ret = ret | usbd_class_drivers[drv_id].control_request(rhport, p_request); + ret = ret || usbd_class_drivers[drv_id].control_request(rhport, p_request); } return ret; } -- cgit v1.3.1 From 9498adef71fe2816d336061b38ed801dc980a8bb Mon Sep 17 00:00:00 2001 From: Nathan Conrad Date: Sat, 21 Sep 2019 19:29:57 -0400 Subject: Changing the bitwise to a logical OR created a huge hard to find bug. It shortcutted the call to the class function, so, lets use shortcutting anyway? --- src/device/usbd.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/device/usbd.c b/src/device/usbd.c index fb28ff0e6..50964bdee 100644 --- a/src/device/usbd.c +++ b/src/device/usbd.c @@ -549,9 +549,10 @@ static bool process_control_request(uint8_t rhport, tusb_control_request_t const // must not call tud_control_status(), and return value will have no effect // class driver is invoked last, so that EP already has EP stall cleared (in event of clear feature EP halt) - if ( usbd_class_drivers[drv_id].control_request ) + if ( usbd_class_drivers[drv_id].control_request && + usbd_class_drivers[drv_id].control_request(rhport, p_request)) { - ret = ret || usbd_class_drivers[drv_id].control_request(rhport, p_request); + ret = true; } return ret; } -- cgit v1.3.1 From fa5b5e4561869e26832d817b4a709ba31e666143 Mon Sep 17 00:00:00 2001 From: Nathan Conrad Date: Sat, 21 Sep 2019 21:46:46 -0400 Subject: Lots of updates (especially error handling) --- examples/device/usbtmc/src/usb_descriptors.c | 4 +- examples/device/usbtmc/src/usbtmc_app.c | 51 ++++-- examples/device/usbtmc/visaQuery.py | 70 +++++++- src/class/usbtmc/usbtmc_device.c | 246 ++++++++++++++------------- src/class/usbtmc/usbtmc_device.h | 2 +- 5 files changed, 236 insertions(+), 137 deletions(-) (limited to 'src') diff --git a/examples/device/usbtmc/src/usb_descriptors.c b/examples/device/usbtmc/src/usb_descriptors.c index 45e1001ea..1175ebb99 100644 --- a/examples/device/usbtmc/src/usb_descriptors.c +++ b/examples/device/usbtmc/src/usb_descriptors.c @@ -107,13 +107,13 @@ uint8_t const * tud_hid_descriptor_report_cb(void) # define TUD_USBTMC_DESC_MAIN(_itfnum,_bNumEndpoints) \ TUD_USBTMC_IF_DESCRIPTOR(_itfnum, _bNumEndpoints, /*_stridx = */ 4u, TUD_USBTMC_PROTOCOL_USB488), \ - TUD_USBTMC_BULK_DESCRIPTORS(/* OUT = */0x03, /* IN = */ 0x83, /* packet size = */USBTMCD_MAX_PACKET_SIZE) + TUD_USBTMC_BULK_DESCRIPTORS(/* OUT = */0x01, /* IN = */ 0x81, /* packet size = */USBTMCD_MAX_PACKET_SIZE) #if defined(CFG_TUD_USBTMC_ENABLE_INT_EP) // Interrupt endpoint should be 2 bytes on a FS USB link # define TUD_USBTMC_DESC(_itfnum) \ TUD_USBTMC_DESC_MAIN(_itfnum, /* _epCount = */ 3), \ - TUD_USBTMC_INT_DESCRIPTOR(/* INT ep # */ 0x84, /* epMaxSize = */ 2, /* bInterval = */16u ) + TUD_USBTMC_INT_DESCRIPTOR(/* INT ep # */ 0x82, /* epMaxSize = */ 2, /* bInterval = */16u ) # define USBTMC_DESC_LEN (TUD_USBTMC_IF_DESCRIPTOR_LEN + TUD_USBTMC_BULK_DESCRIPTORS_LEN + TUD_USBTMC_INT_DESCRIPTOR_LEN) #else diff --git a/examples/device/usbtmc/src/usbtmc_app.c b/examples/device/usbtmc/src/usbtmc_app.c index f8c350f68..495746e07 100644 --- a/examples/device/usbtmc/src/usbtmc_app.c +++ b/examples/device/usbtmc/src/usbtmc_app.c @@ -84,6 +84,7 @@ static volatile uint32_t idnQuery; static uint32_t resp_delay = 125u; // Adjustable delay, to allow for better testing static size_t buffer_len; +static size_t buffer_tx_ix; // for transmitting using multiple transfers static uint8_t buffer[225]; // A few packets long should be enough. @@ -108,6 +109,11 @@ bool tud_usbtmc_app_msgBulkOut_start_cb(uint8_t rhport, usbtmc_msg_request_dev_d (void)rhport; (void)msgHeader; buffer_len = 0; + if(msgHeader->TransferSize > sizeof(buffer)) + { + + return false; + } return true; } @@ -122,6 +128,10 @@ bool tud_usbtmc_app_msg_data_cb(uint8_t rhport, void *data, size_t len, bool tra memcpy(&(buffer[buffer_len]), data, len); buffer_len += len; } + else + { + return false; // buffer overflow! + } queryState = transfer_complete; idnQuery = 0; @@ -145,8 +155,13 @@ bool tud_usbtmc_app_msg_data_cb(uint8_t rhport, void *data, size_t len, bool tra bool tud_usbtmc_app_msgBulkIn_complete_cb(uint8_t rhport) { (void)rhport; - - status &= (uint8_t)~(IEEE4882_STB_MAV); // clear MAV + if((buffer_tx_ix == buffer_len) || idnQuery) // done + { + status &= (uint8_t)~(IEEE4882_STB_MAV); // clear MAV + queryState = 0; + bulkInStarted = 0; + buffer_tx_ix = 0; + } return true; } @@ -161,15 +176,25 @@ bool tud_usbtmc_app_msgBulkIn_request_cb(uint8_t rhport, usbtmc_msg_request_dev_ rspMsg.header.bTag = request->header.bTag, rspMsg.header.bTagInverse = request->header.bTagInverse; msgReqLen = request->TransferSize; + #ifdef xDEBUG uart_tx_str_sync("MSG_IN_DATA: Requested!\r\n"); #endif - TU_ASSERT(bulkInStarted == 0); - bulkInStarted = 1; - - // > If a USBTMC interface receives a Bulk-IN request prior to receiving a USBTMC command message - // that expects a response, the device must NAK the request + if(queryState == 0 || (buffer_tx_ix == 0)) + { + TU_ASSERT(bulkInStarted == 0); + bulkInStarted = 1; + // > If a USBTMC interface receives a Bulk-IN request prior to receiving a USBTMC command message + // that expects a response, the device must NAK the request (*not stall*) + } + else + { + size_t txlen = tu_min32(buffer_len-buffer_tx_ix,msgReqLen); + usbtmcd_transmit_dev_msg_data(rhport, &buffer[buffer_tx_ix], txlen, + (buffer_tx_ix+txlen) == buffer_len, false); + buffer_tx_ix += txlen; + } // Always return true indicating not to stall the EP. return true; } @@ -197,17 +222,17 @@ void usbtmc_app_task_iter(void) { } break; case 4: // time to transmit; - if(bulkInStarted) { - queryState = 0; - bulkInStarted = 0; - + if(bulkInStarted && (buffer_tx_ix == 0)) { if(idnQuery) { - usbtmcd_transmit_dev_msg_data(rhport, idn, tu_min32(sizeof(idn)-1,msgReqLen),false); + usbtmcd_transmit_dev_msg_data(rhport, idn, tu_min32(sizeof(idn)-1,msgReqLen),true,false); + queryState = 0; + bulkInStarted = 0; } else { - usbtmcd_transmit_dev_msg_data(rhport, buffer, tu_min32(buffer_len,msgReqLen),false); + buffer_tx_ix = tu_min32(buffer_len,msgReqLen); + usbtmcd_transmit_dev_msg_data(rhport, buffer, buffer_tx_ix, buffer_tx_ix == buffer_len, false); } // MAV is cleared in the transfer complete callback. } diff --git a/examples/device/usbtmc/visaQuery.py b/examples/device/usbtmc/visaQuery.py index 368b66053..4d4b50c4b 100644 --- a/examples/device/usbtmc/visaQuery.py +++ b/examples/device/usbtmc/visaQuery.py @@ -6,7 +6,8 @@ import sys def test_idn(): idn = inst.query("*idn?"); - assert idn == "TinyUSB,ModelNumber,SerialNumber,FirmwareVer123456\r\n" + assert (idn == "TinyUSB,ModelNumber,SerialNumber,FirmwareVer123456\r\n") + assert (inst.is_4882_compliant) def test_echo(m,n): longstr = "0123456789abcdefghijklmnopqrstuvwxyz" * 50 @@ -34,6 +35,8 @@ def test_trig(): def test_mav(): + inst.write("delay 50") + inst.read_stb() # clear STB assert (inst.read_stb() == 0) inst.write("123") time.sleep(0.3) @@ -60,8 +63,6 @@ def test_srq(): rsp = inst.read() assert(rsp == "123\r\n") - - def test_read_timeout(): inst.timeout = 500 @@ -78,7 +79,53 @@ def test_read_timeout(): t = time.time() - t0 assert ((t*1000.0) > (inst.timeout - 300)) assert ((t*1000.0) < (inst.timeout + 300)) - print(f"Delay was {t}") + print(f"Delay was {t:0.3}") + # Response is still in queue, so send a clear (to be more helpful to the next test) + inst.clear() + time.sleep(0.3) + assert(0 == (inst.read_stb() & 0x10)), "MAV not reset after clear" + +def test_abort_in(): + inst.timeout = 200 + # First read with no MAV + inst.read_stb() + assert (inst.read_stb() == 0) + inst.write("delay 500") + inst.write("xxx") + t0 = time.time() + try: + rsp = inst.read() + assert(false), "Read should have resulted in timeout" + except visa.VisaIOError: + print("Got expected exception") + t = time.time() - t0 + assert ((t*1000.0) > (inst.timeout - 300)) + assert ((t*1000.0) < (inst.timeout + 300)) + print(f"Delay was {t:0.3}") + # Response is still in queue, so send a clear (to be more helpful to the next test) + inst.timeout = 800 + y = inst.read() + assert(y == "xxx\r\n") + +def test_indicate(): + # perform indicator pulse + usb_iface = inst.get_visa_attribute(visa.constants.VI_ATTR_USB_INTFC_NUM) + retv = inst.control_in(request_type_bitmap_field=0xA1, request_id=64, request_value=0x0000, index=usb_iface, length=0x0001) + assert((retv[1] == visa.constants.StatusCode(0)) and (retv[0] == b'\x01')), f"indicator pulse failed: retv={retv}" + + +def test_multi_read(): + old_chunk_size = inst.chunk_size + longstr = "0123456789abcdefghijklmnopqrstuvwxyz" * 10 + timeout = 10 + x = longstr[0:174] + inst.chunk_size = 50 # Seems chunk size only applies to read but not write + inst.write(x) + # I'm not sure how to request just the remaining bit using a max count... so just read it all. + y = inst.read() + assert (x + "\r\n" == y) + #inst.chunk_size = old_chunk_size + rm = visa.ResourceManager("/c/Windows/system32/visa64.dll") reslist = rm.list_resources("USB?::?*::INSTR") @@ -89,12 +136,20 @@ if (len(reslist) == 0): inst = rm.open_resource(reslist[0]); inst.timeout = 3000 + inst.clear() print("+ IDN") test_idn() -inst.timeout = 3000 +print("+test abort in") +test_abort_in() + + +inst.timeout = 2000 + +print("+ multi read") +test_multi_read() print("+ echo delay=0") @@ -110,7 +165,7 @@ inst.write("delay 150") test_echo(53,76) test_echo(165,170) -print("+ Read timeout (no MAV") +print("+ Read timeout (no MAV)") test_read_timeout() print("+ MAV") @@ -119,6 +174,9 @@ test_mav() print("+ SRQ") test_srq() +print("+ indicate") +test_indicate() + print("+ TRIG") test_trig() diff --git a/src/class/usbtmc/usbtmc_device.c b/src/class/usbtmc/usbtmc_device.c index fcd3376f3..2c6c88cf5 100644 --- a/src/class/usbtmc/usbtmc_device.c +++ b/src/class/usbtmc/usbtmc_device.c @@ -31,25 +31,31 @@ * This file is part of the TinyUSB stack. */ -// Synchronization is needed in some spots. -// These functions should NOT be called from interrupts. - -/* The library is designed that its functions can be called by any user task, with need for - * additional locking. In the case of "no OS", this task is never preempted other than by - * interrupts, and the USBTMC code isn't called by interrupts, so all is OK. In the case - * of an OS, this class driver uses the OSAL to perform locking. The code uses a single lock - * and does not call outside of this class with a lock held, so deadlocks won't happen. +/* + * This library is not fully reentrant, though it is reentrant from the view + * of either the application layer or the USB stack. Due to its locking, + * it is not safe to call its functions from interrupts. * - * This module's application-facing functions are not reentrant. The application must - * only call them from a single thread (or implement its own locking). + * The one exception is that its functions may not be called from the application + * until the USB stack is initialized. This should not be a problem since the + * device shouldn't be sending messages until it receives a request from the + * host. */ +/* + * In the case of single-CPU "no OS", this task is never preempted other than by + * interrupts, and the USBTMC code isn't called by interrupts, so all is OK. For "no OS", + * the mutex structure's main effect is to disable the USB interrupts. + * With an OS, this class driver uses the OSAL to perform locking. The code uses a single lock + * and does not call outside of this class with a lock held, so deadlocks won't happen. + */ + //Limitations: // "vendor-specific" commands are not handled. // Dealing with "termchar" must be handled by the application layer, // though additional error checking is does in this module. -// talkOnly and listenOnly are NOT supported. They're no permitted +// talkOnly and listenOnly are NOT supported. They're not permitted // in USB488, anyway. /* Supported: @@ -64,10 +70,7 @@ // TODO: // USBTMC 3.2.2 error conditions not strictly followed // No local lock-out, REN, or GTL. -// Cannot handle clear. // Clear message available status byte at the correct time? (488 4.3.1.3) -// Abort bulk in/out -// No CLEAR_FEATURE/HALT no EP (yet) #include "tusb_option.h" @@ -79,21 +82,24 @@ #include "usbtmc_device.h" #include "device/dcd.h" #include "device/usbd.h" +#include "osal/osal.h" + +// FIXME: I shouldn't need to include _pvt headers, but it is necessary for usbd_edpt_xfer, _stall, and _busy +#include "device/usbd_pvt.h" #ifdef xDEBUG #include "uart_util.h" static char logMsg[150]; #endif - -// FIXME: I shouldn't need to include _pvt headers. -#include "device/usbd_pvt.h" - -static uint8_t termChar; -static uint8_t termCharRequested = false; +/* + * The state machine does not allow simultaneous reading and writing. This is + * consistent with USBTMC. + */ typedef enum { + STATE_CLOSED, STATE_IDLE, STATE_RCV, STATE_TX_REQUESTED, @@ -126,16 +132,12 @@ typedef struct uint8_t lastBulkOutTag; // used for aborts (mostly) uint8_t lastBulkInTag; // used for aborts (mostly) - uint8_t const * devInBuffer; + uint8_t const * devInBuffer; // pointer to application-layer used for transmissions } usbtmc_interface_state_t; static usbtmc_interface_state_t usbtmc_state = { - .state = STATE_IDLE, .itf_id = 0xFF, - .ep_bulk_in = 0, - .ep_bulk_out = 0, - .ep_int_in = 0 }; // We need all headers to fit in a single packet in this implementation. @@ -147,6 +149,9 @@ TU_VERIFY_STATIC( static bool handle_devMsgOutStart(uint8_t rhport, void *data, size_t len); static bool handle_devMsgOut(uint8_t rhport, void *data, size_t len, size_t packetLen); +static uint8_t termChar; +static uint8_t termCharRequested = false; + osal_mutex_def_t usbtmcLockBuffer; static osal_mutex_t usbtmcLock; @@ -155,6 +160,23 @@ static osal_mutex_t usbtmcLock; #define criticalEnter() do {osal_mutex_lock(usbtmcLock,OSAL_TIMEOUT_WAIT_FOREVER); } while (0) #define criticalLeave() do {osal_mutex_unlock(usbtmcLock); } while (0) +bool atomicChangeState(usbtmcd_state_enum expectedState, usbtmcd_state_enum newState) +{ + bool ret = true; + criticalEnter(); + usbtmcd_state_enum oldState = usbtmc_state.state; + if (oldState == expectedState) + { + usbtmc_state.state = newState; + } + else + { + ret = false; + } + criticalLeave(); + return ret; +} + // called from app // We keep a reference to the buffer, so it MUST not change until the app is // notified that the transfer is complete. @@ -165,6 +187,7 @@ static osal_mutex_t usbtmcLock; bool usbtmcd_transmit_dev_msg_data( uint8_t rhport, const void * data, size_t len, + bool endOfMessage, bool usingTermChar) { const unsigned int txBufLen = sizeof(usbtmc_state.ep_bulk_in_buf); @@ -172,68 +195,53 @@ bool usbtmcd_transmit_dev_msg_data( #ifndef NDEBUG TU_ASSERT(len > 0u); TU_ASSERT(len <= usbtmc_state.transfer_size_remaining); + TU_ASSERT(usbtmc_state.transfer_size_sent == 0u); if(usingTermChar) { TU_ASSERT(tud_usbtmc_app_capabilities.bmDevCapabilities.canEndBulkInOnTermChar); TU_ASSERT(termCharRequested); - TU_ASSERT(((uint8_t*)data)[len-1] == termChar); + TU_ASSERT(((uint8_t*)data)[len-1u] == termChar); } #endif TU_VERIFY(usbtmc_state.state == STATE_TX_REQUESTED); usbtmc_msg_dev_dep_msg_in_header_t *hdr = (usbtmc_msg_dev_dep_msg_in_header_t*)usbtmc_state.ep_bulk_in_buf; - memset(hdr, 0x00, sizeof(*hdr)); + tu_varclr(hdr); hdr->header.MsgID = USBTMC_MSGID_DEV_DEP_MSG_IN; hdr->header.bTag = usbtmc_state.lastBulkInTag; hdr->header.bTagInverse = (uint8_t)~(usbtmc_state.lastBulkInTag); hdr->TransferSize = len; - hdr->bmTransferAttributes.EOM = 1u; + hdr->bmTransferAttributes.EOM = endOfMessage; hdr->bmTransferAttributes.UsingTermChar = usingTermChar; // Copy in the header - size_t packetLen = sizeof(*hdr); - - // If it fits in a single trasnmission: - if((packetLen + hdr->TransferSize) <= txBufLen) - { - memcpy((uint8_t*)(usbtmc_state.ep_bulk_in_buf) + packetLen, data, hdr->TransferSize); - packetLen = (uint16_t)(packetLen + hdr->TransferSize); - usbtmc_state.transfer_size_remaining = 0; - usbtmc_state.transfer_size_sent = len; - usbtmc_state.devInBuffer = NULL; - } - else /* partial packet */ - { - memcpy((uint8_t*)(usbtmc_state.ep_bulk_in_buf) + packetLen, data, txBufLen - packetLen); - usbtmc_state.devInBuffer = (uint8_t*)data + (txBufLen - packetLen); - usbtmc_state.transfer_size_remaining = len - (txBufLen - packetLen); - usbtmc_state.transfer_size_sent = txBufLen - packetLen; - packetLen = txBufLen; - } - - - criticalEnter(); - { - TU_VERIFY(usbtmc_state.state == STATE_TX_REQUESTED); - // We used packetlen as a max, not the buffer size, so this is OK here, no need for modulus - usbtmc_state.state = (packetLen >= txBufLen) ? STATE_TX_INITIATED : STATE_TX_SHORTED; - } - criticalLeave(); - - TU_VERIFY( usbd_edpt_xfer(rhport, usbtmc_state.ep_bulk_in, usbtmc_state.ep_bulk_in_buf, (uint16_t)packetLen)); + const size_t headerLen = sizeof(*hdr); + const size_t dataLen = ((headerLen + hdr->TransferSize) <= txBufLen) ? + len : (txBufLen - headerLen); + const size_t packetLen = headerLen + dataLen; + + memcpy((uint8_t*)(usbtmc_state.ep_bulk_in_buf) + headerLen, data, dataLen); + usbtmc_state.transfer_size_remaining = len - dataLen; + usbtmc_state.transfer_size_sent = dataLen; + usbtmc_state.devInBuffer = (uint8_t*)data + (dataLen); + + bool stateChanged = + atomicChangeState(STATE_TX_REQUESTED, (packetLen >= txBufLen) ? STATE_TX_INITIATED : STATE_TX_SHORTED); + TU_VERIFY(stateChanged); + TU_VERIFY(usbd_edpt_xfer(rhport, usbtmc_state.ep_bulk_in, usbtmc_state.ep_bulk_in_buf, (uint16_t)packetLen)); return true; } void usbtmcd_init_cb(void) { #ifndef NDEBUG -# if CFG_USBTMC_CFG_ENABLE_488 - if(tud_usbtmc_app_capabilities.bmIntfcCapabilities488.supportsTrigger) - TU_ASSERT(&tud_usbtmc_app_msg_trigger_cb != NULL,); - // Per USB488 spec: table 8 - TU_ASSERT(!tud_usbtmc_app_capabilities.bmIntfcCapabilities.listenOnly,); - TU_ASSERT(!tud_usbtmc_app_capabilities.bmIntfcCapabilities.talkOnly,); -# endif +# if CFG_USBTMC_CFG_ENABLE_488 + if(tud_usbtmc_app_capabilities.bmIntfcCapabilities488.supportsTrigger) + TU_ASSERT(&tud_usbtmc_app_msg_trigger_cb != NULL,); + // Per USB488 spec: table 8 + TU_ASSERT(!tud_usbtmc_app_capabilities.bmIntfcCapabilities.listenOnly,); + TU_ASSERT(!tud_usbtmc_app_capabilities.bmIntfcCapabilities.talkOnly,); +# endif if(tud_usbtmc_app_capabilities.bmIntfcCapabilities.supportsIndicatorPulse) TU_ASSERT(&tud_usbtmc_app_indicator_pluse_cb != NULL,); #endif @@ -244,20 +252,16 @@ void usbtmcd_init_cb(void) bool usbtmcd_open_cb(uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint16_t *p_length) { (void)rhport; + TU_ASSERT(usbtmc_state.state == STATE_CLOSED); uint8_t const * p_desc; uint8_t found_endpoints = 0; - - usbtmcd_reset_cb(rhport); - - // Perhaps there are other application specific class drivers, so don't assert here. - if( itf_desc->bInterfaceClass != TUD_USBTMC_APP_CLASS) - return false; - if( itf_desc->bInterfaceSubClass != TUD_USBTMC_APP_SUBCLASS) - return false; - +#ifndef NDEBUG + TU_ASSERT(itf_desc->bInterfaceClass == TUD_USBTMC_APP_CLASS); + TU_ASSERT(itf_desc->bInterfaceSubClass == TUD_USBTMC_APP_SUBCLASS); // Only 2 or 3 endpoints are allowed for USBTMC. TU_ASSERT((itf_desc->bNumEndpoints == 2) || (itf_desc->bNumEndpoints ==3)); +#endif // Interface (*p_length) = 0u; @@ -318,28 +322,27 @@ bool usbtmcd_open_cb(uint8_t rhport, tusb_desc_interface_t const * itf_desc, uin } #endif #endif + usbtmc_state.state = STATE_IDLE; TU_VERIFY( usbd_edpt_xfer(rhport, usbtmc_state.ep_bulk_out, usbtmc_state.ep_bulk_out_buf, 64)); return true; } void usbtmcd_reset_cb(uint8_t rhport) { - // FIXME: Do endpoints need to be closed here? - usbtmc_state.state = STATE_IDLE; - usbtmc_state.itf_id = 0xFF; - usbtmc_state.ep_bulk_in = 0; - usbtmc_state.ep_bulk_out = 0; - usbtmc_state.ep_int_in = 0; - usbtmc_state.lastBulkInTag = 0; - usbtmc_state.lastBulkOutTag = 0; - (void)rhport; + + criticalEnter(); + tu_varclr(&usbtmc_state); + usbtmc_state.itf_id = 0xFFu; + criticalLeave(); } static bool handle_devMsgOutStart(uint8_t rhport, void *data, size_t len) { (void)rhport; - TU_VERIFY(usbtmc_state.state == STATE_IDLE); + bool stateChanged = atomicChangeState(STATE_IDLE, STATE_RCV); + TU_VERIFY(stateChanged); + // must be a header, should have been confirmed before calling here. usbtmc_msg_request_dev_dep_out *msg = (usbtmc_msg_request_dev_dep_out*)data; usbtmc_state.transfer_size_remaining = msg->TransferSize; @@ -352,6 +355,9 @@ static bool handle_devMsgOutStart(uint8_t rhport, void *data, size_t len) static bool handle_devMsgOut(uint8_t rhport, void *data, size_t len, size_t packetLen) { (void)rhport; + + TU_VERIFY(usbtmc_state.state == STATE_RCV); + bool shortPacket = (packetLen < USBTMCD_MAX_PACKET_SIZE); // Packet is to be considered complete when we get enough data or at a short packet. @@ -360,18 +366,14 @@ static bool handle_devMsgOut(uint8_t rhport, void *data, size_t len, size_t pack atEnd = true; if(len > usbtmc_state.transfer_size_remaining) len = usbtmc_state.transfer_size_remaining; - tud_usbtmc_app_msg_data_cb(rhport,data, len, atEnd); + TU_VERIFY(tud_usbtmc_app_msg_data_cb(rhport,data, len, atEnd)); + // TODO: Go to an error state upon failure other than just stalling the EP? usbtmc_state.transfer_size_remaining -= len; usbtmc_state.transfer_size_sent += len; - if(atEnd) - { - usbtmc_state.state = STATE_IDLE; - } - else - { - usbtmc_state.state = STATE_RCV; - } + bool stateChanged = atomicChangeState(STATE_RCV, atEnd ? STATE_IDLE : STATE_RCV); + TU_VERIFY(stateChanged); + return true; } @@ -379,16 +381,11 @@ static bool handle_devMsgIn(uint8_t rhport, void *data, size_t len) { TU_VERIFY(len == sizeof(usbtmc_msg_request_dev_dep_in)); usbtmc_msg_request_dev_dep_in *msg = (usbtmc_msg_request_dev_dep_in*)data; - - criticalEnter(); - { - TU_VERIFY(usbtmc_state.state == STATE_IDLE); - usbtmc_state.state = STATE_TX_REQUESTED; - usbtmc_state.lastBulkInTag = msg->header.bTag; - usbtmc_state.transfer_size_remaining = msg->TransferSize; - usbtmc_state.transfer_size_sent = 0u; - } - criticalLeave(); + bool stateChanged = atomicChangeState(STATE_IDLE, STATE_TX_REQUESTED); + TU_VERIFY(stateChanged); + usbtmc_state.lastBulkInTag = msg->header.bTag; + usbtmc_state.transfer_size_remaining = msg->TransferSize; + usbtmc_state.transfer_size_sent = 0u; termCharRequested = msg->bmTransferAttributes.TermCharEnabled; termChar = msg->TermChar; @@ -403,7 +400,7 @@ static bool handle_devMsgIn(uint8_t rhport, void *data, size_t len) bool usbtmcd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes) { TU_VERIFY(result == XFER_RESULT_SUCCESS); - + //uart_tx_str_sync("TMC XFER CB\r\n"); if(usbtmc_state.state == STATE_CLEARING) { return true; /* I think we can ignore everything here */ } @@ -457,7 +454,7 @@ bool usbtmcd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint case STATE_ABORTING_BULK_OUT: TU_VERIFY(false); - return false; // Should be stalled by now... + return false; // Should be stalled by now, shouldn't have received a packet. case STATE_TX_REQUESTED: case STATE_TX_INITIATED: case STATE_ABORTING_BULK_IN: @@ -534,19 +531,26 @@ bool usbtmcd_control_request_cb(uint8_t rhport, tusb_control_request_t const * r (request->bRequest == TUSB_REQ_CLEAR_FEATURE) && (request->wValue == TUSB_REQ_FEATURE_EDPT_HALT)) { - if((request->wIndex) == usbtmc_state.ep_bulk_out) + uint32_t ep_addr = (request->wIndex); + + if(ep_addr == usbtmc_state.ep_bulk_out) { usmtmcd_app_bulkOut_clearFeature_cb(rhport); + // And start a new OUT xfer request now that things are clear + TU_ASSERT( usbd_edpt_xfer(rhport, usbtmc_state.ep_bulk_out, usbtmc_state.ep_bulk_out_buf, 64)); } - else if ((request->wIndex) == usbtmc_state.ep_bulk_in) + else if (ep_addr == usbtmc_state.ep_bulk_in) { usmtmcd_app_bulkIn_clearFeature_cb(rhport); } - return false; // We want USBD core to handle sending the status response, and clear the stall condition + else + { + return false; + } + return true; } - // We only handle class requests, IN direction. - // (for now) + // Otherwise, we only handle class requests. if(request->bmRequestType_bit.type != TUSB_REQ_TYPE_CLASS) { return false; @@ -571,7 +575,7 @@ bool usbtmcd_control_request_cb(uint8_t rhport, tusb_control_request_t const * r { rsp.USBTMC_status = USBTMC_STATUS_FAILED; } - else if(usbtmc_state.lastBulkOutTag == (request->wValue & 0xf7u)) + else if(usbtmc_state.lastBulkOutTag == (request->wValue & 0x7Fu)) { rsp.USBTMC_status = USBTMC_STATUS_TRANSFER_NOT_IN_PROGRESS; } @@ -579,7 +583,9 @@ bool usbtmcd_control_request_cb(uint8_t rhport, tusb_control_request_t const * r { rsp.USBTMC_status = USBTMC_STATUS_SUCCESS; // Check if we've queued a short packet + criticalEnter(); usbtmc_state.state = STATE_ABORTING_BULK_OUT; + criticalLeave(); TU_VERIFY(tud_usbtmc_app_initiate_abort_bulk_out_cb(rhport, &(rsp.USBTMC_status))); usbd_edpt_stall(rhport, usbtmc_state.ep_bulk_out); } @@ -610,13 +616,15 @@ bool usbtmcd_control_request_cb(uint8_t rhport, tusb_control_request_t const * r TU_VERIFY(request->wIndex == usbtmc_state.ep_bulk_in); // wValue is the requested bTag to abort if((usbtmc_state.state == STATE_TX_REQUESTED || usbtmc_state.state == STATE_TX_INITIATED) && - usbtmc_state.lastBulkInTag == (request->wValue & 0xf7u)) + usbtmc_state.lastBulkInTag == (request->wValue & 0x7Fu)) { rsp.USBTMC_status = USBTMC_STATUS_SUCCESS; - usbtmc_state.transfer_size_remaining = 0; + usbtmc_state.transfer_size_remaining = 0u; // Check if we've queued a short packet + criticalEnter(); usbtmc_state.state = ((usbtmc_state.transfer_size_sent % USBTMCD_MAX_PACKET_SIZE) == 0) ? STATE_ABORTING_BULK_IN : STATE_ABORTING_BULK_IN_SHORTED; + criticalLeave(); if(usbtmc_state.transfer_size_sent == 0) { // Send short packet, nothing is in the buffer yet @@ -652,6 +660,7 @@ bool usbtmcd_control_request_cb(uint8_t rhport, tusb_control_request_t const * r .NBYTES_RXD_TXD = usbtmc_state.transfer_size_sent, }; TU_VERIFY(tud_usbtmc_app_check_abort_bulk_in_cb(rhport, &rsp)); + criticalEnter(); switch(usbtmc_state.state) { case STATE_ABORTING_BULK_IN_ABORTED: @@ -665,6 +674,7 @@ bool usbtmcd_control_request_cb(uint8_t rhport, tusb_control_request_t const * r default: break; } + criticalLeave(); TU_VERIFY(tud_control_xfer(rhport, request, (void*)&rsp,sizeof(rsp))); return true; @@ -678,7 +688,9 @@ bool usbtmcd_control_request_cb(uint8_t rhport, tusb_control_request_t const * r // control endpoint response shown in Table 31, and clear all input buffers and output buffers. usbd_edpt_stall(rhport, usbtmc_state.ep_bulk_out); usbtmc_state.transfer_size_remaining = 0; + criticalEnter(); usbtmc_state.state = STATE_CLEARING; + criticalLeave(); TU_VERIFY(tud_usbtmc_app_initiate_clear_cb(rhport, &tmcStatusCode)); TU_VERIFY(tud_control_xfer(rhport, request, (void*)&tmcStatusCode,sizeof(tmcStatusCode))); return true; @@ -702,7 +714,11 @@ bool usbtmcd_control_request_cb(uint8_t rhport, tusb_control_request_t const * r TU_VERIFY(tud_usbtmc_app_check_clear_cb(rhport, &clearStatusRsp)); } if(clearStatusRsp.USBTMC_status == USBTMC_STATUS_SUCCESS) + { + criticalEnter(); usbtmc_state.state = STATE_IDLE; + criticalLeave(); + } TU_VERIFY(tud_control_xfer(rhport, request, (void*)&clearStatusRsp,sizeof(clearStatusRsp))); return true; } @@ -754,7 +770,7 @@ bool usbtmcd_control_request_cb(uint8_t rhport, tusb_control_request_t const * r }, .StatusByte = tud_usbtmc_app_get_stb_cb(rhport, &(rsp.USBTMC_status)) }; - usbd_edpt_xfer(rhport, usbtmc_state.ep_int_in, (void*)&intMsg,sizeof(intMsg)); + usbd_edpt_xfer(rhport, usbtmc_state.ep_int_in, (void*)&intMsg, sizeof(intMsg)); } else { @@ -785,7 +801,7 @@ bool usbtmcd_control_complete_cb(uint8_t rhport, tusb_control_request_t const * { (void)rhport; //------------- Class Specific Request -------------// - TU_VERIFY (request->bmRequestType_bit.type == TUSB_REQ_TYPE_CLASS); + TU_ASSERT (request->bmRequestType_bit.type == TUSB_REQ_TYPE_CLASS); return true; } diff --git a/src/class/usbtmc/usbtmc_device.h b/src/class/usbtmc/usbtmc_device.h index 5c6ee2a8d..d33d73905 100644 --- a/src/class/usbtmc/usbtmc_device.h +++ b/src/class/usbtmc/usbtmc_device.h @@ -91,7 +91,7 @@ TU_ATTR_WEAK bool tud_usbtmc_app_msg_trigger_cb(uint8_t rhport, usbtmc_msg_gener bool usbtmcd_transmit_dev_msg_data( uint8_t rhport, const void * data, size_t len, - bool usingTermChar); + bool endOfMessage, bool usingTermChar); /* "callbacks" from USB device core */ -- cgit v1.3.1 From 108f756e22c07d066f9d3079100872df71416991 Mon Sep 17 00:00:00 2001 From: "William D. Jones" Date: Sat, 21 Sep 2019 22:40:01 -0400 Subject: dcd_synopsys: Fix off-by-one error in FIFO allocation. --- src/portable/st/synopsys/dcd_synopsys.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/portable/st/synopsys/dcd_synopsys.c b/src/portable/st/synopsys/dcd_synopsys.c index f15b92edc..1a7f86219 100644 --- a/src/portable/st/synopsys/dcd_synopsys.c +++ b/src/portable/st/synopsys/dcd_synopsys.c @@ -268,10 +268,10 @@ bool dcd_edpt_open (uint8_t rhport, tusb_desc_endpoint_t const * desc_edpt) uint8_t const epnum = tu_edpt_number(desc_edpt->bEndpointAddress); uint8_t const dir = tu_edpt_dir(desc_edpt->bEndpointAddress); - + TU_ASSERT(desc_edpt->wMaxPacketSize.size <= 64); TU_ASSERT(epnum < EP_MAX); - + xfer_ctl_t * xfer = XFER_CTL_BASE(epnum, dir); xfer->max_size = desc_edpt->wMaxPacketSize.size; @@ -305,18 +305,22 @@ bool dcd_edpt_open (uint8_t rhport, tusb_desc_endpoint_t const * desc_edpt) // Since OUT FIFO = GRXFSIZ, FIFO 0 = 16, for simplicity, we equally allocated for the rest of endpoints // - Size : (FIFO_SIZE/4 - GRXFSIZ - 16) / (EP_MAX-1) // - Offset: GRXFSIZ + 16 + Size*(epnum-1) + // - IN EP 1 gets FIFO 1, IN EP "n" gets FIFO "n". in_ep[epnum].DIEPCTL |= (1 << USB_OTG_DIEPCTL_USBAEP_Pos) | \ - (epnum - 1) << USB_OTG_DIEPCTL_TXFNUM_Pos | \ + epnum << USB_OTG_DIEPCTL_TXFNUM_Pos | \ desc_edpt->bmAttributes.xfer << USB_OTG_DIEPCTL_EPTYP_Pos | \ (desc_edpt->bmAttributes.xfer != TUSB_XFER_ISOCHRONOUS ? USB_OTG_DOEPCTL_SD0PID_SEVNFRM : 0) | \ desc_edpt->wMaxPacketSize.size << USB_OTG_DIEPCTL_MPSIZ_Pos; dev->DAINTMSK |= (1 << (USB_OTG_DAINTMSK_IEPM_Pos + epnum)); - // Both TXFD and TXSA are in unit of 32-bit words + // Both TXFD and TXSA are in unit of 32-bit words. + // IN FIFO 0 was configured during enumeration, hence the "+ 16". uint16_t const allocated_size = (USB_OTG_FS->GRXFSIZ & 0x0000ffff) + 16; uint16_t const fifo_size = (EP_FIFO_SIZE/4 - allocated_size) / (EP_MAX-1); uint32_t const fifo_offset = allocated_size + fifo_size*(epnum-1); + + // DIEPTXF starts at FIFO #1. USB_OTG_FS->DIEPTXF[epnum - 1] = (fifo_size << USB_OTG_DIEPTXF_INEPTXFD_Pos) | fifo_offset; } -- cgit v1.3.1 From e61f2b7393382387634ab38e14ac5fab70e3c122 Mon Sep 17 00:00:00 2001 From: Nathan Conrad Date: Sun, 22 Sep 2019 09:55:28 -0400 Subject: Retool stalling EP on xfer errors. --- src/class/usbtmc/usbtmc_device.c | 43 ++++++++++++++++++++++++++-------------- 1 file changed, 28 insertions(+), 15 deletions(-) (limited to 'src') diff --git a/src/class/usbtmc/usbtmc_device.c b/src/class/usbtmc/usbtmc_device.c index 2c6c88cf5..e3d2c316e 100644 --- a/src/class/usbtmc/usbtmc_device.c +++ b/src/class/usbtmc/usbtmc_device.c @@ -340,8 +340,9 @@ void usbtmcd_reset_cb(uint8_t rhport) static bool handle_devMsgOutStart(uint8_t rhport, void *data, size_t len) { (void)rhport; - bool stateChanged = atomicChangeState(STATE_IDLE, STATE_RCV); - TU_VERIFY(stateChanged); + // return true upon failure, as we can assume error is being handled elsewhere. + TU_VERIFY(atomicChangeState(STATE_IDLE, STATE_RCV), true); + usbtmc_state.transfer_size_sent = 0u; // must be a header, should have been confirmed before calling here. usbtmc_msg_request_dev_dep_out *msg = (usbtmc_msg_request_dev_dep_out*)data; @@ -349,30 +350,36 @@ static bool handle_devMsgOutStart(uint8_t rhport, void *data, size_t len) TU_VERIFY(tud_usbtmc_app_msgBulkOut_start_cb(rhport,msg)); TU_VERIFY(handle_devMsgOut(rhport, (uint8_t*)data + sizeof(*msg), len - sizeof(*msg), len)); + usbtmc_state.lastBulkOutTag = msg->header.bTag; return true; } static bool handle_devMsgOut(uint8_t rhport, void *data, size_t len, size_t packetLen) { (void)rhport; - - TU_VERIFY(usbtmc_state.state == STATE_RCV); + // return true upon failure, as we can assume error is being handled elsewhere. + TU_VERIFY(usbtmc_state.state == STATE_RCV,true); bool shortPacket = (packetLen < USBTMCD_MAX_PACKET_SIZE); // Packet is to be considered complete when we get enough data or at a short packet. bool atEnd = false; if(len >= usbtmc_state.transfer_size_remaining || shortPacket) + { atEnd = true; - if(len > usbtmc_state.transfer_size_remaining) - len = usbtmc_state.transfer_size_remaining; - TU_VERIFY(tud_usbtmc_app_msg_data_cb(rhport,data, len, atEnd)); - // TODO: Go to an error state upon failure other than just stalling the EP? + } + + len = tu_min32(len, usbtmc_state.transfer_size_remaining); + + if(!tud_usbtmc_app_msg_data_cb(rhport,data, len, atEnd)) + { + // TODO: Go to an error state upon failure other than just stalling the EP? + return false; + } usbtmc_state.transfer_size_remaining -= len; usbtmc_state.transfer_size_sent += len; - bool stateChanged = atomicChangeState(STATE_RCV, atEnd ? STATE_IDLE : STATE_RCV); - TU_VERIFY(stateChanged); + TU_VERIFY(atomicChangeState(STATE_RCV, atEnd ? STATE_IDLE : STATE_RCV)); return true; } @@ -420,9 +427,11 @@ bool usbtmcd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint switch(msg->header.MsgID) { case USBTMC_MSGID_DEV_DEP_MSG_OUT: - usbtmc_state.transfer_size_sent = 0u; - TU_VERIFY(handle_devMsgOutStart(rhport, msg, xferred_bytes)); - usbtmc_state.lastBulkOutTag = msg->header.bTag; + if(!handle_devMsgOutStart(rhport, msg, xferred_bytes)) + { + usbd_edpt_stall(rhport, usbtmc_state.ep_bulk_out); + TU_VERIFY(false); + } break; case USBTMC_MSGID_DEV_DEP_MSG_IN: @@ -440,7 +449,7 @@ bool usbtmcd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint case USBTMC_MSGID_VENDOR_SPECIFIC_MSG_OUT: case USBTMC_MSGID_VENDOR_SPECIFIC_IN: default: - + usbd_edpt_stall(rhport, usbtmc_state.ep_bulk_out); TU_VERIFY(false); return false; } @@ -448,7 +457,11 @@ bool usbtmcd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint return true; case STATE_RCV: - TU_VERIFY(handle_devMsgOut(rhport, usbtmc_state.ep_bulk_out_buf, xferred_bytes, xferred_bytes)); + if(!handle_devMsgOut(rhport, usbtmc_state.ep_bulk_out_buf, xferred_bytes, xferred_bytes)) + { + usbd_edpt_stall(rhport, usbtmc_state.ep_bulk_out); + TU_VERIFY(false); + } TU_VERIFY(usbd_edpt_xfer(rhport, usbtmc_state.ep_bulk_out, usbtmc_state.ep_bulk_out_buf, USBTMCD_MAX_PACKET_SIZE)); return true; -- cgit v1.3.1 From 10105557dc5d9bd315f70243f947386728c7d86c Mon Sep 17 00:00:00 2001 From: Nathan Conrad Date: Tue, 24 Sep 2019 13:11:45 -0400 Subject: Let application control interface latency... --- examples/device/usbtmc/src/usbtmc_app.c | 16 ++++++++- src/class/usbtmc/usbtmc_device.c | 62 ++++++++++++++++++++++++--------- src/class/usbtmc/usbtmc_device.h | 15 +++++++- 3 files changed, 74 insertions(+), 19 deletions(-) (limited to 'src') diff --git a/examples/device/usbtmc/src/usbtmc_app.c b/examples/device/usbtmc/src/usbtmc_app.c index 495746e07..2982675b1 100644 --- a/examples/device/usbtmc/src/usbtmc_app.c +++ b/examples/device/usbtmc/src/usbtmc_app.c @@ -96,6 +96,13 @@ static usbtmc_msg_dev_dep_msg_in_header_t rspMsg = { } }; +void tud_usbtmc_app_open_cb(uint8_t rhport, uint8_t interface_id) +{ + (void)interface_id; + usbtmcd_start_bus_read(rhport); +} + + bool tud_usbtmc_app_msg_trigger_cb(uint8_t rhport, usbtmc_msg_generic_t* msg) { (void)rhport; (void)msg; @@ -149,6 +156,7 @@ bool tud_usbtmc_app_msg_data_cb(uint8_t rhport, void *data, size_t len, bool tra d=0; resp_delay = (uint32_t)d; } + usbtmcd_start_bus_read(rhport); return true; } @@ -162,6 +170,7 @@ bool tud_usbtmc_app_msgBulkIn_complete_cb(uint8_t rhport) bulkInStarted = 0; buffer_tx_ix = 0; } + usbtmcd_start_bus_read(rhport); return true; } @@ -259,6 +268,8 @@ bool tud_usbtmc_app_check_clear_cb(uint8_t rhport, usbtmc_get_clear_status_rsp_t queryState = 0; bulkInStarted = false; status = 0; + buffer_tx_ix = 0u; + buffer_len = 0u; rsp->USBTMC_status = USBTMC_STATUS_SUCCESS; rsp->bmClear.BulkInFifoBytes = 0u; return true; @@ -274,6 +285,7 @@ bool tud_usbtmc_app_check_abort_bulk_in_cb(uint8_t rhport, usbtmc_check_abort_bu { (void)rhport; (void)rsp; + usbtmcd_start_bus_read(rhport); return true; } @@ -288,6 +300,7 @@ bool tud_usbtmc_app_check_abort_bulk_out_cb(uint8_t rhport, usbtmc_check_abort_b { (void)rhport; (void)rsp; + usbtmcd_start_bus_read(rhport); return true; } @@ -298,6 +311,7 @@ void usmtmcd_app_bulkIn_clearFeature_cb(uint8_t rhport) void usmtmcd_app_bulkOut_clearFeature_cb(uint8_t rhport) { (void)rhport; + usbtmcd_start_bus_read(rhport); } // Return status byte, but put the transfer result status code in the rspResult argument. @@ -313,7 +327,7 @@ uint8_t tud_usbtmc_app_get_stb_cb(uint8_t rhport, uint8_t *tmcResult) return old_status; } -bool tud_usbtmc_app_indicator_pluse_cb(uint8_t rhport, tusb_control_request_t const * msg, uint8_t *tmcResult) +bool tud_usbtmc_app_indicator_pulse_cb(uint8_t rhport, tusb_control_request_t const * msg, uint8_t *tmcResult) { (void)rhport; (void)msg; diff --git a/src/class/usbtmc/usbtmc_device.c b/src/class/usbtmc/usbtmc_device.c index e3d2c316e..401b4acc4 100644 --- a/src/class/usbtmc/usbtmc_device.c +++ b/src/class/usbtmc/usbtmc_device.c @@ -99,9 +99,10 @@ static char logMsg[150]; typedef enum { - STATE_CLOSED, - STATE_IDLE, - STATE_RCV, + STATE_CLOSED, // Endpoints have not yet been opened since USB reset + STATE_NAK, // Bulk-out endpoint is in NAK state. + STATE_IDLE, // Bulk-out endpoint is waiting for CMD. + STATE_RCV, // Bulk-out is receiving DEV_DEP message STATE_TX_REQUESTED, STATE_TX_INITIATED, STATE_TX_SHORTED, @@ -243,7 +244,7 @@ void usbtmcd_init_cb(void) TU_ASSERT(!tud_usbtmc_app_capabilities.bmIntfcCapabilities.talkOnly,); # endif if(tud_usbtmc_app_capabilities.bmIntfcCapabilities.supportsIndicatorPulse) - TU_ASSERT(&tud_usbtmc_app_indicator_pluse_cb != NULL,); + TU_ASSERT(&tud_usbtmc_app_indicator_pulse_cb != NULL,); #endif usbtmcLock = osal_mutex_create(&usbtmcLockBuffer); @@ -322,11 +323,37 @@ bool usbtmcd_open_cb(uint8_t rhport, tusb_desc_interface_t const * itf_desc, uin } #endif #endif - usbtmc_state.state = STATE_IDLE; - TU_VERIFY( usbd_edpt_xfer(rhport, usbtmc_state.ep_bulk_out, usbtmc_state.ep_bulk_out_buf, 64)); + atomicChangeState(STATE_CLOSED, STATE_NAK); + tud_usbtmc_app_open_cb(rhport, itf_desc->iInterface); return true; } +// Tell USBTMC class to set its bulk-in EP to ACK so that it can +// receive USBTMC commands. +// Returns false if it was already in an ACK state or is busy +// processing a command (such as a clear). Returns true if it was +// in the NAK state and successfully transitioned to the ACK wait +// state. +bool usbtmcd_start_bus_read(uint8_t rhport) +{ + usbtmcd_state_enum oldState = usbtmc_state.state; + switch(oldState) + { + // These may transition to IDLE + case STATE_NAK: + case STATE_ABORTING_BULK_IN_ABORTED: + TU_VERIFY(atomicChangeState(oldState, STATE_IDLE)); + break; + // When receiving, let it remain receiving + case STATE_RCV: + break; + default: + TU_VERIFY(false); + } + TU_VERIFY(usbd_edpt_xfer(rhport, usbtmc_state.ep_bulk_out, usbtmc_state.ep_bulk_out_buf, 64)); + return true; +} + void usbtmcd_reset_cb(uint8_t rhport) { (void)rhport; @@ -367,19 +394,21 @@ static bool handle_devMsgOut(uint8_t rhport, void *data, size_t len, size_t pack if(len >= usbtmc_state.transfer_size_remaining || shortPacket) { atEnd = true; + TU_VERIFY(atomicChangeState(STATE_RCV, STATE_NAK)); } len = tu_min32(len, usbtmc_state.transfer_size_remaining); + usbtmc_state.transfer_size_remaining -= len; + usbtmc_state.transfer_size_sent += len; + + // App may (should?) call the wait_for_bus() command at this point if(!tud_usbtmc_app_msg_data_cb(rhport,data, len, atEnd)) { // TODO: Go to an error state upon failure other than just stalling the EP? return false; } - usbtmc_state.transfer_size_remaining -= len; - usbtmc_state.transfer_size_sent += len; - TU_VERIFY(atomicChangeState(STATE_RCV, atEnd ? STATE_IDLE : STATE_RCV)); return true; } @@ -453,7 +482,6 @@ bool usbtmcd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint TU_VERIFY(false); return false; } - TU_VERIFY(usbd_edpt_xfer(rhport, usbtmc_state.ep_bulk_out, usbtmc_state.ep_bulk_out_buf, USBTMCD_MAX_PACKET_SIZE)); return true; case STATE_RCV: @@ -462,7 +490,6 @@ bool usbtmcd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint usbd_edpt_stall(rhport, usbtmc_state.ep_bulk_out); TU_VERIFY(false); } - TU_VERIFY(usbd_edpt_xfer(rhport, usbtmc_state.ep_bulk_out, usbtmc_state.ep_bulk_out_buf, USBTMCD_MAX_PACKET_SIZE)); return true; case STATE_ABORTING_BULK_OUT: @@ -482,8 +509,7 @@ bool usbtmcd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint { switch(usbtmc_state.state) { case STATE_TX_SHORTED: - - usbtmc_state.state = STATE_IDLE; + TU_VERIFY(atomicChangeState(STATE_TX_SHORTED, STATE_NAK)); TU_VERIFY(tud_usbtmc_app_msgBulkIn_complete_cb(rhport)); break; @@ -508,7 +534,7 @@ bool usbtmcd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint if(((packetLen % USBTMCD_MAX_PACKET_SIZE) != 0) || (packetLen == 0 )) { usbtmc_state.state = STATE_TX_SHORTED; - } + } } return true; case STATE_ABORTING_BULK_IN: @@ -548,9 +574,10 @@ bool usbtmcd_control_request_cb(uint8_t rhport, tusb_control_request_t const * r if(ep_addr == usbtmc_state.ep_bulk_out) { + criticalEnter(); + usbtmc_state.state = STATE_NAK; // USBD core has placed EP in NAK state for us + criticalLeave(); usmtmcd_app_bulkOut_clearFeature_cb(rhport); - // And start a new OUT xfer request now that things are clear - TU_ASSERT( usbd_edpt_xfer(rhport, usbtmc_state.ep_bulk_out, usbtmc_state.ep_bulk_out_buf, 64)); } else if (ep_addr == usbtmc_state.ep_bulk_in) { @@ -605,6 +632,7 @@ bool usbtmcd_control_request_cb(uint8_t rhport, tusb_control_request_t const * r TU_VERIFY(tud_control_xfer(rhport, request, (void*)&rsp,sizeof(rsp))); return true; } + case USBTMC_bREQUEST_CHECK_ABORT_BULK_OUT_STATUS: { usbtmc_check_abort_bulk_rsp_t rsp = { @@ -750,7 +778,7 @@ bool usbtmcd_control_request_cb(uint8_t rhport, tusb_control_request_t const * r TU_VERIFY(request->bmRequestType == 0xA1); // in,class,interface TU_VERIFY(request->wLength == sizeof(tmcStatusCode)); TU_VERIFY(tud_usbtmc_app_capabilities.bmIntfcCapabilities.supportsIndicatorPulse); - TU_VERIFY(tud_usbtmc_app_indicator_pluse_cb(rhport, request, &tmcStatusCode)); + TU_VERIFY(tud_usbtmc_app_indicator_pulse_cb(rhport, request, &tmcStatusCode)); TU_VERIFY(tud_control_xfer(rhport, request, (void*)&tmcStatusCode, sizeof(tmcStatusCode))); return true; } diff --git a/src/class/usbtmc/usbtmc_device.h b/src/class/usbtmc/usbtmc_device.h index d33d73905..3638b5527 100644 --- a/src/class/usbtmc/usbtmc_device.h +++ b/src/class/usbtmc/usbtmc_device.h @@ -55,6 +55,17 @@ extern usbtmc_response_capabilities_488_t const tud_usbtmc_app_capabilities; extern usbtmc_response_capabilities_t const tud_usbtmc_app_capabilities; #endif +// In order to proceed, app must call call usbtmcd_start_bus_read(rhport) during or soon after: +// * tud_usbtmc_app_open_cb +// * tud_usbtmc_app_msg_data_cb +// * tud_usbtmc_app_msgBulkIn_complete_cb +// * tud_usbtmc_app_msg_trigger_cb +// * (successful) tud_usbtmc_app_check_abort_bulk_out_cb +// * (successful) tud_usbtmc_app_check_abort_bulk_in_cb +// * (successful) usmtmcd_app_bulkOut_clearFeature_cb + +void tud_usbtmc_app_open_cb(uint8_t rhport, uint8_t interface_id); + bool tud_usbtmc_app_msgBulkOut_start_cb(uint8_t rhport, usbtmc_msg_request_dev_dep_out const * msgHeader); // transfer_complete does not imply that a message is complete. bool tud_usbtmc_app_msg_data_cb(uint8_t rhport, void *data, size_t len, bool transfer_complete); @@ -73,7 +84,7 @@ bool tud_usbtmc_app_check_abort_bulk_out_cb(uint8_t rhport, usbtmc_check_abort_b bool tud_usbtmc_app_check_clear_cb(uint8_t rhport, usbtmc_get_clear_status_rsp_t *rsp); // Indicator pulse should be 0.5 to 1.0 seconds long -TU_ATTR_WEAK bool tud_usbtmc_app_indicator_pluse_cb(uint8_t rhport, tusb_control_request_t const * msg, uint8_t *tmcResult); +TU_ATTR_WEAK bool tud_usbtmc_app_indicator_pulse_cb(uint8_t rhport, tusb_control_request_t const * msg, uint8_t *tmcResult); #if (CFG_USBTMC_CFG_ENABLE_488) uint8_t tud_usbtmc_app_get_stb_cb(uint8_t rhport, uint8_t *tmcResult); @@ -93,6 +104,8 @@ bool usbtmcd_transmit_dev_msg_data( const void * data, size_t len, bool endOfMessage, bool usingTermChar); +bool usbtmcd_start_bus_read(uint8_t rhport); + /* "callbacks" from USB device core */ -- cgit v1.3.1 From 624f4bf4ceaf1cd334326ccb3777efa2c954de1b Mon Sep 17 00:00:00 2001 From: Nathan Conrad Date: Tue, 24 Sep 2019 13:42:29 -0400 Subject: Remove rhport from app code. If anything, it should be the interface_id. Assume a single interface, for now. --- examples/device/usbtmc/src/usbtmc_app.c | 68 ++++++++++++--------------------- src/class/usbtmc/usbtmc_device.c | 41 ++++++++++---------- src/class/usbtmc/usbtmc_device.h | 37 +++++++++--------- 3 files changed, 64 insertions(+), 82 deletions(-) (limited to 'src') diff --git a/examples/device/usbtmc/src/usbtmc_app.c b/examples/device/usbtmc/src/usbtmc_app.c index 2982675b1..b622d6b9b 100644 --- a/examples/device/usbtmc/src/usbtmc_app.c +++ b/examples/device/usbtmc/src/usbtmc_app.c @@ -96,24 +96,22 @@ static usbtmc_msg_dev_dep_msg_in_header_t rspMsg = { } }; -void tud_usbtmc_app_open_cb(uint8_t rhport, uint8_t interface_id) +void tud_usbtmc_app_open_cb(uint8_t interface_id) { (void)interface_id; - usbtmcd_start_bus_read(rhport); + usbtmcd_start_bus_read(); } -bool tud_usbtmc_app_msg_trigger_cb(uint8_t rhport, usbtmc_msg_generic_t* msg) { - (void)rhport; +bool tud_usbtmc_app_msg_trigger_cb(usbtmc_msg_generic_t* msg) { (void)msg; // Let trigger set the SRQ status |= IEEE4882_STB_SRQ; return true; } -bool tud_usbtmc_app_msgBulkOut_start_cb(uint8_t rhport, usbtmc_msg_request_dev_dep_out const * msgHeader) +bool tud_usbtmc_app_msgBulkOut_start_cb(usbtmc_msg_request_dev_dep_out const * msgHeader) { - (void)rhport; (void)msgHeader; buffer_len = 0; if(msgHeader->TransferSize > sizeof(buffer)) @@ -124,10 +122,8 @@ bool tud_usbtmc_app_msgBulkOut_start_cb(uint8_t rhport, usbtmc_msg_request_dev_d return true; } -bool tud_usbtmc_app_msg_data_cb(uint8_t rhport, void *data, size_t len, bool transfer_complete) +bool tud_usbtmc_app_msg_data_cb(void *data, size_t len, bool transfer_complete) { - (void)rhport; - // If transfer isn't finished, we just ignore it (for now) if(len + buffer_len < sizeof(buffer)) @@ -156,13 +152,12 @@ bool tud_usbtmc_app_msg_data_cb(uint8_t rhport, void *data, size_t len, bool tra d=0; resp_delay = (uint32_t)d; } - usbtmcd_start_bus_read(rhport); + usbtmcd_start_bus_read(); return true; } -bool tud_usbtmc_app_msgBulkIn_complete_cb(uint8_t rhport) +bool tud_usbtmc_app_msgBulkIn_complete_cb() { - (void)rhport; if((buffer_tx_ix == buffer_len) || idnQuery) // done { status &= (uint8_t)~(IEEE4882_STB_MAV); // clear MAV @@ -170,17 +165,15 @@ bool tud_usbtmc_app_msgBulkIn_complete_cb(uint8_t rhport) bulkInStarted = 0; buffer_tx_ix = 0; } - usbtmcd_start_bus_read(rhport); + usbtmcd_start_bus_read(); return true; } static unsigned int msgReqLen; -bool tud_usbtmc_app_msgBulkIn_request_cb(uint8_t rhport, usbtmc_msg_request_dev_dep_in const * request) +bool tud_usbtmc_app_msgBulkIn_request_cb(usbtmc_msg_request_dev_dep_in const * request) { - (void)rhport; - rspMsg.header.MsgID = request->header.MsgID, rspMsg.header.bTag = request->header.bTag, rspMsg.header.bTagInverse = request->header.bTagInverse; @@ -200,7 +193,7 @@ bool tud_usbtmc_app_msgBulkIn_request_cb(uint8_t rhport, usbtmc_msg_request_dev_ else { size_t txlen = tu_min32(buffer_len-buffer_tx_ix,msgReqLen); - usbtmcd_transmit_dev_msg_data(rhport, &buffer[buffer_tx_ix], txlen, + usbtmcd_transmit_dev_msg_data(&buffer[buffer_tx_ix], txlen, (buffer_tx_ix+txlen) == buffer_len, false); buffer_tx_ix += txlen; } @@ -209,7 +202,6 @@ bool tud_usbtmc_app_msgBulkIn_request_cb(uint8_t rhport, usbtmc_msg_request_dev_ } void usbtmc_app_task_iter(void) { - uint8_t const rhport = 0; switch(queryState) { case 0: break; @@ -234,14 +226,14 @@ void usbtmc_app_task_iter(void) { if(bulkInStarted && (buffer_tx_ix == 0)) { if(idnQuery) { - usbtmcd_transmit_dev_msg_data(rhport, idn, tu_min32(sizeof(idn)-1,msgReqLen),true,false); + usbtmcd_transmit_dev_msg_data(idn, tu_min32(sizeof(idn)-1,msgReqLen),true,false); queryState = 0; bulkInStarted = 0; } else { buffer_tx_ix = tu_min32(buffer_len,msgReqLen); - usbtmcd_transmit_dev_msg_data(rhport, buffer, buffer_tx_ix, buffer_tx_ix == buffer_len, false); + usbtmcd_transmit_dev_msg_data(buffer, buffer_tx_ix, buffer_tx_ix == buffer_len, false); } // MAV is cleared in the transfer complete callback. } @@ -252,9 +244,8 @@ void usbtmc_app_task_iter(void) { } } -bool tud_usbtmc_app_initiate_clear_cb(uint8_t rhport, uint8_t *tmcResult) +bool tud_usbtmc_app_initiate_clear_cb(uint8_t *tmcResult) { - (void)rhport; *tmcResult = USBTMC_STATUS_SUCCESS; queryState = 0; bulkInStarted = false; @@ -262,9 +253,8 @@ bool tud_usbtmc_app_initiate_clear_cb(uint8_t rhport, uint8_t *tmcResult) return true; } -bool tud_usbtmc_app_check_clear_cb(uint8_t rhport, usbtmc_get_clear_status_rsp_t *rsp) +bool tud_usbtmc_app_check_clear_cb(usbtmc_get_clear_status_rsp_t *rsp) { - (void)rhport; queryState = 0; bulkInStarted = false; status = 0; @@ -274,50 +264,43 @@ bool tud_usbtmc_app_check_clear_cb(uint8_t rhport, usbtmc_get_clear_status_rsp_t rsp->bmClear.BulkInFifoBytes = 0u; return true; } -bool tud_usbtmc_app_initiate_abort_bulk_in_cb(uint8_t rhport, uint8_t *tmcResult) +bool tud_usbtmc_app_initiate_abort_bulk_in_cb(uint8_t *tmcResult) { - (void)rhport; bulkInStarted = 0; *tmcResult = USBTMC_STATUS_SUCCESS; return true; } -bool tud_usbtmc_app_check_abort_bulk_in_cb(uint8_t rhport, usbtmc_check_abort_bulk_rsp_t *rsp) +bool tud_usbtmc_app_check_abort_bulk_in_cb(usbtmc_check_abort_bulk_rsp_t *rsp) { - (void)rhport; (void)rsp; - usbtmcd_start_bus_read(rhport); + usbtmcd_start_bus_read(); return true; } -bool tud_usbtmc_app_initiate_abort_bulk_out_cb(uint8_t rhport, uint8_t *tmcResult) +bool tud_usbtmc_app_initiate_abort_bulk_out_cb(uint8_t *tmcResult) { - (void)rhport; *tmcResult = USBTMC_STATUS_SUCCESS; return true; } -bool tud_usbtmc_app_check_abort_bulk_out_cb(uint8_t rhport, usbtmc_check_abort_bulk_rsp_t *rsp) +bool tud_usbtmc_app_check_abort_bulk_out_cb(usbtmc_check_abort_bulk_rsp_t *rsp) { - (void)rhport; (void)rsp; - usbtmcd_start_bus_read(rhport); + usbtmcd_start_bus_read(); return true; } -void usmtmcd_app_bulkIn_clearFeature_cb(uint8_t rhport) +void usmtmcd_app_bulkIn_clearFeature_cb(void) { - (void)rhport; } -void usmtmcd_app_bulkOut_clearFeature_cb(uint8_t rhport) +void usmtmcd_app_bulkOut_clearFeature_cb(void) { - (void)rhport; - usbtmcd_start_bus_read(rhport); + usbtmcd_start_bus_read(); } // Return status byte, but put the transfer result status code in the rspResult argument. -uint8_t tud_usbtmc_app_get_stb_cb(uint8_t rhport, uint8_t *tmcResult) +uint8_t tud_usbtmc_app_get_stb_cb(uint8_t *tmcResult) { - (void)rhport; uint8_t old_status = status; status = (uint8_t)(status & ~(IEEE4882_STB_SRQ)); // clear SRQ @@ -327,9 +310,8 @@ uint8_t tud_usbtmc_app_get_stb_cb(uint8_t rhport, uint8_t *tmcResult) return old_status; } -bool tud_usbtmc_app_indicator_pulse_cb(uint8_t rhport, tusb_control_request_t const * msg, uint8_t *tmcResult) +bool tud_usbtmc_app_indicator_pulse_cb(tusb_control_request_t const * msg, uint8_t *tmcResult) { - (void)rhport; (void)msg; led_indicator_pulse(); *tmcResult = USBTMC_STATUS_SUCCESS; diff --git a/src/class/usbtmc/usbtmc_device.c b/src/class/usbtmc/usbtmc_device.c index 401b4acc4..a65c5e7c4 100644 --- a/src/class/usbtmc/usbtmc_device.c +++ b/src/class/usbtmc/usbtmc_device.c @@ -119,6 +119,7 @@ typedef struct volatile usbtmcd_state_enum state; uint8_t itf_id; + uint8_t rhport; uint8_t ep_bulk_in; uint8_t ep_bulk_out; uint8_t ep_int_in; @@ -186,7 +187,6 @@ bool atomicChangeState(usbtmcd_state_enum expectedState, usbtmcd_state_enum newS // We can't just send the whole thing at once because we need to concatanate the // header with the data. bool usbtmcd_transmit_dev_msg_data( - uint8_t rhport, const void * data, size_t len, bool endOfMessage, bool usingTermChar) @@ -229,7 +229,7 @@ bool usbtmcd_transmit_dev_msg_data( bool stateChanged = atomicChangeState(STATE_TX_REQUESTED, (packetLen >= txBufLen) ? STATE_TX_INITIATED : STATE_TX_SHORTED); TU_VERIFY(stateChanged); - TU_VERIFY(usbd_edpt_xfer(rhport, usbtmc_state.ep_bulk_in, usbtmc_state.ep_bulk_in_buf, (uint16_t)packetLen)); + TU_VERIFY(usbd_edpt_xfer(usbtmc_state.rhport, usbtmc_state.ep_bulk_in, usbtmc_state.ep_bulk_in_buf, (uint16_t)packetLen)); return true; } @@ -269,6 +269,7 @@ bool usbtmcd_open_cb(uint8_t rhport, tusb_desc_interface_t const * itf_desc, uin p_desc = (uint8_t const *) itf_desc; usbtmc_state.itf_id = itf_desc->bInterfaceNumber; + usbtmc_state.rhport = rhport; while (found_endpoints < itf_desc->bNumEndpoints) { @@ -324,7 +325,7 @@ bool usbtmcd_open_cb(uint8_t rhport, tusb_desc_interface_t const * itf_desc, uin #endif #endif atomicChangeState(STATE_CLOSED, STATE_NAK); - tud_usbtmc_app_open_cb(rhport, itf_desc->iInterface); + tud_usbtmc_app_open_cb(itf_desc->iInterface); return true; } @@ -334,7 +335,7 @@ bool usbtmcd_open_cb(uint8_t rhport, tusb_desc_interface_t const * itf_desc, uin // processing a command (such as a clear). Returns true if it was // in the NAK state and successfully transitioned to the ACK wait // state. -bool usbtmcd_start_bus_read(uint8_t rhport) +bool usbtmcd_start_bus_read() { usbtmcd_state_enum oldState = usbtmc_state.state; switch(oldState) @@ -350,7 +351,7 @@ bool usbtmcd_start_bus_read(uint8_t rhport) default: TU_VERIFY(false); } - TU_VERIFY(usbd_edpt_xfer(rhport, usbtmc_state.ep_bulk_out, usbtmc_state.ep_bulk_out_buf, 64)); + TU_VERIFY(usbd_edpt_xfer(usbtmc_state.rhport, usbtmc_state.ep_bulk_out, usbtmc_state.ep_bulk_out_buf, 64)); return true; } @@ -374,7 +375,7 @@ static bool handle_devMsgOutStart(uint8_t rhport, void *data, size_t len) // must be a header, should have been confirmed before calling here. usbtmc_msg_request_dev_dep_out *msg = (usbtmc_msg_request_dev_dep_out*)data; usbtmc_state.transfer_size_remaining = msg->TransferSize; - TU_VERIFY(tud_usbtmc_app_msgBulkOut_start_cb(rhport,msg)); + TU_VERIFY(tud_usbtmc_app_msgBulkOut_start_cb(msg)); TU_VERIFY(handle_devMsgOut(rhport, (uint8_t*)data + sizeof(*msg), len - sizeof(*msg), len)); usbtmc_state.lastBulkOutTag = msg->header.bTag; @@ -403,7 +404,7 @@ static bool handle_devMsgOut(uint8_t rhport, void *data, size_t len, size_t pack usbtmc_state.transfer_size_sent += len; // App may (should?) call the wait_for_bus() command at this point - if(!tud_usbtmc_app_msg_data_cb(rhport,data, len, atEnd)) + if(!tud_usbtmc_app_msg_data_cb(data, len, atEnd)) { // TODO: Go to an error state upon failure other than just stalling the EP? return false; @@ -413,7 +414,7 @@ static bool handle_devMsgOut(uint8_t rhport, void *data, size_t len, size_t pack return true; } -static bool handle_devMsgIn(uint8_t rhport, void *data, size_t len) +static bool handle_devMsgIn(void *data, size_t len) { TU_VERIFY(len == sizeof(usbtmc_msg_request_dev_dep_in)); usbtmc_msg_request_dev_dep_in *msg = (usbtmc_msg_request_dev_dep_in*)data; @@ -429,7 +430,7 @@ static bool handle_devMsgIn(uint8_t rhport, void *data, size_t len) if(termCharRequested) TU_VERIFY(tud_usbtmc_app_capabilities.bmDevCapabilities.canEndBulkInOnTermChar); - TU_VERIFY(tud_usbtmc_app_msgBulkIn_request_cb(rhport, msg)); + TU_VERIFY(tud_usbtmc_app_msgBulkIn_request_cb(msg)); return true; } @@ -464,14 +465,14 @@ bool usbtmcd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint break; case USBTMC_MSGID_DEV_DEP_MSG_IN: - TU_VERIFY(handle_devMsgIn(rhport, msg, xferred_bytes)); + TU_VERIFY(handle_devMsgIn(msg, xferred_bytes)); break; #if (CFG_USBTMC_CFG_ENABLE_488) case USBTMC_MSGID_USB488_TRIGGER: // Spec says we halt the EP if we didn't declare we support it. TU_VERIFY(tud_usbtmc_app_capabilities.bmIntfcCapabilities488.supportsTrigger); - TU_VERIFY(tud_usbtmc_app_msg_trigger_cb(rhport, msg)); + TU_VERIFY(tud_usbtmc_app_msg_trigger_cb(msg)); break; #endif @@ -626,7 +627,7 @@ bool usbtmcd_control_request_cb(uint8_t rhport, tusb_control_request_t const * r criticalEnter(); usbtmc_state.state = STATE_ABORTING_BULK_OUT; criticalLeave(); - TU_VERIFY(tud_usbtmc_app_initiate_abort_bulk_out_cb(rhport, &(rsp.USBTMC_status))); + TU_VERIFY(tud_usbtmc_app_initiate_abort_bulk_out_cb(&(rsp.USBTMC_status))); usbd_edpt_stall(rhport, usbtmc_state.ep_bulk_out); } TU_VERIFY(tud_control_xfer(rhport, request, (void*)&rsp,sizeof(rsp))); @@ -642,7 +643,7 @@ bool usbtmcd_control_request_cb(uint8_t rhport, tusb_control_request_t const * r TU_VERIFY(request->bmRequestType == 0xA2); // in,class,EP TU_VERIFY(request->wLength == sizeof(rsp)); TU_VERIFY(request->wIndex == usbtmc_state.ep_bulk_out); - TU_VERIFY(tud_usbtmc_app_check_abort_bulk_out_cb(rhport, &rsp)); + TU_VERIFY(tud_usbtmc_app_check_abort_bulk_out_cb(&rsp)); TU_VERIFY(usbd_edpt_xfer(rhport, 0u, (void*)&rsp,sizeof(rsp))); return true; } @@ -672,7 +673,7 @@ bool usbtmcd_control_request_cb(uint8_t rhport, tusb_control_request_t const * r TU_VERIFY( usbd_edpt_xfer(rhport, usbtmc_state.ep_bulk_in, usbtmc_state.ep_bulk_in_buf,(uint16_t)0u)); usbtmc_state.state = STATE_ABORTING_BULK_IN_SHORTED; } - TU_VERIFY(tud_usbtmc_app_initiate_abort_bulk_in_cb(rhport, &(rsp.USBTMC_status))); + TU_VERIFY(tud_usbtmc_app_initiate_abort_bulk_in_cb(&(rsp.USBTMC_status))); } else if((usbtmc_state.state == STATE_TX_REQUESTED || usbtmc_state.state == STATE_TX_INITIATED)) { // FIXME: Unsure how to check if the OUT endpoint fifo is non-empty.... @@ -700,7 +701,7 @@ bool usbtmcd_control_request_cb(uint8_t rhport, tusb_control_request_t const * r }, .NBYTES_RXD_TXD = usbtmc_state.transfer_size_sent, }; - TU_VERIFY(tud_usbtmc_app_check_abort_bulk_in_cb(rhport, &rsp)); + TU_VERIFY(tud_usbtmc_app_check_abort_bulk_in_cb(&rsp)); criticalEnter(); switch(usbtmc_state.state) { @@ -732,7 +733,7 @@ bool usbtmcd_control_request_cb(uint8_t rhport, tusb_control_request_t const * r criticalEnter(); usbtmc_state.state = STATE_CLEARING; criticalLeave(); - TU_VERIFY(tud_usbtmc_app_initiate_clear_cb(rhport, &tmcStatusCode)); + TU_VERIFY(tud_usbtmc_app_initiate_clear_cb(&tmcStatusCode)); TU_VERIFY(tud_control_xfer(rhport, request, (void*)&tmcStatusCode,sizeof(tmcStatusCode))); return true; } @@ -752,7 +753,7 @@ bool usbtmcd_control_request_cb(uint8_t rhport, tusb_control_request_t const * r else { // Let app check if it's clear - TU_VERIFY(tud_usbtmc_app_check_clear_cb(rhport, &clearStatusRsp)); + TU_VERIFY(tud_usbtmc_app_check_clear_cb(&clearStatusRsp)); } if(clearStatusRsp.USBTMC_status == USBTMC_STATUS_SUCCESS) { @@ -778,7 +779,7 @@ bool usbtmcd_control_request_cb(uint8_t rhport, tusb_control_request_t const * r TU_VERIFY(request->bmRequestType == 0xA1); // in,class,interface TU_VERIFY(request->wLength == sizeof(tmcStatusCode)); TU_VERIFY(tud_usbtmc_app_capabilities.bmIntfcCapabilities.supportsIndicatorPulse); - TU_VERIFY(tud_usbtmc_app_indicator_pulse_cb(rhport, request, &tmcStatusCode)); + TU_VERIFY(tud_usbtmc_app_indicator_pulse_cb(request, &tmcStatusCode)); TU_VERIFY(tud_control_xfer(rhport, request, (void*)&tmcStatusCode, sizeof(tmcStatusCode))); return true; } @@ -809,13 +810,13 @@ bool usbtmcd_control_request_cb(uint8_t rhport, tusb_control_request_t const * r .one = 1, .bTag = bTag & 0x7Fu, }, - .StatusByte = tud_usbtmc_app_get_stb_cb(rhport, &(rsp.USBTMC_status)) + .StatusByte = tud_usbtmc_app_get_stb_cb(&(rsp.USBTMC_status)) }; usbd_edpt_xfer(rhport, usbtmc_state.ep_int_in, (void*)&intMsg, sizeof(intMsg)); } else { - rsp.statusByte = tud_usbtmc_app_get_stb_cb(rhport, &(rsp.USBTMC_status)); + rsp.statusByte = tud_usbtmc_app_get_stb_cb(&(rsp.USBTMC_status)); } TU_VERIFY(tud_control_xfer(rhport, request, (void*)&rsp, sizeof(rsp))); return true; diff --git a/src/class/usbtmc/usbtmc_device.h b/src/class/usbtmc/usbtmc_device.h index 3638b5527..9f88e5e83 100644 --- a/src/class/usbtmc/usbtmc_device.h +++ b/src/class/usbtmc/usbtmc_device.h @@ -64,32 +64,32 @@ extern usbtmc_response_capabilities_t const tud_usbtmc_app_capabilities; // * (successful) tud_usbtmc_app_check_abort_bulk_in_cb // * (successful) usmtmcd_app_bulkOut_clearFeature_cb -void tud_usbtmc_app_open_cb(uint8_t rhport, uint8_t interface_id); +void tud_usbtmc_app_open_cb(uint8_t interface_id); -bool tud_usbtmc_app_msgBulkOut_start_cb(uint8_t rhport, usbtmc_msg_request_dev_dep_out const * msgHeader); +bool tud_usbtmc_app_msgBulkOut_start_cb(usbtmc_msg_request_dev_dep_out const * msgHeader); // transfer_complete does not imply that a message is complete. -bool tud_usbtmc_app_msg_data_cb(uint8_t rhport, void *data, size_t len, bool transfer_complete); -void usmtmcd_app_bulkOut_clearFeature_cb(uint8_t rhport); // Notice to clear and abort the pending BULK out transfer +bool tud_usbtmc_app_msg_data_cb( void *data, size_t len, bool transfer_complete); +void usmtmcd_app_bulkOut_clearFeature_cb(); // Notice to clear and abort the pending BULK out transfer -bool tud_usbtmc_app_msgBulkIn_request_cb(uint8_t rhport, usbtmc_msg_request_dev_dep_in const * request); -bool tud_usbtmc_app_msgBulkIn_complete_cb(uint8_t rhport); -void usmtmcd_app_bulkIn_clearFeature_cb(uint8_t rhport); // Notice to clear and abort the pending BULK out transfer +bool tud_usbtmc_app_msgBulkIn_request_cb(usbtmc_msg_request_dev_dep_in const * request); +bool tud_usbtmc_app_msgBulkIn_complete_cb(); +void usmtmcd_app_bulkIn_clearFeature_cb(); // Notice to clear and abort the pending BULK out transfer -bool tud_usbtmc_app_initiate_abort_bulk_in_cb(uint8_t rhport, uint8_t *tmcResult); -bool tud_usbtmc_app_initiate_abort_bulk_out_cb(uint8_t rhport, uint8_t *tmcResult); -bool tud_usbtmc_app_initiate_clear_cb(uint8_t rhport, uint8_t *tmcResult); +bool tud_usbtmc_app_initiate_abort_bulk_in_cb(uint8_t *tmcResult); +bool tud_usbtmc_app_initiate_abort_bulk_out_cb(uint8_t *tmcResult); +bool tud_usbtmc_app_initiate_clear_cb(uint8_t *tmcResult); -bool tud_usbtmc_app_check_abort_bulk_in_cb(uint8_t rhport, usbtmc_check_abort_bulk_rsp_t *rsp); -bool tud_usbtmc_app_check_abort_bulk_out_cb(uint8_t rhport, usbtmc_check_abort_bulk_rsp_t *rsp); -bool tud_usbtmc_app_check_clear_cb(uint8_t rhport, usbtmc_get_clear_status_rsp_t *rsp); +bool tud_usbtmc_app_check_abort_bulk_in_cb(usbtmc_check_abort_bulk_rsp_t *rsp); +bool tud_usbtmc_app_check_abort_bulk_out_cb(usbtmc_check_abort_bulk_rsp_t *rsp); +bool tud_usbtmc_app_check_clear_cb(usbtmc_get_clear_status_rsp_t *rsp); // Indicator pulse should be 0.5 to 1.0 seconds long -TU_ATTR_WEAK bool tud_usbtmc_app_indicator_pulse_cb(uint8_t rhport, tusb_control_request_t const * msg, uint8_t *tmcResult); +TU_ATTR_WEAK bool tud_usbtmc_app_indicator_pulse_cb(tusb_control_request_t const * msg, uint8_t *tmcResult); #if (CFG_USBTMC_CFG_ENABLE_488) -uint8_t tud_usbtmc_app_get_stb_cb(uint8_t rhport, uint8_t *tmcResult); -TU_ATTR_WEAK bool tud_usbtmc_app_msg_trigger_cb(uint8_t rhport, usbtmc_msg_generic_t* msg); -//TU_ATTR_WEAK bool tud_usbtmc_app_go_to_local_cb(uint8_t rhport); +uint8_t tud_usbtmc_app_get_stb_cb(uint8_t *tmcResult); +TU_ATTR_WEAK bool tud_usbtmc_app_msg_trigger_cb(usbtmc_msg_generic_t* msg); +//TU_ATTR_WEAK bool tud_usbtmc_app_go_to_local_cb(); #endif /******************************************* @@ -100,11 +100,10 @@ TU_ATTR_WEAK bool tud_usbtmc_app_msg_trigger_cb(uint8_t rhport, usbtmc_msg_gener ******************************************/ bool usbtmcd_transmit_dev_msg_data( - uint8_t rhport, const void * data, size_t len, bool endOfMessage, bool usingTermChar); -bool usbtmcd_start_bus_read(uint8_t rhport); +bool usbtmcd_start_bus_read(); /* "callbacks" from USB device core */ -- cgit v1.3.1 From 412a279073b77c6f5d3b6796089eb90509322a7a Mon Sep 17 00:00:00 2001 From: Nathan Conrad Date: Tue, 24 Sep 2019 13:54:45 -0400 Subject: I never understood why I need to write void as empty function arguments. --- src/class/usbtmc/usbtmc_device.c | 6 +++--- src/class/usbtmc/usbtmc_device.h | 8 ++++---- 2 files changed, 7 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/class/usbtmc/usbtmc_device.c b/src/class/usbtmc/usbtmc_device.c index a65c5e7c4..dad892f43 100644 --- a/src/class/usbtmc/usbtmc_device.c +++ b/src/class/usbtmc/usbtmc_device.c @@ -511,7 +511,7 @@ bool usbtmcd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint switch(usbtmc_state.state) { case STATE_TX_SHORTED: TU_VERIFY(atomicChangeState(STATE_TX_SHORTED, STATE_NAK)); - TU_VERIFY(tud_usbtmc_app_msgBulkIn_complete_cb(rhport)); + TU_VERIFY(tud_usbtmc_app_msgBulkIn_complete_cb()); break; case STATE_TX_INITIATED: @@ -578,11 +578,11 @@ bool usbtmcd_control_request_cb(uint8_t rhport, tusb_control_request_t const * r criticalEnter(); usbtmc_state.state = STATE_NAK; // USBD core has placed EP in NAK state for us criticalLeave(); - usmtmcd_app_bulkOut_clearFeature_cb(rhport); + usmtmcd_app_bulkOut_clearFeature_cb(); } else if (ep_addr == usbtmc_state.ep_bulk_in) { - usmtmcd_app_bulkIn_clearFeature_cb(rhport); + usmtmcd_app_bulkIn_clearFeature_cb(); } else { diff --git a/src/class/usbtmc/usbtmc_device.h b/src/class/usbtmc/usbtmc_device.h index 9f88e5e83..a3f0e90e0 100644 --- a/src/class/usbtmc/usbtmc_device.h +++ b/src/class/usbtmc/usbtmc_device.h @@ -69,11 +69,11 @@ void tud_usbtmc_app_open_cb(uint8_t interface_id); bool tud_usbtmc_app_msgBulkOut_start_cb(usbtmc_msg_request_dev_dep_out const * msgHeader); // transfer_complete does not imply that a message is complete. bool tud_usbtmc_app_msg_data_cb( void *data, size_t len, bool transfer_complete); -void usmtmcd_app_bulkOut_clearFeature_cb(); // Notice to clear and abort the pending BULK out transfer +void usmtmcd_app_bulkOut_clearFeature_cb(void); // Notice to clear and abort the pending BULK out transfer bool tud_usbtmc_app_msgBulkIn_request_cb(usbtmc_msg_request_dev_dep_in const * request); -bool tud_usbtmc_app_msgBulkIn_complete_cb(); -void usmtmcd_app_bulkIn_clearFeature_cb(); // Notice to clear and abort the pending BULK out transfer +bool tud_usbtmc_app_msgBulkIn_complete_cb(void); +void usmtmcd_app_bulkIn_clearFeature_cb(void); // Notice to clear and abort the pending BULK out transfer bool tud_usbtmc_app_initiate_abort_bulk_in_cb(uint8_t *tmcResult); bool tud_usbtmc_app_initiate_abort_bulk_out_cb(uint8_t *tmcResult); @@ -103,7 +103,7 @@ bool usbtmcd_transmit_dev_msg_data( const void * data, size_t len, bool endOfMessage, bool usingTermChar); -bool usbtmcd_start_bus_read(); +bool usbtmcd_start_bus_read(void); /* "callbacks" from USB device core */ -- cgit v1.3.1 From 2d4352bfe9d969c76374cd15c3332fbe9f98d66a Mon Sep 17 00:00:00 2001 From: Nathan Conrad Date: Wed, 25 Sep 2019 11:34:27 -0400 Subject: Rename USBTMC functions. --- examples/device/usbtmc/src/tusb_config.h | 2 +- examples/device/usbtmc/src/usbtmc_app.c | 26 +++++++++++++------------- src/class/usbtmc/usbtmc_device.c | 18 +++++++++--------- src/class/usbtmc/usbtmc_device.h | 20 ++++++++++---------- 4 files changed, 33 insertions(+), 33 deletions(-) (limited to 'src') diff --git a/examples/device/usbtmc/src/tusb_config.h b/examples/device/usbtmc/src/tusb_config.h index 688fb02be..c20b05fbb 100644 --- a/examples/device/usbtmc/src/tusb_config.h +++ b/examples/device/usbtmc/src/tusb_config.h @@ -57,7 +57,7 @@ #define CFG_TUD_USBTMC 1 #define CFG_TUD_USBTMC_ENABLE_INT_EP 1 -#define CFG_USBTMC_CFG_ENABLE_488 1 +#define CFG_TUD_USBTMC_ENABLE_488 1 #ifdef __cplusplus } diff --git a/examples/device/usbtmc/src/usbtmc_app.c b/examples/device/usbtmc/src/usbtmc_app.c index b622d6b9b..d06014ce8 100644 --- a/examples/device/usbtmc/src/usbtmc_app.c +++ b/examples/device/usbtmc/src/usbtmc_app.c @@ -29,7 +29,7 @@ #include "bsp/board.h" #include "main.h" -#if (CFG_USBTMC_CFG_ENABLE_488) +#if (CFG_TUD_USBTMC_ENABLE_488) usbtmc_response_capabilities_488_t const #else usbtmc_response_capabilities_t const @@ -48,7 +48,7 @@ tud_usbtmc_app_capabilities = .canEndBulkInOnTermChar = 0 }, -#if (CFG_USBTMC_CFG_ENABLE_488) +#if (CFG_TUD_USBTMC_ENABLE_488) .bcdUSB488 = USBTMC_488_VERSION, .bmIntfcCapabilities488 = { @@ -99,7 +99,7 @@ static usbtmc_msg_dev_dep_msg_in_header_t rspMsg = { void tud_usbtmc_app_open_cb(uint8_t interface_id) { (void)interface_id; - usbtmcd_start_bus_read(); + tud_usbtmc_start_bus_read(); } @@ -152,7 +152,7 @@ bool tud_usbtmc_app_msg_data_cb(void *data, size_t len, bool transfer_complete) d=0; resp_delay = (uint32_t)d; } - usbtmcd_start_bus_read(); + tud_usbtmc_start_bus_read(); return true; } @@ -165,7 +165,7 @@ bool tud_usbtmc_app_msgBulkIn_complete_cb() bulkInStarted = 0; buffer_tx_ix = 0; } - usbtmcd_start_bus_read(); + tud_usbtmc_start_bus_read(); return true; } @@ -193,7 +193,7 @@ bool tud_usbtmc_app_msgBulkIn_request_cb(usbtmc_msg_request_dev_dep_in const * r else { size_t txlen = tu_min32(buffer_len-buffer_tx_ix,msgReqLen); - usbtmcd_transmit_dev_msg_data(&buffer[buffer_tx_ix], txlen, + tud_usbtmc_transmit_dev_msg_data(&buffer[buffer_tx_ix], txlen, (buffer_tx_ix+txlen) == buffer_len, false); buffer_tx_ix += txlen; } @@ -226,14 +226,14 @@ void usbtmc_app_task_iter(void) { if(bulkInStarted && (buffer_tx_ix == 0)) { if(idnQuery) { - usbtmcd_transmit_dev_msg_data(idn, tu_min32(sizeof(idn)-1,msgReqLen),true,false); + tud_usbtmc_transmit_dev_msg_data(idn, tu_min32(sizeof(idn)-1,msgReqLen),true,false); queryState = 0; bulkInStarted = 0; } else { buffer_tx_ix = tu_min32(buffer_len,msgReqLen); - usbtmcd_transmit_dev_msg_data(buffer, buffer_tx_ix, buffer_tx_ix == buffer_len, false); + tud_usbtmc_transmit_dev_msg_data(buffer, buffer_tx_ix, buffer_tx_ix == buffer_len, false); } // MAV is cleared in the transfer complete callback. } @@ -273,7 +273,7 @@ bool tud_usbtmc_app_initiate_abort_bulk_in_cb(uint8_t *tmcResult) bool tud_usbtmc_app_check_abort_bulk_in_cb(usbtmc_check_abort_bulk_rsp_t *rsp) { (void)rsp; - usbtmcd_start_bus_read(); + tud_usbtmc_start_bus_read(); return true; } @@ -286,16 +286,16 @@ bool tud_usbtmc_app_initiate_abort_bulk_out_cb(uint8_t *tmcResult) bool tud_usbtmc_app_check_abort_bulk_out_cb(usbtmc_check_abort_bulk_rsp_t *rsp) { (void)rsp; - usbtmcd_start_bus_read(); + tud_usbtmc_start_bus_read(); return true; } -void usmtmcd_app_bulkIn_clearFeature_cb(void) +void tud_usbtmc_app_bulkIn_clearFeature_cb(void) { } -void usmtmcd_app_bulkOut_clearFeature_cb(void) +void tud_usmtmc_app_bulkOut_clearFeature_cb(void) { - usbtmcd_start_bus_read(); + tud_usbtmc_start_bus_read(); } // Return status byte, but put the transfer result status code in the rspResult argument. diff --git a/src/class/usbtmc/usbtmc_device.c b/src/class/usbtmc/usbtmc_device.c index dad892f43..f0b74fe38 100644 --- a/src/class/usbtmc/usbtmc_device.c +++ b/src/class/usbtmc/usbtmc_device.c @@ -186,7 +186,7 @@ bool atomicChangeState(usbtmcd_state_enum expectedState, usbtmcd_state_enum newS // We can't just send the whole thing at once because we need to concatanate the // header with the data. -bool usbtmcd_transmit_dev_msg_data( +bool tud_usbtmc_transmit_dev_msg_data( const void * data, size_t len, bool endOfMessage, bool usingTermChar) @@ -236,7 +236,7 @@ bool usbtmcd_transmit_dev_msg_data( void usbtmcd_init_cb(void) { #ifndef NDEBUG -# if CFG_USBTMC_CFG_ENABLE_488 +# if CFG_TUD_USBTMC_ENABLE_488 if(tud_usbtmc_app_capabilities.bmIntfcCapabilities488.supportsTrigger) TU_ASSERT(&tud_usbtmc_app_msg_trigger_cb != NULL,); // Per USB488 spec: table 8 @@ -316,7 +316,7 @@ bool usbtmcd_open_cb(uint8_t rhport, tusb_desc_interface_t const * itf_desc, uin { TU_ASSERT(usbtmc_state.ep_int_in != 0); } -#if (CFG_USBTMC_CFG_ENABLE_488) +#if (CFG_TUD_USBTMC_ENABLE_488) if(tud_usbtmc_app_capabilities.bmIntfcCapabilities488.is488_2 || tud_usbtmc_app_capabilities.bmDevCapabilities488.SR1) { @@ -335,7 +335,7 @@ bool usbtmcd_open_cb(uint8_t rhport, tusb_desc_interface_t const * itf_desc, uin // processing a command (such as a clear). Returns true if it was // in the NAK state and successfully transitioned to the ACK wait // state. -bool usbtmcd_start_bus_read() +bool tud_usbtmc_start_bus_read() { usbtmcd_state_enum oldState = usbtmc_state.state; switch(oldState) @@ -468,7 +468,7 @@ bool usbtmcd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint TU_VERIFY(handle_devMsgIn(msg, xferred_bytes)); break; -#if (CFG_USBTMC_CFG_ENABLE_488) +#if (CFG_TUD_USBTMC_ENABLE_488) case USBTMC_MSGID_USB488_TRIGGER: // Spec says we halt the EP if we didn't declare we support it. TU_VERIFY(tud_usbtmc_app_capabilities.bmIntfcCapabilities488.supportsTrigger); @@ -562,7 +562,7 @@ bool usbtmcd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint bool usbtmcd_control_request_cb(uint8_t rhport, tusb_control_request_t const * request) { uint8_t tmcStatusCode = USBTMC_STATUS_FAILED; -#if (CFG_USBTMC_CFG_ENABLE_488) +#if (CFG_TUD_USBTMC_ENABLE_488) uint8_t bTag; #endif @@ -578,11 +578,11 @@ bool usbtmcd_control_request_cb(uint8_t rhport, tusb_control_request_t const * r criticalEnter(); usbtmc_state.state = STATE_NAK; // USBD core has placed EP in NAK state for us criticalLeave(); - usmtmcd_app_bulkOut_clearFeature_cb(); + tud_usmtmc_app_bulkOut_clearFeature_cb(); } else if (ep_addr == usbtmc_state.ep_bulk_in) { - usmtmcd_app_bulkIn_clearFeature_cb(); + tud_usbtmc_app_bulkIn_clearFeature_cb(); } else { @@ -783,7 +783,7 @@ bool usbtmcd_control_request_cb(uint8_t rhport, tusb_control_request_t const * r TU_VERIFY(tud_control_xfer(rhport, request, (void*)&tmcStatusCode, sizeof(tmcStatusCode))); return true; } -#if (CFG_USBTMC_CFG_ENABLE_488) +#if (CFG_TUD_USBTMC_ENABLE_488) // USB488 required requests case USB488_bREQUEST_READ_STATUS_BYTE: diff --git a/src/class/usbtmc/usbtmc_device.h b/src/class/usbtmc/usbtmc_device.h index a3f0e90e0..9f1020e58 100644 --- a/src/class/usbtmc/usbtmc_device.h +++ b/src/class/usbtmc/usbtmc_device.h @@ -37,8 +37,8 @@ #include "usbtmc.h" // Enable 488 mode by default -#if !defined(CFG_USBTMC_CFG_ENABLE_488) -#define CFG_CFG_USBTMC_CFG_ENABLE_488 (1) +#if !defined(CFG_TUD_USBTMC_ENABLE_488) +#define CFG_TUD_USBTMC_ENABLE_488 (1) #endif // USB spec says that full-speed must be 8,16,32, or 64. @@ -49,31 +49,31 @@ * Functions to be implemeted by the class implementation */ -#if (CFG_USBTMC_CFG_ENABLE_488) +#if (CFG_TUD_USBTMC_ENABLE_488) extern usbtmc_response_capabilities_488_t const tud_usbtmc_app_capabilities; #else extern usbtmc_response_capabilities_t const tud_usbtmc_app_capabilities; #endif -// In order to proceed, app must call call usbtmcd_start_bus_read(rhport) during or soon after: +// In order to proceed, app must call call tud_usbtmc_start_bus_read(rhport) during or soon after: // * tud_usbtmc_app_open_cb // * tud_usbtmc_app_msg_data_cb // * tud_usbtmc_app_msgBulkIn_complete_cb // * tud_usbtmc_app_msg_trigger_cb // * (successful) tud_usbtmc_app_check_abort_bulk_out_cb // * (successful) tud_usbtmc_app_check_abort_bulk_in_cb -// * (successful) usmtmcd_app_bulkOut_clearFeature_cb +// * (successful) tud_usmtmc_app_bulkOut_clearFeature_cb void tud_usbtmc_app_open_cb(uint8_t interface_id); bool tud_usbtmc_app_msgBulkOut_start_cb(usbtmc_msg_request_dev_dep_out const * msgHeader); // transfer_complete does not imply that a message is complete. bool tud_usbtmc_app_msg_data_cb( void *data, size_t len, bool transfer_complete); -void usmtmcd_app_bulkOut_clearFeature_cb(void); // Notice to clear and abort the pending BULK out transfer +void tud_usmtmc_app_bulkOut_clearFeature_cb(void); // Notice to clear and abort the pending BULK out transfer bool tud_usbtmc_app_msgBulkIn_request_cb(usbtmc_msg_request_dev_dep_in const * request); bool tud_usbtmc_app_msgBulkIn_complete_cb(void); -void usmtmcd_app_bulkIn_clearFeature_cb(void); // Notice to clear and abort the pending BULK out transfer +void tud_usbtmc_app_bulkIn_clearFeature_cb(void); // Notice to clear and abort the pending BULK out transfer bool tud_usbtmc_app_initiate_abort_bulk_in_cb(uint8_t *tmcResult); bool tud_usbtmc_app_initiate_abort_bulk_out_cb(uint8_t *tmcResult); @@ -86,7 +86,7 @@ bool tud_usbtmc_app_check_clear_cb(usbtmc_get_clear_status_rsp_t *rsp); // Indicator pulse should be 0.5 to 1.0 seconds long TU_ATTR_WEAK bool tud_usbtmc_app_indicator_pulse_cb(tusb_control_request_t const * msg, uint8_t *tmcResult); -#if (CFG_USBTMC_CFG_ENABLE_488) +#if (CFG_TUD_USBTMC_ENABLE_488) uint8_t tud_usbtmc_app_get_stb_cb(uint8_t *tmcResult); TU_ATTR_WEAK bool tud_usbtmc_app_msg_trigger_cb(usbtmc_msg_generic_t* msg); //TU_ATTR_WEAK bool tud_usbtmc_app_go_to_local_cb(); @@ -99,11 +99,11 @@ TU_ATTR_WEAK bool tud_usbtmc_app_msg_trigger_cb(usbtmc_msg_generic_t* msg); * notified that the transfer is complete. ******************************************/ -bool usbtmcd_transmit_dev_msg_data( +bool tud_usbtmc_transmit_dev_msg_data( const void * data, size_t len, bool endOfMessage, bool usingTermChar); -bool usbtmcd_start_bus_read(void); +bool tud_usbtmc_start_bus_read(void); /* "callbacks" from USB device core */ -- cgit v1.3.1 From 3a87dd65d735085845cbf799add77596cf737f44 Mon Sep 17 00:00:00 2001 From: Nathan Conrad Date: Wed, 25 Sep 2019 12:17:49 -0400 Subject: Change getting the capabilities structure to a callback instead of an extern struct. --- examples/device/usbtmc/src/usbtmc_app.c | 14 +++++++++++-- src/class/usbtmc/usbtmc_device.c | 36 ++++++++++++++++++++++----------- src/class/usbtmc/usbtmc_device.h | 12 +++++------ 3 files changed, 42 insertions(+), 20 deletions(-) (limited to 'src') diff --git a/examples/device/usbtmc/src/usbtmc_app.c b/examples/device/usbtmc/src/usbtmc_app.c index d06014ce8..924a33fab 100644 --- a/examples/device/usbtmc/src/usbtmc_app.c +++ b/examples/device/usbtmc/src/usbtmc_app.c @@ -30,9 +30,9 @@ #include "main.h" #if (CFG_TUD_USBTMC_ENABLE_488) -usbtmc_response_capabilities_488_t const +static usbtmc_response_capabilities_488_t const #else -usbtmc_response_capabilities_t const +static usbtmc_response_capabilities_t const #endif tud_usbtmc_app_capabilities = { @@ -102,6 +102,16 @@ void tud_usbtmc_app_open_cb(uint8_t interface_id) tud_usbtmc_start_bus_read(); } +#if (CFG_TUD_USBTMC_ENABLE_488) +usbtmc_response_capabilities_488_t const * +#else +usbtmc_response_capabilities_t const * +#endif +tud_usbtmc_get_capabilities_cb() +{ + return &tud_usbtmc_app_capabilities; +} + bool tud_usbtmc_app_msg_trigger_cb(usbtmc_msg_generic_t* msg) { (void)msg; diff --git a/src/class/usbtmc/usbtmc_device.c b/src/class/usbtmc/usbtmc_device.c index f0b74fe38..927ac8ecf 100644 --- a/src/class/usbtmc/usbtmc_device.c +++ b/src/class/usbtmc/usbtmc_device.c @@ -114,6 +114,13 @@ typedef enum STATE_NUM_STATES } usbtmcd_state_enum; +#if (CFG_TUD_USBTMC_ENABLE_488) + typedef usbtmc_response_capabilities_488_t usbtmc_capabilities_specific_t; +#else + typedef usbtmc_response_capabilities_t usbtmc_capabilities_specific_t; +#endif + + typedef struct { volatile usbtmcd_state_enum state; @@ -135,6 +142,8 @@ typedef struct uint8_t lastBulkInTag; // used for aborts (mostly) uint8_t const * devInBuffer; // pointer to application-layer used for transmissions + + usbtmc_capabilities_specific_t const * capabilities; } usbtmc_interface_state_t; static usbtmc_interface_state_t usbtmc_state = @@ -199,7 +208,7 @@ bool tud_usbtmc_transmit_dev_msg_data( TU_ASSERT(usbtmc_state.transfer_size_sent == 0u); if(usingTermChar) { - TU_ASSERT(tud_usbtmc_app_capabilities.bmDevCapabilities.canEndBulkInOnTermChar); + TU_ASSERT(usbtmc_state.capabilities->bmDevCapabilities.canEndBulkInOnTermChar); TU_ASSERT(termCharRequested); TU_ASSERT(((uint8_t*)data)[len-1u] == termChar); } @@ -235,15 +244,16 @@ bool tud_usbtmc_transmit_dev_msg_data( void usbtmcd_init_cb(void) { + usbtmc_state.capabilities = tud_usbtmc_get_capabilities_cb(); #ifndef NDEBUG # if CFG_TUD_USBTMC_ENABLE_488 - if(tud_usbtmc_app_capabilities.bmIntfcCapabilities488.supportsTrigger) + if(usbtmc_state.capabilities->bmIntfcCapabilities488.supportsTrigger) TU_ASSERT(&tud_usbtmc_app_msg_trigger_cb != NULL,); // Per USB488 spec: table 8 - TU_ASSERT(!tud_usbtmc_app_capabilities.bmIntfcCapabilities.listenOnly,); - TU_ASSERT(!tud_usbtmc_app_capabilities.bmIntfcCapabilities.talkOnly,); + TU_ASSERT(!usbtmc_state.capabilities->bmIntfcCapabilities.listenOnly,); + TU_ASSERT(!usbtmc_state.capabilities->bmIntfcCapabilities.talkOnly,); # endif - if(tud_usbtmc_app_capabilities.bmIntfcCapabilities.supportsIndicatorPulse) + if(usbtmc_state.capabilities->bmIntfcCapabilities.supportsIndicatorPulse) TU_ASSERT(&tud_usbtmc_app_indicator_pulse_cb != NULL,); #endif @@ -317,8 +327,8 @@ bool usbtmcd_open_cb(uint8_t rhport, tusb_desc_interface_t const * itf_desc, uin TU_ASSERT(usbtmc_state.ep_int_in != 0); } #if (CFG_TUD_USBTMC_ENABLE_488) - if(tud_usbtmc_app_capabilities.bmIntfcCapabilities488.is488_2 || - tud_usbtmc_app_capabilities.bmDevCapabilities488.SR1) + if(usbtmc_state.capabilities->bmIntfcCapabilities488.is488_2 || + usbtmc_state.capabilities->bmDevCapabilities488.SR1) { TU_ASSERT(usbtmc_state.ep_int_in != 0); } @@ -358,9 +368,11 @@ bool tud_usbtmc_start_bus_read() void usbtmcd_reset_cb(uint8_t rhport) { (void)rhport; + usbtmc_capabilities_specific_t const * capabilities = tud_usbtmc_get_capabilities_cb(); criticalEnter(); tu_varclr(&usbtmc_state); + usbtmc_state.capabilities = capabilities; usbtmc_state.itf_id = 0xFFu; criticalLeave(); } @@ -428,7 +440,7 @@ static bool handle_devMsgIn(void *data, size_t len) termChar = msg->TermChar; if(termCharRequested) - TU_VERIFY(tud_usbtmc_app_capabilities.bmDevCapabilities.canEndBulkInOnTermChar); + TU_VERIFY(usbtmc_state.capabilities->bmDevCapabilities.canEndBulkInOnTermChar); TU_VERIFY(tud_usbtmc_app_msgBulkIn_request_cb(msg)); return true; @@ -471,7 +483,7 @@ bool usbtmcd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint #if (CFG_TUD_USBTMC_ENABLE_488) case USBTMC_MSGID_USB488_TRIGGER: // Spec says we halt the EP if we didn't declare we support it. - TU_VERIFY(tud_usbtmc_app_capabilities.bmIntfcCapabilities488.supportsTrigger); + TU_VERIFY(usbtmc_state.capabilities->bmIntfcCapabilities488.supportsTrigger); TU_VERIFY(tud_usbtmc_app_msg_trigger_cb(msg)); break; @@ -768,8 +780,8 @@ bool usbtmcd_control_request_cb(uint8_t rhport, tusb_control_request_t const * r case USBTMC_bREQUEST_GET_CAPABILITIES: { TU_VERIFY(request->bmRequestType == 0xA1); // in,class,interface - TU_VERIFY(request->wLength == sizeof(tud_usbtmc_app_capabilities)); - TU_VERIFY(tud_control_xfer(rhport, request, (void*)&tud_usbtmc_app_capabilities, sizeof(tud_usbtmc_app_capabilities))); + TU_VERIFY(request->wLength == sizeof(*(usbtmc_state.capabilities))); + TU_VERIFY(tud_control_xfer(rhport, request, (void*)usbtmc_state.capabilities, sizeof(*usbtmc_state.capabilities))); return true; } // USBTMC Optional Requests @@ -778,7 +790,7 @@ bool usbtmcd_control_request_cb(uint8_t rhport, tusb_control_request_t const * r { TU_VERIFY(request->bmRequestType == 0xA1); // in,class,interface TU_VERIFY(request->wLength == sizeof(tmcStatusCode)); - TU_VERIFY(tud_usbtmc_app_capabilities.bmIntfcCapabilities.supportsIndicatorPulse); + TU_VERIFY(usbtmc_state.capabilities->bmIntfcCapabilities.supportsIndicatorPulse); TU_VERIFY(tud_usbtmc_app_indicator_pulse_cb(request, &tmcStatusCode)); TU_VERIFY(tud_control_xfer(rhport, request, (void*)&tmcStatusCode, sizeof(tmcStatusCode))); return true; diff --git a/src/class/usbtmc/usbtmc_device.h b/src/class/usbtmc/usbtmc_device.h index 9f1020e58..adccd65e1 100644 --- a/src/class/usbtmc/usbtmc_device.h +++ b/src/class/usbtmc/usbtmc_device.h @@ -49,12 +49,6 @@ * Functions to be implemeted by the class implementation */ -#if (CFG_TUD_USBTMC_ENABLE_488) -extern usbtmc_response_capabilities_488_t const tud_usbtmc_app_capabilities; -#else -extern usbtmc_response_capabilities_t const tud_usbtmc_app_capabilities; -#endif - // In order to proceed, app must call call tud_usbtmc_start_bus_read(rhport) during or soon after: // * tud_usbtmc_app_open_cb // * tud_usbtmc_app_msg_data_cb @@ -64,6 +58,12 @@ extern usbtmc_response_capabilities_t const tud_usbtmc_app_capabilities; // * (successful) tud_usbtmc_app_check_abort_bulk_in_cb // * (successful) tud_usmtmc_app_bulkOut_clearFeature_cb +#if (CFG_TUD_USBTMC_ENABLE_488) +usbtmc_response_capabilities_488_t const * tud_usbtmc_get_capabilities_cb(void); +#else +usbtmc_response_capabilities_t const * tud_usbtmc_get_capabilities_cb(void); +#endif + void tud_usbtmc_app_open_cb(uint8_t interface_id); bool tud_usbtmc_app_msgBulkOut_start_cb(usbtmc_msg_request_dev_dep_out const * msgHeader); -- cgit v1.3.1 From 6841b236e89cad45024280c44a77e43490635af2 Mon Sep 17 00:00:00 2001 From: Nathan Conrad Date: Wed, 25 Sep 2019 12:45:39 -0400 Subject: Remove _app from callback function names. --- examples/device/usbtmc/src/usbtmc_app.c | 32 +++++++++++------------ src/class/usbtmc/usbtmc_device.c | 38 +++++++++++++-------------- src/class/usbtmc/usbtmc_device.h | 46 ++++++++++++++++----------------- 3 files changed, 58 insertions(+), 58 deletions(-) (limited to 'src') diff --git a/examples/device/usbtmc/src/usbtmc_app.c b/examples/device/usbtmc/src/usbtmc_app.c index 924a33fab..0e39b4227 100644 --- a/examples/device/usbtmc/src/usbtmc_app.c +++ b/examples/device/usbtmc/src/usbtmc_app.c @@ -96,7 +96,7 @@ static usbtmc_msg_dev_dep_msg_in_header_t rspMsg = { } }; -void tud_usbtmc_app_open_cb(uint8_t interface_id) +void tud_usbtmc_open_cb(uint8_t interface_id) { (void)interface_id; tud_usbtmc_start_bus_read(); @@ -113,14 +113,14 @@ tud_usbtmc_get_capabilities_cb() } -bool tud_usbtmc_app_msg_trigger_cb(usbtmc_msg_generic_t* msg) { +bool tud_usbtmc_msg_trigger_cb(usbtmc_msg_generic_t* msg) { (void)msg; // Let trigger set the SRQ status |= IEEE4882_STB_SRQ; return true; } -bool tud_usbtmc_app_msgBulkOut_start_cb(usbtmc_msg_request_dev_dep_out const * msgHeader) +bool tud_usbtmc_msgBulkOut_start_cb(usbtmc_msg_request_dev_dep_out const * msgHeader) { (void)msgHeader; buffer_len = 0; @@ -132,7 +132,7 @@ bool tud_usbtmc_app_msgBulkOut_start_cb(usbtmc_msg_request_dev_dep_out const * m return true; } -bool tud_usbtmc_app_msg_data_cb(void *data, size_t len, bool transfer_complete) +bool tud_usbtmc_msg_data_cb(void *data, size_t len, bool transfer_complete) { // If transfer isn't finished, we just ignore it (for now) @@ -166,7 +166,7 @@ bool tud_usbtmc_app_msg_data_cb(void *data, size_t len, bool transfer_complete) return true; } -bool tud_usbtmc_app_msgBulkIn_complete_cb() +bool tud_usbtmc_msgBulkIn_complete_cb() { if((buffer_tx_ix == buffer_len) || idnQuery) // done { @@ -182,7 +182,7 @@ bool tud_usbtmc_app_msgBulkIn_complete_cb() static unsigned int msgReqLen; -bool tud_usbtmc_app_msgBulkIn_request_cb(usbtmc_msg_request_dev_dep_in const * request) +bool tud_usbtmc_msgBulkIn_request_cb(usbtmc_msg_request_dev_dep_in const * request) { rspMsg.header.MsgID = request->header.MsgID, rspMsg.header.bTag = request->header.bTag, @@ -254,7 +254,7 @@ void usbtmc_app_task_iter(void) { } } -bool tud_usbtmc_app_initiate_clear_cb(uint8_t *tmcResult) +bool tud_usbtmc_initiate_clear_cb(uint8_t *tmcResult) { *tmcResult = USBTMC_STATUS_SUCCESS; queryState = 0; @@ -263,7 +263,7 @@ bool tud_usbtmc_app_initiate_clear_cb(uint8_t *tmcResult) return true; } -bool tud_usbtmc_app_check_clear_cb(usbtmc_get_clear_status_rsp_t *rsp) +bool tud_usbtmc_check_clear_cb(usbtmc_get_clear_status_rsp_t *rsp) { queryState = 0; bulkInStarted = false; @@ -274,42 +274,42 @@ bool tud_usbtmc_app_check_clear_cb(usbtmc_get_clear_status_rsp_t *rsp) rsp->bmClear.BulkInFifoBytes = 0u; return true; } -bool tud_usbtmc_app_initiate_abort_bulk_in_cb(uint8_t *tmcResult) +bool tud_usbtmc_initiate_abort_bulk_in_cb(uint8_t *tmcResult) { bulkInStarted = 0; *tmcResult = USBTMC_STATUS_SUCCESS; return true; } -bool tud_usbtmc_app_check_abort_bulk_in_cb(usbtmc_check_abort_bulk_rsp_t *rsp) +bool tud_usbtmc_check_abort_bulk_in_cb(usbtmc_check_abort_bulk_rsp_t *rsp) { (void)rsp; tud_usbtmc_start_bus_read(); return true; } -bool tud_usbtmc_app_initiate_abort_bulk_out_cb(uint8_t *tmcResult) +bool tud_usbtmc_initiate_abort_bulk_out_cb(uint8_t *tmcResult) { *tmcResult = USBTMC_STATUS_SUCCESS; return true; } -bool tud_usbtmc_app_check_abort_bulk_out_cb(usbtmc_check_abort_bulk_rsp_t *rsp) +bool tud_usbtmc_check_abort_bulk_out_cb(usbtmc_check_abort_bulk_rsp_t *rsp) { (void)rsp; tud_usbtmc_start_bus_read(); return true; } -void tud_usbtmc_app_bulkIn_clearFeature_cb(void) +void tud_usbtmc_bulkIn_clearFeature_cb(void) { } -void tud_usmtmc_app_bulkOut_clearFeature_cb(void) +void tud_usmtmc_bulkOut_clearFeature_cb(void) { tud_usbtmc_start_bus_read(); } // Return status byte, but put the transfer result status code in the rspResult argument. -uint8_t tud_usbtmc_app_get_stb_cb(uint8_t *tmcResult) +uint8_t tud_usbtmc_get_stb_cb(uint8_t *tmcResult) { uint8_t old_status = status; status = (uint8_t)(status & ~(IEEE4882_STB_SRQ)); // clear SRQ @@ -320,7 +320,7 @@ uint8_t tud_usbtmc_app_get_stb_cb(uint8_t *tmcResult) return old_status; } -bool tud_usbtmc_app_indicator_pulse_cb(tusb_control_request_t const * msg, uint8_t *tmcResult) +bool tud_usbtmc_indicator_pulse_cb(tusb_control_request_t const * msg, uint8_t *tmcResult) { (void)msg; led_indicator_pulse(); diff --git a/src/class/usbtmc/usbtmc_device.c b/src/class/usbtmc/usbtmc_device.c index 927ac8ecf..c8e742fc5 100644 --- a/src/class/usbtmc/usbtmc_device.c +++ b/src/class/usbtmc/usbtmc_device.c @@ -248,13 +248,13 @@ void usbtmcd_init_cb(void) #ifndef NDEBUG # if CFG_TUD_USBTMC_ENABLE_488 if(usbtmc_state.capabilities->bmIntfcCapabilities488.supportsTrigger) - TU_ASSERT(&tud_usbtmc_app_msg_trigger_cb != NULL,); + TU_ASSERT(&tud_usbtmc_msg_trigger_cb != NULL,); // Per USB488 spec: table 8 TU_ASSERT(!usbtmc_state.capabilities->bmIntfcCapabilities.listenOnly,); TU_ASSERT(!usbtmc_state.capabilities->bmIntfcCapabilities.talkOnly,); # endif if(usbtmc_state.capabilities->bmIntfcCapabilities.supportsIndicatorPulse) - TU_ASSERT(&tud_usbtmc_app_indicator_pulse_cb != NULL,); + TU_ASSERT(&tud_usbtmc_indicator_pulse_cb != NULL,); #endif usbtmcLock = osal_mutex_create(&usbtmcLockBuffer); @@ -335,7 +335,7 @@ bool usbtmcd_open_cb(uint8_t rhport, tusb_desc_interface_t const * itf_desc, uin #endif #endif atomicChangeState(STATE_CLOSED, STATE_NAK); - tud_usbtmc_app_open_cb(itf_desc->iInterface); + tud_usbtmc_open_cb(itf_desc->iInterface); return true; } @@ -387,7 +387,7 @@ static bool handle_devMsgOutStart(uint8_t rhport, void *data, size_t len) // must be a header, should have been confirmed before calling here. usbtmc_msg_request_dev_dep_out *msg = (usbtmc_msg_request_dev_dep_out*)data; usbtmc_state.transfer_size_remaining = msg->TransferSize; - TU_VERIFY(tud_usbtmc_app_msgBulkOut_start_cb(msg)); + TU_VERIFY(tud_usbtmc_msgBulkOut_start_cb(msg)); TU_VERIFY(handle_devMsgOut(rhport, (uint8_t*)data + sizeof(*msg), len - sizeof(*msg), len)); usbtmc_state.lastBulkOutTag = msg->header.bTag; @@ -416,7 +416,7 @@ static bool handle_devMsgOut(uint8_t rhport, void *data, size_t len, size_t pack usbtmc_state.transfer_size_sent += len; // App may (should?) call the wait_for_bus() command at this point - if(!tud_usbtmc_app_msg_data_cb(data, len, atEnd)) + if(!tud_usbtmc_msg_data_cb(data, len, atEnd)) { // TODO: Go to an error state upon failure other than just stalling the EP? return false; @@ -442,7 +442,7 @@ static bool handle_devMsgIn(void *data, size_t len) if(termCharRequested) TU_VERIFY(usbtmc_state.capabilities->bmDevCapabilities.canEndBulkInOnTermChar); - TU_VERIFY(tud_usbtmc_app_msgBulkIn_request_cb(msg)); + TU_VERIFY(tud_usbtmc_msgBulkIn_request_cb(msg)); return true; } @@ -484,7 +484,7 @@ bool usbtmcd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint case USBTMC_MSGID_USB488_TRIGGER: // Spec says we halt the EP if we didn't declare we support it. TU_VERIFY(usbtmc_state.capabilities->bmIntfcCapabilities488.supportsTrigger); - TU_VERIFY(tud_usbtmc_app_msg_trigger_cb(msg)); + TU_VERIFY(tud_usbtmc_msg_trigger_cb(msg)); break; #endif @@ -523,7 +523,7 @@ bool usbtmcd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint switch(usbtmc_state.state) { case STATE_TX_SHORTED: TU_VERIFY(atomicChangeState(STATE_TX_SHORTED, STATE_NAK)); - TU_VERIFY(tud_usbtmc_app_msgBulkIn_complete_cb()); + TU_VERIFY(tud_usbtmc_msgBulkIn_complete_cb()); break; case STATE_TX_INITIATED: @@ -590,11 +590,11 @@ bool usbtmcd_control_request_cb(uint8_t rhport, tusb_control_request_t const * r criticalEnter(); usbtmc_state.state = STATE_NAK; // USBD core has placed EP in NAK state for us criticalLeave(); - tud_usmtmc_app_bulkOut_clearFeature_cb(); + tud_usmtmc_bulkOut_clearFeature_cb(); } else if (ep_addr == usbtmc_state.ep_bulk_in) { - tud_usbtmc_app_bulkIn_clearFeature_cb(); + tud_usbtmc_bulkIn_clearFeature_cb(); } else { @@ -639,7 +639,7 @@ bool usbtmcd_control_request_cb(uint8_t rhport, tusb_control_request_t const * r criticalEnter(); usbtmc_state.state = STATE_ABORTING_BULK_OUT; criticalLeave(); - TU_VERIFY(tud_usbtmc_app_initiate_abort_bulk_out_cb(&(rsp.USBTMC_status))); + TU_VERIFY(tud_usbtmc_initiate_abort_bulk_out_cb(&(rsp.USBTMC_status))); usbd_edpt_stall(rhport, usbtmc_state.ep_bulk_out); } TU_VERIFY(tud_control_xfer(rhport, request, (void*)&rsp,sizeof(rsp))); @@ -655,7 +655,7 @@ bool usbtmcd_control_request_cb(uint8_t rhport, tusb_control_request_t const * r TU_VERIFY(request->bmRequestType == 0xA2); // in,class,EP TU_VERIFY(request->wLength == sizeof(rsp)); TU_VERIFY(request->wIndex == usbtmc_state.ep_bulk_out); - TU_VERIFY(tud_usbtmc_app_check_abort_bulk_out_cb(&rsp)); + TU_VERIFY(tud_usbtmc_check_abort_bulk_out_cb(&rsp)); TU_VERIFY(usbd_edpt_xfer(rhport, 0u, (void*)&rsp,sizeof(rsp))); return true; } @@ -685,7 +685,7 @@ bool usbtmcd_control_request_cb(uint8_t rhport, tusb_control_request_t const * r TU_VERIFY( usbd_edpt_xfer(rhport, usbtmc_state.ep_bulk_in, usbtmc_state.ep_bulk_in_buf,(uint16_t)0u)); usbtmc_state.state = STATE_ABORTING_BULK_IN_SHORTED; } - TU_VERIFY(tud_usbtmc_app_initiate_abort_bulk_in_cb(&(rsp.USBTMC_status))); + TU_VERIFY(tud_usbtmc_initiate_abort_bulk_in_cb(&(rsp.USBTMC_status))); } else if((usbtmc_state.state == STATE_TX_REQUESTED || usbtmc_state.state == STATE_TX_INITIATED)) { // FIXME: Unsure how to check if the OUT endpoint fifo is non-empty.... @@ -713,7 +713,7 @@ bool usbtmcd_control_request_cb(uint8_t rhport, tusb_control_request_t const * r }, .NBYTES_RXD_TXD = usbtmc_state.transfer_size_sent, }; - TU_VERIFY(tud_usbtmc_app_check_abort_bulk_in_cb(&rsp)); + TU_VERIFY(tud_usbtmc_check_abort_bulk_in_cb(&rsp)); criticalEnter(); switch(usbtmc_state.state) { @@ -745,7 +745,7 @@ bool usbtmcd_control_request_cb(uint8_t rhport, tusb_control_request_t const * r criticalEnter(); usbtmc_state.state = STATE_CLEARING; criticalLeave(); - TU_VERIFY(tud_usbtmc_app_initiate_clear_cb(&tmcStatusCode)); + TU_VERIFY(tud_usbtmc_initiate_clear_cb(&tmcStatusCode)); TU_VERIFY(tud_control_xfer(rhport, request, (void*)&tmcStatusCode,sizeof(tmcStatusCode))); return true; } @@ -765,7 +765,7 @@ bool usbtmcd_control_request_cb(uint8_t rhport, tusb_control_request_t const * r else { // Let app check if it's clear - TU_VERIFY(tud_usbtmc_app_check_clear_cb(&clearStatusRsp)); + TU_VERIFY(tud_usbtmc_check_clear_cb(&clearStatusRsp)); } if(clearStatusRsp.USBTMC_status == USBTMC_STATUS_SUCCESS) { @@ -791,7 +791,7 @@ bool usbtmcd_control_request_cb(uint8_t rhport, tusb_control_request_t const * r TU_VERIFY(request->bmRequestType == 0xA1); // in,class,interface TU_VERIFY(request->wLength == sizeof(tmcStatusCode)); TU_VERIFY(usbtmc_state.capabilities->bmIntfcCapabilities.supportsIndicatorPulse); - TU_VERIFY(tud_usbtmc_app_indicator_pulse_cb(request, &tmcStatusCode)); + TU_VERIFY(tud_usbtmc_indicator_pulse_cb(request, &tmcStatusCode)); TU_VERIFY(tud_control_xfer(rhport, request, (void*)&tmcStatusCode, sizeof(tmcStatusCode))); return true; } @@ -822,13 +822,13 @@ bool usbtmcd_control_request_cb(uint8_t rhport, tusb_control_request_t const * r .one = 1, .bTag = bTag & 0x7Fu, }, - .StatusByte = tud_usbtmc_app_get_stb_cb(&(rsp.USBTMC_status)) + .StatusByte = tud_usbtmc_get_stb_cb(&(rsp.USBTMC_status)) }; usbd_edpt_xfer(rhport, usbtmc_state.ep_int_in, (void*)&intMsg, sizeof(intMsg)); } else { - rsp.statusByte = tud_usbtmc_app_get_stb_cb(&(rsp.USBTMC_status)); + rsp.statusByte = tud_usbtmc_get_stb_cb(&(rsp.USBTMC_status)); } TU_VERIFY(tud_control_xfer(rhport, request, (void*)&rsp, sizeof(rsp))); return true; diff --git a/src/class/usbtmc/usbtmc_device.h b/src/class/usbtmc/usbtmc_device.h index adccd65e1..4c52989c2 100644 --- a/src/class/usbtmc/usbtmc_device.h +++ b/src/class/usbtmc/usbtmc_device.h @@ -50,13 +50,13 @@ */ // In order to proceed, app must call call tud_usbtmc_start_bus_read(rhport) during or soon after: -// * tud_usbtmc_app_open_cb -// * tud_usbtmc_app_msg_data_cb -// * tud_usbtmc_app_msgBulkIn_complete_cb -// * tud_usbtmc_app_msg_trigger_cb -// * (successful) tud_usbtmc_app_check_abort_bulk_out_cb -// * (successful) tud_usbtmc_app_check_abort_bulk_in_cb -// * (successful) tud_usmtmc_app_bulkOut_clearFeature_cb +// * tud_usbtmc_open_cb +// * tud_usbtmc_msg_data_cb +// * tud_usbtmc_msgBulkIn_complete_cb +// * tud_usbtmc_msg_trigger_cb +// * (successful) tud_usbtmc_check_abort_bulk_out_cb +// * (successful) tud_usbtmc_check_abort_bulk_in_cb +// * (successful) tud_usmtmc_bulkOut_clearFeature_cb #if (CFG_TUD_USBTMC_ENABLE_488) usbtmc_response_capabilities_488_t const * tud_usbtmc_get_capabilities_cb(void); @@ -64,31 +64,31 @@ usbtmc_response_capabilities_488_t const * tud_usbtmc_get_capabilities_cb(void); usbtmc_response_capabilities_t const * tud_usbtmc_get_capabilities_cb(void); #endif -void tud_usbtmc_app_open_cb(uint8_t interface_id); +void tud_usbtmc_open_cb(uint8_t interface_id); -bool tud_usbtmc_app_msgBulkOut_start_cb(usbtmc_msg_request_dev_dep_out const * msgHeader); +bool tud_usbtmc_msgBulkOut_start_cb(usbtmc_msg_request_dev_dep_out const * msgHeader); // transfer_complete does not imply that a message is complete. -bool tud_usbtmc_app_msg_data_cb( void *data, size_t len, bool transfer_complete); -void tud_usmtmc_app_bulkOut_clearFeature_cb(void); // Notice to clear and abort the pending BULK out transfer +bool tud_usbtmc_msg_data_cb( void *data, size_t len, bool transfer_complete); +void tud_usmtmc_bulkOut_clearFeature_cb(void); // Notice to clear and abort the pending BULK out transfer -bool tud_usbtmc_app_msgBulkIn_request_cb(usbtmc_msg_request_dev_dep_in const * request); -bool tud_usbtmc_app_msgBulkIn_complete_cb(void); -void tud_usbtmc_app_bulkIn_clearFeature_cb(void); // Notice to clear and abort the pending BULK out transfer +bool tud_usbtmc_msgBulkIn_request_cb(usbtmc_msg_request_dev_dep_in const * request); +bool tud_usbtmc_msgBulkIn_complete_cb(void); +void tud_usbtmc_bulkIn_clearFeature_cb(void); // Notice to clear and abort the pending BULK out transfer -bool tud_usbtmc_app_initiate_abort_bulk_in_cb(uint8_t *tmcResult); -bool tud_usbtmc_app_initiate_abort_bulk_out_cb(uint8_t *tmcResult); -bool tud_usbtmc_app_initiate_clear_cb(uint8_t *tmcResult); +bool tud_usbtmc_initiate_abort_bulk_in_cb(uint8_t *tmcResult); +bool tud_usbtmc_initiate_abort_bulk_out_cb(uint8_t *tmcResult); +bool tud_usbtmc_initiate_clear_cb(uint8_t *tmcResult); -bool tud_usbtmc_app_check_abort_bulk_in_cb(usbtmc_check_abort_bulk_rsp_t *rsp); -bool tud_usbtmc_app_check_abort_bulk_out_cb(usbtmc_check_abort_bulk_rsp_t *rsp); -bool tud_usbtmc_app_check_clear_cb(usbtmc_get_clear_status_rsp_t *rsp); +bool tud_usbtmc_check_abort_bulk_in_cb(usbtmc_check_abort_bulk_rsp_t *rsp); +bool tud_usbtmc_check_abort_bulk_out_cb(usbtmc_check_abort_bulk_rsp_t *rsp); +bool tud_usbtmc_check_clear_cb(usbtmc_get_clear_status_rsp_t *rsp); // Indicator pulse should be 0.5 to 1.0 seconds long -TU_ATTR_WEAK bool tud_usbtmc_app_indicator_pulse_cb(tusb_control_request_t const * msg, uint8_t *tmcResult); +TU_ATTR_WEAK bool tud_usbtmc_indicator_pulse_cb(tusb_control_request_t const * msg, uint8_t *tmcResult); #if (CFG_TUD_USBTMC_ENABLE_488) -uint8_t tud_usbtmc_app_get_stb_cb(uint8_t *tmcResult); -TU_ATTR_WEAK bool tud_usbtmc_app_msg_trigger_cb(usbtmc_msg_generic_t* msg); +uint8_t tud_usbtmc_get_stb_cb(uint8_t *tmcResult); +TU_ATTR_WEAK bool tud_usbtmc_msg_trigger_cb(usbtmc_msg_generic_t* msg); //TU_ATTR_WEAK bool tud_usbtmc_app_go_to_local_cb(); #endif -- cgit v1.3.1