schrader_tpms.c 2.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758
  1. /* Schrader TPMS. Usually 443.92 Mhz OOK, 120us pulse len.
  2. *
  3. * 500us high pulse + Preamble + Manchester coded bits where:
  4. * 1 = 10
  5. * 0 = 01
  6. *
  7. * 60 bits of data total (first 4 nibbles is the preamble, 0xF).
  8. *
  9. * Used in FIAT-Chrysler, Mercedes, ... */
  10. #include "../app.h"
  11. #define USE_TEST_VECTOR 0
  12. static const char *test_vector = "000000111101010101011010010110010110101001010110100110011001100101010101011010100110100110011010101010101010101010101010101010101010101010101010";
  13. static bool decode(uint8_t *bits, uint32_t numbytes, uint32_t numbits, ProtoViewMsgInfo *info) {
  14. if (USE_TEST_VECTOR) { /* Test vector to check that decoding works. */
  15. bitmap_set_pattern(bits,numbytes,test_vector);
  16. numbits = strlen(test_vector);
  17. }
  18. if (numbits < 64) return false; /* Preamble + data. */
  19. const char *sync_pattern = "1111010101" "01011010";
  20. uint64_t off = bitmap_seek_bits(bits,numbytes,0,numbits,sync_pattern);
  21. if (off == BITMAP_SEEK_NOT_FOUND) return false;
  22. FURI_LOG_E(TAG, "Schrader TPMS gap+preamble found");
  23. off += 10; /* Skip just the long pulse and the first 3 bits of sync, so
  24. that we have the first byte of data with the sync nibble
  25. 0011 = 0x3. */
  26. uint8_t raw[8];
  27. uint32_t decoded =
  28. convert_from_line_code(raw,sizeof(raw),bits,numbytes,off,
  29. "01","10"); /* Manchester code. */
  30. FURI_LOG_E(TAG, "Schrader TPMS decoded bits: %lu", decoded);
  31. if (decoded < 64) return false; /* Require the full 8 bytes. */
  32. float kpa = (float)raw[5]*2.5;
  33. int temp = raw[6]-50;
  34. snprintf(info->name,sizeof(info->name),"%s","Schrader TPMS");
  35. snprintf(info->raw,sizeof(info->raw),"%02X%02X%02X%02X%02X%02X%02X%02X",
  36. raw[0],raw[1],raw[2],raw[3],raw[4],raw[5],
  37. raw[6],raw[7]);
  38. snprintf(info->info1,sizeof(info->info1),"Tire ID %01X%02X%02X%02X",
  39. raw[1]&7,raw[2],raw[3],raw[4]); /* Only 28 bits of ID, not 32. */
  40. snprintf(info->info2,sizeof(info->info2),"Pressure %.2f kpa", (double)kpa);
  41. snprintf(info->info3,sizeof(info->info3),"Temperature %d C", temp);
  42. return true;
  43. }
  44. ProtoViewDecoder SchraderTPMSDecoder = {
  45. "Schrader TPMS", decode
  46. };