+ // set clock - might be able to get this externally and remove this work...
+ if (!clk) {
+ for (uint8_t clkCnt = 0; clkCnt<7; clkCnt++) {
+ tol = fndClk[clkCnt]/8;
+ if (minClk >= fndClk[clkCnt]-tol && minClk <= fndClk[clkCnt]+1) {
+ clk=fndClk[clkCnt];
+ break;
+ }
+ }
+ // clock not found - ERROR
+ if (!clk) {
+ if (g_debugMode==2) prnt("DEBUG STT: clock not found - quitting");
+ return false;
+ }
+ } else tol = clk/8;
+
+ *foundclock = clk;
+
+ // look for Sequence Terminator - should be pulses of clk*(1 or 1.5), clk*2, clk*(1.5 or 2)
+ start = -1;
+ for (i = 0; i < j - 4; ++i) {
+ skip += tmpbuff[i];
+ if (tmpbuff[i] >= clk*1-tol && tmpbuff[i] <= (clk*2)+tol && waveLen[i] < clk+tol) { //1 to 2 clocks depending on 2 bits prior
+ if (tmpbuff[i+1] >= clk*2-tol && tmpbuff[i+1] <= clk*2+tol && waveLen[i+1] > clk*3/2-tol) { //2 clocks and wave size is 1 1/2
+ if (tmpbuff[i+2] >= (clk*3)/2-tol && tmpbuff[i+2] <= clk*2+tol && waveLen[i+2] > clk-tol) { //1 1/2 to 2 clocks and at least one full clock wave
+ if (tmpbuff[i+3] >= clk*1-tol && tmpbuff[i+3] <= clk*2+tol) { //1 to 2 clocks for end of ST + first bit
+ start = i + 3;
+ break;
+ }
+ }
+ }
+ }
+ }
+ // first ST not found - ERROR
+ if (start < 0) {
+ if (g_debugMode==2) prnt("DEBUG STT: first STT not found - quitting");
+ return false;
+ } else {
+ if (g_debugMode==2) prnt("DEBUG STT: first STT found at: %d, j=%d",start, j);
+ }
+ if (waveLen[i+2] > clk*1+tol)
+ phaseoff = 0;
+ else
+ phaseoff = clk/2;
+
+ // skip over the remainder of ST
+ skip += clk*7/2; //3.5 clocks from tmpbuff[i] = end of st - also aligns for ending point
+
+ // now do it again to find the end
+ end = skip;
+ for (i += 3; i < j - 4; ++i) {
+ end += tmpbuff[i];
+ if (tmpbuff[i] >= clk*1-tol && tmpbuff[i] <= (clk*2)+tol && waveLen[i] < clk+tol) { //1 to 2 clocks depending on 2 bits prior
+ if (tmpbuff[i+1] >= clk*2-tol && tmpbuff[i+1] <= clk*2+tol && waveLen[i+1] > clk*3/2-tol) { //2 clocks and wave size is 1 1/2
+ if (tmpbuff[i+2] >= (clk*3)/2-tol && tmpbuff[i+2] <= clk*2+tol && waveLen[i+2] > clk-tol) { //1 1/2 to 2 clocks and at least one full clock wave
+ if (tmpbuff[i+3] >= clk*1-tol && tmpbuff[i+3] <= clk*2+tol) { //1 to 2 clocks for end of ST + first bit
+ complete = true;
+ break;
+ }
+ }
+ }
+ }
+ }
+ end -= phaseoff;
+ //didn't find second ST - ERROR
+ if (!complete) {
+ if (g_debugMode==2) prnt("DEBUG STT: second STT not found - quitting");
+ return false;
+ }
+ if (g_debugMode==2) prnt("DEBUG STT: start of data: %d end of data: %d, datalen: %d, clk: %d, bits: %d, phaseoff: %d", skip, end, end-skip, clk, (end-skip)/clk, phaseoff);
+ //now begin to trim out ST so we can use normal demod cmds
+ start = skip;
+ size_t datalen = end - start;
+ // check validity of datalen (should be even clock increments) - use a tolerance of up to 1/8th a clock
+ if ( clk - (datalen % clk) <= clk/8) {
+ // padd the amount off - could be problematic... but shouldn't happen often
+ datalen += clk - (datalen % clk);
+ } else if ( (datalen % clk) <= clk/8 ) {
+ // padd the amount off - could be problematic... but shouldn't happen often
+ datalen -= datalen % clk;
+ } else {
+ if (g_debugMode==2) prnt("DEBUG STT: datalen not divisible by clk: %u %% %d = %d - quitting", datalen, clk, datalen % clk);
+ return false;
+ }
+ // if datalen is less than one t55xx block - ERROR
+ if (datalen/clk < 8*4) {
+ if (g_debugMode==2) prnt("DEBUG STT: datalen is less than 1 full t55xx block - quitting");
+ return false;
+ }
+ size_t dataloc = start;
+ if (buffer[dataloc-(clk*4)-(clk/8)] <= low && buffer[dataloc] <= low && buffer[dataloc-(clk*4)] >= high) {
+ //we have low drift (and a low just before the ST and a low just after the ST) - compensate by backing up the start
+ for ( i=0; i <= (clk/8); ++i ) {
+ if ( buffer[dataloc - (clk*4) - i] <= low ) {
+ dataloc -= i;
+ break;
+ }
+ }
+ }
+
+ size_t newloc = 0;
+ i=0;
+ if (g_debugMode==2) prnt("DEBUG STT: Starting STT trim - start: %d, datalen: %d ",dataloc, datalen);
+ bool firstrun = true;
+ // warning - overwriting buffer given with raw wave data with ST removed...
+ while ( dataloc < bufsize-(clk/2) ) {
+ //compensate for long high at end of ST not being high due to signal loss... (and we cut out the start of wave high part)
+ if (buffer[dataloc]<high && buffer[dataloc]>low && buffer[dataloc+3]<high && buffer[dataloc+3]>low) {
+ for(i=0; i < clk/2-tol; ++i) {
+ buffer[dataloc+i] = high+5;
+ }
+ } //test for single sample outlier (high between two lows) in the case of very strong waves
+ if (buffer[dataloc] >= high && buffer[dataloc+2] <= low) {
+ buffer[dataloc] = buffer[dataloc+2];
+ buffer[dataloc+1] = buffer[dataloc+2];
+ }
+ if (firstrun) {
+ *stend = dataloc;
+ *ststart = dataloc-(clk*4);
+ firstrun=false;
+ }
+ for (i=0; i<datalen; ++i) {
+ if (i+newloc < bufsize) {
+ if (i+newloc < dataloc)
+ buffer[i+newloc] = buffer[dataloc];
+
+ dataloc++;
+ }
+ }
+ newloc += i;
+ //skip next ST - we just assume it will be there from now on...
+ if (g_debugMode==2) prnt("DEBUG STT: skipping STT at %d to %d", dataloc, dataloc+(clk*4));
+ dataloc += clk*4;
+ }
+ *size = newloc;
+ return true;
+}
+bool DetectST(uint8_t buffer[], size_t *size, int *foundclock) {
+ size_t ststart = 0, stend = 0;
+ return DetectST_ext(buffer, size, foundclock, &ststart, &stend);
+}
+
+//by marshmellow
+//take 01 or 10 = 1 and 11 or 00 = 0
+//check for phase errors - should never have 111 or 000 should be 01001011 or 10110100 for 1010
+//decodes biphase or if inverted it is AKA conditional dephase encoding AKA differential manchester encoding
+int BiphaseRawDecode(uint8_t *BitStream, size_t *size, int offset, int invert) {
+ uint16_t bitnum = 0;
+ uint16_t errCnt = 0;
+ size_t i = offset;
+ uint16_t MaxBits=512;
+ //if not enough samples - error
+ if (*size < 51) return -1;
+ //check for phase change faults - skip one sample if faulty
+ uint8_t offsetA = 1, offsetB = 1;
+ for (; i<48; i+=2){
+ if (BitStream[i+1]==BitStream[i+2]) offsetA=0;
+ if (BitStream[i+2]==BitStream[i+3]) offsetB=0;
+ }
+ if (!offsetA && offsetB) offset++;
+ for (i=offset; i<*size-3; i+=2){
+ //check for phase error
+ if (BitStream[i+1]==BitStream[i+2]) {
+ BitStream[bitnum++]=7;
+ errCnt++;
+ }
+ if((BitStream[i]==1 && BitStream[i+1]==0) || (BitStream[i]==0 && BitStream[i+1]==1)){
+ BitStream[bitnum++]=1^invert;
+ } else if((BitStream[i]==0 && BitStream[i+1]==0) || (BitStream[i]==1 && BitStream[i+1]==1)){
+ BitStream[bitnum++]=invert;
+ } else {
+ BitStream[bitnum++]=7;
+ errCnt++;
+ }
+ if(bitnum>MaxBits) break;
+ }
+ *size=bitnum;
+ return errCnt;
+}
+
+//by marshmellow
+//take 10 and 01 and manchester decode
+//run through 2 times and take least errCnt
+int manrawdecode(uint8_t * BitStream, size_t *size, uint8_t invert, uint8_t *alignPos) {
+ uint16_t bitnum=0, MaxBits = 512, errCnt = 0;
+ size_t i, ii;
+ uint16_t bestErr = 1000, bestRun = 0;
+ if (*size < 16) return -1;
+ //find correct start position [alignment]
+ for (ii=0;ii<2;++ii){
+ for (i=ii; i<*size-3; i+=2)
+ if (BitStream[i]==BitStream[i+1])
+ errCnt++;
+
+ if (bestErr>errCnt){
+ bestErr=errCnt;
+ bestRun=ii;
+ }
+ errCnt=0;
+ }
+ *alignPos=bestRun;
+ //decode
+ for (i=bestRun; i < *size-3; i+=2){
+ if(BitStream[i] == 1 && (BitStream[i+1] == 0)){
+ BitStream[bitnum++]=invert;
+ } else if((BitStream[i] == 0) && BitStream[i+1] == 1){
+ BitStream[bitnum++]=invert^1;
+ } else {
+ BitStream[bitnum++]=7;
+ }
+ if(bitnum>MaxBits) break;
+ }
+ *size=bitnum;
+ return bestErr;
+}
+
+// by marshmellow
+// to detect a wave that has heavily clipped (clean) samples
+uint8_t DetectCleanAskWave(uint8_t dest[], size_t size, uint8_t high, uint8_t low) {
+ bool allArePeaks = true;
+ uint16_t cntPeaks=0;
+ size_t loopEnd = 512+160;
+ if (loopEnd > size) loopEnd = size;
+ for (size_t i=160; i<loopEnd; i++){
+ if (dest[i]>low && dest[i]<high)
+ allArePeaks = false;
+ else
+ cntPeaks++;
+ }
+ if (!allArePeaks){
+ if (cntPeaks > 300) return true;
+ }
+ return allArePeaks;