USB low speed packet capture

Dependencies:   mbed

usbpkt.cpp

Committer:
va009039
Date:
2013-04-29
Revision:
0:654d7d47e816

File content as of revision 0:654d7d47e816:

// 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");
}