Since usb_rx is now only used to receive ACK/NAK, we can replace it
with a more streamlined version. This should also marginally improve
error handling.
---
 softusb-input/main.c |  110 ++++++++++++++++++++++----------------------------
 1 files changed, 48 insertions(+), 62 deletions(-)

diff --git a/softusb-input/main.c b/softusb-input/main.c
index 3c8b639..032517f 100644
--- a/softusb-input/main.c
+++ b/softusb-input/main.c
@@ -109,53 +109,10 @@ static inline void usb_ack(void)
        while(rio8(SIE_TX_BUSY));
 }
 
-static const char transfer_start[] PROGMEM = "Transfer start: ";
+static const char ack_error[] PROGMEM = "ACK: ";
 static const char timeout_error[] PROGMEM = "RX timeout error\n";
 static const char bitstuff_error[] PROGMEM = "RX bitstuff error\n";
 
-static unsigned char usb_rx(unsigned char *buf, unsigned char maxlen)
-{
-       unsigned int timeout;
-       unsigned char i;
-
-       i = 0;
-       timeout = 0x1ff;
-       while(!rio8(SIE_RX_PENDING)) {
-               if(timeout-- == 0) {
-                       print_string(transfer_start);
-                       print_string(timeout_error);
-                       return 0;
-               }
-               if(rio8(SIE_RX_ERROR)) {
-                       print_string(transfer_start);
-                       print_string(bitstuff_error);
-                       return 0;
-               }
-       }
-       while(1) {
-               timeout = 0x1ff;
-               while(!rio8(SIE_RX_PENDING)) {
-                       if(rio8(SIE_RX_ERROR)) {
-                               print_string(bitstuff_error);
-                               return 0;
-                       }
-                       if(!rio8(SIE_RX_ACTIVE))
-                               return i;
-                       if(timeout-- == 0) {
-                               print_string(timeout_error);
-                               return 0;
-                       }
-               }
-               if(i == maxlen)
-                       return 0;
-               buf[i] = rio8(SIE_RX_DATA);
-               i++;
-       }
-}
-
-static const char in_reply[] PROGMEM = "IN reply:\n";
-static const char datax_mismatch[] PROGMEM = "DATAx mismatch\n";
-
 #define        WAIT_RX(first, end)                                     \
        do {                                                    \
                unsigned timeout = 0x200;                       \
@@ -169,6 +126,49 @@ static const char datax_mismatch[] PROGMEM = "DATAx 
mismatch\n";
                }                                               \
        } while (0)
 
+
+static char usb_rx_ack(void)
+{
+       unsigned char pid;
+       unsigned char i;
+
+       /* SYNC */
+       WAIT_RX(1, nothing);
+
+       /* PID */
+       WAIT_RX(0, nothing);
+       pid = rio8(SIE_RX_DATA);
+
+       /* wait for idle, or simply time out and fall foward */
+       for(i = 200; i; i--)
+               if(!rio8(SIE_RX_ACTIVE))
+                       break;
+
+       if(pid == USB_PID_ACK)
+               return 1;
+       if(pid == USB_PID_NAK)
+               return 0;
+
+       for(i = 200; i; i--)
+               WAIT_RX(0,out);
+out:
+       print_string(ack_error);
+       print_hex(pid);
+       print_char('\n');
+       return -1;
+
+timeout:
+       print_string(timeout_error);
+nothing:
+       return 0;
+error:
+       print_string(bitstuff_error);
+       return 0;
+}
+
+static const char in_reply[] PROGMEM = "IN reply:\n";
+static const char datax_mismatch[] PROGMEM = "DATAx mismatch\n";
+
 static int usb_in(unsigned addr, unsigned char expected_data,
     unsigned char *buf, unsigned char maxlen)
 {
@@ -250,8 +250,6 @@ 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);
@@ -261,15 +259,7 @@ static char usb_out(unsigned addr, const unsigned char 
*buf, unsigned char len)
        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;
+       return usb_rx_ack();
 }
 
 struct setup_packet {
@@ -285,8 +275,7 @@ static inline unsigned char toggle(unsigned char old)
        return old ^ USB_PID_DATA0 ^ USB_PID_DATA1;
 }
 
-static const char control_failed[] PROGMEM = "Control transfer failed:\n";
-static const char setup_reply[] PROGMEM = "SETUP reply:\n";
+static const char setup_ack[] PROGMEM = "SETUP not ACKed\n";
 
 static int control_transfer(unsigned char addr, struct setup_packet *p,
     char out, unsigned char *payload, int maxlen)
@@ -314,11 +303,8 @@ wio8(SIE_SEL_TX, 3);
 wio8(SIE_SEL_TX, 2);
 #endif
        /* get ACK token from device */
-       rxlen = usb_rx(usb_buffer, 11);
-       if((rxlen != 1) || (usb_buffer[0] != USB_PID_ACK)) {
-               print_string(control_failed);
-               print_string(setup_reply);
-               dump_hex(usb_buffer, rxlen);
+       if(usb_rx_ack() != 1) {
+               print_string(setup_ack);
                return -1;
        }
 
-- 
1.7.1

_______________________________________________
http://lists.milkymist.org/listinfo.cgi/devel-milkymist.org
IRC: #milkymist@Freenode

Reply via email to