This is mainly cosmetic, to reduce the amount of code. It adds
retry on timeout, though.
Again, as a side-effect, debug messages become a bit less detailed.
---
softusb-input/main.c | 73 ++++++++++++++++++++++++++-----------------------
1 files changed, 39 insertions(+), 34 deletions(-)
diff --git a/softusb-input/main.c b/softusb-input/main.c
index b465995..c84da2b 100644
--- a/softusb-input/main.c
+++ b/softusb-input/main.c
@@ -85,7 +85,7 @@ static void make_usb_token(unsigned char pid, unsigned int
elevenbits, unsigned
out[2] |= usb_crc5(out[1], out[2]) << 3;
}
-static void usb_tx(unsigned char *buf, unsigned char len)
+static void usb_tx(const unsigned char *buf, unsigned char len)
{
unsigned char i;
@@ -178,6 +178,33 @@ static int usb_in(unsigned addr, unsigned char
expected_data,
return 0;
}
+static const char out_reply[] PROGMEM = "OUT/DATA reply:\n";
+
+static char usb_out(unsigned addr, const unsigned char *buf, unsigned char len)
+{
+ unsigned char out[3];
+ unsigned char ack[11];
+ unsigned char got;
+
+ /* send OUT */
+ make_usb_token(USB_PID_OUT, addr, out);
+ usb_tx(out, 3);
+
+ /* send DATAx */
+ usb_tx(buf, len);
+
+ /* receive ACK */
+ got = usb_rx(ack, 11);
+ if(got == 1 && ack[0] == USB_PID_ACK)
+ return 1;
+ if (!got || ack[0] == USB_PID_NAK) /* timeout or NAK */
+ return 0;
+
+ print_string(out_reply);
+ dump_hex(ack, got);
+ return -1;
+}
+
struct setup_packet {
unsigned char bmRequestType;
unsigned char bRequest;
@@ -194,7 +221,6 @@ static inline unsigned char toggle(unsigned char old)
static const char control_failed[] PROGMEM = "Control transfer failed:\n";
static const char termination[] PROGMEM = "(termination)\n";
static const char setup_reply[] PROGMEM = "SETUP reply:\n";
-static const char out_reply[] PROGMEM = "OUT/DATA reply:\n";
static int control_transfer(unsigned char addr, struct setup_packet *p,
char out, unsigned char *payload, int maxlen)
@@ -240,26 +266,15 @@ wio8(SIE_SEL_TX, 2);
if(chunklen > 8)
chunklen = 8;
- /* send OUT token */
- make_usb_token(USB_PID_OUT, addr, usb_buffer);
- usb_tx(usb_buffer, 3);
- /* send DATAx packet */
+ /* make DATAx packet */
usb_buffer[0] = expected_data;
memcpy(&usb_buffer[1], payload, chunklen);
usb_crc16(&usb_buffer[1], chunklen,
&usb_buffer[chunklen+1]);
- usb_tx(usb_buffer, chunklen+3);
-
- /* get ACK from device */
- rxlen = usb_rx(usb_buffer, 11);
- if((rxlen != 1) || (usb_buffer[0] != USB_PID_ACK)) {
- if((rxlen > 0) &&
- (usb_buffer[0] == USB_PID_NAK))
- continue; /* NAK: retry */
- print_string(control_failed);
- print_string(out_reply);
- dump_hex(usb_buffer, rxlen);
+ rxlen = usb_out(addr, usb_buffer, chunklen+3);
+ if(!rxlen)
+ continue;
+ if(rxlen < 0)
return -1;
- }
expected_data = toggle(expected_data);
transferred += chunklen;
@@ -297,25 +312,15 @@ retry:
if(rxlen < 0)
return -1;
} else {
- /* send OUT token */
- make_usb_token(USB_PID_OUT, addr, usb_buffer);
- usb_tx(usb_buffer, 3);
-
- /* send DATAx packet */
+ /* make DATA1 packet */
usb_buffer[0] = USB_PID_DATA1;
usb_buffer[1] = usb_buffer[2] = 0x00; /* CRC is 0x0000 without
data */
- usb_tx(usb_buffer, 3);
- /* get ACK token from device */
- rxlen = usb_rx(usb_buffer, 11);
- if((rxlen != 1) || (usb_buffer[0] != USB_PID_ACK)) {
- if((rxlen > 0) && (usb_buffer[0] == USB_PID_NAK))
- goto retry; /* NAK: retry */
- print_string(control_failed);
- print_string(termination);
- print_string(out_reply);
- dump_hex(usb_buffer, rxlen);
+
+ rxlen = usb_out(addr, usb_buffer, 3);
+ if(!rxlen)
+ goto retry;
+ if(!rxlen < 0)
return -1;
- }
}
return transferred;
--
1.7.1
_______________________________________________
http://lists.milkymist.org/listinfo.cgi/devel-milkymist.org
IRC: #milkymist@Freenode