Skip to content

Commit

Permalink
Differential Manchester encoding.
Browse files Browse the repository at this point in the history
  • Loading branch information
antirez committed Jan 11, 2023
1 parent 015ee09 commit 126f1f3
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 7 deletions.
1 change: 1 addition & 0 deletions app.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
21 changes: 19 additions & 2 deletions custom_presets.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
*
Expand All @@ -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. */
Expand Down Expand Up @@ -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)
Expand Down
29 changes: 24 additions & 5 deletions signal.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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/<name>.c */

Expand Down

0 comments on commit 126f1f3

Please sign in to comment.