rusEFI
The most advanced open source ECU
Loading...
Searching...
No Matches
idle_hardware.cpp
Go to the documentation of this file.
1/**
2 * @file idle_hardware.cpp
3 * @brief Idle Air Control valve hardware
4 *
5 * @date November 3, 2020
6 *
7 * This is just the hardware interface - deciding where to put the valve happens in idle_thread.cpp
8 */
9
10#include "pch.h"
11
12#if EFI_IDLE_CONTROL
13#include "idle_hardware.h"
14
15#include "electronic_throttle.h"
16
17#include "dc_motors.h"
18#if ! EFI_UNIT_TEST
19#include "stepper.h"
20/* Storing two following structs in CCM memory cause HardFault (at least on F4)
21 * This need deep debuging. Until it is moved out of CMM. */
22static StepDirectionStepper iacStepperHw /*CCM_OPTIONAL*/;
23static DualHBridgeStepper iacHbridgeHw /*CCM_OPTIONAL*/;
25#endif /* EFI_UNIT_TEST */
26
27static SimplePwm idleSolenoidOpen("idle open");
28static SimplePwm idleSolenoidClose("idle close");
29
31 /**
32 * currently idle level is an percent value (0-100 range), and PWM takes a float in the 0..1 range
33 * todo: unify?
34 */
35 float duty = PERCENT_TO_DUTY(position);
36
37#if EFI_ELECTRONIC_THROTTLE_BODY
38 setEtbIdlePosition(position);
39#endif // EFI_ELECTRONIC_THROTTLE_BODY
40
41#if EFI_UNIT_TEST
42 if (false) {
43#endif // EFI_UNIT_TEST
44
45#if ! EFI_UNIT_TEST
47 iacMotor.setTargetPosition(duty * engineConfiguration->idleStepperTotalSteps);
48#endif /* EFI_UNIT_TEST */
49 } else {
50 // if not spinning or running a bench test, turn off the idle valve(s) to be quieter and save power
51#if EFI_SHAFT_POSITION_INPUT
55 return;
56 }
57#endif // EFI_SHAFT_POSITION_INPUT
58
61 } else {
62 // use 0.01..0.99 range
63 float idle_range = 0.98; // move to config?
64
65 float idle_open = 0.01 + idle_range * duty;
66 float idle_close = 0.01 + idle_range * (1.0 - duty);
67
70 }
71 }
72}
73
74#if !EFI_UNIT_TEST
75
77 return isConfigurationChanged(stepperEnablePin) ||
78 isConfigurationChanged(stepperEnablePinMode) ||
79 isConfigurationChanged(idle.stepperStepPin) ||
80 isConfigurationChanged(idle.solenoidFrequency) ||
81 isConfigurationChanged(useStepperIdle) ||
82 isConfigurationChanged(idle.solenoidPin) ||
83 isConfigurationChanged(secondSolenoidPin) ||
84 isConfigurationChanged(useRawOutputToDriveIdleStepper) ||
85 isConfigurationChanged(stepper_raw_output[0]) ||
86 isConfigurationChanged(stepper_raw_output[1]) ||
87 isConfigurationChanged(stepper_raw_output[2]) ||
88 isConfigurationChanged(stepper_raw_output[3]);
89}
90
91bool isIdleMotorBusy() {
93 // todo: check other motor types?
94 return false;
95 }
96 return iacMotor.isBusy();
97}
98
99void initIdleHardware() {
101 StepperHw* hw;
102
104 // four Push-Pull outputs to directly drive stepper idle air valve coils
106 engineConfiguration->stepper_raw_output[1], ETB_COUNT + 0);
108 engineConfiguration->stepper_raw_output[3], ETB_COUNT + 1);
109
111 motorA,
112 motorB,
114 );
115
116 hw = &iacHbridgeHw;
118 auto motorA = initDcMotor("DC dis-1", engineConfiguration->stepperDcIo[0],
120 auto motorB = initDcMotor("DC dis-2", engineConfiguration->stepperDcIo[1],
122
124 motorA,
125 motorB,
127 );
128
129 hw = &iacHbridgeHw;
130 } else {
131 // like DRV8825?
139 );
140
141 hw = &iacStepperHw;
142 }
143
146 // we are here for single or double solenoid idle
147
148 /**
149 * Start PWM for idleValvePin
150 */
151 // todo: even for double-solenoid mode we can probably use same single SimplePWM
152 startSimplePwm(&idleSolenoidOpen, "Idle Valve Open",
156
159 criticalError("Second idle pin should be configured for double solenoid mode.");
160 return;
161 }
162
163 startSimplePwm(&idleSolenoidClose, "Idle Valve Close",
167 }
168 }
169}
170
171#endif
172
173#endif // EFI_IDLE_HARDWARE
void initialize(DcMotor *motorPhaseA, DcMotor *motorPhaseB, float reactionTime)
TriggerCentral triggerCentral
Definition engine.h:318
SingleTimerExecutor scheduler
Definition engine.h:271
efitimeus_t timeToStopIdleTest
Definition engine.h:351
RegisteredOutputPin secondIdleSolenoidPin
Definition efi_gpio.h:113
RegisteredOutputPin idleSolenoidPin
Definition efi_gpio.h:112
void setSimplePwmDutyCycle(float dutyCycle) override
void initialize(brain_pin_e stepPin, brain_pin_e directionPin, pin_output_mode_e directionPinMode, float reactionTime, brain_pin_e enablePin, pin_output_mode_e enablePinMode)
Definition stepper.cpp:217
bool engineMovedRecently(efitick_t nowNt) const
DcMotor * initDcMotor(const char *disPinMsg, const dc_io &io, size_t index, bool useTwoWires)
Definition dc_motors.cpp:90
EnginePins enginePins
Definition efi_gpio.cpp:24
void setEtbIdlePosition(percent_t pos)
static EngineAccessor engine
Definition engine.h:413
static constexpr persistent_config_s * config
static constexpr engine_configuration_s * engineConfiguration
static DualHBridgeStepper iacHbridgeHw
static StepDirectionStepper iacStepperHw
void applyIACposition(percent_t position)
static SimplePwm idleSolenoidClose("idle close")
StepperMotor iacMotor CCM_OPTIONAL
static SimplePwm idleSolenoidOpen("idle open")
Idle Air Control valve hardware.
bool isIdleHardwareRestartNeeded()
void initIdleHardware()
bool isIdleMotorBusy()
bool isBrainPinValid(brain_pin_e brainPin)
void startSimplePwm(SimplePwm *state, const char *msg, Scheduler *executor, OutputPin *output, float frequency, float dutyCycle, pwm_gen_callback *callback)
float percent_t
float cltIdleCorrTable[CLT_IDLE_TABLE_RPM_SIZE][CLT_IDLE_TABLE_CLT_SIZE]
static float duty