usbtmc updates....
This commit is contained in:
		| @@ -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 | ||||
|   | ||||
| @@ -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; | ||||
|   } | ||||
|   | ||||
| @@ -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); | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Nathan Conrad
					Nathan Conrad