diff options
author | AJM <poslathian@poslathian.(none)> | 2010-12-13 22:03:14 -0500 |
---|---|---|
committer | AJM <poslathian@poslathian.(none)> | 2010-12-13 22:03:14 -0500 |
commit | 873356a31fae8cf4e8b6a5ab609125a5a501d1c4 (patch) | |
tree | 7747300a71f5597ef048128c47ec267a59e9e04b | |
parent | b67d281d85bd59a9738a9a43c4db1027f81d9208 (diff) | |
download | librambutan-873356a31fae8cf4e8b6a5ab609125a5a501d1c4.tar.gz librambutan-873356a31fae8cf4e8b6a5ab609125a5a501d1c4.zip |
candidate bugfix for serialusb receive bug
changed USB driver to nak whenever it cant fill an entire endpoint (64B) worth of new data. The old scheme was to set receive valid as long as as the endpoint buffer wasnt full, the new scheme is to nak until it is completely empty.
-rw-r--r-- | libmaple/usb/descriptors.h | 25 | ||||
-rw-r--r-- | libmaple/usb/usb.c | 30 | ||||
-rw-r--r-- | libmaple/usb/usb.h | 6 | ||||
-rw-r--r-- | libmaple/usb/usb_callbacks.c | 8 |
4 files changed, 43 insertions, 26 deletions
diff --git a/libmaple/usb/descriptors.h b/libmaple/usb/descriptors.h index 6652942..6f7d08b 100644 --- a/libmaple/usb/descriptors.h +++ b/libmaple/usb/descriptors.h @@ -1,4 +1,27 @@ -/* insert license */ +/* ***************************************************************************** + * The MIT License + * + * Copyright (c) 2010 LeafLabs LLC. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * ****************************************************************************/ + #ifndef __DESCRIPTORS_H #define __DESCRIPTORS_H diff --git a/libmaple/usb/usb.c b/libmaple/usb/usb.c index 923e54b..2b99132 100644 --- a/libmaple/usb/usb.c +++ b/libmaple/usb/usb.c @@ -332,23 +332,11 @@ void usbWaitReset(void) { * This function will quickly copy up to 64 bytes of data (out of an * arbitrarily large buffer) into the USB peripheral TX buffer and return the * number placed in that buffer. It is up to usercode to divide larger packets - * into 64-byte chunks to guarantee delivery. Use usbGetCountTx() to determine - * whether the bytes were ACTUALLY recieved by the host or just transfered to - * the buffer. + * into 64-byte chunks to guarantee delivery. * - * The function will return -1 if it doesn't think that the USB host is - * "connected", but it can't detect this state robustly. "Connected" in this - * context means that an actual program on the Host operating system is - * connected to the virtual COM/ttyACM device and is recieving the bytes; the - * Host operating system is almost always configured and keeping this endpoint - * alive, but the bytes never get read out of the endpoint buffer. - * - * The behavior of this function is subtle and frustrating; it has gone through - * many simpler and cleaner implementation that frustratingly don't work cross - * platform. - * - * */ -uint16 usbSendBytes(uint8* sendBuf, uint16 len) { + * + */ +uint32 usbSendBytes(uint8* sendBuf, uint16 len) { uint16 loaded = 0; @@ -384,7 +372,7 @@ uint16 usbSendBytes(uint8* sendBuf, uint16 len) { } /* returns the number of available bytes are in the recv FIFO */ -uint8 usbBytesAvailable(void) { +uint32 usbBytesAvailable(void) { return VCOM_RX_EPSIZE - maxNewBytes; } @@ -392,7 +380,7 @@ uint8 usbBytesAvailable(void) { usb packet buffer) into recvBuf and deq's the fifo. will only copy the minimum of len or the available bytes. returns the number of bytes copied */ -uint8 usbReceiveBytes(uint8* recvBuf, uint8 len) { +uint32 usbReceiveBytes(uint8* recvBuf, uint8 len) { if (len > VCOM_RX_EPSIZE - maxNewBytes) { len = VCOM_RX_EPSIZE - maxNewBytes; } @@ -403,11 +391,13 @@ uint8 usbReceiveBytes(uint8* recvBuf, uint8 len) { recvBufOut = (recvBufOut + 1) % VCOM_RX_EPSIZE; } - maxNewBytes += len; + maxNewBytes += len; /* is this the potential bug? */ + // assert(maxNewBytes < VCOM_RX_EPSIZE) /* re-enable the rx endpoint which we had set to receive 0 bytes */ - if (maxNewBytes - len == 0) { + if (maxNewBytes >= VCOM_RX_EPSIZE) { SetEPRxCount(VCOM_RX_ENDP,maxNewBytes); + SetEPRxStatus(VCOM_RX_ENDP,EP_RX_VALID); } return len; diff --git a/libmaple/usb/usb.h b/libmaple/usb/usb.h index ffba9ff..84390cb 100644 --- a/libmaple/usb/usb.h +++ b/libmaple/usb/usb.h @@ -73,9 +73,9 @@ void usb_lpIRQHandler(void); void usbWaitReset(void); /* blocking functions for send/receive */ -uint16 usbSendBytes(uint8* sendBuf,uint16 len); -uint8 usbBytesAvailable(void); -uint8 usbReceiveBytes(uint8* recvBuf, uint8 len); +uint32 usbSendBytes(uint8* sendBuf,uint16 len); +uint32 usbBytesAvailable(void); +uint32 usbReceiveBytes(uint8* recvBuf, uint8 len); uint8 usbGetDTR(void); uint8 usbGetRTS(void); uint8 usbIsConnected(void); diff --git a/libmaple/usb/usb_callbacks.c b/libmaple/usb/usb_callbacks.c index 4cdaf73..c30d650 100644 --- a/libmaple/usb/usb_callbacks.c +++ b/libmaple/usb/usb_callbacks.c @@ -132,8 +132,12 @@ void vcomDataRxCb(void) { } maxNewBytes -= newBytes; - SetEPRxCount(VCOM_RX_ENDP,maxNewBytes); - SetEPRxValid(VCOM_RX_ENDP); + + if (maxNewBytes > VCOM_RX_EPSIZE) { + SetEPRxCount(VCOM_RX_ENDP,0); + SetEPRxStatus(VCOM_RX_ENDP,EP_RX_NAK); /* nak until we clear the buffer */ + } + } void vcomManagementCb(void) { |