FTDI Latency timer Getter/setter

This commit is contained in:
Andrew J. Kroll 2018-11-18 04:47:51 -05:00
parent 5c303ed62c
commit ffaba6dad3
2 changed files with 59 additions and 18 deletions

View file

@ -86,8 +86,7 @@ uint8_t FTDI::Init(uint8_t parent, uint8_t port, bool lowspeed) {
if(rcode) { if(rcode) {
goto FailGetDevDescr; goto FailGetDevDescr;
} }
if(udd->idVendor != FTDI_VID || udd->idProduct != wIdProduct) if(udd->idVendor != FTDI_VID || udd->idProduct != wIdProduct) {
{
USBTRACE("FTDI Init: Product not supported\r\n"); USBTRACE("FTDI Init: Product not supported\r\n");
USBTRACE2("Expected VID:", FTDI_VID); USBTRACE2("Expected VID:", FTDI_VID);
USBTRACE2("Found VID:", udd->idVendor); USBTRACE2("Found VID:", udd->idVendor);
@ -108,6 +107,9 @@ uint8_t FTDI::Init(uint8_t parent, uint8_t port, bool lowspeed) {
// Extract Max Packet Size from the device descriptor // Extract Max Packet Size from the device descriptor
epInfo[0].maxPktSize = udd->bMaxPacketSize0; epInfo[0].maxPktSize = udd->bMaxPacketSize0;
// Some devices set endpoint lengths to zero, which is incorrect.
// we should check them, and if zero, set them to 64.
if(epInfo[0].maxPktSize == 0) epInfo[0].maxPktSize = 64;
// Assign new address to the device // Assign new address to the device
rcode = pUsb->setAddr(0, 0, bAddress); rcode = pUsb->setAddr(0, 0, bAddress);
@ -175,6 +177,12 @@ uint8_t FTDI::Init(uint8_t parent, uint8_t port, bool lowspeed) {
if(rcode) if(rcode)
goto FailSetConfDescr; goto FailSetConfDescr;
// default latency is 16ms on-chip, reduce it to 1
rcode = SetLatency(1);
if(rcode)
goto FailOnLatency;
rcode = pAsync->OnInit(this); rcode = pAsync->OnInit(this);
if(rcode) if(rcode)
@ -185,6 +193,12 @@ uint8_t FTDI::Init(uint8_t parent, uint8_t port, bool lowspeed) {
ready = true; ready = true;
return 0; return 0;
FailOnLatency:
#ifdef DEBUG_USB_HOST
USBTRACE("SetLatency: ");
goto Fail;
#endif
FailGetDevDescr: FailGetDevDescr:
#ifdef DEBUG_USB_HOST #ifdef DEBUG_USB_HOST
NotifyFailGetDevDescr(); NotifyFailGetDevDescr();
@ -241,6 +255,9 @@ void FTDI::EndpointXtract(uint8_t conf, uint8_t iface, uint8_t alt, uint8_t prot
epInfo[index].maxPktSize = (uint8_t)pep->wMaxPacketSize; epInfo[index].maxPktSize = (uint8_t)pep->wMaxPacketSize;
epInfo[index].bmSndToggle = 0; epInfo[index].bmSndToggle = 0;
epInfo[index].bmRcvToggle = 0; epInfo[index].bmRcvToggle = 0;
// Some device vendors set endpoint lengths to zero, which is incorrect.
// Check, and if zero, set to 64.
if(epInfo[index].maxPktSize == 0) epInfo[index].maxPktSize = 64;
bNumEP++; bNumEP++;
@ -313,6 +330,26 @@ uint8_t FTDI::SetBaudRate(uint32_t baud) {
return rv; return rv;
} }
// No docs on if this is 8 or 16 bit, so play it safe, make maximum 255ms
uint8_t FTDI::SetLatency(uint8_t l) {
uint8_t rv = pUsb->ctrlReq(bAddress, 0, bmREQ_FTDI_OUT, FTDI_SIO_SET_LATENCY_TIMER, l, 0, 0, 0, 0, NULL, NULL);
if(rv && rv != hrNAK) {
Release();
}
return rv;
}
// No docs on if this is 8 or 16 bit, so play it safe, make maximum 255ms
uint8_t FTDI::GetLatency(uint8_t *l) {
uint8_t rv = pUsb->ctrlReq(bAddress, 0, bmREQ_FTDI_OUT, FTDI_SIO_GET_LATENCY_TIMER, 0, 0, 0, 0, 1, (uint8_t *)l, NULL);
if(rv && rv != hrNAK) {
Release();
}
return rv;
}
uint8_t FTDI::SetModemControl(uint16_t signal) { uint8_t FTDI::SetModemControl(uint16_t signal) {
uint8_t rv = pUsb->ctrlReq(bAddress, 0, bmREQ_FTDI_OUT, FTDI_SIO_MODEM_CTRL, signal & 0xff, signal >> 8, 0, 0, 0, NULL, NULL); uint8_t 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) { if(rv && rv != hrNAK) {

View file

@ -42,6 +42,8 @@ e-mail : support@circuitsathome.com
#define FTDI_SIO_GET_MODEM_STATUS 5 /* Retrieve current value of modem status register */ #define FTDI_SIO_GET_MODEM_STATUS 5 /* Retrieve current value of modem status register */
#define FTDI_SIO_SET_EVENT_CHAR 6 /* Set the event character */ #define FTDI_SIO_SET_EVENT_CHAR 6 /* Set the event character */
#define FTDI_SIO_SET_ERROR_CHAR 7 /* Set the error character */ #define FTDI_SIO_SET_ERROR_CHAR 7 /* Set the error character */
#define FTDI_SIO_SET_LATENCY_TIMER 9 /* Set the latency timer */
#define FTDI_SIO_GET_LATENCY_TIMER 10 /* Get the latency timer */
#define FTDI_SIO_RESET_SIO 0 #define FTDI_SIO_RESET_SIO 0
#define FTDI_SIO_RESET_PURGE_RX 1 #define FTDI_SIO_RESET_PURGE_RX 1
@ -121,8 +123,10 @@ public:
uint8_t SetModemControl(uint16_t control); uint8_t SetModemControl(uint16_t control);
uint8_t SetFlowControl(uint8_t protocol, uint8_t xon = 0x11, uint8_t xoff = 0x13); uint8_t SetFlowControl(uint8_t protocol, uint8_t xon = 0x11, uint8_t xoff = 0x13);
uint8_t SetData(uint16_t databm); uint8_t SetData(uint16_t databm);
uint8_t SetLatency(uint8_t l);
uint8_t GetLatency(uint8_t *l);
// Methods for recieving and sending data // Methods for receiving and sending data
uint8_t RcvData(uint16_t *bytes_rcvd, uint8_t *dataptr); uint8_t RcvData(uint16_t *bytes_rcvd, uint8_t *dataptr);
uint8_t SndData(uint16_t nbytes, uint8_t *dataptr); uint8_t SndData(uint16_t nbytes, uint8_t *dataptr);
@ -139,7 +143,7 @@ public:
void EndpointXtract(uint8_t conf, uint8_t iface, uint8_t alt, uint8_t proto, const USB_ENDPOINT_DESCRIPTOR *ep); void EndpointXtract(uint8_t conf, uint8_t iface, uint8_t alt, uint8_t proto, const USB_ENDPOINT_DESCRIPTOR *ep);
virtual bool VIDPIDOK(uint16_t vid, uint16_t pid) { virtual bool VIDPIDOK(uint16_t vid, uint16_t pid) {
return (vid == FTDI_VID && pid == wIdProduct); return (vid == FTDI_VID && pid == FTDI_PID);
} }
virtual bool isReady() { virtual bool isReady() {
return ready; return ready;