#include #include #include #include // Number of bytes between transitions #define CAPTURE_FREQ (24000) #define BIT_HEADER (770) #define BIT_SYNC1 (2500) #define BIT_SYNC2 (2000) #define BIT_ZERO (2000) #define BIT_ONE (1000) const unsigned capture_freq=(CAPTURE_FREQ); const unsigned bit_header=BIT_HEADER; // 770 Hertz const unsigned bit_sync1=BIT_SYNC1; // one half cycle aka one delay const unsigned bit_sync2=BIT_SYNC2; // one half cycle aka one delay const unsigned bit_zero=BIT_ZERO; // 250 hertz - one full cycle const unsigned bit_one=BIT_ONE; // 500 hertz - one full cycle // The last /2 is because count is of half cycles so takes 2 half // cycles to make the full cycle. const unsigned count_header= CAPTURE_FREQ/BIT_HEADER/2; // 15.58... const unsigned count_sync1 = CAPTURE_FREQ/BIT_SYNC1/2; // 4.8 const unsigned count_sync2 = CAPTURE_FREQ/BIT_SYNC2/2; // 6 const unsigned count_zero = CAPTURE_FREQ/BIT_ZERO/2; // 6 const unsigned count_one = CAPTURE_FREQ/BIT_ONE/2; // 12 unsigned CalcDeltas(FILE *fp,unsigned char *delta,unsigned dc_average); unsigned Convert(unsigned num_delta,unsigned char *delta, unsigned *delta_index, unsigned max_data_size,unsigned char *data, unsigned initial_crc); void PrintData(unsigned char *data, unsigned num_byte,unsigned initial_crc); unsigned verbose=0; int main(int argc, char **argv) { unsigned count=0, total=0, dc_average; unsigned num_delta, delta_index; unsigned char *delta; int ch; // Convert vars unsigned max_data_size, num_bytes; unsigned char *data; unsigned basic_length; FILE *fpin, *fpout=0; if (argc < 2 || argc > 4) { printf("USAGE: %s IN_FILENAME [OUT_FILENAME] [-v for verbose/debug]\n", argv[0]); return -1; } fpin = fopen(argv[1],"r"); if (!fpin) { printf("FAILED to open \"%s\"\n", argv[1]); return -1; } if (argc > 2) { if (strcmp(argv[2],"-v")==0) verbose=1; else { fpout = fopen(argv[2],"w"); if (!fpout) { printf("FAILED to open output file: \"%s\"\n", argv[2]); fclose(fpin); return -1; } } } if (argc==4) { if (strcmp(argv[3],"-v")==0) verbose=1; } // Calculate DC average while (1) { ch = fgetc(fpin); if (ch==EOF) break; count++; total += ch; } if (count==0) { printf("ERROR: Empty file?\n"); goto abort; } dc_average = total / count; if (verbose & count) printf("total=%u size=%u DC average=%u\n", total, count, total/count); delta = calloc(count,sizeof(unsigned char)); rewind(fpin); num_delta = CalcDeltas(fpin,delta,dc_average); if (verbose) printf("num_delta=%u\n",num_delta); max_data_size=num_delta/8/2; // 8 bits/byte, 2 samples per bit data = calloc(max_data_size,sizeof(unsigned char)); // calloc sets to 0 num_bytes = Convert(num_delta,delta,&delta_index,max_data_size,data,0xff); printf("num_bytes=%d\n",num_bytes); if (num_bytes==2 || num_bytes==1) { basic_length = (data[1] << 8) + data[0]; printf("Since num_bytes==2 I Ass.U.Me this is a basic program\n "\ "I calculate byte length to be:%u=0x%x delta_index=%u\n", basic_length, basic_length, delta_index); if (delta_index >= num_delta) { printf("delta_index=%u > num_delta=%u so aborting\n", delta_index, num_delta); goto abort; } num_bytes = Convert(num_delta-delta_index,delta+delta_index, &delta_index,max_data_size,data,0); printf("Read num_bytes=%u of basic program\n",num_bytes); } if (num_bytes && fpout) fwrite(data,1,num_bytes,fpout); abort: fclose(fpin); if (fpout) fclose(fpout); return 0; } unsigned GetLevel(FILE *fp,unsigned dc_average) { int ch = fgetc(fp); if (ch==EOF) return EOF; if (ch < dc_average) return 0; else return 1; } unsigned CalcDeltas(FILE *fp,unsigned char *delta,unsigned dc_average) { unsigned index=0, delta_ct=0, next_level; unsigned level = GetLevel(fp,dc_average); while( 1 ) { delta_ct++; // Did it toggle? next_level = GetLevel(fp,dc_average); if (next_level==EOF) break; if (level != next_level) { level = next_level; delta[index++] = delta_ct; if (verbose) printf("%u ",delta_ct); delta_ct=0; } } printf("\n"); return index; } unsigned Convert(unsigned num_delta,unsigned char *delta, unsigned *delta_index_return, unsigned max_data_size,unsigned char *data, unsigned initial_crc) { unsigned delta_index=0; unsigned num_delta_before_header=0; unsigned num_delta_in_header=0; unsigned di,di2; unsigned bit_index=0, byte_index=0; unsigned checksum_byte=0; unsigned last_byte=initial_crc; // For checksum. Last byte not in checksum calc. unsigned header_byte_count=0; // Skip any junk before header for (delta_index=0; delta_index= count_header-1 && delta[delta_index] <= count_header+1 ) header_byte_count++; else num_delta_before_header++; // In the pre header data might be a byte that looks like a header // so require a few so we don't get tricked. if (header_byte_count >= 3) break; } if (verbose) printf("Junk before header=%u deltas\n", num_delta_before_header); // Skip header for ( ; delta_index count_header+1) break; num_delta_in_header++; } if (verbose) printf("Num deltas in header=%u ended at delta_index=%u\n", num_delta_in_header, delta_index); // Get Skip sync1 (1 delta) half period.... hopefully if (delta[delta_index] < count_sync1-1 || delta[delta_index] > count_sync1+1) { printf("Expected sync1 delta=%u +/- 1 at delta_index=%u but read %u\n", count_sync1, delta_index, delta[delta_index]); *delta_index_return=delta_index; return 0; } delta_index++; // Get Skip sync2 (1 delta) half period.... hopefully if (delta[delta_index] < count_sync2-1 || delta[delta_index] > count_sync2+1) { printf("Expected sync2 delta=%u +/- 1 at delta_index=%u but read %u\n", count_sync2, delta_index, delta[delta_index]); *delta_index_return=delta_index; return 0; } // Now lets read the data delta_index++; for ( ;delta_index= count_zero-1 && di <= count_zero+1) { if (di2 >= count_zero-1 && di2 <= count_zero+1) { //printf("0"); } else break; // Bad second half-bit or end of data record } else if (di >= count_one-1 && di <= count_one+1) { if (di2 >= count_one-1 && di2 <= count_one+1) { //printf("1"); data[byte_index] |= (1 << (7-bit_index)); } else break; // Bad second half-bit or end of data record } else break; // Bad 1st half of bit or end of data record bit_index++; if (bit_index>=8) { bit_index=0; checksum_byte = checksum_byte ^ last_byte; last_byte = data[byte_index]; byte_index++; } } *delta_index_return=delta_index; // Leave byte_index pointing at CRC if (byte_index > 0) byte_index--; if (verbose) printf("End of data at delta_index=%u\n", delta_index); if (verbose) printf("byte_index=0x%x bit_index=%d\n",byte_index,bit_index); if (verbose) printf("checksum_byte=0x%0x\n", checksum_byte); if (byte_index > 0 && bit_index==0 && verbose) printf("bit_index ended on 0 like it's supposed to. Maybe data is good\n"); if (checksum_byte == data[byte_index]) printf("Checksum=0x%0x is GOOD! last byte = ^XOR checksum\n", checksum_byte); else printf("BAD CHECKSUM=0x%0x last byte=%0x :-(\n", checksum_byte,data[byte_index]); if (verbose) PrintData(data,byte_index,initial_crc); if (checksum_byte==data[byte_index]) return byte_index-1; else return 0; } void PrintData(unsigned char *data, unsigned num_bytes, unsigned initial_checksum) { unsigned i,j; unsigned checksum=initial_checksum, line_checksum=0; unsigned ascii_left=0; printf("Initial checksum:0x%0x\n", initial_checksum); for (i=0; i