Ejemplo n.º 1
0
void registerActuatorEventExt(engine_configuration_s const *engineConfiguration, trigger_shape_s * s, ActuatorEvent *e,
                              OutputSignal *actuator, float angleOffset) {
    efiAssertVoid(s->getSize() > 0, "uninitialized trigger_shape_s");

    if (e == NULL) {
        // error already reported
        return;
    }
    e->actuator = actuator;

    findTriggerPosition(engineConfiguration, s, &e->position, angleOffset);
}
Ejemplo n.º 2
0
void testAngleResolver(void) {
	printf("*************************************************** testAngleResolver\r\n");

	EngineTestHelper eth(FORD_ASPIRE_1996);
	Engine *engine = &eth.engine;

	engine_configuration_s *engineConfiguration = eth.engine.engineConfiguration;

	engineConfiguration->globalTriggerAngleOffset = 175;
	assertTrue(engine->engineConfiguration2!=NULL);
	trigger_shape_s * ts = &engine->triggerShape;

	confgiureFordAspireTriggerShape(ts);

	ts->calculateTriggerSynchPoint(engineConfiguration, engine);

	assertEqualsM("index 2", 228.0450, ts->eventAngles[3]); // this angle is relation to synch point
	assertEqualsM("time 2", 0.3233, ts->wave.getSwitchTime(2));
	assertEqualsM("index 5", 413.7470, ts->eventAngles[6]);
	assertEqualsM("time 5", 0.5692, ts->wave.getSwitchTime(5));

	assertEquals(4, ts->getTriggerShapeSynchPointIndex());

	assertEqualsM("shape size", 10, ts->getSize());

	OutputSignalList list;

	ae.resetEventList();
	printf("*************************************************** testAngleResolver 0\r\n");
	findTriggerPosition(&ae.getNextActuatorEvent()->position, 53 - 175 PASS_ENGINE_PARAMETER);
	assertEqualsM("size", 1, ae.size);
	assertEquals(1, ae.events[0].position.eventIndex);
	assertEquals(3.1588, ae.events[0].position.angleOffset);

	printf("*************************************************** testAngleResolver 2\r\n");
	ae.resetEventList();
	findTriggerPosition(&ae.getNextActuatorEvent()->position, 51 + 180 - 175 PASS_ENGINE_PARAMETER);
	assertEquals(2, ae.events[0].position.eventIndex);
	assertEquals(112.3495, ae.events[0].position.angleOffset);
}
Ejemplo n.º 3
0
static void registerSparkEvent(engine_configuration_s const *engineConfiguration, trigger_shape_s * s,
                               IgnitionEventList *list, io_pin_e pin, float localAdvance, float dwell) {

    IgnitionEvent *event = list->getNextActuatorEvent();
    if (event == NULL)
        return; // error already reported

    event->io_pin = pin;

    event->advance = localAdvance;

    findTriggerPosition(engineConfiguration, s, &event->dwellPosition, localAdvance - dwell);
}
Ejemplo n.º 4
0
static ALWAYS_INLINE void handleSparkEvent(uint32_t eventIndex, IgnitionEvent *iEvent,
		int rpm DECLARE_ENGINE_PARAMETER_S) {

	float dwellMs = engine->engineState.sparkDwell;
	if (cisnan(dwellMs) || dwellMs < 0) {
		firmwareError("invalid dwell: %f at %d", dwellMs, rpm);
		return;
	}

	floatus_t chargeDelayUs = engine->rpmCalculator.oneDegreeUs * iEvent->dwellPosition.angleOffset;
	int isIgnitionError = chargeDelayUs < 0;
	ignitionErrorDetection.add(isIgnitionError);
	if (isIgnitionError) {
#if EFI_PROD_CODE
		scheduleMsg(logger, "Negative spark delay=%f", chargeDelayUs);
#endif
		chargeDelayUs = 0;
		return;
	}

	if (cisnan(dwellMs)) {
		firmwareError("NaN in scheduleOutput", dwellMs);
		return;
	}

	/**
	 * We are alternating two event lists in order to avoid a potential issue around revolution boundary
	 * when an event is scheduled within the next revolution.
	 */
	scheduling_s * sUp = &iEvent->signalTimerUp;
	scheduling_s * sDown = &iEvent->signalTimerDown;

	/**
	 * The start of charge is always within the current trigger event range, so just plain time-based scheduling
	 */
	scheduleTask("spark up", sUp, chargeDelayUs, (schfunc_t) &turnPinHigh, iEvent->output);
	/**
	 * Spark event is often happening during a later trigger event timeframe
	 * TODO: improve precision
	 */

	findTriggerPosition(&iEvent->sparkPosition, iEvent->advance PASS_ENGINE_PARAMETER);

	if (iEvent->sparkPosition.eventIndex == eventIndex) {
		/**
		 * Spark should be fired before the next trigger event - time-based delay is best precision possible
		 */
		float timeTillIgnitionUs = engine->rpmCalculator.oneDegreeUs * iEvent->sparkPosition.angleOffset;

		scheduleTask("spark 1down", sDown, (int) timeTillIgnitionUs, (schfunc_t) &turnPinLow, iEvent->output);
	} else {
		/**
		 * Spark should be scheduled in relation to some future trigger event, this way we get better firing precision
		 */
		bool isPending = assertNotInList<IgnitionEvent>(iHead, iEvent);
		if (isPending)
			return;

		LL_APPEND(iHead, iEvent);
	}
}