rusefi/firmware/hw_layer/drivers/sent/sent_logic.h

124 lines
2.8 KiB
C++

/**
* sent_logic.h
*/
#pragma once
#ifndef SENT_CHANNELS_NUM
#define SENT_CHANNELS_NUM 4 // Number of sent channels
#endif
/* Maximum slow shannel mailboxes, DO NOT CHANGE */
#define SENT_SLOW_CHANNELS_MAX 16
/* collect statistic */
#define SENT_STATISTIC_COUNTERS 1
typedef enum
{
SENT_STATE_CALIB = 0,
SENT_STATE_INIT,
SENT_STATE_SYNC,
SENT_STATE_STATUS,
SENT_STATE_SIG1_DATA1,
SENT_STATE_SIG1_DATA2,
SENT_STATE_SIG1_DATA3,
SENT_STATE_SIG2_DATA1,
SENT_STATE_SIG2_DATA2,
SENT_STATE_SIG2_DATA3,
SENT_STATE_CRC,
SENT_STATE_PAUSE,
} SENT_STATE_enum;
struct sent_channel_stat {
uint32_t ShortIntervalErr;
uint32_t LongIntervalErr;
uint32_t SyncErr;
uint32_t CrcErrCnt;
uint32_t FrameCnt;
uint32_t RestartCnt;
/* Slow channel */
uint32_t sc;
uint32_t scCrcErr;
uint32_t getTotalError() {
return ShortIntervalErr + LongIntervalErr + SyncErr + CrcErrCnt;
}
float getErrorRate() {
return getTotalError() * 1.0 / FrameCnt;
}
};
class sent_channel {
private:
SENT_STATE_enum state = SENT_STATE_CALIB;
/* Unit interval in timer clocks - adjusted on SYNC */
uint32_t tickPerUnit = 0;
uint32_t pulseCounter = 0;
/* pulses skipped in init or calibration state while waiting for SYNC */
uint32_t currentStatePulseCounter = 0;
bool hasPausePulse = false;
/* fast channel shift register*/
uint32_t rxReg;
bool hasValidFast = false;
/* fast channel last received valid message */
uint32_t rxLast;
/* slow channel shift registers and flags */
uint16_t scMsgFlags;
uint32_t scShift2; /* shift register for bit 2 from status nibble */
uint32_t scShift3; /* shift register for bit 3 from status nibble */
uint32_t scCrcShift; /* shift register for special order for CRC6 calculation */
/* Slow channel decoder and helpers */
int StoreSlowChannelValue(uint8_t id, uint16_t data);
int SlowChannelDecoder();
/* CRC */
uint8_t crc4(uint32_t data);
uint8_t crc4_gm(uint32_t data);
uint8_t crc4_gm_v2(uint32_t data);
/* Slow channel CRC6 */
uint8_t crc6(uint32_t data);
/* calc unit tick time from sync pulse */
uint32_t calcTickPerUnit(uint32_t clocks);
void restart();
public:
/* slow channel data */
struct {
uint16_t data;
uint8_t id;
} scMsg[SENT_SLOW_CHANNELS_MAX];
/* Statistic counters */
#if SENT_STATISTIC_COUNTERS
sent_channel_stat statistic;
#endif // SENT_STATISTIC_COUNTERS
/* Decoder */
int Decoder(uint16_t clocks);
/* Get last raw message */
int GetMsg(uint32_t* rx);
/* Unpack last valid message to status, signal0 and signal1
* Note:
* sig0 is nibbles 0 .. 2, where nibble 0 is MSB
* sig1 is nibbles 5 .. 3, where nibble 5 is MSB */
int GetSignals(uint8_t *pStat, uint16_t *pSig0, uint16_t *pSig1);
/* Get slow channel value for given ID 8*/
int GetSlowChannelValue(uint8_t id);
/* Current tick time in CPU/timer clocks */
float getTickTime();
/* Show status */
void Info();
};