LCOV - code coverage report
Current view: top level - firmware/hw_layer - kline.cpp (source / functions) Hit Total Coverage
Test: coverage.info Lines: 15 15 100.0 %
Date: 2024-04-25 02:23:43 Functions: 4 4 100.0 %

          Line data    Source code
       1             : #include "pch.h"
       2             : #include "kline.h"
       3             : #include "hellen_meta.h"
       4             : #include "crc8hondak.h"
       5             : 
       6           1 : size_t readWhileGives(ByteSource source, uint8_t *buffer, size_t bufferSize) {
       7           1 :         size_t totalBytes = 0;
       8          12 :         while (totalBytes < bufferSize) {
       9          12 :            size_t readThisTime = source(&buffer[totalBytes], bufferSize - totalBytes);
      10          12 :            if (readThisTime == 0) {
      11             :                 // looks like idle gap
      12           1 :                 break;
      13             :            }
      14          11 :            totalBytes += readThisTime;
      15             :         }
      16           1 :     return totalBytes;
      17             : }
      18             : 
      19             : #ifdef EFI_KLINE
      20             : 
      21             : static uint8_t kvalues[8];
      22             : 
      23             : #define HONDA_K_BCM_STATUS_NIBBLE 0x0
      24             : #define HONDA_K_BCM_REQ_NIBBLE 0x1
      25             : 
      26             : bool kAcRequestState;
      27             : 
      28             : static void handleHonda(uint8_t *bufferIn) {
      29             : 
      30             :     // no headlights 0x40, with headlights 0x60
      31             :         uint8_t statusByte1 = bufferIn[1];
      32             :         // no cabin blower 0x06, with blower 0x86
      33             :         uint8_t statusByte2 = bufferIn[2];
      34             :     kAcRequestState = statusByte2 & 0x80;
      35             :     if (engineConfiguration->verboseKLine) {
      36             :         efiPrintf("honda status packet with 0x%02x 0x%02x state %d", statusByte1, statusByte2, kAcRequestState);
      37             :     }
      38             : }
      39             : 
      40             : static SerialDriver* const klDriver = &KLINE_SERIAL_DEVICE;
      41             : static THD_WORKING_AREA(klThreadStack, UTILITY_THREAD_STACK_SIZE);
      42             : 
      43             : static int totalBytes = 0;
      44             : 
      45             : void kLineThread(void*) {
      46             :     // due to single wire we read everything we've transmitted
      47             :     bool ignoreRecentTransmit = false;
      48             :     int sendCounter = 0;
      49             :     while (1) {
      50             : 
      51             :         /**
      52             :          * under the hood there is SERIAL_BUFFERS_SIZE which we hope to help us
      53             :          */
      54             : 
      55             :         uint8_t bufferIn[16];
      56             :         // a bit of a busy read open question if this would affect performance?
      57             :         // on 2003 Honda for instance the bus seems to be 70%-ish busy. 9600 baud is 1.04ms per byte, a bit below 1kHz
      58             :         ByteSource serialSource = [] (uint8_t * buffer, int maxSize) {
      59             :             return chnReadTimeout(klDriver,buffer, maxSize, TIME_US2I(engineConfiguration->kLinePeriodUs));
      60             :         };
      61             :         size_t len = readWhileGives(serialSource, bufferIn, sizeof(bufferIn));
      62             : 
      63             :                     if (engineConfiguration->verboseKLine) {
      64             : //                        efiPrintf("ignoreRecentTransmit %d", ignoreRecentTransmit);
      65             :                     }
      66             : 
      67             :         // to begin with just write byte to console
      68             :         if (len > 0) {
      69             :             if (engineConfiguration->verboseKLine) {
      70             :                 efiPrintf("kline: got count 0x%02x", len);
      71             :             }
      72             :             for (size_t i =0;i<len;i++) {
      73             :                 if (engineConfiguration->verboseKLine) {
      74             :                     efiPrintf("kline: got 0x%02x", bufferIn[i]);
      75             :                 }
      76             :                 totalBytes++;
      77             :             }
      78             :             if (len > 1) {
      79             :                 int crc = crc_hondak_calc(bufferIn, len - 1);
      80             :                 uint8_t low = bufferIn[0] & 0xF;
      81             :                 if (crc == bufferIn[len - 1]) {
      82             :                     if (engineConfiguration->verboseKLine) {
      83             :                         efiPrintf("happy CRC 0x%02x", crc);
      84             :                     }
      85             :                     if (low == HONDA_K_BCM_STATUS_NIBBLE) {
      86             :                         handleHonda(bufferIn);
      87             :                     }
      88             : 
      89             :                     if (low == HONDA_K_BCM_REQ_NIBBLE) {
      90             :                         if (engineConfiguration->verboseKLine) {
      91             :                             efiPrintf("BCM request 0x%02x", bufferIn[0]);
      92             :                         }
      93             :                     }
      94             : 
      95             :                 } else if (low == HONDA_K_BCM_STATUS_NIBBLE && bufferIn[4] == crc_hondak_calc(bufferIn, 4)) {
      96             :                     if (engineConfiguration->verboseKLine) {
      97             :                         efiPrintf("hack for now, happy CRC 0x%02x", crc);
      98             :                     }
      99             :                     handleHonda(bufferIn);
     100             :                 }
     101             : 
     102             : 
     103             :                 if (engineConfiguration->kLineDoHondaSend && !ignoreRecentTransmit) {
     104             :                     sendCounter++;
     105             : #define OUT_SIZE 6
     106             : //                      const uint8_t out2[] = {0x2, 0x0, 0x0, 0x50, 0x0, 0x0};
     107             :                     //static_assert(sizeof(out2) == OUT_SIZE);
     108             : //                      const uint8_t outB[] = {0x42, 0x0, 0x0, 0x50, 0x0, 0x0};
     109             : //                      static_assert(sizeof(outB) == OUT_SIZE);
     110             :                         //const uint8_t *out = (sendCounter % 3 == 0) ? outB : out2;
     111             : //                      const uint8_t *out = out2;
     112             : 
     113             :                     if (sendCounter % 30 == 0) {
     114             :                         // no idea what this, maybe "i am running"?
     115             :                         kvalues[0] = 0x82;
     116             :                         kvalues[2] = 0x10;
     117             :                     } else {
     118             :                         kvalues[0] = 0x2;
     119             :                         kvalues[2] = 0;
     120             :                     }
     121             : 
     122             :                     if (engineConfiguration->verboseKLine) {
     123             :                         efiPrintf("kline doSend");
     124             :                     }
     125             :                     int positiveCltWithHighishValueInCaseOfSensorIssue = maxI(1,
     126             :                         /* temporary while we are playing with calibration */
     127             :                         engineConfiguration->auxiliarySetting1 + Sensor::get(SensorType::Clt).value_or(140)
     128             :                     );
     129             :     // 125 about horizontal
     130             :     // 162 points at red mark, looks like gauge has hysteresis?
     131             :     // value 200 way above red mark
     132             :                     kvalues[3] = positiveCltWithHighishValueInCaseOfSensorIssue;
     133             : 
     134             :                     chnWrite(klDriver, (const uint8_t *)kvalues, OUT_SIZE);
     135             :                     crc = crc_hondak_calc(kvalues, OUT_SIZE);
     136             :                     chnWrite(klDriver, (const uint8_t *)&crc, 1);
     137             :                     ignoreRecentTransmit = true;
     138             :                 } else {
     139             :                     ignoreRecentTransmit = false;
     140             :                 }
     141             :             }
     142             :         }
     143             :     }
     144             : }
     145             : #endif // EFI_KLINE
     146             : 
     147         147 : void startKLine() {
     148             : #ifdef EFI_KLINE
     149             :     if (!engineConfiguration->enableKline) {
     150             :         return;
     151             :     }
     152             : #if EFI_PROD_CODE
     153             :         efiSetPadMode("K-Line UART RX", KLINE_SERIAL_DEVICE_RX, PAL_MODE_ALTERNATE(TS_SERIAL_AF));
     154             :         efiSetPadMode("K-Line UART TX", KLINE_SERIAL_DEVICE_TX, PAL_MODE_ALTERNATE(TS_SERIAL_AF));
     155             : #endif /* EFI_PROD_CODE */
     156             : 
     157             :         static SerialConfig cfg = {
     158             :                 #if EFI_PROD_CODE
     159             :                         .speed = 0,
     160             :                         .cr1 = 0,
     161             :                         .cr2 = USART_CR2_STOP1_BITS | USART_CR2_LINEN,
     162             :                         .cr3 = 0
     163             :                 #endif // EFI_PROD_CODE
     164             :         };
     165             : 
     166             :     if (engineConfiguration->kLineBaudRate < 100)
     167             :         engineConfiguration->kLineBaudRate = KLINE_BAUD_RATE;
     168             :     cfg.speed = engineConfiguration->kLineBaudRate;
     169             : 
     170             :         sdStart(klDriver, &cfg);
     171             : #endif // EFI_KLINE
     172         147 : }
     173             : 
     174         147 : void stopKLine() {
     175             : #ifdef EFI_KLINE
     176             : #if EFI_PROD_CODE
     177             :     if (activeConfiguration.enableKline) {
     178             :             efiSetPadUnused(KLINE_SERIAL_DEVICE_RX);
     179             :             efiSetPadUnused(KLINE_SERIAL_DEVICE_TX);
     180             : 
     181             :             sdStop(klDriver);
     182             :         }
     183             : 
     184             : #endif /* EFI_PROD_CODE */
     185             : #endif // EFI_KLINE
     186         147 : }
     187             : 
     188         306 : void initKLine() {
     189         306 :     if (!engineConfiguration->enableKline) {
     190         306 :         return;
     191             :     }
     192             : #ifdef EFI_KLINE
     193             :         startKLine();
     194             : 
     195             :     if (engineConfiguration->kLinePeriodUs == 0) {
     196             :         engineConfiguration->kLinePeriodUs = 300 /* us*/;
     197             :     }
     198             :     engineConfiguration->kLineDoHondaSend = true;
     199             : 
     200             :     memset(kvalues, 0, sizeof(kvalues));
     201             :     kvalues[0] = 0x2;
     202             : 
     203             :     chThdCreateStatic(klThreadStack, sizeof(klThreadStack), NORMALPRIO + 1, kLineThread, nullptr);
     204             :     addConsoleAction("kline", [](){
     205             :         efiPrintf("kline totalBytes %d", totalBytes);
     206             :     });
     207             :     addConsoleAction("klineyes", [](){
     208             :         engineConfiguration->kLineDoHondaSend = true;
     209             :         efiPrintf("kline send %d", engineConfiguration->kLineDoHondaSend);
     210             :     });
     211             :     addConsoleAction("klineno", [](){
     212             :         engineConfiguration->kLineDoHondaSend = false;
     213             :         efiPrintf("kline send %d", engineConfiguration->kLineDoHondaSend);
     214             :     });
     215             :     addConsoleActionII("temp_k", [](int index, int value) {
     216             :         kvalues[index] = value;
     217             :     });
     218             : 
     219             : #endif // EFI_KLINE
     220             : }

Generated by: LCOV version 1.14