Add support for Porsche Boxter/Cayman TPMS

This commit is contained in:
Christian W. Zuckschwerdt 2021-12-07 11:01:53 +01:00
parent 69039a94fc
commit 556759d998
8 changed files with 133 additions and 0 deletions

View file

@ -286,6 +286,7 @@ See [CONTRIBUTING.md](./docs/CONTRIBUTING.md).
[200]* Auriol 4-LD5661 temperature/rain sensor
[201] Unbranded SolarTPMS for trucks
[202] Funkbus / Instafunk (Berker, Jira, Jung)
[203] Porsche Boxster/Cayman TPMS
* Disabled by default, use -R n or -G
@ -323,6 +324,7 @@ Common keys are:
reset=<reset> (or: r=<reset>)
gap=<gap> (or: g=<gap>)
tolerance=<tolerance> (or: t=<tolerance>)
priority=<n> : run decoder only as fallback
where:
<name> can be any descriptive name tag you need in the output
<modulation> is one of:

View file

@ -423,6 +423,7 @@ stop_after_successful_events false
# protocol 200 # Auriol 4-LD5661 temperature/rain sensor
protocol 201 # Unbranded SolarTPMS for trucks
protocol 202 # Funkbus / Instafunk (Berker, Jira, Jung)
protocol 203 # Porsche Boxster/Cayman TPMS
## Flex devices (command line option "-X")

View file

@ -210,6 +210,7 @@
DECL(auriol_4ld5661) \
DECL(tpms_truck) \
DECL(funkbus_remote) \
DECL(tpms_porsche) \
/* Add new decoders here. */

View file

@ -225,6 +225,9 @@ gap=<gap> (or: g=<gap>)
.RS
tolerance=<tolerance> (or: t=<tolerance>)
.RE
.RS
priority=<n> : run decoder only as fallback
.RE
where:
<name> can be any descriptive name tag you need in the output
<modulation> is one of:

View file

@ -196,6 +196,7 @@ add_library(r_433 STATIC
devices/tpms_jansite.c
devices/tpms_jansite_solar.c
devices/tpms_pmv107j.c
devices/tpms_porsche.c
devices/tpms_renault.c
devices/tpms_toyota.c
devices/tpms_truck.c

121
src/devices/tpms_porsche.c Normal file
View file

@ -0,0 +1,121 @@
/** @file
Porsche Boxster/Cayman TPMS.
Copyright (C) 2021 Christian W. Zuckschwerdt <zany@triq.net>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
*/
/**
Porsche Boxster/Cayman TPMS.
Seen on Porsche second generation (Typ 987) Boxster/Cayman.
Full preamble is {30}ccccccca (33333332).
The data is Differential Manchester Coded (DMC).
Example data:
{193}333333354ab32d334b2d4ab2cab54cb34cb2aab4cd552ccd8
{193}333333354ab32d334b2d4ab2caaab34cb34d554aacd2b2cd8
23d7 ad23 623b bb02 f05f
23d7 ad23 603b bb02 1d37
Data layout (nibbles):
II II II II PP TT SS SS CC
- I: 32 bit ID
- P: 8 bit Pressure (scale?)
- T: 8 bit Temperature (deg. C offset by 40)
- S: Status?
- C: 16 bit Checksum, CRC-16 poly 0x1021 init 0xffff
*/
#include "decoder.h"
static int tpms_porsche_decode(r_device *decoder, bitbuffer_t *bitbuffer, unsigned row, unsigned bitpos)
{
bitbuffer_t packet_bits = {0};
bitbuffer_differential_manchester_decode(bitbuffer, row, bitpos, &packet_bits, 80);
// make sure we decoded the expected number of bits
if (packet_bits.bits_per_row[0] < 80) {
// fprintf(stderr, "bitpos=%u start_pos=%u = %u\n", bitpos, start_pos, (start_pos - bitpos));
return 0; // DECODE_FAIL_SANITY;
}
uint8_t *b = packet_bits.bb[0];
// Checksum is CRC-16 poly 0x1021 init 0xffff over 8 bytes
int checksum = crc16(b, 10, 0x1021, 0xffff);
if (checksum != 0) {
return 0; //DECODE_FAIL_MIC;
}
int id = (unsigned)b[0] << 24 | b[1] << 16 | b[2] << 8 | b[3];
int pressure = b[4];
int temperature = b[5];
int flags = b[6] << 8 | b[7];
char id_str[4 * 2 + 1];
sprintf(id_str, "%08x", id);
/* clang-format off */
data_t *data = data_make(
"model", "", DATA_STRING, "Porsche",
"type", "", DATA_STRING, "TPMS",
"id", "", DATA_STRING, id_str,
"pressure", "Pressure", DATA_INT, pressure, // need to find the scaling
"temperature_C", "Temperature", DATA_FORMAT, "%.0f C", DATA_DOUBLE, (float)temperature - 40.0,
"flags", "", DATA_FORMAT, "%04x", DATA_INT, flags,
"mic", "Integrity", DATA_STRING, "CRC",
NULL);
/* clang-format on */
decoder_output_data(decoder, data);
return 1;
}
/** @sa tpms_porsche_decode() */
static int tpms_porsche_callback(r_device *decoder, bitbuffer_t *bitbuffer)
{
// Full preamble is {30}ccccccca (33333332).
uint8_t const preamble_pattern[] = {0x33, 0x33, 0x20}; // 20 bit
int events = 0;
// Find a preamble with enough bits after it that it could be a complete packet
unsigned bitpos = 0;
while ((bitpos = bitbuffer_search(bitbuffer, 0, bitpos, preamble_pattern, 20)) + 100 <=
bitbuffer->bits_per_row[0]) {
events += tpms_porsche_decode(decoder, bitbuffer, 0, bitpos + 20);
bitpos += 2;
}
return events;
}
static char *output_fields[] = {
"model",
"type",
"id",
"pressure",
"temperature_C",
"flags",
"mic",
NULL,
};
r_device tpms_porsche = {
.name = "Porsche Boxster/Cayman TPMS",
.modulation = FSK_PULSE_PCM,
.short_width = 52, // 12-13 samples @250k
.long_width = 52, // FSK
.reset_limit = 150, // Maximum gap size before End Of Message [us].
.decode_fn = &tpms_porsche_callback,
.fields = output_fields,
};

View file

@ -325,6 +325,7 @@ COPY ..\..\libusb\MS64\dll\libusb*.dll $(TargetDir)</Command>
<ClCompile Include="..\src\devices\tpms_jansite.c" />
<ClCompile Include="..\src\devices\tpms_jansite_solar.c" />
<ClCompile Include="..\src\devices\tpms_pmv107j.c" />
<ClCompile Include="..\src\devices\tpms_porsche.c" />
<ClCompile Include="..\src\devices\tpms_renault.c" />
<ClCompile Include="..\src\devices\tpms_toyota.c" />
<ClCompile Include="..\src\devices\tpms_truck.c" />

View file

@ -712,6 +712,9 @@
<ClCompile Include="..\src\devices\tpms_pmv107j.c">
<Filter>Source Files\devices</Filter>
</ClCompile>
<ClCompile Include="..\src\devices\tpms_porsche.c">
<Filter>Source Files\devices</Filter>
</ClCompile>
<ClCompile Include="..\src\devices\tpms_renault.c">
<Filter>Source Files\devices</Filter>
</ClCompile>