static ALWAYS_INLINE void handleFuel(uint32_t eventIndex, int rpm DECLARE_ENGINE_PARAMETER_S) {
	if (!isInjectionEnabled(engine->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 =
	isCrankingR(rpm) ?
			&ENGINE(engineConfiguration2)->crankingInjectionEvents : &engine->engineConfiguration2->injectionEvents;

	InjectionEventList *source = &fs->events;

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

	engine->tpsAccelEnrichment.onEngineCycleTps(PASS_ENGINE_PARAMETER_F);

	engine->mapAccelEnrichment.onEngineCycle(PASS_ENGINE_PARAMETER_F);
	ENGINE(fuelMs) = getFuelMs(rpm PASS_ENGINE_PARAMETER) * engineConfiguration->globalFuelCorrection;

	for (int i = 0; i < source->size; i++) {
		InjectionEvent *event = &source->elements[i];
		if (event->injectionStart.eventIndex != eventIndex)
			continue;
		handleFuelInjectionEvent(event, rpm PASS_ENGINE_PARAMETER);
	}
}
Beispiel #2
0
void vappendPrintf(Logging *logging, const char *fmt, va_list arg) {
	efiAssertVoid(getRemainingStack(chThdSelf()) > 16, "stack#5b");
	if (!intermediateLoggingBufferInited) {
		firmwareError("intermediateLoggingBufferInited not inited!");
		return;
	}
	int is_locked = isLocked();
	int icsr_vectactive = isIsrContext();
	if (is_locked) {
		vappendPrintfI(logging, fmt, arg);
	} else {
		if (icsr_vectactive == 0) {
			chSysLock()
			;
			vappendPrintfI(logging, fmt, arg);
			chSysUnlock()
			;
		} else {
			chSysLockFromIsr()
			;
			vappendPrintfI(logging, fmt, arg);
			chSysUnlockFromIsr()
			;
		}
	}
}
Beispiel #3
0
void doSlowAdc(void) {

	efiAssertVoid(CUSTOM_ERR_6658, getRemainingStack(chThdGetSelfX())> 32, "lwStAdcSlow");

#if EFI_INTERNAL_ADC

	/* Starts an asynchronous ADC conversion operation, the conversion
	 will be executed in parallel to the current PWM cycle and will
	 terminate before the next PWM cycle.*/
	slowAdc.conversionCount++;
	chSysLockFromISR()
	;
	if (ADC_SLOW_DEVICE.state != ADC_READY &&
	ADC_SLOW_DEVICE.state != ADC_COMPLETE &&
	ADC_SLOW_DEVICE.state != ADC_ERROR) {
		// todo: why and when does this happen? firmwareError(OBD_PCM_Processor_Fault, "ADC slow not ready?");
		slowAdc.errorsCount++;
		chSysUnlockFromISR()
		;
		return;
	}
	adcStartConversionI(&ADC_SLOW_DEVICE, &adcgrpcfgSlow, slowAdc.samples, ADC_BUF_DEPTH_SLOW);
	chSysUnlockFromISR()
	;
#endif /* EFI_INTERNAL_ADC */
}
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);
	}
}
Beispiel #5
0
static void pwmpcb_slow(PWMDriver *pwmp) {
	efiAssertVoid(getRemainingStack(chThdSelf())> 32, "lwStAdcSlow");

#if EFI_INTERNAL_ADC
	(void) pwmp;

	/* Starts an asynchronous ADC conversion operation, the conversion
	 will be executed in parallel to the current PWM cycle and will
	 terminate before the next PWM cycle.*/
	slowAdc.conversionCount++;
	chSysLockFromIsr()
	;
	if (ADC_SLOW_DEVICE.state != ADC_READY &&
	ADC_SLOW_DEVICE.state != ADC_COMPLETE &&
	ADC_SLOW_DEVICE.state != ADC_ERROR) {
		// todo: why and when does this happen? firmwareError("ADC slow not ready?");
		slowAdc.errorsCount++;
		chSysUnlockFromIsr()
		;
		return;
	}
	adcStartConversionI(&ADC_SLOW_DEVICE, &adcgrpcfgSlow, slowAdc.samples, ADC_BUF_DEPTH_SLOW);
	chSysUnlockFromIsr()
	;
#endif
}
Beispiel #6
0
/**
 * This method is not in the adc* lower-level file because it is more business logic then hardware.
 */
void adc_callback_fast(ADCDriver *adcp, adcsample_t *buffer, size_t n) {

	(void) buffer;
	(void) n;
	/**
	 * Note, only in the ADC_COMPLETE state because the ADC driver fires an
	 * intermediate callback when the buffer is half full.
	 * */
	if (adcp->state == ADC_COMPLETE) {
		/**
		 * this callback is executed 10 000 times a second, it needs to be as fast as possible
		 */
		efiAssertVoid(CUSTOM_ERR_6676, getRemainingStack(chThdGetSelfX()) > 128, "lowstck#9b");

#if EFI_MAP_AVERAGING
		mapAveragingAdcCallback(fastAdc.samples[fastMapSampleIndex]);
#endif /* EFI_MAP_AVERAGING */
#if EFI_HIP_9011 || defined(__DOXYGEN__)
		if (CONFIGB(isHip9011Enabled)) {
			hipAdcCallback(fastAdc.samples[hipSampleIndex]);
		}
#endif
//		if (tpsSampleIndex != TPS_IS_SLOW) {
//			tpsFastAdc = fastAdc.samples[tpsSampleIndex];
//		}
	}
}
Beispiel #7
0
void readFromFlash(void) {
	efiAssertVoid(getRemainingStack(chThdSelf()) > 256, "read f");
	printMsg(logger, "readFromFlash()");
	flashRead(FLASH_ADDR, (char *) &persistentState, PERSISTENT_SIZE);

	persisted_configuration_state_e result;

	if (!isValidCrc(&persistentState)) {
		result = CRC_FAILED;
		resetConfigurationExt(logger, DEFAULT_ENGINE_TYPE PASS_ENGINE_PARAMETER);
	} else if (persistentState.version != FLASH_DATA_VERSION || persistentState.size != PERSISTENT_SIZE) {
		result = INCOMPATIBLE_VERSION;
		resetConfigurationExt(logger, engineConfiguration->engineType PASS_ENGINE_PARAMETER);
	} else {
		/**
		 * At this point we know that CRC and version number is what we expect. Safe to assume it's a valid configuration.
		 */
		result = OK;
		applyNonPersistentConfiguration(logger PASS_ENGINE_PARAMETER);
	}
	// we can only change the state after the CRC check
	engineConfiguration->firmwareVersion = getRusEfiVersion();

	if (result == CRC_FAILED) {
		printMsg(logger, "Need to reset flash to default due to CRC");
	} else if (result == INCOMPATIBLE_VERSION) {
		printMsg(logger, "Resetting but saving engine type [%d]", engineConfiguration->engineType);
	} else {
		printMsg(logger, "Got valid configuration from flash!");
	}
}
Beispiel #8
0
void runConsoleLoop(ts_channel_s *console) {
	if (boardConfiguration->startConsoleInBinaryMode) {
		// switch to binary protocol
		consoleInBinaryMode = true;
		runBinaryProtocolLoop(console, true);
	}

	while (true) {
		efiAssertVoid(getRemainingStack(chThdGetSelfX()) > 256, "lowstck#9e");
		bool end = getConsoleLine((BaseSequentialStream*) console->channel, console->crcReadBuffer, sizeof(console->crcReadBuffer) - 3);
		if (end) {
			// firmware simulator is the only case when this happens
			continue;
		}

		char *trimmed = efiTrim(console->crcReadBuffer);

		(console_line_callback)(trimmed);

		if (consoleInBinaryMode) {
#if EFI_SIMULATOR || defined(__DOXYGEN__)
			logMsg("Switching to binary mode\r\n");
#endif
			// switch to binary protocol
			runBinaryProtocolLoop(console, true);
		}
	}
}
Beispiel #9
0
static void pwmpcb_fast(PWMDriver *pwmp) {
	efiAssertVoid(CUSTOM_ERR_6659, getRemainingStack(chThdGetSelfX())> 32, "lwStAdcFast");
#if EFI_INTERNAL_ADC
	(void) pwmp;

	/*
	 * Starts an asynchronous ADC conversion operation, the conversion
	 * will be executed in parallel to the current PWM cycle and will
	 * terminate before the next PWM cycle.
	 */
	chSysLockFromISR()
	;
	if (ADC_FAST_DEVICE.state != ADC_READY &&
	ADC_FAST_DEVICE.state != ADC_COMPLETE &&
	ADC_FAST_DEVICE.state != ADC_ERROR) {
		fastAdc.errorsCount++;
		// todo: when? why? firmwareError(OBD_PCM_Processor_Fault, "ADC fast not ready?");
		chSysUnlockFromISR()
		;
		return;
	}
	adcStartConversionI(&ADC_FAST_DEVICE, &adcgrpcfg_fast, fastAdc.samples, ADC_BUF_DEPTH_FAST);
	chSysUnlockFromISR()
	;
	fastAdc.conversionCount++;
#endif /* EFI_INTERNAL_ADC */
}
Beispiel #10
0
void appendPrintf(Logging *logging, const char *fmt, ...) {
	efiAssertVoid(getRemainingStack(chThdSelf()) > 128, "lowstck#4");
	va_list ap;
	va_start(ap, fmt);
	vappendPrintf(logging, fmt, ap);
	va_end(ap);
}
Beispiel #11
0
static void vappendPrintfI(Logging *logging, const char *fmt, va_list arg) {
	intermediateLoggingBuffer.eos = 0; // reset
	efiAssertVoid(getRemainingStack(chThdSelf()) > 128, "lowstck#1b");
	chvprintf((BaseSequentialStream *) &intermediateLoggingBuffer, fmt, arg);
	intermediateLoggingBuffer.buffer[intermediateLoggingBuffer.eos] = 0; // need to terminate explicitly
	append(logging, (char *) intermediateLoggingBufferData);
}
Beispiel #12
0
static void executorCallback(void *arg) {
	(void)arg;
	efiAssertVoid(getRemainingStack(chThdSelf()) > 256, "lowstck#2y");

//	callbackTime = getTimeNowNt();
//	if((callbackTime > nextEventTimeNt) && (callbackTime - nextEventTimeNt > US2NT(5000))) {
//		timerIsLate++;
//	}

	instance.onTimerCallback();
}
Beispiel #13
0
/**
 * this method acquires system lock to guard the shared intermediateLoggingBuffer memory stream
 */
void vappendPrintf(Logging *logging, const char *fmt, va_list arg) {
	efiAssertVoid(getRemainingStack(chThdSelf()) > 128, "lowstck#5b");
	if (!intermediateLoggingBufferInited) {
		firmwareError("intermediateLoggingBufferInited not inited!");
		return;
	}
	int wasLocked = lockAnyContext();
	vappendPrintfI(logging, fmt, arg);
	if (!wasLocked) {
		unlockAnyContext();
	}
}
Beispiel #14
0
/**
 * This method would output a simple console message immediately.
 * This method should only be invoked on main thread because only the main thread can write to the console
 */
void printMsg(Logging *logger, const char *fmt, ...) {
	efiAssertVoid(getRemainingStack(chThdSelf()) > 128, "lowstck#5o");
//	resetLogging(logging); // I guess 'reset' is not needed here?
	appendMsgPrefix(logger);

	va_list ap;
	va_start(ap, fmt);
	vappendPrintf(logger, fmt, ap);
	va_end(ap);

	append(logger, DELIMETER);
	printLine(logger);
}
Beispiel #15
0
void hwHandleShaftSignal(trigger_event_e signal) {
	triggerHanlderEntryTime = GET_TIMESTAMP();
	isInsideTriggerHandler = true;
	if (triggerReentraint > maxTriggerReentraint)
		maxTriggerReentraint = triggerReentraint;
	triggerReentraint++;
	efiAssertVoid(getRemainingStack(chThdSelf()) > 128, "lowstck#8");
	triggerCentral.handleShaftSignal(signal PASS_ENGINE_PARAMETER);
	triggerReentraint--;
	triggerDuration = GET_TIMESTAMP() - triggerHanlderEntryTime;
	isInsideTriggerHandler = false;
	if (triggerDuration > triggerMaxDuration)
		triggerMaxDuration = triggerDuration;
}
Beispiel #16
0
void tunerStudioWriteData(ts_channel_s *tsChannel, const uint8_t * buffer, int size) {
        efiAssertVoid(getRemainingStack(chThdSelf()) > 64, "tunerStudioWriteData");
#if EFI_SIMULATOR || defined(__DOXYGEN__)
			logMsg("chSequentialStreamWrite [%d]\r\n", size);
#endif
	int transferred = chnWriteTimeout(tsChannel->channel, buffer, size, BINARY_IO_TIMEOUT);
#if EFI_SIMULATOR || defined(__DOXYGEN__)
			logMsg("transferred [%d]\r\n", transferred);
#endif
	if (transferred != size) {
#if EFI_SIMULATOR || defined(__DOXYGEN__)
			logMsg("!!! NOT ACCEPTED %d out of %d !!!", transferred, size);
#endif
		scheduleMsg(&tsLogger, "!!! NOT ACCEPTED %d out of %d !!!", transferred, size);
	}
}
Beispiel #17
0
static void adc_callback_slow(ADCDriver *adcp, adcsample_t *buffer, size_t n) {
	(void) buffer;
	(void) n;
	efiAssertVoid(getRemainingStack(chThdSelf()) > 128, "lowstck#9c");
	/* Note, only in the ADC_COMPLETE state because the ADC driver fires
	 * an intermediate callback when the buffer is half full. */
	if (adcp->state == ADC_COMPLETE) {
		/* Calculates the average values from the ADC samples.*/
		for (int i = 0; i < slowAdc.size(); i++) {
			int value = getAvgAdcValue(i, slowAdc.samples, ADC_BUF_DEPTH_SLOW, slowAdc.size());
			adcsample_t prev = slowAdc.values.adc_data[i];
			slowAdc.values.adc_data[i] = (slowAdcCounter == 0) ? value :
					CONFIG(slowAdcAlpha) * value + (1 - CONFIG(slowAdcAlpha)) * prev;
		}
		slowAdcCounter++;
	}
}
Beispiel #18
0
/**
 * @brief Shaft position callback used by RPM calculation logic.
 *
 * This callback should always be the first of trigger callbacks because other callbacks depend of values
 * updated here.
 * This callback is invoked on interrupt thread.
 */
void rpmShaftPositionCallback(trigger_event_e ckpSignalType, uint32_t index DECLARE_ENGINE_PARAMETER_S) {
	RpmCalculator *rpmState = &engine->rpmCalculator;
	uint64_t nowNt = getTimeNowNt();
#if EFI_PROD_CODE
	efiAssertVoid(getRemainingStack(chThdSelf()) > 256, "lowstck#2z");
#endif

	if (index != 0) {
#if EFI_ANALOG_CHART || defined(__DOXYGEN__)
		if (boardConfiguration->analogChartMode == AC_TRIGGER)
			acAddData(getCrankshaftAngleNt(nowNt PASS_ENGINE_PARAMETER), 1000 * ckpSignalType + index);
#endif
		return;
	}

	bool hadRpmRecently = rpmState->isRunning(PASS_ENGINE_PARAMETER_F);

	if (hadRpmRecently) {
		uint64_t diffNt = nowNt - rpmState->lastRpmEventTimeNt;
		/**
		 * Four stroke cycle is two crankshaft revolutions
		 *
		 * We always do '* 2' because the event signal is already adjusted to 'per engine cycle'
		 * and each revolution of crankshaft consists of two engine cycles revolutions
		 *
		 */
		if (diffNt == 0) {
			rpmState->setRpmValue(NOISY_RPM);
		} else {
			int mult = engineConfiguration->engineCycle / 360;
			int rpm = (int) (60 * US2NT(US_PER_SECOND_LL) * mult / diffNt);
			rpmState->setRpmValue(rpm > UNREALISTIC_RPM ? NOISY_RPM : rpm);
		}
	}
	rpmState->onNewEngineCycle();
	rpmState->lastRpmEventTimeNt = nowNt;
#if EFI_ANALOG_CHART || defined(__DOXYGEN__)
	if (boardConfiguration->analogChartMode == AC_TRIGGER)
		acAddData(getCrankshaftAngleNt(nowNt PASS_ENGINE_PARAMETER), index);
#endif
}
Beispiel #19
0
static void adc_callback_slow(ADCDriver *adcp, adcsample_t *buffer, size_t n) {
	(void) buffer;
	(void) n;
	efiAssertVoid(getRemainingStack(chThdSelf()) > 128, "lowstck#9c");
	/* Note, only in the ADC_COMPLETE state because the ADC driver fires
	 * an intermediate callback when the buffer is half full. */
	if (adcp->state == ADC_COMPLETE) {
		/* Calculates the average values from the ADC samples.*/

		adcCallbackCounter_slow++;

//		newState.time = chimeNow();
		for (int i = 0; i < slowAdc.size(); i++) {
			/**
			 * todo: No need to average since DEPTH is '1'
			 */
			int value = getAvgAdcValue(i, slowAdc.samples, ADC_BUF_DEPTH_SLOW, slowAdc.size());
			slowAdc.values.adc_data[i] = value;
		}
	}
}
Beispiel #20
0
static msg_t consoleThreadThreadEntryPoint(void *arg) {
	(void) arg;
	chRegSetThreadName("console thread");

#if (EFI_PROD_CODE && EFI_USB_SERIAL) || defined(__DOXYGEN__)
	if (!isSerialOverUart()) {
		/**
		 * This method contains a long delay, that's the reason why this is not done on the main thread
		 */
		usb_serial_start();
	}
#endif /* EFI_PROD_CODE */

	binaryConsole.channel = (BaseChannel *) getConsoleChannel();

	while (true) {
		efiAssert(getRemainingStack(chThdSelf()) > 256, "lowstck#9e", 0);
		bool end = getConsoleLine((BaseSequentialStream*) getConsoleChannel(), consoleInput, sizeof(consoleInput));
		if (end) {
			// firmware simulator is the only case when this happens
			continue;
		}

		char *trimmed = efiTrim(consoleInput);

		(console_line_callback)(trimmed);

		if (consoleInBinaryMode) {
#if EFI_SIMULATOR || defined(__DOXYGEN__)
			logMsg("Switching to binary mode\r\n");
#endif
			// switch to binary protocol
			runBinaryProtocolLoop(&binaryConsole, true);
		}
	}
#if defined __GNUC__
	return false;
#endif        
}
Beispiel #21
0
void sr5WriteData(ts_channel_s *tsChannel, const uint8_t * buffer, int size) {
        efiAssertVoid(CUSTOM_ERR_6570, getRemainingStack(chThdGetSelfX()) > 64, "tunerStudioWriteData");
#if EFI_SIMULATOR || defined(__DOXYGEN__)
			logMsg("chSequentialStreamWrite [%d]\r\n", size);
#endif

#if TS_UART_DMA_MODE && EFI_PROD_CODE
	UNUSED(tsChannel);
	int transferred = size;
	uartSendTimeout(TS_DMA_UART_DEVICE, (size_t *)&transferred, buffer, BINARY_IO_TIMEOUT);
#else
	if (tsChannel->channel == NULL)
		return;

//	int transferred = chnWriteTimeout(tsChannel->channel, buffer, size, BINARY_IO_TIMEOUT);
	// temporary attempt to work around #553
	// instead of one huge packet let's try sending a few smaller packets
	int transferred = 0;
	int stillToTransfer = size;
	while (stillToTransfer > 0) {
		int thisTransferSize = minI(stillToTransfer, 768);
		transferred += chnWriteTimeout(tsChannel->channel, buffer, thisTransferSize, BINARY_IO_TIMEOUT);
		buffer += thisTransferSize;
		stillToTransfer -= thisTransferSize;
	}

#endif

#if EFI_SIMULATOR || defined(__DOXYGEN__)
			logMsg("transferred [%d]\r\n", transferred);
#endif
	if (transferred != size) {
#if EFI_SIMULATOR || defined(__DOXYGEN__)
			logMsg("!!! NOT ACCEPTED %d out of %d !!!", transferred, size);
#endif /* EFI_SIMULATOR */
		scheduleMsg(&tsLogger, "!!! NOT ACCEPTED %d out of %d !!!", transferred, size);
	}
}
Beispiel #22
0
/**
 * this method could and should be executed before we have any
 * connectivity so no console output here
 */
persisted_configuration_state_e readConfiguration(Logging * logger) {
	efiAssert(getRemainingStack(chThdSelf()) > 256, "read f", PC_ERROR);
	flashRead(FLASH_ADDR, (char *) &persistentState, PERSISTENT_SIZE);

	persisted_configuration_state_e result;
	if (!isValidCrc(&persistentState)) {
		result = CRC_FAILED;
		warning(CUSTOM_ERR_FLASH_CRC_FAILED, "flash CRC failed");
		resetConfigurationExt(logger, DEFAULT_ENGINE_TYPE PASS_ENGINE_PARAMETER);
	} else if (persistentState.version != FLASH_DATA_VERSION || persistentState.size != PERSISTENT_SIZE) {
		result = INCOMPATIBLE_VERSION;
		resetConfigurationExt(logger, engineConfiguration->engineType PASS_ENGINE_PARAMETER);
	} else {
		/**
		 * At this point we know that CRC and version number is what we expect. Safe to assume it's a valid configuration.
		 */
		result = OK;
		applyNonPersistentConfiguration(logger PASS_ENGINE_PARAMETER);
	}
	// we can only change the state after the CRC check
	engineConfiguration->byFirmwareVersion = getRusEfiVersion();
	return result;
}
Beispiel #23
0
static void periodicSlowCallback(Engine *engine) {
	efiAssertVoid(getRemainingStack(chThdSelf()) > 64, "lowStckOnEv");
#if EFI_PROD_CODE
	/**
	 * We need to push current value into the 64 bit counter often enough so that we do not miss an overflow
	 */
	bool alreadyLocked = lockAnyContext();
	updateAndSet(&halTime.state, hal_lld_get_counter_value());
	if (!alreadyLocked) {
		unlockAnyContext();
	}
#endif

	if (!engine->rpmCalculator.isRunning()) {
#if (EFI_PROD_CODE && EFI_ENGINE_CONTROL && EFI_INTERNAL_FLASH) || defined(__DOXYGEN__)
		writeToFlashIfPending();
#endif
		resetAccel();
	}

	if (versionForConfigurationListeners.isOld()) {
		updateAccelParameters();
		engine->engineState.warmupAfrPid.reset();
	}

	engine->watchdog();
	engine->updateSlowSensors();

#if (EFI_PROD_CODE && EFI_FSIO) || defined(__DOXYGEN__)
	runFsio();
#endif

	cylinderCleanupControl(engine);

	scheduleNextSlowInvocation();
}
Beispiel #24
0
/**
 * @brief	Register an event for digital sniffer
 */
void WaveChart::addEvent3(const char *name, const char * msg) {
#if EFI_TEXT_LOGGING || defined(__DOXYGEN__)
	if (!ENGINE(isEngineChartEnabled)) {
		return;
	}
	if (skipUntilEngineCycle != 0 && ENGINE(rpmCalculator.getRevolutionCounter()) < skipUntilEngineCycle)
		return;
	efiAssertVoid(CUSTOM_ERR_6651, name!=NULL, "WC: NULL name");

#if EFI_PROD_CODE
	efiAssertVoid(CUSTOM_ERR_6652, getRemainingStack(chThdGetSelfX()) > 32, "lowstck#2c");
#endif

	efiAssertVoid(CUSTOM_ERR_6653, isInitialized, "chart not initialized");
#if DEBUG_WAVE
	scheduleSimpleMsg(&debugLogging, "current", chart->counter);
#endif
	if (isFull()) {
		return;
	}

#if EFI_HISTOGRAMS && EFI_PROD_CODE
	int beforeCallback = hal_lld_get_counter_value();
#endif

	efitick_t nowNt = getTimeNowNt();

	bool alreadyLocked = lockOutputBuffer(); // we have multiple threads writing to the same output buffer

	if (counter == 0) {
		startTimeNt = nowNt;
	}
	counter++;

	/**
	 * We want smaller times within a chart in order to reduce packet size.
	 */
	/**
	 * todo: migrate to binary fractions in order to eliminate
	 * this division? I do not like division
	 *
	 * at least that's 32 bit division now
	 */
	uint32_t diffNt = nowNt - startTimeNt;
	uint32_t time100 = NT2US(diffNt / 10);

	if (remainingSize(&logging) > 35) {
		/**
		 * printf is a heavy method, append is used here as a performance optimization
		 */
		appendFast(&logging, name);
		appendChar(&logging, CHART_DELIMETER);
		appendFast(&logging, msg);
		appendChar(&logging, CHART_DELIMETER);
//		time100 -= startTime100;

		itoa10(timeBuffer, time100);
		appendFast(&logging, timeBuffer);
		appendChar(&logging, CHART_DELIMETER);
		logging.linePointer[0] = 0;
	}
	if (!alreadyLocked) {
		unlockOutputBuffer();
	}

#if EFI_HISTOGRAMS && EFI_PROD_CODE
	int64_t diff = hal_lld_get_counter_value() - beforeCallback;
	if (diff > 0) {
		hsAdd(&engineSnifferHisto, diff);
	}
#endif /* EFI_HISTOGRAMS */
#endif /* EFI_TEXT_LOGGING */
}
Beispiel #25
0
	addSkippedToothTriggerEvents(T_SECONDARY, s, totalTeethCount, skippedCount, 0.5, 360, 360, NO_LEFT_FILTER,
	NO_RIGHT_FILTER);

	s->isSynchronizationNeeded = false;
}

static TriggerState state CCM_OPTIONAL;

/**
 * External logger is needed because at this point our logger is not yet initialized
 */
void TriggerShape::initializeTriggerShape(Logging *logger DECLARE_ENGINE_PARAMETER_S) {
	const trigger_config_s *triggerConfig = &engineConfiguration->trigger;
#if EFI_PROD_CODE || defined(__DOXYGEN__)
	efiAssertVoid(getRemainingStack(chThdSelf()) > 256, "init t");
	scheduleMsg(logger, "initializeTriggerShape(%s/%d)", getTrigger_type_e(triggerConfig->type), (int) triggerConfig->type);
#endif
	TriggerShape *triggerShape = this;


	switch (triggerConfig->type) {

	case TT_TOOTHED_WHEEL:
		initializeSkippedToothTriggerShapeExt(triggerShape, triggerConfig->customTotalToothCount,
				triggerConfig->customSkippedToothCount, engineConfiguration->operationMode);
		break;

	case TT_MAZDA_MIATA_NA:
		initializeMazdaMiataNaShape(triggerShape PASS_ENGINE_PARAMETER);
		break;
Beispiel #26
0
void initHardware(Logging *l) {
	efiAssertVoid(CUSTOM_IH_STACK, getRemainingStack(chThdGetSelfX()) > 256, "init h");
	sharedLogger = l;
	engine_configuration_s *engineConfiguration = engine->engineConfigurationPtr;
	efiAssertVoid(CUSTOM_EC_NULL, engineConfiguration!=NULL, "engineConfiguration");
	board_configuration_s *boardConfiguration = &engineConfiguration->bc;

	printMsg(sharedLogger, "initHardware()");
	// todo: enable protection. it's disabled because it takes
	// 10 extra seconds to re-flash the chip
	//flashProtect();

	chMtxObjectInit(&spiMtx);

#if EFI_HISTOGRAMS
	/**
	 * histograms is a data structure for CPU monitor, it does not depend on configuration
	 */
	initHistogramsModule();
#endif /* EFI_HISTOGRAMS */

	/**
	 * We need the LED_ERROR pin even before we read configuration
	 */
	initPrimaryPins();

	if (hasFirmwareError()) {
		return;
	}

#if EFI_INTERNAL_FLASH

	palSetPadMode(CONFIG_RESET_SWITCH_PORT, CONFIG_RESET_SWITCH_PIN, PAL_MODE_INPUT_PULLUP);

	initFlash(sharedLogger);
	/**
	 * this call reads configuration from flash memory or sets default configuration
	 * if flash state does not look right.
	 */
	if (SHOULD_INGORE_FLASH()) {
		engineConfiguration->engineType = DEFAULT_ENGINE_TYPE;
		resetConfigurationExt(sharedLogger, engineConfiguration->engineType PASS_ENGINE_PARAMETER_SUFFIX);
		writeToFlashNow();
	} else {
		readFromFlash();
	}
#else
	engineConfiguration->engineType = DEFAULT_ENGINE_TYPE;
	resetConfigurationExt(sharedLogger, engineConfiguration->engineType PASS_ENGINE_PARAMETER_SUFFIX);
#endif /* EFI_INTERNAL_FLASH */

#if EFI_HD44780_LCD
//	initI2Cmodule();
	lcd_HD44780_init(sharedLogger);
	if (hasFirmwareError())
		return;

	lcd_HD44780_print_string(VCS_VERSION);

#endif /* EFI_HD44780_LCD */

	if (hasFirmwareError()) {
		return;
	}

#if EFI_SHAFT_POSITION_INPUT || defined(__DOXYGEN__)
	initTriggerDecoder();
#endif

	bool isBoardTestMode_b;
	if (CONFIGB(boardTestModeJumperPin) != GPIO_UNASSIGNED) {
		efiSetPadMode("board test", CONFIGB(boardTestModeJumperPin),
		PAL_MODE_INPUT_PULLUP);
		isBoardTestMode_b = (!efiReadPin(CONFIGB(boardTestModeJumperPin)));

		// we can now relese this pin, it is actually used as output sometimes
		unmarkPin(CONFIGB(boardTestModeJumperPin));
	} else {
		isBoardTestMode_b = false;
	}

#if HAL_USE_ADC || defined(__DOXYGEN__)
	initAdcInputs(isBoardTestMode_b);
#endif

	if (isBoardTestMode_b) {
		// this method never returns
		initBoardTest();
	}

	initRtc();

	initOutputPins();

#if EFI_MAX_31855
	initMax31855(sharedLogger, getSpiDevice(CONFIGB(max31855spiDevice)), CONFIGB(max31855_cs));
#endif /* EFI_MAX_31855 */

#if EFI_CAN_SUPPORT
	initCan();
#endif /* EFI_CAN_SUPPORT */

//	init_adc_mcp3208(&adcState, &SPID2);
//	requestAdcValue(&adcState, 0);

#if EFI_SHAFT_POSITION_INPUT || defined(__DOXYGEN__)
	// todo: figure out better startup logic
	initTriggerCentral(sharedLogger);
#endif /* EFI_SHAFT_POSITION_INPUT */

	turnOnHardware(sharedLogger);


#if HAL_USE_SPI || defined(__DOXYGEN__)
	initSpiModules(boardConfiguration);
#endif

#if EFI_HIP_9011 || defined(__DOXYGEN__)
	initHip9011(sharedLogger);
#endif /* EFI_HIP_9011 */

#if EFI_FILE_LOGGING || defined(__DOXYGEN__)
	initMmcCard();
#endif /* EFI_FILE_LOGGING */

#if EFI_MEMS || defined(__DOXYGEN__)
	initAccelerometer(PASS_ENGINE_PARAMETER_SIGNATURE);
#endif
//	initFixedLeds();


#if EFI_BOSCH_YAW || defined(__DOXYGEN__)
	initBoschYawRateSensor();
#endif /* EFI_BOSCH_YAW */

	//	initBooleanInputs();

#if EFI_UART_GPS || defined(__DOXYGEN__)
	initGps();
#endif

#if EFI_SERVO
	initServo();
#endif

#if ADC_SNIFFER || defined(__DOXYGEN__)
	initAdcDriver();
#endif

#if HAL_USE_I2C || defined(__DOXYGEN__)
	addConsoleActionII("i2c", sendI2Cbyte);
#endif


//	USBMassStorageDriver UMSD1;

//	while (true) {
//		for (int addr = 0x20; addr < 0x28; addr++) {
//			sendI2Cbyte(addr, 0);
//			int err = i2cGetErrors(&I2CD1);
//			print("I2C: err=%x from %d\r\n", err, addr);
//			chThdSleepMilliseconds(5);
//			sendI2Cbyte(addr, 255);
//			chThdSleepMilliseconds(5);
//		}
//	}

#if EFI_VEHICLE_SPEED || defined(__DOXYGEN__)
	initVehicleSpeed(sharedLogger);
#endif

#if EFI_CDM_INTEGRATION
	cdmIonInit();
#endif

#if HAL_USE_EXT || defined(__DOXYGEN__)
	initJoystick(sharedLogger);
#endif

	calcFastAdcIndexes();

	printMsg(sharedLogger, "initHardware() OK!");
}
Beispiel #27
0
/**
 * Only one consumer can use SPI bus at a given time
 */
void lockSpi(spi_device_e device) {
	efiAssertVoid(CUSTOM_ERR_6674, getRemainingStack(chThdGetSelfX()) > 128, "lockSpi");
	// todo: different locks for different SPI devices!
	chMtxLock(&spiMtx);
}
Beispiel #28
0
	for (int i = 0; i < TRIGGER_CHANNEL_COUNT; i++) {
		waves[i].init(pinStates[i]);
	}
}

TriggerShape::TriggerShape() :
		wave(switchTimesBuffer, NULL) {
	initialize(OM_NONE, false);
	wave.waves = h.waves;

	memset(triggerIndexByAngle, 0, sizeof(triggerIndexByAngle));
}

void TriggerShape::calculateTriggerSynchPoint(TriggerState *state DECLARE_ENGINE_PARAMETER_S) {
#if EFI_PROD_CODE || defined(__DOXYGEN__)
	efiAssertVoid(getRemainingStack(chThdSelf()) > 256, "calc s");
#endif
	trigger_config_s const*triggerConfig = &engineConfiguration->trigger;

	triggerShapeSynchPointIndex = findTriggerZeroEventIndex(state, this, triggerConfig PASS_ENGINE_PARAMETER);

	engine->engineCycleEventCount = getLength();

	float firstAngle = getAngle(triggerShapeSynchPointIndex);

	int frontOnlyIndex = 0;

	for (int eventIndex = 0; eventIndex < engine->engineCycleEventCount; eventIndex++) {
		if (eventIndex == 0) {
			// explicit check for zero to avoid issues where logical zero is not exactly zero due to float nature
			eventAngles[0] = 0;
Beispiel #29
0
void runRusEfi(void) {
	msObjectInit(&firmwareErrorMessageStream, errorMessageBuffer, sizeof(errorMessageBuffer), 0);

	// that's dirty, this assignment should be nicer or in a better spot
	engine->engineConfiguration = engineConfiguration;
	engine->engineConfiguration2 = engineConfiguration2;
	engineConfiguration2->engineConfiguration = engineConfiguration;

	initErrorHandling();

	/**
	 * First data structure keeps track of which hardware I/O pins are used by whom
	 */
	initPinRepository();

	/**
	 * Next we should initialize serial port console, it's important to know what's going on
	 */
	initializeConsole();
	initLogging(&logging, "main");

	engine->init();

	addConsoleAction("reset", scheduleReset);

	/**
	 * Initialize hardware drivers
	 */
	initHardware(&logging, engine);

	initStatusLoop(engine);
	/**
	 * Now let's initialize actual engine control logic
	 * todo: should we initialize some? most? controllers before hardware?
	 */
	initEngineContoller(engine);

#if EFI_PERF_METRICS || defined(__DOXYGEN__)
	initTimePerfActions();
#endif

#if EFI_ENGINE_EMULATOR || defined(__DOXYGEN__)
	initEngineEmulator(engine);
#endif
	startStatusThreads(engine);

	print("Running main loop\r\n");
	main_loop_started = TRUE;
	/**
	 * This loop is the closes we have to 'main loop' - but here we only publish the status. The main logic of engine
	 * control is around main_trigger_callback
	 */
	while (TRUE) {
		efiAssertVoid(getRemainingStack(chThdSelf()) > 128, "stack#1");

#if (EFI_CLI_SUPPORT && !EFI_UART_ECHO_TEST_MODE) || defined(__DOXYGEN__)
		// sensor state + all pending messages for our own dev console
		updateDevConsoleState(engine);
#endif /* EFI_CLI_SUPPORT */

		chThdSleepMilliseconds(boardConfiguration->consoleLoopPeriod);
	}
}
	applyNonPersistentConfiguration(logger PASS_ENGINE_PARAMETER);
	// todo: eliminate triggerShape.operationMode?
	if (engineConfiguration->operationMode != engine->triggerShape.getOperationMode())
		firmwareError("operationMode mismatch");

#if EFI_TUNER_STUDIO
	syncTunerStudioCopy();
#endif
}

engine_configuration2_s::engine_configuration2_s() {
}

void applyNonPersistentConfiguration(Logging * logger DECLARE_ENGINE_PARAMETER_S) {
#if EFI_PROD_CODE || defined(__DOXYGEN__)
	efiAssertVoid(getRemainingStack(chThdSelf()) > 256, "apply c");
	scheduleMsg(logger, "applyNonPersistentConfiguration()");
#endif

// todo: this would require 'initThermistors() to re-establish a reference, todo: fix
//	memset(engineConfiguration2, 0, sizeof(engine_configuration2_s));
#if EFI_ENGINE_CONTROL || defined(__DOXYGEN__)
	engine->triggerShape.initializeTriggerShape(logger PASS_ENGINE_PARAMETER);
#endif
	if (engine->triggerShape.getSize() == 0) {
		firmwareError("triggerShape size is zero");
		return;
	}
	if (engine->triggerShape.getSize() == 0) {
		firmwareError("shaftPositionEventCount is zero");
		return;