swv.c (3009B)
1 // Copyright 2005-2022, Brian Swetland <swetland@frotz.net> 2 // Licensed under the Apache License, Version 2.0 3 4 typedef enum { 5 SWV_SYNC, 6 SWV_1X1, 7 SWV_1X2, 8 SWV_1X4, 9 SWV_2X2, 10 SWV_2X4, 11 SWV_3X4, 12 SWV_4X4, 13 SWV_PROTO, 14 SWV_IDLE, 15 } swv_state_t; 16 17 typedef struct { 18 swv_state_t state; 19 unsigned zcount; 20 unsigned ccount; 21 unsigned id; 22 unsigned val; 23 unsigned char data[8]; 24 } swv_t; 25 26 static swv_t swv = { 27 .state = SWV_SYNC, 28 .zcount = 0 29 }; 30 31 void handle_swv_src(unsigned id, unsigned val, unsigned n) { 32 printf("SRC %s %02x %08x\n", (id & 0x100) ? "HW" : "SW", id & 0xFF, val); 33 } 34 35 void handle_swv_proto(unsigned char *data, unsigned len) { 36 switch (len) { 37 case 1: 38 printf("PRO %02x\n", data[0]); 39 break; 40 case 2: 41 printf("PRO %02x %02x\n", data[0], data[1]); 42 break; 43 case 3: 44 printf("PRO %02x %02x %02x\n", 45 data[0], data[1], data[2]); 46 break; 47 case 4: 48 printf("PRO %02x %02x %02x %02x\n", 49 data[0], data[1], data[2], data[3]); 50 break; 51 case 5: 52 printf("PRO %02x %02x %02x %02x %02x\n", 53 data[0], data[1], data[2], data[3], data[4]);; 54 break; 55 case 6: 56 printf("PRO %02x %02x %02x %02x %02x %02x\n", 57 data[0], data[1], data[2], data[3], 58 data[4], data[5]); 59 break; 60 case 7: 61 printf("PRO %02x %02x %02x %02x %02x %02x %02x\n", 62 data[0], data[1], data[2], data[3], 63 data[4], data[5], data[6]); 64 break; 65 } 66 } 67 68 void handle_swv(swv_t *swv, unsigned x) { 69 //printf("%02x ", x); fflush(stdout); 70 // any sequence ending in 00 00 00 00 00 80 is a re-sync 71 if (x == 0) { 72 swv->zcount++; 73 } else { 74 if ((swv->zcount >= 5) && (x == 0x80)) { 75 swv->state = SWV_IDLE; 76 swv->zcount = 0; 77 printf("SYNC\n"); 78 return; 79 } 80 swv->zcount = 0; 81 } 82 83 switch (swv->state) { 84 case SWV_IDLE: 85 if (x & 7) { 86 // AAAAAHSS source packet 87 swv->id = (x >> 3) | ((x & 4) << 6); 88 swv->val = 0; 89 swv->state = (x & 3); 90 } else if (x != 0) { 91 // CXXXXX00 protocol packet 92 swv->data[0] = x; 93 if (x & 0x80) { 94 swv->ccount = 1; 95 swv->state = SWV_PROTO; 96 } else { 97 handle_swv_proto(swv->data, 1); 98 } 99 } else { 100 // 00 packets are for sync, ignore 101 } 102 break; 103 case SWV_PROTO: 104 swv->data[swv->ccount++] = x; 105 // protocol packets end at 7 total bytes or a byte with bit7 clear 106 if ((swv->ccount == 7) || (!(x & 0x80))) { 107 handle_swv_proto(swv->data, swv->ccount); 108 swv->state = SWV_IDLE; 109 } 110 break; 111 case SWV_1X1: 112 handle_swv_src(swv->id, x, 1); 113 swv->state = SWV_IDLE; 114 break; 115 case SWV_1X2: 116 swv->val = x; 117 swv->state = SWV_2X2; 118 break; 119 case SWV_2X2: 120 handle_swv_src(swv->id, swv->val | (x << 8), 2); 121 swv->state = SWV_IDLE; 122 break; 123 case SWV_1X4: 124 swv->val = x; 125 swv->state = SWV_2X4; 126 break; 127 case SWV_2X4: 128 swv->val |= (x << 8); 129 swv->state = SWV_3X4; 130 break; 131 case SWV_3X4: 132 swv->val |= (x << 16); 133 swv->state = SWV_4X4; 134 break; 135 case SWV_4X4: 136 handle_swv_src(swv->id, swv->val | (x << 24), 4); 137 swv->state = SWV_IDLE; 138 break; 139 case SWV_SYNC: 140 break; 141 default: 142 // impossible 143 printf("fatal error, bad state %d\n", swv->state); 144 exit(1); 145 } 146 } 147