USB low speed packet capture

Dependencies:   mbed

Files at this revision

API Documentation at this revision

Comitter:
va009039
Date:
Mon Apr 29 08:11:31 2013 +0000
Commit message:
first commit

Changed in this revision

lowspeed.s Show annotated file Show diff for this revision Revisions of this file
main.cpp Show annotated file Show diff for this revision Revisions of this file
mbed.bld Show annotated file Show diff for this revision Revisions of this file
usbpkt.cpp Show annotated file Show diff for this revision Revisions of this file
usbpkt.h Show annotated file Show diff for this revision Revisions of this file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/lowspeed.s	Mon Apr 29 08:11:31 2013 +0000
@@ -0,0 +1,74 @@
+; lowspeed.s 2013/4/29
+;
+        AREA    LOWSPEED,CODE,READONLY
+
+; Base addresses
+LPC_GPIO_BASE   EQU     0x2009c000
+
+; GPIOs                                                                      */
+LPC_GPIO0_BASE  EQU     (LPC_GPIO_BASE + 0x00000)
+LPC_GPIO1_BASE  EQU     (LPC_GPIO_BASE + 0x00020)
+LPC_GPIO2_BASE  EQU     (LPC_GPIO_BASE + 0x00040)
+LPC_GPIO3_BASE  EQU     (LPC_GPIO_BASE + 0x00060)
+LPC_GPIO4_BASE  EQU     (LPC_GPIO_BASE + 0x00080)
+
+; offset
+FIOPIN      EQU     0x14
+FIOPIN0     EQU     0x14
+FIOPIN1     EQU     0x15
+FIOPIN2     EQU     0x16
+FIOPIN3     EQU     0x17
+FIOSET      EQU     0x18
+FIOSET0     EQU     0x18
+FIOSET1     EQU     0x19
+FIOSET2     EQU     0x1a
+FIOSET3     EQU     0x1b
+FIOCLR      EQU     0x1c
+FIOCLR0     EQU     0x1c
+FIOCLR1     EQU     0x1d
+FIOCLR2     EQU     0x1e
+FIOCLR3     EQU     0x1f
+
+; FIOSET2,FIOCLR2
+P1_18   EQU     (1<<2)
+P1_20   EQU     (1<<4)
+; FIOPIN0
+P2_4    EQU     (1<<4)
+P2_5    EQU     (1<<5)
+
+LED1    EQU     P1_18
+LED2    EQU     P1_20
+p21     EQU     P2_5
+p22     EQU     P2_4            
+
+USB_MASK    EQU     (p21+p22)
+USB_SE0     EQU     (p21+p22)
+;
+; uint8_t* capraw(uint8_t* buf, int size, int count)
+;
+        EXPORT    capraw
+capraw
+        PUSH    {r4-r7}
+        LDR     r6,=LPC_GPIO1_BASE
+        MOV     r7,#LED1
+cap10   LDR     r4,=LPC_GPIO2_BASE+FIOPIN0 ; D+ p21(P2_5), D- p22(P2_4)
+cap20   LDRB    r5,[r4]
+        TST     r5,#p21
+        BEQ     cap20
+        STRB    r7,[r6,#FIOSET2] ; LED1 on
+cap50   LDRB    r5,[r4]
+        STRB    r5,[r0],#+1
+        TST     r5,#USB_SE0 ; EOP ?
+        BNE     cap70
+        STRB    r7,[r6,#FIOCLR2] ; LED1 off
+        SUBS    r2,r2,#1
+        BEQ     cap90
+        B       cap10
+cap70   SUBS    r1,r1,#1    ; buffer full ?
+        BNE     cap50
+cap90   POP     {r4-r7}        
+        BX      lr 
+        
+        ALIGN
+        END
+ 
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Mon Apr 29 08:11:31 2013 +0000
@@ -0,0 +1,54 @@
+// main.cpp 2013/4/29
+#include "mbed.h"
+#include "mbed_debug.h"
+#include "usbpkt.h"
+
+DigitalIn usb_data_p(p21); // USB DATA+ 
+DigitalIn usb_data_m(p22); // USB DATA-
+DigitalOut led_usb(LED1);
+
+#define DISP_RAW 0
+#define BUFFER_SIZE (1024*16)
+#define MAX_PACKET_COUNT 35
+
+#define USB_MASK (3<<4)
+#define USB_DATA (2<<4)
+
+DigitalOut led_run(LED4);
+Serial pc(USBTX, USBRX);
+
+extern "C" {
+    uint8_t* capraw(uint8_t* buf, int size, int count); // lowspeed.s
+}
+
+uint8_t buf[BUFFER_SIZE];
+
+int main() {
+    pc.baud(921600);
+    debug("%s\n", __FILE__);
+
+    usb_data_p.mode(PullNone);
+    usb_data_m.mode(PullNone);
+
+    while(1) {
+        uint8_t* ret = capraw(buf, sizeof(buf)-16, MAX_PACKET_COUNT);
+        usbpkt pkt;
+        pkt.reset();
+        uint8_t* p = buf;
+        while(p < ret) {
+            uint8_t d = *p++;
+            if ((d&USB_MASK) == 0) { // EOP ?
+                debug_if(DISP_RAW, "\n");
+                //pkt.printHEX(stdout);
+                pkt.printUSB(stdout);
+                pkt.reset();
+            } else {
+                pkt.inputRaw((d&USB_DATA) ? 1 : 0);
+                debug_if(DISP_RAW, "%c", (d&USB_DATA) ? '*' : '.');
+            }
+        }
+        debug("\n");
+        wait_ms(200);
+        led_run = !led_run;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed.bld	Mon Apr 29 08:11:31 2013 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/mbed_official/code/mbed/builds/7e6c9f46b3bd
\ No newline at end of file
--- /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");
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbpkt.h	Mon Apr 29 08:11:31 2013 +0000
@@ -0,0 +1,27 @@
+// usbpkt.h 2013/3/39
+#pragma once
+#include "mbed.h"
+
+#define MAX_PACKET_SIZE 256
+
+class usbpkt {
+public:
+    void reset();
+    void inputByte(uint8_t value);
+    void inputBit(int value);
+    void inputRaw(int value);
+    void printUSB(FILE* fp);
+    void printHEX(FILE* fp);
+
+    uint8_t packet[MAX_PACKET_SIZE];
+    int pktpos;
+private:
+    int _DEF_WIDTH;
+    int _pre_value;
+    uint8_t _data0;
+    int _data0_len;
+    uint8_t _data;
+    int _data_len;
+    int _width;
+    bool _sync;
+};