summaryrefslogtreecommitdiff
path: root/src/class
diff options
context:
space:
mode:
authorNathan Conrad <[email protected]>2019-09-14 22:55:42 -0400
committerNathan Conrad <[email protected]>2019-09-17 13:29:38 -0400
commitc755aee7d0c1e2486055e02ac353878d8da3ba59 (patch)
tree4ceab626cdc1c823f0e8ed00386ebdb571ce0f15 /src/class
parente53e9bd4f0749e53740c9c33e740998ac202dd8a (diff)
Clear
Diffstat (limited to 'src/class')
-rw-r--r--src/class/usbtmc/usbtmc.h94
-rw-r--r--src/class/usbtmc/usbtmc_device.c135
-rw-r--r--src/class/usbtmc/usbtmc_device.h4
3 files changed, 152 insertions, 81 deletions
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];
@@ -203,38 +219,49 @@ TU_VERIFY_STATIC(sizeof(usbtmc_response_capabilities_t) == 0x18, "struct wrong l
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_rsp_488_t rsp;
+ TU_VERIFY(request->bmRequestType == 0xA1); // in,class,interface
+ TU_VERIFY(request->wLength == sizeof(rsp)); // in,class,interface
- usbtmc_read_stb_interrupt_488_t intMsg =
+ 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);