diff --git a/cdcacm.cpp b/cdcacm.cpp index 08f9ac7b..87fb421b 100644 --- a/cdcacm.cpp +++ b/cdcacm.cpp @@ -278,39 +278,84 @@ uint8_t ACM::Poll() { } uint8_t ACM::RcvData(uint16_t *bytes_rcvd, uint8_t *dataptr) { - return pUsb->inTransfer(bAddress, epInfo[epDataInIndex].epAddr, bytes_rcvd, dataptr); + uint8_t rv; + rv = pUsb->inTransfer(bAddress, epInfo[epDataInIndex].epAddr, bytes_rcvd, dataptr); + if(rv && rv != hrNAK) { + Release(); + } + return rv; } uint8_t ACM::SndData(uint16_t nbytes, uint8_t *dataptr) { - return pUsb->outTransfer(bAddress, epInfo[epDataOutIndex].epAddr, nbytes, dataptr); + uint8_t rv; + rv = pUsb->outTransfer(bAddress, epInfo[epDataOutIndex].epAddr, nbytes, dataptr); + if(rv && rv != hrNAK) { + Release(); + } + return rv; } uint8_t ACM::SetCommFeature(uint16_t fid, uint8_t nbytes, uint8_t *dataptr) { - return ( pUsb->ctrlReq(bAddress, 0, bmREQ_CDCOUT, CDC_SET_COMM_FEATURE, (fid & 0xff), (fid >> 8), bControlIface, nbytes, nbytes, dataptr, NULL)); + uint8_t rv; + rv = ( pUsb->ctrlReq(bAddress, 0, bmREQ_CDCOUT, CDC_SET_COMM_FEATURE, (fid & 0xff), (fid >> 8), bControlIface, nbytes, nbytes, dataptr, NULL)); + if(rv && rv != hrNAK) { + Release(); + } + return rv; } uint8_t ACM::GetCommFeature(uint16_t fid, uint8_t nbytes, uint8_t *dataptr) { - return ( pUsb->ctrlReq(bAddress, 0, bmREQ_CDCIN, CDC_GET_COMM_FEATURE, (fid & 0xff), (fid >> 8), bControlIface, nbytes, nbytes, dataptr, NULL)); + uint8_t rv; + if(rv && rv != hrNAK) { + Release(); + } + return rv; + rv = ( pUsb->ctrlReq(bAddress, 0, bmREQ_CDCIN, CDC_GET_COMM_FEATURE, (fid & 0xff), (fid >> 8), bControlIface, nbytes, nbytes, dataptr, NULL)); } uint8_t ACM::ClearCommFeature(uint16_t fid) { - return ( pUsb->ctrlReq(bAddress, 0, bmREQ_CDCOUT, CDC_CLEAR_COMM_FEATURE, (fid & 0xff), (fid >> 8), bControlIface, 0, 0, NULL, NULL)); + uint8_t rv; + rv = ( pUsb->ctrlReq(bAddress, 0, bmREQ_CDCOUT, CDC_CLEAR_COMM_FEATURE, (fid & 0xff), (fid >> 8), bControlIface, 0, 0, NULL, NULL)); + if(rv && rv != hrNAK) { + Release(); + } + return rv; } uint8_t ACM::SetLineCoding(const LINE_CODING *dataptr) { - return ( pUsb->ctrlReq(bAddress, 0, bmREQ_CDCOUT, CDC_SET_LINE_CODING, 0x00, 0x00, bControlIface, sizeof (LINE_CODING), sizeof (LINE_CODING), (uint8_t*)dataptr, NULL)); + uint8_t rv; + rv = ( pUsb->ctrlReq(bAddress, 0, bmREQ_CDCOUT, CDC_SET_LINE_CODING, 0x00, 0x00, bControlIface, sizeof (LINE_CODING), sizeof (LINE_CODING), (uint8_t*)dataptr, NULL)); + if(rv && rv != hrNAK) { + Release(); + } + return rv; } uint8_t ACM::GetLineCoding(LINE_CODING *dataptr) { - return ( pUsb->ctrlReq(bAddress, 0, bmREQ_CDCIN, CDC_GET_LINE_CODING, 0x00, 0x00, bControlIface, sizeof (LINE_CODING), sizeof (LINE_CODING), (uint8_t*)dataptr, NULL)); + uint8_t rv; + rv = ( pUsb->ctrlReq(bAddress, 0, bmREQ_CDCIN, CDC_GET_LINE_CODING, 0x00, 0x00, bControlIface, sizeof (LINE_CODING), sizeof (LINE_CODING), (uint8_t*)dataptr, NULL)); + if(rv && rv != hrNAK) { + Release(); + } + return rv; } uint8_t ACM::SetControlLineState(uint8_t state) { - return ( pUsb->ctrlReq(bAddress, 0, bmREQ_CDCOUT, CDC_SET_CONTROL_LINE_STATE, state, 0, bControlIface, 0, 0, NULL, NULL)); + uint8_t rv; + rv = ( pUsb->ctrlReq(bAddress, 0, bmREQ_CDCOUT, CDC_SET_CONTROL_LINE_STATE, state, 0, bControlIface, 0, 0, NULL, NULL)); + if(rv && rv != hrNAK) { + Release(); + } + return rv; } uint8_t ACM::SendBreak(uint16_t duration) { - return ( pUsb->ctrlReq(bAddress, 0, bmREQ_CDCOUT, CDC_SEND_BREAK, (duration & 0xff), (duration >> 8), bControlIface, 0, 0, NULL, NULL)); + uint8_t rv; + rv = ( pUsb->ctrlReq(bAddress, 0, bmREQ_CDCOUT, CDC_SEND_BREAK, (duration & 0xff), (duration >> 8), bControlIface, 0, 0, NULL, NULL)); + if(rv && rv != hrNAK) { + Release(); + } + return rv; } void ACM::PrintEndpointDescriptor(const USB_ENDPOINT_DESCRIPTOR* ep_ptr) { diff --git a/cdcftdi.cpp b/cdcftdi.cpp index f0f5d0d1..ccc46e36 100644 --- a/cdcftdi.cpp +++ b/cdcftdi.cpp @@ -182,7 +182,7 @@ uint8_t FTDI::Init(uint8_t parent, uint8_t port, bool lowspeed) { USBTRACE("FTDI configured\r\n"); - bPollEnable = true; + ready = true; return 0; FailGetDevDescr: @@ -254,6 +254,7 @@ uint8_t FTDI::Release() { bNumEP = 1; qNextPollTime = 0; bPollEnable = false; + ready = false; return pAsync->OnRelease(this); } @@ -275,7 +276,7 @@ uint8_t FTDI::Poll() { uint8_t FTDI::SetBaudRate(uint32_t baud) { uint16_t baud_value, baud_index = 0; uint32_t divisor3; - + uint8_t rv = 0; divisor3 = 48000000 / 2 / baud; // divisor shifted 3 bits to the left if(wFTDIType == FT232AM) { @@ -306,27 +307,56 @@ uint8_t FTDI::SetBaudRate(uint32_t baud) { } USBTRACE2("baud_value:", baud_value); USBTRACE2("baud_index:", baud_index); - return pUsb->ctrlReq(bAddress, 0, bmREQ_FTDI_OUT, FTDI_SIO_SET_BAUD_RATE, baud_value & 0xff, baud_value >> 8, baud_index, 0, 0, NULL, NULL); + rv = pUsb->ctrlReq(bAddress, 0, bmREQ_FTDI_OUT, FTDI_SIO_SET_BAUD_RATE, baud_value & 0xff, baud_value >> 8, baud_index, 0, 0, NULL, NULL); + if(rv && rv != hrNAK) { + Release(); + } + return rv; } uint8_t FTDI::SetModemControl(uint16_t signal) { - return pUsb->ctrlReq(bAddress, 0, bmREQ_FTDI_OUT, FTDI_SIO_MODEM_CTRL, signal & 0xff, signal >> 8, 0, 0, 0, NULL, NULL); + uint8_t rv; + rv = pUsb->ctrlReq(bAddress, 0, bmREQ_FTDI_OUT, FTDI_SIO_MODEM_CTRL, signal & 0xff, signal >> 8, 0, 0, 0, NULL, NULL); + if(rv && rv != hrNAK) { + Release(); + } + return rv; } uint8_t FTDI::SetFlowControl(uint8_t protocol, uint8_t xon, uint8_t xoff) { - return pUsb->ctrlReq(bAddress, 0, bmREQ_FTDI_OUT, FTDI_SIO_SET_FLOW_CTRL, xon, xoff, protocol << 8, 0, 0, NULL, NULL); + uint8_t rv; + rv = pUsb->ctrlReq(bAddress, 0, bmREQ_FTDI_OUT, FTDI_SIO_SET_FLOW_CTRL, xon, xoff, protocol << 8, 0, 0, NULL, NULL); + if(rv && rv != hrNAK) { + Release(); + } + return rv; } uint8_t FTDI::SetData(uint16_t databm) { - return pUsb->ctrlReq(bAddress, 0, bmREQ_FTDI_OUT, FTDI_SIO_SET_DATA, databm & 0xff, databm >> 8, 0, 0, 0, NULL, NULL); + uint8_t rv; + rv = pUsb->ctrlReq(bAddress, 0, bmREQ_FTDI_OUT, FTDI_SIO_SET_DATA, databm & 0xff, databm >> 8, 0, 0, 0, NULL, NULL); + if(rv && rv != hrNAK) { + Release(); + } + return rv; } uint8_t FTDI::RcvData(uint16_t *bytes_rcvd, uint8_t *dataptr) { - return pUsb->inTransfer(bAddress, epInfo[epDataInIndex].epAddr, bytes_rcvd, dataptr); + uint8_t rv; + rv = pUsb->inTransfer(bAddress, epInfo[epDataInIndex].epAddr, bytes_rcvd, dataptr); + if(rv && rv != hrNAK) { + Release(); + } + return rv; } uint8_t FTDI::SndData(uint16_t nbytes, uint8_t *dataptr) { - return pUsb->outTransfer(bAddress, epInfo[epDataOutIndex].epAddr, nbytes, dataptr); + uint8_t rv; + rv = pUsb->outTransfer(bAddress, epInfo[epDataOutIndex].epAddr, nbytes, dataptr); + if(rv && rv != hrNAK) { + Release(); + } + return rv; } void FTDI::PrintEndpointDescriptor(const USB_ENDPOINT_DESCRIPTOR* ep_ptr) { diff --git a/cdcftdi.h b/cdcftdi.h index f6ee7e8c..435891da 100644 --- a/cdcftdi.h +++ b/cdcftdi.h @@ -105,7 +105,8 @@ class FTDI : public USBDeviceConfig, public UsbConfigXtracter { uint8_t bNumIface; // number of interfaces in the configuration uint8_t bNumEP; // total number of EP in the configuration uint32_t qNextPollTime; // next poll time - bool bPollEnable; // poll enable flag + volatile bool bPollEnable; // poll enable flag + volatile bool ready; //device ready indicator uint16_t wFTDIType; // Type of FTDI chip uint16_t wIdProduct; // expected PID @@ -141,10 +142,9 @@ public: return (vid == FTDI_VID && pid == FTDI_PID); } virtual bool isReady() { - return bPollEnable; + return ready; }; - }; #endif // __CDCFTDI_H__