More proper handling of clear.

This commit is contained in:
Nathan Conrad 2019-09-15 14:57:02 -04:00
parent c755aee7d0
commit e234998c6c
4 changed files with 71 additions and 28 deletions

View File

@ -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) 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.MsgID = request->header.MsgID,
rspMsg.header.bTag = request->header.bTag, rspMsg.header.bTag = request->header.bTag,
rspMsg.header.bTagInverse = request->header.bTagInverse; rspMsg.header.bTagInverse = request->header.bTagInverse;
@ -135,6 +136,8 @@ void usbtmc_app_task_iter(void) {
uint8_t const rhport = 0; uint8_t const rhport = 0;
switch(queryState) { switch(queryState) {
case 0:
break;
case 1: case 1:
queryDelayStart = board_millis(); queryDelayStart = board_millis();
queryState = 2; 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; (void)rhport;
*tmcResult = USBTMC_STATUS_SUCCESS; *tmcResult = USBTMC_STATUS_SUCCESS;
queryState = 0;
bulkInStarted = false;
status = 0;
return true; 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; (void)rhport;
queryState = 0;
bulkInStarted = false;
status = 0;
rsp->USBTMC_status = USBTMC_STATUS_SUCCESS; rsp->USBTMC_status = USBTMC_STATUS_SUCCESS;
rsp->bmClear.BulkInFifoBytes = 0u; rsp->bmClear.BulkInFifoBytes = 0u;
return true; 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. // 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 usbtmcd_app_get_stb(uint8_t rhport, uint8_t *tmcResult)

View File

@ -279,13 +279,11 @@ TU_VERIFY_STATIC(sizeof(usbtmc_read_stb_rsp_488_t) == 3u, "struct wrong length")
typedef struct TU_ATTR_PACKET typedef struct TU_ATTR_PACKET
{ {
union { struct TU_ATTR_PACKED
struct TU_ATTR_PACKED { {
unsigned int bTag : 7; unsigned int bTag : 7;
unsigned int one : 1; unsigned int one : 1;
} bNotify1Struct; } bNotify1;
uint8_t bNotify1;
};
uint8_t StatusByte; uint8_t StatusByte;
} usbtmc_read_stb_interrupt_488_t; } usbtmc_read_stb_interrupt_488_t;

View File

@ -115,18 +115,19 @@ bool usbtmcd_transmit_dev_msg_data(
const void *data) const void *data)
{ {
TU_ASSERT(usbtmc_state.state == STATE_TX_REQUESTED); TU_ASSERT(usbtmc_state.state == STATE_TX_REQUESTED);
#ifndef NDEBUG
TU_ASSERT(hdr->TransferSize > 0u); TU_ASSERT(hdr->TransferSize > 0u);
if(hdr->bmTransferAttributes.UsingTermChar) if(hdr->bmTransferAttributes.UsingTermChar)
{ {
TU_ASSERT(usbtmcd_app_capabilities.bmDevCapabilities.canEndBulkInOnTermChar); TU_ASSERT(usbtmcd_app_capabilities.bmDevCapabilities.canEndBulkInOnTermChar);
TU_ASSERT(termCharRequested); TU_ASSERT(termCharRequested);
TU_ASSERT(((uint8_t*)data)[hdr->TransferSize-1] == termChar); TU_ASSERT(((uint8_t*)data)[hdr->TransferSize-1] == termChar);
} }
#endif
// Copy in the header // Copy in the header
memcpy(usbtmc_state.ep_bulk_in_buf, hdr, sizeof(*hdr)); memcpy(usbtmc_state.ep_bulk_in_buf, hdr, sizeof(*hdr));
uint packetLen = sizeof(*hdr); size_t packetLen = sizeof(*hdr);
// Single-packet transfer // Single-packet transfer
if((packetLen + hdr->TransferSize) <= USBTMCD_MAX_PACKET_SIZE) if((packetLen + hdr->TransferSize) <= USBTMCD_MAX_PACKET_SIZE)
{ {
@ -155,13 +156,14 @@ bool usbtmcd_transmit_dev_msg_data(
void usbtmcd_init(void) void usbtmcd_init(void)
{ {
#ifndef NDEBUG
# if USBTMC_CFG_ENABLE_488 # if USBTMC_CFG_ENABLE_488
if(usbtmcd_app_capabilities.bmIntfcCapabilities488.supportsTrigger) if(usbtmcd_app_capabilities.bmIntfcCapabilities488.supportsTrigger)
TU_ASSERT(&usbtmcd_app_msg_trigger != NULL,); TU_ASSERT(&usbtmcd_app_msg_trigger != NULL,);
# endif # endif
if(usbtmcd_app_capabilities.bmIntfcCapabilities.supportsIndicatorPulse) if(usbtmcd_app_capabilities.bmIntfcCapabilities.supportsIndicatorPulse)
TU_ASSERT(&usbtmcd_app_indicator_pluse != NULL,); TU_ASSERT(&usbtmcd_app_indicator_pluse != NULL,);
#endif
} }
bool usbtmcd_open(uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint16_t *p_length) 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; break;
case TUSB_XFER_INTERRUPT: case TUSB_XFER_INTERRUPT:
#ifndef NDEBUG
TU_ASSERT(tu_edpt_dir(ep_desc->bEndpointAddress) == TUSB_DIR_IN); TU_ASSERT(tu_edpt_dir(ep_desc->bEndpointAddress) == TUSB_DIR_IN);
TU_ASSERT(usbtmc_state.ep_int_in == 0); TU_ASSERT(usbtmc_state.ep_int_in == 0);
#endif
usbtmc_state.ep_int_in = ep_desc->bEndpointAddress; usbtmc_state.ep_int_in = ep_desc->bEndpointAddress;
break; break;
default: 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 // 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_in != 0);
TU_ASSERT(usbtmc_state.ep_bulk_out != 0); TU_ASSERT(usbtmc_state.ep_bulk_out != 0);
if (itf_desc->bNumEndpoints == 2) { 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); 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)); TU_VERIFY( usbd_edpt_xfer(rhport, usbtmc_state.ep_bulk_out, usbtmc_state.ep_bulk_out_buf, 64));
return true; 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 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); memcpy(usbtmc_state.ep_bulk_in_buf, usbtmc_state.devInBuffer, usbtmc_state.transfer_size_remaining);
while((packetLen % 4) != 0) 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; uint8_t tmcStatusCode = USBTMC_STATUS_FAILED;
#if (USBTMC_CFG_ENABLE_488) #if (USBTMC_CFG_ENABLE_488)
ushort bTag; uint8_t bTag;
#endif #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. // We only handle class requests, IN direction.
// (for now) // (for now)
if(request->bmRequestType_bit.type != TUSB_REQ_TYPE_CLASS) 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->bmRequestType == 0xA2); // in,class,EP
TU_VERIFY(request->wLength == 1u); TU_VERIFY(request->wLength == 1u);
tmcStatusCode = USBTMC_STATUS_FAILED; 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; 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. // control endpoint response shown in Table 31, and clear all input buffers and output buffers.
usbd_edpt_stall(rhport, usbtmc_state.ep_bulk_out); usbd_edpt_stall(rhport, usbtmc_state.ep_bulk_out);
TU_VERIFY(usbtmcd_app_initiate_clear(rhport, &tmcStatusCode)); 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; 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(request->wLength == sizeof(clearStatusRsp));
TU_VERIFY(usbtmcd_app_get_clear_status(rhport, &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; 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 = usbtmc_read_stb_interrupt_488_t intMsg =
{ {
.bNotify1 = (uint8_t)(0x80 | bTag), .bNotify1 = {
.one = 1,
.bTag = bTag & 0x7Fu,
},
.StatusByte = usbtmcd_app_get_stb(rhport, &(rsp.USBTMC_status)) .StatusByte = usbtmcd_app_get_stb(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 else
{ {
@ -503,6 +528,7 @@ bool usbtmcd_control_request(uint8_t rhport, tusb_control_request_t const * requ
default: default:
TU_VERIFY(false); TU_VERIFY(false);
return false;
} }
TU_VERIFY(false); TU_VERIFY(false);
} }

View File

@ -56,13 +56,13 @@ extern usbtmc_response_capabilities_t const usbtmcd_app_capabilities;
#endif #endif
bool usbtmcd_app_msgBulkOut_start(uint8_t rhport, 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. // 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); 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_request(uint8_t rhport, usbtmc_msg_request_dev_dep_in const * request);
bool usbtmcd_app_msgBulkIn_complete(uint8_t rhport); 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); 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_CLASS TUSB_CLASS_APPLICATION_SPECIFIC
#define USBTMC_APP_SUBCLASS 0x03 #define USBTMC_APP_SUBCLASS 0x03u
#define USBTMC_PROTOCOL_STD 0x00 #define USBTMC_PROTOCOL_STD 0x00u
#define USBTMC_PROTOCOL_USB488 0x01 #define USBTMC_PROTOCOL_USB488 0x01u
// Interface number, number of endpoints, EP string index, USB_TMC_PROTOCOL*, bulk-out endpoint ID, // Interface number, number of endpoints, EP string index, USB_TMC_PROTOCOL*, bulk-out endpoint ID,
// bulk-in endpoint ID // bulk-in endpoint ID