aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fw/usb.c126
-rw-r--r--sw/usbcom/usbcom.c17
2 files changed, 78 insertions, 65 deletions
diff --git a/fw/usb.c b/fw/usb.c
index 2992888..a843945 100644
--- a/fw/usb.c
+++ b/fw/usb.c
@@ -2,6 +2,7 @@
#include <stdbool.h>
#include <stdint.h>
+#include <string.h>
#include <usb.h>
#include <usb_device.h>
@@ -20,8 +21,7 @@ enum {
// State
typedef enum {
- IDLE, // waiting for command
- CMD_START, // received opcode
+ IDLE,
ECHO,
WRITE_EEPROM,
READ_EEPROM,
@@ -29,75 +29,88 @@ typedef enum {
static uint8_t readBuf[CDC_DATA_OUT_EP_SIZE];
static uint8_t writeBuf[CDC_DATA_IN_EP_SIZE];
-static State state = IDLE;
+static uint8_t readLen = 0u;
// Handle "e" echo command.
-static void
+// Returns the next state.
+static State
echo(void) {
- static uint8_t readLen = 0u;
- static uint8_t ri, wi;
-
- if (!USBUSARTIsTxTrfReady()) {
- return;
- }
+ uint8_t i;
+ State state = ECHO;
if (readLen == 0u) {
readLen = getsUSBUSART(readBuf, sizeof(readBuf));
- ri = 0u;
- wi = 0u;
}
- while (readLen--) {
- if (wi > sizeof(writeBuf)) {
- // Overflow; flush
- putUSBUSART(writeBuf, sizeof(writeBuf));
- wi = 0u;
- return; // continue on next call
- }
-
- writeBuf[wi] = readBuf[ri];
- if (readBuf[ri] == '\n') {
+ for (i = 0u; i < readLen; i++) {
+ writeBuf[i] = readBuf[i];
+ if (readBuf[i] == '\n') {
// End of command
- putUSBUSART(writeBuf, wi);
- readLen = 0u;
state = IDLE;
- return;
+ i++;
+ break;
}
+ }
- ri++;
- wi++;
+ if (readLen > 0u) {
+ putUSBUSART(writeBuf, i);
}
+ readLen = 0u;
+
+ return state;
}
// Handle "w" write eeprom command.
-static void
+// Returns the next state.
+static State
writeEeprom(void) {
// TODO
+ return IDLE;
}
// Handle "r" read eeprom command.
-static void readEeprom(void) {
+// Returns the next state.
+static State
+readEeprom(void) {
// TODO
+ return IDLE;
}
-static void
-setCmdState(uint8_t opcode) {
+static State
+cmdState(uint8_t opcode) {
switch (opcode) {
- case 'e': // echo
- state = ECHO;
- break;
- case 'w':
- state = WRITE_EEPROM;
- break;
- case 'r':
- state = READ_EEPROM;
- break;
+ case 'e': return ECHO;
+ case 'w': return WRITE_EEPROM;
+ case 'r': return READ_EEPROM;
+ default: return IDLE; // invalid command
}
}
+// Read (the start of) a command from USB.
+// Leaves <args> at the beginning of the read buffer.
+// Returns the next state based on the opcode of the command.
+static State
+readCmd(void) {
+ uint8_t opcode;
+
+ readLen = getsUSBUSART(readBuf, sizeof(readBuf));
+ if (readLen < 2u) {
+ // Invalid command. Must start with <opcode> <space>
+ return IDLE;
+ }
+
+ opcode = readBuf[0u];
+
+ // skip <opcode> <space>
+ memmove(readBuf, readBuf+2u, readLen-2u);
+ readLen -= 2u;
+
+ return cmdState(opcode);
+}
+
void
usbTask(void) {
- static uint8_t opcode = 0u;
+ static State state = IDLE;
USBDeviceTasks();
@@ -108,23 +121,13 @@ usbTask(void) {
return;
}
- switch (state) {
- case IDLE:
- if (getsUSBUSART(&opcode, 1u) > 0) {
- state = CMD_START;
- }
- break;
- case CMD_START:
- // Skip space char
- if (getsUSBUSART(readBuf, 1u) > 0) {
- setCmdState(opcode);
+ if (USBUSARTIsTxTrfReady()) {
+ switch (state) {
+ case IDLE: state = readCmd(); break;
+ case ECHO: state = echo(); break;
+ case WRITE_EEPROM: state = writeEeprom(); break;
+ case READ_EEPROM: state = readEeprom(); break;
}
- case ECHO: echo();
- break;
- case WRITE_EEPROM: writeEeprom();
- break;
- case READ_EEPROM: readEeprom();
- break;
}
CDCTxService();
@@ -143,25 +146,34 @@ USER_USB_CALLBACK_EVENT_HANDLER(USB_EVENT event, void *pdata, uint16_t size) {
switch ((int)event) {
case EVENT_TRANSFER:
break;
+
case EVENT_SOF:
break;
+
case EVENT_SUSPEND:
break;
+
case EVENT_RESUME:
break;
+
case EVENT_CONFIGURED:
CDCInitEP();
configure();
break;
+
case EVENT_SET_DESCRIPTOR:
break;
+
case EVENT_EP0_REQUEST:
USBCheckCDCRequest();
break;
+
case EVENT_BUS_ERROR:
break;
+
case EVENT_TRANSFER_TERMINATED:
break;
+
default:
break;
}
diff --git a/sw/usbcom/usbcom.c b/sw/usbcom/usbcom.c
index 920b4a1..1568d88 100644
--- a/sw/usbcom/usbcom.c
+++ b/sw/usbcom/usbcom.c
@@ -8,7 +8,7 @@
#define TIMEOUT_MS 1000
-#define BUF_SIZE 64
+#define BUF_SIZE 512
#define INTERFACE 0
@@ -94,9 +94,9 @@ txChars(libusb_device_handle *devh, unsigned char *data, int n) {
while (actualLen < n) {
res = libusb_bulk_transfer(devh, EP_OUT_ADDR, data, n, &actualLen, TIMEOUT_MS);
if (res == LIBUSB_ERROR_TIMEOUT) {
- printf("Timeout (%d)\n", actualLen);
+ printf("Tx timeout (%d)\n", actualLen);
} else if (res < 0) {
- fprintf(stderr, "Error sending data\n");
+ fprintf(stderr, "Tx error: %s\n", libusb_strerror(res));
}
assert(actualLen <= n);
n -= actualLen;
@@ -108,17 +108,17 @@ txChars(libusb_device_handle *devh, unsigned char *data, int n) {
// Returns number of bytes read, or -1 on error
static int
rxChars(libusb_device_handle *devh, unsigned char *data, int size) {
- int res, actualLen;
+ int res, len;
- res = libusb_bulk_transfer(devh, EP_IN_ADDR, data, size, &actualLen, TIMEOUT_MS);
+ res = libusb_bulk_transfer(devh, EP_IN_ADDR, data, size, &len, TIMEOUT_MS);
if (res == LIBUSB_ERROR_TIMEOUT) {
- fprintf(stderr, "Timeout\n");
+ fprintf(stderr, "Rx timeout\n");
return -1;
} else if (res < 0) {
- fprintf(stderr, "Error receiving data\n");
+ fprintf(stderr, "Rx error: %s\n", libusb_strerror(res));
return -1;
}
- return actualLen;
+ return len;
}
// Get line from stdin
@@ -192,3 +192,4 @@ main(int argc, char *argv[]) {
teardown(devh);
return 0;
}
+