rusEFI
The most advanced open source ECU
Loading...
Searching...
No Matches
sent.cpp
Go to the documentation of this file.
1/*
2 * sent.cpp
3 *
4 * SENT protocol decoder
5 *
6 * TODO support MAF sensors like 04E906051 see https://github.com/rusefi/rusefi-hardware/issues/146
7 *
8 * @date Oct 01, 2022
9 * @author Andrey Gusakov <dron0gus@gmail.com>, (c) 2022
10 */
11
12#include "pch.h"
13
14#if EFI_PROD_CODE
15#if EFI_SENT_SUPPORT
16
17#include "sent.h"
18#include "init.h"
19#include "sent_decoder.h"
20
21#ifndef SENT_CHANNELS_NUM
22#define SENT_CHANNELS_NUM 4 // Number of sent channels
23#endif
24
25static sent_channel channels[SENT_CHANNELS_NUM];
26
27void sent_channel::Info() {
28 uint8_t stat;
29 uint16_t sig0, sig1;
30
31 efiPrintf("Unit time %lu timer ticks", tickPerUnit);
32 efiPrintf("Pause pulse detected %s", pausePulseReceived ? "Yes" : "No");
33 efiPrintf("Total pulses %lu", pulseCounter);
34
35 if (GetSignals(&stat, &sig0, &sig1) == 0) {
36 efiPrintf("Last valid fast msg Status 0x%01x Sig0 0x%03x Sig1 0x%03x", stat, sig0, sig1);
37 }
38
39 efiPrintf("Slow channels:");
40 /* run for all possible slow channel IDs (8 bit) */
41 for (int i = 0; i < 256; i++) {
42 int value;
43 value = GetSlowChannelValue(i);
44 if (value < 0)
45 continue;
46 efiPrintf(" ID %d: %d\n", i, value);
47 }
48
49 #if SENT_STATISTIC_COUNTERS
50 efiPrintf("HW overflows %lu\n", statistic.hwOverflowCnt);
51
52 efiPrintf("Pause pulses %lu\n", statistic.PauseCnt);
53 efiPrintf("Restarts %lu", statistic.RestartCnt);
54 efiPrintf("Interval errors %lu short, %lu long", statistic.ShortIntervalErr, statistic.LongIntervalErr);
55 efiPrintf("Total frames %lu with CRC error %lu (%f%%)", statistic.FrameCnt, statistic.CrcErrCnt, statistic.CrcErrCnt * 100.0 / statistic.FrameCnt);
56 efiPrintf("Total slow channel messages %lu with crc6 errors %lu (%f%%)", statistic.sc12 + statistic.sc16, statistic.scCrcErr, (statistic.sc12 + statistic.sc16) ? statistic.scCrcErr * 100.0 / (statistic.sc12 + statistic.sc16) : 0);
57 efiPrintf("Sync errors %lu", statistic.SyncErr);
58 #endif
59}
60
61/*==========================================================================*/
62/* Decoder thread settings. */
63/*==========================================================================*/
64
65/* 4 per channel should be enough */
66#define SENT_MB_SIZE (4 * SENT_CHANNELS_NUM)
67
68static msg_t sent_mb_buffer[SENT_MB_SIZE];
69static MAILBOX_DECL(sent_mb, sent_mb_buffer, SENT_MB_SIZE);
70
71static THD_WORKING_AREA(waSentDecoderThread, 256);
72
73void SENT_ISR_Handler(uint8_t channel, uint16_t clocks, uint8_t flags) {
74 /* encode to fit msg_t */
75 msg_t msg = (flags << 24) | (channel << 16) | clocks;
76
77 /* called from ISR */
78 chSysLockFromISR();
79 chMBPostI(&sent_mb, msg);
80 chSysUnlockFromISR();
81}
82
83static void SentDecoderThread(void*) {
84 while (true) {
85 msg_t ret;
86 msg_t msg;
87
88 ret = chMBFetchTimeout(&sent_mb, &msg, TIME_INFINITE);
89
90 if (ret == MSG_OK) {
91 uint16_t tick = msg & 0xffff;
92 uint8_t n = (msg >> 16) & 0xff;
93 uint8_t flags = (msg >> 24) & 0xff;
94
95 if (n < SENT_CHANNELS_NUM) {
96 sent_channel &channel = channels[n];
97
98 if (channel.Decoder(tick, flags) > 0) {
99 /* report only for first channel */
100 if (n == 0) {
101 uint16_t sig0, sig1;
102 channel.GetSignals(NULL, &sig0, &sig1);
103 engine->sent_state.value0 = sig0;
104 engine->sent_state.value1 = sig1;
105
106 #if SENT_STATISTIC_COUNTERS
107 engine->sent_state.errorRate = 100.0 * channel.statistic.getErrorRate();
108 #endif // SENT_STATISTIC_COUNTERS
109 }
110
111 SentInput input = static_cast<SentInput>((size_t)SentInput::INPUT1 + n);
112 /* Call high level decoder from here */
113 /* TODO: implemnet subscribers, like it is done for ADC */
114 sentTpsDecode(input);
115 sentPressureDecode(input);
116 }
117 }
118 }
119 }
120}
121
122static void printSentInfo() {
123 for (int i = 0; i < SENT_CHANNELS_NUM; i++) {
124 sent_channel &channel = channels[i];
125
127 efiPrintf("---- SENT input %d ---- on %s", i + 1, pinName);
128 channel.Info();
129 efiPrintf("--------------------");
130 }
131}
132
133/* Don't be confused: this actually returns throttle body position */
134/* TODO: remove, replace with getSentValues() */
136 size_t index = static_cast<size_t>(input) - static_cast<size_t>(SentInput::INPUT1);
137
138 if (index < SENT_CHANNELS_NUM) {
139 uint16_t sig0, sig1;
140 sent_channel &channel = channels[index];
141
142 if (channel.GetSignals(NULL, &sig0, &sig1) == 0) {
143
144 // GM sig0 + sig1 == 0xfff but Ford does not
145 /* scale to 0.0 .. 1.0 */
146 return sig0;
147 }
148 }
149
150 return NAN;
151}
152
153int getSentValues(SentInput input, uint16_t *sig0, uint16_t *sig1) {
154 size_t index = static_cast<size_t>(input) - static_cast<size_t>(SentInput::INPUT1);
155
156 if (index < SENT_CHANNELS_NUM) {
157 sent_channel &channel = channels[index];
158
159 return channel.GetSignals(NULL, sig0, sig1);
160 }
161
162 /* invalid channel */
163 return -1;
164}
165
166/* Should be called once */
167void initSent(void) {
168 /* init interval mailbox */
169 chMBObjectInit(&sent_mb, sent_mb_buffer, SENT_MB_SIZE);
170
171 chThdCreateStatic(waSentDecoderThread, sizeof(waSentDecoderThread), NORMALPRIO, SentDecoderThread, nullptr);
172
173 /* Start HW layer */
174 startSent();
175
176 addConsoleAction("sentinfo", &printSentInfo);
177}
178
179#endif /* EFI_SENT_SUPPORT */
180#endif /* EFI_PROD_CODE */
uint16_t channel
Definition adc_inputs.h:104
sent_state_s sent_state
Definition engine.h:348
void addConsoleAction(const char *token, Void callback)
Register console action without parameters.
static EngineAccessor engine
Definition engine.h:413
static constexpr engine_configuration_s * engineConfiguration
const char * getBoardSpecificPinName(brain_pin_e brainPin)
void sentPressureDecode(SentInput sentCh)
SentInput
static MAILBOX_DECL(sent_mb, sent_mb_buffer, SENT_MB_SIZE)
static void SentDecoderThread(void *)
Definition sent.cpp:83
static sent_channel channels[SENT_CHANNELS_NUM]
Definition sent.cpp:25
static THD_WORKING_AREA(waSentDecoderThread, 256)
void SENT_ISR_Handler(uint8_t channel, uint16_t clocks, uint8_t flags)
Definition sent.cpp:73
float getSentValue(SentInput input)
Definition sent.cpp:135
int getSentValues(SentInput input, uint16_t *sig0, uint16_t *sig1)
Definition sent.cpp:153
static msg_t sent_mb_buffer[SENT_MB_SIZE]
Definition sent.cpp:68
void initSent(void)
Definition sent.cpp:167
static void printSentInfo()
Definition sent.cpp:122
void startSent()
void sentTpsDecode(SentInput sentCh)
Definition tps.cpp:71