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); } }
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() ; } } }
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); } }
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 }
/** * 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]; // } } }
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!"); } }
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); } } }
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 */ }
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); }
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); }
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(); }
/** * 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(); } }
/** * 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); }
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; }
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); } }
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++; } }
/** * @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 }
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; } } }
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 }
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); } }
/** * 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; }
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(); }
/** * @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 */ }
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;
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!"); }
/** * 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); }
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;
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;