Пример #1
0
/**
 *
 * @param	delay	the number of ticks before the output signal
 * 					immediate output if delay is zero
 * @param	dwell	the number of ticks of output duration
 *
 */
void scheduleOutput(OutputSignal *signal, float delayMs, float durationMs) {
	if (durationMs < 0) {
		firmwareError("duration cannot be negative: %d", durationMs);
		return;
	}
	if (cisnan(durationMs)) {
		firmwareError("NaN in scheduleOutput", durationMs);
		return;
	}

	int index = getRevolutionCounter() % 2;
	scheduling_s * sUp = &signal->signalTimerUp[index];
	scheduling_s * sDown = &signal->signalTimerDown[index];

	scheduleTask("out up", sUp, (int)MS2US(delayMs), (schfunc_t) &turnPinHigh, (void *) signal->io_pin);
	scheduleTask("out down", sDown, (int)MS2US(delayMs + durationMs), (schfunc_t) &turnPinLow, (void*) signal->io_pin);
}
Пример #2
0
//Nullable
static digital_input_s * finddigital_input_s(ICUDriver *driver) {
	for (int i = 0; i < registeredIcus.size; i++) {
		if (registeredIcus.elements[i].driver == driver) {
			return &registeredIcus.elements[i];
		}
	}
	firmwareError(CUSTOM_ERR_ICU, "reader not found");
	return (digital_input_s *) NULL;
}
Пример #3
0
/**
 * @brief Reset histogram_s to orignal state
 */
void initHistogram(histogram_s *h, const char *name) {
	if (efiStrlen(name) > sizeof(h->name) - 1) {
		firmwareError(ERROR_HISTO_NAME, "Histogram name [%s] too long", name);
	}
	strcpy(h->name, name);
	h->total_value = 0;
	h->total_count = 0;
	memset(h->values, 0, sizeof(h->values));
}
Пример #4
0
void efiIcuStart(const char *msg, ICUDriver *icup, const ICUConfig *config) {
	if (icup->state != ICU_STOP && icup->state != ICU_READY) {
		static char icuError[30];
		sprintf(icuError, "ICU already used %s", msg);
		firmwareError(CUSTOM_ERR_6679, icuError);
		return;
	}
	icuStart(icup, config);
}
Пример #5
0
void resetLogging(Logging *logging) {
	char *buffer = logging->buffer;
	if (buffer == NULL) {
		firmwareError("Null buffer: %s", logging->name);
		return;
	}
	logging->linePointer = buffer;
	logging->linePointer[0] = 0;
}
Пример #6
0
ioportid_t getHwPort(const char *msg, brain_pin_e brainPin) {
	if (brainPin == GPIO_UNASSIGNED || brainPin == GPIO_INVALID)
		return GPIO_NULL;
	if (brainPin < GPIOA_0 || brainPin > GPIOH_15) {
		firmwareError(CUSTOM_ERR_INVALID_PIN, "%s: Invalid brain_pin_e: %d", msg, brainPin);
		return GPIO_NULL;
	}
	return PORTS[(brainPin - GPIOA_0)/ PORT_SIZE];
}
Пример #7
0
ioportmask_t getHwPin(brain_pin_e brainPin) {
	if (brainPin == GPIO_UNASSIGNED)
		return EFI_ERROR_CODE;
	if (brainPin > GPIO_UNASSIGNED || brainPin < 0) {
		firmwareError("Invalid brain_pin_e: %d", brainPin);
		return EFI_ERROR_CODE;
	}
	return brainPin % PORT_SIZE;
}
Пример #8
0
/**
 * @brief Reset histogram_s to orignal state
 */
void initHistogram(histogram_s *h, const char *name) {
	if (efiStrlen(name) > sizeof(h->name) - 1) {
		firmwareError(OBD_PCM_Processor_Fault, "Histogram name [%s] too long", name);
	}
	strcpy(h->name, name);
	h->total_value = 0;
	h->total_count = 0;
	memset(h->values, 0, sizeof(h->values));
}
Пример #9
0
GPIO_TypeDef * getHwPort(brain_pin_e brainPin) {
	if (brainPin == GPIO_UNASSIGNED)
		return GPIO_NULL;
	if (brainPin > GPIO_UNASSIGNED || brainPin < 0) {
		firmwareError("Invalid brain_pin_e: %d", brainPin);
		return GPIO_NULL;
	}
	return PORTS[brainPin / PORT_SIZE];
}
Пример #10
0
ioportid_t getHwPort(brain_pin_e brainPin) {
	if (brainPin == GPIO_UNASSIGNED)
		return GPIO_NULL;
	if (brainPin > GPIO_UNASSIGNED || brainPin < 0) {
		firmwareError(CUSTOM_ERR_INVALID_PIN, "Invalid brain_pin_e: %d", brainPin);
		return GPIO_NULL;
	}
	return PORTS[brainPin / PORT_SIZE];
}
Пример #11
0
void lcd_HD44780_init(Logging *sharedLogger) {
	logger = sharedLogger;

	addConsoleAction("lcdinfo", lcdInfo);

	if (engineConfiguration->displayMode > DM_HD44780_OVER_PCF8574) {
		firmwareError("Unexpected displayMode %d", engineConfiguration->displayMode);
		return;
	}

	printMsg(logger, "lcd_HD44780_init %d", engineConfiguration->displayMode);

	if (engineConfiguration->displayMode == DM_HD44780) {
		// initialize hardware lines
		mySetPadMode2("lcd RS", boardConfiguration->HD44780_rs, PAL_MODE_OUTPUT_PUSHPULL);
		mySetPadMode2("lcd E", boardConfiguration->HD44780_e, PAL_MODE_OUTPUT_PUSHPULL);
		mySetPadMode2("lcd DB4", boardConfiguration->HD44780_db4, PAL_MODE_OUTPUT_PUSHPULL);
		mySetPadMode2("lcd DB6", boardConfiguration->HD44780_db5, PAL_MODE_OUTPUT_PUSHPULL);
		mySetPadMode2("lcd DB7", boardConfiguration->HD44780_db6, PAL_MODE_OUTPUT_PUSHPULL);
		mySetPadMode2("lcd DB8", boardConfiguration->HD44780_db7, PAL_MODE_OUTPUT_PUSHPULL);
		// and zero values
		palWritePad(getHwPort(boardConfiguration->HD44780_rs), getHwPin(boardConfiguration->HD44780_rs), 0);
		palWritePad(getHwPort(boardConfiguration->HD44780_e), getHwPin(boardConfiguration->HD44780_e), 0);
		palWritePad(getHwPort(boardConfiguration->HD44780_db4), getHwPin(boardConfiguration->HD44780_db4), 0);
		palWritePad(getHwPort(boardConfiguration->HD44780_db5), getHwPin(boardConfiguration->HD44780_db5), 0);
		palWritePad(getHwPort(boardConfiguration->HD44780_db6), getHwPin(boardConfiguration->HD44780_db6), 0);
		palWritePad(getHwPort(boardConfiguration->HD44780_db7), getHwPin(boardConfiguration->HD44780_db7), 0);
	}

	chThdSleepMilliseconds(20); // LCD needs some time to wake up
	lcd_HD44780_write(LCD_HD44780_RESET); // reset 1x
	chThdSleepMilliseconds(1);
	lcd_HD44780_write(LCD_HD44780_RESET); // reset 2x
	lcd_HD44780_write(LCD_HD44780_RESET); // reset 3x

	lcd_HD44780_write(LCD_HD44780_4_BIT_BUS);	// 4 bit, 2 line
	chThdSleepMicroseconds(40);

	lcd_HD44780_write(LCD_HD44780_4_BIT_BUS);	// 4 bit, 2 line
	lcd_HD44780_write(0x80);
	chThdSleepMicroseconds(40);

	lcd_HD44780_write_command(0x08);	// display and cursor control
	chThdSleepMicroseconds(40);

	lcd_HD44780_write_command(LCD_HD44780_DISPLAY_CLEAR);
	chThdSleepMilliseconds(2);

	lcd_HD44780_write_command(LCD_HD44780_SHIFT_CURSOR_RIGHT);
	chThdSleepMilliseconds(2);

	lcd_HD44780_write_command(LCD_HD44780_DISPLAY_ON);

	lcd_HD44780_set_position(0, 0);
	printMsg(logger, "lcd_HD44780_init() done");
}
Пример #12
0
void startTunerStudioConnectivity(void) {
	if (sizeof(persistent_config_s) != getTunerStudioPageSize(0))
		firmwareError("TS page size mismatch: %d/%d", sizeof(persistent_config_s), getTunerStudioPageSize(0));

	if (sizeof(TunerStudioOutputChannels) != TS_OUTPUT_SIZE)
		firmwareError("TS outputs size mismatch: %d/%d", sizeof(TunerStudioOutputChannels), TS_OUTPUT_SIZE);

	memset(&tsState, 0, sizeof(tsState));
	syncTunerStudioCopy();

	addConsoleAction("tsinfo", printTsStats);
	addConsoleAction("reset_ts", resetTs);
	addConsoleActionI("set_ts_speed", setTsSpeed);

	tsChannel.channel = getTsSerialDevice();
	tsChannel.writeBuffer = tsCrcWriteBuffer;

	chThdCreateStatic(tsThreadStack, sizeof(tsThreadStack), NORMALPRIO, tsThreadEntryPoint, NULL);
}
Пример #13
0
static uint32_t doFindTrigger(TriggerStimulatorHelper *helper, trigger_shape_s * shape,
		trigger_config_s const*triggerConfig, TriggerState *state) {
	for (int i = 0; i < 4 * PWM_PHASE_MAX_COUNT; i++) {
		helper->nextStep(state, shape, i, triggerConfig);

		if (state->shaft_is_synchronized)
			return i;
	}
	firmwareError("findTriggerZeroEventIndex() failed");
	return EFI_ERROR_CODE;
}
Пример #14
0
static void doAddAction(const char *token, action_type_e type, Void callback, void *param) {
	for (uint32_t i = 0; i < efiStrlen(token);i++) {
		char ch = token[i];
		if (ch != mytolower(ch)) {
			firmwareError(CUSTOM_ERR_COMMAND_LOWER_CASE_EXPECTED, "lowerCase expected [%s]", token);
		}
	}
	for (int i = 0; i < consoleActionCount; i++) {
		if (strcmp(token, consoleActions[i].token) == 0 /* zero result means strings are equal */) {
			firmwareError(CUSTOM_SAME_TWICE, "Same action twice [%s]", token);
		}
	}

	efiAssertVoid(CUSTOM_CONSOLE_TOO_MANY, consoleActionCount < CONSOLE_MAX_ACTIONS, "Too many console actions");
	TokenCallback *current = &consoleActions[consoleActionCount++];
	current->token = token;
	current->parameterType = type;
	current->callback = callback;
	current->param = param;
}
Пример #15
0
/**
 * @returns true if data does not fit into this buffer
 */
static bool validateBuffer(Logging *logging, uint32_t extraLen) {
	if (logging->buffer == NULL) {
		firmwareError("Logging not initialized: %s", logging->name);
		return true;
	}

	if (remainingSize(logging) < extraLen + 1) {
		warning(OBD_PCM_Processor_Fault, "buffer overflow %s", logging->name);
		return true;
	}
	return false;
}
Пример #16
0
static void addChannel(const char *name, adc_channel_e setting, adc_channel_mode_e mode) {
	if (setting == EFI_ADC_NONE) {
		return;
	}
	if (adcHwChannelEnabled[setting] != ADC_OFF) {
		getPinNameByAdcChannel(name, setting, errorMsgBuff);
		firmwareError(CUSTOM_ERR_ADC_USED, "ADC mapping error: input %s for %s already used by %s?", errorMsgBuff, name, adcHwChannelUsage[setting]);
	}

	adcHwChannelUsage[setting] = name;
	adcHwChannelEnabled[setting] = mode;
}
Пример #17
0
OutputSignal * OutputSignalList::add(io_pin_e ioPin) {
	if (size == OUTPUT_SIGNAL_MAX_SIZE) {
		firmwareError("Too many signals, adding %d", ioPin);
		return NULL;
	}

	OutputSignal *signal = &signals[size++];

	initOutputSignal(signal, ioPin);

	return signal;
}
Пример #18
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();
	}
}
Пример #19
0
static void usTimerWatchDog(void) {
	if (getTimeNowNt() >= lastSetTimerTimeNt + 2 * CORE_CLOCK) {
		strcpy(buff, "no_event");
		itoa10(&buff[8], lastSetTimerValue);
		firmwareError(OBD_PCM_Processor_Fault, buff);
		return;
	}

	msg = isTimerPending ? "No_cb too long" : "Timer not awhile";
	// 2 seconds of inactivity would not look right
	efiAssertVoid(getTimeNowNt() < lastSetTimerTimeNt + 2 * CORE_CLOCK, msg);

}
Пример #20
0
	void PeriodicTask(efitime_t nowNt) override
	{
		if (nowNt >= lastSetTimerTimeNt + 2 * CORE_CLOCK) {
			strcpy(buff, "no_event");
			itoa10(&buff[8], lastSetTimerValue);
			firmwareError(CUSTOM_ERR_SCHEDULING_ERROR, buff);
			return;
		}

		msg = isTimerPending ? "No_cb too long" : "Timer not awhile";
		// 2 seconds of inactivity would not look right
		efiAssertVoid(CUSTOM_ERR_6682, nowNt < lastSetTimerTimeNt + 2 * CORE_CLOCK, msg);
	}
Пример #21
0
/**
 * Number of injections into each cylinder per engine cycle
 */
static int getNumberOfInjections(injection_mode_e mode DECLARE_ENGINE_PARAMETER_S) {
	switch (mode) {
	case IM_SIMULTANEOUS:
		return engineConfiguration->specs.cylindersCount;
	case IM_SEQUENTIAL:
		return 1;
	case IM_BATCH:
		return engineConfiguration->specs.cylindersCount / 2;
	default:
		firmwareError("Unexpected getFuelMultiplier %d", mode);
		return 1;
	}
}
Пример #22
0
/*
 * Return current TPS position based on configured ADC levels, and adc
 *
 * */
float getTpsValue(int adc) {
    if (adc < engineConfiguration->tpsMin) {
        return 0.0f;
    }
    if (adc > engineConfiguration->tpsMax) {
        return 100.0f;
    }
    // todo: double comparison using EPS
    if (engineConfiguration->tpsMin == engineConfiguration->tpsMax) {
        firmwareError("Invalid TPS configuration: same value");
        return 0.0f;
    }
    return interpolate(engineConfiguration->tpsMin, 0, engineConfiguration->tpsMax, 100, adc);
}
Пример #23
0
/**
 * @returns true if data does not fit into this buffer
 */
static INLINE bool validateBuffer(Logging *logging, uint32_t extraLen) {
	if (logging->buffer == NULL) {
		firmwareError("Logging not initialized: %s", logging->name);
		return true;
	}

	if (remainingSize(logging) < extraLen + 1) {
#if EFI_PROD_CODE
		warning(OBD_PCM_Processor_Fault, "output overflow %s", logging->name);
#endif
		return true;
	}
	return false;
}
Пример #24
0
/**
 * @brief Initialize the hardware output pin while also assigning it a logical name
 */
void initOutputPinExt(const char *msg, OutputPin *outputPin, ioportid_t port, uint32_t pinNumber, iomode_t mode) {
	if (outputPin->port != NULL && (outputPin->port != port || outputPin->pin != pinNumber)) {
		/**
		 * here we check if another physical pin is already assigned to this logical output
		 */
// todo: need to clear '&outputs' in io_pins.c
		firmwareError(OBD_PCM_Processor_Fault, "outputPin [%s] already assigned to %x%d", msg, outputPin->port, outputPin->pin);
		return;
	}
	outputPin->currentLogicValue = INITIAL_PIN_STATE;
	outputPin->port = port;
	outputPin->pin = pinNumber;

	mySetPadMode(msg, port, pinNumber, mode);
}
Пример #25
0
void EventQueue::insertTask(scheduling_s *scheduling, uint64_t nowUs, int delayUs, schfunc_t callback, void *param) {
    if (callback == NULL)
        firmwareError("NULL callback");
    uint64_t time = nowUs + delayUs;

    int alreadyPending = checkIfPending(scheduling);
    if (alreadyPending || hasFirmwareError())
        return;

    scheduling->momentUs = time;
    scheduling->callback = callback;
    scheduling->param = param;

    LL_PREPEND(head, scheduling);
}
Пример #26
0
static const char *getPinShortName(io_pin_e pin) {
	switch (pin) {
	case ALTERNATOR_SWITCH:
		return "AL";
	case FUEL_PUMP_RELAY:
		return "FP";
	case FAN_RELAY:
		return "FN";
	case O2_HEATER:
		return "O2H";
	default:
		firmwareError("No short name for %d", (int) pin);
		return "";
	}
}
Пример #27
0
/**
 * Schedules a callback 'angle' degree of crankshaft from now.
 * The callback would be executed once after the duration of time which
 * it takes the crankshaft to rotate to the specified angle.
 */
void scheduleByAngle(int rpm, scheduling_s *timer, angle_t angle, schfunc_t callback, void *param) {
	if (!isValidRpm(rpm)) {
		/**
		 * this might happen in case of a single trigger event after a pause - this is normal, so no
		 * warning here
		 */
		return;
	}
	float delayUs = getOneDegreeTimeUs(rpm) * angle;
	if (cisnan(delayUs)) {
		firmwareError("NaN delay?");
		return;
	}
	scheduleTask("by angle", timer, (int) delayUs, callback, param);
}
Пример #28
0
//Nullable
ICUDriver * getInputCaptureDriver(const char *msg, brain_pin_e hwPin) {
	if (hwPin == GPIO_UNASSIGNED || hwPin == GPIO_INVALID) {
		return NULL;
	}
#if STM32_ICU_USE_TIM1
	if (hwPin == GPIOA_8 ||
	    hwPin == GPIOA_9 ||
		hwPin == GPIOE_9 ||
		hwPin == GPIOE_11) {
		return &ICUD1;
	}
#endif
#if STM32_ICU_USE_TIM2
	if (hwPin == GPIOA_1 ||
		hwPin == GPIOA_5 ||
		hwPin == GPIOA_15 ||
		hwPin == GPIOB_3) {
		return &ICUD2;
	}
#endif
#if STM32_ICU_USE_TIM3
	if (hwPin == GPIOA_6 ||
		hwPin == GPIOA_7 ||
		hwPin == GPIOB_4 ||
		hwPin == GPIOB_5 ||
		hwPin == GPIOC_6 ||
		hwPin == GPIOC_7) {
		return &ICUD3;
	}
#endif
#if STM32_ICU_USE_TIM8
	if (hwPin == GPIOC_6 ||
		hwPin == GPIOC_7) {
		return &ICUD8;
	}
#endif
#if STM32_ICU_USE_TIM9
	if (hwPin == GPIOA_2 ||
		hwPin == GPIOA_3 ||
		hwPin == GPIOE_5 ||
		hwPin == GPIOE_6) {
		return &ICUD9;
	}
#endif
	firmwareError(CUSTOM_ERR_NOT_INPUT_PIN, "%s: Not input pin %s", msg, hwPortname(hwPin));
	return (ICUDriver *) NULL;
}
Пример #29
0
void initializeIgnitionActions(float advance, float dwellAngle, engine_configuration_s *engineConfiguration,
                               engine_configuration2_s *engineConfiguration2, IgnitionEventList *list) {

    efiAssertVoid(engineConfiguration->cylindersCount > 0, "cylindersCount");

    list->resetEventList();

    switch (engineConfiguration->ignitionMode) {
    case IM_ONE_COIL:
        for (int i = 0; i < engineConfiguration->cylindersCount; i++) {
            // todo: extract method
            float localAdvance = advance + 720.0f * i / engineConfiguration->cylindersCount;

            registerSparkEvent(engineConfiguration, &engineConfiguration2->triggerShape, list,
                               SPARKOUT_1_OUTPUT, localAdvance, dwellAngle);
        }
        break;
    case IM_WASTED_SPARK:
        for (int i = 0; i < engineConfiguration->cylindersCount; i++) {
            float localAdvance = advance + 720.0f * i / engineConfiguration->cylindersCount;

            int wastedIndex = i % (engineConfiguration->cylindersCount / 2);

            int id = getCylinderId(engineConfiguration->firingOrder, wastedIndex) - 1;
            io_pin_e ioPin = (io_pin_e) (SPARKOUT_1_OUTPUT + id);

            registerSparkEvent(engineConfiguration, &engineConfiguration2->triggerShape, list,
                               ioPin, localAdvance, dwellAngle);

        }

        break;
    case IM_INDIVIDUAL_COILS:
        for (int i = 0; i < engineConfiguration->cylindersCount; i++) {
            float localAdvance = advance + 720.0f * i / engineConfiguration->cylindersCount;

            io_pin_e pin = (io_pin_e) ((int) SPARKOUT_1_OUTPUT + getCylinderId(engineConfiguration->firingOrder, i) - 1);
            registerSparkEvent(engineConfiguration, &engineConfiguration2->triggerShape, list, pin,
                               localAdvance, dwellAngle);
        }
        break;

    default:
        firmwareError("unsupported ignitionMode %d in initializeIgnitionActions()", engineConfiguration->ignitionMode);
    }
}
Пример #30
0
/**
 * @param index from zero to cylindersCount - 1
 * @return cylinderId from one to cylindersCount
 */
int getCylinderId(firing_order_e firingOrder, int index) {

    switch (firingOrder) {
    case FO_ONE_CYLINDER:
        return 1;
    case FO_1_THEN_3_THEN_4_THEN2:
        return order_1_THEN_3_THEN_4_THEN2[index];
    case FO_1_THEN_5_THEN_3_THEN_6_THEN_2_THEN_4:
        return order_1_THEN_5_THEN_3_THEN_6_THEN_2_THEN_4[index];
    case FO_1_8_4_3_6_5_7_2:
        return order_1_8_4_3_6_5_7_2[index];

    default:
        firmwareError("getCylinderId not supported for %d", firingOrder);
    }
    return -1;
}