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); } }
/** * sets the alarm to the specified number of microseconds from now. * This function should be invoked under kernel lock which would disable interrupts. */ void setHardwareUsTimer(int32_t timeUs) { /** * #259 BUG error: not positive timeUs * Once in a while we night get an interrupt where we do not expect it */ if (timeUs <= 0) { timerFreezeCounter++; warning(CUSTOM_OBD_42, "local freeze cnt=%d", timerFreezeCounter); } if (timeUs < 2) timeUs = 2; // for some reason '1' does not really work efiAssertVoid(timeUs > 0, "not positive timeUs"); efiAssertVoid(timeUs < 10 * US_PER_SECOND, "setHardwareUsTimer() too large"); if (GPTDEVICE.state == GPT_ONESHOT) gptStopTimerI(&GPTDEVICE); efiAssertVoid(GPTDEVICE.state == GPT_READY, "hw timer"); if (hasFirmwareError()) return; gptStartOneShotI(&GPTDEVICE, timeUs); lastSetTimerTimeNt = getTimeNowNt(); lastSetTimerValue = timeUs; isTimerPending = TRUE; timerRestartCounter++; }
void startInputDriver(const char *msg, /*nullable*/digital_input_s *hw, bool isActiveHigh) { if (hw == NULL) { // we can get NULL driver if user somehow has invalid pin in his configuration warning(CUSTOM_ERR_INVALID_INPUT_ICU_PIN, "s_not input pin"); return; } hw->isActiveHigh = isActiveHigh; if (hw->isActiveHigh) { wave_icucfg.mode = ICU_INPUT_ACTIVE_HIGH; } else { wave_icucfg.mode = ICU_INPUT_ACTIVE_LOW; } ICUDriver *driver = hw->driver; if (driver != NULL) { if (hw->started) { icuDisableNotificationsI(driver); icuStopCapture(driver); icuStop(driver); } wave_icucfg.channel = getInputCaptureChannel(hw->brainPin); efiIcuStart(msg, driver, &wave_icucfg); efiAssertVoid(CUSTOM_ERR_6672, driver != NULL, "di: driver is NULL"); efiAssertVoid(CUSTOM_ERR_6673, driver->state == ICU_READY, "di: driver not ready"); icuStartCapture(driver); // this would change state from READY to WAITING icuEnableNotifications(driver); } hw->started = true; }
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); } }
void PwmConfig::weComplexInit(const char *msg, int phaseCount, float *switchTimes, int waveCount, pin_state_t **pinStates, pwm_cycle_callback *pwmCycleCallback, pwm_gen_callback *stateChangeCallback) { efiAssertVoid(periodNt != 0, "period is not initialized"); if (phaseCount == 0) { firmwareError(CUSTOM_ERR_PWM_1, "signal length cannot be zero"); return; } if (phaseCount > PWM_PHASE_MAX_COUNT) { firmwareError(CUSTOM_ERR_PWM_2, "too many phases in PWM"); return; } efiAssertVoid(waveCount > 0, "waveCount should be positive"); checkSwitchTimes2(phaseCount, switchTimes); this->pwmCycleCallback = pwmCycleCallback; this->stateChangeCallback = stateChangeCallback; multiWave.waveCount = waveCount; copyPwmParameters(this, phaseCount, switchTimes, waveCount, pinStates); safe.phaseIndex = 0; safe.periodNt = -1; safe.iteration = -1; // let's start the indefinite callback loop of PWM generation timerCallback(this); }
void configureMiniCooperTriggerShape(TriggerShape *s) { s->initialize(FOUR_STROKE_CAM_SENSOR, true); // s->initialState[0] = 1; float w = 360.0 / 121; float a = w / 2; s->addEvent720(a, T_SECONDARY, TV_FALL); a += w; for (int i = 0; i <= 22; i++) { a = addPair(s, a, w); } a += 3 * w; float firstGapAngle = a; /* may be */UNUSED(firstGapAngle); s->addEvent720(a, T_SECONDARY, TV_RISE); a += 3 * w; s->addEvent720(a, T_SECONDARY, TV_FALL); a += w; for (int i = 0; i < 36; i++) { a = addPair(s, a, w); } s->addEvent720(376, T_PRIMARY, TV_RISE); for (int i = 0; i < 21; i++) { a = addPair(s, a, w); } a += 3 * w; efiAssertVoid(CUSTOM_ERR_6584, absF(firstGapAngle + 360 - a) < 0.1, "shape constraint"); s->addEvent720(a, T_SECONDARY, TV_RISE); a += 3 * w; s->addEvent720(a, T_SECONDARY, TV_FALL); a += w; for (int i = 0; i < 33; i++) { a = addPair(s, a, w); } efiAssertVoid(CUSTOM_ERR_6585, absF(720 - w / 2 - a) < 0.1, "shape constraint"); s->addEvent720(a, T_SECONDARY, TV_RISE); s->addEvent720(720.0, T_PRIMARY, TV_FALL); /** * With just one tooth on camshaft synchronization is not needed */ s->isSynchronizationNeeded = false; s->useOnlyPrimaryForSync = true; }
void configureMiniCooperTriggerShape(TriggerShape *s) { s->reset(FOUR_STROKE_CAM_SENSOR, true); // s->initialState[0] = 1; float w = 360.0 / 121; float a = w / 2; s->addEvent(a, T_SECONDARY, TV_LOW); a += w; for (int i = 0; i <= 22; i++) { a = addPair(s, a, w); } a += 3 * w; float firstGapAngle = a; s->addEvent(a, T_SECONDARY, TV_HIGH); a += 3 * w; s->addEvent(a, T_SECONDARY, TV_LOW); a += w; for (int i = 0; i < 36; i++) { a = addPair(s, a, w); } s->addEvent(376, T_PRIMARY, TV_HIGH); for (int i = 0; i < 21; i++) { a = addPair(s, a, w); } a += 3 * w; efiAssertVoid(absF(firstGapAngle + 360 - a) < 0.1, "shape constraint"); s->addEvent(a, T_SECONDARY, TV_HIGH); a += 3 * w; s->addEvent(a, T_SECONDARY, TV_LOW); a += w; for (int i = 0; i < 33; i++) { a = addPair(s, a, w); } efiAssertVoid(absF(720 - w / 2 - a) < 0.1, "shape constraint"); s->addEvent(a, T_SECONDARY, TV_HIGH); s->addEvent(720.0, T_PRIMARY, TV_LOW); /** * With just one tooth on camshaft synchronization is not needed */ s->isSynchronizationNeeded = false; }
static void applyIdleSolenoidPinState(PwmConfig *state, int stateIndex) { efiAssertVoid(stateIndex < PWM_PHASE_MAX_COUNT, "invalid stateIndex"); efiAssertVoid(state->multiWave.waveCount == 1, "invalid idle waveCount"); OutputPin *output = state->outputPins[0]; int value = state->multiWave.waves[0].pinStates[stateIndex]; if (!value /* always allow turning solenoid off */ || (engine->rpmCalculator.rpmValue != 0 || timeToStopIdleTest != 0) /* do not run solenoid unless engine is spinning or bench testing in progress */ ) { output->setValue(value); } }
void initializeSkippedToothTriggerShapeExt(TriggerShape *s, int totalTeethCount, int skippedCount, operation_mode_e operationMode) { efiAssertVoid(totalTeethCount > 0, "totalTeethCount is zero"); efiAssertVoid(s != NULL, "TriggerShape is NULL"); s->initialize(operationMode, false); s->setTriggerSynchronizationGap(skippedCount + 1); s->isSynchronizationNeeded = (skippedCount != 0); addSkippedToothTriggerEvents(T_PRIMARY, s, totalTeethCount, skippedCount, 0.5, 0, getEngineCycle(operationMode), NO_LEFT_FILTER, NO_RIGHT_FILTER); }
void OutputPin::setValue(int logicValue) { #if EFI_PROD_CODE if (port != GPIO_NULL) { efiAssertVoid(modePtr!=NULL, "pin mode not initialized"); pin_output_mode_e mode = *modePtr; efiAssertVoid(mode <= OM_OPENDRAIN_INVERTED, "invalid pin_output_mode_e"); int eValue = getElectricalValue(logicValue, mode); setPinValue(this, eValue, logicValue); } #else /* EFI_PROD_CODE */ setPinValue(this, eValue, logicValue); #endif /* EFI_PROD_CODE */ }
/** * sets the alarm to the specified number of microseconds from now. * This function should be invoked under kernel lock which would disable interrupts. */ void setHardwareUsTimer(int32_t timeUs) { if (timeUs == 1) timeUs = 2; // for some reason '1' does not really work efiAssertVoid(timeUs > 0, "neg timeUs"); efiAssertVoid(timeUs < 10 * US_PER_SECOND, "setHardwareUsTimer() too large"); if (GPTDEVICE.state == GPT_ONESHOT) gptStopTimerI(&GPTDEVICE); gptStartOneShotI(&GPTDEVICE, timeUs); lastSetTimerTime = getTimeNowUs(); lastSetTimerValue = timeUs; isTimerPending = TRUE; timerRestartCounter++; }
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 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 initWave(const char *name, int index) { brain_pin_e brainPin = boardConfiguration->logicAnalyzerPins[index]; ioportid_t port = getHwPort(brainPin); ioportmask_t pin = getHwPin(brainPin); ICUDriver *driver = getInputCaptureDriver(brainPin); bool mode = boardConfiguration->logicAnalyzerMode[index]; waveReaderCount++; efiAssertVoid(index < MAX_ICU_COUNT, "too many ICUs"); WaveReader *reader = &readers[index]; WaveReaderHw *hw = &reader->hw; reader->name = name; registerCallback(&hw->widthListeners, (IntListener) waAnaWidthCallback, (void*) reader); registerCallback(&hw->periodListeners, (IntListener) waIcuPeriodCallback, (void*) reader); initWaveAnalyzerDriver(hw, driver, port, pin); print("wave%d input on %s%d\r\n", index, portname(reader->hw.port), reader->hw.pin); setWaveReaderMode(hw, mode); }
static ALWAYS_INLINE void handleFuelInjectionEvent(int eventIndex, bool limitedFuel, InjectionEvent *event, int rpm DECLARE_ENGINE_PARAMETER_S) { if (limitedFuel) return; // todo: move this check up /** * todo: this is a bit tricky with batched injection. is it? Does the same * wetting coefficient works the same way for any injection mode, or is something * x2 or /2? */ floatms_t injectionDuration = ENGINE(wallFuel).adjust(event->injectorIndex, ENGINE(fuelMs) PASS_ENGINE_PARAMETER); ENGINE(actualLastInjection) = injectionDuration; if (cisnan(injectionDuration)) { warning(OBD_PCM_Processor_Fault, "NaN injection pulse"); return; } if (injectionDuration < 0) { warning(OBD_PCM_Processor_Fault, "Negative injection pulse %f", injectionDuration); return; } if (engine->isCylinderCleanupMode) return; floatus_t injectionStartDelayUs = ENGINE(rpmCalculator.oneDegreeUs) * event->injectionStart.angleOffset; OutputSignal *signal = &ENGINE(engineConfiguration2)->fuelActuators[eventIndex]; if (event->isSimultanious) { if (injectionDuration < 0) { firmwareError("duration cannot be negative: %d", injectionDuration); return; } if (cisnan(injectionDuration)) { firmwareError("NaN in scheduleOutput", injectionDuration); return; } /** * this is pretty much copy-paste of 'scheduleOutput' * 'scheduleOutput' is currently only used for injection, so maybe it should be * changed into 'scheduleInjection' and unified? todo: think about it. */ efiAssertVoid(signal!=NULL, "signal is NULL"); int index = getRevolutionCounter() % 2; scheduling_s * sUp = &signal->signalTimerUp[index]; scheduling_s * sDown = &signal->signalTimerDown[index]; scheduleTask("out up", sUp, (int) injectionStartDelayUs, (schfunc_t) &startSimultaniousInjection, engine); scheduleTask("out down", sDown, (int) injectionStartDelayUs + MS2US(injectionDuration), (schfunc_t) &endSimultaniousInjection, engine); } else { #if EFI_UNIT_TEST || defined(__DOXYGEN__) printf("scheduling injection angle=%f/delay=%f injectionDuration=%f\r\n", event->injectionStart.angleOffset, injectionStartDelayUs, injectionDuration); #endif scheduleOutput(signal, getTimeNowUs(), injectionStartDelayUs, MS2US(injectionDuration), event->output); } }
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 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 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 */ }
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 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 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 }
void addSkippedToothTriggerEvents(trigger_wheel_e wheel, TriggerShape *s, int totalTeethCount, int skippedCount, float toothWidth, float offset, float engineCycle, float filterLeft, float filterRight) { efiAssertVoid(CUSTOM_ERR_6586, totalTeethCount > 0, "total count"); efiAssertVoid(CUSTOM_ERR_6587, skippedCount >= 0, "skipped count"); for (int i = 0; i < totalTeethCount - skippedCount - 1; i++) { float angleDown = engineCycle / totalTeethCount * (i + (1 - toothWidth)); float angleUp = engineCycle / totalTeethCount * (i + 1); s->addEvent3(offset + angleDown, wheel, TV_RISE, filterLeft, filterRight); s->addEvent3(offset + angleUp, wheel, TV_FALL, filterLeft, filterRight); } float angleDown = engineCycle / totalTeethCount * (totalTeethCount - skippedCount - 1 + (1 - toothWidth)); s->addEvent3(offset + angleDown, wheel, TV_RISE, filterLeft, filterRight); s->addEvent3(offset + engineCycle, wheel, TV_FALL, filterLeft, filterRight); }
/** * 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]; // } } }
/** * sets the alarm to the specified number of microseconds from now. * This function should be invoked under kernel lock which would disable interrupts. */ void setHardwareUsTimer(int32_t timeUs) { setHwTimerCounter++; /** * #259 BUG error: not positive timeUs * Once in a while we night get an interrupt where we do not expect it */ if (timeUs <= 0) { timerFreezeCounter++; warning(CUSTOM_OBD_LOCAL_FREEZE, "local freeze cnt=%d", timerFreezeCounter); } if (timeUs < 2) timeUs = 2; // for some reason '1' does not really work efiAssertVoid(CUSTOM_ERR_6681, timeUs > 0, "not positive timeUs"); if (timeUs >= 10 * US_PER_SECOND) { firmwareError(CUSTOM_ERR_TIMER_OVERFLOW, "setHardwareUsTimer() too long: %d", timeUs); return; } if (GPTDEVICE.state == GPT_ONESHOT) { gptStopTimerI(&GPTDEVICE); } if (GPTDEVICE.state != GPT_READY) { firmwareError(CUSTOM_HW_TIMER, "HW timer state %d/%d", GPTDEVICE.state, setHwTimerCounter); return; } if (hasFirmwareError()) return; gptStartOneShotI(&GPTDEVICE, timeUs); lastSetTimerTimeNt = getTimeNowNt(); lastSetTimerValue = timeUs; isTimerPending = TRUE; timerRestartCounter++; }
void setVwConfiguration(TriggerShape *s) { efiAssertVoid(s != NULL, "TriggerShape is NULL"); operation_mode_e operationMode = FOUR_STROKE_CRANK_SENSOR; s->useRiseEdge = true; initializeSkippedToothTriggerShapeExt(s, 60, 2, operationMode); s->isSynchronizationNeeded = true; s->reset(operationMode, false); int totalTeethCount = 60; int skippedCount = 2; float engineCycle = getEngineCycle(operationMode); float toothWidth = 0.5; addSkippedToothTriggerEvents(T_PRIMARY, s, 60, 2, toothWidth, 0, engineCycle, NO_LEFT_FILTER, 690); float angleDown = engineCycle / totalTeethCount * (totalTeethCount - skippedCount - 1 + (1 - toothWidth) ); s->addEvent(0 + angleDown + 12, T_PRIMARY, TV_HIGH, NO_LEFT_FILTER, NO_RIGHT_FILTER); s->addEvent(0 + engineCycle, T_PRIMARY, TV_LOW, NO_LEFT_FILTER, NO_RIGHT_FILTER); s->setTriggerSynchronizationGap2(1.6, 4); }
/** * Main PWM loop: toggle pin & schedule next invocation */ static void timerCallback(PwmConfig *state) { state->dbgNestingLevel++; efiAssertVoid(state->dbgNestingLevel < 25, "PWM nesting issue"); efitimeus_t switchTimeUs = state->togglePwmState(); scheduleByTimestamp(&state->scheduling, switchTimeUs, (schfunc_t) timerCallback, state); state->dbgNestingLevel--; }
static void doAddAction(const char *token, action_type_e type, Void callback, void *param) { efiAssertVoid(consoleActionCount < CONSOLE_MAX_ACTIONS, "Too many console actions"); TokenCallback *current = &consoleActions[consoleActionCount++]; current->token = token; current->parameterType = type; current->callback = callback; current->param = param; }
/** * @breif Add a new value into histogram_s */ void hsAdd(histogram_s *h, int64_t value) { int index = histogramGetIndex(value); int count = 1; h->total_value += value; h->total_count += count; efiAssertVoid(index < BOUND_LENGTH, "histogram issue"); h->values[index] += count; }
void assertCylinderId(int cylinderId, const char *msg) { int isValid = cylinderId >= 1 && cylinderId <= engineConfiguration->specs.cylindersCount; if (!isValid) { // we are here only in case of a fatal issue - at this point it is fine to make some blocking i-o //scheduleSimpleMsg(&logger, "cid=", cylinderId); print("ERROR [%s] cid=%d\r\n", msg, cylinderId); efiAssertVoid(false, "Cylinder ID"); } }
void append(Logging *logging, const char *text) { efiAssertVoid(text != NULL, "append NULL"); uint32_t extraLen = efiStrlen(text); int isError = validateBuffer(logging, extraLen); if (isError) { return; } strcpy(logging->linePointer, text); logging->linePointer += extraLen; }