diff options
-rw-r--r-- | libmaple/usb/descriptors.h | 25 | ||||
-rw-r--r-- | libmaple/usb/usb.c | 30 | ||||
-rw-r--r-- | libmaple/usb/usb.h | 8 | ||||
-rw-r--r-- | libmaple/usb/usb_callbacks.c | 8 | ||||
-rw-r--r-- | wirish/usb_serial.cpp | 14 |
5 files changed, 56 insertions, 29 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 c0fcec0..84390cb 100644 --- a/libmaple/usb/usb.h +++ b/libmaple/usb/usb.h @@ -72,10 +72,10 @@ void usbEnbISR(void); void usb_lpIRQHandler(void); void usbWaitReset(void); -/* nonblocking functions for send/receive */ -uint16 usbSendBytes(uint8* sendBuf,uint16 len); -uint8 usbBytesAvailable(void); -uint8 usbReceiveBytes(uint8* recvBuf, uint8 len); +/* blocking functions for send/receive */ +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) { diff --git a/wirish/usb_serial.cpp b/wirish/usb_serial.cpp index 5c8a65f..d4a8148 100644 --- a/wirish/usb_serial.cpp +++ b/wirish/usb_serial.cpp @@ -101,17 +101,27 @@ uint32 USBSerial::available(void) { return usbBytesAvailable(); } +/* blocks forever until len_bytes is received */ uint32 USBSerial::read(void *buf, uint32 len) { if (!buf) { return 0; } - return usbReceiveBytes((uint8*)buf, len); + uint32 bytes_in = 0; + while (len > 0) { + uint32 new_bytes = usbReceiveBytes(&(uint8)buf[new_bytes], len); + len -= newBytes; + bytes_in += new_bytes; + } + + return len; } +/* blocks forever until 1 byte is received */ uint8 USBSerial::read(void) { uint8 ch; - usbReceiveBytes(&ch, 1); + + while (usbReceiveBytes(&ch, 1) == 0); return ch; } |