Let application control interface latency...

This commit is contained in:
Nathan Conrad 2019-09-24 13:11:45 -04:00
parent e61f2b7393
commit 10105557dc
3 changed files with 74 additions and 19 deletions

View File

@ -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;

View File

@ -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;
}

View File

@ -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 */