schrader.c 2.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465
  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. raw[0] |= 0xf0; // Fix the preamble nibble for checksum computation.
  33. uint8_t cksum = crc8(raw,sizeof(raw)-1,0xf0,0x7);
  34. if (cksum != raw[7]) {
  35. FURI_LOG_E(TAG, "Schrader TPMS checksum mismatch");
  36. return false;
  37. }
  38. float kpa = (float)raw[5]*2.5;
  39. int temp = raw[6]-50;
  40. snprintf(info->name,sizeof(info->name),"%s","Schrader TPMS");
  41. snprintf(info->raw,sizeof(info->raw),"%02X%02X%02X%02X%02X%02X%02X%02X",
  42. raw[0],raw[1],raw[2],raw[3],raw[4],raw[5],
  43. raw[6],raw[7]);
  44. snprintf(info->info1,sizeof(info->info1),"Tire ID %01X%02X%02X%02X",
  45. raw[1]&7,raw[2],raw[3],raw[4]); /* Only 28 bits of ID, not 32. */
  46. snprintf(info->info2,sizeof(info->info2),"Pressure %.2f kpa", (double)kpa);
  47. snprintf(info->info3,sizeof(info->info3),"Temperature %d C", temp);
  48. return true;
  49. }
  50. ProtoViewDecoder SchraderTPMSDecoder = {
  51. "Schrader TPMS", decode
  52. };