diff --git a/app.h b/app.h index 3d5c2567750..ec530acd153 100644 --- a/app.h +++ b/app.h @@ -163,6 +163,7 @@ void bitmap_invert_bytes_bits(uint8_t *p, uint32_t len); bool bitmap_match_bits(uint8_t *b, uint32_t blen, uint32_t bitpos, const char *bits); uint32_t bitmap_seek_bits(uint8_t *b, uint32_t blen, uint32_t startpos, uint32_t maxbits, const char *bits); uint32_t convert_from_line_code(uint8_t *buf, uint64_t buflen, uint8_t *bits, uint32_t len, uint32_t offset, const char *zero_pattern, const char *one_pattern); +uint32_t convert_from_diff_manchester(uint8_t *buf, uint64_t buflen, uint8_t *bits, uint32_t len, uint32_t off, bool previous); /* view_*.c */ void render_view_raw_pulses(Canvas *const canvas, ProtoViewApp *app); diff --git a/custom_presets.h b/custom_presets.h index 8645d0e6b1b..38fca0e314e 100644 --- a/custom_presets.h +++ b/custom_presets.h @@ -11,7 +11,7 @@ * * ((256+MDMCFG3)*(2^MDMCFG4:0..3bits)) / 2^28 * 26000000. * - * For instance for the default values of MDMCFG3 (34) and MDMCFG4 (12): + * For instance for the default values of MDMCFG3[0..3] (34) and MDMCFG4 (12): * * ((256+34)*(2^12))/(2^28)*26000000 = 115051.2688000000, that is 115KBaud * @@ -38,6 +38,23 @@ * d 82 khz * e 68 khz * f 58 khz + * + * FSK deviation is controlled by the DEVIATION register. In Ruby: + * + * dev = (26000000.0/2**17)*(8+(deviation&7))*(2**(deviation>>4&7)) + * + * deviation&7 (last three bits) is the deviation mantissa, while + * deviation>>4&7 (bits 6,5,4) are the exponent. + * + * Deviations values according to certain configuration of DEVIATION: + * + * 0x04 -> 2.380371 kHz + * 0x24 -> 9.521484 kHz + * 0x34 -> 19.042969 Khz + * 0x40 -> 25.390625 Khz + * 0x43 -> 34.912109 Khz + * 0x45 -> 41.259765 Khz + * 0x47 -> 47.607422 kHz */ /* 20 KBaud, 2FSK, 28.56 kHz deviation, 325 Khz bandwidth filter. */ @@ -148,7 +165,7 @@ static uint8_t protoview_subghz_tpms3_async_regs[][2] = { {CC1101_MDMCFG2, 0x10}, // GFSK without any other check {CC1101_MDMCFG3, 0x93}, // Data rate is 20kBaud {CC1101_MDMCFG4, 0x59}, // Rx bandwidth filter is 325 kHz - {CC1101_DEVIATN, 0x40}, // Deviation 25.39 Khz + {CC1101_DEVIATN, 0x34}, // Deviation 19.04 Khz, works well with TPMS /* Main Radio Control State Machine */ {CC1101_MCSM0, 0x18}, // Autocalibrate on idle-to-rx/tx, PO_TIMEOUT is 64 cycles(149-155us) diff --git a/signal.c b/signal.c index e6d43cee384..cdb20f6d980 100644 --- a/signal.c +++ b/signal.c @@ -318,11 +318,9 @@ uint32_t convert_signal_to_bits(uint8_t *b, uint32_t blen, RawSamplesBuffer *s, /* This function converts the line code used to the final data representation. * The representation is put inside 'buf', for up to 'buflen' bytes of total - * data. For instance in order to convert manchester I can use "10" and "01" - * as zero and one patterns. It is possible to use "?" inside patterns in - * order to skip certain bits. For instance certain devices encode data twice, - * with each bit encoded in manchester encoding and then in its reversed - * representation. In such a case I could use "10??" and "01??". + * data. For instance in order to convert manchester you can use "10" and "01" + * as zero and one patterns. However this function does not handle differential + * encodings. See below for convert_from_diff_manchester(). * * The function returns the number of bits converted. It will stop as soon * as it finds a pattern that does not match zero or one patterns, or when @@ -351,6 +349,27 @@ uint32_t convert_from_line_code(uint8_t *buf, uint64_t buflen, uint8_t *bits, ui return decoded; } +/* Convert the differential Manchester code to bits. This is similar to + * convert_from_line_code() but specific for Manchester. The user must + * supply the value of the previous symbol before this stream, since + * in differential codings the next bits depend on the previous one. + * + * Parameters and return values are like convert_from_line_code(). */ +uint32_t convert_from_diff_manchester(uint8_t *buf, uint64_t buflen, uint8_t *bits, uint32_t len, uint32_t off, bool previous) +{ + uint32_t decoded = 0; + len *= 8; /* Conver to bits. */ + for (uint32_t j = off; j < len; j += 2) { + bool b0 = bitmap_get(bits,len,j); + bool b1 = bitmap_get(bits,len,j+1); + if (b0 == previous) break; /* Each new bit must switch value. */ + bitmap_set(buf,buflen,decoded++,b0 == b1); + previous = b1; + if (decoded/8 == buflen) break; /* No space left on target buffer. */ + } + return decoded; +} + /* Supported protocols go here, with the relevant implementation inside * protocols/.c */