rusefi/firmware/controllers/system/efi_gpio.h

254 lines
6.5 KiB
C
Raw Normal View History

2015-07-10 06:01:56 -07:00
/**
2019-03-29 06:11:13 -07:00
* @file efi_gpio.h
2017-04-21 10:36:51 -07:00
* @brief EFI-related GPIO code
*
2015-07-10 06:01:56 -07:00
*
* @date Sep 26, 2014
2020-01-07 21:02:40 -08:00
* @author Andrey Belomutskiy, (c) 2012-2020
2015-07-10 06:01:56 -07:00
*/
#pragma once
2015-07-10 06:01:56 -07:00
2018-09-16 19:26:57 -07:00
#include "global.h"
#include "io_pins.h"
2019-09-19 18:41:52 -07:00
#include "engine_configuration.h"
2020-04-06 11:13:29 -07:00
#include "smart_gpio.h"
2015-07-10 06:01:56 -07:00
void initPrimaryPins();
void initOutputPins();
2017-04-21 10:36:51 -07:00
2019-04-12 19:07:03 -07:00
#if EFI_GPIO_HARDWARE
2017-04-21 10:36:51 -07:00
void turnAllPinsOff(void);
2017-04-21 12:14:37 -07:00
#else /* EFI_GPIO_HARDWARE */
2017-04-21 10:36:51 -07:00
#define turnAllPinsOff() {}
2017-04-21 12:14:37 -07:00
#endif /* EFI_GPIO_HARDWARE */
// Used if you want a function to be virtual only for unit testing purposes
#if EFI_UNIT_TEST
#define TEST_VIRTUAL virtual
#else
#define TEST_VIRTUAL
#endif
2019-04-04 16:56:03 -07:00
#ifdef __cplusplus
2017-04-21 12:14:37 -07:00
/**
* @brief Single output pin reference and state
*/
class OutputPin {
public:
OutputPin();
2017-07-10 18:41:13 -07:00
/**
* initializes pin & registers it in pin repository
2020-05-15 15:08:11 -07:00
* outputMode being a pointer allow us to change configuration (for example invert logical pin) in configuration and get resuts applied
* away, or at least I hope that's why
2017-07-10 18:41:13 -07:00
*/
void initPin(const char *msg, brain_pin_e brainPin, const pin_output_mode_e *outputMode, bool forceInitWithFatalError = false);
2017-07-10 18:41:13 -07:00
/**
* same as above, with DEFAULT_OUTPUT mode
*/
void initPin(const char *msg, brain_pin_e brainPin);
2017-07-10 18:41:13 -07:00
/**
2017-07-10 19:05:40 -07:00
* dissociates pin from this output and un-registers it in pin repository
2017-07-10 18:41:13 -07:00
*/
void deInit();
2017-07-10 18:41:13 -07:00
2017-04-21 12:14:37 -07:00
bool isInitialized();
2017-07-10 18:41:13 -07:00
2020-03-30 22:06:19 -07:00
bool getAndSet(int logicValue);
TEST_VIRTUAL void setValue(int logicValue);
2018-01-28 08:08:37 -08:00
void toggle();
bool getLogicValue() const;
2017-07-10 18:34:31 -07:00
2019-04-12 19:07:03 -07:00
#if EFI_GPIO_HARDWARE
ioportid_t port = 0;
uint8_t pin = 0;
2017-04-21 13:52:02 -07:00
#endif /* EFI_GPIO_HARDWARE */
brain_pin_e brainPin = GPIO_UNASSIGNED;
#if (EFI_GPIO_HARDWARE && (BOARD_EXT_GPIOCHIPS > 0))
/* used for external pins */
bool ext = false;
#endif /* EFI_GPIO_HARDWARE */
int8_t currentLogicValue = INITIAL_PIN_STATE;
2017-04-21 12:14:37 -07:00
/**
* we track current pin status so that we do not touch the actual hardware if we want to write new pin bit
* which is same as current pin value. This maybe helps in case of status leds, but maybe it's a total over-engineering
*/
2017-07-10 19:05:40 -07:00
private:
// todo: inline this method?
2019-01-16 05:24:37 -08:00
void setDefaultPinState(const pin_output_mode_e *defaultState);
2020-12-10 16:18:14 -08:00
void setOnchipValue(int electricalValue);
2017-07-10 19:05:40 -07:00
// 4 byte pointer is a bit of a memory waste here
const pin_output_mode_e *modePtr = nullptr;
2017-04-21 12:14:37 -07:00
};
2020-11-09 16:47:10 -08:00
/**
* OutputPin which is reported on Engine Sniffer
*/
class NamedOutputPin : public virtual OutputPin, public EnginePtr {
2015-07-10 06:01:56 -07:00
public:
NamedOutputPin();
explicit NamedOutputPin(const char *name);
2017-04-21 16:23:20 -07:00
void setHigh();
void setLow();
const char *getName() const;
const char *getShortName() const;
2016-11-03 20:02:58 -07:00
/**
* @return true if pin was stopped
*/
bool stop();
2017-01-06 08:02:49 -08:00
// todo: char pointer is a bit of a memory waste here, we can reduce RAM usage by software-based getName() method
const char *name = nullptr;
/**
* rusEfi Engine Sniffer protocol uses these short names to reduce bytes usage
*/
const char *shortName = nullptr;
2015-07-10 06:01:56 -07:00
};
2020-07-18 23:03:12 -07:00
class InjectorOutputPin final : public NamedOutputPin {
2016-09-03 21:03:27 -07:00
public:
InjectorOutputPin();
void reset();
2020-07-18 23:03:12 -07:00
void open(efitick_t nowNt);
void close(efitick_t nowNt);
2020-07-18 23:03:12 -07:00
2020-07-20 03:29:43 -07:00
int8_t getOverlappingCounter() const { return overlappingCounter; }
2020-01-10 20:24:17 -08:00
// todo: re-implement this injectorIndex via address manipulation to reduce memory usage?
2017-01-06 08:02:49 -08:00
int8_t injectorIndex;
2020-07-18 23:03:12 -07:00
private:
2017-01-06 08:02:49 -08:00
int8_t overlappingCounter;
2016-09-03 21:03:27 -07:00
};
2016-10-31 19:02:12 -07:00
class IgnitionOutputPin : public NamedOutputPin {
public:
IgnitionOutputPin();
void reset();
2016-11-01 20:01:54 -07:00
int signalFallSparkId;
bool outOfOrder; // https://sourceforge.net/p/rusefi/tickets/319/
2016-10-31 19:02:12 -07:00
};
2020-11-09 16:47:10 -08:00
/**
* OutputPin with semi-automated init/deinit on configuration change
*/
class RegisteredOutputPin : public virtual OutputPin {
public:
RegisteredOutputPin(const char *registrationName, short pinOffset, short pinModeOffset);
void init();
void unregister();
RegisteredOutputPin *next;
const char *registrationName;
private:
short pinOffset;
short pinModeOffset;
bool isPinConfigurationChanged();
};
class RegisteredNamedOutputPin : public RegisteredOutputPin, public NamedOutputPin {
public:
RegisteredNamedOutputPin(const char *name, short pinOffset, short pinModeOffset);
};
class EnginePins : public EnginePtr {
2016-09-06 21:02:11 -07:00
public:
2016-11-03 20:02:58 -07:00
EnginePins();
2021-07-09 14:02:25 -07:00
void startPins();
2016-11-01 06:02:29 -07:00
void reset();
static void debug();
2016-11-03 20:02:58 -07:00
bool stopPins();
2021-07-09 14:02:25 -07:00
void unregisterPins();
RegisteredOutputPin mainRelay;
2020-11-03 10:19:56 -08:00
/**
* High Pressure Fuel Pump valve control
*/
2020-11-09 18:41:13 -08:00
RegisteredNamedOutputPin hpfpValve;
2020-03-24 22:28:37 -07:00
// this one cranks engine
RegisteredOutputPin starterControl;
2020-11-02 20:52:26 -08:00
// this one prevents driver from cranking engine
RegisteredOutputPin starterRelayDisable;
2020-03-24 22:28:37 -07:00
RegisteredOutputPin fanRelay;
RegisteredOutputPin fanRelay2;
2019-09-08 13:45:02 -07:00
// see acRelayPin
RegisteredOutputPin acRelay;
RegisteredOutputPin fuelPumpRelay;
2015-07-10 06:01:56 -07:00
OutputPin o2heater;
2017-01-30 03:02:53 -08:00
/**
* brain board RED LED by default
*/
2017-02-24 16:42:34 -08:00
OutputPin errorLedPin;
2018-07-26 12:51:06 -07:00
OutputPin communicationLedPin; // blue LED on brain board by default
OutputPin warningLedPin; // orange LED on brain board by default
OutputPin runningLedPin; // green LED on brain board by default
2017-02-24 16:42:34 -08:00
OutputPin debugTriggerSync;
RegisteredOutputPin boostPin;
RegisteredOutputPin idleSolenoidPin;
RegisteredOutputPin secondIdleSolenoidPin;
RegisteredOutputPin alternatorPin;
2017-01-30 03:02:53 -08:00
/**
* this one is usually on the gauge cluster, not on the ECU
*/
RegisteredOutputPin checkEnginePin;
2017-11-26 19:30:37 -08:00
RegisteredNamedOutputPin tachOut;
2017-11-26 19:30:37 -08:00
RegisteredOutputPin triggerDecoderErrorPin;
2016-09-14 16:03:00 -07:00
OutputPin sdCsPin;
2017-08-27 21:08:37 -07:00
OutputPin accelerometerCs;
2016-09-13 21:03:14 -07:00
InjectorOutputPin injectors[MAX_CYLINDER_COUNT];
IgnitionOutputPin coils[MAX_CYLINDER_COUNT];
IgnitionOutputPin trailingCoils[MAX_CYLINDER_COUNT];
2017-11-26 19:30:37 -08:00
NamedOutputPin auxValve[AUX_DIGITAL_VALVE_COUNT];
2020-12-22 11:03:54 -08:00
OutputPin tcuSolenoids[TCU_SOLENOID_COUNT];
private:
2021-07-09 14:02:25 -07:00
void startInjectionPins();
void startIgnitionPins();
void startAuxValves();
2021-07-09 14:02:25 -07:00
void stopInjectionPins();
void stopIgnitionPins();
void stopAuxValves();
2016-09-06 21:02:11 -07:00
};
2015-07-10 06:01:56 -07:00
2019-04-04 16:56:03 -07:00
#endif /* __cplusplus */
2015-07-10 06:01:56 -07:00
/**
* it's a macro to be sure that stack is not used
* @return 0 for OM_DEFAULT and OM_OPENDRAIN
*/
#define getElectricalValue0(mode) ((mode) == OM_INVERTED || (mode) == OM_OPENDRAIN_INVERTED)
/**
* it's a macro to be sure that stack is not used
* @return 1 for OM_DEFAULT and OM_OPENDRAIN
*/
#define getElectricalValue1(mode) ((mode) == OM_DEFAULT || (mode) == OM_OPENDRAIN)
#define getElectricalValue(logicalValue, mode) \
(logicalValue ? getElectricalValue1(mode) : getElectricalValue0(mode))
2019-04-12 19:07:03 -07:00
#if EFI_GPIO_HARDWARE
2017-04-21 14:38:13 -07:00
2019-04-04 16:56:03 -07:00
EXTERNC ioportmask_t getHwPin(const char *msg, brain_pin_e brainPin);
EXTERNC ioportid_t getHwPort(const char *msg, brain_pin_e brainPin);
2017-04-21 13:20:06 -07:00
const char *portname(ioportid_t GPIOx);
2017-04-21 09:31:17 -07:00
2017-04-21 13:20:06 -07:00
#endif /* EFI_GPIO_HARDWARE */
void printSpiConfig(const char *msg, spi_device_e device);
2017-04-21 13:20:06 -07:00
brain_pin_e parseBrainPin(const char *str);
const char *hwPortname(brain_pin_e brainPin);
extern EnginePins enginePins;