parent
6d3e71fae3
commit
a25c9ab520
|
@ -7,11 +7,12 @@
|
|||
* @author Andrey Gusakov <dron0gus@gmail.com>, (c) 2022
|
||||
*/
|
||||
|
||||
#if EFI_PROD_CODE
|
||||
#if EFI_PROD_CODE || EFI_UNIT_TEST
|
||||
|
||||
#include "pch.h"
|
||||
|
||||
#include "sent.h"
|
||||
#include "sent_logic.h"
|
||||
|
||||
/*==========================================================================*/
|
||||
/* Protocol definitions. */
|
||||
|
@ -36,12 +37,6 @@
|
|||
/* Decoder configuration */
|
||||
/*==========================================================================*/
|
||||
|
||||
#ifndef SENT_CHANNELS_NUM
|
||||
#define SENT_CHANNELS_NUM 4 // Number of sent channels
|
||||
#endif
|
||||
|
||||
/* collect statistic */
|
||||
#define SENT_STATISTIC_COUNTERS 1
|
||||
|
||||
/* Maximum slow shannel mailboxes, DO NOT CHANGE */
|
||||
#define SENT_SLOW_CHANNELS_MAX 16
|
||||
|
@ -63,92 +58,6 @@
|
|||
#define MsgGetSig1(msg) (((msg) >> (1 * 4)) & 0xfff)
|
||||
#define MsgGetCrc(msg) MsgGetNibble(msg, 7)
|
||||
|
||||
/* convert CPU ticks to float Us */
|
||||
#define TicksToUs(ticks) ((float)(ticks) * 1000.0 * 1000.0 / CORE_CLOCK)
|
||||
|
||||
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_enum;
|
||||
|
||||
struct sent_channel_stat {
|
||||
uint32_t ShortIntervalErr;
|
||||
uint32_t LongIntervalErr;
|
||||
uint32_t SyncErr;
|
||||
uint32_t CrcErrCnt;
|
||||
uint32_t FrameCnt;
|
||||
uint32_t RestartCnt;
|
||||
};
|
||||
|
||||
class sent_channel {
|
||||
private:
|
||||
SENT_STATE_enum state = SENT_STATE_CALIB;
|
||||
|
||||
/* Unit interval in timer clocks - adjusted on SYNC */
|
||||
uint32_t tickPerUnit;
|
||||
uint32_t pulseCounter;
|
||||
/* pulses skipped in init state while waiting for SYNC */
|
||||
uint32_t initStatePulseCounter;
|
||||
|
||||
/* fast channel shift register*/
|
||||
uint32_t rxReg;
|
||||
/* 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 */
|
||||
/* Slow channel decoder */
|
||||
int SlowChannelStore(uint8_t id, uint16_t data);
|
||||
int SlowChannelDecoder(void);
|
||||
|
||||
/* CRC */
|
||||
uint8_t crc4(uint32_t data);
|
||||
uint8_t crc4_gm(uint32_t data);
|
||||
uint8_t crc4_gm_v2(uint32_t data);
|
||||
|
||||
void restart(void);
|
||||
|
||||
public:
|
||||
/* slow channel data */
|
||||
struct {
|
||||
uint16_t data;
|
||||
uint8_t id;
|
||||
} scMsg[16];
|
||||
|
||||
/* 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 niblles 5 .. 3, where niblle 5 is MSB */
|
||||
int GetSignals(uint8_t *pStat, uint16_t *pSig0, uint16_t *pSig1);
|
||||
|
||||
/* Show status */
|
||||
void Info(void);
|
||||
};
|
||||
|
||||
static sent_channel channels[SENT_CHANNELS_NUM];
|
||||
|
||||
void sent_channel::restart(void)
|
||||
{
|
||||
state = SENT_STATE_CALIB;
|
||||
|
@ -517,6 +426,15 @@ uint8_t sent_channel::crc4_gm_v2(uint32_t data)
|
|||
return crc;
|
||||
}
|
||||
|
||||
#endif // EFI_PROD_CODE || EFI_UNIT_TEST
|
||||
|
||||
#if EFI_PROD_CODE
|
||||
|
||||
static sent_channel channels[SENT_CHANNELS_NUM];
|
||||
|
||||
/* convert CPU ticks to float Us */
|
||||
#define TicksToUs(ticks) ((float)(ticks) * 1000.0 * 1000.0 / CORE_CLOCK)
|
||||
|
||||
void sent_channel::Info(void)
|
||||
{
|
||||
int i;
|
||||
|
@ -543,7 +461,7 @@ void sent_channel::Info(void)
|
|||
#if SENT_STATISTIC_COUNTERS
|
||||
efiPrintf("Restarts %d", statistic.RestartCnt);
|
||||
efiPrintf("Interval errors %d short, %d long", statistic.ShortIntervalErr, statistic.LongIntervalErr);
|
||||
efiPrintf("Total frames %d with crc error %d (%f %%)", statistic.FrameCnt, statistic.CrcErrCnt, statistic.CrcErrCnt * 100.0 / statistic.FrameCnt);
|
||||
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);
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -0,0 +1,93 @@
|
|||
/**
|
||||
* sent_logic.h
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef SENT_CHANNELS_NUM
|
||||
#define SENT_CHANNELS_NUM 4 // Number of sent channels
|
||||
#endif
|
||||
|
||||
/* 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_enum;
|
||||
|
||||
struct sent_channel_stat {
|
||||
uint32_t ShortIntervalErr;
|
||||
uint32_t LongIntervalErr;
|
||||
uint32_t SyncErr;
|
||||
uint32_t CrcErrCnt;
|
||||
uint32_t FrameCnt;
|
||||
uint32_t RestartCnt;
|
||||
};
|
||||
|
||||
class sent_channel {
|
||||
private:
|
||||
SENT_STATE_enum state = SENT_STATE_CALIB;
|
||||
|
||||
/* Unit interval in timer clocks - adjusted on SYNC */
|
||||
uint32_t tickPerUnit;
|
||||
uint32_t pulseCounter;
|
||||
/* pulses skipped in init state while waiting for SYNC */
|
||||
uint32_t initStatePulseCounter;
|
||||
|
||||
/* fast channel shift register*/
|
||||
uint32_t rxReg;
|
||||
/* 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 */
|
||||
/* Slow channel decoder */
|
||||
int SlowChannelStore(uint8_t id, uint16_t data);
|
||||
int SlowChannelDecoder(void);
|
||||
|
||||
/* CRC */
|
||||
uint8_t crc4(uint32_t data);
|
||||
uint8_t crc4_gm(uint32_t data);
|
||||
uint8_t crc4_gm_v2(uint32_t data);
|
||||
|
||||
void restart(void);
|
||||
|
||||
public:
|
||||
/* slow channel data */
|
||||
struct {
|
||||
uint16_t data;
|
||||
uint8_t id;
|
||||
} scMsg[16];
|
||||
|
||||
/* 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 niblles 5 .. 3, where niblle 5 is MSB */
|
||||
int GetSignals(uint8_t *pStat, uint16_t *pSig0, uint16_t *pSig1);
|
||||
|
||||
/* Show status */
|
||||
void Info(void);
|
||||
};
|
|
@ -40,7 +40,11 @@ bool CsvReader::haveMore() {
|
|||
return result;
|
||||
}
|
||||
|
||||
double CsvReader::readTimestampAndValues(double *v) {
|
||||
/**
|
||||
* @param values reference of values array to modify
|
||||
* @return timestamp of current line
|
||||
*/
|
||||
double CsvReader::readTimestampAndValues(double *values) {
|
||||
const char s[2] = ",";
|
||||
char *line = buffer;
|
||||
|
||||
|
@ -49,12 +53,13 @@ double CsvReader::readTimestampAndValues(double *v) {
|
|||
|
||||
for (size_t i = 0; i < m_triggerCount; i++) {
|
||||
char *triggerToken = trim(strtok(nullptr, s));
|
||||
v[i] = std::stod(triggerToken);
|
||||
values[i] = std::stod(triggerToken);
|
||||
}
|
||||
|
||||
return timeStamp;
|
||||
}
|
||||
|
||||
// todo: separate trigger handling from csv file processing
|
||||
void CsvReader::processLine(EngineTestHelper *eth) {
|
||||
Engine *engine = ð->engine;
|
||||
|
||||
|
|
|
@ -0,0 +1,36 @@
|
|||
#include "pch.h"
|
||||
#include "logicdata_csv_reader.h"
|
||||
#include "sent_logic.h"
|
||||
|
||||
TEST(sent, testFordIdle) {
|
||||
CsvReader reader(1, 0);
|
||||
|
||||
reader.open("tests/sent/resources/ford-sent-idle.csv");
|
||||
|
||||
sent_channel channel;
|
||||
|
||||
int lineCount = 0;
|
||||
|
||||
double prevTimeStamp;
|
||||
|
||||
while (reader.haveMore()) {
|
||||
double value = 0;
|
||||
double stamp = reader.readTimestampAndValues(&value);
|
||||
lineCount++;
|
||||
|
||||
if (lineCount == 1) {
|
||||
prevTimeStamp = stamp;
|
||||
continue;
|
||||
}
|
||||
double diff = stamp - prevTimeStamp;
|
||||
|
||||
// todo: proper mult
|
||||
channel.Decoder(diff * 10'000'000);
|
||||
|
||||
prevTimeStamp = stamp;
|
||||
|
||||
}
|
||||
printf("testFordIdle: Got %d lines\n", lineCount);
|
||||
|
||||
ASSERT_TRUE(lineCount > 100);
|
||||
}
|
|
@ -25,6 +25,7 @@ TESTS_SRC_CPP = \
|
|||
tests/trigger/test_nissan_vq_vvt.cpp \
|
||||
tests/trigger/test_override_gaps.cpp \
|
||||
tests/trigger/test_injection_scheduling.cpp \
|
||||
tests/sent/test_sent.cpp \
|
||||
tests/ignition_injection/injection_mode_transition.cpp \
|
||||
tests/ignition_injection/test_startOfCrankingPrimingPulse.cpp \
|
||||
tests/ignition_injection/test_multispark.cpp \
|
||||
|
|
Loading…
Reference in New Issue