+ *size = bitnum;
+ return bestErrCnt;
+}
+
+//by marshmellow
+//detects the bit clock for FSK given the high and low Field Clocks
+uint8_t detectFSKClk(uint8_t *BitStream, size_t size, uint8_t fcHigh, uint8_t fcLow)
+{
+ uint8_t clk[] = {8,16,32,40,50,64,100,128,0};
+ uint16_t rfLens[] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
+ uint8_t rfCnts[] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
+ uint8_t rfLensFnd = 0;
+ uint8_t lastFCcnt = 0;
+ uint16_t fcCounter = 0;
+ uint16_t rfCounter = 0;
+ uint8_t firstBitFnd = 0;
+ size_t i;
+ if (size == 0) return 0;
+
+ uint8_t fcTol = (uint8_t)(0.5+(float)(fcHigh-fcLow)/2);
+ rfLensFnd=0;
+ fcCounter=0;
+ rfCounter=0;
+ firstBitFnd=0;
+ //PrintAndLog("DEBUG: fcTol: %d",fcTol);
+ // prime i to first up transition
+ for (i = 1; i < size-1; i++)
+ if (BitStream[i] > BitStream[i-1] && BitStream[i]>=BitStream[i+1])
+ break;
+
+ for (; i < size-1; i++){
+ fcCounter++;
+ rfCounter++;
+
+ if (BitStream[i] <= BitStream[i-1] || BitStream[i] < BitStream[i+1])
+ continue;
+ // else new peak
+ // if we got less than the small fc + tolerance then set it to the small fc
+ if (fcCounter < fcLow+fcTol)
+ fcCounter = fcLow;
+ else //set it to the large fc
+ fcCounter = fcHigh;
+
+ //look for bit clock (rf/xx)
+ if ((fcCounter < lastFCcnt || fcCounter > lastFCcnt)){
+ //not the same size as the last wave - start of new bit sequence
+ if (firstBitFnd > 1){ //skip first wave change - probably not a complete bit
+ for (int ii=0; ii<15; ii++){
+ if (rfLens[ii] == rfCounter){
+ rfCnts[ii]++;
+ rfCounter = 0;
+ break;
+ }
+ }
+ if (rfCounter > 0 && rfLensFnd < 15){
+ //PrintAndLog("DEBUG: rfCntr %d, fcCntr %d",rfCounter,fcCounter);
+ rfCnts[rfLensFnd]++;
+ rfLens[rfLensFnd++] = rfCounter;
+ }
+ } else {
+ firstBitFnd++;
+ }
+ rfCounter=0;
+ lastFCcnt=fcCounter;
+ }
+ fcCounter=0;
+ }
+ uint8_t rfHighest=15, rfHighest2=15, rfHighest3=15;
+
+ for (i=0; i<15; i++){
+ //PrintAndLog("DEBUG: RF %d, cnts %d",rfLens[i], rfCnts[i]);
+ //get highest 2 RF values (might need to get more values to compare or compare all?)
+ if (rfCnts[i]>rfCnts[rfHighest]){
+ rfHighest3=rfHighest2;
+ rfHighest2=rfHighest;
+ rfHighest=i;
+ } else if(rfCnts[i]>rfCnts[rfHighest2]){
+ rfHighest3=rfHighest2;
+ rfHighest2=i;
+ } else if(rfCnts[i]>rfCnts[rfHighest3]){
+ rfHighest3=i;
+ }
+ }
+ // set allowed clock remainder tolerance to be 1 large field clock length+1
+ // we could have mistakenly made a 9 a 10 instead of an 8 or visa versa so rfLens could be 1 FC off
+ uint8_t tol1 = fcHigh+1;
+
+ //PrintAndLog("DEBUG: hightest: 1 %d, 2 %d, 3 %d",rfLens[rfHighest],rfLens[rfHighest2],rfLens[rfHighest3]);
+
+ // loop to find the highest clock that has a remainder less than the tolerance
+ // compare samples counted divided by
+ int ii=7;
+ for (; ii>=0; ii--){
+ if (rfLens[rfHighest] % clk[ii] < tol1 || rfLens[rfHighest] % clk[ii] > clk[ii]-tol1){
+ if (rfLens[rfHighest2] % clk[ii] < tol1 || rfLens[rfHighest2] % clk[ii] > clk[ii]-tol1){
+ if (rfLens[rfHighest3] % clk[ii] < tol1 || rfLens[rfHighest3] % clk[ii] > clk[ii]-tol1){
+ break;
+ }
+ }
+ }
+ }
+
+ if (ii<0) return 0; // oops we went too far
+
+ return clk[ii];
+}
+
+//by marshmellow
+//countFC is to detect the field clock lengths.
+//counts and returns the 2 most common wave lengths
+//mainly used for FSK field clock detection
+uint16_t countFC(uint8_t *BitStream, size_t size, uint8_t fskAdj)
+{
+ uint8_t fcLens[] = {0,0,0,0,0,0,0,0,0,0};
+ uint16_t fcCnts[] = {0,0,0,0,0,0,0,0,0,0};
+ uint8_t fcLensFnd = 0;
+ uint8_t lastFCcnt=0;
+ uint8_t fcCounter = 0;
+ size_t i;
+ if (size == 0) return 0;
+
+ // prime i to first up transition
+ for (i = 1; i < size-1; i++)
+ if (BitStream[i] > BitStream[i-1] && BitStream[i] >= BitStream[i+1])
+ break;
+
+ for (; i < size-1; i++){
+ if (BitStream[i] > BitStream[i-1] && BitStream[i] >= BitStream[i+1]){
+ // new up transition
+ fcCounter++;
+ if (fskAdj){
+ //if we had 5 and now have 9 then go back to 8 (for when we get a fc 9 instead of an 8)
+ if (lastFCcnt==5 && fcCounter==9) fcCounter--;
+ //if fc=9 or 4 add one (for when we get a fc 9 instead of 10 or a 4 instead of a 5)
+ if ((fcCounter==9) || fcCounter==4) fcCounter++;
+ // save last field clock count (fc/xx)
+ lastFCcnt = fcCounter;
+ }
+ // find which fcLens to save it to:
+ for (int ii=0; ii<10; ii++){
+ if (fcLens[ii]==fcCounter){
+ fcCnts[ii]++;
+ fcCounter=0;
+ break;