2019-05-03 18:13:25 -07:00
|
|
|
/*
|
|
|
|
* @file mc33816.cpp
|
|
|
|
*
|
2023-12-12 11:10:57 -08:00
|
|
|
* TL,DR: GDI
|
|
|
|
*
|
2019-05-03 18:13:25 -07:00
|
|
|
* The NXP MC33816 is a programmable gate driver IC for precision solenoid control applications.
|
|
|
|
*
|
2019-05-08 07:58:43 -07:00
|
|
|
*
|
2020-07-04 18:38:52 -07:00
|
|
|
* Useful wires:
|
|
|
|
* 5v, 3(3.3v), Gnd, 12v, VccIO(3v) SPI, DRVEN, RSTB
|
|
|
|
*
|
2019-05-08 07:58:43 -07:00
|
|
|
* For MC33816 vs PT2000 differences see
|
|
|
|
* https://www.nxp.com/docs/en/application-note/AN5203.pdf
|
|
|
|
*
|
2019-05-03 18:13:25 -07:00
|
|
|
* @date May 3, 2019
|
2020-01-07 21:02:40 -08:00
|
|
|
* @author Andrey Belomutskiy, (c) 2012-2020
|
2019-05-03 18:13:25 -07:00
|
|
|
*/
|
|
|
|
|
2021-07-25 22:05:17 -07:00
|
|
|
#include "pch.h"
|
2019-05-03 18:13:25 -07:00
|
|
|
|
|
|
|
#if EFI_MC33816
|
|
|
|
|
2019-05-03 18:38:34 -07:00
|
|
|
#include "hardware.h"
|
2019-05-03 18:54:38 -07:00
|
|
|
#include "mpu_util.h"
|
2024-05-08 18:45:32 -07:00
|
|
|
#include "ignition_controller.h"
|
2019-05-03 18:38:34 -07:00
|
|
|
|
2024-06-17 14:57:29 -07:00
|
|
|
static SPIConfig spiCfg = {
|
|
|
|
.circular = false,
|
|
|
|
#ifdef _CHIBIOS_RT_CONF_VER_6_1_
|
|
|
|
.end_cb = NULL,
|
|
|
|
#else
|
|
|
|
.slave = false,
|
|
|
|
.data_cb = NULL,
|
|
|
|
.error_cb = NULL,
|
|
|
|
#endif
|
2024-08-11 12:16:57 -07:00
|
|
|
.ssport = nullptr,
|
2019-05-03 18:38:34 -07:00
|
|
|
.sspad = 0,
|
2019-05-03 18:54:38 -07:00
|
|
|
.cr1 =
|
2024-08-23 20:57:03 -07:00
|
|
|
SPI_CR1_MSTR |
|
|
|
|
SPI_CR1_SSM | // Software Slave Management, the SSI bit will be internal reference
|
|
|
|
SPI_CR1_SSI | // Internal Slave Select (active low) set High
|
2024-08-24 06:46:25 -07:00
|
|
|
SPI_CR1_CPHA |
|
2024-08-23 20:57:03 -07:00
|
|
|
//SPI_CR1_BR_1 // 5MHz
|
2024-08-24 06:46:25 -07:00
|
|
|
SPI_CR1_BR_0 | SPI_CR1_BR_1 | SPI_CR1_BR_2 |
|
2024-08-23 20:57:03 -07:00
|
|
|
SPI_CR1_SPE,
|
|
|
|
.cr2 = SPI_CR2_SSOE |
|
|
|
|
SPI_CR2_16BIT_MODE
|
|
|
|
};
|
2019-05-03 18:38:34 -07:00
|
|
|
|
2022-08-08 05:53:08 -07:00
|
|
|
class Pt2001 : public Pt2001Base {
|
|
|
|
public:
|
2024-09-23 07:11:03 -07:00
|
|
|
bool init();
|
2022-08-08 05:53:08 -07:00
|
|
|
void initIfNeeded();
|
2019-05-03 18:38:34 -07:00
|
|
|
|
2022-08-08 05:53:08 -07:00
|
|
|
protected:
|
2024-08-27 08:28:48 -07:00
|
|
|
void acquireBus() override {
|
2024-09-23 07:11:03 -07:00
|
|
|
criticalAssertVoid(driver != nullptr, "mc33816");
|
2024-08-27 08:50:38 -07:00
|
|
|
spiAcquireBus(driver);
|
2024-08-27 06:37:48 -07:00
|
|
|
}
|
|
|
|
|
2024-08-27 08:28:48 -07:00
|
|
|
void releaseBus() override {
|
2024-08-27 08:50:38 -07:00
|
|
|
spiReleaseBus(driver);
|
2024-08-27 06:37:48 -07:00
|
|
|
}
|
|
|
|
|
2022-08-08 05:53:08 -07:00
|
|
|
void select() override {
|
2024-09-23 07:11:03 -07:00
|
|
|
criticalAssertVoid(driver != nullptr, "mc33816");
|
2024-08-11 12:16:57 -07:00
|
|
|
// revive MC33816 driver, also support bus sharing #6781
|
|
|
|
// should be somewhere but not here spiStart(driver, &spiCfg);
|
2024-08-27 11:37:12 -07:00
|
|
|
// efiPrintf("mc select %s", hwOnChipPhysicalPinName(driver->config->ssport, driver->config->sspad));
|
2022-08-08 05:53:08 -07:00
|
|
|
spiSelect(driver);
|
2024-08-23 20:57:03 -07:00
|
|
|
//chris - "no implementation on stm32"
|
|
|
|
chipSelect.setValue(0);
|
2020-11-17 22:07:09 -08:00
|
|
|
}
|
2019-06-06 17:12:03 -07:00
|
|
|
|
2022-08-08 05:53:08 -07:00
|
|
|
void deselect() override {
|
|
|
|
spiUnselect(driver);
|
2024-08-23 20:57:03 -07:00
|
|
|
//chris - "no implementation on stm32"
|
|
|
|
chipSelect.setValue(1);
|
2022-08-08 05:53:08 -07:00
|
|
|
}
|
2019-06-06 17:12:03 -07:00
|
|
|
|
2022-08-08 05:53:08 -07:00
|
|
|
uint16_t sendRecv(uint16_t tx) override {
|
|
|
|
return spiPolledExchange(driver, tx);
|
|
|
|
}
|
2019-05-03 18:13:25 -07:00
|
|
|
|
2022-08-08 05:53:08 -07:00
|
|
|
// Send `count` number of 16 bit words from `data`
|
|
|
|
void sendLarge(const uint16_t* data, size_t count) override {
|
|
|
|
spiSend(driver, count, data);
|
|
|
|
}
|
2020-04-16 04:32:08 -07:00
|
|
|
|
2022-08-08 05:53:08 -07:00
|
|
|
// GPIO reset and enable pins
|
|
|
|
void setResetB(bool state) override {
|
|
|
|
resetB.setValue(state);
|
|
|
|
}
|
2020-04-16 04:32:08 -07:00
|
|
|
|
2022-08-08 05:53:08 -07:00
|
|
|
void setDriveEN(bool state) override {
|
|
|
|
driven.setValue(state);
|
|
|
|
}
|
2022-07-15 23:23:05 -07:00
|
|
|
|
2022-08-08 05:53:08 -07:00
|
|
|
// GPIO inputs for various pins we need
|
|
|
|
bool readFlag0() const override {
|
|
|
|
return efiReadPin(engineConfiguration->mc33816_flag0);
|
|
|
|
}
|
2020-04-16 04:32:08 -07:00
|
|
|
|
2022-08-08 05:53:08 -07:00
|
|
|
// Get battery voltage - only try to init chip when powered
|
|
|
|
float getVbatt() const override {
|
2024-08-07 20:47:48 -07:00
|
|
|
// reminder that we do not have sensor subsystem right away
|
|
|
|
return Sensor::get(SensorType::BatteryVoltage).value_or(0);
|
2022-08-08 05:53:08 -07:00
|
|
|
}
|
2020-04-16 04:32:08 -07:00
|
|
|
|
2022-08-08 05:53:08 -07:00
|
|
|
// CONFIGURATIONS: currents, timings, voltages
|
|
|
|
float getBoostVoltage() const override {
|
|
|
|
return engineConfiguration->mc33_hvolt;
|
|
|
|
}
|
2020-05-19 23:35:18 -07:00
|
|
|
|
2022-08-08 05:53:08 -07:00
|
|
|
// Currents in amps
|
|
|
|
float getBoostCurrent() const override {
|
|
|
|
return engineConfiguration->mc33_i_boost;
|
|
|
|
}
|
2020-05-19 23:35:18 -07:00
|
|
|
|
2022-08-08 05:53:08 -07:00
|
|
|
float getPeakCurrent() const override {
|
|
|
|
return engineConfiguration->mc33_i_peak;
|
2020-04-16 13:04:09 -07:00
|
|
|
}
|
2022-08-08 05:53:08 -07:00
|
|
|
|
|
|
|
float getHoldCurrent() const override {
|
|
|
|
return engineConfiguration->mc33_i_hold;
|
2020-04-16 13:04:09 -07:00
|
|
|
}
|
2020-04-16 04:32:08 -07:00
|
|
|
|
2022-08-08 05:53:08 -07:00
|
|
|
float getPumpPeakCurrent() const override {
|
|
|
|
return engineConfiguration->mc33_hpfp_i_peak;
|
|
|
|
}
|
2020-04-13 21:57:19 -07:00
|
|
|
|
2022-08-08 05:53:08 -07:00
|
|
|
float getPumpHoldCurrent() const override {
|
|
|
|
return engineConfiguration->mc33_hpfp_i_hold;
|
|
|
|
}
|
2020-04-13 21:57:19 -07:00
|
|
|
|
2022-08-08 05:53:08 -07:00
|
|
|
// Timings in microseconds
|
|
|
|
uint16_t getTpeakOff() const override {
|
|
|
|
return engineConfiguration->mc33_t_peak_off;
|
|
|
|
}
|
2020-04-13 21:57:19 -07:00
|
|
|
|
2022-08-08 05:53:08 -07:00
|
|
|
uint16_t getTpeakTot() const override {
|
|
|
|
return engineConfiguration->mc33_t_peak_tot;
|
|
|
|
}
|
2020-04-13 21:57:19 -07:00
|
|
|
|
2022-08-08 05:53:08 -07:00
|
|
|
uint16_t getTbypass() const override {
|
|
|
|
return engineConfiguration->mc33_t_bypass;
|
|
|
|
}
|
2020-04-13 21:57:19 -07:00
|
|
|
|
2022-08-08 05:53:08 -07:00
|
|
|
uint16_t getTholdOff() const override {
|
|
|
|
return engineConfiguration->mc33_t_hold_off;
|
|
|
|
}
|
2020-05-10 22:52:20 -07:00
|
|
|
|
2022-08-08 05:53:08 -07:00
|
|
|
uint16_t getTHoldTot() const override {
|
|
|
|
return engineConfiguration->mc33_t_hold_tot;
|
|
|
|
}
|
2020-05-10 22:52:20 -07:00
|
|
|
|
2022-08-08 05:53:08 -07:00
|
|
|
uint16_t getTBoostMin() const override {
|
|
|
|
return engineConfiguration->mc33_t_min_boost;
|
|
|
|
}
|
2020-05-17 13:28:05 -07:00
|
|
|
|
2022-08-08 05:53:08 -07:00
|
|
|
uint16_t getTBoostMax() const override {
|
|
|
|
return engineConfiguration->mc33_t_max_boost;
|
|
|
|
}
|
2020-05-10 22:52:20 -07:00
|
|
|
|
2022-08-08 05:53:08 -07:00
|
|
|
uint16_t getPumpTholdOff() const override {
|
|
|
|
return engineConfiguration->mc33_hpfp_i_hold_off;
|
|
|
|
}
|
2020-05-10 22:52:20 -07:00
|
|
|
|
2022-08-08 05:53:08 -07:00
|
|
|
uint16_t getPumpTholdTot() const override {
|
|
|
|
return engineConfiguration->mc33_hpfp_max_hold;
|
|
|
|
}
|
2020-05-10 22:52:20 -07:00
|
|
|
|
2022-08-08 05:53:08 -07:00
|
|
|
// Print out an error message
|
|
|
|
void onError(const char* why) override {
|
|
|
|
efiPrintf("PT2001 error: %s", why);
|
|
|
|
}
|
2019-06-06 17:12:03 -07:00
|
|
|
|
2024-08-24 06:46:25 -07:00
|
|
|
bool errorOnUnexpectedFlag() override {
|
|
|
|
efiPrintf("****** unexpected mc33 flag state ******");
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2022-08-16 20:02:34 -07:00
|
|
|
void sleepMs(size_t ms) override {
|
|
|
|
chThdSleepMilliseconds(ms);
|
|
|
|
}
|
|
|
|
|
2022-08-08 05:53:08 -07:00
|
|
|
private:
|
|
|
|
SPIDriver* driver;
|
2019-06-06 17:12:03 -07:00
|
|
|
|
2022-08-08 05:53:08 -07:00
|
|
|
OutputPin resetB;
|
|
|
|
OutputPin driven;
|
|
|
|
OutputPin chipSelect;
|
|
|
|
};
|
2019-05-03 18:54:38 -07:00
|
|
|
|
2024-08-07 20:47:48 -07:00
|
|
|
static Pt2001 pt;
|
|
|
|
|
2024-09-23 07:11:03 -07:00
|
|
|
/**
|
|
|
|
* returns true if chip has configuration
|
|
|
|
*/
|
|
|
|
bool Pt2001::init() {
|
2020-02-25 19:38:08 -08:00
|
|
|
//
|
2020-10-19 19:04:06 -07:00
|
|
|
// see setTest33816EngineConfiguration for default configuration
|
2020-04-16 13:04:09 -07:00
|
|
|
// Pins
|
2021-11-17 00:54:21 -08:00
|
|
|
if (!isBrainPinValid(engineConfiguration->mc33816_cs) ||
|
|
|
|
!isBrainPinValid(engineConfiguration->mc33816_rstb) ||
|
|
|
|
!isBrainPinValid(engineConfiguration->mc33816_driven)) {
|
2024-09-23 07:11:03 -07:00
|
|
|
return false;
|
2020-10-19 19:04:06 -07:00
|
|
|
}
|
2021-11-17 00:54:21 -08:00
|
|
|
if (isBrainPinValid(engineConfiguration->mc33816_flag0)) {
|
|
|
|
efiSetPadMode("mc33816 flag0", engineConfiguration->mc33816_flag0, getInputMode(PI_DEFAULT));
|
2020-04-16 13:04:09 -07:00
|
|
|
}
|
2019-05-03 18:38:34 -07:00
|
|
|
|
2020-04-14 16:23:53 -07:00
|
|
|
chipSelect.initPin("mc33 CS", engineConfiguration->mc33816_cs /*, &engineConfiguration->csPinMode*/);
|
2024-08-11 12:16:57 -07:00
|
|
|
chipSelect.setValue(1);
|
2020-04-14 16:23:53 -07:00
|
|
|
|
2019-06-06 17:12:03 -07:00
|
|
|
// Initialize the chip via ResetB
|
|
|
|
resetB.initPin("mc33 RESTB", engineConfiguration->mc33816_rstb);
|
2020-04-12 15:03:53 -07:00
|
|
|
// High Voltage via DRIVEN
|
|
|
|
driven.initPin("mc33 DRIVEN", engineConfiguration->mc33816_driven);
|
2019-06-06 17:12:03 -07:00
|
|
|
|
2024-01-02 20:08:11 -08:00
|
|
|
spiCfg.ssport = getHwPort("mc33816", engineConfiguration->mc33816_cs);
|
|
|
|
spiCfg.sspad = getHwPin("mc33816", engineConfiguration->mc33816_cs);
|
2019-05-03 18:38:34 -07:00
|
|
|
|
2024-08-07 20:07:06 -07:00
|
|
|
#if HW_MICRO_RUSEFI
|
2019-05-03 18:38:34 -07:00
|
|
|
// hard-coded for now, just resolve the conflict with SD card!
|
|
|
|
engineConfiguration->mc33816spiDevice = SPI_DEVICE_3;
|
2024-08-07 20:07:06 -07:00
|
|
|
#endif
|
|
|
|
|
|
|
|
if (engineConfiguration->mc33816spiDevice == SPI_NONE) {
|
|
|
|
criticalError("mc33816 needs SPI selection");
|
|
|
|
}
|
2019-05-03 18:38:34 -07:00
|
|
|
|
|
|
|
driver = getSpiDevice(engineConfiguration->mc33816spiDevice);
|
2024-08-07 20:07:06 -07:00
|
|
|
if (driver == nullptr) {
|
2019-05-03 18:38:34 -07:00
|
|
|
// error already reported
|
2024-09-23 07:11:03 -07:00
|
|
|
return false;
|
2019-05-03 18:38:34 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
spiStart(driver, &spiCfg);
|
2024-08-08 10:14:23 -07:00
|
|
|
efiPrintf("mc33 started SPI");
|
2019-05-03 18:13:25 -07:00
|
|
|
|
2022-08-08 05:53:08 -07:00
|
|
|
// addConsoleAction("mc33_stats", showStats);
|
2024-08-07 20:47:48 -07:00
|
|
|
addConsoleAction("mc33_restart", [](){
|
|
|
|
pt.initIfNeeded();
|
|
|
|
});
|
2019-06-06 17:12:03 -07:00
|
|
|
|
2024-08-07 20:47:48 -07:00
|
|
|
// todo: too soon to read voltage, it has to fail, right?!
|
2022-08-08 05:53:08 -07:00
|
|
|
initIfNeeded();
|
2024-09-23 07:11:03 -07:00
|
|
|
return true;
|
2020-04-14 16:23:53 -07:00
|
|
|
}
|
|
|
|
|
2023-05-15 13:28:50 -07:00
|
|
|
static bool isInitialized = false;
|
2019-05-03 18:54:38 -07:00
|
|
|
|
2022-08-08 05:53:08 -07:00
|
|
|
void Pt2001::initIfNeeded() {
|
2024-08-24 11:10:16 -07:00
|
|
|
if (!isIgnVoltage()) {
|
|
|
|
isInitialized = false;
|
|
|
|
efiPrintf("unhappy mc33 due to battery voltage");
|
|
|
|
} else {
|
2023-05-15 13:28:50 -07:00
|
|
|
if (!isInitialized) {
|
|
|
|
isInitialized = restart();
|
2023-12-12 13:13:36 -08:00
|
|
|
if (isInitialized) {
|
|
|
|
efiPrintf("happy mc33/PT2001!");
|
2023-12-12 15:24:42 -08:00
|
|
|
} else {
|
2024-08-26 17:17:55 -07:00
|
|
|
efiPrintf("unhappy mc33 fault=%d %s", (int)fault, mcFaultToString(fault));
|
2023-12-12 13:13:36 -08:00
|
|
|
}
|
2020-10-19 19:04:06 -07:00
|
|
|
}
|
2024-08-24 11:10:16 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static THD_WORKING_AREA(mc33_thread_wa, 256);
|
|
|
|
|
|
|
|
static THD_FUNCTION(mc33_driver_thread, p) {
|
|
|
|
(void)p;
|
|
|
|
|
|
|
|
while (true) {
|
|
|
|
if (!isIgnVoltage()) {
|
2024-08-27 16:50:39 -07:00
|
|
|
if (isInitialized) {
|
|
|
|
efiPrintf("Power loss? Would have to re-init mc33/PT2001?");
|
|
|
|
isInitialized = false;
|
|
|
|
}
|
2024-08-24 11:10:16 -07:00
|
|
|
chThdSleepMilliseconds(100);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
pt.initIfNeeded();
|
|
|
|
chThdSleepMilliseconds(100);
|
|
|
|
}
|
2020-10-19 19:04:06 -07:00
|
|
|
}
|
|
|
|
|
2022-08-08 05:53:08 -07:00
|
|
|
void initMc33816() {
|
2024-09-23 07:11:03 -07:00
|
|
|
bool isConfigured = pt.init();
|
|
|
|
if (isConfigured) {
|
|
|
|
chThdCreateStatic(mc33_thread_wa, sizeof(mc33_thread_wa), PRIO_GPIOCHIP, mc33_driver_thread, nullptr);
|
|
|
|
}
|
2022-08-08 05:53:08 -07:00
|
|
|
}
|
|
|
|
|
2019-05-03 18:13:25 -07:00
|
|
|
#endif /* EFI_MC33816 */
|