Просмотр исходного кода

Differential Manchester encoding.

antirez 3 лет назад
Родитель
Сommit
126f1f3321
3 измененных файлов с 44 добавлено и 7 удалено
  1. 1 0
      app.h
  2. 19 2
      custom_presets.h
  3. 24 5
      signal.c

+ 1 - 0
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);

+ 19 - 2
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)

+ 24 - 5
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/<name>.c */