Use RTC backup register to save Stepper IAC position (#471)

This commit is contained in:
andreika-git 2017-08-07 14:28:21 +03:00 committed by rusefi
parent 80ddf1ec37
commit 83dfee8e96
7 changed files with 68 additions and 19 deletions

View File

@ -91,13 +91,6 @@ Engine _engine CCM_OPTIONAL;
Engine * engine = &_engine; Engine * engine = &_engine;
#endif /* EFI_PROD_CODE */ #endif /* EFI_PROD_CODE */
/**
* I am not sure if this needs to be configurable.
*
* Also technically the whole feature might be implemented as cranking fuel coefficient curve by TPS.
*/
#define CLEANUP_MODE_TPS 90
static msg_t csThread(void) { static msg_t csThread(void) {
chRegSetThreadName("status"); chRegSetThreadName("status");
#if EFI_SHAFT_POSITION_INPUT || defined(__DOXYGEN__) #if EFI_SHAFT_POSITION_INPUT || defined(__DOXYGEN__)

View File

@ -14,6 +14,14 @@
#include "engine_configuration.h" #include "engine_configuration.h"
#include "engine.h" #include "engine.h"
/**
* I am not sure if this needs to be configurable.
*
* Also technically the whole feature might be implemented as cranking fuel coefficient curve by TPS.
*/
#define CLEANUP_MODE_TPS 90
#define STEPPER_PARKING_TPS CLEANUP_MODE_TPS
char * getPinNameByAdcChannel(const char *msg, adc_channel_e hwChannel, char *buffer); char * getPinNameByAdcChannel(const char *msg, adc_channel_e hwChannel, char *buffer);
void initPeriodicEvents(DECLARE_ENGINE_PARAMETER_SIGNATURE); void initPeriodicEvents(DECLARE_ENGINE_PARAMETER_SIGNATURE);
void initEngineContoller(Logging *sharedLogger DECLARE_ENGINE_PARAMETER_SUFFIX); void initEngineContoller(Logging *sharedLogger DECLARE_ENGINE_PARAMETER_SUFFIX);

View File

@ -335,7 +335,7 @@ static void initIdleHardware() {
if (boardConfiguration->useStepperIdle) { if (boardConfiguration->useStepperIdle) {
iacMotor.initialize(boardConfiguration->idle.stepperStepPin, boardConfiguration->idle.stepperDirectionPin, iacMotor.initialize(boardConfiguration->idle.stepperStepPin, boardConfiguration->idle.stepperDirectionPin,
engineConfiguration->stepperDirectionPinMode, engineConfiguration->idleStepperReactionTime, engineConfiguration->stepperDirectionPinMode, engineConfiguration->idleStepperReactionTime,
engineConfiguration->idleStepperTotalSteps, engineConfiguration->stepperEnablePin); engineConfiguration->idleStepperTotalSteps, engineConfiguration->stepperEnablePin, logger);
} else { } else {
/** /**
* Start PWM for idleValvePin * Start PWM for idleValvePin

View File

@ -70,7 +70,7 @@ AdcDevice::AdcDevice(ADCConversionGroup* hwConfig) {
// is there a reason to have this configurable? // is there a reason to have this configurable?
#define ADC_FAST_DEVICE ADCD2 #define ADC_FAST_DEVICE ADCD2
static int slowAdcCounter = 0; static volatile int slowAdcCounter = 0;
static LoggingWithStorage logger("ADC"); static LoggingWithStorage logger("ADC");
// todo: move this flag to Engine god object // todo: move this flag to Engine god object
@ -546,6 +546,14 @@ static void setAdcDebugReporting(int value) {
scheduleMsg(&logger, "adcDebug=%d", adcDebugReporting); scheduleMsg(&logger, "adcDebug=%d", adcDebugReporting);
} }
void waitForSlowAdc() {
// we use slowAdcCounter instead of slowAdc.conversionCount because we need ADC_COMPLETE state
// todo: use sync.objects?
while (slowAdcCounter < 1) {
chThdSleepMilliseconds(1);
}
}
static void adc_callback_slow(ADCDriver *adcp, adcsample_t *buffer, size_t n) { static void adc_callback_slow(ADCDriver *adcp, adcsample_t *buffer, size_t n) {
(void) buffer; (void) buffer;
(void) n; (void) n;

View File

@ -27,6 +27,9 @@ ioportid_t getAdcChannelPort(const char *msg, adc_channel_e hwChannel);
adc_channel_e getAdcChannel(brain_pin_e pin); adc_channel_e getAdcChannel(brain_pin_e pin);
brain_pin_e getAdcChannelBrainPin(const char *msg, adc_channel_e hwChannel); brain_pin_e getAdcChannelBrainPin(const char *msg, adc_channel_e hwChannel);
// wait until at least 1 slowADC sampling is complete
void waitForSlowAdc();
int getAdcHardwareIndexByInternalIndex(int index); int getAdcHardwareIndexByInternalIndex(int index);
void printFullAdcReportIfNeeded(Logging *log); void printFullAdcReportIfNeeded(Logging *log);

View File

@ -10,22 +10,54 @@
#include "stepper.h" #include "stepper.h"
#include "pin_repository.h" #include "pin_repository.h"
#include "engine.h" #include "engine.h"
#include "tps.h"
#include "engine_controller.h"
#include "adc_inputs.h"
EXTERN_ENGINE; EXTERN_ENGINE;
static Logging *logger;
static void saveStepperPos(int pos) {
// use backup-power RTC registers to store the data
RTCD1.rtc->BKP0R = (pos + 1);
}
static int loadStepperPos() {
return (int)RTCD1.rtc->BKP0R - 1;
}
static msg_t stThread(StepperMotor *motor) { static msg_t stThread(StepperMotor *motor) {
chRegSetThreadName("stepper"); chRegSetThreadName("stepper");
motor->directionPin.setValue(false); motor->directionPin.setValue(false);
/** // try to get saved stepper position (-1 for no data)
* let's park the motor in a known position to begin with motor->currentPosition = loadStepperPos();
*
* I believe it's safer to retract the valve for parking - at least on a bench I've seen valves // first wait until at least 1 slowADC sampling is complete
* disassembling themselves while pushing too far out. waitForSlowAdc();
*/ // now check if stepper motor re-initialization is requested - if the throttle pedal is pressed at startup
for (int i = 0; i < motor->totalSteps; i++) { bool forceStepperParking = !engine->rpmCalculator.isRunning(PASS_ENGINE_PARAMETER_SIGNATURE) && getTPS(PASS_ENGINE_PARAMETER_SIGNATURE) > STEPPER_PARKING_TPS;
motor->pulse(); scheduleMsg(logger, "Stepper: savedStepperPos=%d forceStepperParking=%d (tps=%f)", motor->currentPosition, (forceStepperParking ? 1 : 0), getTPS(PASS_ENGINE_PARAMETER_SIGNATURE));
if (motor->currentPosition < 0 || forceStepperParking) {
// reset saved value
saveStepperPos(-1);
/**
* let's park the motor in a known position to begin with
*
* I believe it's safer to retract the valve for parking - at least on a bench I've seen valves
* disassembling themselves while pushing too far out.
*/
for (int i = 0; i < motor->totalSteps; i++) {
motor->pulse();
}
// set & save zero stepper position after the parking completion
motor->currentPosition = 0;
saveStepperPos(motor->currentPosition);
} }
while (true) { while (true) {
@ -44,6 +76,8 @@ static msg_t stThread(StepperMotor *motor) {
motor->currentPosition--; motor->currentPosition--;
} }
motor->pulse(); motor->pulse();
// save position to backup RTC register
saveStepperPos(motor->currentPosition);
} }
// let's part the motor in a known position to begin with // let's part the motor in a known position to begin with
@ -85,9 +119,12 @@ void StepperMotor::pulse() {
} }
void StepperMotor::initialize(brain_pin_e stepPin, brain_pin_e directionPin, pin_output_mode_e directionPinMode, void StepperMotor::initialize(brain_pin_e stepPin, brain_pin_e directionPin, pin_output_mode_e directionPinMode,
float reactionTime, int totalSteps, brain_pin_e enablePin) { float reactionTime, int totalSteps, brain_pin_e enablePin, Logging *sharedLogger) {
this->reactionTime = maxF(1, reactionTime); this->reactionTime = maxF(1, reactionTime);
this->totalSteps = maxI(3, totalSteps); this->totalSteps = maxI(3, totalSteps);
logger = sharedLogger;
if (stepPin == GPIO_UNASSIGNED || directionPin == GPIO_UNASSIGNED) { if (stepPin == GPIO_UNASSIGNED || directionPin == GPIO_UNASSIGNED) {
return; return;
} }

View File

@ -14,7 +14,7 @@ class StepperMotor {
public: public:
StepperMotor(); StepperMotor();
void initialize(brain_pin_e stepPin, brain_pin_e directionPin, pin_output_mode_e directionPinMode, float reactionTime, int totalSteps, void initialize(brain_pin_e stepPin, brain_pin_e directionPin, pin_output_mode_e directionPinMode, float reactionTime, int totalSteps,
brain_pin_e enablePin); brain_pin_e enablePin, Logging *sharedLogger);
void pulse(); void pulse();
void setTargetPosition(int targetPosition); void setTargetPosition(int targetPosition);
int getTargetPosition(); int getTargetPosition();