USB low speed packet capture

Dependencies:   mbed

Revision:
0:654d7d47e816
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbpkt.cpp	Mon Apr 29 08:11:31 2013 +0000
@@ -0,0 +1,130 @@
+// usbpkt.cpp 2013/4/29
+#include "usbpkt.h"
+
+void usbpkt::reset()
+{
+    _DEF_WIDTH = 7;
+    _pre_value = 0;
+    _data0 = 0;
+    _data0_len = 0;
+    _data = 0x00;
+    _data_len = 0;
+    _width = 0;
+    _sync = false;
+
+    pktpos = 0;
+}
+
+void usbpkt::inputByte(uint8_t value)
+{
+    if (pktpos < MAX_PACKET_SIZE) {
+        packet[pktpos++] = value;
+    }
+}
+
+void usbpkt::inputBit(int value)
+{
+    _data0 >>= 1;
+    if (value) {
+        _data0 |= 0x80;
+    }
+    _data0_len++;
+    if (!_sync) {
+        if (_data0 == 0x80 && _data0_len >= 4) {
+            inputByte(0x80); // SYNC
+            _sync = true;
+        }
+        return;
+    }
+    if (_data0 == 0x7e) { // bit stuffing
+        return;
+    }
+    _data >>= 1;
+    if (value) {
+        _data |= 0x80;
+    }
+    _data_len++;
+    if (_data_len >= 8) {
+        inputByte(_data);
+        _data_len = 0;
+        _data = 0x00;
+    }
+}    
+
+void usbpkt::inputRaw(int value)
+{
+    if (value != _pre_value) {
+        inputBit(0);
+        _width = 0;
+        _pre_value = value;
+    } else {
+        _width++;
+        if (_width >= (_DEF_WIDTH*3/2)) {
+            _width -= _DEF_WIDTH;
+            inputBit(1);
+        }
+    }
+}
+
+void  usbpkt::printHEX(FILE* fp)
+{
+    for(int i = 0; i < pktpos; i++) {
+        fprintf(fp, "[%02x]", packet[i]);
+    }
+    fprintf(fp, "\n");
+}
+
+void  usbpkt::printUSB(FILE* fp)
+{
+    const char* pidName[] = {
+        "Reserved","OUT",  "ACK",   "DATA0",  // 0-3
+        "PING",    "SOF",  "NYET",  "DATA2",  // 4-7
+        "SPLIT",   "IN",   "NAK",   "DATA1",  // 8-b
+        "PRE",     "SETUP","STALL", "MDATA",  // a-f
+    };
+    uint8_t pid = 0;
+    for(int pos = 0; pos < pktpos; pos++) {
+        uint8_t c = packet[pos];
+        if (pos == 0) {
+            if (c == 0x80) {
+                fprintf(fp, "[SYNC]");
+            } else {
+                fprintf(fp,"[%02x]", c);
+            } 
+        } else if (pos == 1) {
+            pid = c & 0x0f;
+            fprintf(fp, "[%s]", pidName[pid]);
+        } else if (pos >= 2) {
+            if (pid == 1 || pid == 4 || pid == 9 || pid == 0xd) {
+                uint16_t u = packet[pos]|packet[pos+1]<<8;
+                uint8_t addr = u&0x7f;
+                uint8_t endp = (u>>7) & 0x0f;
+                uint8_t crc5 = u>>11;
+                fprintf(fp, "[ADDR=%02x][ENDP=%02x][CRC5=%02x]", addr, endp, crc5);
+                break;
+            } else if (pid == 3 || pid == 7 || pid == 0xb || pid == 0xf) {
+                fprintf(fp, "[");
+                for(int i = pos; i < pktpos-2; i++) {
+                    if (i == pos) {
+                        fprintf(fp, "%02x", packet[i]);
+                    } else {
+                        fprintf(fp, " %02x", packet[i]);
+                    }
+                }
+                uint16_t crc16 = packet[pktpos-2]|packet[pktpos-1]<<8;
+                fprintf(fp, "][CRC16=%04x]", crc16);
+                break;
+            } else if (pid == 5) {
+                uint16_t u = packet[pos]|packet[pos+1]<<8;
+                uint16_t frame = u&0x3f;
+                uint8_t crc5 = u>>11;
+                fprintf(fp, "[frame=%04x][CRC5=%02x]", frame, crc5);
+                break;                
+            } else {
+                fprintf(fp, "[%02x]", packet[pos]);
+            }
+        }
+    }
+    fprintf(fp, "[EOP]\n");
+}
+