rusEFI
The most advanced open source ECU
Loading...
Searching...
No Matches
Public Member Functions | Data Fields | Private Member Functions | Private Attributes
OutputPin Class Reference

Single output pin reference and state. More...

#include <efi_output.h>

Inheritance diagram for OutputPin:
Inheritance graph
[legend]
Collaboration diagram for OutputPin:
Collaboration graph
[legend]

Public Member Functions

void initPin (const char *msg, brain_pin_e brainPin, pin_output_mode_e outputMode, bool forceInitWithFatalError=false)
 
void initPin (const char *msg, brain_pin_e brainPin)
 
void deInit ()
 
bool isInitialized () const
 
bool getAndSet (int logicValue)
 
void setValue (const char *msg, int logicValue, bool isForce=false)
 
TEST_VIRTUAL void setValue (int logicValue, bool isForce=false)
 
void toggle ()
 
bool getLogicValue () const
 
brain_pin_diag_e getDiag () const
 
void resetToggleStats ()
 

Data Fields

ioportid_t m_port = 0
 
uint8_t m_pin = 0
 
int pinToggleCounter = 0
 
Timer pinToggleTimer
 
uint32_t durationsInStateMs [2]
 
brain_pin_e brainPin = Gpio::Unassigned
 
bool ext = false
 
int8_t currentLogicValue = INITIAL_PIN_STATE
 

Private Member Functions

void setDefaultPinState (pin_output_mode_e mode)
 
void setOnchipValue (int electricalValue)
 

Private Attributes

pin_output_mode_e mode = OM_DEFAULT
 

Detailed Description

Single output pin reference and state.

Definition at line 49 of file efi_output.h.

Member Function Documentation

◆ deInit()

void OutputPin::deInit ( )

Definition at line 803 of file efi_gpio.cpp.

803 {
804 efiPrintf("unregistering %s", hwPortname(brainPin));
805
806 // Unregister under lock - we don't want other threads mucking with the pin while we're trying to turn it off
807 chibios_rt::CriticalSectionLocker csl;
808
809 // nothing to do if not registered in the first place
811 return;
812 }
813
814#if (BOARD_EXT_GPIOCHIPS > 0)
815 ext = false;
816#endif // (BOARD_EXT_GPIOCHIPS > 0)
817
818#if EFI_GPIO_HARDWARE && EFI_PROD_CODE
820#endif /* EFI_GPIO_HARDWARE */
821
822 // Clear the pin so that it won't get set any more
824}
brain_pin_e brainPin
Definition efi_output.h:86
@ Unassigned
void efiSetPadUnused(brain_pin_e brainPin)
Definition io_pins.cpp:20
const char * hwPortname(brain_pin_e brainPin)
bool isBrainPinValid(brain_pin_e brainPin)

Referenced by initPin(), luaDeInitPins(), stopTriggerEmulatorPins(), stopVvtControlPins(), and RegisteredOutputPin::unregister().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ getAndSet()

bool OutputPin::getAndSet ( int  logicValue)

Definition at line 576 of file efi_gpio.cpp.

576 {
577 bool oldValue = getLogicValue();
578 setValue(logicValue);
579 return oldValue;
580}
bool getLogicValue() const
Definition efi_gpio.cpp:668
void setValue(const char *msg, int logicValue, bool isForce=false)
Definition efi_gpio.cpp:605

Referenced by disengageStarterIfNeeded(), and doStartCranking().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ getDiag()

brain_pin_diag_e OutputPin::getDiag ( ) const

Definition at line 679 of file efi_gpio.cpp.

679 {
680#if EFI_PROD_CODE
681#if BOARD_EXT_GPIOCHIPS > 0
684 }
685#endif
686#endif /* EFI_PROD_CODE */
687 // TODO: add hook to board code for custom diagnostic, like it is done on S105
688 return PIN_UNKNOWN;
689}
brain_pin_diag_e gpiochips_getDiag(brain_pin_e pin)
Get diagnostic for given gpio.
Definition core.cpp:381
bool brain_pin_is_onchip(brain_pin_e brainPin)

Referenced by benchOff(), and SensorChecker::onSlowCallback().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ getLogicValue()

bool OutputPin::getLogicValue ( ) const

Definition at line 668 of file efi_gpio.cpp.

668 {
669 // Compare against 1 since it could also be INITIAL_PIN_STATE (which means logical 0, but we haven't initialized the pin yet)
670 return currentLogicValue == 1;
671}
int8_t currentLogicValue
Definition efi_output.h:93

Referenced by canDashboardHaltech(), configureRusefiLuaHooks(), getAndSet(), getHellenBoardEnabled(), IdleController::getIdlePosition(), IdleController::getRunningOpenLoop(), populateFrame(), slowStartStopButtonCallback(), NamedOutputPin::stop(), toggle(), updateFlags(), and updateTunerStudioState().

Here is the caller graph for this function:

◆ initPin() [1/2]

void OutputPin::initPin ( const char msg,
brain_pin_e  brainPin 
)

Definition at line 708 of file efi_gpio.cpp.

708 {
709 initPin(p_msg, p_brainPin, OM_DEFAULT);
710}
void initPin(const char *msg, brain_pin_e brainPin, pin_output_mode_e outputMode, bool forceInitWithFatalError=false)
Definition efi_gpio.cpp:712
Here is the call graph for this function:

◆ initPin() [2/2]

void OutputPin::initPin ( const char msg,
brain_pin_e  brainPin,
pin_output_mode_e  outputMode,
bool  forceInitWithFatalError = false 
)

Definition at line 712 of file efi_gpio.cpp.

712 {
713#if EFI_UNIT_TEST
715#endif
716
717 if (!isBrainPinValid(p_brainPin)) {
718 return;
719 }
720
721 // Enter a critical section so that other threads can't change the pin state out from underneath us
722 chibios_rt::CriticalSectionLocker csl;
723
724 if (!forceInitWithFatalError && hasFirmwareError()) {
725 // Don't allow initializing more pins if we have a fatal error.
726 // Pins should have just been reset, so we shouldn't try to init more.
727 return;
728 }
729
730 // Check that this OutputPin isn't already assigned to another pin (reinit is allowed to change mode)
731 // To avoid this error, call deInit() first
732 if (isBrainPinValid(brainPin) && brainPin != p_brainPin) {
733 firmwareError(ObdCode::CUSTOM_OBD_PIN_CONFLICT, "outputPin [%s] already assigned, cannot reassign without unregister first", msg);
734 return;
735 }
736
737 if (outputMode > OM_OPENDRAIN_INVERTED) {
738 firmwareError(ObdCode::CUSTOM_INVALID_MODE_SETTING, "%s invalid pin_output_mode_e %d %s",
739 msg,
740 outputMode,
741 hwPortname(p_brainPin)
742 );
743 return;
744 }
745
746#if EFI_GPIO_HARDWARE && EFI_PROD_CODE
747 iomode_t l_mode = (outputMode == OM_DEFAULT || outputMode == OM_INVERTED) ?
748 PAL_MODE_OUTPUT_PUSHPULL : PAL_MODE_OUTPUT_OPENDRAIN;
749
750 #if (BOARD_EXT_GPIOCHIPS > 0)
751 this->ext = false;
752 #endif
753 if (brain_pin_is_onchip(p_brainPin)) {
754 m_port = getHwPort(msg, p_brainPin);
755 m_pin = getHwPin(msg, p_brainPin);
756
757 // Validate port
758 if (!m_port) {
759 criticalError("OutputPin::initPin got invalid port for pin idx %d", static_cast<int>(p_brainPin));
760 return;
761 }
762 }
763 #if (BOARD_EXT_GPIOCHIPS > 0)
764 else {
765 this->ext = true;
766 }
767 #endif
768#endif // briefly leave the include guard because we need to set default state in tests
769
770 brainPin = p_brainPin;
771
772 // The order of the next two calls may look strange, which is a good observation.
773 // We call them in this order so that the pin is set to a known state BEFORE
774 // it's enabled. Enabling the pin then setting it could result in a (brief)
775 // mystery state being driven on the pin (potentially dangerous).
776 setDefaultPinState(outputMode);
777
778#if EFI_GPIO_HARDWARE && EFI_PROD_CODE
779 efiSetPadMode(msg, brainPin, l_mode);
781 // todo: handle OM_OPENDRAIN and OM_OPENDRAIN_INVERTED as well
782 if (outputMode == OM_DEFAULT || outputMode == OM_INVERTED) {
783#ifndef DISABLE_PIN_STATE_VALIDATION
784 int actualValue = palReadPad(m_port, m_pin);
785 // we had enough drama with pin configuration in board.h and else that we shall self-check
786
787 const int logicalValue =
788 (outputMode == OM_INVERTED)
789 ? !actualValue
790 : actualValue;
791
792 // if the pin was set to logical 1, then set an error and disable the pin so that things don't catch fire
793 if (logicalValue) {
794 criticalError("HARDWARE VALIDATION FAILED %s: unexpected startup pin state %s actual value=%d logical value=%d mode=%s", msg, hwPortname(brainPin), actualValue, logicalValue, getPin_output_mode_e(outputMode));
796 }
797#endif
798 }
799 }
800#endif /* EFI_GPIO_HARDWARE */
801}
const char * getPin_output_mode_e(pin_output_mode_e value)
void efiSetPadMode(const char *msg, brain_pin_e brainPin, iomode_t mode)
void deInit()
Definition efi_gpio.cpp:803
ioportid_t m_port
Definition efi_output.h:71
int pinToggleCounter
Definition efi_output.h:76
uint8_t m_pin
Definition efi_output.h:72
void setDefaultPinState(pin_output_mode_e mode)
Definition efi_gpio.cpp:673
ioportid_t getHwPort(const char *msg, brain_pin_e brainPin)
ioportmask_t getHwPin(const char *msg, brain_pin_e brainPin)
void firmwareError(ObdCode code, const char *fmt,...)
uint32_t iomode_t
Digital I/O modes.
Definition hal_pal_lld.h:83
@ CUSTOM_INVALID_MODE_SETTING
@ CUSTOM_OBD_PIN_CONFLICT

Referenced by alphax_2chan_boardInitHardware(), alphax_4chan_boardInitHardware(), alphax_4kGDI_boardInitHardware(), alphax_8chan_boardInitHardware(), alphax_8chan_reva_boardInitHardware(), alphax_gold_boardInitHardware(), alphax_silver_boardInitHardware(), alphax_silver_revA_boardInitHardware(), board_init_ext_gpios(), configureHellenCanTerminator(), hellen154hyundai_f7_boardInitHardware(), hellenMegaAccelerometerPreInitCS2Pin(), RegisteredOutputPin::init(), SimpleTransmissionController::init(), Generic4TransmissionController::init(), Gm4l6xTransmissionController::init(), initAccelerometer(), initErrorLed(), initGpPwm(), StepDirectionStepper::initialize(), initMiscOutputPins(), initPin(), initStatusLeds(), initWarningRunningPins(), nm_bus_init(), portInitAdc(), setHellenEnPin(), DcHardware::start(), EnginePins::startAuxValves(), EnginePins::startIgnitionPins(), EnginePins::startInjectionPins(), startSimplePwmExt(), startSmartCsPins(), and startTriggerEmulatorPins().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ isInitialized()

bool OutputPin::isInitialized ( ) const

Definition at line 560 of file efi_gpio.cpp.

560 {
561#if EFI_GPIO_HARDWARE && EFI_PROD_CODE
562#if (BOARD_EXT_GPIOCHIPS > 0)
563 if (ext)
564 return true;
565#endif /* (BOARD_EXT_GPIOCHIPS > 0) */
566 return m_port != NULL;
567#else /* EFI_GPIO_HARDWARE */
568 return true;
569#endif /* EFI_GPIO_HARDWARE */
570}

Referenced by assertPinAssigned(), hellenMegaAccelerometerPreInitCS2Pin(), initAccelerometer(), isGdiEngine(), HpfpController::onFastCallback(), HpfpController::scheduleNextCycle(), NamedOutputPin::stop(), and InjectionEvent::update().

Here is the caller graph for this function:

◆ resetToggleStats()

void OutputPin::resetToggleStats ( )

Definition at line 599 of file efi_gpio.cpp.

599 {
602}
uint32_t durationsInStateMs[2]
Definition efi_output.h:81

Referenced by resetPinStats().

Here is the caller graph for this function:

◆ setDefaultPinState()

void OutputPin::setDefaultPinState ( pin_output_mode_e  mode)
private

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

Definition at line 673 of file efi_gpio.cpp.

673 {
674 assertOMode(mode);
675 this->mode = outputMode;
676 setValue(false, /*force*/true); // initial state
677}
pin_output_mode_e mode
Definition efi_output.h:104

Referenced by initPin().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ setOnchipValue()

void OutputPin::setOnchipValue ( int  electricalValue)
private

Definition at line 584 of file efi_gpio.cpp.

584 {
586 // todo: make 'setOnchipValue' or 'reportsetOnchipValueError' virtual and override for NamedOutputPin?
587 warning(ObdCode::CUSTOM_ERR_6586, "attempting to change unassigned pin");
588 return;
589 }
590 palWritePad(m_port, m_pin, electricalValue);
591}
@ Invalid
bool warning(ObdCode code, const char *fmt,...)
@ CUSTOM_ERR_6586

Referenced by setValue().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ setValue() [1/2]

void OutputPin::setValue ( const char msg,
int  logicValue,
bool  isForce = false 
)

Definition at line 605 of file efi_gpio.cpp.

605 {
606 UNUSED(msg);
607 if ((isHwQcMode() || getOutputOnTheBenchTest() == this) && !isForce) {
608 return;
609 }
610
611#if ENABLE_PERF_TRACE
612// todo: https://github.com/rusefi/rusefi/issues/1638
613// ScopePerf perf(PE::OutputPinSetValue);
614#endif // ENABLE_PERF_TRACE
615
616#if EFI_UNIT_TEST
617 if (currentLogicValue != logicValue) {
619 }
620#endif // EFI_UNIT_TEST
621
622#if EFI_SIMULATOR
623 if (currentLogicValue != logicValue) {
624 if (pinToggleCounter > 0) {
626 durationsInStateMs[1] = pinToggleTimer.getElapsedUs() / 1000;
627 }
629 pinToggleTimer.reset();
630 }
631#endif // EFI_SIMULATOR
632
633#if EFI_UNIT_TEST
634 if (verboseMode) {
635 efiPrintf("pin goes %d", logicValue);
636 }
637#endif // EFI_UNIT_TEST
638
639 // Always store the current logical value of the pin (so it can be
640 // used internally even if not connected to a real hardware pin)
641 currentLogicValue = logicValue;
642
643 // Nothing else to do if not configured
645 return;
646 }
647
648 efiAssertVoid(ObdCode::CUSTOM_ERR_6622, mode <= OM_OPENDRAIN_INVERTED, "invalid pin_output_mode_e");
649 int electricalValue = getElectricalValue(logicValue, mode);
650
651#if EFI_PROD_CODE
652 #if (BOARD_EXT_GPIOCHIPS > 0)
653 if (!this->ext) {
654 setOnchipValue(electricalValue);
655 } else {
656 /* external pin */
657 gpiochips_writePad(this->brainPin, logicValue);
658 /* TODO: check return value */
659 }
660 #else
661 setOnchipValue(electricalValue);
662 #endif
663#else /* EFI_PROD_CODE */
664 setMockState(brainPin, electricalValue);
665#endif /* EFI_PROD_CODE */
666}
const OutputPin * getOutputOnTheBenchTest()
bool isHwQcMode()
Timer pinToggleTimer
Definition efi_output.h:80
void setOnchipValue(int electricalValue)
Definition efi_gpio.cpp:584
int gpiochips_writePad(brain_pin_e pin, int value)
Set value to gpio of gpiochip.
Definition core.cpp:336
void setMockState(brain_pin_e pin, bool state)
Definition io_pins.cpp:132
UNUSED(samplingTimeSeconds)
@ CUSTOM_ERR_6622
bool verboseMode

Referenced by alphax_4kGDI_boardInitHardware(), alphax_gold_OnConfigurationChange(), applyPinState(), PwmConfig::applyPwmValue(), benchOff(), benchOn(), blink_digits(), board_init_ext_gpios(), configureHellenCanTerminator(), customBoardOnConfigurationChange(), TwoPinDcMotor::disable(), TwoPinDcMotor::enable(), errorHandlerWriteReportFile(), firmwareErrorV(), getAndSet(), hellen154hyundai_f7_boardInitHardware(), hellenMegaAccelerometerPreInitCS2Pin(), StepDirectionStepper::initialize(), nm_bus_init(), AcController::onSlowCallback(), HarleyAcr::onSlowCallback(), MainRelayController::onSlowCallback(), NitrousController::onSlowCallback(), FuelPumpController::onSlowCallback(), VvlController::onSlowCallback(), Engine::OnTriggerSynchronization(), Engine::periodicSlowCallback(), StepDirectionStepper::pulse(), readSlowAnalogInputs(), InjectorOutputPin::reset(), TwoPinDcMotor::set(), setDefaultPinState(), StepDirectionStepper::setDirection(), setHellenEnValue(), NamedOutputPin::setHigh(), NamedOutputPin::setLow(), GppwmChannel::setOutput(), PwmWrapper::setSimplePwmDutyCycle(), Generic4TransmissionController::setTccState(), setValue(), slowAdcEndCB(), DcHardware::start(), startSmartCsPins(), NamedOutputPin::stop(), toggle(), turnAllPinsOff(), and SimpleTransmissionController::update().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ setValue() [2/2]

void OutputPin::setValue ( int  logicValue,
bool  isForce = false 
)

Definition at line 594 of file efi_gpio.cpp.

594 {
595 setValue(nullptr, logicValue, isForce);
596}
Here is the call graph for this function:

◆ toggle()

void OutputPin::toggle ( )

Definition at line 572 of file efi_gpio.cpp.

572 {
573 setValue("toggle", !getLogicValue());
574}

Referenced by TriggerDecoderBase::decodeTriggerEvent().

Here is the call graph for this function:
Here is the caller graph for this function:

Field Documentation

◆ brainPin

brain_pin_e OutputPin::brainPin = Gpio::Unassigned

◆ currentLogicValue

int8_t OutputPin::currentLogicValue = INITIAL_PIN_STATE

◆ durationsInStateMs

uint32_t OutputPin::durationsInStateMs[2]

Definition at line 81 of file efi_output.h.

Referenced by resetToggleStats(), runBench(), and setValue().

◆ ext

bool OutputPin::ext = false

Definition at line 90 of file efi_output.h.

Referenced by deInit(), initPin(), isInitialized(), and setValue().

◆ m_pin

uint8_t OutputPin::m_pin = 0

Definition at line 72 of file efi_output.h.

Referenced by initPin(), nm_bus_init(), and setOnchipValue().

◆ m_port

ioportid_t OutputPin::m_port = 0

Definition at line 71 of file efi_output.h.

Referenced by initPin(), isInitialized(), nm_bus_init(), and setOnchipValue().

◆ mode

pin_output_mode_e OutputPin::mode = OM_DEFAULT
private

Definition at line 104 of file efi_output.h.

Referenced by setDefaultPinState(), and setValue().

◆ pinToggleCounter

int OutputPin::pinToggleCounter = 0

Definition at line 76 of file efi_output.h.

Referenced by initPin(), resetToggleStats(), runBench(), and setValue().

◆ pinToggleTimer

Timer OutputPin::pinToggleTimer

Definition at line 80 of file efi_output.h.

Referenced by setValue().


The documentation for this class was generated from the following files: