Tle8888 big update 1 (#1892)

* smart gpio: fix tle8888 direct pin mapping for MRE

* MRE: use TLE8888 pins instead of MCU gpios that drives TLE8888

* TLE8888: cleanup

* TLE8888: do not reset driver private data on WD/undervoltage reset

* TLE8888: diagnostic updates

* TLE8888 driver: BIG driver rework

* TLE8888: check SPI answers for abnormal states

Reply with other than requested register can be a sign of:
-Power-On-Reset, then OpStat0 will be replyed
-WatchDog reset, then FWDStat1 will be replyed
-Invalid communication frame, then Diag0 will be replyed

Keep tracking last accessed register and check with the next reply.

* TLE8888: debug clean-up

* TLE8888: implement spi array write

This reduce CS inactive state time between two consequent accesses
from 8.8 uS to 1.4 uS

* TLE8888: fix PP outputs in OD mode

* TLE8888: cleanup register definitions

* TLE8888: run separate driver thread for each chip instance

Calculating poll interval for few chips become more complex, avoid
this running thread for each device.

* TLE8888: fix cypress and kinetic compilation

Both platforms define its own MAX and cause redifination error if
common.h is included in driver.

* MRE: update mapping.yaml and fix direct pin mapping for TLE8888

* TLE8888: diagnnostic: disable switch off in case of overcurrent

For all output, use current limiting instead

* TLE8888: check for overvoltage on OUT8..OUT13

* TLE8888: add TODO note about how to recover from failure condition

Currently TLE8888 automaticly recovers only from overcurrent and
(may be) overtemperature conditions.
Short to bat cause output disable (bit in OECONFIG is reset) and
needs driver/host intervention.

* TLE8888: save few bytes of RAM

* TLE8888: Lada Kalina is test mule for IDLE stepper on TLE8888

Don't forget to enable PP mode for TLE8888 outputs 21..24:
uncomment line 1087 in tle8888.c

* TLE8888: reorder code, cleanup

* TLE8888: mode all debug/statisctic to per-chip struct

* TLE8888: rework poll interval calculation

* MRE: use TLE8888 pins instead of MCU gpios that drives TLE8888 #2
This commit is contained in:
Andrey G 2020-10-23 19:25:30 +03:00 committed by GitHub
parent ec17daeee7
commit 8e11675afd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 852 additions and 631 deletions

View File

@ -37,10 +37,10 @@ const ConfigOverrides& getConfigOverrides() {
}
static void setInjectorPins() {
engineConfiguration->injectionPins[0] = GPIOE_14;
engineConfiguration->injectionPins[1] = GPIOE_13;
engineConfiguration->injectionPins[2] = GPIOE_12;
engineConfiguration->injectionPins[3] = GPIOE_11;
engineConfiguration->injectionPins[0] = TLE8888_PIN_1;
engineConfiguration->injectionPins[1] = TLE8888_PIN_2;
engineConfiguration->injectionPins[2] = TLE8888_PIN_3;
engineConfiguration->injectionPins[3] = TLE8888_PIN_4;
// Disable remainder
for (int i = 4; i < INJECTION_PIN_COUNT;i++) {
@ -211,8 +211,8 @@ void setBoardConfigurationOverrides(void) {
// rusEfi firmware is totally not involved with main relay control on microRusEfi board
// todo: maybe even set EFI_MAIN_RELAY_CONTROL to FALSE for MRE configuration
// TLE8888 half bridges (pushpull, lowside, or high-low) TLE8888_IN11 / TLE8888_OUT21
// GPIOE_8: "35 - GP Out 1"
engineConfiguration->fuelPumpPin = GPIOE_8;
// TLE8888_PIN_21: "35 - GP Out 1"
engineConfiguration->fuelPumpPin = TLE8888_PIN_21;
engineConfiguration->sdCardSpiDevice = SPI_DEVICE_3;
engineConfiguration->spi3mosiPin = GPIOC_12;
@ -225,7 +225,7 @@ void setBoardConfigurationOverrides(void) {
// TLE8888 high current low side: VVT2 IN9 / OUT5
// GPIOE_10: "3 - Lowside 2"
engineConfiguration->idle.solenoidPin = GPIOE_10;
engineConfiguration->idle.solenoidPin = TLE8888_PIN_5;
// TLE8888_PIN_22: "34 - GP Out 2"

View File

@ -5,10 +5,10 @@
outputs:
# TLE8888 injector channels
GPIOE_14: "37 - Injector 1"
GPIOE_13: "38 - Injector 2"
GPIOE_12: "41 - Injector 3"
GPIOE_11: "42 - Injector 4"
TLE8888_PIN_1: "37 - Injector 1"
TLE8888_PIN_2: "38 - Injector 2"
TLE8888_PIN_3: "41 - Injector 3"
TLE8888_PIN_4: "42 - Injector 4"
# TC4427 ignition outputs (5v)
GPIOD_4: "9 - Ignition 1"
GPIOD_3: "10 - Ignition 2"
@ -18,17 +18,18 @@ outputs:
GPIOD_7: "14 - GP Out 5"
GPIOD_6: "13 - GP Out 6"
# default VVT TLE8888 high current low side: VVT1 TLE8888_IN10 / TLE8888_OUT6
GPIOE_9: "7 - Lowside 1"
# default Idle Air Control TLE8888 high current low side: VVT2 TLE8888_IN9 / TLE8888_OUT5
GPIOE_10: "3 - Lowside 2"
# default VVT TLE8888 high current low side: VVT1 TLE8888_OUT6
TLE8888_PIN_6: "7 - Lowside 1"
# default Idle Air Control TLE8888 high current low side: VVT2 TLE8888_OUT5
TLE8888_PIN_5: "3 - Lowside 2"
# TLE8888 half bridges (pushpull, lowside, or high-low) TLE8888_IN11 / TLE8888_OUT21#91
GPIOE_8: "35 - GP Out 1"
# TLE8888 half bridges (pushpull, lowside, or high-low) IN? / TLE8888_OUT22#89
# this should work but it does not GPIOE_7: "34 - GP Out 2"
# TLE8888 half bridges (pushpull, lowside, or high-low) TLE8888_OUT21#91
TLE8888_PIN_21: "35 - GP Out 1"
# TLE8888 half bridges (pushpull, lowside, or high-low) TLE8888_OUT22#89
TLE8888_PIN_22: "34 - GP Out 2"
# TLE8888 half bridges (pushpull, lowside, or high-low) TLE8888_OUT23
TLE8888_PIN_23: "33 - GP Out 3"
# TLE8888 half bridges (pushpull, lowside, or high-low) TLE8888_OUT24
TLE8888_PIN_24: "43 - GP Out 4"
# J2

View File

@ -195,13 +195,13 @@ void setBoardConfigurationOverrides(void) {
// Configure the TLE8888 half bridges (pushpull, lowside, or high-low)
// TLE8888_IN11 -> TLE8888_OUT21
// GPIOE_8: "35 - GP Out 1"
engineConfiguration->fuelPumpPin = GPIOE_8;
// TLE8888_PIN_21: "35 - GP Out 1"
engineConfiguration->fuelPumpPin = TLE8888_PIN_21;
// TLE8888 high current low side: VVT2 IN9 / OUT5
// GPIOE_10: "3 - Lowside 2"
engineConfiguration->idle.solenoidPin = GPIOE_10;
// TLE8888_PIN_4: "3 - Lowside 2"
engineConfiguration->idle.solenoidPin = TLE8888_PIN_5;
// TLE8888_PIN_22: "34 - GP Out 2"

View File

@ -469,24 +469,24 @@ void mreBoardOldTest(DECLARE_CONFIG_PARAMETER_SIGNATURE) {
// LED #1
// GPIOE_7: "34 - GP Out 2"
engineConfiguration->injectionPins[1 - 1] = TLE8888_PIN_22;//GPIOE_7;
// TLE8888_PIN_22: "34 - GP Out 2"
engineConfiguration->injectionPins[1 - 1] = TLE8888_PIN_22;
// LED #2
// TLE8888_PIN_23: "33 - GP Out 3"
engineConfiguration->injectionPins[10 - 1] = TLE8888_PIN_23;
// LED #3 - INJ#2
engineConfiguration->injectionPins[9 - 1] = GPIOE_13;
// TLE8888_PIN_1: LED #3 - INJ#2
engineConfiguration->injectionPins[9 - 1] = TLE8888_PIN_1;
// LED #4 - INJ#1
engineConfiguration->injectionPins[4 - 1] = GPIOE_14;
// TLE8888_PIN_2: LED #4 - INJ#1
engineConfiguration->injectionPins[4 - 1] = TLE8888_PIN_2;
// LED #5 - INJ#3
engineConfiguration->injectionPins[3 - 1] = GPIOE_12;
// TLE8888_PIN_3: LED #5 - INJ#3
engineConfiguration->injectionPins[3 - 1] = TLE8888_PIN_3;
// LED #6 - INJ#4
engineConfiguration->injectionPins[6 - 1] = GPIOE_11;
// TLE8888_PIN_4: LED #6 - INJ#4
engineConfiguration->injectionPins[6 - 1] = TLE8888_PIN_4;
// LED #7
// TLE8888_PIN_24: "43 - GP Out 4"
@ -494,18 +494,18 @@ void mreBoardOldTest(DECLARE_CONFIG_PARAMETER_SIGNATURE) {
// LED #8
// TLE8888 half bridges (pushpull, lowside, or high-low) IN12
// GPIOE_8: "35 - GP Out 1"
engineConfiguration->injectionPins[8 - 1] = GPIOE_8;
// TLE8888_PIN_21: "35 - GP Out 1"
engineConfiguration->injectionPins[8 - 1] = TLE8888_PIN_21;
// LED #9
// TLE8888 high current low side: IN10
// GPIOE_9: "7 - Lowside 1"
engineConfiguration->injectionPins[7 - 1] = GPIOE_9;
// TLE8888_PIN_6: "7 - Lowside 1"
engineConfiguration->injectionPins[7 - 1] = TLE8888_PIN_6;
// LED #10
// TLE8888 high current low side: VVT2 IN9 / OUT5
// GPIOE_10: "3 - Lowside 2"
engineConfiguration->injectionPins[2 - 1] = GPIOE_10;
// TLE8888_PIN_5: "3 - Lowside 2"
engineConfiguration->injectionPins[2 - 1] = TLE8888_PIN_5;
#endif /* BOARD_TLE8888_COUNT */
}
@ -530,17 +530,16 @@ void mreBCM(DECLARE_CONFIG_PARAMETER_SIGNATURE) {
#if (BOARD_TLE8888_COUNT > 0)
engineConfiguration->fsioOutputPins[0] = GPIOE_14;// "37 - Injector 1"
engineConfiguration->fsioOutputPins[1] = GPIOE_13;// "38 - Injector 2"
engineConfiguration->fsioOutputPins[2] = GPIOE_12;// "41 - Injector 3"
engineConfiguration->fsioOutputPins[3] = GPIOE_11;// "42 - Injector 4"
// engineConfiguration->fsioOutputPins[4] = LS1
// engineConfiguration->fsioOutputPins[5] = LS2
// engineConfiguration->fsioOutputPins[6] = GP1
engineConfiguration->fsioOutputPins[7] = TLE8888_PIN_22;// "34 - GP Out 2"
engineConfiguration->fsioOutputPins[8] = TLE8888_PIN_23;// "33 - GP Out 3"
engineConfiguration->fsioOutputPins[9] = TLE8888_PIN_24;// "43 - GP Out 4"
engineConfiguration->fsioOutputPins[0] = TLE8888_PIN_1; // "37 - Injector 1"
engineConfiguration->fsioOutputPins[1] = TLE8888_PIN_2; // "38 - Injector 2"
engineConfiguration->fsioOutputPins[2] = TLE8888_PIN_3; // "41 - Injector 3"
engineConfiguration->fsioOutputPins[3] = TLE8888_PIN_4; // "42 - Injector 4"
// engineConfiguration->fsioOutputPins[4] = TLE8888_PIN_5;
// engineConfiguration->fsioOutputPins[5] = TLE8888_PIN_6;
// engineConfiguration->fsioOutputPins[6] = TLE8888_PIN_21;
engineConfiguration->fsioOutputPins[7] = TLE8888_PIN_22; // "34 - GP Out 2"
engineConfiguration->fsioOutputPins[8] = TLE8888_PIN_23; // "33 - GP Out 3"
engineConfiguration->fsioOutputPins[9] = TLE8888_PIN_24; // "43 - GP Out 4"
#endif /* BOARD_TLE8888_COUNT */
}
@ -555,9 +554,6 @@ void mreBoardNewTest(DECLARE_CONFIG_PARAMETER_SIGNATURE) {
engineConfiguration->specs.cylindersCount = 12;
engineConfiguration->specs.firingOrder = FO_1_2_3_4_5_6_7_8_9_10_11_12;
#if (BOARD_TLE8888_COUNT > 0)
engineConfiguration->ignitionPins[1 - 1] = GPIOD_6;
engineConfiguration->ignitionPins[2 - 1] = GPIOD_7;
@ -571,12 +567,12 @@ void mreBoardNewTest(DECLARE_CONFIG_PARAMETER_SIGNATURE) {
// LED #8
// TLE8888 half bridges (pushpull, lowside, or high-low) IN12
// GPIOE_8: "35 - GP Out 1"
engineConfiguration->ignitionPins[9 - 1] = GPIOE_8;
// TLE8888_PIN_21: "35 - GP Out 1"
engineConfiguration->ignitionPins[9 - 1] = TLE8888_PIN_21;
// LED #1
// GPIOE_7: "34 - GP Out 2"
engineConfiguration->ignitionPins[10- 1] = TLE8888_PIN_22;//GPIOE_7;
// TLE8888_PIN_22: "34 - GP Out 2"
engineConfiguration->ignitionPins[10- 1] = TLE8888_PIN_22;
// LED #2
// TLE8888_PIN_23: "33 - GP Out 3"
@ -589,27 +585,22 @@ void mreBoardNewTest(DECLARE_CONFIG_PARAMETER_SIGNATURE) {
engineConfiguration->afr.hwChannel = EFI_ADC_6;
engineConfiguration->throttlePedalPositionAdcChannel = EFI_ADC_NONE;
// TLE8888 high current low side: IN10
// GPIOE_9: "7 - Lowside 1"
engineConfiguration->injectionPins[1 - 1] = GPIOE_9;
// TLE8888_PIN_6: "7 - Lowside 1"
engineConfiguration->injectionPins[1 - 1] = TLE8888_PIN_6;
// TLE8888 high current low side: VVT2 IN9 / OUT5
// GPIOE_10: "3 - Lowside 2"
engineConfiguration->injectionPins[2 - 1] = GPIOE_10;
// TLE8888_PIN_5: "3 - Lowside 2"
engineConfiguration->injectionPins[2 - 1] = TLE8888_PIN_5;
// INJ#4
engineConfiguration->injectionPins[3 - 1] = GPIOE_11;
// INJ#3
engineConfiguration->injectionPins[4 - 1] = GPIOE_12;
// INJ#2
engineConfiguration->injectionPins[5 - 1] = GPIOE_13;
// LED #3 - INJ#1
engineConfiguration->injectionPins[6 - 1] = GPIOE_14;
// TLE8888_PIN_4: INJ#4
engineConfiguration->injectionPins[3 - 1] = TLE8888_PIN_4;
// TLE8888_PIN_3: INJ#3
engineConfiguration->injectionPins[4 - 1] = TLE8888_PIN_3;
// TLE8888_PIN_2: INJ#2
engineConfiguration->injectionPins[5 - 1] = TLE8888_PIN_2;
// TLE8888_PIN_1: LED #3 - INJ#1
engineConfiguration->injectionPins[6 - 1] = TLE8888_PIN_1;
engineConfiguration->injectionPins[7 - 1] = GPIOA_4; // AV10
@ -620,11 +611,6 @@ void mreBoardNewTest(DECLARE_CONFIG_PARAMETER_SIGNATURE) {
engineConfiguration->injectionPins[11- 1] = TLE8888_PIN_13;
engineConfiguration->injectionPins[12- 1] = TLE8888_PIN_10;
#endif /* BOARD_TLE8888_COUNT */
}

View File

@ -13,6 +13,25 @@
EXTERN_CONFIG;
#if (BOARD_TLE8888_COUNT > 0)
void setLadaKalina(DECLARE_CONFIG_PARAMETER_SIGNATURE) {
/* MRE uses TLE8888_PIN_21 for fuel pump */
engineConfiguration->fuelPumpPin = GPIO_UNASSIGNED;
/* PRE uses TLE8888_PIN_22 for fan */
engineConfiguration->fanPin = GPIO_UNASSIGNED;
// TLE8888 two bridge drivers for stepper
engineConfiguration->etbIo2[0].directionPin1 = TLE8888_PIN_21;
engineConfiguration->etbIo2[0].directionPin2 = TLE8888_PIN_22;
engineConfiguration->etbIo2[1].directionPin1 = TLE8888_PIN_23;
engineConfiguration->etbIo2[1].directionPin2 = TLE8888_PIN_24;
/* IDLE configuration */
engineConfiguration->useStepperIdle = true;
engineConfiguration->useHbridges = true;
engineConfiguration->idleMode = IM_AUTO;
}
#else
void setLadaKalina(DECLARE_CONFIG_PARAMETER_SIGNATURE) {
setFrankensoConfiguration(PASS_CONFIG_PARAMETER_SIGNATURE);
disableLCD(engineConfiguration);
@ -59,3 +78,4 @@ void setLadaKalina(DECLARE_CONFIG_PARAMETER_SIGNATURE) {
setFsioExt(0, GPIOE_3, RPM_BELOW_USER_SETTING_1, 0 PASS_CONFIG_PARAMETER_SUFFIX);
#endif /* EFI_FSIO */
}
#endif

View File

@ -99,7 +99,7 @@ void setVwPassatB6(DECLARE_CONFIG_PARAMETER_SIGNATURE) {
}
}
*/
coolantControl->pin = GPIOE_10; // "3 - Lowside 2"
coolantControl->pin = TLE8888_PIN_5; // "3 - Lowside 2"
engineConfiguration->idle.solenoidPin = GPIO_UNASSIGNED;

View File

@ -199,7 +199,7 @@ void Engine::periodicSlowCallback(DECLARE_ENGINE_PARAMETER_SIGNATURE) {
if (CONFIG(useTLE8888_cranking_hack) && ENGINE(rpmCalculator).isCranking()) {
efitick_t nowNt = getTimeNowNt();
if (nowNt - tle8888CrankingResetTime > MS2NT(300)) {
requestTLE8888initialization();
tle8888_req_init();
// let's reset TLE8888 every 300ms while cranking since that's the best we can do to deal with undervoltage reset
// PS: oh yes, it's a horrible design! Please suggest something better!
tle8888CrankingResetTime = nowNt;

View File

@ -286,7 +286,7 @@ static void handleCommandX14(uint16_t index) {
return;
case 8:
#if (BOARD_TLE8888_COUNT > 0)
requestTLE8888initialization();
tle8888_req_init();
#endif
return;
case 0xA:

File diff suppressed because it is too large Load Diff

View File

@ -19,21 +19,9 @@
* 4 INJ channels - OUT1..4 - IN5..8 */
#define TLE8888_DIRECT_OUTPUTS (4 + 4 + TLE8888_DIRECT_MISC)
// Looks like reset value is 113.6ms? 1.6ms * 0x47
#define Functional_Watchdog_PERIOD_MS 20
// we can change this value on TLE8888QK but we probably do not have a reason to change
#define Window_watchdog_close_window_time_ms 100.8
#define getRegisterFromResponse(x) (((x) >> 1) & 0x7f)
#define getDataFromResponse(x) (((x) >> 8) & 0xff)
// unchangeable value for TLE8888QK
// unused for now
//#define Window_watchdog_open_window_time_ms 12.8
/* DOTO: add irq support */
#define TLE8888_POLL_INTERVAL_MS 7
/* note that spi transfer should be LSB first */
struct tle8888_config {
@ -45,12 +33,15 @@ struct tle8888_config {
uint_fast8_t pad;
} reset;
struct {
/* MCU port-pin routed to IN9..12 */
/* MCU port-pin routed to IN1..12 */
ioportid_t port;
uint_fast8_t pad;
} direct_gpio[TLE8888_DIRECT_OUTPUTS];
/* IN9..IN12 to output mapping */
struct {
/* ...used to drive output (starts from 1, as in DS, coders gonna hate) */
int output;
} direct_io[TLE8888_DIRECT_MISC];
} direct_maps[TLE8888_DIRECT_MISC];
struct {
ioportid_t port;
uint_fast8_t pad;
@ -71,7 +62,10 @@ extern "C"
* @return return gpio chip base
*/
int tle8888_add(unsigned int index, const struct tle8888_config *cfg);
void requestTLE8888initialization(void);
/* debug */
void tle8888_read_reg(uint16_t reg, uint16_t *val);
void tle8888_req_init(void);
#if EFI_TUNER_STUDIO
#include "tunerstudio_debug_struct.h"

View File

@ -95,19 +95,15 @@ PinRepository::PinRepository() {
}
#if (BOARD_TLE8888_COUNT > 0)
/* DEBUG */
extern "C" {
extern void tle8888_read_reg(uint16_t reg, uint16_t *val);
}
void tle8888_dump_regs(void)
{
// since responses are always in the NEXT transmission we will have this one first
tle8888_read_reg(0, NULL);
scheduleMsg(&logger, "register: data");
for (int request = 0; request < 0x7e + 1; request++) {
for (int request = 0; request <= 0x7e + 1; request++) {
uint16_t tmp;
tle8888_read_reg(request, &tmp);
tle8888_read_reg(request < (0x7e + 1) ? request : 0x7e, &tmp);
uint8_t reg = getRegisterFromResponse(tmp);
uint8_t data = getDataFromResponse(tmp);
@ -227,7 +223,7 @@ void initPinRepository(void) {
#if (BOARD_TLE8888_COUNT > 0)
addConsoleAction("tle8888", tle8888_dump_regs);
addConsoleAction("tle8888init", requestTLE8888initialization);
addConsoleAction("tle8888init", tle8888_req_init);
#endif
}

View File

@ -122,20 +122,29 @@ struct tle8888_config tle8888_cfg = {
.cr2 = SPI_CR2_16BIT_MODE
},
.reset = {.port = NULL, .pad = 0},
.direct_io = {
[0] = {.port = GPIOE, .pad = 10, .output = 5},
[1] = {.port = GPIOE, .pad = 9, .output = 6},
[2] = {.port = GPIOE, .pad = 8, .output = 21},
[3] = {.port = NULL, .pad = 0, .output = 15},
// [3] = {.port = GPIOE, .pad = 7, .output = 22},
/*
[0] = {.port = NULL, .pad = 0, .output = 9},
[1] = {.port = NULL, .pad = 0, .output = 10},
[2] = {.port = NULL, .pad = 0, .output = 11},
[3] = {.port = NULL, .pad = 0, .output = 12},
*/
.direct_gpio = {
/* IN1..4 -> OUT1..OUT4 (Injectors) */
[0] = {.port = GPIOE, .pad = 14},
[1] = {.port = GPIOE, .pad = 13},
[2] = {.port = GPIOE, .pad = 12},
[3] = {.port = GPIOE, .pad = 11},
/* IN5..8 -> IGN1..IGN4 (Ignotors) */
/* Not used */
[4] = {.port = NULL, .pad = 0},
[5] = {.port = NULL, .pad = 0},
[6] = {.port = NULL, .pad = 0},
[7] = {.port = NULL, .pad = 0},
/* Remapable IN9..12 */
[8] = {.port = GPIOE, .pad = 10},
[9] = {.port = GPIOE, .pad = 9},
[10] = {.port = GPIOE, .pad = 8},
[11] = {.port = GPIOE, .pad = 7},
},
.direct_maps = {
[0] = {.output = 5},
[1] = {.output = 6},
[2] = {.output = 21},
[3] = {.output = 22},
},
.ign_en = {.port = GPIOD, .pad = 10},
.inj_en = {.port = GPIOD, .pad = 11},