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