SENT fixes (#4692)

* SENT: measure more pulses during Unit time calibration

* SENT: no magic numbers

* SENT: fix typo

* SENT: setninfo output: do not show slow channels if not detected

* SENT: fix GM-style CRC calculation

* SENT: another one CRC algorithm, now for pressure sensor

* SENT: show CRC error percentage
This commit is contained in:
Andrey G 2022-10-23 01:07:22 +03:00 committed by GitHub
parent 98076927b0
commit d21d5397ac
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 47 additions and 17 deletions

View File

@ -29,6 +29,9 @@
/* Status + two 12-bit signals + CRC */ /* Status + two 12-bit signals + CRC */
#define SENT_MSG_PAYLOAD_SIZE (1 + SENT_MSG_DATA_SIZE + 1) // Size of payload #define SENT_MSG_PAYLOAD_SIZE (1 + SENT_MSG_DATA_SIZE + 1) // Size of payload
/* use 3 full frames + one additional pulse for unit time calibration */
#define SENT_CALIBRATION_PULSES (1 + 3 * SENT_MSG_PAYLOAD_SIZE)
/*==========================================================================*/ /*==========================================================================*/
/* Decoder configuration */ /* Decoder configuration */
/*==========================================================================*/ /*==========================================================================*/
@ -96,6 +99,7 @@ private:
/* CRC */ /* CRC */
uint8_t crc4(uint8_t* pdata, uint16_t ndata); uint8_t crc4(uint8_t* pdata, uint16_t ndata);
uint8_t crc4_gm(uint8_t* pdata, uint16_t ndata); uint8_t crc4_gm(uint8_t* pdata, uint16_t ndata);
uint8_t crc4_gm_v2(uint8_t* pdata, uint16_t ndata);
void restart(void); void restart(void);
@ -161,12 +165,13 @@ int sent_channel::Decoder(uint16_t clocks)
/* special case - tick time calculation */ /* special case - tick time calculation */
if (state == SENT_STATE_CALIB) { if (state == SENT_STATE_CALIB) {
/* Find longes pulse ... */ /* Find longes pulse */
if (clocks > tickPerUnit) { if (clocks > tickPerUnit) {
tickPerUnit = clocks; tickPerUnit = clocks;
} }
/* ... of 9 pulses */ /* ...this should be SYNC pulse */
if (pulseCounter >= (SENT_MSG_PAYLOAD_SIZE + 1)) { if (pulseCounter >= SENT_CALIBRATION_PULSES) {
/* calculate Unit time from SYNC pulse */
tickPerUnit = (tickPerUnit + (SENT_SYNC_INTERVAL + SENT_OFFSET_INTERVAL) / 2) / tickPerUnit = (tickPerUnit + (SENT_SYNC_INTERVAL + SENT_OFFSET_INTERVAL) / 2) /
(SENT_SYNC_INTERVAL + SENT_OFFSET_INTERVAL); (SENT_SYNC_INTERVAL + SENT_OFFSET_INTERVAL);
pulseCounter = 0; pulseCounter = 0;
@ -221,7 +226,8 @@ int sent_channel::Decoder(uint16_t clocks)
if (interval == SENT_SYNC_INTERVAL) if (interval == SENT_SYNC_INTERVAL)
{// sync interval - 56 ticks {// sync interval - 56 ticks
/* measured tick interval will be used until next sync pulse */ /* measured tick interval will be used until next sync pulse */
tickPerUnit = (clocks + 56 / 2) / (SENT_SYNC_INTERVAL + SENT_OFFSET_INTERVAL); tickPerUnit = (clocks + (SENT_SYNC_INTERVAL + SENT_OFFSET_INTERVAL) / 2) /
(SENT_SYNC_INTERVAL + SENT_OFFSET_INTERVAL);
state = SENT_STATE_STATUS; state = SENT_STATE_STATUS;
} }
else else
@ -268,7 +274,8 @@ int sent_channel::Decoder(uint16_t clocks)
/* CRC check */ /* CRC check */
/* TODO: find correct way to calculate CRC */ /* TODO: find correct way to calculate CRC */
if ((nibbles[7] == crc4(nibbles, 7)) || if ((nibbles[7] == crc4(nibbles, 7)) ||
(nibbles[7] == crc4_gm(nibbles + 1, 6))) (nibbles[7] == crc4_gm(nibbles + 1, 6)) ||
(nibbles[7] == crc4_gm_v2(nibbles + 1, 6)))
{ {
/* Full packet with correct CRC has been received /* Full packet with correct CRC has been received
* NOTE different MSB packing for sig0 and sig1 * NOTE different MSB packing for sig0 and sig1
@ -441,22 +448,43 @@ uint8_t sent_channel::crc4(uint8_t* pdata, uint16_t ndata)
/* This CRC works for GM pressure sensor for message minus status nibble and minus CRC nibble */ /* This CRC works for GM pressure sensor for message minus status nibble and minus CRC nibble */
/* TODO: double check and use same CRC routine? */ /* TODO: double check and use same CRC routine? */
/* This is correct for GM throttle body */
uint8_t sent_channel::crc4_gm(uint8_t* pdata, uint16_t ndata) uint8_t sent_channel::crc4_gm(uint8_t* pdata, uint16_t ndata)
{ {
size_t i;
uint8_t crc = SENT_CRC_SEED; // initialize checksum with seed "0101"
const uint8_t CrcLookup[16] = {0, 13, 7, 10, 14, 3, 9, 4, 1, 12, 6, 11, 15, 2, 8, 5}; const uint8_t CrcLookup[16] = {0, 13, 7, 10, 14, 3, 9, 4, 1, 12, 6, 11, 15, 2, 8, 5};
uint8_t calculatedCRC, i;
calculatedCRC = SENT_CRC_SEED; // initialize checksum with seed "0101"
for (i = 0; i < ndata; i++) for (i = 0; i < ndata; i++)
{ {
calculatedCRC = CrcLookup[calculatedCRC]; crc = CrcLookup[crc];
calculatedCRC = (calculatedCRC ^ pdata[i]) & 0x0F; crc = (crc ^ pdata[i]) & 0x0F;
//crc = pdata[i] ^ CrcLookup[crc];
} }
// One more round with 0 as input // One more round with 0 as input
calculatedCRC = CrcLookup[calculatedCRC]; //crc = CrcLookup[crc];
return calculatedCRC; return crc;
}
/* This is correct for GDI fuel pressure sensor */
uint8_t sent_channel::crc4_gm_v2(uint8_t* pdata, uint16_t ndata)
{
size_t i;
uint8_t crc = SENT_CRC_SEED; // initialize checksum with seed "0101"
const uint8_t CrcLookup[16] = {0, 13, 7, 10, 14, 3, 9, 4, 1, 12, 6, 11, 15, 2, 8, 5};
for (i = 0; i < ndata; i++)
{
crc = CrcLookup[crc];
crc = (crc ^ pdata[i]) & 0x0F;
//crc = pdata[i] ^ CrcLookup[crc];
}
// One more round with 0 as input
crc = CrcLookup[crc];
return crc;
} }
void sent_channel::Info(void) void sent_channel::Info(void)
@ -467,17 +495,19 @@ void sent_channel::Info(void)
efiPrintf("Total pulses %d", pulseCounter); efiPrintf("Total pulses %d", pulseCounter);
efiPrintf("Last fast msg Status 0x%01x Sig0 0x%03x Sig1 0x%03x", stat, sig0, sig1); efiPrintf("Last fast msg Status 0x%01x Sig0 0x%03x Sig1 0x%03x", stat, sig0, sig1);
efiPrintf("Slow channels:"); if (scMsgFlags) {
for (i = 0; i < SENT_SLOW_CHANNELS_MAX; i++) { efiPrintf("Slow channels:");
if (scMsgFlags & BIT(i)) { for (i = 0; i < SENT_SLOW_CHANNELS_MAX; i++) {
efiPrintf(" ID %d: %d", scMsg[i].id, scMsg[i].data); if (scMsgFlags & BIT(i)) {
efiPrintf(" ID %d: %d", scMsg[i].id, scMsg[i].data);
}
} }
} }
#if SENT_STATISTIC_COUNTERS #if SENT_STATISTIC_COUNTERS
efiPrintf("Restarts %d", statistic.RestartCnt); efiPrintf("Restarts %d", statistic.RestartCnt);
efiPrintf("Interval errors %d short, %d long", statistic.ShortIntervalErr, statistic.LongIntervalErr); efiPrintf("Interval errors %d short, %d long", statistic.ShortIntervalErr, statistic.LongIntervalErr);
efiPrintf("Total frames %d with crc erorr %d", statistic.FrameCnt, statistic.CrcErrCnt); efiPrintf("Total frames %d with crc error %d (%f %%)", statistic.FrameCnt, statistic.CrcErrCnt, statistic.CrcErrCnt * 100.0 / statistic.FrameCnt);
efiPrintf("Sync errors %d", statistic.SyncErr); efiPrintf("Sync errors %d", statistic.SyncErr);
#endif #endif
} }