@kb1rma/libcomm14cux-ts 0.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +674 -0
- package/README.md +154 -0
- package/dist/bytes.d.ts +9 -0
- package/dist/bytes.d.ts.map +1 -0
- package/dist/bytes.js +13 -0
- package/dist/bytes.js.map +1 -0
- package/dist/constants.d.ts +174 -0
- package/dist/constants.d.ts.map +1 -0
- package/dist/constants.js +122 -0
- package/dist/constants.js.map +1 -0
- package/dist/decoders/airflow.d.ts +19 -0
- package/dist/decoders/airflow.d.ts.map +1 -0
- package/dist/decoders/airflow.js +36 -0
- package/dist/decoders/airflow.js.map +1 -0
- package/dist/decoders/engineSpeed.d.ts +20 -0
- package/dist/decoders/engineSpeed.d.ts.map +1 -0
- package/dist/decoders/engineSpeed.js +33 -0
- package/dist/decoders/engineSpeed.js.map +1 -0
- package/dist/decoders/faultCodes.d.ts +19 -0
- package/dist/decoders/faultCodes.d.ts.map +1 -0
- package/dist/decoders/faultCodes.js +48 -0
- package/dist/decoders/faultCodes.js.map +1 -0
- package/dist/decoders/flags.d.ts +45 -0
- package/dist/decoders/flags.d.ts.map +1 -0
- package/dist/decoders/flags.js +54 -0
- package/dist/decoders/flags.js.map +1 -0
- package/dist/decoders/fuelMap.d.ts +89 -0
- package/dist/decoders/fuelMap.d.ts.map +1 -0
- package/dist/decoders/fuelMap.js +109 -0
- package/dist/decoders/fuelMap.js.map +1 -0
- package/dist/decoders/gear.d.ts +10 -0
- package/dist/decoders/gear.d.ts.map +1 -0
- package/dist/decoders/gear.js +23 -0
- package/dist/decoders/gear.js.map +1 -0
- package/dist/decoders/idleBypass.d.ts +8 -0
- package/dist/decoders/idleBypass.d.ts.map +1 -0
- package/dist/decoders/idleBypass.js +15 -0
- package/dist/decoders/idleBypass.js.map +1 -0
- package/dist/decoders/lambdaTrim.d.ts +15 -0
- package/dist/decoders/lambdaTrim.d.ts.map +1 -0
- package/dist/decoders/lambdaTrim.js +23 -0
- package/dist/decoders/lambdaTrim.js.map +1 -0
- package/dist/decoders/mainVoltage.d.ts +14 -0
- package/dist/decoders/mainVoltage.d.ts.map +1 -0
- package/dist/decoders/mainVoltage.js +26 -0
- package/dist/decoders/mainVoltage.js.map +1 -0
- package/dist/decoders/roadSpeed.d.ts +8 -0
- package/dist/decoders/roadSpeed.d.ts.map +1 -0
- package/dist/decoders/roadSpeed.js +14 -0
- package/dist/decoders/roadSpeed.js.map +1 -0
- package/dist/decoders/romRevision.d.ts +18 -0
- package/dist/decoders/romRevision.d.ts.map +1 -0
- package/dist/decoders/romRevision.js +26 -0
- package/dist/decoders/romRevision.js.map +1 -0
- package/dist/decoders/temperature.d.ts +12 -0
- package/dist/decoders/temperature.d.ts.map +1 -0
- package/dist/decoders/temperature.js +39 -0
- package/dist/decoders/temperature.js.map +1 -0
- package/dist/decoders/throttle.d.ts +18 -0
- package/dist/decoders/throttle.d.ts.map +1 -0
- package/dist/decoders/throttle.js +33 -0
- package/dist/decoders/throttle.js.map +1 -0
- package/dist/decoders/tuneRevision.d.ts +25 -0
- package/dist/decoders/tuneRevision.d.ts.map +1 -0
- package/dist/decoders/tuneRevision.js +22 -0
- package/dist/decoders/tuneRevision.js.map +1 -0
- package/dist/ecu.d.ts +473 -0
- package/dist/ecu.d.ts.map +1 -0
- package/dist/ecu.js +700 -0
- package/dist/ecu.js.map +1 -0
- package/dist/errors.d.ts +31 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +33 -0
- package/dist/errors.js.map +1 -0
- package/dist/index.d.ts +11 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +8 -0
- package/dist/index.js.map +1 -0
- package/dist/protocol/protocol.d.ts +57 -0
- package/dist/protocol/protocol.d.ts.map +1 -0
- package/dist/protocol/protocol.js +137 -0
- package/dist/protocol/protocol.js.map +1 -0
- package/dist/protocol/readCount.d.ts +21 -0
- package/dist/protocol/readCount.d.ts.map +1 -0
- package/dist/protocol/readCount.js +30 -0
- package/dist/protocol/readCount.js.map +1 -0
- package/dist/queue.d.ts +15 -0
- package/dist/queue.d.ts.map +1 -0
- package/dist/queue.js +21 -0
- package/dist/queue.js.map +1 -0
- package/dist/transport/simulated.d.ts +65 -0
- package/dist/transport/simulated.d.ts.map +1 -0
- package/dist/transport/simulated.js +190 -0
- package/dist/transport/simulated.js.map +1 -0
- package/dist/transport/types.d.ts +9 -0
- package/dist/transport/types.d.ts.map +1 -0
- package/dist/transport/types.js +4 -0
- package/dist/transport/types.js.map +1 -0
- package/dist/transport/webSerial.d.ts +49 -0
- package/dist/transport/webSerial.d.ts.map +1 -0
- package/dist/transport/webSerial.js +129 -0
- package/dist/transport/webSerial.js.map +1 -0
- package/dist/version.d.ts +18 -0
- package/dist/version.d.ts.map +1 -0
- package/dist/version.js +5 -0
- package/dist/version.js.map +1 -0
- package/package.json +58 -0
- package/src/bytes.ts +13 -0
- package/src/constants.ts +175 -0
- package/src/decoders/airflow.ts +41 -0
- package/src/decoders/engineSpeed.ts +36 -0
- package/src/decoders/faultCodes.ts +61 -0
- package/src/decoders/flags.ts +64 -0
- package/src/decoders/fuelMap.ts +167 -0
- package/src/decoders/gear.ts +26 -0
- package/src/decoders/idleBypass.ts +16 -0
- package/src/decoders/lambdaTrim.ts +24 -0
- package/src/decoders/mainVoltage.ts +37 -0
- package/src/decoders/roadSpeed.ts +14 -0
- package/src/decoders/romRevision.ts +30 -0
- package/src/decoders/temperature.ts +42 -0
- package/src/decoders/throttle.ts +37 -0
- package/src/decoders/tuneRevision.ts +42 -0
- package/src/ecu.ts +948 -0
- package/src/errors.ts +38 -0
- package/src/index.ts +16 -0
- package/src/protocol/protocol.ts +167 -0
- package/src/protocol/readCount.ts +45 -0
- package/src/queue.ts +24 -0
- package/src/test-support/ecu.ts +126 -0
- package/src/transport/simulated.ts +220 -0
- package/src/transport/types.ts +11 -0
- package/src/transport/webSerial.ts +163 -0
- package/src/version.ts +21 -0
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
declare const FAULT_BITS: readonly [readonly [0, 0, "romChecksumFailure"], readonly [0, 1, "lambdaSensorOdd"], readonly [0, 2, "lambdaSensorEven"], readonly [0, 4, "misfireOddBank"], readonly [0, 5, "misfireEvenBank"], readonly [0, 6, "airflowMeter"], readonly [0, 7, "tuneResistorOutOfRange"], readonly [1, 0, "injectorOddBank"], readonly [1, 2, "injectorEvenBank"], readonly [1, 3, "coolantTempSensor"], readonly [1, 4, "throttlePot"], readonly [1, 5, "throttlePotHiMafLo"], readonly [1, 6, "throttlePotLoMafHi"], readonly [1, 7, "purgeValveLeak"], readonly [2, 1, "mixtureTooLean"], readonly [2, 3, "intakeAirLeak"], readonly [3, 0, "lowFuelPressure"], readonly [3, 4, "idleValveStepperMotor"], readonly [3, 6, "roadSpeedSensor"], readonly [3, 7, "neutralSwitch"], readonly [4, 4, "lowFuelPressureOrAirLeak"], readonly [4, 5, "fuelTempSensor"], readonly [5, 6, "batteryDisconnected"], readonly [5, 7, "ramChecksumFailure"]];
|
|
2
|
+
/**
|
|
3
|
+
* Name of a fault flag in {@link FaultCodes}, taken from the field names of
|
|
4
|
+
* the C `c14cux_faultcodes` struct.
|
|
5
|
+
*/
|
|
6
|
+
export type FaultCodeName = (typeof FAULT_BITS)[number][2];
|
|
7
|
+
/** Fault code flags (`c14cux_faultcodes`); `true` means the fault is set. */
|
|
8
|
+
export type FaultCodes = Record<FaultCodeName, boolean>;
|
|
9
|
+
/** Number of bytes in the fault code block at 0x0049. */
|
|
10
|
+
export declare const FAULT_CODE_BLOCK_SIZE = 6;
|
|
11
|
+
/**
|
|
12
|
+
* Decodes the fault code block into named flags. Spare bits are ignored.
|
|
13
|
+
*
|
|
14
|
+
* @param bytes - The six bytes read from 0x0049.
|
|
15
|
+
* @returns A flag for each fault; `true` means the fault is set.
|
|
16
|
+
*/
|
|
17
|
+
export declare function decodeFaultCodes(bytes: Uint8Array): FaultCodes;
|
|
18
|
+
export {};
|
|
19
|
+
//# sourceMappingURL=faultCodes.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"faultCodes.d.ts","sourceRoot":"","sources":["../../src/decoders/faultCodes.ts"],"names":[],"mappings":"AAOA,QAAA,MAAM,UAAU,s4BAyBN,CAAC;AAEX;;;GAGG;AACH,MAAM,MAAM,aAAa,GAAG,CAAC,OAAO,UAAU,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;AAE3D,6EAA6E;AAC7E,MAAM,MAAM,UAAU,GAAG,MAAM,CAAC,aAAa,EAAE,OAAO,CAAC,CAAC;AAExD,yDAAyD;AACzD,eAAO,MAAM,qBAAqB,IAAI,CAAC;AAEvC;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,UAAU,GAAG,UAAU,CAQ9D"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
// SPDX-License-Identifier: GPL-3.0-only
|
|
2
|
+
// Derived from libcomm14cux (https://github.com/colinbourassa/libcomm14cux)
|
|
3
|
+
// Copyright (C) Colin Bourassa. Licensed under the GNU GPL v3.
|
|
4
|
+
// Ported to TypeScript and modified for comm14cux-ts, 2026.
|
|
5
|
+
// [byte offset from 0x0049, bit (0 = LSB), name]. Spare bits are omitted.
|
|
6
|
+
// Names follow the field names of `c14cux_faultcodes`.
|
|
7
|
+
const FAULT_BITS = [
|
|
8
|
+
[0, 0, 'romChecksumFailure'],
|
|
9
|
+
[0, 1, 'lambdaSensorOdd'],
|
|
10
|
+
[0, 2, 'lambdaSensorEven'],
|
|
11
|
+
[0, 4, 'misfireOddBank'],
|
|
12
|
+
[0, 5, 'misfireEvenBank'],
|
|
13
|
+
[0, 6, 'airflowMeter'],
|
|
14
|
+
[0, 7, 'tuneResistorOutOfRange'],
|
|
15
|
+
[1, 0, 'injectorOddBank'],
|
|
16
|
+
[1, 2, 'injectorEvenBank'],
|
|
17
|
+
[1, 3, 'coolantTempSensor'],
|
|
18
|
+
[1, 4, 'throttlePot'],
|
|
19
|
+
[1, 5, 'throttlePotHiMafLo'],
|
|
20
|
+
[1, 6, 'throttlePotLoMafHi'],
|
|
21
|
+
[1, 7, 'purgeValveLeak'],
|
|
22
|
+
[2, 1, 'mixtureTooLean'],
|
|
23
|
+
[2, 3, 'intakeAirLeak'],
|
|
24
|
+
[3, 0, 'lowFuelPressure'],
|
|
25
|
+
[3, 4, 'idleValveStepperMotor'],
|
|
26
|
+
[3, 6, 'roadSpeedSensor'],
|
|
27
|
+
[3, 7, 'neutralSwitch'],
|
|
28
|
+
[4, 4, 'lowFuelPressureOrAirLeak'],
|
|
29
|
+
[4, 5, 'fuelTempSensor'],
|
|
30
|
+
[5, 6, 'batteryDisconnected'],
|
|
31
|
+
[5, 7, 'ramChecksumFailure'],
|
|
32
|
+
];
|
|
33
|
+
/** Number of bytes in the fault code block at 0x0049. */
|
|
34
|
+
export const FAULT_CODE_BLOCK_SIZE = 6;
|
|
35
|
+
/**
|
|
36
|
+
* Decodes the fault code block into named flags. Spare bits are ignored.
|
|
37
|
+
*
|
|
38
|
+
* @param bytes - The six bytes read from 0x0049.
|
|
39
|
+
* @returns A flag for each fault; `true` means the fault is set.
|
|
40
|
+
*/
|
|
41
|
+
export function decodeFaultCodes(bytes) {
|
|
42
|
+
const codes = {};
|
|
43
|
+
for (const [byteIndex, bit, name] of FAULT_BITS) {
|
|
44
|
+
codes[name] = (((bytes[byteIndex] ?? 0) >> bit) & 1) === 1;
|
|
45
|
+
}
|
|
46
|
+
return codes;
|
|
47
|
+
}
|
|
48
|
+
//# sourceMappingURL=faultCodes.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"faultCodes.js","sourceRoot":"","sources":["../../src/decoders/faultCodes.ts"],"names":[],"mappings":"AAAA,wCAAwC;AACxC,4EAA4E;AAC5E,+DAA+D;AAC/D,4DAA4D;AAE5D,0EAA0E;AAC1E,uDAAuD;AACvD,MAAM,UAAU,GAAG;IACjB,CAAC,CAAC,EAAE,CAAC,EAAE,oBAAoB,CAAC;IAC5B,CAAC,CAAC,EAAE,CAAC,EAAE,iBAAiB,CAAC;IACzB,CAAC,CAAC,EAAE,CAAC,EAAE,kBAAkB,CAAC;IAC1B,CAAC,CAAC,EAAE,CAAC,EAAE,gBAAgB,CAAC;IACxB,CAAC,CAAC,EAAE,CAAC,EAAE,iBAAiB,CAAC;IACzB,CAAC,CAAC,EAAE,CAAC,EAAE,cAAc,CAAC;IACtB,CAAC,CAAC,EAAE,CAAC,EAAE,wBAAwB,CAAC;IAChC,CAAC,CAAC,EAAE,CAAC,EAAE,iBAAiB,CAAC;IACzB,CAAC,CAAC,EAAE,CAAC,EAAE,kBAAkB,CAAC;IAC1B,CAAC,CAAC,EAAE,CAAC,EAAE,mBAAmB,CAAC;IAC3B,CAAC,CAAC,EAAE,CAAC,EAAE,aAAa,CAAC;IACrB,CAAC,CAAC,EAAE,CAAC,EAAE,oBAAoB,CAAC;IAC5B,CAAC,CAAC,EAAE,CAAC,EAAE,oBAAoB,CAAC;IAC5B,CAAC,CAAC,EAAE,CAAC,EAAE,gBAAgB,CAAC;IACxB,CAAC,CAAC,EAAE,CAAC,EAAE,gBAAgB,CAAC;IACxB,CAAC,CAAC,EAAE,CAAC,EAAE,eAAe,CAAC;IACvB,CAAC,CAAC,EAAE,CAAC,EAAE,iBAAiB,CAAC;IACzB,CAAC,CAAC,EAAE,CAAC,EAAE,uBAAuB,CAAC;IAC/B,CAAC,CAAC,EAAE,CAAC,EAAE,iBAAiB,CAAC;IACzB,CAAC,CAAC,EAAE,CAAC,EAAE,eAAe,CAAC;IACvB,CAAC,CAAC,EAAE,CAAC,EAAE,0BAA0B,CAAC;IAClC,CAAC,CAAC,EAAE,CAAC,EAAE,gBAAgB,CAAC;IACxB,CAAC,CAAC,EAAE,CAAC,EAAE,qBAAqB,CAAC;IAC7B,CAAC,CAAC,EAAE,CAAC,EAAE,oBAAoB,CAAC;CACpB,CAAC;AAWX,yDAAyD;AACzD,MAAM,CAAC,MAAM,qBAAqB,GAAG,CAAC,CAAC;AAEvC;;;;;GAKG;AACH,MAAM,UAAU,gBAAgB,CAAC,KAAiB;IAChD,MAAM,KAAK,GAAG,EAAgB,CAAC;IAE/B,KAAK,MAAM,CAAC,SAAS,EAAE,GAAG,EAAE,IAAI,CAAC,IAAI,UAAU,EAAE,CAAC;QAChD,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,IAAI,GAAG,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC;IAC7D,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC","sourcesContent":["// SPDX-License-Identifier: GPL-3.0-only\n// Derived from libcomm14cux (https://github.com/colinbourassa/libcomm14cux)\n// Copyright (C) Colin Bourassa. Licensed under the GNU GPL v3.\n// Ported to TypeScript and modified for comm14cux-ts, 2026.\n\n// [byte offset from 0x0049, bit (0 = LSB), name]. Spare bits are omitted.\n// Names follow the field names of `c14cux_faultcodes`.\nconst FAULT_BITS = [\n [0, 0, 'romChecksumFailure'],\n [0, 1, 'lambdaSensorOdd'],\n [0, 2, 'lambdaSensorEven'],\n [0, 4, 'misfireOddBank'],\n [0, 5, 'misfireEvenBank'],\n [0, 6, 'airflowMeter'],\n [0, 7, 'tuneResistorOutOfRange'],\n [1, 0, 'injectorOddBank'],\n [1, 2, 'injectorEvenBank'],\n [1, 3, 'coolantTempSensor'],\n [1, 4, 'throttlePot'],\n [1, 5, 'throttlePotHiMafLo'],\n [1, 6, 'throttlePotLoMafHi'],\n [1, 7, 'purgeValveLeak'],\n [2, 1, 'mixtureTooLean'],\n [2, 3, 'intakeAirLeak'],\n [3, 0, 'lowFuelPressure'],\n [3, 4, 'idleValveStepperMotor'],\n [3, 6, 'roadSpeedSensor'],\n [3, 7, 'neutralSwitch'],\n [4, 4, 'lowFuelPressureOrAirLeak'],\n [4, 5, 'fuelTempSensor'],\n [5, 6, 'batteryDisconnected'],\n [5, 7, 'ramChecksumFailure'],\n] as const;\n\n/**\n * Name of a fault flag in {@link FaultCodes}, taken from the field names of\n * the C `c14cux_faultcodes` struct.\n */\nexport type FaultCodeName = (typeof FAULT_BITS)[number][2];\n\n/** Fault code flags (`c14cux_faultcodes`); `true` means the fault is set. */\nexport type FaultCodes = Record<FaultCodeName, boolean>;\n\n/** Number of bytes in the fault code block at 0x0049. */\nexport const FAULT_CODE_BLOCK_SIZE = 6;\n\n/**\n * Decodes the fault code block into named flags. Spare bits are ignored.\n *\n * @param bytes - The six bytes read from 0x0049.\n * @returns A flag for each fault; `true` means the fault is set.\n */\nexport function decodeFaultCodes(bytes: Uint8Array): FaultCodes {\n const codes = {} as FaultCodes;\n\n for (const [byteIndex, bit, name] of FAULT_BITS) {\n codes[name] = (((bytes[byteIndex] ?? 0) >> bit) & 1) === 1;\n }\n\n return codes;\n}\n"]}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { PurgeValveState } from '../constants.js';
|
|
2
|
+
/**
|
|
3
|
+
* Decodes the fuel pump relay line. The relay is closed when bit 6 of port 1 is clear.
|
|
4
|
+
*
|
|
5
|
+
* @param port1 - The port 1 byte read from 0x0002.
|
|
6
|
+
* @returns `true` when the relay is closed (pump running).
|
|
7
|
+
*/
|
|
8
|
+
export declare const decodeFuelPumpRelay: (port1: number) => boolean;
|
|
9
|
+
/**
|
|
10
|
+
* Decodes the malfunction indicator lamp. It is lit when bit 0 of port 1 is clear.
|
|
11
|
+
*
|
|
12
|
+
* @param port1 - The port 1 byte read from 0x0002.
|
|
13
|
+
* @returns `true` when the MIL is lit.
|
|
14
|
+
*/
|
|
15
|
+
export declare const decodeMilOn: (port1: number) => boolean;
|
|
16
|
+
/**
|
|
17
|
+
* Decodes idle mode, which is active when bit 0 of 0x2047 is set.
|
|
18
|
+
*
|
|
19
|
+
* @param byte - The byte read from 0x2047.
|
|
20
|
+
* @returns `true` when the ECU is driving an idle speed.
|
|
21
|
+
*/
|
|
22
|
+
export declare const decodeIdleMode: (byte: number) => boolean;
|
|
23
|
+
/**
|
|
24
|
+
* Decodes the heated screen state. It is on when bit 2 of 0x00DD is clear.
|
|
25
|
+
*
|
|
26
|
+
* @param bits - The flag byte read from its address.
|
|
27
|
+
* @returns `true` when the screen heater is on.
|
|
28
|
+
*/
|
|
29
|
+
export declare const decodeScreenHeater: (bits: number) => boolean;
|
|
30
|
+
/**
|
|
31
|
+
* Decodes the A/C compressor input. It is on when bit 3 of 0x008A is clear.
|
|
32
|
+
*
|
|
33
|
+
* @param bits - The flag byte read from its address.
|
|
34
|
+
* @returns `true` when the compressor is on.
|
|
35
|
+
*/
|
|
36
|
+
export declare const decodeAcCompressor: (bits: number) => boolean;
|
|
37
|
+
/**
|
|
38
|
+
* Decodes the purge valve state from the ECU's 16-bit purge timer, using the
|
|
39
|
+
* thresholds the ECU itself uses.
|
|
40
|
+
*
|
|
41
|
+
* @param timer - The value read from 0x0096.
|
|
42
|
+
* @returns Closed below 4000, toggling below 29000, otherwise open.
|
|
43
|
+
*/
|
|
44
|
+
export declare function decodePurgeValveState(timer: number): PurgeValveState;
|
|
45
|
+
//# sourceMappingURL=flags.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"flags.d.ts","sourceRoot":"","sources":["../../src/decoders/flags.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAElD;;;;;GAKG;AACH,eAAO,MAAM,mBAAmB,GAAI,OAAO,MAAM,KAAG,OAC9B,CAAC;AAEvB;;;;;GAKG;AACH,eAAO,MAAM,WAAW,GAAI,OAAO,MAAM,KAAG,OAA+B,CAAC;AAE5E;;;;;GAKG;AACH,eAAO,MAAM,cAAc,GAAI,MAAM,MAAM,KAAG,OAAiC,CAAC;AAEhF;;;;;GAKG;AACH,eAAO,MAAM,kBAAkB,GAAI,MAAM,MAAM,KAAG,OAC7B,CAAC;AAEtB;;;;;GAKG;AACH,eAAO,MAAM,kBAAkB,GAAI,MAAM,MAAM,KAAG,OAC7B,CAAC;AAEtB;;;;;;GAMG;AACH,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,MAAM,GAAG,eAAe,CAMpE"}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
// SPDX-License-Identifier: GPL-3.0-only
|
|
2
|
+
// Derived from libcomm14cux (https://github.com/colinbourassa/libcomm14cux)
|
|
3
|
+
// Copyright (C) Colin Bourassa. Licensed under the GNU GPL v3.
|
|
4
|
+
// Ported to TypeScript and modified for comm14cux-ts, 2026.
|
|
5
|
+
import { PurgeValveState } from '../constants.js';
|
|
6
|
+
/**
|
|
7
|
+
* Decodes the fuel pump relay line. The relay is closed when bit 6 of port 1 is clear.
|
|
8
|
+
*
|
|
9
|
+
* @param port1 - The port 1 byte read from 0x0002.
|
|
10
|
+
* @returns `true` when the relay is closed (pump running).
|
|
11
|
+
*/
|
|
12
|
+
export const decodeFuelPumpRelay = (port1) => (port1 & 0x40) === 0;
|
|
13
|
+
/**
|
|
14
|
+
* Decodes the malfunction indicator lamp. It is lit when bit 0 of port 1 is clear.
|
|
15
|
+
*
|
|
16
|
+
* @param port1 - The port 1 byte read from 0x0002.
|
|
17
|
+
* @returns `true` when the MIL is lit.
|
|
18
|
+
*/
|
|
19
|
+
export const decodeMilOn = (port1) => (port1 & 0x01) === 0;
|
|
20
|
+
/**
|
|
21
|
+
* Decodes idle mode, which is active when bit 0 of 0x2047 is set.
|
|
22
|
+
*
|
|
23
|
+
* @param byte - The byte read from 0x2047.
|
|
24
|
+
* @returns `true` when the ECU is driving an idle speed.
|
|
25
|
+
*/
|
|
26
|
+
export const decodeIdleMode = (byte) => (byte & 0x01) === 0x01;
|
|
27
|
+
/**
|
|
28
|
+
* Decodes the heated screen state. It is on when bit 2 of 0x00DD is clear.
|
|
29
|
+
*
|
|
30
|
+
* @param bits - The flag byte read from its address.
|
|
31
|
+
* @returns `true` when the screen heater is on.
|
|
32
|
+
*/
|
|
33
|
+
export const decodeScreenHeater = (bits) => (bits & 0x04) === 0;
|
|
34
|
+
/**
|
|
35
|
+
* Decodes the A/C compressor input. It is on when bit 3 of 0x008A is clear.
|
|
36
|
+
*
|
|
37
|
+
* @param bits - The flag byte read from its address.
|
|
38
|
+
* @returns `true` when the compressor is on.
|
|
39
|
+
*/
|
|
40
|
+
export const decodeAcCompressor = (bits) => (bits & 0x08) === 0;
|
|
41
|
+
/**
|
|
42
|
+
* Decodes the purge valve state from the ECU's 16-bit purge timer, using the
|
|
43
|
+
* thresholds the ECU itself uses.
|
|
44
|
+
*
|
|
45
|
+
* @param timer - The value read from 0x0096.
|
|
46
|
+
* @returns Closed below 4000, toggling below 29000, otherwise open.
|
|
47
|
+
*/
|
|
48
|
+
export function decodePurgeValveState(timer) {
|
|
49
|
+
if (timer < 4000) {
|
|
50
|
+
return PurgeValveState.Closed;
|
|
51
|
+
}
|
|
52
|
+
return timer < 29000 ? PurgeValveState.Toggling : PurgeValveState.Open;
|
|
53
|
+
}
|
|
54
|
+
//# sourceMappingURL=flags.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"flags.js","sourceRoot":"","sources":["../../src/decoders/flags.ts"],"names":[],"mappings":"AAAA,wCAAwC;AACxC,4EAA4E;AAC5E,+DAA+D;AAC/D,4DAA4D;AAE5D,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAElD;;;;;GAKG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,KAAa,EAAW,EAAE,CAC5D,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC;AAEvB;;;;;GAKG;AACH,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,KAAa,EAAW,EAAE,CAAC,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC;AAE5E;;;;;GAKG;AACH,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,IAAY,EAAW,EAAE,CAAC,CAAC,IAAI,GAAG,IAAI,CAAC,KAAK,IAAI,CAAC;AAEhF;;;;;GAKG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,IAAY,EAAW,EAAE,CAC1D,CAAC,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC;AAEtB;;;;;GAKG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,IAAY,EAAW,EAAE,CAC1D,CAAC,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC;AAEtB;;;;;;GAMG;AACH,MAAM,UAAU,qBAAqB,CAAC,KAAa;IACjD,IAAI,KAAK,GAAG,IAAI,EAAE,CAAC;QACjB,OAAO,eAAe,CAAC,MAAM,CAAC;IAChC,CAAC;IAED,OAAO,KAAK,GAAG,KAAK,CAAC,CAAC,CAAC,eAAe,CAAC,QAAQ,CAAC,CAAC,CAAC,eAAe,CAAC,IAAI,CAAC;AACzE,CAAC","sourcesContent":["// SPDX-License-Identifier: GPL-3.0-only\n// Derived from libcomm14cux (https://github.com/colinbourassa/libcomm14cux)\n// Copyright (C) Colin Bourassa. Licensed under the GNU GPL v3.\n// Ported to TypeScript and modified for comm14cux-ts, 2026.\n\nimport { PurgeValveState } from '../constants.js';\n\n/**\n * Decodes the fuel pump relay line. The relay is closed when bit 6 of port 1 is clear.\n *\n * @param port1 - The port 1 byte read from 0x0002.\n * @returns `true` when the relay is closed (pump running).\n */\nexport const decodeFuelPumpRelay = (port1: number): boolean =>\n (port1 & 0x40) === 0;\n\n/**\n * Decodes the malfunction indicator lamp. It is lit when bit 0 of port 1 is clear.\n *\n * @param port1 - The port 1 byte read from 0x0002.\n * @returns `true` when the MIL is lit.\n */\nexport const decodeMilOn = (port1: number): boolean => (port1 & 0x01) === 0;\n\n/**\n * Decodes idle mode, which is active when bit 0 of 0x2047 is set.\n *\n * @param byte - The byte read from 0x2047.\n * @returns `true` when the ECU is driving an idle speed.\n */\nexport const decodeIdleMode = (byte: number): boolean => (byte & 0x01) === 0x01;\n\n/**\n * Decodes the heated screen state. It is on when bit 2 of 0x00DD is clear.\n *\n * @param bits - The flag byte read from its address.\n * @returns `true` when the screen heater is on.\n */\nexport const decodeScreenHeater = (bits: number): boolean =>\n (bits & 0x04) === 0;\n\n/**\n * Decodes the A/C compressor input. It is on when bit 3 of 0x008A is clear.\n *\n * @param bits - The flag byte read from its address.\n * @returns `true` when the compressor is on.\n */\nexport const decodeAcCompressor = (bits: number): boolean =>\n (bits & 0x08) === 0;\n\n/**\n * Decodes the purge valve state from the ECU's 16-bit purge timer, using the\n * thresholds the ECU itself uses.\n *\n * @param timer - The value read from 0x0096.\n * @returns Closed below 4000, toggling below 29000, otherwise open.\n */\nexport function decodePurgeValveState(timer: number): PurgeValveState {\n if (timer < 4000) {\n return PurgeValveState.Closed;\n }\n\n return timer < 29000 ? PurgeValveState.Toggling : PurgeValveState.Open;\n}\n"]}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import { DataOffsetRev } from '../constants.js';
|
|
2
|
+
import { pulseWidthToRpm } from './engineSpeed.js';
|
|
3
|
+
/**
|
|
4
|
+
* Where a fuel map lives in ECU memory.
|
|
5
|
+
*/
|
|
6
|
+
export interface FuelMapLocation {
|
|
7
|
+
/** Address of the 128-byte map; the 2-byte adjustment factor follows it. */
|
|
8
|
+
offset: number;
|
|
9
|
+
/** Address of the row scaler byte. */
|
|
10
|
+
scalerOffset: number;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* A {@link DataOffsetRev} that has been determined (not `Unset`).
|
|
14
|
+
*/
|
|
15
|
+
export type KnownDataOffsetRev = Exclude<DataOffsetRev, 0>;
|
|
16
|
+
/**
|
|
17
|
+
* Rejects a fuel map id outside 0 to 5.
|
|
18
|
+
*
|
|
19
|
+
* @param id - The fuel map id to check.
|
|
20
|
+
* @throws {@link RangeError} if `id` is not an integer from 0 to 5.
|
|
21
|
+
*/
|
|
22
|
+
export declare function assertFuelMapId(id: number): void;
|
|
23
|
+
/**
|
|
24
|
+
* Finds where a fuel map lives for the given ROM data layout.
|
|
25
|
+
*
|
|
26
|
+
* @param id - Map id, 0 to 5 (checked by {@link assertFuelMapId}).
|
|
27
|
+
* @param revision - The ROM's data layout.
|
|
28
|
+
* @returns The map's address and its row scaler's address.
|
|
29
|
+
*/
|
|
30
|
+
export declare function fuelMapLocation(id: number, revision: KnownDataOffsetRev): FuelMapLocation;
|
|
31
|
+
/**
|
|
32
|
+
* Validates the current fuel map id.
|
|
33
|
+
*
|
|
34
|
+
* @param id - The byte read from 0x202C.
|
|
35
|
+
* @returns The map id, 0 to 5.
|
|
36
|
+
* @throws {@link InvalidReadingError} if `id` is above 5.
|
|
37
|
+
*/
|
|
38
|
+
export declare function decodeCurrentFuelMap(id: number): number;
|
|
39
|
+
/**
|
|
40
|
+
* A position within the fuel map and its interpolation weighting.
|
|
41
|
+
*/
|
|
42
|
+
export interface FuelMapIndex {
|
|
43
|
+
/**
|
|
44
|
+
* The row or column index.
|
|
45
|
+
*/
|
|
46
|
+
index: number;
|
|
47
|
+
/**
|
|
48
|
+
* The weighting (0 to 15) used to interpolate toward the next row or column.
|
|
49
|
+
*/
|
|
50
|
+
weighting: number;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Decodes the row index byte: the high nibble is the row, the low nibble the
|
|
54
|
+
* weighting.
|
|
55
|
+
*
|
|
56
|
+
* @param byte - The byte read from 0x005B.
|
|
57
|
+
* @returns The row index (0 to 7) and weighting.
|
|
58
|
+
* @throws {@link InvalidReadingError} if the row index is 8 or more.
|
|
59
|
+
*/
|
|
60
|
+
export declare const decodeFuelMapRowIndex: (byte: number) => FuelMapIndex;
|
|
61
|
+
/**
|
|
62
|
+
* Decodes the column index byte: the high nibble is the column, the low nibble
|
|
63
|
+
* the weighting.
|
|
64
|
+
*
|
|
65
|
+
* @param byte - The byte read from 0x005C.
|
|
66
|
+
* @returns The column index (0 to 15) and weighting.
|
|
67
|
+
* @throws {@link InvalidReadingError} if the column index is 16 or more.
|
|
68
|
+
*/
|
|
69
|
+
export declare const decodeFuelMapColumnIndex: (byte: number) => FuelMapIndex;
|
|
70
|
+
/**
|
|
71
|
+
* Gives the address of one entry in the RPM table.
|
|
72
|
+
*
|
|
73
|
+
* @param column - Fuel map column, 0 to 15.
|
|
74
|
+
* @returns The address of the column's two-byte pulse width.
|
|
75
|
+
*/
|
|
76
|
+
export declare const rpmTableEntryAddress: (column: number) => number;
|
|
77
|
+
/**
|
|
78
|
+
* Gives the slot in the result array for an RPM table column. The C library
|
|
79
|
+
* stores column 0 last.
|
|
80
|
+
*
|
|
81
|
+
* @param column - Fuel map column, 0 to 15.
|
|
82
|
+
* @returns The index in the result array.
|
|
83
|
+
*/
|
|
84
|
+
export declare const rpmTableSlot: (column: number) => number;
|
|
85
|
+
/**
|
|
86
|
+
* Converts one RPM table pulse width to RPM; see {@link pulseWidthToRpm}.
|
|
87
|
+
*/
|
|
88
|
+
export declare const decodeRpmTableEntry: typeof pulseWidthToRpm;
|
|
89
|
+
//# sourceMappingURL=fuelMap.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fuelMap.d.ts","sourceRoot":"","sources":["../../src/decoders/fuelMap.ts"],"names":[],"mappings":"AAKA,OAAO,EACL,aAAa,EAKd,MAAM,iBAAiB,CAAC;AAEzB,OAAO,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAEnD;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,4EAA4E;IAC5E,MAAM,EAAE,MAAM,CAAC;IACf,sCAAsC;IACtC,YAAY,EAAE,MAAM,CAAC;CACtB;AAkBD;;GAEG;AACH,MAAM,MAAM,kBAAkB,GAAG,OAAO,CAAC,aAAa,EAAE,CAAC,CAAC,CAAC;AAE3D;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,CAIhD;AAED;;;;;;GAMG;AACH,wBAAgB,eAAe,CAC7B,EAAE,EAAE,MAAM,EACV,QAAQ,EAAE,kBAAkB,GAC3B,eAAe,CAajB;AAED;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,CAMvD;AAED;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B;;OAEG;IACH,KAAK,EAAE,MAAM,CAAC;IACd;;OAEG;IACH,SAAS,EAAE,MAAM,CAAC;CACnB;AAYD;;;;;;;GAOG;AACH,eAAO,MAAM,qBAAqB,GAAI,MAAM,MAAM,KAAG,YACZ,CAAC;AAE1C;;;;;;;GAOG;AACH,eAAO,MAAM,wBAAwB,GAAI,MAAM,MAAM,KAAG,YACT,CAAC;AAEhD;;;;;GAKG;AACH,eAAO,MAAM,oBAAoB,GAAI,QAAQ,MAAM,KAAG,MAClB,CAAC;AAErC;;;;;;GAMG;AACH,eAAO,MAAM,YAAY,GAAI,QAAQ,MAAM,KAAG,MACf,CAAC;AAEhC;;GAEG;AACH,eAAO,MAAM,mBAAmB,wBAAkB,CAAC"}
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
// SPDX-License-Identifier: GPL-3.0-only
|
|
2
|
+
// Derived from libcomm14cux (https://github.com/colinbourassa/libcomm14cux)
|
|
3
|
+
// Copyright (C) Colin Bourassa. Licensed under the GNU GPL v3.
|
|
4
|
+
// Ported to TypeScript and modified for comm14cux-ts, 2026.
|
|
5
|
+
import { DataOffsetRev, FUEL_MAP_COLUMNS, FUEL_MAP_ROWS, FUEL_MAP_ROW_SCALER_OFFSET, MemoryOffset, } from '../constants.js';
|
|
6
|
+
import { InvalidReadingError } from '../errors.js';
|
|
7
|
+
import { pulseWidthToRpm } from './engineSpeed.js';
|
|
8
|
+
const OLD_MAPS = [
|
|
9
|
+
MemoryOffset.OldFuelMap1,
|
|
10
|
+
MemoryOffset.OldFuelMap2,
|
|
11
|
+
MemoryOffset.OldFuelMap3,
|
|
12
|
+
MemoryOffset.OldFuelMap4,
|
|
13
|
+
MemoryOffset.OldFuelMap5,
|
|
14
|
+
];
|
|
15
|
+
const NEW_MAPS = [
|
|
16
|
+
MemoryOffset.NewFuelMap1,
|
|
17
|
+
MemoryOffset.NewFuelMap2,
|
|
18
|
+
MemoryOffset.NewFuelMap3,
|
|
19
|
+
MemoryOffset.NewFuelMap4,
|
|
20
|
+
MemoryOffset.NewFuelMap5,
|
|
21
|
+
];
|
|
22
|
+
/**
|
|
23
|
+
* Rejects a fuel map id outside 0 to 5.
|
|
24
|
+
*
|
|
25
|
+
* @param id - The fuel map id to check.
|
|
26
|
+
* @throws {@link RangeError} if `id` is not an integer from 0 to 5.
|
|
27
|
+
*/
|
|
28
|
+
export function assertFuelMapId(id) {
|
|
29
|
+
if (!Number.isInteger(id) || id < 0 || id > 5) {
|
|
30
|
+
throw new RangeError(`Invalid fuel map id: ${id}`);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Finds where a fuel map lives for the given ROM data layout.
|
|
35
|
+
*
|
|
36
|
+
* @param id - Map id, 0 to 5 (checked by {@link assertFuelMapId}).
|
|
37
|
+
* @param revision - The ROM's data layout.
|
|
38
|
+
* @returns The map's address and its row scaler's address.
|
|
39
|
+
*/
|
|
40
|
+
export function fuelMapLocation(id, revision) {
|
|
41
|
+
// Map 0 is at the same place in both layouts.
|
|
42
|
+
if (id === 0) {
|
|
43
|
+
return {
|
|
44
|
+
offset: MemoryOffset.FuelMap0,
|
|
45
|
+
scalerOffset: MemoryOffset.Map0RowScalerInitValue,
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
const maps = revision === DataOffsetRev.RevC ? NEW_MAPS : OLD_MAPS;
|
|
49
|
+
const offset = maps[id - 1] ?? 0;
|
|
50
|
+
return { offset, scalerOffset: offset + FUEL_MAP_ROW_SCALER_OFFSET };
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Validates the current fuel map id.
|
|
54
|
+
*
|
|
55
|
+
* @param id - The byte read from 0x202C.
|
|
56
|
+
* @returns The map id, 0 to 5.
|
|
57
|
+
* @throws {@link InvalidReadingError} if `id` is above 5.
|
|
58
|
+
*/
|
|
59
|
+
export function decodeCurrentFuelMap(id) {
|
|
60
|
+
if (id > 5) {
|
|
61
|
+
throw new InvalidReadingError(`Invalid fuel map id: ${id}`);
|
|
62
|
+
}
|
|
63
|
+
return id;
|
|
64
|
+
}
|
|
65
|
+
function decodeIndex(byte, limit, what) {
|
|
66
|
+
const index = byte >> 4;
|
|
67
|
+
if (index >= limit) {
|
|
68
|
+
throw new InvalidReadingError(`Invalid fuel map ${what} index: ${index}`);
|
|
69
|
+
}
|
|
70
|
+
return { index, weighting: byte & 0x0f };
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Decodes the row index byte: the high nibble is the row, the low nibble the
|
|
74
|
+
* weighting.
|
|
75
|
+
*
|
|
76
|
+
* @param byte - The byte read from 0x005B.
|
|
77
|
+
* @returns The row index (0 to 7) and weighting.
|
|
78
|
+
* @throws {@link InvalidReadingError} if the row index is 8 or more.
|
|
79
|
+
*/
|
|
80
|
+
export const decodeFuelMapRowIndex = (byte) => decodeIndex(byte, FUEL_MAP_ROWS, 'row');
|
|
81
|
+
/**
|
|
82
|
+
* Decodes the column index byte: the high nibble is the column, the low nibble
|
|
83
|
+
* the weighting.
|
|
84
|
+
*
|
|
85
|
+
* @param byte - The byte read from 0x005C.
|
|
86
|
+
* @returns The column index (0 to 15) and weighting.
|
|
87
|
+
* @throws {@link InvalidReadingError} if the column index is 16 or more.
|
|
88
|
+
*/
|
|
89
|
+
export const decodeFuelMapColumnIndex = (byte) => decodeIndex(byte, FUEL_MAP_COLUMNS, 'column');
|
|
90
|
+
/**
|
|
91
|
+
* Gives the address of one entry in the RPM table.
|
|
92
|
+
*
|
|
93
|
+
* @param column - Fuel map column, 0 to 15.
|
|
94
|
+
* @returns The address of the column's two-byte pulse width.
|
|
95
|
+
*/
|
|
96
|
+
export const rpmTableEntryAddress = (column) => MemoryOffset.RPMTable + column * 4;
|
|
97
|
+
/**
|
|
98
|
+
* Gives the slot in the result array for an RPM table column. The C library
|
|
99
|
+
* stores column 0 last.
|
|
100
|
+
*
|
|
101
|
+
* @param column - Fuel map column, 0 to 15.
|
|
102
|
+
* @returns The index in the result array.
|
|
103
|
+
*/
|
|
104
|
+
export const rpmTableSlot = (column) => FUEL_MAP_COLUMNS - column - 1;
|
|
105
|
+
/**
|
|
106
|
+
* Converts one RPM table pulse width to RPM; see {@link pulseWidthToRpm}.
|
|
107
|
+
*/
|
|
108
|
+
export const decodeRpmTableEntry = pulseWidthToRpm;
|
|
109
|
+
//# sourceMappingURL=fuelMap.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fuelMap.js","sourceRoot":"","sources":["../../src/decoders/fuelMap.ts"],"names":[],"mappings":"AAAA,wCAAwC;AACxC,4EAA4E;AAC5E,+DAA+D;AAC/D,4DAA4D;AAE5D,OAAO,EACL,aAAa,EACb,gBAAgB,EAChB,aAAa,EACb,0BAA0B,EAC1B,YAAY,GACb,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AACnD,OAAO,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAYnD,MAAM,QAAQ,GAAG;IACf,YAAY,CAAC,WAAW;IACxB,YAAY,CAAC,WAAW;IACxB,YAAY,CAAC,WAAW;IACxB,YAAY,CAAC,WAAW;IACxB,YAAY,CAAC,WAAW;CACzB,CAAC;AAEF,MAAM,QAAQ,GAAG;IACf,YAAY,CAAC,WAAW;IACxB,YAAY,CAAC,WAAW;IACxB,YAAY,CAAC,WAAW;IACxB,YAAY,CAAC,WAAW;IACxB,YAAY,CAAC,WAAW;CACzB,CAAC;AAOF;;;;;GAKG;AACH,MAAM,UAAU,eAAe,CAAC,EAAU;IACxC,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,EAAE,CAAC,IAAI,EAAE,GAAG,CAAC,IAAI,EAAE,GAAG,CAAC,EAAE,CAAC;QAC9C,MAAM,IAAI,UAAU,CAAC,wBAAwB,EAAE,EAAE,CAAC,CAAC;IACrD,CAAC;AACH,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,eAAe,CAC7B,EAAU,EACV,QAA4B;IAE5B,8CAA8C;IAC9C,IAAI,EAAE,KAAK,CAAC,EAAE,CAAC;QACb,OAAO;YACL,MAAM,EAAE,YAAY,CAAC,QAAQ;YAC7B,YAAY,EAAE,YAAY,CAAC,sBAAsB;SAClD,CAAC;IACJ,CAAC;IAED,MAAM,IAAI,GAAG,QAAQ,KAAK,aAAa,CAAC,IAAI,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC;IACnE,MAAM,MAAM,GAAG,IAAI,CAAC,EAAE,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC;IAEjC,OAAO,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,0BAA0B,EAAE,CAAC;AACvE,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,oBAAoB,CAAC,EAAU;IAC7C,IAAI,EAAE,GAAG,CAAC,EAAE,CAAC;QACX,MAAM,IAAI,mBAAmB,CAAC,wBAAwB,EAAE,EAAE,CAAC,CAAC;IAC9D,CAAC;IAED,OAAO,EAAE,CAAC;AACZ,CAAC;AAgBD,SAAS,WAAW,CAAC,IAAY,EAAE,KAAa,EAAE,IAAY;IAC5D,MAAM,KAAK,GAAG,IAAI,IAAI,CAAC,CAAC;IAExB,IAAI,KAAK,IAAI,KAAK,EAAE,CAAC;QACnB,MAAM,IAAI,mBAAmB,CAAC,oBAAoB,IAAI,WAAW,KAAK,EAAE,CAAC,CAAC;IAC5E,CAAC;IAED,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,IAAI,GAAG,IAAI,EAAE,CAAC;AAC3C,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,qBAAqB,GAAG,CAAC,IAAY,EAAgB,EAAE,CAClE,WAAW,CAAC,IAAI,EAAE,aAAa,EAAE,KAAK,CAAC,CAAC;AAE1C;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,wBAAwB,GAAG,CAAC,IAAY,EAAgB,EAAE,CACrE,WAAW,CAAC,IAAI,EAAE,gBAAgB,EAAE,QAAQ,CAAC,CAAC;AAEhD;;;;;GAKG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAAC,MAAc,EAAU,EAAE,CAC7D,YAAY,CAAC,QAAQ,GAAG,MAAM,GAAG,CAAC,CAAC;AAErC;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,MAAc,EAAU,EAAE,CACrD,gBAAgB,GAAG,MAAM,GAAG,CAAC,CAAC;AAEhC;;GAEG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAG,eAAe,CAAC","sourcesContent":["// SPDX-License-Identifier: GPL-3.0-only\n// Derived from libcomm14cux (https://github.com/colinbourassa/libcomm14cux)\n// Copyright (C) Colin Bourassa. Licensed under the GNU GPL v3.\n// Ported to TypeScript and modified for comm14cux-ts, 2026.\n\nimport {\n DataOffsetRev,\n FUEL_MAP_COLUMNS,\n FUEL_MAP_ROWS,\n FUEL_MAP_ROW_SCALER_OFFSET,\n MemoryOffset,\n} from '../constants.js';\nimport { InvalidReadingError } from '../errors.js';\nimport { pulseWidthToRpm } from './engineSpeed.js';\n\n/**\n * Where a fuel map lives in ECU memory.\n */\nexport interface FuelMapLocation {\n /** Address of the 128-byte map; the 2-byte adjustment factor follows it. */\n offset: number;\n /** Address of the row scaler byte. */\n scalerOffset: number;\n}\n\nconst OLD_MAPS = [\n MemoryOffset.OldFuelMap1,\n MemoryOffset.OldFuelMap2,\n MemoryOffset.OldFuelMap3,\n MemoryOffset.OldFuelMap4,\n MemoryOffset.OldFuelMap5,\n];\n\nconst NEW_MAPS = [\n MemoryOffset.NewFuelMap1,\n MemoryOffset.NewFuelMap2,\n MemoryOffset.NewFuelMap3,\n MemoryOffset.NewFuelMap4,\n MemoryOffset.NewFuelMap5,\n];\n\n/**\n * A {@link DataOffsetRev} that has been determined (not `Unset`).\n */\nexport type KnownDataOffsetRev = Exclude<DataOffsetRev, 0>;\n\n/**\n * Rejects a fuel map id outside 0 to 5.\n *\n * @param id - The fuel map id to check.\n * @throws {@link RangeError} if `id` is not an integer from 0 to 5.\n */\nexport function assertFuelMapId(id: number): void {\n if (!Number.isInteger(id) || id < 0 || id > 5) {\n throw new RangeError(`Invalid fuel map id: ${id}`);\n }\n}\n\n/**\n * Finds where a fuel map lives for the given ROM data layout.\n *\n * @param id - Map id, 0 to 5 (checked by {@link assertFuelMapId}).\n * @param revision - The ROM's data layout.\n * @returns The map's address and its row scaler's address.\n */\nexport function fuelMapLocation(\n id: number,\n revision: KnownDataOffsetRev,\n): FuelMapLocation {\n // Map 0 is at the same place in both layouts.\n if (id === 0) {\n return {\n offset: MemoryOffset.FuelMap0,\n scalerOffset: MemoryOffset.Map0RowScalerInitValue,\n };\n }\n\n const maps = revision === DataOffsetRev.RevC ? NEW_MAPS : OLD_MAPS;\n const offset = maps[id - 1] ?? 0;\n\n return { offset, scalerOffset: offset + FUEL_MAP_ROW_SCALER_OFFSET };\n}\n\n/**\n * Validates the current fuel map id.\n *\n * @param id - The byte read from 0x202C.\n * @returns The map id, 0 to 5.\n * @throws {@link InvalidReadingError} if `id` is above 5.\n */\nexport function decodeCurrentFuelMap(id: number): number {\n if (id > 5) {\n throw new InvalidReadingError(`Invalid fuel map id: ${id}`);\n }\n\n return id;\n}\n\n/**\n * A position within the fuel map and its interpolation weighting.\n */\nexport interface FuelMapIndex {\n /**\n * The row or column index.\n */\n index: number;\n /**\n * The weighting (0 to 15) used to interpolate toward the next row or column.\n */\n weighting: number;\n}\n\nfunction decodeIndex(byte: number, limit: number, what: string): FuelMapIndex {\n const index = byte >> 4;\n\n if (index >= limit) {\n throw new InvalidReadingError(`Invalid fuel map ${what} index: ${index}`);\n }\n\n return { index, weighting: byte & 0x0f };\n}\n\n/**\n * Decodes the row index byte: the high nibble is the row, the low nibble the\n * weighting.\n *\n * @param byte - The byte read from 0x005B.\n * @returns The row index (0 to 7) and weighting.\n * @throws {@link InvalidReadingError} if the row index is 8 or more.\n */\nexport const decodeFuelMapRowIndex = (byte: number): FuelMapIndex =>\n decodeIndex(byte, FUEL_MAP_ROWS, 'row');\n\n/**\n * Decodes the column index byte: the high nibble is the column, the low nibble\n * the weighting.\n *\n * @param byte - The byte read from 0x005C.\n * @returns The column index (0 to 15) and weighting.\n * @throws {@link InvalidReadingError} if the column index is 16 or more.\n */\nexport const decodeFuelMapColumnIndex = (byte: number): FuelMapIndex =>\n decodeIndex(byte, FUEL_MAP_COLUMNS, 'column');\n\n/**\n * Gives the address of one entry in the RPM table.\n *\n * @param column - Fuel map column, 0 to 15.\n * @returns The address of the column's two-byte pulse width.\n */\nexport const rpmTableEntryAddress = (column: number): number =>\n MemoryOffset.RPMTable + column * 4;\n\n/**\n * Gives the slot in the result array for an RPM table column. The C library\n * stores column 0 last.\n *\n * @param column - Fuel map column, 0 to 15.\n * @returns The index in the result array.\n */\nexport const rpmTableSlot = (column: number): number =>\n FUEL_MAP_COLUMNS - column - 1;\n\n/**\n * Converts one RPM table pulse width to RPM; see {@link pulseWidthToRpm}.\n */\nexport const decodeRpmTableEntry = pulseWidthToRpm;\n"]}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { Gear } from '../constants.js';
|
|
2
|
+
/**
|
|
3
|
+
* Decodes the gear selection from the neutral switch ADC byte. The thresholds
|
|
4
|
+
* are those hardcoded in the ECU firmware.
|
|
5
|
+
*
|
|
6
|
+
* @param adc - The byte read from 0x2000.
|
|
7
|
+
* @returns Park/neutral below 0x4D, drive/reverse above 0xB3, otherwise manual gearbox.
|
|
8
|
+
*/
|
|
9
|
+
export declare function decodeGear(adc: number): Gear;
|
|
10
|
+
//# sourceMappingURL=gear.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gear.d.ts","sourceRoot":"","sources":["../../src/decoders/gear.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,IAAI,EAAE,MAAM,iBAAiB,CAAC;AAEvC;;;;;;GAMG;AACH,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAW5C"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
// SPDX-License-Identifier: GPL-3.0-only
|
|
2
|
+
// Derived from libcomm14cux (https://github.com/colinbourassa/libcomm14cux)
|
|
3
|
+
// Copyright (C) Colin Bourassa. Licensed under the GNU GPL v3.
|
|
4
|
+
// Ported to TypeScript and modified for comm14cux-ts, 2026.
|
|
5
|
+
import { Gear } from '../constants.js';
|
|
6
|
+
/**
|
|
7
|
+
* Decodes the gear selection from the neutral switch ADC byte. The thresholds
|
|
8
|
+
* are those hardcoded in the ECU firmware.
|
|
9
|
+
*
|
|
10
|
+
* @param adc - The byte read from 0x2000.
|
|
11
|
+
* @returns Park/neutral below 0x4D, drive/reverse above 0xB3, otherwise manual gearbox.
|
|
12
|
+
*/
|
|
13
|
+
export function decodeGear(adc) {
|
|
14
|
+
if (adc < 0x4d) {
|
|
15
|
+
return Gear.ParkOrNeutral;
|
|
16
|
+
}
|
|
17
|
+
if (adc > 0xb3) {
|
|
18
|
+
return Gear.DriveOrReverse;
|
|
19
|
+
}
|
|
20
|
+
// Manual gearboxes have a resistor fitted to give a midpoint value.
|
|
21
|
+
return Gear.ManualGearbox;
|
|
22
|
+
}
|
|
23
|
+
//# sourceMappingURL=gear.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gear.js","sourceRoot":"","sources":["../../src/decoders/gear.ts"],"names":[],"mappings":"AAAA,wCAAwC;AACxC,4EAA4E;AAC5E,+DAA+D;AAC/D,4DAA4D;AAE5D,OAAO,EAAE,IAAI,EAAE,MAAM,iBAAiB,CAAC;AAEvC;;;;;;GAMG;AACH,MAAM,UAAU,UAAU,CAAC,GAAW;IACpC,IAAI,GAAG,GAAG,IAAI,EAAE,CAAC;QACf,OAAO,IAAI,CAAC,aAAa,CAAC;IAC5B,CAAC;IAED,IAAI,GAAG,GAAG,IAAI,EAAE,CAAC;QACf,OAAO,IAAI,CAAC,cAAc,CAAC;IAC7B,CAAC;IAED,oEAAoE;IACpE,OAAO,IAAI,CAAC,aAAa,CAAC;AAC5B,CAAC","sourcesContent":["// SPDX-License-Identifier: GPL-3.0-only\n// Derived from libcomm14cux (https://github.com/colinbourassa/libcomm14cux)\n// Copyright (C) Colin Bourassa. Licensed under the GNU GPL v3.\n// Ported to TypeScript and modified for comm14cux-ts, 2026.\n\nimport { Gear } from '../constants.js';\n\n/**\n * Decodes the gear selection from the neutral switch ADC byte. The thresholds\n * are those hardcoded in the ECU firmware.\n *\n * @param adc - The byte read from 0x2000.\n * @returns Park/neutral below 0x4D, drive/reverse above 0xB3, otherwise manual gearbox.\n */\nexport function decodeGear(adc: number): Gear {\n if (adc < 0x4d) {\n return Gear.ParkOrNeutral;\n }\n\n if (adc > 0xb3) {\n return Gear.DriveOrReverse;\n }\n\n // Manual gearboxes have a resistor fitted to give a midpoint value.\n return Gear.ManualGearbox;\n}\n"]}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Decodes the idle bypass motor position. 180 counts is fully closed.
|
|
3
|
+
*
|
|
4
|
+
* @param raw - The byte read from 0x006D.
|
|
5
|
+
* @returns Position as a fraction from 0 (closed) to 1 (widest opening).
|
|
6
|
+
*/
|
|
7
|
+
export declare function decodeIdleBypassPosition(raw: number): number;
|
|
8
|
+
//# sourceMappingURL=idleBypass.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"idleBypass.d.ts","sourceRoot":"","sources":["../../src/decoders/idleBypass.ts"],"names":[],"mappings":"AAOA;;;;;GAKG;AACH,wBAAgB,wBAAwB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAE5D"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
// SPDX-License-Identifier: GPL-3.0-only
|
|
2
|
+
// Derived from libcomm14cux (https://github.com/colinbourassa/libcomm14cux)
|
|
3
|
+
// Copyright (C) Colin Bourassa. Licensed under the GNU GPL v3.
|
|
4
|
+
// Ported to TypeScript and modified for comm14cux-ts, 2026.
|
|
5
|
+
const FULLY_CLOSED = 180;
|
|
6
|
+
/**
|
|
7
|
+
* Decodes the idle bypass motor position. 180 counts is fully closed.
|
|
8
|
+
*
|
|
9
|
+
* @param raw - The byte read from 0x006D.
|
|
10
|
+
* @returns Position as a fraction from 0 (closed) to 1 (widest opening).
|
|
11
|
+
*/
|
|
12
|
+
export function decodeIdleBypassPosition(raw) {
|
|
13
|
+
return (FULLY_CLOSED - Math.min(raw, FULLY_CLOSED)) / FULLY_CLOSED;
|
|
14
|
+
}
|
|
15
|
+
//# sourceMappingURL=idleBypass.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"idleBypass.js","sourceRoot":"","sources":["../../src/decoders/idleBypass.ts"],"names":[],"mappings":"AAAA,wCAAwC;AACxC,4EAA4E;AAC5E,+DAA+D;AAC/D,4DAA4D;AAE5D,MAAM,YAAY,GAAG,GAAG,CAAC;AAEzB;;;;;GAKG;AACH,MAAM,UAAU,wBAAwB,CAAC,GAAW;IAClD,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,YAAY,CAAC,CAAC,GAAG,YAAY,CAAC;AACrE,CAAC","sourcesContent":["// SPDX-License-Identifier: GPL-3.0-only\n// Derived from libcomm14cux (https://github.com/colinbourassa/libcomm14cux)\n// Copyright (C) Colin Bourassa. Licensed under the GNU GPL v3.\n// Ported to TypeScript and modified for comm14cux-ts, 2026.\n\nconst FULLY_CLOSED = 180;\n\n/**\n * Decodes the idle bypass motor position. 180 counts is fully closed.\n *\n * @param raw - The byte read from 0x006D.\n * @returns Position as a fraction from 0 (closed) to 1 (widest opening).\n */\nexport function decodeIdleBypassPosition(raw: number): number {\n return (FULLY_CLOSED - Math.min(raw, FULLY_CLOSED)) / FULLY_CLOSED;\n}\n"]}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Decodes a lambda fueling trim. A larger number means more fuel.
|
|
3
|
+
*
|
|
4
|
+
* @param raw - The 16-bit value read from the trim location.
|
|
5
|
+
* @returns Trim in counts, from -256 to 255.
|
|
6
|
+
*/
|
|
7
|
+
export declare function decodeLambdaTrim(raw: number): number;
|
|
8
|
+
/**
|
|
9
|
+
* Decodes the MAF CO trim voltage from the even-bank long-term trim value.
|
|
10
|
+
*
|
|
11
|
+
* @param raw - The 16-bit value read from 0x0046.
|
|
12
|
+
* @returns Voltage in volts.
|
|
13
|
+
*/
|
|
14
|
+
export declare function decodeCoTrimVoltage(raw: number): number;
|
|
15
|
+
//# sourceMappingURL=lambdaTrim.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lambdaTrim.d.ts","sourceRoot":"","sources":["../../src/decoders/lambdaTrim.ts"],"names":[],"mappings":"AAKA;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAEpD;AAED;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAEvD"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
// SPDX-License-Identifier: GPL-3.0-only
|
|
2
|
+
// Derived from libcomm14cux (https://github.com/colinbourassa/libcomm14cux)
|
|
3
|
+
// Copyright (C) Colin Bourassa. Licensed under the GNU GPL v3.
|
|
4
|
+
// Ported to TypeScript and modified for comm14cux-ts, 2026.
|
|
5
|
+
/**
|
|
6
|
+
* Decodes a lambda fueling trim. A larger number means more fuel.
|
|
7
|
+
*
|
|
8
|
+
* @param raw - The 16-bit value read from the trim location.
|
|
9
|
+
* @returns Trim in counts, from -256 to 255.
|
|
10
|
+
*/
|
|
11
|
+
export function decodeLambdaTrim(raw) {
|
|
12
|
+
return Math.trunc(raw / 0x80) - 0x100;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Decodes the MAF CO trim voltage from the even-bank long-term trim value.
|
|
16
|
+
*
|
|
17
|
+
* @param raw - The 16-bit value read from 0x0046.
|
|
18
|
+
* @returns Voltage in volts.
|
|
19
|
+
*/
|
|
20
|
+
export function decodeCoTrimVoltage(raw) {
|
|
21
|
+
return (5.0 * (raw >> 7)) / 1024.0;
|
|
22
|
+
}
|
|
23
|
+
//# sourceMappingURL=lambdaTrim.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lambdaTrim.js","sourceRoot":"","sources":["../../src/decoders/lambdaTrim.ts"],"names":[],"mappings":"AAAA,wCAAwC;AACxC,4EAA4E;AAC5E,+DAA+D;AAC/D,4DAA4D;AAE5D;;;;;GAKG;AACH,MAAM,UAAU,gBAAgB,CAAC,GAAW;IAC1C,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,GAAG,IAAI,CAAC,GAAG,KAAK,CAAC;AACxC,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,mBAAmB,CAAC,GAAW;IAC7C,OAAO,CAAC,GAAG,GAAG,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC;AACrC,CAAC","sourcesContent":["// SPDX-License-Identifier: GPL-3.0-only\n// Derived from libcomm14cux (https://github.com/colinbourassa/libcomm14cux)\n// Copyright (C) Colin Bourassa. Licensed under the GNU GPL v3.\n// Ported to TypeScript and modified for comm14cux-ts, 2026.\n\n/**\n * Decodes a lambda fueling trim. A larger number means more fuel.\n *\n * @param raw - The 16-bit value read from the trim location.\n * @returns Trim in counts, from -256 to 255.\n */\nexport function decodeLambdaTrim(raw: number): number {\n return Math.trunc(raw / 0x80) - 0x100;\n}\n\n/**\n * Decodes the MAF CO trim voltage from the even-bank long-term trim value.\n *\n * @param raw - The 16-bit value read from 0x0046.\n * @returns Voltage in volts.\n */\nexport function decodeCoTrimVoltage(raw: number): number {\n return (5.0 * (raw >> 7)) / 1024.0;\n}\n"]}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Reverses the quadratic the ECU applies to the battery voltage ADC count,
|
|
3
|
+
* then maps the count linearly to volts.
|
|
4
|
+
*
|
|
5
|
+
* @param stored - The 16-bit value read from 0x0055.
|
|
6
|
+
* @param a - First coefficient (a byte).
|
|
7
|
+
* @param b - Second coefficient (a byte).
|
|
8
|
+
* @param c - Third coefficient (16 bits).
|
|
9
|
+
* @returns The main relay voltage in volts.
|
|
10
|
+
* @throws {@link InvalidReadingError} if the coefficients cannot produce a real
|
|
11
|
+
* result for `stored`.
|
|
12
|
+
*/
|
|
13
|
+
export declare function decodeMainVoltage(stored: number, a: number, b: number, c: number): number;
|
|
14
|
+
//# sourceMappingURL=mainVoltage.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mainVoltage.d.ts","sourceRoot":"","sources":["../../src/decoders/mainVoltage.ts"],"names":[],"mappings":"AAOA;;;;;;;;;;;GAWG;AACH,wBAAgB,iBAAiB,CAC/B,MAAM,EAAE,MAAM,EACd,CAAC,EAAE,MAAM,EACT,CAAC,EAAE,MAAM,EACT,CAAC,EAAE,MAAM,GACR,MAAM,CAYR"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
// SPDX-License-Identifier: GPL-3.0-only
|
|
2
|
+
// Derived from libcomm14cux (https://github.com/colinbourassa/libcomm14cux)
|
|
3
|
+
// Copyright (C) Colin Bourassa. Licensed under the GNU GPL v3.
|
|
4
|
+
// Ported to TypeScript and modified for comm14cux-ts, 2026.
|
|
5
|
+
import { InvalidReadingError } from '../errors.js';
|
|
6
|
+
/**
|
|
7
|
+
* Reverses the quadratic the ECU applies to the battery voltage ADC count,
|
|
8
|
+
* then maps the count linearly to volts.
|
|
9
|
+
*
|
|
10
|
+
* @param stored - The 16-bit value read from 0x0055.
|
|
11
|
+
* @param a - First coefficient (a byte).
|
|
12
|
+
* @param b - Second coefficient (a byte).
|
|
13
|
+
* @param c - Third coefficient (16 bits).
|
|
14
|
+
* @returns The main relay voltage in volts.
|
|
15
|
+
* @throws {@link InvalidReadingError} if the coefficients cannot produce a real
|
|
16
|
+
* result for `stored`.
|
|
17
|
+
*/
|
|
18
|
+
export function decodeMainVoltage(stored, a, b, c) {
|
|
19
|
+
const discriminant = 4 * a * stored - a * c + 64 * b * b;
|
|
20
|
+
if (discriminant < 0) {
|
|
21
|
+
throw new InvalidReadingError('Main voltage coefficients do not fit reading');
|
|
22
|
+
}
|
|
23
|
+
const adcCount = Math.trunc((-16 * (Math.sqrt(discriminant) - 8 * b)) / a);
|
|
24
|
+
return 0.07 * adcCount - 0.09;
|
|
25
|
+
}
|
|
26
|
+
//# sourceMappingURL=mainVoltage.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mainVoltage.js","sourceRoot":"","sources":["../../src/decoders/mainVoltage.ts"],"names":[],"mappings":"AAAA,wCAAwC;AACxC,4EAA4E;AAC5E,+DAA+D;AAC/D,4DAA4D;AAE5D,OAAO,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AAEnD;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,iBAAiB,CAC/B,MAAc,EACd,CAAS,EACT,CAAS,EACT,CAAS;IAET,MAAM,YAAY,GAAG,CAAC,GAAG,CAAC,GAAG,MAAM,GAAG,CAAC,GAAG,CAAC,GAAG,EAAE,GAAG,CAAC,GAAG,CAAC,CAAC;IAEzD,IAAI,YAAY,GAAG,CAAC,EAAE,CAAC;QACrB,MAAM,IAAI,mBAAmB,CAC3B,8CAA8C,CAC/C,CAAC;IACJ,CAAC;IAED,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;IAE3E,OAAO,IAAI,GAAG,QAAQ,GAAG,IAAI,CAAC;AAChC,CAAC","sourcesContent":["// SPDX-License-Identifier: GPL-3.0-only\n// Derived from libcomm14cux (https://github.com/colinbourassa/libcomm14cux)\n// Copyright (C) Colin Bourassa. Licensed under the GNU GPL v3.\n// Ported to TypeScript and modified for comm14cux-ts, 2026.\n\nimport { InvalidReadingError } from '../errors.js';\n\n/**\n * Reverses the quadratic the ECU applies to the battery voltage ADC count,\n * then maps the count linearly to volts.\n *\n * @param stored - The 16-bit value read from 0x0055.\n * @param a - First coefficient (a byte).\n * @param b - Second coefficient (a byte).\n * @param c - Third coefficient (16 bits).\n * @returns The main relay voltage in volts.\n * @throws {@link InvalidReadingError} if the coefficients cannot produce a real\n * result for `stored`.\n */\nexport function decodeMainVoltage(\n stored: number,\n a: number,\n b: number,\n c: number,\n): number {\n const discriminant = 4 * a * stored - a * c + 64 * b * b;\n\n if (discriminant < 0) {\n throw new InvalidReadingError(\n 'Main voltage coefficients do not fit reading',\n );\n }\n\n const adcCount = Math.trunc((-16 * (Math.sqrt(discriminant) - 8 * b)) / a);\n\n return 0.07 * adcCount - 0.09;\n}\n"]}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Converts the road speed byte to miles per hour.
|
|
3
|
+
*
|
|
4
|
+
* @param kph - The byte read from 0x2003, in kilometres per hour.
|
|
5
|
+
* @returns Speed in whole miles per hour, truncated.
|
|
6
|
+
*/
|
|
7
|
+
export declare function decodeRoadSpeedMph(kph: number): number;
|
|
8
|
+
//# sourceMappingURL=roadSpeed.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"roadSpeed.d.ts","sourceRoot":"","sources":["../../src/decoders/roadSpeed.ts"],"names":[],"mappings":"AAKA;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAEtD"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
// SPDX-License-Identifier: GPL-3.0-only
|
|
2
|
+
// Derived from libcomm14cux (https://github.com/colinbourassa/libcomm14cux)
|
|
3
|
+
// Copyright (C) Colin Bourassa. Licensed under the GNU GPL v3.
|
|
4
|
+
// Ported to TypeScript and modified for comm14cux-ts, 2026.
|
|
5
|
+
/**
|
|
6
|
+
* Converts the road speed byte to miles per hour.
|
|
7
|
+
*
|
|
8
|
+
* @param kph - The byte read from 0x2003, in kilometres per hour.
|
|
9
|
+
* @returns Speed in whole miles per hour, truncated.
|
|
10
|
+
*/
|
|
11
|
+
export function decodeRoadSpeedMph(kph) {
|
|
12
|
+
return Math.trunc(kph * 0.621371192);
|
|
13
|
+
}
|
|
14
|
+
//# sourceMappingURL=roadSpeed.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"roadSpeed.js","sourceRoot":"","sources":["../../src/decoders/roadSpeed.ts"],"names":[],"mappings":"AAAA,wCAAwC;AACxC,4EAA4E;AAC5E,+DAA+D;AAC/D,4DAA4D;AAE5D;;;;;GAKG;AACH,MAAM,UAAU,kBAAkB,CAAC,GAAW;IAC5C,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,GAAG,WAAW,CAAC,CAAC;AACvC,CAAC","sourcesContent":["// SPDX-License-Identifier: GPL-3.0-only\n// Derived from libcomm14cux (https://github.com/colinbourassa/libcomm14cux)\n// Copyright (C) Colin Bourassa. Licensed under the GNU GPL v3.\n// Ported to TypeScript and modified for comm14cux-ts, 2026.\n\n/**\n * Converts the road speed byte to miles per hour.\n *\n * @param kph - The byte read from 0x2003, in kilometres per hour.\n * @returns Speed in whole miles per hour, truncated.\n */\nexport function decodeRoadSpeedMph(kph: number): number {\n return Math.trunc(kph * 0.621371192);\n}\n"]}
|