sconsole

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs

commit 17b721e71fff68133ab4adecfeb778e236b1bb5f
parent 74bba63f4f1b1694356b8a693f817376ca80e77b
Author: Brian Swetland <swetland@frotz.net>
Date:   Fri,  3 Jul 2015 04:25:44 -0700

add -s option to decode SWO/SWV packet streams

Diffstat:
Msconsole.c | 150+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 150 insertions(+), 0 deletions(-)

diff --git a/sconsole.c b/sconsole.c @@ -238,6 +238,150 @@ void usage(void) { ); } +typedef enum { + SWV_SYNC, + SWV_1X1, + SWV_1X2, + SWV_1X4, + SWV_2X2, + SWV_2X4, + SWV_3X4, + SWV_4X4, + SWV_PROTO, + SWV_IDLE, +} swv_state_t; + +typedef struct { + swv_state_t state; + unsigned zcount; + unsigned ccount; + unsigned id; + unsigned val; + unsigned char data[8]; +} swv_t; + +static swv_t swv = { + .state = SWV_SYNC, + .zcount = 0 +}; + +void handle_swv_src(unsigned id, unsigned val, unsigned n) { + printf("SRC %s %02x %08x\n", (id & 0x100) ? "HW" : "SW", id & 0xFF, val); +} + +void handle_swv_proto(unsigned char *data, unsigned len) { + switch (len) { + case 1: + printf("PRO %02x\n", data[0]); + break; + case 2: + printf("PRO %02x %02x\n", data[0], data[1]); + break; + case 3: + printf("PRO %02x %02x %02x\n", + data[0], data[1], data[2]); + break; + case 4: + printf("PRO %02x %02x %02x %02x\n", + data[0], data[1], data[2], data[3]); + break; + case 5: + printf("PRO %02x %02x %02x %02x %02x\n", + data[0], data[1], data[2], data[3], data[4]);; + break; + case 6: + printf("PRO %02x %02x %02x %02x %02x %02x\n", + data[0], data[1], data[2], data[3], + data[4], data[5]); + break; + case 7: + printf("PRO %02x %02x %02x %02x %02x %02x %02x\n", + data[0], data[1], data[2], data[3], + data[4], data[5], data[6]); + break; + } +} + +void handle_swv(swv_t *swv, unsigned x) { + //printf("%02x ", x); fflush(stdout); + // any sequence ending in 00 00 00 00 00 80 is a re-sync + if (x == 0) { + swv->zcount++; + } else { + if ((swv->zcount >= 5) && (x == 0x80)) { + swv->state = SWV_IDLE; + swv->zcount = 0; + printf("SYNC\n"); + return; + } + swv->zcount = 0; + } + + switch (swv->state) { + case SWV_IDLE: + if (x & 7) { + // AAAAAHSS source packet + swv->id = (x >> 3) | ((x & 4) << 6); + swv->val = 0; + swv->state = (x & 3); + } else if (x != 0) { + // CXXXXX00 protocol packet + swv->data[0] = x; + if (x & 0x80) { + swv->ccount = 1; + swv->state = SWV_PROTO; + } else { + handle_swv_proto(swv->data, 1); + } + } else { + // 00 packets are for sync, ignore + } + break; + case SWV_PROTO: + swv->data[swv->ccount++] = x; + // protocol packets end at 7 total bytes or a byte with bit7 clear + if ((swv->ccount == 7) || (!(x & 0x80))) { + handle_swv_proto(swv->data, swv->ccount); + swv->state = SWV_IDLE; + } + break; + case SWV_1X1: + handle_swv_src(swv->id, x, 1); + swv->state = SWV_IDLE; + break; + case SWV_1X2: + swv->val = x; + swv->state = SWV_2X2; + break; + case SWV_2X2: + handle_swv_src(swv->id, swv->val | (x << 8), 2); + swv->state = SWV_IDLE; + break; + case SWV_1X4: + swv->val = x; + swv->state = SWV_2X4; + break; + case SWV_2X4: + swv->val |= (x << 8); + swv->state = SWV_3X4; + break; + case SWV_3X4: + swv->val |= (x << 16); + swv->state = SWV_4X4; + break; + case SWV_4X4: + handle_swv_src(swv->id, swv->val | (x << 24), 4); + swv->state = SWV_IDLE; + break; + case SWV_SYNC: + break; + default: + // impossible + printf("fatal error, bad state %d\n", swv->state); + exit(1); + } +} + int main(int argc, char *argv[]) { struct pollfd fds[2]; @@ -254,6 +398,7 @@ int main(int argc, char *argv[]) int logfd = -1; int hexmode = 0; unsigned char ESC = 27; + int decode_swv = 0; for (n = ' '; n < 127; n++) valid[n] = 1; @@ -287,6 +432,9 @@ int main(int argc, char *argv[]) case 'h': usage(); return 0; + case 's': + decode_swv = 1; + break; default: fprintf(stderr, "error: unknown option %s\n\n", argv[1]); usage(); @@ -390,6 +538,8 @@ int main(int argc, char *argv[]) char hex[4]; sprintf(hex, "%02x ", x); write(1, hex, 3); + } else if (decode_swv) { + handle_swv(&swv, x); } else { unsigned char c = x; if (!valid[x])