From 2a91ac8c7d02ff277ebe40e7339a18bee2fe32dd Mon Sep 17 00:00:00 2001 From: antirez Date: Thu, 12 Jan 2023 16:30:24 +0100 Subject: [PATCH] Schrader TPMS implementation + CRC8 implementation. --- app.h | 3 ++ crc.c | 20 ++++++++++++++ protocols/b4b1.c | 2 +- protocols/renault_tpms.c | 10 +++---- protocols/schrader_tpms.c | 58 +++++++++++++++++++++++++++++++++++++++ protocols/toyota_tpms.c | 4 +-- signal.c | 6 ++-- 7 files changed, 93 insertions(+), 10 deletions(-) create mode 100644 crc.c create mode 100644 protocols/schrader_tpms.c diff --git a/app.h b/app.h index 2e6e5c34aed..7b4bd9aefe0 100644 --- a/app.h +++ b/app.h @@ -180,3 +180,6 @@ void view_exit_settings(ProtoViewApp *app); /* ui.c */ void canvas_draw_str_with_border(Canvas* canvas, uint8_t x, uint8_t y, const char* str, Color text_color, Color border_color); + +/* crc.c */ +uint8_t crc8(const uint8_t *data, size_t len, uint8_t init, uint8_t poly); diff --git a/crc.c b/crc.c new file mode 100644 index 00000000000..38a809e1037 --- /dev/null +++ b/crc.c @@ -0,0 +1,20 @@ +#include +#include + +/* CRC8 with the specified initialization value 'init' and + * polynomial 'poly'. */ +uint8_t crc8(const uint8_t *data, size_t len, uint8_t init, uint8_t poly) +{ + uint8_t crc = init; + size_t i, j; + for (i = 0; i < len; i++) { + crc ^= data[i]; + for (j = 0; j < 8; j++) { + if ((crc & 0x80) != 0) + crc = (uint8_t)((crc << 1) ^ poly); + else + crc <<= 1; + } + } + return crc; +} diff --git a/protocols/b4b1.c b/protocols/b4b1.c index 6977c0eb357..2bed2ac32fd 100644 --- a/protocols/b4b1.c +++ b/protocols/b4b1.c @@ -1,7 +1,7 @@ /* PT/SC remotes. Usually 443.92 Mhz OOK. * * This line code is used in many remotes such as Princeton chips - * named PT, Silian Microelectronics SC5262 and others. + * named PT2262, Silian Microelectronics SC5262 and others. * Basically every 4 pulsee represent a bit, where 1000 means 0, and * 1110 means 1. Usually we can read 24 bits of data. * In this specific implementation we check for a prelude that is diff --git a/protocols/renault_tpms.c b/protocols/renault_tpms.c index 0ad21445ab6..6c2cfb1e256 100644 --- a/protocols/renault_tpms.c +++ b/protocols/renault_tpms.c @@ -1,7 +1,7 @@ /* Renault tires TPMS. Usually 443.92 Mhz FSK. * - * Preamble + marshal-encoded bits. 9 Bytes in total if we don't - * count the preamble. */ + * Preamble + sync + Manchester bits. ~48us short pulse. + * 9 Bytes in total not counting the preamble. */ #include "../app.h" @@ -53,10 +53,10 @@ static bool decode(uint8_t *bits, uint32_t numbytes, uint32_t numbits, ProtoView snprintf(info->raw,sizeof(info->raw),"%02X%02X%02X%02X%02X%02X%02X%02X%02X", raw[0],raw[1],raw[2],raw[3],raw[4],raw[5], raw[6],raw[7],raw[8]); - snprintf(info->raw,sizeof(info->raw),"Tire ID %02X%02X%02X", + snprintf(info->info1,sizeof(info->info1),"Tire ID %02X%02X%02X", raw[3],raw[4],raw[5]); - snprintf(info->info1,sizeof(info->info1),"Pressure %.2f kpa", (double)kpa); - snprintf(info->info2,sizeof(info->info2),"Temperature %d C", temp); + snprintf(info->info2,sizeof(info->info2),"Pressure %.2f kpa", (double)kpa); + snprintf(info->info3,sizeof(info->info3),"Temperature %d C", temp); return true; } diff --git a/protocols/schrader_tpms.c b/protocols/schrader_tpms.c new file mode 100644 index 00000000000..e19a10ee1b8 --- /dev/null +++ b/protocols/schrader_tpms.c @@ -0,0 +1,58 @@ +/* Schrader TPMS. Usually 443.92 Mhz OOK, 120us pulse len. + * + * 500us high pulse + Preamble + Manchester coded bits where: + * 1 = 10 + * 0 = 01 + * + * 60 bits of data total (first 4 nibbles is the preamble, 0xF). + * + * Used in FIAT-Chrysler, Mercedes, ... */ + +#include "../app.h" + +#define USE_TEST_VECTOR 0 +static const char *test_vector = "000000111101010101011010010110010110101001010110100110011001100101010101011010100110100110011010101010101010101010101010101010101010101010101010"; + +static bool decode(uint8_t *bits, uint32_t numbytes, uint32_t numbits, ProtoViewMsgInfo *info) { + + if (USE_TEST_VECTOR) { /* Test vector to check that decoding works. */ + bitmap_set_pattern(bits,numbytes,test_vector); + numbits = strlen(test_vector); + } + + if (numbits < 64) return false; /* Preamble + data. */ + + const char *sync_pattern = "1111010101" "01011010"; + uint64_t off = bitmap_seek_bits(bits,numbytes,0,numbits,sync_pattern); + if (off == BITMAP_SEEK_NOT_FOUND) return false; + FURI_LOG_E(TAG, "Schrader TPMS gap+preamble found"); + + off += 10; /* Skip just the long pulse and the first 3 bits of sync, so + that we have the first byte of data with the sync nibble + 0011 = 0x3. */ + + uint8_t raw[8]; + uint32_t decoded = + convert_from_line_code(raw,sizeof(raw),bits,numbytes,off, + "01","10"); /* Manchester code. */ + FURI_LOG_E(TAG, "Schrader TPMS decoded bits: %lu", decoded); + + if (decoded < 64) return false; /* Require the full 8 bytes. */ + + float kpa = (float)raw[5]*2.5; + int temp = raw[6]-50; + + snprintf(info->name,sizeof(info->name),"%s","Schrader TPMS"); + snprintf(info->raw,sizeof(info->raw),"%02X%02X%02X%02X%02X%02X%02X%02X", + raw[0],raw[1],raw[2],raw[3],raw[4],raw[5], + raw[6],raw[7]); + snprintf(info->info1,sizeof(info->info1),"Tire ID %01X%02X%02X%02X", + raw[1]&7,raw[2],raw[3],raw[4]); /* Only 28 bits of ID, not 32. */ + snprintf(info->info2,sizeof(info->info2),"Pressure %.2f kpa", (double)kpa); + snprintf(info->info3,sizeof(info->info3),"Temperature %d C", temp); + return true; +} + +ProtoViewDecoder SchraderTPMSDecoder = { + "Schrader TPMS", decode +}; diff --git a/protocols/toyota_tpms.c b/protocols/toyota_tpms.c index 2e1d220c41f..c142769be33 100644 --- a/protocols/toyota_tpms.c +++ b/protocols/toyota_tpms.c @@ -1,6 +1,6 @@ -/* Ford tires TPMS. Usually 443.92 Mhz FSK (In Europe). +/* Toyota tires TPMS. Usually 443.92 Mhz FSK (In Europe). * - * Preamble + sync + 64 bits of data. + * Preamble + sync + 64 bits of data. ~48us short pulse length. * * The preamble + sync is something like: * diff --git a/signal.c b/signal.c index a83a6fe2ddb..463f4b30d94 100644 --- a/signal.c +++ b/signal.c @@ -163,7 +163,7 @@ void scan_for_signal(ProtoViewApp *app) { app->signal_decoded = decoded; raw_samples_copy(DetectedSamples,copy); raw_samples_center(DetectedSamples,i); - FURI_LOG_E(TAG, "Displayed sample updated (%d samples %lu us)", + FURI_LOG_E(TAG, "===> Displayed sample updated (%d samples %lu us)", (int)thislen, DetectedSamples->short_pulse_dur); /* Adjust raw view scale if the signal has an high @@ -382,12 +382,14 @@ extern ProtoViewDecoder Oregon2Decoder; extern ProtoViewDecoder B4B1Decoder; extern ProtoViewDecoder RenaultTPMSDecoder; extern ProtoViewDecoder ToyotaTPMSDecoder; +extern ProtoViewDecoder SchraderTPMSDecoder; ProtoViewDecoder *Decoders[] = { &Oregon2Decoder, /* Oregon sensors v2.1 protocol. */ &B4B1Decoder, /* PT, SC, ... 24 bits remotes. */ &RenaultTPMSDecoder, /* Renault TPMS. */ &ToyotaTPMSDecoder, /* Toyota TPMS. */ + &SchraderTPMSDecoder, /* Schrader TPMS. */ NULL }; @@ -407,7 +409,7 @@ bool decode_signal(RawSamplesBuffer *s, uint64_t len, ProtoViewMsgInfo *info) { /* We call the decoders with an offset a few samples before the actual * signal detected and for a len of a few bits after its end. */ - uint32_t before_samples = 10; + uint32_t before_samples = 20; uint32_t after_samples = 100; uint8_t *bitmap = malloc(bitmap_size);