aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--libmaple/usb/descriptors.h25
-rw-r--r--libmaple/usb/usb.c30
-rw-r--r--libmaple/usb/usb.h8
-rw-r--r--libmaple/usb/usb_callbacks.c8
-rw-r--r--wirish/usb_serial.cpp14
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;
}