rusefi/firmware/hw_layer/kline.cpp

221 lines
7.4 KiB
C++
Raw Permalink Normal View History

#include "pch.h"
#include "kline.h"
#include "hellen_meta.h"
#include "crc8hondak.h"
size_t readWhileGives(ByteSource source, uint8_t *buffer, size_t bufferSize) {
size_t totalBytes = 0;
while (totalBytes < bufferSize) {
size_t readThisTime = source(&buffer[totalBytes], bufferSize - totalBytes);
if (readThisTime == 0) {
// looks like idle gap
break;
}
totalBytes += readThisTime;
}
return totalBytes;
}
#ifdef EFI_KLINE
static uint8_t kvalues[8];
2023-05-01 07:06:51 -07:00
2023-05-01 08:24:09 -07:00
#define HONDA_K_BCM_STATUS_NIBBLE 0x0
#define HONDA_K_BCM_REQ_NIBBLE 0x1
2023-03-12 09:01:51 -07:00
bool kAcRequestState;
static void handleHonda(uint8_t *bufferIn) {
2023-05-01 10:47:49 -07:00
// no headlights 0x40, with headlights 0x60
2023-05-01 08:24:09 -07:00
uint8_t statusByte1 = bufferIn[1];
2023-05-01 12:51:18 -07:00
// no cabin blower 0x06, with blower 0x86
2023-05-01 08:24:09 -07:00
uint8_t statusByte2 = bufferIn[2];
kAcRequestState = statusByte2 & 0x80;
2023-03-12 09:01:51 -07:00
if (engineConfiguration->verboseKLine) {
2023-05-01 08:24:09 -07:00
efiPrintf("honda status packet with 0x%02x 0x%02x state %d", statusByte1, statusByte2, kAcRequestState);
2023-03-12 09:01:51 -07:00
}
}
static SerialDriver* const klDriver = &KLINE_SERIAL_DEVICE;
static THD_WORKING_AREA(klThreadStack, UTILITY_THREAD_STACK_SIZE);
2023-02-18 20:13:24 -08:00
static int totalBytes = 0;
void kLineThread(void*) {
2023-04-03 13:54:26 -07:00
// due to single wire we read everything we've transmitted
bool ignoreRecentTransmit = false;
2023-04-04 19:41:22 -07:00
int sendCounter = 0;
while (1) {
2023-04-03 13:54:26 -07:00
/**
* under the hood there is SERIAL_BUFFERS_SIZE which we hope to help us
*/
uint8_t bufferIn[16];
// a bit of a busy read open question if this would affect performance?
// on 2003 Honda for instance the bus seems to be 70%-ish busy. 9600 baud is 1.04ms per byte, a bit below 1kHz
ByteSource serialSource = [] (uint8_t * buffer, int maxSize) {
return chnReadTimeout(klDriver,buffer, maxSize, TIME_US2I(engineConfiguration->kLinePeriodUs));
};
size_t len = readWhileGives(serialSource, bufferIn, sizeof(bufferIn));
2023-04-03 13:50:24 -07:00
if (engineConfiguration->verboseKLine) {
2023-05-01 10:47:49 -07:00
// efiPrintf("ignoreRecentTransmit %d", ignoreRecentTransmit);
2023-04-03 13:50:24 -07:00
}
// to begin with just write byte to console
if (len > 0) {
2023-03-12 09:01:51 -07:00
if (engineConfiguration->verboseKLine) {
efiPrintf("kline: got count 0x%02x", len);
}
for (size_t i =0;i<len;i++) {
2023-03-12 09:01:51 -07:00
if (engineConfiguration->verboseKLine) {
efiPrintf("kline: got 0x%02x", bufferIn[i]);
}
totalBytes++;
}
if (len > 1) {
int crc = crc_hondak_calc(bufferIn, len - 1);
2023-05-01 08:24:09 -07:00
uint8_t low = bufferIn[0] & 0xF;
if (crc == bufferIn[len - 1]) {
2023-03-12 09:01:51 -07:00
if (engineConfiguration->verboseKLine) {
efiPrintf("happy CRC 0x%02x", crc);
}
2023-05-01 08:24:09 -07:00
if (low == HONDA_K_BCM_STATUS_NIBBLE) {
2023-03-12 09:01:51 -07:00
handleHonda(bufferIn);
}
2023-05-01 08:24:09 -07:00
if (low == HONDA_K_BCM_REQ_NIBBLE) {
if (engineConfiguration->verboseKLine) {
efiPrintf("BCM request 0x%02x", bufferIn[0]);
}
}
} else if (low == HONDA_K_BCM_STATUS_NIBBLE && bufferIn[4] == crc_hondak_calc(bufferIn, 4)) {
2023-04-03 09:41:17 -07:00
if (engineConfiguration->verboseKLine) {
efiPrintf("hack for now, happy CRC 0x%02x", crc);
}
handleHonda(bufferIn);
}
2023-04-03 11:10:07 -07:00
2023-04-03 13:33:49 -07:00
if (engineConfiguration->kLineDoHondaSend && !ignoreRecentTransmit) {
2023-04-04 19:41:22 -07:00
sendCounter++;
2023-05-01 07:06:51 -07:00
#define OUT_SIZE 6
2023-05-01 08:24:09 -07:00
// const uint8_t out2[] = {0x2, 0x0, 0x0, 0x50, 0x0, 0x0};
//static_assert(sizeof(out2) == OUT_SIZE);
// const uint8_t outB[] = {0x42, 0x0, 0x0, 0x50, 0x0, 0x0};
// static_assert(sizeof(outB) == OUT_SIZE);
//const uint8_t *out = (sendCounter % 3 == 0) ? outB : out2;
// const uint8_t *out = out2;
2023-05-01 12:51:18 -07:00
if (sendCounter % 30 == 0) {
// no idea what this, maybe "i am running"?
kvalues[0] = 0x82;
kvalues[2] = 0x10;
} else {
kvalues[0] = 0x2;
kvalues[2] = 0;
}
2023-04-03 13:33:49 -07:00
if (engineConfiguration->verboseKLine) {
efiPrintf("kline doSend");
}
2023-05-01 11:28:01 -07:00
int positiveCltWithHighishValueInCaseOfSensorIssue = maxI(1,
/* temporary while we are playing with calibration */
engineConfiguration->auxiliarySetting1 + Sensor::get(SensorType::Clt).value_or(140)
);
2023-05-01 10:38:17 -07:00
// 125 about horizontal
// 162 points at red mark, looks like gauge has hysteresis?
// value 200 way above red mark
kvalues[3] = positiveCltWithHighishValueInCaseOfSensorIssue;
2023-05-01 08:24:09 -07:00
chnWrite(klDriver, (const uint8_t *)kvalues, OUT_SIZE);
crc = crc_hondak_calc(kvalues, OUT_SIZE);
2023-05-01 07:06:51 -07:00
chnWrite(klDriver, (const uint8_t *)&crc, 1);
2023-04-03 13:30:00 -07:00
ignoreRecentTransmit = true;
} else {
ignoreRecentTransmit = false;
2023-04-03 11:10:07 -07:00
}
}
}
}
}
#endif // EFI_KLINE
void startKLine() {
#ifdef EFI_KLINE
2023-03-09 14:05:46 -08:00
if (!engineConfiguration->enableKline) {
return;
}
#if EFI_PROD_CODE
efiSetPadMode("K-Line UART RX", KLINE_SERIAL_DEVICE_RX, PAL_MODE_ALTERNATE(TS_SERIAL_AF));
efiSetPadMode("K-Line UART TX", KLINE_SERIAL_DEVICE_TX, PAL_MODE_ALTERNATE(TS_SERIAL_AF));
#endif /* EFI_PROD_CODE */
2023-03-03 19:03:00 -08:00
static SerialConfig cfg = {
#if EFI_PROD_CODE
2023-03-03 18:27:48 -08:00
.speed = 0,
.cr1 = 0,
.cr2 = USART_CR2_STOP1_BITS | USART_CR2_LINEN,
.cr3 = 0
#endif // EFI_PROD_CODE
};
2023-03-03 18:27:48 -08:00
if (engineConfiguration->kLineBaudRate < 100)
engineConfiguration->kLineBaudRate = KLINE_BAUD_RATE;
cfg.speed = engineConfiguration->kLineBaudRate;
sdStart(klDriver, &cfg);
#endif // EFI_KLINE
}
void stopKLine() {
#ifdef EFI_KLINE
#if EFI_PROD_CODE
2023-03-09 14:05:46 -08:00
if (activeConfiguration.enableKline) {
efiSetPadUnused(KLINE_SERIAL_DEVICE_RX);
efiSetPadUnused(KLINE_SERIAL_DEVICE_TX);
2023-03-09 14:05:46 -08:00
sdStop(klDriver);
}
#endif /* EFI_PROD_CODE */
#endif // EFI_KLINE
}
void initKLine() {
2023-03-09 14:05:46 -08:00
if (!engineConfiguration->enableKline) {
return;
}
#ifdef EFI_KLINE
startKLine();
if (engineConfiguration->kLinePeriodUs == 0) {
2023-04-03 08:51:11 -07:00
engineConfiguration->kLinePeriodUs = 300 /* us*/;
}
2023-05-01 12:51:18 -07:00
engineConfiguration->kLineDoHondaSend = true;
2023-05-01 07:06:51 -07:00
memset(kvalues, 0, sizeof(kvalues));
kvalues[0] = 0x2;
chThdCreateStatic(klThreadStack, sizeof(klThreadStack), NORMALPRIO + 1, kLineThread, nullptr);
addConsoleAction("kline", [](){
efiPrintf("kline totalBytes %d", totalBytes);
});
2023-04-03 11:10:07 -07:00
addConsoleAction("klineyes", [](){
2023-04-03 13:33:49 -07:00
engineConfiguration->kLineDoHondaSend = true;
efiPrintf("kline send %d", engineConfiguration->kLineDoHondaSend);
2023-04-03 11:10:07 -07:00
});
2023-04-03 11:51:26 -07:00
addConsoleAction("klineno", [](){
2023-04-03 13:33:49 -07:00
engineConfiguration->kLineDoHondaSend = false;
efiPrintf("kline send %d", engineConfiguration->kLineDoHondaSend);
2023-04-03 11:10:07 -07:00
});
addConsoleActionII("temp_k", [](int index, int value) {
kvalues[index] = value;
});
#endif // EFI_KLINE
}