SENT fixes (#4698)

* SENT: use shift register for storing nibbles

* SENT: rxReg shift to the left

* SENT: todo
This commit is contained in:
Andrey G 2022-10-24 15:50:11 +03:00 committed by GitHub
parent 0ad451c915
commit dff2693698
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 89 additions and 56 deletions

View File

@ -50,6 +50,19 @@
/* Decoder */ /* Decoder */
/*==========================================================================*/ /*==========================================================================*/
/* Helpers for Msg manipulations */
/* nibbles order: status, sig0_MSN, sig0_MidN, sig0_LSN, sig1_MSN, sig1_MidN, sig1_LSN, CRC */
/* we shift rxReg left for 4 bits on each neable received and put newest nibble
* in [3:0] bits of rxReg, so when full message is received:
* CRC is [3:0] - nibble 7
* status is [31:28] - nibble 0
* sig0 is [27:16], sig1 is [15:4] */
#define MsgGetNibble(msg, n) (((msg) >> (4 * (7 - (n)))) & 0xf)
#define MsgGetStat(msg) MsgGetNibble(msg, 0)
#define MsgGetSig0(msg) (((msg) >> (4 * 4)) & 0xfff)
#define MsgGetSig1(msg) (((msg) >> (1 * 4)) & 0xfff)
#define MsgGetCrc(msg) MsgGetNibble(msg, 7)
typedef enum typedef enum
{ {
SENT_STATE_CALIB = 0, SENT_STATE_CALIB = 0,
@ -84,9 +97,10 @@ private:
/* pulses skipped in init state while waiting for SYNC */ /* pulses skipped in init state while waiting for SYNC */
uint32_t initStatePulseCounter; uint32_t initStatePulseCounter;
/* fast channel nibbles. /* fast channel shift register*/
* TODO: rewrite with uint32_t shift register */ uint32_t rxReg;
uint8_t nibbles[SENT_MSG_PAYLOAD_SIZE]; /* fast channel last received valid message */
uint32_t rxLast;
/* slow channel shift registers and flags */ /* slow channel shift registers and flags */
uint16_t scMsgFlags; uint16_t scMsgFlags;
@ -97,18 +111,13 @@ private:
int SlowChannelDecoder(void); int SlowChannelDecoder(void);
/* CRC */ /* CRC */
uint8_t crc4(uint8_t* pdata, uint16_t ndata); uint8_t crc4(uint32_t data);
uint8_t crc4_gm(uint8_t* pdata, uint16_t ndata); uint8_t crc4_gm(uint32_t data);
uint8_t crc4_gm_v2(uint8_t* pdata, uint16_t ndata); uint8_t crc4_gm_v2(uint32_t data);
void restart(void); void restart(void);
public: public:
/* fast channel data */
int32_t sig0;
int32_t sig1;
int8_t stat;
/* slow channel data */ /* slow channel data */
struct { struct {
uint16_t data; uint16_t data;
@ -123,11 +132,13 @@ public:
/* Decoder */ /* Decoder */
int Decoder(uint16_t clocks); int Decoder(uint16_t clocks);
/* get latest valid signal0 and signal1 /* Get last raw message */
int GetMsg(uint32_t* rx);
/* Unpack last valid message to status, signal0 and signal1
* Note: * Note:
* sig0 is nibbles 0 .. 2, where nibble 0 is MSB * sig0 is nibbles 0 .. 2, where nibble 0 is MSB
* sig1 is niblles 5 .. 3, where niblle 5 is MSB */ * sig1 is niblles 5 .. 3, where niblle 5 is MSB */
int GetSignals(uint16_t *pSig0, uint16_t *pSig1); int GetSignals(uint8_t *pStat, uint16_t *pSig0, uint16_t *pSig1);
/* Show status */ /* Show status */
void Info(void); void Info(void);
@ -228,6 +239,7 @@ int sent_channel::Decoder(uint16_t clocks)
/* measured tick interval will be used until next sync pulse */ /* measured tick interval will be used until next sync pulse */
tickPerUnit = (clocks + (SENT_SYNC_INTERVAL + SENT_OFFSET_INTERVAL) / 2) / tickPerUnit = (clocks + (SENT_SYNC_INTERVAL + SENT_OFFSET_INTERVAL) / 2) /
(SENT_SYNC_INTERVAL + SENT_OFFSET_INTERVAL); (SENT_SYNC_INTERVAL + SENT_OFFSET_INTERVAL);
rxReg = 0;
state = SENT_STATE_STATUS; state = SENT_STATE_STATUS;
} }
else else
@ -259,7 +271,7 @@ int sent_channel::Decoder(uint16_t clocks)
case SENT_STATE_CRC: case SENT_STATE_CRC:
if(interval <= SENT_MAX_INTERVAL) if(interval <= SENT_MAX_INTERVAL)
{ {
nibbles[state - SENT_STATE_STATUS] = interval; rxReg = (rxReg << 4) | (uint32_t)interval;
if (state != SENT_STATE_CRC) if (state != SENT_STATE_CRC)
{ {
@ -273,24 +285,13 @@ int sent_channel::Decoder(uint16_t clocks)
#endif // SENT_STATISTIC_COUNTERS #endif // SENT_STATISTIC_COUNTERS
/* 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 ((MsgGetCrc(rxReg) == crc4(rxReg)) ||
(nibbles[7] == crc4_gm(nibbles + 1, 6)) || (MsgGetCrc(rxReg) == crc4_gm(rxReg)) ||
(nibbles[7] == crc4_gm_v2(nibbles + 1, 6))) (MsgGetCrc(rxReg) == crc4_gm_v2(rxReg)))
{ {
/* Full packet with correct CRC has been received /* Full packet with correct CRC has been received */
* NOTE different MSB packing for sig0 and sig1 rxLast = rxReg;
* is it protocol-defined or device-specific? /* TODO: add timestamp? */
* looks like some devices send 16 + 8 bit, not 12 + 12 */
sig0 =
(nibbles[1 + 0] << 8) |
(nibbles[1 + 1] << 4) |
(nibbles[1 + 2] << 0);
sig1 =
(nibbles[1 + 3] << 0) |
(nibbles[1 + 4] << 4) |
(nibbles[1 + 5] << 8);
stat =
nibbles[0];
ret = 1; ret = 1;
} }
else else
@ -328,14 +329,45 @@ int sent_channel::Decoder(uint16_t clocks)
return ret; return ret;
} }
int sent_channel::GetSignals(uint16_t *pSig0, uint16_t *pSig1) int sent_channel::GetMsg(uint32_t* rx)
{ {
if (rx) {
*rx = rxLast;
}
/* TODO: add check if any packet was received */
/* TODO: add check for time since last message reseived */
return 0;
}
int sent_channel::GetSignals(uint8_t *pStat, uint16_t *pSig0, uint16_t *pSig1)
{
uint32_t rx;
int ret = GetMsg(&rx);
if (ret < 0) {
return ret;
}
/* NOTE different MSB packing for sig0 and sig1
* is it protocol-defined or device-specific?
* Also looks like some devices send 16 + 8 bit, not 12 + 12 */
if (pStat) {
*pStat = MsgGetStat(rx);
}
if (pSig0) { if (pSig0) {
*pSig0 = sig0; uint16_t tmp = MsgGetSig0(rx);
*pSig0 = tmp;
} }
if (pSig1) { if (pSig1) {
*pSig1 = sig1; uint16_t tmp = MsgGetSig1(rx);
/* swap */
tmp = ((tmp >> 8) & 0x00f) |
((tmp << 8) & 0xf00) |
(tmp & 0x0f0);
*pSig1 = tmp;
} }
return 0; return 0;
@ -371,8 +403,8 @@ int sent_channel::SlowChannelStore(uint8_t id, uint16_t data)
int sent_channel::SlowChannelDecoder() int sent_channel::SlowChannelDecoder()
{ {
/* bit 2 and bit 3 from status nibble are used to transfer short messages */ /* bit 2 and bit 3 from status nibble are used to transfer short messages */
bool b2 = !!(nibbles[0] & (1 << 2)); bool b2 = !!(MsgGetStat(rxLast) & BIT(2));
bool b3 = !!(nibbles[0] & (1 << 3)); bool b3 = !!(MsgGetStat(rxLast) & BIT(3));
/* shift in new data */ /* shift in new data */
scShift2 = (scShift2 << 1) | b2; scShift2 = (scShift2 << 1) | b2;
@ -430,56 +462,51 @@ int sent_channel::SlowChannelDecoder()
return 0; return 0;
} }
/* This CRC works for Si7215 for WHOLE message expect last nibble (CRC) */ /* This is correct for Si7215 */
uint8_t sent_channel::crc4(uint8_t* pdata, uint16_t ndata) /* This CRC is calculated for WHOLE message expect last nibble (CRC) */
uint8_t sent_channel::crc4(uint32_t data)
{ {
size_t i; size_t i;
uint8_t crc = SENT_CRC_SEED; // initialize checksum with seed "0101" 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};
for (i = 0; i < ndata; i++) for (i = 0; i < 7; i++) {
{ crc = crc ^ MsgGetNibble(data, i);
crc = crc ^ pdata[i];
crc = CrcLookup[crc]; crc = CrcLookup[crc];
} }
return crc; return crc;
} }
/* This CRC works for GM pressure sensor for message minus status nibble and minus CRC nibble */ /* TODO: double check two following and use same CRC routine? */
/* TODO: double check and use same CRC routine? */
/* This is correct for GM throttle body */ /* This is correct for GM throttle body */
uint8_t sent_channel::crc4_gm(uint8_t* pdata, uint16_t ndata) /* This CRC is calculated for message expect status nibble and minus CRC nibble */
uint8_t sent_channel::crc4_gm(uint32_t data)
{ {
size_t i; size_t i;
uint8_t crc = SENT_CRC_SEED; // initialize checksum with seed "0101" 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};
for (i = 0; i < ndata; i++) for (i = 1; i < 7; i++) {
{
crc = CrcLookup[crc]; crc = CrcLookup[crc];
crc = (crc ^ pdata[i]) & 0x0F; crc = (crc ^ MsgGetNibble(data, i)) & 0xf;
//crc = pdata[i] ^ CrcLookup[crc];
} }
// One more round with 0 as input
//crc = CrcLookup[crc];
return crc; return crc;
} }
/* This is correct for GDI fuel pressure sensor */ /* This is correct for GDI fuel pressure sensor */
uint8_t sent_channel::crc4_gm_v2(uint8_t* pdata, uint16_t ndata) /* This CRC is calculated for message expect status nibble and minus CRC nibble */
uint8_t sent_channel::crc4_gm_v2(uint32_t data)
{ {
size_t i; size_t i;
uint8_t crc = SENT_CRC_SEED; // initialize checksum with seed "0101" 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};
for (i = 0; i < ndata; i++) for (i = 1; i < 7; i++) {
{
crc = CrcLookup[crc]; crc = CrcLookup[crc];
crc = (crc ^ pdata[i]) & 0x0F; crc = (crc ^ MsgGetNibble(data, i)) & 0xf;
//crc = pdata[i] ^ CrcLookup[crc];
} }
// One more round with 0 as input // One more round with 0 as input
crc = CrcLookup[crc]; crc = CrcLookup[crc];
@ -491,9 +518,15 @@ void sent_channel::Info(void)
{ {
int i; int i;
uint8_t stat;
uint16_t sig0, sig1;
efiPrintf("Unit time %d timer ticks", tickPerUnit); efiPrintf("Unit time %d timer ticks", tickPerUnit);
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);
if (GetSignals(&stat, &sig0, &sig1) == 0) {
efiPrintf("Last valid fast msg Status 0x%01x Sig0 0x%03x Sig1 0x%03x", stat, sig0, sig1);
}
if (scMsgFlags) { if (scMsgFlags) {
efiPrintf("Slow channels:"); efiPrintf("Slow channels:");