rusEFI
The most advanced open source ECU
Loading...
Searching...
No Matches
mc33816.cpp
Go to the documentation of this file.
1/*
2 * @file mc33816.cpp
3 *
4 * TL,DR: GDI
5 *
6 * The NXP MC33816 is a programmable gate driver IC for precision solenoid control applications.
7 *
8 *
9 * Useful wires:
10 * 5v, 3(3.3v), Gnd, 12v, VccIO(3v) SPI, DRVEN, RSTB
11 *
12 * For MC33816 vs PT2000 differences see
13 * https://www.nxp.com/docs/en/application-note/AN5203.pdf
14 *
15 * @date May 3, 2019
16 * @author Andrey Belomutskiy, (c) 2012-2020
17 */
18
19#include "pch.h"
20
21#if EFI_MC33816
22
23#include "hardware.h"
24#include "mpu_util.h"
26
27static SPIConfig spiCfg = {
28 .circular = false,
29#ifdef _CHIBIOS_RT_CONF_VER_6_1_
30 .end_cb = NULL,
31#else
32 .slave = false,
33 .data_cb = NULL,
34 .error_cb = NULL,
35#endif
36 .ssport = nullptr,
37 .sspad = 0,
38 .cr1 =
39 SPI_CR1_MSTR |
40 SPI_CR1_SSM | // Software Slave Management, the SSI bit will be internal reference
41 SPI_CR1_SSI | // Internal Slave Select (active low) set High
42 SPI_CR1_CPHA |
43 //SPI_CR1_BR_1 // 5MHz
44 SPI_CR1_BR_0 | SPI_CR1_BR_1 | SPI_CR1_BR_2 |
45 SPI_CR1_SPE,
46 .cr2 = SPI_CR2_SSOE |
47 SPI_CR2_16BIT_MODE
48 };
49
50class Pt2001 : public Pt2001Base {
51public:
52 bool init();
53 void initIfNeeded();
54
55protected:
56 void acquireBus() override {
57 criticalAssertVoid(driver != nullptr, "mc33816");
58 spiAcquireBus(driver);
59 }
60
61 void releaseBus() override {
62 spiReleaseBus(driver);
63 }
64
65 void select() override {
66 criticalAssertVoid(driver != nullptr, "mc33816");
67// revive MC33816 driver, also support bus sharing #6781
68// should be somewhere but not here spiStart(driver, &spiCfg);
69// efiPrintf("mc select %s", hwOnChipPhysicalPinName(driver->config->ssport, driver->config->sspad));
70 spiSelect(driver);
71 //chris - "no implementation on stm32"
72 chipSelect.setValue(0);
73 }
74
75 void deselect() override {
76 spiUnselect(driver);
77 //chris - "no implementation on stm32"
78 chipSelect.setValue(1);
79 }
80
81 uint16_t sendRecv(uint16_t tx) override {
82 return spiPolledExchange(driver, tx);
83 }
84
85 // Send `count` number of 16 bit words from `data`
86 void sendLarge(const uint16_t* data, size_t count) override {
87 spiSend(driver, count, data);
88 }
89
90 // GPIO reset and enable pins
91 void setResetB(bool state) override {
92 resetB.setValue(state);
93 }
94
95 void setDriveEN(bool state) override {
96 driven.setValue(state);
97 }
98
99 // GPIO inputs for various pins we need
100 bool readFlag0() const override {
102 }
103
104 // Get battery voltage - only try to init chip when powered
105 float getVbatt() const override {
106 // reminder that we do not have sensor subsystem right away
107 return Sensor::get(SensorType::BatteryVoltage).value_or(0);
108 }
109
110 // CONFIGURATIONS: currents, timings, voltages
111 float getBoostVoltage() const override {
113 }
114
115 // Currents in amps
116 float getBoostCurrent() const override {
118 }
119
120 float getPeakCurrent() const override {
122 }
123
124 float getHoldCurrent() const override {
126 }
127
128 float getPumpPeakCurrent() const override {
130 }
131
132 float getPumpHoldCurrent() const override {
134 }
135
136 // Timings in microseconds
137 uint16_t getTpeakOff() const override {
139 }
140
141 uint16_t getTpeakTot() const override {
143 }
144
145 uint16_t getTbypass() const override {
147 }
148
149 uint16_t getTholdOff() const override {
151 }
152
153 uint16_t getTHoldTot() const override {
155 }
156
157 uint16_t getTBoostMin() const override {
159 }
160
161 uint16_t getTBoostMax() const override {
163 }
164
165 uint16_t getPumpTholdOff() const override {
167 }
168
169 uint16_t getPumpTholdTot() const override {
171 }
172
173 // Print out an error message
174 void onError(const char* why) override {
175 efiPrintf("PT2001 error: %s", why);
176 }
177
178 bool errorOnUnexpectedFlag() override {
179 efiPrintf("****** unexpected mc33 flag state ******");
180 return false;
181 }
182
183 void sleepMs(size_t ms) override {
184 chThdSleepMilliseconds(ms);
185 }
186
187private:
188 SPIDriver* driver;
189
190 OutputPin resetB;
191 OutputPin driven;
192 OutputPin chipSelect;
193};
194
195static Pt2001 pt;
196
197/**
198 * returns true if chip has configuration
199 */
200bool Pt2001::init() {
201 //
202 // see setTest33816EngineConfiguration for default configuration
203 // Pins
207 return false;
208 }
210 efiSetPadMode("mc33816 flag0", engineConfiguration->mc33816_flag0, getInputMode(PI_DEFAULT));
211 }
212
213 chipSelect.initPin("mc33 CS", engineConfiguration->mc33816_cs /*, &engineConfiguration->csPinMode*/);
214 chipSelect.setValue(1);
215
216 // Initialize the chip via ResetB
217 resetB.initPin("mc33 RESTB", engineConfiguration->mc33816_rstb);
218 // High Voltage via DRIVEN
219 driven.initPin("mc33 DRIVEN", engineConfiguration->mc33816_driven);
220
221 spiCfg.ssport = getHwPort("mc33816", engineConfiguration->mc33816_cs);
222 spiCfg.sspad = getHwPin("mc33816", engineConfiguration->mc33816_cs);
223
224#if HW_MICRO_RUSEFI
225 // hard-coded for now, just resolve the conflict with SD card!
227#endif
228
229 if (engineConfiguration->mc33816spiDevice == SPI_NONE) {
230 criticalError("mc33816 needs SPI selection");
231 }
232
234 if (driver == nullptr) {
235 // error already reported
236 return false;
237 }
238
239 spiStart(driver, &spiCfg);
240 efiPrintf("mc33 started SPI");
241
242 // addConsoleAction("mc33_stats", showStats);
243 addConsoleAction("mc33_restart", [](){
244 pt.initIfNeeded();
245 });
246
247 // todo: too soon to read voltage, it has to fail, right?!
248 initIfNeeded();
249 return true;
250}
251
253
254void Pt2001::initIfNeeded() {
255 if (!gatekeeper.haveVoltage()) {
256 return;
257 }
258
260 gatekeeper.isInitialized = restart();
262 efiPrintf("happy mc33/PT2001!");
263 } else {
264 efiPrintf("unhappy mc33 fault=%d %s", (int)fault, mcFaultToString(fault));
265 }
266 }
267}
268
269static THD_WORKING_AREA(mc33_thread_wa, 256);
270
271static THD_FUNCTION(mc33_driver_thread, p) {
272 (void)p;
273
274 while (true) {
275 pt.initIfNeeded();
276 chThdSleepMilliseconds(100);
277 }
278}
279
281 bool isConfigured = pt.init();
282 if (isConfigured) {
283 chThdCreateStatic(mc33_thread_wa, sizeof(mc33_thread_wa), PRIO_GPIOCHIP, mc33_driver_thread, nullptr);
284 }
285}
286
287#endif /* EFI_MC33816 */
void efiSetPadMode(const char *msg, brain_pin_e brainPin, iomode_t mode)
Single output pin reference and state.
Definition efi_output.h:49
virtual SensorResult get() const =0
void addConsoleAction(const char *token, Void callback)
Register console action without parameters.
ioportid_t getHwPort(const char *msg, brain_pin_e brainPin)
ioportmask_t getHwPin(const char *msg, brain_pin_e brainPin)
static constexpr engine_configuration_s * engineConfiguration
SPIDriver * getSpiDevice(spi_device_e spiDevice)
Definition hardware.cpp:149
iomode_t getInputMode(pin_input_mode_e mode)
Definition io_pins.cpp:103
bool efiReadPin(brain_pin_e pin)
Definition io_pins.cpp:89
static THD_FUNCTION(mc33_driver_thread, p)
Definition mc33816.cpp:271
static SPIConfig spiCfg
Definition mc33816.cpp:27
static THD_WORKING_AREA(mc33_thread_wa, 256)
void initMc33816()
Definition mc33816.cpp:280
static IgnVoltageGatekeeper gatekeeper
Definition mc33816.cpp:252
static Pt2001 pt
Definition mc33816.cpp:195
bool isBrainPinValid(brain_pin_e brainPin)
state("state", SensorCategory.SENSOR_INPUTS, FieldType.INT8, 1871, 1.0, -1.0, -1.0, "")
uint16_t count
Definition tunerstudio.h:1