Example #1
0
void updateAuxValves(DECLARE_ENGINE_PARAMETER_SIGNATURE) {
	if (engineConfiguration->auxValves[0] == GPIO_UNASSIGNED) {
		return;
	}

	float x = getTPS(PASS_ENGINE_PARAMETER_SIGNATURE);
	if (cisnan(x)) {
		// error should be already reported by now
		return;
	}
	engine->engineState.auxValveStart = interpolate2d("aux", x,
			engineConfiguration->fsioCurve1Bins,
			engineConfiguration->fsioCurve1, FSIO_CURVE_16);

	engine->engineState.auxValveEnd = interpolate2d("aux", x,
			engineConfiguration->fsioCurve2Bins,
			engineConfiguration->fsioCurve2, FSIO_CURVE_16);

	if (engine->engineState.auxValveStart >= engine->engineState.auxValveEnd) {
		// this is a fatal error to make this really visible
		firmwareError(CUSTOM_AUX_OUT_OF_ORDER, "out of order at %.2f %.2f %.2f", x,
				engine->engineState.auxValveStart,
				engine->engineState.auxValveEnd);
	}
}
static ALWAYS_INLINE void handleFuel(bool limitedFuel, uint32_t eventIndex, int rpm DECLARE_ENGINE_PARAMETER_S) {
	if (!isInjectionEnabled(engineConfiguration))
		return;
	efiAssertVoid(getRemainingStack(chThdSelf()) > 128, "lowstck#3");
	efiAssertVoid(eventIndex < ENGINE(triggerShape.getLength()), "handleFuel/event index");

	/**
	 * Ignition events are defined by addFuelEvents() according to selected
	 * fueling strategy
	 */
	FuelSchedule *fs = ENGINE(engineConfiguration2)->injectionEvents;

	InjectionEventList *source = &fs->injectionEvents;

	if (!fs->hasEvents[eventIndex])
		return;

	ENGINE(tpsAccelEnrichment.onNewValue(getTPS(PASS_ENGINE_PARAMETER_F) PASS_ENGINE_PARAMETER));
	ENGINE(engineLoadAccelEnrichment.onEngineCycle(PASS_ENGINE_PARAMETER_F));

	ENGINE(fuelMs) = getFuelMs(rpm PASS_ENGINE_PARAMETER) * CONFIG(globalFuelCorrection);

	for (int i = 0; i < source->size; i++) {
		InjectionEvent *event = &source->elements[i];
		if (event->injectionStart.eventIndex != eventIndex)
			continue;
		handleFuelInjectionEvent(i, limitedFuel, event, rpm PASS_ENGINE_PARAMETER);
	}
}
Example #3
0
void EngineState::periodicFastCallback(DECLARE_ENGINE_PARAMETER_F) {
	int rpm = ENGINE(rpmCalculator.rpmValue);

	sparkDwell = getSparkDwell(rpm PASS_ENGINE_PARAMETER);
	dwellAngle = sparkDwell / getOneDegreeTimeMs(rpm);

	iatFuelCorrection = getIatCorrection(iat PASS_ENGINE_PARAMETER);
	cltFuelCorrection = getCltCorrection(clt PASS_ENGINE_PARAMETER);

	engineNoiseHipLevel = interpolate2d(rpm, engineConfiguration->knockNoiseRpmBins,
					engineConfiguration->knockNoise, ENGINE_NOISE_CURVE_SIZE);

	baroCorrection = getBaroCorrection(PASS_ENGINE_PARAMETER_F);

	injectionOffset = getinjectionOffset(rpm PASS_ENGINE_PARAMETER);
	float engineLoad = getEngineLoadT(PASS_ENGINE_PARAMETER_F);
	timingAdvance = getAdvance(rpm, engineLoad PASS_ENGINE_PARAMETER);

	if (engineConfiguration->algorithm == LM_SPEED_DENSITY) {
		float coolantC = ENGINE(engineState.clt);
		float intakeC = ENGINE(engineState.iat);
		float tps = getTPS(PASS_ENGINE_PARAMETER_F);
		tChargeK = convertCelsiusToKelvin(getTCharge(rpm, tps, coolantC, intakeC));
		float map = getMap();

		/**
		 * *0.01 because of https://sourceforge.net/p/rusefi/tickets/153/
		 */
		currentVE = baroCorrection * veMap.getValue(map, rpm) * 0.01;
		targerAFR = afrMap.getValue(map, rpm);
	} else {
		baseTableFuel = getBaseTableFuel(engineConfiguration, rpm, engineLoad);
	}

}
Example #4
0
static char * prepareCltIatTpsLine(Engine *engine, char *buffer) {
	char *ptr = buffer;
	*ptr++ = 'C';

	ptr = appendStr(ptr, " TP");
	ptr = itoa10(ptr, (int) getTPS(PASS_ENGINE_PARAMETER_F));
	return ptr;
}
Example #5
0
static void printTPSInfo(void) {
#if EFI_PROD_CODE
	GPIO_TypeDef* port = getAdcChannelPort(engineConfiguration->tpsAdcChannel);
	int pin = getAdcChannelPin(engineConfiguration->tpsAdcChannel);

	scheduleMsg(&logger, "tps min %d/max %d v=%f @%s%d", engineConfiguration->tpsMin, engineConfiguration->tpsMax, getTPSVoltage(), portname(port), pin);
#endif
	scheduleMsg(&logger, "current 10bit=%d value=%f rate=%f", getTPS10bitAdc(), getTPS(), getTpsRateOfChange());
}
Example #6
0
static char * prepareCltIatTpsLine(char *buffer) {
	char *ptr = buffer;
	*ptr++ = 'C';
	ptr = ftoa(ptr, getCoolantTemperature(), 10.0f);

	ptr = appendStr(ptr, " C");
	ptr = ftoa(ptr, getIntakeAirTemperature(), 10.0f);

	ptr = appendStr(ptr, " TP");
	ptr = itoa10(ptr, (int) getTPS());
	return ptr;
}
Example #7
0
/**
 * Hugo game state machine - called during onIdle
 */
void HugoEngine::runMachine() {
	Status &gameStatus = getGameStatus();

	// Don't process if gameover
	if (gameStatus._gameOverFl)
		return;

	_curTime = g_system->getMillis();
	// Process machine once every tick
	while (_curTime - _lastTime < (uint32)(1000 / getTPS())) {
		g_system->delayMillis(5);
		_curTime = g_system->getMillis();
	}

	_lastTime = _curTime;

	switch (gameStatus._viewState) {
	case kViewIdle:                                 // Not processing state machine
		_screen->hideCursor();
		_intro->preNewGame();                       // Any processing before New Game selected
		break;
	case kViewIntroInit:                            // Initialization before intro begins
		_intro->introInit();
		gameStatus._viewState = kViewIntro;
		break;
	case kViewIntro:                                // Do any game-dependant preamble
		if (_intro->introPlay()) {                  // Process intro screen
			_scheduler->newScreen(0);               // Initialize first screen
			gameStatus._viewState = kViewPlay;
		}
		break;
	case kViewPlay:                                 // Playing game
		_screen->showCursor();
		_parser->charHandler();                     // Process user cmd input
		_object->moveObjects();                     // Process object movement
		_scheduler->runScheduler();                 // Process any actions
		_screen->displayList(kDisplayRestore);      // Restore previous background
		_object->updateImages();                    // Draw into _frontBuffer, compile display list
		_screen->drawStatusText();
		_screen->displayList(kDisplayDisplay);      // Blit the display list to screen
		_sound->checkMusic();
		break;
	case kViewInvent:                               // Accessing inventory
		_inventory->runInventory();                 // Process Inventory state machine
		break;
	case kViewExit:                                 // Game over or user exited
		gameStatus._viewState = kViewIdle;
		_status._doQuitFl = true;
		break;
	}
}
Example #8
0
static void cylinderCleanupControl(Engine *engine) {
#if EFI_ENGINE_CONTROL || defined(__DOXYGEN__)
	bool newValue;
	if (engineConfiguration->isCylinderCleanupEnabled) {
		newValue = !engine->rpmCalculator.isRunning(PASS_ENGINE_PARAMETER_F) && getTPS(PASS_ENGINE_PARAMETER_F) > CLEANUP_MODE_TPS;
	} else {
		newValue = false;
	}
	if (newValue != engine->isCylinderCleanupMode) {
		engine->isCylinderCleanupMode = newValue;
		scheduleMsg(&logger, "isCylinderCleanupMode %s", boolToString(newValue));
	}
#endif
}
Example #9
0
static msg_t etbThread(void *arg) {
	while (TRUE) {
		int tps = (int)getTPS();

		if (tps != prevTps) {
			prevTps = tps;
			scheduleMsg(&logger, "tps=%d", (int) tps);
		}

		// this thread is activated 10 times per second
		chThdSleepMilliseconds(100);
	}
#if defined __GNUC__
	return -1;
#endif
}
Example #10
0
void StartupFuelPumping::update(DECLARE_ENGINE_PARAMETER_SIGNATURE) {
	if (engine->rpmCalculator.getRpm(PASS_ENGINE_PARAMETER_SIGNATURE) == 0) {
		bool isTpsAbove50 = getTPS(PASS_ENGINE_PARAMETER_SIGNATURE) >= 50;

		if (this->isTpsAbove50 != isTpsAbove50) {
			setPumpsCounter(pumpsCounter + 1);
		}

	} else {
		/**
		 * Engine is not stopped - not priming pumping mode
		 */
		setPumpsCounter(0);
		isTpsAbove50 = false;
	}
}
Example #11
0
static void printTPSInfo(void) {
#if (EFI_PROD_CODE && HAL_USE_ADC) || defined(__DOXYGEN__)
	if (!engineConfiguration->hasTpsSensor) {
		scheduleMsg(&logger, "NO TPS SENSOR");
		return;
	}

	GPIO_TypeDef* port = getAdcChannelPort(engineConfiguration->tpsAdcChannel);
	int pin = getAdcChannelPin(engineConfiguration->tpsAdcChannel);

	scheduleMsg(&logger, "tps min %d/max %d v=%f @%s%d", engineConfiguration->tpsMin, engineConfiguration->tpsMax,
			getTPSVoltage(PASS_ENGINE_PARAMETER_F), portname(port), pin);
#endif
	scheduleMsg(&logger, "current 10bit=%d value=%f rate=%f", getTPS10bitAdc(), getTPS(PASS_ENGINE_PARAMETER_F),
			getTpsRateOfChange());
}
Example #12
0
floatms_t getCrankingFuel3(float coolantTemperature,
		uint32_t revolutionCounterSinceStart DECLARE_ENGINE_PARAMETER_S) {
	// these magic constants are in Celsius
	float baseCrankingFuel = engineConfiguration->cranking.baseFuel;
	if (cisnan(coolantTemperature))
		return baseCrankingFuel;
	float durationCoef = interpolate2d(revolutionCounterSinceStart, config->crankingCycleBins,
			config->crankingCycleCoef, CRANKING_CURVE_SIZE);

	float coolantTempCoef = interpolate2d(coolantTemperature, config->crankingFuelBins,
			config->crankingFuelCoef, CRANKING_CURVE_SIZE);

	float tpsCoef = interpolate2d(getTPS(PASS_ENGINE_PARAMETER_F), engineConfiguration->crankingTpsBins,
			engineConfiguration->crankingTpsCoef, CRANKING_CURVE_SIZE);

	return baseCrankingFuel * durationCoef * coolantTempCoef * tpsCoef;
}
Example #13
0
/**
 * @return value in Milliseconds
 */
float getSpeedDensityFuel(Engine *engine, int rpm) {
	//int rpm = engine->rpmCalculator->rpm();

	engine_configuration_s *engineConfiguration = engine->engineConfiguration;

	float tps = getTPS(engineConfiguration);
	float coolantC = getCoolantTemperature(engine->engineConfiguration2);
	float intakeC = getIntakeAirTemperature(engine->engineConfiguration2);
	float tChargeK = convertCelsiusToKelvin(getTCharge(rpm, tps, coolantC, intakeC));
	float map = getMap();
	float VE = veMap.getValue(map, engineConfiguration->veLoadBins, rpm,
			engineConfiguration->veRpmBins);
	float AFR = afrMap.getValue(map, engineConfiguration->afrLoadBins, rpm,
			engineConfiguration->afrRpmBins);

	return sdMath(engine->engineConfiguration, VE, map, AFR, tChargeK) * 1000;
}
Example #14
0
/**
 * @brief Returns engine load according to selected engine_load_mode
 *
 */
float getEngineLoadT(Engine *engine) {
    efiAssert(engine!=NULL, "engine 2NULL", NAN);
    engine_configuration_s *engineConfiguration = engine->engineConfiguration;
    efiAssert(engineConfiguration!=NULL, "engineConfiguration 2NULL", NAN);
    switch (engineConfiguration->algorithm) {
    case LM_MAF:
        return getMafT(engineConfiguration);
    case LM_SPEED_DENSITY:
    // SD engine load is used for timing lookup but not for fuel calculation
    case LM_MAP:
        return getMap();
    case LM_TPS:
        return getTPS();
    default:
        firmwareError("Unexpected engine load parameter: %d", engineConfiguration->algorithm);
        return -1;
    }
}
Example #15
0
static void showEthInfo(void) {
	static char pinNameBuffer[16];

	scheduleMsg(&logger, "etbAutoTune=%d",
			engine->etbAutoTune);

	scheduleMsg(&logger, "throttlePedal=%.2f %.2f/%.2f @%s",
			getPedalPosition(),
			engineConfiguration->throttlePedalUpVoltage,
			engineConfiguration->throttlePedalWOTVoltage,
			getPinNameByAdcChannel("tPedal", engineConfiguration->throttlePedalPositionAdcChannel, pinNameBuffer));

	scheduleMsg(&logger, "TPS=%.2f", getTPS());
	scheduleMsg(&logger, "dir=%d DC=%f", etb1.dcMotor.isOpenDirection(), etb1.dcMotor.Get());

	scheduleMsg(&logger, "etbControlPin1=%s duty=%.2f freq=%d",
			hwPortname(CONFIGB(etb1.controlPin1)),
			currentEtbDuty,
			engineConfiguration->etbFreq);
	scheduleMsg(&logger, "close dir=%s", hwPortname(CONFIGB(etb1.directionPin2)));
	pid.showPidStatus(&logger, "ETB");
}
Example #16
0
/**
 * @brief Returns engine load according to selected engine_load_mode
 *
 */
float getEngineLoadT(DECLARE_ENGINE_PARAMETER_F) {
	efiAssert(engine!=NULL, "engine 2NULL", NAN);
	efiAssert(engineConfiguration!=NULL, "engineConfiguration 2NULL", NAN);
	switch (engineConfiguration->algorithm) {
	case LM_PLAIN_MAF:
		if (!hasMafSensor(PASS_ENGINE_PARAMETER_F)) {
			warning(OBD_PCM_Processor_Fault, "MAF sensor needed for current fuel algorithm");
			return NAN;
		}
		return getMafT(engineConfiguration);
	case LM_SPEED_DENSITY:
		// SD engine load is used for timing lookup but not for fuel calculation
	case LM_MAP:
		return getMap();
	case LM_ALPHA_N:
		return getTPS(PASS_ENGINE_PARAMETER_F);
	case LM_REAL_MAF: {
		return getRealMaf(PASS_ENGINE_PARAMETER_F);
	}
	default:
		warning(OBD_PCM_Processor_Fault, "Unexpected engine load parameter: %d", engineConfiguration->algorithm);
		return -1;
	}
}
Example #17
0
}

#if EFI_TUNER_STUDIO || defined(__DOXYGEN__)

extern WallFuel wallFuel;

extern fuel_Map3D_t veMap;

void updateTunerStudioState(TunerStudioOutputChannels *tsOutputChannels DECLARE_ENGINE_PARAMETER_S) {
#if EFI_SHAFT_POSITION_INPUT || defined(__DOXYGEN__)
	int rpm = getRpmE(engine);
#else
	int rpm = 0;
#endif

	float tps = getTPS(PASS_ENGINE_PARAMETER_F);
	float coolant = getCoolantTemperature(PASS_ENGINE_PARAMETER_F);
	float intake = getIntakeAirTemperature(PASS_ENGINE_PARAMETER_F);

	float engineLoad = getEngineLoadT(PASS_ENGINE_PARAMETER_F);
	float baseFuelMs = getBaseFuel(rpm PASS_ENGINE_PARAMETER);

	// header
	tsOutputChannels->tsConfigVersion = TS_FILE_VERSION;

	// engine state
	tsOutputChannels->rpm = rpm;
	tsOutputChannels->coolant_temperature = coolant;
	tsOutputChannels->intakeAirTemperature = intake;
	tsOutputChannels->throttlePositon = tps;
	tsOutputChannels->massAirFlowVoltage = hasMafSensor() ? getMaf() : 0;
Example #18
0
void EngineState::periodicFastCallback(DECLARE_ENGINE_PARAMETER_SIGNATURE) {
	efitick_t nowNt = getTimeNowNt();
	if (ENGINE(rpmCalculator).isCranking(PASS_ENGINE_PARAMETER_SIGNATURE)) {
		crankingTime = nowNt;
		timeSinceCranking = 0.0f;
	} else {
		timeSinceCranking = nowNt - crankingTime;
	}
	updateAuxValves(PASS_ENGINE_PARAMETER_SIGNATURE);

	int rpm = ENGINE(rpmCalculator).getRpm(PASS_ENGINE_PARAMETER_SIGNATURE);
	sparkDwell = getSparkDwell(rpm PASS_ENGINE_PARAMETER_SUFFIX);
	dwellAngle = sparkDwell / getOneDegreeTimeMs(rpm);
	if (hasAfrSensor(PASS_ENGINE_PARAMETER_SIGNATURE)) {
		engine->sensors.currentAfr = getAfr(PASS_ENGINE_PARAMETER_SIGNATURE);
	}

	// todo: move this into slow callback, no reason for IAT corr to be here
	iatFuelCorrection = getIatFuelCorrection(engine->sensors.iat PASS_ENGINE_PARAMETER_SUFFIX);
	// todo: move this into slow callback, no reason for CLT corr to be here
	if (boardConfiguration->useWarmupPidAfr && engine->sensors.clt < engineConfiguration->warmupAfrThreshold) {
		if (rpm < 200) {
			cltFuelCorrection = 1;
			warmupAfrPid.reset();
		} else {
			cltFuelCorrection = warmupAfrPid.getValue(warmupTargetAfr, engine->sensors.currentAfr, 1);
		}
#if ! EFI_UNIT_TEST || defined(__DOXYGEN__)
		if (engineConfiguration->debugMode == DBG_WARMUP_ENRICH) {
			tsOutputChannels.debugFloatField1 = warmupTargetAfr;
			warmupAfrPid.postState(&tsOutputChannels);
		}
#endif

	} else {
		cltFuelCorrection = getCltFuelCorrection(PASS_ENGINE_PARAMETER_SIGNATURE);
	}

	// update fuel consumption states
	fuelConsumption.update(nowNt PASS_ENGINE_PARAMETER_SUFFIX);

	// Fuel cut-off isn't just 0 or 1, it can be tapered
	fuelCutoffCorrection = getFuelCutOffCorrection(nowNt, rpm PASS_ENGINE_PARAMETER_SUFFIX);
	
	// post-cranking fuel enrichment.
	// for compatibility reasons, apply only if the factor is greater than zero (0.01 margin used)
	if (engineConfiguration->postCrankingFactor > 0.01f) {
		// convert to microsecs and then to seconds
		float timeSinceCrankingInSecs = NT2US(timeSinceCranking) / 1000000.0f;
		// use interpolation for correction taper
		postCrankingFuelCorrection = interpolateClamped(0.0f, engineConfiguration->postCrankingFactor, 
			engineConfiguration->postCrankingDurationSec, 1.0f, timeSinceCrankingInSecs);
	} else {
		postCrankingFuelCorrection = 1.0f;
	}

	cltTimingCorrection = getCltTimingCorrection(PASS_ENGINE_PARAMETER_SIGNATURE);

	engineNoiseHipLevel = interpolate2d("knock", rpm, engineConfiguration->knockNoiseRpmBins,
					engineConfiguration->knockNoise, ENGINE_NOISE_CURVE_SIZE);

	baroCorrection = getBaroCorrection(PASS_ENGINE_PARAMETER_SIGNATURE);

	injectionOffset = getinjectionOffset(rpm PASS_ENGINE_PARAMETER_SUFFIX);
	float engineLoad = getEngineLoadT(PASS_ENGINE_PARAMETER_SIGNATURE);
	timingAdvance = getAdvance(rpm, engineLoad PASS_ENGINE_PARAMETER_SUFFIX);

	if (engineConfiguration->fuelAlgorithm == LM_SPEED_DENSITY) {
		float coolantC = ENGINE(sensors.clt);
		float intakeC = ENGINE(sensors.iat);
		float tps = getTPS(PASS_ENGINE_PARAMETER_SIGNATURE);
		tChargeK = convertCelsiusToKelvin(getTCharge(rpm, tps, coolantC, intakeC PASS_ENGINE_PARAMETER_SUFFIX));
		float map = getMap();

		/**
		 * *0.01 because of https://sourceforge.net/p/rusefi/tickets/153/
		 */
		float rawVe = veMap.getValue(rpm, map);
		// get VE from the separate table for Idle
		if (CONFIG(useSeparateVeForIdle)) {
			float idleVe = interpolate2d("idleVe", rpm, config->idleVeBins, config->idleVe, IDLE_VE_CURVE_SIZE);
			// interpolate between idle table and normal (running) table using TPS threshold
			rawVe = interpolateClamped(0.0f, idleVe, boardConfiguration->idlePidDeactivationTpsThreshold, rawVe, tps);
		}
		currentVE = baroCorrection * rawVe * 0.01;
		targetAFR = afrMap.getValue(rpm, map);
	} else {
		baseTableFuel = getBaseTableFuel(rpm, engineLoad);
	}
}
Example #19
0
void EngineState::periodicFastCallback(DECLARE_ENGINE_PARAMETER_F) {
	int rpm = ENGINE(rpmCalculator.rpmValue);

	efitick_t nowNt = getTimeNowNt();
	if (isCrankingR(rpm)) {
		crankingTime = nowNt;
	} else {
		timeSinceCranking = nowNt - crankingTime;
	}

	sparkDwell = getSparkDwell(rpm PASS_ENGINE_PARAMETER);
	dwellAngle = sparkDwell / getOneDegreeTimeMs(rpm);

	// todo: move this into slow callback, no reason for IAT corr to be here
	iatFuelCorrection = getIatCorrection(iat PASS_ENGINE_PARAMETER);
	// todo: move this into slow callback, no reason for CLT corr to be here
	if (boardConfiguration->useWarmupPidAfr && clt < engineConfiguration->warmupAfrThreshold) {
		if (rpm < 200) {
			cltFuelCorrection = 1;
			warmupAfrPid.reset();
		} else {
			cltFuelCorrection = warmupAfrPid.getValue(warmupTargetAfr, getAfr(PASS_ENGINE_PARAMETER_F), 1);
		}
#if ! EFI_UNIT_TEST || defined(__DOXYGEN__)
		if (engineConfiguration->debugMode == WARMUP_ENRICH) {
			tsOutputChannels.debugFloatField1 = warmupTargetAfr;
			warmupAfrPid.postState(&tsOutputChannels);
		}
#endif

	} else {
		cltFuelCorrection = getCltFuelCorrection(clt PASS_ENGINE_PARAMETER);
	}

	cltTimingCorrection = getCltTimingCorrection(clt PASS_ENGINE_PARAMETER);

	engineNoiseHipLevel = interpolate2d(rpm, engineConfiguration->knockNoiseRpmBins,
					engineConfiguration->knockNoise, ENGINE_NOISE_CURVE_SIZE);

	baroCorrection = getBaroCorrection(PASS_ENGINE_PARAMETER_F);

	injectionOffset = getinjectionOffset(rpm PASS_ENGINE_PARAMETER);
	float engineLoad = getEngineLoadT(PASS_ENGINE_PARAMETER_F);
	timingAdvance = getAdvance(rpm, engineLoad PASS_ENGINE_PARAMETER);

	if (engineConfiguration->fuelAlgorithm == LM_SPEED_DENSITY) {
		float coolantC = ENGINE(engineState.clt);
		float intakeC = ENGINE(engineState.iat);
		float tps = getTPS(PASS_ENGINE_PARAMETER_F);
		tChargeK = convertCelsiusToKelvin(getTCharge(rpm, tps, coolantC, intakeC PASS_ENGINE_PARAMETER));
		float map = getMap();

		/**
		 * *0.01 because of https://sourceforge.net/p/rusefi/tickets/153/
		 */
		currentVE = baroCorrection * veMap.getValue(rpm, map) * 0.01;
		targetAFR = afrMap.getValue(rpm, map);
	} else {
		baseTableFuel = getBaseTableFuel(engineConfiguration, rpm, engineLoad);
	}

}
Example #20
0
static msg_t stThread(StepperMotor *motor) {
	chRegSetThreadName("stepper");

	// try to get saved stepper position (-1 for no data)
	motor->currentPosition = loadStepperPos();

	// first wait until at least 1 slowADC sampling is complete
	waitForSlowAdc();
	// now check if stepper motor re-initialization is requested - if the throttle pedal is pressed at startup
	bool forceStepperParking = !engine->rpmCalculator.isRunning(PASS_ENGINE_PARAMETER_SIGNATURE) && getTPS(PASS_ENGINE_PARAMETER_SIGNATURE) > STEPPER_PARKING_TPS;
	if (boardConfiguration->stepperForceParkingEveryRestart)
		forceStepperParking = true;
	scheduleMsg(logger, "Stepper: savedStepperPos=%d forceStepperParking=%d (tps=%.2f)", 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.
		 *
		 * Add extra steps to compensate step skipping by some old motors.
		 */
		int numParkingSteps = (int)efiRound((1.0f + (float)boardConfiguration->stepperParkingExtraSteps / PERCENT_MULT) * motor->totalSteps, 1.0f);
		for (int i = 0; i < numParkingSteps; i++) {
			motor->pulse();
		}

		// set & save zero stepper position after the parking completion
		motor->currentPosition = 0;
		saveStepperPos(motor->currentPosition);
	} else {
		// The initial target position should correspond to the saved stepper position.
		// Idle thread starts later and sets a new target position.
		motor->setTargetPosition(motor->currentPosition);
	}

	while (true) {
		int targetPosition = motor->getTargetPosition();
		int currentPosition = motor->currentPosition;

		if (targetPosition == currentPosition) {
			chThdSleepMilliseconds(motor->reactionTime);
			continue;
		}
		bool isIncrementing = targetPosition > currentPosition;
		motor->setDirection(isIncrementing);
		if (isIncrementing) {
			motor->currentPosition++;
		} else {
			motor->currentPosition--;
		}
		motor->pulse();
		// save position to backup RTC register
		saveStepperPos(motor->currentPosition);
	}

	// let's part the motor in a known position to begin with
//	for (int i = 0; i < ST_COUNT / 2; i++) {
//		motor->pulse();
//	}

	return 0;
}
Example #21
0
void AccelEnrichmemnt::onEngineCycleTps(DECLARE_ENGINE_PARAMETER_F) {
	onNewValue(getTPS(PASS_ENGINE_PARAMETER_F) PASS_ENGINE_PARAMETER);
}
Example #22
0
	void PeriodicTask(efitime_t nowNt) override	{
		UNUSED(nowNt);
		setPeriod(GET_PERIOD_LIMITED(&engineConfiguration->etb));


		// set debug_mode 17
		if (engineConfiguration->debugMode == DBG_ELECTRONIC_THROTTLE_PID) {
#if EFI_TUNER_STUDIO
			pid.postState(&tsOutputChannels);
			tsOutputChannels.debugIntField5 = feedForward;
#endif /* EFI_TUNER_STUDIO */
		} else if (engineConfiguration->debugMode == DBG_ELECTRONIC_THROTTLE_EXTRA) {
#if EFI_TUNER_STUDIO
			// set debug_mode 29
			tsOutputChannels.debugFloatField1 = directPwmValue;
#endif /* EFI_TUNER_STUDIO */
		}

		if (shouldResetPid) {
			pid.reset();
			shouldResetPid = false;
		}

		if (!cisnan(directPwmValue)) {
			etb1.dcMotor.Set(directPwmValue);
			return;
		}

		if (boardConfiguration->pauseEtbControl) {
			etb1.dcMotor.Set(0);
			return;
		}

		percent_t actualThrottlePosition = getTPS();

		if (engine->etbAutoTune) {
			autoTune.input = actualThrottlePosition;
			bool result = autoTune.Runtime(&logger);

			tuneWorkingPid.updateFactors(autoTune.output, 0, 0);

			float value = tuneWorkingPid.getOutput(50, actualThrottlePosition);
			scheduleMsg(&logger, "AT input=%f output=%f PID=%f", autoTune.input,
					autoTune.output,
					value);
			scheduleMsg(&logger, "AT PID=%f", value);
			etb1.dcMotor.Set(PERCENT_TO_DUTY(value));

			if (result) {
				scheduleMsg(&logger, "GREAT NEWS! %f/%f/%f", autoTune.GetKp(), autoTune.GetKi(), autoTune.GetKd());
			}

			return;
		}


		percent_t targetPosition = getPedalPosition(PASS_ENGINE_PARAMETER_SIGNATURE);

		feedForward = interpolate2d("etbb", targetPosition, engineConfiguration->etbBiasBins, engineConfiguration->etbBiasValues, ETB_BIAS_CURVE_LENGTH);

		pid.iTermMin = engineConfiguration->etb_iTermMin;
		pid.iTermMax = engineConfiguration->etb_iTermMax;

		currentEtbDuty = feedForward +
				pid.getOutput(targetPosition, actualThrottlePosition);

		etb1.dcMotor.Set(PERCENT_TO_DUTY(currentEtbDuty));

		if (engineConfiguration->isVerboseETB) {
			pid.showPidStatus(&logger, "ETB");
		}
	}
Example #23
0
static void printSensors(Logging *log, bool fileFormat) {
	// current time, in milliseconds
	int nowMs = currentTimeMillis();
	float sec = ((float) nowMs) / 1000;
	reportSensorF(log, fileFormat, "time", "", sec, 3);

	int rpm = 0;
#if EFI_SHAFT_POSITION_INPUT || defined(__DOXYGEN__)
	rpm = getRpmE(engine);
	reportSensorI(log, fileFormat, "rpm", "RPM", rpm);

//	reportSensorF(log, fileFormat, "TRG_0_DUTY", "%", getTriggerDutyCycle(0), 2);
//	reportSensorF(log, fileFormat, "TRG_1_DUTY", "%", getTriggerDutyCycle(1), 2);
#endif

	if (hasMafSensor()) {
		reportSensorF(log, fileFormat, "maf", "V", getMaf(), 2);
		reportSensorF(log, fileFormat, "mafr", "kg/hr", getRealMaf(), 2);
	}

	reportSensorF(log, fileFormat, "ENGINE_LOAD", "x", getEngineLoadT(), 2);


#if EFI_ANALOG_SENSORS || defined(__DOXYGEN__)
	if (engineConfiguration->hasMapSensor) {
		reportSensorF(log, fileFormat, "MAP", "kPa", getMap(), 2);
//		reportSensorF(log, fileFormat, "map_r", "V", getRawMap(), 2);
	}
	if (hasBaroSensor()) {
		reportSensorF(log, fileFormat, "baro", "kPa", getBaroPressure(), 2);
	}
	if (engineConfiguration->hasAfrSensor) {
		reportSensorF(log, fileFormat, "afr", "AFR", getAfr(), 2);
	}
#endif

#if EFI_VEHICLE_SPEED || defined(__DOXYGEN__)
	if (engineConfiguration->hasVehicleSpeedSensor) {
		reportSensorF(log, fileFormat, "vss", "kph", getVehicleSpeed(), 2);
	}
#endif /* EFI_PROD_CODE */

	reportSensorF(log, fileFormat, "ks", "count", engine->knockCount, 0);
	reportSensorF(log, fileFormat, "kv", "v", engine->knockVolts, 2);


//	reportSensorF(log, fileFormat, "vref", "V", getVRef(engineConfiguration), 2);
	if (hasVBatt(PASS_ENGINE_PARAMETER_F)) {
		reportSensorF(log, fileFormat, "vbatt", "V", getVBatt(PASS_ENGINE_PARAMETER_F), 2);
	}

	reportSensorF(log, fileFormat, "TP", "%", getTPS(PASS_ENGINE_PARAMETER_F), 2);

	if (fileFormat) {
		reportSensorF(log, fileFormat, "tpsacc", "ms", engine->tpsAccelEnrichment.getTpsEnrichment(PASS_ENGINE_PARAMETER_F), 2);
		reportSensorF(log, fileFormat, "advance", "deg", engine->tpsAccelEnrichment.getTpsEnrichment(PASS_ENGINE_PARAMETER_F), 2);
	}

	if (engineConfiguration->hasCltSensor) {
		reportSensorF(log, fileFormat, "CLT", "C", getCoolantTemperature(PASS_ENGINE_PARAMETER_F), 2);
	}

	reportSensorF(log, fileFormat, "MAT", "C", getIntakeAirTemperature(PASS_ENGINE_PARAMETER_F), 2);

//	debugFloat(&logger, "tch", getTCharge1(tps), 2);

}
Example #24
0
void AccelEnrichmemnt::onEngineCycleTps(DECLARE_ENGINE_PARAMETER_SIGNATURE) {
	onNewValue(getTPS(PASS_ENGINE_PARAMETER_SIGNATURE) PASS_ENGINE_PARAMETER_SUFFIX);
}
Example #25
0
static void printSensors(Logging *log, bool fileFormat) {
	// current time, in milliseconds
	int nowMs = currentTimeMillis();
	float sec = ((float) nowMs) / 1000;
	reportSensorF(log, fileFormat, "time", "", sec, 3); // log column 1

	int rpm = 0;
#if EFI_SHAFT_POSITION_INPUT || defined(__DOXYGEN__)
	rpm = getRpmE(engine);
	reportSensorI(log, fileFormat, "rpm", "RPM", rpm); // log column 2

//	reportSensorF(log, fileFormat, "TRG_0_DUTY", "%", getTriggerDutyCycle(0), 2);
//	reportSensorF(log, fileFormat, "TRG_1_DUTY", "%", getTriggerDutyCycle(1), 2);
#endif

#if EFI_PROD_CODE || defined(__DOXYGEN__)
	reportSensorF(log, fileFormat, "int_temp", "C", getMCUInternalTemperature(), 2); // log column #3
#endif

	reportSensorI(log, fileFormat, "mode", "v", packEngineMode(PASS_ENGINE_PARAMETER_F)); // log column #3

	if (hasCltSensor()) {
		reportSensorF(log, fileFormat, "CLT", "C", getCoolantTemperature(PASS_ENGINE_PARAMETER_F), 2); // log column #4
	}
	if (hasTpsSensor()) {
		reportSensorF(log, fileFormat, "TPS", "%", getTPS(PASS_ENGINE_PARAMETER_F), 2); // log column #5
	}

	if (hasVBatt(PASS_ENGINE_PARAMETER_F)) {
		reportSensorF(log, fileFormat, "vbatt", "V", getVBatt(PASS_ENGINE_PARAMETER_F), 2); // log column #6
	}

	if (hasIatSensor()) {
		reportSensorF(log, fileFormat, "IAT", "C", getIntakeAirTemperature(PASS_ENGINE_PARAMETER_F), 2); // log column #7
	}

	if (hasMafSensor()) {
		reportSensorF(log, fileFormat, "maf", "V", getMaf(PASS_ENGINE_PARAMETER_F), 2);
		reportSensorF(log, fileFormat, "mafr", "kg/hr", getRealMaf(PASS_ENGINE_PARAMETER_F), 2);
	}
#if EFI_ANALOG_SENSORS || defined(__DOXYGEN__)
	if (engineConfiguration->map.sensor.hwChannel != EFI_ADC_NONE) {
		reportSensorF(log, fileFormat, "MAP", "kPa", getMap(), 2);
//		reportSensorF(log, fileFormat, "map_r", "V", getRawMap(), 2);
	}
#endif /* EFI_ANALOG_SENSORS */
#if EFI_ANALOG_SENSORS || defined(__DOXYGEN__)
	if (hasBaroSensor()) {
		reportSensorF(log, fileFormat, "baro", "kPa", getBaroPressure(), 2);
	}
#endif /* EFI_ANALOG_SENSORS */

	if (hasAfrSensor(PASS_ENGINE_PARAMETER_F)) {
		reportSensorF(log, fileFormat, "afr", "AFR", getAfr(PASS_ENGINE_PARAMETER_F), 2);
	}

#if EFI_IDLE_CONTROL || defined(__DOXYGEN__)
	if (fileFormat) {
		reportSensorF(log, fileFormat, "idle", "%", getIdlePosition(), 2);
	}
#endif /* EFI_IDLE_CONTROL */

#if EFI_ANALOG_SENSORS || defined(__DOXYGEN__)
	reportSensorF(log, fileFormat, "target", "AFR", engine->engineState.targetAFR, 2);
#endif /* EFI_ANALOG_SENSORS */

	if (fileFormat) {
		reportSensorF(log, fileFormat, "tCharge", "K", engine->engineState.tChargeK, 2); // log column #8
		reportSensorF(log, fileFormat, "curVE", "%", veMap.getValue(rpm, getMap()), 2);
	}

	float engineLoad = getEngineLoadT(PASS_ENGINE_PARAMETER_F);
	reportSensorF(log, fileFormat, "ENGINE_LOAD", "x", engineLoad, 2);


	reportSensorF(log, fileFormat, "dwell", "ms", ENGINE(engineState.sparkDwell), 2);
	if (fileFormat) {
		reportSensorF(log, fileFormat, "timing", "deg", engine->engineState.timingAdvance, 2);

	}

	if (fileFormat) {
		floatms_t fuelBase = getBaseFuel(rpm PASS_ENGINE_PARAMETER);
		reportSensorF(log, fileFormat, "f: base", "ms", fuelBase, 2);
		reportSensorF(log, fileFormat, "f: actual", "ms", ENGINE(actualLastInjection), 2);
		reportSensorF(log, fileFormat, "f: lag", "ms", engine->engineState.injectorLag, 2);
		reportSensorF(log, fileFormat, "f: running", "ms", ENGINE(engineState.runningFuel), 2);

		reportSensorF(log, fileFormat, "f: wall amt", "v", ENGINE(wallFuel).getWallFuel(0), 2);
		reportSensorF(log, fileFormat, "f: wall crr", "v", ENGINE(wallFuelCorrection), 2);

		reportSensorI(log, fileFormat, "version", "#", getRusEfiVersion());
	}


	if (engineConfiguration->hasVehicleSpeedSensor) {
#if EFI_VEHICLE_SPEED || defined(__DOXYGEN__)
		float vehicleSpeed = getVehicleSpeed();
#else
		float vehicleSpeed = 0;
#endif /* EFI_PROD_CODE */
		reportSensorF(log, fileFormat, "vss", "kph", vehicleSpeed, 2);
		float sp2rpm = rpm == 0 ? 0 : vehicleSpeed / rpm;
		reportSensorF(log, fileFormat, "sp2rpm", "x", sp2rpm, 2);
	}

	reportSensorF(log, fileFormat, "knck_c", "count", engine->knockCount, 0);
	reportSensorF(log, fileFormat, "knck_v", "v", engine->knockVolts, 2);

//	reportSensorF(log, fileFormat, "vref", "V", getVRef(engineConfiguration), 2);

	if (fileFormat) {
		reportSensorF(log, fileFormat, "f: tps delta", "v", engine->tpsAccelEnrichment.getMaxDelta(), 2);
		reportSensorF(log, fileFormat, "f: tps fuel", "ms", engine->engineState.tpsAccelEnrich, 2);

		reportSensorF(log, fileFormat, "f: el delta", "v", engine->engineLoadAccelEnrichment.getMaxDelta(), 2);
		reportSensorF(log, fileFormat, "f: el fuel", "v", engine->engineLoadAccelEnrichment.getEngineLoadEnrichment(PASS_ENGINE_PARAMETER_F) * 100 / getMap(), 2);

		reportSensorF(log, fileFormat, "f: duty", "%", getInjectorDutyCycle(rpm PASS_ENGINE_PARAMETER), 2);
	}


//	debugFloat(&logger, "tch", getTCharge1(tps), 2);

	for (int i = 0;i<FSIO_ADC_COUNT;i++) {
		if (engineConfiguration->fsioAdc[i] != EFI_ADC_NONE) {
			strcpy(buf, "adcX");
			buf[3] = '0' + i;
			reportSensorF(log, fileFormat, buf, "", getVoltage("fsio", engineConfiguration->fsioAdc[i]), 2);
		}
	}

	reportSensorI(log, fileFormat, "warn", "count", engine->engineState.warningCounter);
	reportSensorI(log, fileFormat, "error", "code", engine->engineState.lastErrorCode);

}
Example #26
0
static void showLine(lcd_line_e line, int screenY) {
	static char buffer[10];

	switch (line) {
	case LL_VERSION:
		lcdPrintf("version %s", VCS_VERSION);
		return;
	case LL_CONFIG:
		lcdPrintf("config %s", getConfigurationName(engineConfiguration->engineType));
		return;
	case LL_RPM:
		lcdPrintf("RPM %d", getRpmE(engine));
		{
			char sdState;
			if (boardConfiguration->isSdCardEnabled) {
				sdState = isSdCardAlive() ? 'L' : 'n';
			} else {
				sdState = 'D';
			}
			int seconds = getTimeNowSeconds();
			if (seconds < 10000) {
				lcdPrintf("  %d%c", seconds, sdState);
			}
		}
		return;
	case LL_CLT_TEMPERATURE:
		lcdPrintf("Coolant %f", getCoolantTemperature(PASS_ENGINE_PARAMETER_F));
		return;
	case LL_IAT_TEMPERATURE:
		lcdPrintf("Intake Air %f", getIntakeAirTemperature(PASS_ENGINE_PARAMETER_F));
		return;
	case LL_ALGORITHM:
		lcdPrintf(getEngine_load_mode_e(engineConfiguration->algorithm));
		return;
	case LL_INJECTION:
		lcdPrintf(getInjection_mode_e(engineConfiguration->injectionMode));
		return;
	case LL_ING_FLOW:
		lcdPrintf("Inj %fcc", engineConfiguration->injector.flow);
		return;
	case LL_IGNITION:
		lcdPrintf(getIgnition_mode_e(engineConfiguration->ignitionMode));
		return;
	case LL_TPS:
		getPinNameByAdcChannel(engineConfiguration->tpsAdcChannel, buffer);

		lcdPrintf("Throttle %s %f%%", buffer, getTPS());
		return;
	case LL_VBATT:
		lcdPrintf("Battery %fv", getVBatt(PASS_ENGINE_PARAMETER_F));
		return;
	case LL_KNOCK:
		getPinNameByAdcChannel(engineConfiguration->hipOutputChannel, buffer);
		lcdPrintf("Knock %s %fv", buffer, engine->knockVolts);
		return;

#if	EFI_ANALOG_SENSORS || defined(__DOXYGEN__)
	case LL_BARO:
		if (hasBaroSensor()) {
			lcdPrintf("Baro: %f", getBaroPressure());
		} else {
			lcdPrintf("Baro: none");
		}
		return;
#endif
	case LL_AFR:
		if (engineConfiguration->hasAfrSensor) {
			lcdPrintf("AFR: %f", getAfr());
		} else {
			lcdPrintf("AFR: none");
		}
		return;
	case LL_MAP:
		if (engineConfiguration->hasMapSensor) {
			lcdPrintf("MAP %f", getMap());
		} else {
			lcdPrintf("MAP: none");
		}
		return;
	case LL_MAF_V:
		if (hasMafSensor()) {
			lcdPrintf("MAF: %fv", getMaf());
		} else {
			lcdPrintf("MAF: none");
		}
		return;
	case LL_MAF_KG_HR:
		if (hasMafSensor()) {
			lcdPrintf("MAF: %f kg/hr", getRealMaf());
		} else {
			lcdPrintf("MAF: none");
		}
		return;
	case LL_TRIGGER_ERRORS:
		lcdPrintf("Errors");
		return;
	case LL_TRIGGER_DUTY:
		lcdPrintf("Duty");
		return;
	default:
		lcdPrintf("()");
	}
}