]> git.zerfleddert.de Git - proxmark3-svn/blame - common/lfdemod.c
LF demod/cmd code cleanup + new lf search
[proxmark3-svn] / common / lfdemod.c
CommitLineData
eb191de6 1//-----------------------------------------------------------------------------
2// Copyright (C) 2014
3//
4// This code is licensed to you under the terms of the GNU GPL, version 2 or,
5// at your option, any later version. See the LICENSE.txt file for the text of
6// the license.
7//-----------------------------------------------------------------------------
8// Low frequency commands
9//-----------------------------------------------------------------------------
10
11//#include <stdio.h>
12#include <stdlib.h>
13#include <string.h>
14//#include <inttypes.h>
15//#include <limits.h>
16#include "lfdemod.h"
17//#include "proxmark3.h"
18//#include "data.h"
19//#include "ui.h"
20//#include "graph.h"
21//#include "cmdparser.h"
22//#include "util.h"
23//#include "cmdmain.h"
24//#include "cmddata.h"
25//uint8_t BinStream[MAX_GRAPH_TRACE_LEN];
26//uint8_t BinStreamLen;
27
28//by marshmellow
29//takes 1s and 0s and searches for EM410x format - output EM ID
66707a3b 30uint64_t Em410xDecode(uint8_t *BitStream,uint32_t BitLen)
eb191de6 31{
32 //no arguments needed - built this way in case we want this to be a direct call from "data " cmds in the future
33 // otherwise could be a void with no arguments
34 //set defaults
35 int high=0, low=0;
36 uint64_t lo=0; //hi=0,
37
38 uint32_t i = 0;
66707a3b 39 uint32_t initLoopMax = 65;
eb191de6 40 if (initLoopMax>BitLen) initLoopMax=BitLen;
41
66707a3b 42 for (;i < initLoopMax; ++i) //65 samples should be plenty to find high and low values
eb191de6 43 {
44 if (BitStream[i] > high)
45 high = BitStream[i];
46 else if (BitStream[i] < low)
47 low = BitStream[i];
48 }
49 if (((high !=1)||(low !=0))){ //allow only 1s and 0s
50 // PrintAndLog("no data found");
51 return 0;
52 }
53 uint8_t parityTest=0;
54 // 111111111 bit pattern represent start of frame
55 uint8_t frame_marker_mask[] = {1,1,1,1,1,1,1,1,1};
56 uint32_t idx = 0;
57 uint32_t ii=0;
58 uint8_t resetCnt = 0;
59 while( (idx + 64) < BitLen) {
66707a3b 60 restart:
eb191de6 61 // search for a start of frame marker
62 if ( memcmp(BitStream+idx, frame_marker_mask, sizeof(frame_marker_mask)) == 0)
63 { // frame marker found
64 idx+=9;//sizeof(frame_marker_mask);
65 for (i=0; i<10;i++){
66 for(ii=0; ii<5; ++ii){
67 parityTest += BitStream[(i*5)+ii+idx];
68 }
69 if (parityTest== ((parityTest>>1)<<1)){
70 parityTest=0;
71 for (ii=0; ii<4;++ii){
72 //hi = (hi<<1)|(lo>>31);
73 lo=(lo<<1LL)|(BitStream[(i*5)+ii+idx]);
74 }
75 //PrintAndLog("DEBUG: EM parity passed parity val: %d, i:%d, ii:%d,idx:%d, Buffer: %d%d%d%d%d,lo: %d",parityTest,i,ii,idx,BitStream[idx+ii+(i*5)-5],BitStream[idx+ii+(i*5)-4],BitStream[idx+ii+(i*5)-3],BitStream[idx+ii+(i*5)-2],BitStream[idx+ii+(i*5)-1],lo);
76 }else {//parity failed
77 //PrintAndLog("DEBUG: EM parity failed parity val: %d, i:%d, ii:%d,idx:%d, Buffer: %d%d%d%d%d",parityTest,i,ii,idx,BitStream[idx+ii+(i*5)-5],BitStream[idx+ii+(i*5)-4],BitStream[idx+ii+(i*5)-3],BitStream[idx+ii+(i*5)-2],BitStream[idx+ii+(i*5)-1]);
78 parityTest=0;
79 idx-=8;
80 if (resetCnt>5)return 0;
81 resetCnt++;
82 goto restart;//continue;
83 }
84 }
85 //skip last 5 bit parity test for simplicity.
86 return lo;
87 }else{
88 idx++;
89 }
90 }
91 return 0;
92}
93
94//by marshmellow
95//takes 2 arguments - clock and invert both as integers
96//attempts to demodulate ask while decoding manchester
97//prints binary found and saves in graphbuffer for further commands
98int askmandemod(uint8_t * BinStream,uint32_t *BitLen,int *clk, int *invert)
99{
100 uint32_t i;
101 //int invert=0; //invert default
102 int high = 0, low = 0;
103 *clk=DetectClock2(BinStream,(size_t)*BitLen,*clk); //clock default
66707a3b 104 uint8_t BitStream[252] = {0};
eb191de6 105
106 //sscanf(Cmd, "%i %i", &clk, &invert);
107 if (*clk<8) *clk =64;
108 if (*clk<32) *clk=32;
109 if (*invert != 0 && *invert != 1) *invert=0;
66707a3b 110 uint32_t initLoopMax = 200;
eb191de6 111 if (initLoopMax>*BitLen) initLoopMax=*BitLen;
112 // Detect high and lows
113 //PrintAndLog("Using Clock: %d and invert=%d",clk,invert);
66707a3b 114 for (i = 0; i < initLoopMax; ++i) //200 samples should be enough to find high and low values
eb191de6 115 {
116 if (BinStream[i] > high)
117 high = BinStream[i];
118 else if (BinStream[i] < low)
119 low = BinStream[i];
120 }
121 if ((high < 30) && ((high !=1)||(low !=-1))){ //throw away static - allow 1 and -1 (in case of threshold command first)
122 //PrintAndLog("no data found");
123 return -1;
124 }
125 //13% fuzz in case highs and lows aren't clipped [marshmellow]
126 high=(int)(0.75*high);
127 low=(int)(0.75*low);
128
129 //PrintAndLog("DEBUG - valid high: %d - valid low: %d",high,low);
130 int lastBit = 0; //set first clock check
131 uint32_t bitnum = 0; //output counter
132 uint8_t tol = 0; //clock tolerance adjust - waves will be accepted as within the clock if they fall + or - this value + clock from last valid wave
133 if (*clk==32)tol=1; //clock tolerance may not be needed anymore currently set to + or - 1 but could be increased for poor waves or removed entirely
134 uint32_t iii = 0;
135 uint32_t gLen = *BitLen;
136 if (gLen > 500) gLen=500;
137 uint8_t errCnt =0;
138 uint32_t bestStart = *BitLen;
139 uint32_t bestErrCnt = (*BitLen/1000);
140 //PrintAndLog("DEBUG - lastbit - %d",lastBit);
141 //loop to find first wave that works
142 for (iii=0; iii < gLen; ++iii){
143 if ((BinStream[iii]>=high)||(BinStream[iii]<=low)){
144 lastBit=iii-*clk;
66707a3b 145 bitnum=0;
eb191de6 146 //loop through to see if this start location works
147 for (i = iii; i < *BitLen; ++i) {
148 if ((BinStream[i] >= high) && ((i-lastBit)>(*clk-tol))){
149 lastBit+=*clk;
150 BitStream[bitnum] = *invert;
151 bitnum++;
152 } else if ((BinStream[i] <= low) && ((i-lastBit)>(*clk-tol))){
153 //low found and we are expecting a bar
154 lastBit+=*clk;
155 BitStream[bitnum] = 1-*invert;
156 bitnum++;
157 } else {
158 //mid value found or no bar supposed to be here
159 if ((i-lastBit)>(*clk+tol)){
160 //should have hit a high or low based on clock!!
161
162
163 //debug
164 //PrintAndLog("DEBUG - no wave in expected area - location: %d, expected: %d-%d, lastBit: %d - resetting search",i,(lastBit+(clk-((int)(tol)))),(lastBit+(clk+((int)(tol)))),lastBit);
165 if (bitnum > 0){
166 BitStream[bitnum]=77;
167 bitnum++;
168 }
169
170
171 errCnt++;
172 lastBit+=*clk;//skip over until hit too many errors
173 if (errCnt>((*BitLen/1000))){ //allow 1 error for every 1000 samples else start over
174 errCnt=0;
175 bitnum=0;//start over
176 break;
177 }
178 }
179 }
66707a3b 180 if (bitnum >250) break;
eb191de6 181 }
182 //we got more than 64 good bits and not all errors
183 if ((bitnum > (64+errCnt)) && (errCnt<(*BitLen/1000))) {
184 //possible good read
185 if (errCnt==0) break; //great read - finish
186 if (bestStart == iii) break; //if current run == bestErrCnt run (after exhausted testing) then finish
187 if (errCnt<bestErrCnt){ //set this as new best run
188 bestErrCnt=errCnt;
189 bestStart = iii;
190 }
191 }
192 }
193 if (iii>=gLen){ //exhausted test
194 //if there was a ok test go back to that one and re-run the best run (then dump after that run)
195 if (bestErrCnt < (*BitLen/1000)) iii=bestStart;
196 }
197 }
198 if (bitnum>16){
199
200 // PrintAndLog("Data start pos:%d, lastBit:%d, stop pos:%d, numBits:%d",iii,lastBit,i,bitnum);
201 //move BitStream back to GraphBuffer
202 //ClearGraph(0);
203 for (i=0; i < bitnum; ++i){
204 BinStream[i]=BitStream[i];
205 }
206 *BitLen=bitnum;
207 //RepaintGraphWindow();
208 //output
209 //if (errCnt>0){
210 // PrintAndLog("# Errors during Demoding (shown as 77 in bit stream): %d",errCnt);
211 //}
212 // PrintAndLog("ASK decoded bitstream:");
213 // Now output the bitstream to the scrollback by line of 16 bits
214 // printBitStream2(BitStream,bitnum);
215 // Em410xDecode(Cmd);
216 }
217 return errCnt;
218}
219
220//by marshmellow
221//take 10 and 01 and manchester decode
222//run through 2 times and take least errCnt
223int manrawdemod(uint8_t * BitStream, int *bitLen)
224{
66707a3b 225 uint8_t BitStream2[252]={0};
eb191de6 226 int bitnum=0;
227 int errCnt =0;
228 int i=1;
229 int bestErr = 1000;
230 int bestRun = 0;
231 int finish = 0;
232 int ii=1;
233 for (ii=1;ii<3;++ii){
234 i=1;
235 for (i=i+ii;i<*bitLen-2;i+=2){
236 if(BitStream[i]==1 && (BitStream[i+1]==0)){
237 BitStream2[bitnum++]=0;
238 } else if((BitStream[i]==0)&& BitStream[i+1]==1){
239 BitStream2[bitnum++]=1;
240 } else {
241 BitStream2[bitnum++]=77;
242 errCnt++;
243 }
66707a3b 244 if(bitnum>250) break;
eb191de6 245 }
246 if (bestErr>errCnt){
247 bestErr=errCnt;
248 bestRun=ii;
249 }
250 if (ii>1 || finish==1) {
251 if (bestRun==ii) {
252 break;
253 } else{
254 ii=bestRun-1;
255 finish=1;
256 }
257 }
258 errCnt=0;
259 bitnum=0;
260 }
261 errCnt=bestErr;
2df8c079 262 if (errCnt<20){
eb191de6 263 for (i=0; i<bitnum;++i){
264 BitStream[i]=BitStream2[i];
265 }
266 *bitLen=bitnum;
267 }
268 return errCnt;
269}
270
271//by marshmellow
272//takes 2 arguments - clock and invert both as integers
273//attempts to demodulate ask only
274//prints binary found and saves in graphbuffer for further commands
275int askrawdemod(uint8_t *BinStream, int *bitLen,int *clk, int *invert)
276{
277 uint32_t i;
278 // int invert=0; //invert default
279 int high = 0, low = 0;
280 *clk=DetectClock2(BinStream,*bitLen,*clk); //clock default
2df8c079 281 uint8_t BitStream[502] = {0};
eb191de6 282
283 if (*clk<8) *clk =64;
284 if (*clk<32) *clk=32;
285 if (*invert != 0 && *invert != 1) *invert =0;
66707a3b 286 uint32_t initLoopMax = 200;
eb191de6 287 if (initLoopMax>*bitLen) initLoopMax=*bitLen;
288 // Detect high and lows
66707a3b 289 for (i = 0; i < initLoopMax; ++i) //200 samples should be plenty to find high and low values
eb191de6 290 {
291 if (BinStream[i] > high)
292 high = BinStream[i];
293 else if (BinStream[i] < low)
294 low = BinStream[i];
295 }
296 if ((high < 30) && ((high !=1)||(low !=-1))){ //throw away static - allow 1 and -1 (in case of threshold command first)
297 // PrintAndLog("no data found");
298 return -1;
299 }
66707a3b 300 //25% fuzz in case highs and lows aren't clipped [marshmellow]
eb191de6 301 high=(int)(0.75*high);
302 low=(int)(0.75*low);
303
304 //PrintAndLog("DEBUG - valid high: %d - valid low: %d",high,low);
305 int lastBit = 0; //set first clock check
306 uint32_t bitnum = 0; //output counter
307 uint8_t tol = 0; //clock tolerance adjust - waves will be accepted as within the clock if they fall + or - this value + clock from last valid wave
308 if (*clk==32)tol=1; //clock tolerance may not be needed anymore currently set to + or - 1 but could be increased for poor waves or removed entirely
309 uint32_t iii = 0;
310 uint32_t gLen = *bitLen;
311 if (gLen > 500) gLen=500;
312 uint8_t errCnt =0;
313 uint32_t bestStart = *bitLen;
314 uint32_t bestErrCnt = (*bitLen/1000);
315 uint8_t midBit=0;
316 //PrintAndLog("DEBUG - lastbit - %d",lastBit);
317 //loop to find first wave that works
318 for (iii=0; iii < gLen; ++iii){
319 if ((BinStream[iii]>=high)||(BinStream[iii]<=low)){
320 lastBit=iii-*clk;
321 //loop through to see if this start location works
322 for (i = iii; i < *bitLen; ++i) {
323 if ((BinStream[i] >= high) && ((i-lastBit)>(*clk-tol))){
324 lastBit+=*clk;
325 BitStream[bitnum] = *invert;
326 bitnum++;
327 midBit=0;
328 } else if ((BinStream[i] <= low) && ((i-lastBit)>(*clk-tol))){
329 //low found and we are expecting a bar
330 lastBit+=*clk;
331 BitStream[bitnum] = 1-*invert;
332 bitnum++;
333 midBit=0;
334 } else if ((BinStream[i]<=low) && (midBit==0) && ((i-lastBit)>((*clk/2)-tol))){
335 //mid bar?
336 midBit=1;
337 BitStream[bitnum]= 1-*invert;
338 bitnum++;
339 } else if ((BinStream[i]>=high)&&(midBit==0) && ((i-lastBit)>((*clk/2)-tol))){
340 //mid bar?
341 midBit=1;
342 BitStream[bitnum]= *invert;
343 bitnum++;
344 } else if ((i-lastBit)>((*clk/2)+tol)&&(midBit==0)){
345 //no mid bar found
346 midBit=1;
347 BitStream[bitnum]= BitStream[bitnum-1];
348 bitnum++;
349 } else {
350 //mid value found or no bar supposed to be here
351
352 if ((i-lastBit)>(*clk+tol)){
353 //should have hit a high or low based on clock!!
354 //debug
355 //PrintAndLog("DEBUG - no wave in expected area - location: %d, expected: %d-%d, lastBit: %d - resetting search",i,(lastBit+(clk-((int)(tol)))),(lastBit+(clk+((int)(tol)))),lastBit);
356 if (bitnum > 0){
357 BitStream[bitnum]=77;
358 bitnum++;
359 }
360
361
362 errCnt++;
363 lastBit+=*clk;//skip over until hit too many errors
364 if (errCnt>((*bitLen/1000))){ //allow 1 error for every 1000 samples else start over
365 errCnt=0;
366 bitnum=0;//start over
367 break;
368 }
66707a3b 369 }
eb191de6 370 }
2df8c079 371 if (bitnum>500) break;
eb191de6 372 }
373 //we got more than 64 good bits and not all errors
374 if ((bitnum > (64+errCnt)) && (errCnt<(*bitLen/1000))) {
375 //possible good read
376 if (errCnt==0) break; //great read - finish
377 if (bestStart == iii) break; //if current run == bestErrCnt run (after exhausted testing) then finish
378 if (errCnt<bestErrCnt){ //set this as new best run
379 bestErrCnt=errCnt;
380 bestStart = iii;
381 }
382 }
383 }
384 if (iii>=gLen){ //exhausted test
385 //if there was a ok test go back to that one and re-run the best run (then dump after that run)
386 if (bestErrCnt < (*bitLen/1000)) iii=bestStart;
387 }
388 }
389 if (bitnum>16){
390
391 // PrintAndLog("Data start pos:%d, lastBit:%d, stop pos:%d, numBits:%d",iii,lastBit,i,bitnum);
392 //move BitStream back to BinStream
393 // ClearGraph(0);
394 for (i=0; i < bitnum; ++i){
395 BinStream[i]=BitStream[i];
396 }
397 *bitLen=bitnum;
398 // RepaintGraphWindow();
399 //output
400 // if (errCnt>0){
401 // PrintAndLog("# Errors during Demoding (shown as 77 in bit stream): %d",errCnt);
402 // }
403 // PrintAndLog("ASK decoded bitstream:");
404 // Now output the bitstream to the scrollback by line of 16 bits
405 // printBitStream2(BitStream,bitnum);
406 //int errCnt=0;
407 //errCnt=manrawdemod(BitStream,bitnum);
408
409 // Em410xDecode(Cmd);
410 } else return -1;
411 return errCnt;
412}
413//translate wave to 11111100000 (1 for each short wave 0 for each long wave)
66707a3b 414size_t fsk_wave_demod(uint8_t * dest, size_t size)
eb191de6 415{
416 uint32_t last_transition = 0;
417 uint32_t idx = 1;
418 uint32_t maxVal=0;
66707a3b 419
420 // we do care about the actual theshold value as sometimes near the center of the
eb191de6 421 // wave we may get static that changes direction of wave for one value
422 // if our value is too low it might affect the read. and if our tag or
423 // antenna is weak a setting too high might not see anything. [marshmellow]
424 if (size<100) return 0;
425 for(idx=1; idx<100; idx++){
426 if(maxVal<dest[idx]) maxVal = dest[idx];
427 }
428 // set close to the top of the wave threshold with 13% margin for error
429 // less likely to get a false transition up there.
430 // (but have to be careful not to go too high and miss some short waves)
66707a3b 431 uint8_t threshold_value = (uint8_t)(maxVal*.87); idx=1;
432 //uint8_t threshold_value = 127;
eb191de6 433
434 // sync to first lo-hi transition, and threshold
435
436 // Need to threshold first sample
437 if(dest[0] < threshold_value) dest[0] = 0;
438 else dest[0] = 1;
439
440 size_t numBits = 0;
441 // count cycles between consecutive lo-hi transitions, there should be either 8 (fc/8)
442 // or 10 (fc/10) cycles but in practice due to noise etc we may end up with with anywhere
443 // between 7 to 11 cycles so fuzz it by treat anything <9 as 8 and anything else as 10
444 for(idx = 1; idx < size; idx++) {
445 // threshold current value
446 if (dest[idx] < threshold_value) dest[idx] = 0;
447 else dest[idx] = 1;
448
449 // Check for 0->1 transition
450 if (dest[idx-1] < dest[idx]) { // 0 -> 1 transition
66707a3b 451 if (idx-last_transition<6){ //0-5 = garbage noise
eb191de6 452 //do nothing with extra garbage
66707a3b 453 } else if (idx-last_transition < 9) { //6-8 = 8 waves
eb191de6 454 dest[numBits]=1;
66707a3b 455 } else { //9+ = 10 waves
eb191de6 456 dest[numBits]=0;
457 }
458 last_transition = idx;
459 numBits++;
460 }
461 }
462 return numBits; //Actually, it returns the number of bytes, but each byte represents a bit: 1 or 0
463}
464
465uint32_t myround2(float f)
466{
467 if (f >= 2000) return 2000;//something bad happened
468 return (uint32_t) (f + (float)0.5);
469}
470
471//translate 11111100000 to 10
66707a3b 472size_t aggregate_bits(uint8_t *dest,size_t size, uint8_t rfLen, uint8_t maxConsequtiveBits, uint8_t invert )// uint8_t h2l_crossing_value,uint8_t l2h_crossing_value,
eb191de6 473{
474 uint8_t lastval=dest[0];
475 uint32_t idx=0;
476 size_t numBits=0;
477 uint32_t n=1;
478
479 for( idx=1; idx < size; idx++) {
480
481 if (dest[idx]==lastval) {
482 n++;
483 continue;
484 }
485 //if lastval was 1, we have a 1->0 crossing
486 if ( dest[idx-1]==1 ) {
487 n=myround2((float)(n+1)/((float)(rfLen)/(float)8));
488 //n=(n+1) / h2l_crossing_value;
489 } else {// 0->1 crossing
66707a3b 490 n=myround2((float)(n+1)/((float)(rfLen-2)/(float)10)); //-2 for fudge factor
eb191de6 491 //n=(n+1) / l2h_crossing_value;
492 }
493 if (n == 0) n = 1;
494
495 if(n < maxConsequtiveBits) //Consecutive
496 {
497 if(invert==0){ //invert bits
498 memset(dest+numBits, dest[idx-1] , n);
499 }else{
500 memset(dest+numBits, dest[idx-1]^1 , n);
501 }
502 numBits += n;
503 }
504 n=0;
505 lastval=dest[idx];
506 }//end for
507 return numBits;
508}
509//by marshmellow (from holiman's base)
510// full fsk demod from GraphBuffer wave to decoded 1s and 0s (no mandemod)
511int fskdemod(uint8_t *dest, size_t size, uint8_t rfLen, uint8_t invert)
512{
513 //uint8_t h2l_crossing_value = 6;
514 //uint8_t l2h_crossing_value = 5;
515
516 // if (rfLen==64) //currently only know settings for RF/64 change from default if option entered
517 // {
518 // h2l_crossing_value=8; //or 8 as 64/8 = 8
519 // l2h_crossing_value=6; //or 6.4 as 64/10 = 6.4
520 // }
521 // size_t size = GraphTraceLen;
522 // FSK demodulator
66707a3b 523 size = fsk_wave_demod(dest, size);
524 size = aggregate_bits(dest, size,rfLen,192,invert);
eb191de6 525 // size = aggregate_bits(size, h2l_crossing_value, l2h_crossing_value,192, invert); //192=no limit to same values
526 //done messing with GraphBuffer - repaint
527 //RepaintGraphWindow();
528 return size;
529}
530// loop to get raw HID waveform then FSK demodulate the TAG ID from it
531int HIDdemodFSK(uint8_t *dest, size_t size, uint32_t *hi2, uint32_t *hi, uint32_t *lo)
532{
533
534 size_t idx=0; //, found=0; //size=0,
535 // FSK demodulator
536 size = fskdemod(dest, size,50,0);
537
538 // final loop, go over previously decoded manchester data and decode into usable tag ID
539 // 111000 bit pattern represent start of frame, 01 pattern represents a 1 and 10 represents a 0
540 uint8_t frame_marker_mask[] = {1,1,1,0,0,0};
541 int numshifts = 0;
542 idx = 0;
543 //one scan
544 while( idx + sizeof(frame_marker_mask) < size) {
545 // search for a start of frame marker
546 if ( memcmp(dest+idx, frame_marker_mask, sizeof(frame_marker_mask)) == 0)
547 { // frame marker found
548 idx+=sizeof(frame_marker_mask);
549 while(dest[idx] != dest[idx+1] && idx < size-2)
550 {
551 // Keep going until next frame marker (or error)
552 // Shift in a bit. Start by shifting high registers
553 *hi2 = (*hi2<<1)|(*hi>>31);
554 *hi = (*hi<<1)|(*lo>>31);
555 //Then, shift in a 0 or one into low
556 if (dest[idx] && !dest[idx+1]) // 1 0
557 *lo=(*lo<<1)|0;
558 else // 0 1
559 *lo=(*lo<<1)|1;
560 numshifts++;
561 idx += 2;
562 }
563 // Hopefully, we read a tag and hit upon the next frame marker
564 if(idx + sizeof(frame_marker_mask) < size)
565 {
566 if ( memcmp(dest+idx, frame_marker_mask, sizeof(frame_marker_mask)) == 0)
567 {
568 //good return
569 return idx;
570 }
571 }
572 // reset
573 *hi2 = *hi = *lo = 0;
574 numshifts = 0;
575 }else {
576 idx++;
577 }
578 }
579 return -1;
580}
581
582uint32_t bytebits_to_byte(uint8_t* src, int numbits)
583{
584 uint32_t num = 0;
585 for(int i = 0 ; i < numbits ; i++)
586 {
587 num = (num << 1) | (*src);
588 src++;
589 }
590 return num;
591}
592
593int IOdemodFSK(uint8_t *dest, size_t size)
594{
66707a3b 595 uint32_t idx=0;
eb191de6 596 //make sure buffer has data
597 if (size < 64) return -1;
598 //test samples are not just noise
599 uint8_t testMax=0;
600 for(idx=0;idx<64;idx++){
601 if (testMax<dest[idx]) testMax=dest[idx];
602 }
603 idx=0;
604 //if not just noise
605 if (testMax>170){
606 // FSK demodulator
607 size = fskdemod(dest, size,64,1);
608 //Index map
609 //0 10 20 30 40 50 60
610 //| | | | | | |
611 //01234567 8 90123456 7 89012345 6 78901234 5 67890123 4 56789012 3 45678901 23
612 //-----------------------------------------------------------------------------
613 //00000000 0 11110000 1 facility 1 version* 1 code*one 1 code*two 1 ???????? 11
614 //
615 //XSF(version)facility:codeone+codetwo
616 //Handle the data
66707a3b 617 uint8_t mask[] = {0,0,0,0,0,0,0,0,0,1};
eb191de6 618 for( idx=0; idx < (size - 74); idx++) {
619 if ( memcmp(dest + idx, mask, sizeof(mask))==0) {
620 //frame marker found
621 if (!dest[idx+8] && dest[idx+17]==1 && dest[idx+26]==1 && dest[idx+35]==1 && dest[idx+44]==1 && dest[idx+53]==1){
622 //confirmed proper separator bits found
623 //return start position
66707a3b 624 return (int) idx;
eb191de6 625 }
626 }
627 }
628 }
629 return 0;
630}
631
632// by marshmellow
633// not perfect especially with lower clocks or VERY good antennas (heavy wave clipping)
634// maybe somehow adjust peak trimming value based on samples to fix?
635int DetectClock2(uint8_t dest[], size_t size, int clock)
636{
637 int i=0;
638 int peak=0;
639 int low=0;
640 int clk[]={16,32,40,50,64,100,128,256};
641 for (;i<8;++i)
642 if (clk[i]==clock) return clock;
643 if (!peak){
644 for (i=0;i<size;++i){
645 if(dest[i]>peak){
646 peak = dest[i];
647 }
648 if(dest[i]<low){
649 low = dest[i];
650 }
651 }
652 peak=(int)(peak*.75);
653 low= (int)(low*.75);
654 }
655 int ii;
656 int loopCnt = 256;
657 if (size<loopCnt) loopCnt = size;
658 int clkCnt;
659 int tol = 0;
660 int bestErr=1000;
661 int errCnt[]={0,0,0,0,0,0,0,0};
662 for(clkCnt=0; clkCnt<6;++clkCnt){
663 if (clk[clkCnt]==32){
664 tol=1;
665 }else{
666 tol=0;
667 }
668 bestErr=1000;
669 for (ii=0; ii<loopCnt; ++ii){
670 if ((dest[ii]>=peak) || (dest[ii]<=low)){
671 errCnt[clkCnt]=0;
672 for (i=0; i<((int)(size/clk[clkCnt])-1); ++i){
673 if (dest[ii+(i*clk[clkCnt])]>=peak || dest[ii+(i*clk[clkCnt])]<=low){
674 }else if(dest[ii+(i*clk[clkCnt])-tol]>=peak || dest[ii+(i*clk[clkCnt])-tol]<=low){
675 }else if(dest[ii+(i*clk[clkCnt])+tol]>=peak || dest[ii+(i*clk[clkCnt])+tol]<=low){
676 }else{ //error no peak detected
677 errCnt[clkCnt]++;
678 }
679 }
680 if(errCnt[clkCnt]==0) return clk[clkCnt];
681 if(errCnt[clkCnt]<bestErr) bestErr=errCnt[clkCnt];
682 }
683 }
684 errCnt[clkCnt]=bestErr;
685 }
686 int iii=0;
687 int best=0;
688 for (iii=0; iii<6;++iii){
689 if (errCnt[iii]<errCnt[best]){
690 best = iii;
691 }
692 }
693 return clk[best];
694}
Impressum, Datenschutz