예제 #1
0
/**
 * The idea of this method is to execute all heavy calculations in a lower-priority thread,
 * so that trigger event handler/IO scheduler tasks are faster.
 */
void Engine::periodicFastCallback(DECLARE_ENGINE_PARAMETER_F) {
	int rpm = rpmCalculator.rpmValue;

	if (isValidRpm(rpm)) {
		MAP_sensor_config_s * c = &engineConfiguration->map;
		angle_t start = interpolate2d(rpm, c->samplingAngleBins, c->samplingAngle, MAP_ANGLE_SIZE);

		angle_t offsetAngle = TRIGGER_SHAPE(eventAngles[CONFIG(mapAveragingSchedulingAtIndex)]);

		for (int i = 0; i < engineConfiguration->specs.cylindersCount; i++) {
			angle_t cylinderOffset = getEngineCycle(engineConfiguration->operationMode) * i / engineConfiguration->specs.cylindersCount;
			float cylinderStart = start + cylinderOffset - offsetAngle + tdcPosition();
			fixAngle(cylinderStart, "cylinderStart");
			engine->engineState.mapAveragingStart[i] = cylinderStart;
		}
		engine->engineState.mapAveragingDuration = interpolate2d(rpm, c->samplingWindowBins, c->samplingWindow, MAP_WINDOW_SIZE);
	} else {
		for (int i = 0; i < engineConfiguration->specs.cylindersCount; i++) {
			engine->engineState.mapAveragingStart[i] = NAN;
		}
		engine->engineState.mapAveragingDuration = NAN;
	}

	engineState.periodicFastCallback(PASS_ENGINE_PARAMETER_F);

	engine->m.beforeFuelCalc = GET_TIMESTAMP();
	ENGINE(fuelMs) = getInjectionDuration(rpm PASS_ENGINE_PARAMETER) * engineConfiguration->globalFuelCorrection;
	engine->m.fuelCalcTime = GET_TIMESTAMP() - engine->m.beforeFuelCalc;

}
예제 #2
0
void Engine::checkShutdown() {
#if EFI_MAIN_RELAY_CONTROL || defined(__DOXYGEN__)
	int rpm = rpmCalculator.getRpm();

	const float vBattThreshold = 5.0f;
	if (isValidRpm(rpm) && sensors.vBatt < vBattThreshold && stopEngineRequestTimeNt == 0) {
		stopEngine();
		// todo: add stepper motor parking
	}
#endif /* EFI_MAIN_RELAY_CONTROL */
}
예제 #3
0
/**
 * Schedules a callback 'angle' degree of crankshaft from now.
 * The callback would be executed once after the duration of time which
 * it takes the crankshaft to rotate to the specified angle.
 */
void scheduleByAngle(int rpm, scheduling_s *timer, angle_t angle, schfunc_t callback, void *param) {
	if (!isValidRpm(rpm)) {
		/**
		 * this might happen in case of a single trigger event after a pause - this is normal, so no
		 * warning here
		 */
		return;
	}
	float delayUs = getOneDegreeTimeUs(rpm) * angle;
	if (cisnan(delayUs)) {
		firmwareError("NaN delay?");
		return;
	}
	scheduleTask("by angle", timer, (int) delayUs, callback, param);
}
예제 #4
0
static void auxValveTriggerCallback(trigger_event_e ckpSignalType,
		uint32_t index DECLARE_ENGINE_PARAMETER_SUFFIX) {
	UNUSED(ckpSignalType);
#if EFI_PROD_CODE || EFI_SIMULATOR
	if (index != SCHEDULING_TRIGGER_INDEX) {
		return;
	}
	int rpm = GET_RPM_VALUE;
	if (!isValidRpm(rpm)) {
		return;
	}

	for (int valveIndex = 0; valveIndex < AUX_DIGITAL_VALVE_COUNT;
			valveIndex++) {

		NamedOutputPin *output = &enginePins.auxValve[valveIndex];

		for (int phaseIndex = 0; phaseIndex < 2; phaseIndex++) {
/* I believe a more correct implementation is the following:
 * here we properly account for trigger angle position in engine cycle coordinates
			// todo: at the moment this logic is assuming four-stroke 720-degree engine cycle
			angle_t extra = phaseIndex * 360 // cycle opens twice per 720 engine cycle
					+ valveIndex * 180 // 2nd valve is operating at 180 offset to first
					+ tdcPosition() // engine cycle position to trigger cycle position conversion
					- ENGINE(triggerCentral.triggerShape.eventAngles[SCHEDULING_TRIGGER_INDEX])
					;
*/
			angle_t extra = phaseIndex * 360 + valveIndex * 180;
			angle_t onTime = extra + engine->engineState.auxValveStart;
			fixAngle(onTime, "onTime", CUSTOM_ERR_6556);
			scheduleByAngle(rpm, &turnOnEvent[valveIndex][phaseIndex],
					onTime,
					(schfunc_t) &turnOn, output, &engine->rpmCalculator);
			angle_t offTime = extra + engine->engineState.auxValveEnd;
			fixAngle(offTime, "offTime", CUSTOM_ERR_6557);
			scheduleByAngle(rpm, &turnOffEvent[valveIndex][phaseIndex],
					offTime,
					(schfunc_t) &turnOff, output, &engine->rpmCalculator);

		}
	}

#endif /* EFI_PROD_CODE || EFI_SIMULATOR */
}
예제 #5
0
/**
 * Shaft Position callback used to start or finish HIP integration
 */
static void intHoldCallback(trigger_event_e ckpEventType, uint32_t index DECLARE_ENGINE_PARAMETER_S) {
	// this callback is invoked on interrupt thread
	engine->m.beforeHipCb = GET_TIMESTAMP();
	if (index != 0)
		return;

	int rpm = engine->rpmCalculator.rpmValue;
	if (!isValidRpm(rpm))
		return;

	int structIndex = getRevolutionCounter() % 2;
	// todo: schedule this based on closest trigger event, same as ignition works
	scheduleByAngle(rpm, &startTimer[structIndex], engineConfiguration->knockDetectionWindowStart,
			(schfunc_t) &startIntegration, NULL, &engine->rpmCalculator);
	hipLastExecutionCount = lastExecutionCount;
	scheduleByAngle(rpm, &endTimer[structIndex], engineConfiguration->knockDetectionWindowEnd,
			(schfunc_t) &endIntegration,
			NULL, &engine->rpmCalculator);
	engine->m.hipCbTime = GET_TIMESTAMP() - engine->m.beforeHipCb;
}
예제 #6
0
파일: hip9011.cpp 프로젝트: rusefi/rusefi
/**
 * Shaft Position callback used to start or finish HIP integration
 */
static void intHoldCallback(trigger_event_e ckpEventType, uint32_t index DECLARE_ENGINE_PARAMETER_SUFFIX) {
	(void)ckpEventType;
	// this callback is invoked on interrupt thread
	if (index != 0)
		return;
	engine->m.beforeHipCb = getTimeNowLowerNt();

	int rpm = GET_RPM_VALUE;
	if (!isValidRpm(rpm))
		return;

	int structIndex = getRevolutionCounter() % 2;
	// todo: schedule this based on closest trigger event, same as ignition works
	scheduleByAngle(rpm, &startTimer[structIndex], engineConfiguration->knockDetectionWindowStart,
			(schfunc_t) &startIntegration, NULL, &engine->rpmCalculator);
#if EFI_PROD_CODE
	hipLastExecutionCount = lastExecutionCount;
#endif /* EFI_PROD_CODE */
	scheduleByAngle(rpm, &endTimer[structIndex], engineConfiguration->knockDetectionWindowEnd,
			(schfunc_t) &endIntegration,
			NULL, &engine->rpmCalculator);
	engine->m.hipCbTime = getTimeNowLowerNt() - engine->m.beforeHipCb;
}