Ejemplo n.º 1
0
static void manualIdleController(int positionPercent) {
	// todo: this is not great that we have to write into configuration here
	boardConfiguration->manIdlePosition = positionPercent;

	if (isCranking()) {
		positionPercent += engineConfiguration->crankingIdleAdjustment;
	}

	percent_t cltCorrectedPosition = interpolate2d(engine->engineState.clt, config->cltIdleCorrBins, config->cltIdleCorr,
	CLT_CURVE_SIZE) / PERCENT_MULT * positionPercent;

	// let's put the value into the right range
	cltCorrectedPosition = maxF(cltCorrectedPosition, 0.01);
	cltCorrectedPosition = minF(cltCorrectedPosition, 99.9);

	if (engineConfiguration->debugMode == IDLE) {
		tsOutputChannels.debugFloatField1 = actualIdlePosition;
	}

	if (absF(cltCorrectedPosition - actualIdlePosition) < 1) {
		return; // value is pretty close, let's leave the poor valve alone
	}
	actualIdlePosition = cltCorrectedPosition;


	if (boardConfiguration->useStepperIdle) {
		iacMotor.setTargetPosition(cltCorrectedPosition / 100 * engineConfiguration->idleStepperTotalSteps);
	} else {
		setIdleValvePwm(cltCorrectedPosition);
	}
}
Ejemplo n.º 2
0
void StepperMotor::initialize(brain_pin_e stepPin, brain_pin_e directionPin, pin_output_mode_e directionPinMode,
		float reactionTime, int totalSteps, brain_pin_e enablePin, Logging *sharedLogger) {
	this->reactionTime = maxF(1, reactionTime);
	this->totalSteps = maxI(3, totalSteps);
	
	logger = sharedLogger;

	if (stepPin == GPIO_UNASSIGNED || directionPin == GPIO_UNASSIGNED) {
		return;
	}

	stepPort = getHwPort("step", stepPin);
	this->stepPin = getHwPin("step", stepPin);

	this->directionPinMode = directionPinMode;
	this->directionPin.initPin("stepper dir", directionPin, &this->directionPinMode);

	enablePort = getHwPort("enable", enablePin);
	this->enablePin = getHwPin("enable", enablePin);

	efiSetPadMode("stepper step", stepPin, PAL_MODE_OUTPUT_PUSHPULL);
	efiSetPadMode("stepper enable", enablePin, PAL_MODE_OUTPUT_PUSHPULL);
	palWritePad(this->enablePort, enablePin, true); // disable stepper

	// All pins must be 0 for correct hardware startup (e.g. stepper auto-disabling circuit etc.).
	palWritePad(this->stepPort, this->stepPin, false);
	this->directionPin.setValue(false);
	this->currentDirection = false;

	chThdCreateStatic(stThreadStack, sizeof(stThreadStack), NORMALPRIO, (tfunc_t) stThread, this);
}
Ejemplo n.º 3
0
percent_t getPedalPosition(DECLARE_ENGINE_PARAMETER_SIGNATURE) {
	if (mockPedalPosition != MOCK_UNDEFINED) {
		return mockPedalPosition;
	}
	float voltage = getVoltageDivided("pPS", engineConfiguration->throttlePedalPositionAdcChannel);
	float result = interpolateMsg("pedal", engineConfiguration->throttlePedalUpVoltage, 0, engineConfiguration->throttlePedalWOTVoltage, 100, voltage);

	// this would put the value into the 0-100 range
	return maxF(0, minF(100, result));
}
Ejemplo n.º 4
0
void hipAdcCallback(adcsample_t value) {
	if (state == WAITING_FOR_ADC_TO_SKIP) {
		state = WAITING_FOR_RESULT_ADC;
	} else if (state == WAITING_FOR_RESULT_ADC) {
		engine->knockVolts = adcToVoltsDivided(value);
		hipValueMax = maxF(engine->knockVolts, hipValueMax);
		engine->knockLogic(engine->knockVolts);

		float angleWindowWidth =
		engineConfiguration->knockDetectionWindowEnd - engineConfiguration->knockDetectionWindowStart;

		if (angleWindowWidth != currentAngleWindowWidth) {
			currentAngleWindowWidth = angleWindowWidth;
		prepareHip9011RpmLookup(currentAngleWindowWidth);
		}

		int integratorIndex = getIntegrationIndexByRpm(engine->rpmCalculator.rpmValue);
		int gainIndex = getHip9011GainIndex(boardConfiguration->hip9011Gain);
		int bandIndex = getBandIndex();
		int prescalerIndex = engineConfiguration->hip9011PrescalerAndSDO;


		if (currentGainIndex != gainIndex) {
			currentGainIndex = gainIndex;
			tx_buff[0] = SET_GAIN_CMD + gainIndex;

			state = IS_SENDING_SPI_COMMAND;
			spiSelectI(driver);
			spiStartExchangeI(driver, 1, tx_buff, rx_buff);
		} else if (currentIntergratorIndex != integratorIndex) {
			currentIntergratorIndex = integratorIndex;
			tx_buff[0] = SET_INTEGRATOR_CMD + integratorIndex;

			state = IS_SENDING_SPI_COMMAND;
			spiSelectI(driver);
			spiStartExchangeI(driver, 1, tx_buff, rx_buff);
		} else if (currentBandIndex != bandIndex) {
			currentBandIndex = bandIndex;
			tx_buff[0] = SET_BAND_PASS_CMD + bandIndex;

			state = IS_SENDING_SPI_COMMAND;
			spiSelectI(driver);
			spiStartExchangeI(driver, 1, tx_buff, rx_buff);
		} else if (currentPrescaler != prescalerIndex) {
			currentPrescaler = prescalerIndex;
			tx_buff[0] = SET_PRESCALER_CMD + prescalerIndex;

			state = IS_SENDING_SPI_COMMAND;
			spiSelectI(driver);
			spiStartExchangeI(driver, 1, tx_buff, rx_buff);
		} else {
			state = READY_TO_INTEGRATE;
		}
	}
}
Ejemplo n.º 5
0
void hipAdcCallback(adcsample_t adcValue) {
	if (instance.state == WAITING_FOR_ADC_TO_SKIP) {
		instance.state = WAITING_FOR_RESULT_ADC;
	} else if (instance.state == WAITING_FOR_RESULT_ADC) {
		engine->knockVolts = adcValue * engine->adcToVoltageInputDividerCoefficient;
		hipValueMax = maxF(engine->knockVolts, hipValueMax);
		engine->knockLogic(engine->knockVolts);

		instance.handleValue(GET_RPM_VALUE DEFINE_PARAM_SUFFIX(PASS_HIP_PARAMS));

	}
}
Ejemplo n.º 6
0
void CJ125::SetHeater(float value DECLARE_ENGINE_PARAMETER_SUFFIX) {
	// limit duty cycle for sensor safety
	// todo: would be much nicer to have continuous function (vBatt)
	float maxDuty = (engine->sensors.vBatt > CJ125_HEATER_LIMITING_VOLTAGE) ? CJ125_HEATER_LIMITING_RATE : 1.0f;
	heaterDuty = (value < CJ125_HEATER_MIN_DUTY) ? 0.0f : minF(maxF(value, 0.0f), maxDuty);
#ifdef CJ125_DEBUG
	scheduleMsg(logger, "cjSetHeater: %.2f", heaterDuty);
#endif
	// a little trick to disable PWM if needed.
	// todo: this should be moved to wboHeaterControl.setPwmDutyCycle()
	// todo: is this really needed?!
	wboHeaterControl.setFrequency(heaterDuty == 0.0f ? NAN : CJ125_HEATER_PWM_FREQ);
	wboHeaterControl.setSimplePwmDutyCycle(heaterDuty);
}
Ejemplo n.º 7
0
static int adjustCell(int i, int j, void (*callback)(int, float, float)) {
	int count = afrs.counts[i][j];
	if (count < HOW_MANY_MEASURMENTS_ARE_NEEDED)
		return 0;

	float value = avgGetValueByIndexes(&afrs, i, j);
	afrs.counts[i][j] = 0;
	afrs.values[i][j] = 0;

	if (value < TARGET_MIN_AFR) {
		float currentMult = adjustments.values[i][j];
//		printf("adj %d %d. cur=%f\r\n", i, j, currentMult);
		float newValue = maxF(0.1, MULT_STEP_DOWN * currentMult);
		adjustments.values[i][j] = newValue;
//		printf("adj %d %d. new=%f\r\n", i, j, adjustments.values[i][j]);
		if (callback != NULL)
			callback(MAX_RPM * i / AVG_TAB_SIZE, 1.0 * MAX_KEY * j / AVG_TAB_SIZE, newValue);
		return 1;
	}
	return 0;
}
Ejemplo n.º 8
0
/*
 * Return current TPS position based on configured ADC levels, and adc
 *
 * */
percent_t getTpsValue(int adc DECLARE_ENGINE_PARAMETER_SUFFIX) {
	if (engineConfiguration->tpsMin == engineConfiguration->tpsMax) {
		warning(CUSTOM_INVALID_TPS_SETTING, "Invalid TPS configuration: same value %d", engineConfiguration->tpsMin);
		return NAN;
	}
	float result = interpolateMsg("TPS", TPS_TS_CONVERSION * engineConfiguration->tpsMax, 100, TPS_TS_CONVERSION * engineConfiguration->tpsMin, 0, adc);
	if (result < engineConfiguration->tpsErrorDetectionTooLow) {
#if EFI_PROD_CODE
		// too much noise with simulator
		warning(OBD_Throttle_Position_Sensor_Circuit_Malfunction, "TPS too low: %.2f", result);
#endif /* EFI_PROD_CODE */
	}
	if (result > engineConfiguration->tpsErrorDetectionTooHigh) {
#if EFI_PROD_CODE
		// too much noise with simulator
		warning(OBD_Throttle_Position_Sensor_Range_Performance_Problem, "TPS too high: %.2f", result);
#endif /* EFI_PROD_CODE */
	}

	// this would put the value into the 0-100 range
	return maxF(0, minF(100, result));
}
Ejemplo n.º 9
0
void LECalculator::doJob(Engine *engine, LEElement *element) {
	switch (element->action) {

	case LE_NUMERIC_VALUE:
		stack.push(element->fValue);
		break;
	case LE_OPERATOR_AND: {
		float v1 = pop(LE_OPERATOR_AND);
		float v2 = pop(LE_OPERATOR_AND);

		stack.push(float2bool(v1) && float2bool(v2));
	}
		break;
	case LE_OPERATOR_OR: {
		float v1 = pop(LE_OPERATOR_OR);
		float v2 = pop(LE_OPERATOR_OR);

		stack.push(float2bool(v1) || float2bool(v2));
	}
		break;
	case LE_OPERATOR_LESS: {
		// elements on stack are in reverse order
		float v2 = pop(LE_OPERATOR_LESS);
		float v1 = pop(LE_OPERATOR_LESS);

		stack.push(v1 < v2);
	}
		break;
	case LE_OPERATOR_NOT: {
		float v = pop(LE_OPERATOR_NOT);
		stack.push(!float2bool(v));
	}
		break;
	case LE_OPERATOR_MORE: {
		// elements on stack are in reverse order
		float v2 = pop(LE_OPERATOR_MORE);
		float v1 = pop(LE_OPERATOR_MORE);

		stack.push(v1 > v2);
	}
		break;
	case LE_OPERATOR_ADDITION: {
		// elements on stack are in reverse order
		float v2 = pop(LE_OPERATOR_MORE);
		float v1 = pop(LE_OPERATOR_MORE);

		stack.push(v1 + v2);
	}
		break;
	case LE_OPERATOR_SUBSTRACTION: {
		// elements on stack are in reverse order
		float v2 = pop(LE_OPERATOR_MORE);
		float v1 = pop(LE_OPERATOR_MORE);

		stack.push(v1 - v2);
	}
		break;
	case LE_OPERATOR_MULTIPLICATION: {
		// elements on stack are in reverse order
		float v2 = pop(LE_OPERATOR_MORE);
		float v1 = pop(LE_OPERATOR_MORE);

		stack.push(v1 * v2);
	}
		break;
	case LE_OPERATOR_DIVISION: {
		// elements on stack are in reverse order
		float v2 = pop(LE_OPERATOR_MORE);
		float v1 = pop(LE_OPERATOR_MORE);

		stack.push(v1 / v2);
	}
		break;
	case LE_OPERATOR_LESS_OR_EQUAL: {
		// elements on stack are in reverse order
		float v2 = pop(LE_OPERATOR_LESS_OR_EQUAL);
		float v1 = pop(LE_OPERATOR_LESS_OR_EQUAL);

		stack.push(v1 <= v2);
	}
		break;
	case LE_OPERATOR_MORE_OR_EQUAL: {
		// elements on stack are in reverse order
		float v2 = pop(LE_OPERATOR_MORE_OR_EQUAL);
		float v1 = pop(LE_OPERATOR_MORE_OR_EQUAL);

		stack.push(v1 >= v2);
	}
		break;
	case LE_METHOD_IF: {
		// elements on stack are in reverse order
		float vFalse = pop(LE_METHOD_IF);
		float vTrue = pop(LE_METHOD_IF);
		float vCond = pop(LE_METHOD_IF);
		stack.push(vCond != 0 ? vTrue : vFalse);
	}
		break;
	case LE_METHOD_MAX: {
		float v2 = pop(LE_METHOD_MAX);
		float v1 = pop(LE_METHOD_MAX);
		stack.push(maxF(v1, v2));
	}
		break;
	case LE_METHOD_MIN: {
		float v2 = pop(LE_METHOD_MIN);
		float v1 = pop(LE_METHOD_MIN);
		stack.push(minF(v1, v2));
	}
		break;
	case LE_METHOD_FSIO_SETTING: {
		float i = pop(LE_METHOD_FSIO_SETTING);
		int index = (int) i;
		if (index >= 0 && index < LE_COMMAND_COUNT) {
			stack.push(engine->engineConfiguration->bc.fsio_setting[index]);
		} else {
			stack.push(NAN);
		}
	}
		break;
	case LE_UNDEFINED:
		firmwareError("Undefined not expected here");
		break;
	default:
		stack.push(getLEValue(engine, &stack, element->action));
	}
}