new files
This commit is contained in:
parent
0367b7e344
commit
4aab101ebd
|
@ -3,7 +3,7 @@ rm -rf .dep/
|
|||
|
||||
rm -rf build\rusefi.hex
|
||||
|
||||
java -jar ../java_tools/version2header.jar
|
||||
call update_version.bat
|
||||
|
||||
echo Starting compilation
|
||||
make
|
||||
|
|
|
@ -115,7 +115,7 @@ void printSensors(void) {
|
|||
#endif /* EFI_FILE_LOGGING */
|
||||
|
||||
// current time, in milliseconds
|
||||
int nowMs = chTimeNow() / TICKS_IN_MS;
|
||||
int nowMs = currentTimeMillis();
|
||||
float sec = ((float) nowMs) / 1000;
|
||||
reportSensorF("time", sec, 3);
|
||||
|
||||
|
@ -263,7 +263,7 @@ void updateDevConsoleState(void) {
|
|||
if (!fullLog)
|
||||
return;
|
||||
|
||||
systime_t nowSeconds = chTimeNowSeconds();
|
||||
systime_t nowSeconds = getTimeNowSeconds();
|
||||
printVersion(nowSeconds);
|
||||
|
||||
int currentCkpEventCounter = getCrankEventCounter();
|
||||
|
|
|
@ -12,8 +12,8 @@
|
|||
|
||||
#include "global.h"
|
||||
|
||||
// number of ticks in one period of given frequency (per second)
|
||||
#define frequency2period(freq) (((float)CH_FREQUENCY) / (freq))
|
||||
// number of milliseconds in one period of given frequency (per second)
|
||||
#define frequency2period(freq) (((float)1000) / (freq))
|
||||
|
||||
float floatmod(float value, float divider);
|
||||
int waveState(time_t start, time_t now, float waveLen, float leftSide,
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
svn up
|
||||
call generate_docs
|
||||
|
||||
rem http://www.ncftp.com/download/
|
||||
cd ../doxygen
|
||||
ncftpput -u u71977750-docs -p docspass rusefi.com /html html/*
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
/**
|
||||
* @file main.cpp
|
||||
* @brief C++ main entry point
|
||||
*
|
||||
* @date Nov 29, 2012
|
||||
* @author Andrey Belomutskiy, (c) 2012-2014
|
||||
* http://rusefi.com/
|
||||
*/
|
||||
|
||||
extern "C"
|
||||
{
|
||||
#include "global.h"
|
||||
}
|
||||
#include "main.h"
|
||||
|
||||
extern "C"
|
||||
{
|
||||
#include "rusefi.h"
|
||||
}
|
||||
int main(void) {
|
||||
/*
|
||||
* ChibiOS/RT initialization
|
||||
*/
|
||||
halInit();
|
||||
chSysInit();
|
||||
|
||||
// looks like this holds a random value on start? Let's set a nice clean zero
|
||||
DWT_CYCCNT = 0;
|
||||
|
||||
runRusEfi();
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -0,0 +1,61 @@
|
|||
/**
|
||||
* @file main.h
|
||||
*
|
||||
* @date Nov 29, 2012
|
||||
* @author Andrey Belomutskiy, (c) 2012-2014
|
||||
*/
|
||||
#pragma once
|
||||
#ifndef MAIN_H_
|
||||
#define MAIN_H_
|
||||
|
||||
#include <math.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#include "global.h"
|
||||
|
||||
#include "eficonsole.h"
|
||||
#include "eficonsole_logic.h"
|
||||
#include "efilib.h"
|
||||
#include "rusefi.h"
|
||||
|
||||
#include "efifeatures.h"
|
||||
#include "efitime.h"
|
||||
#include "engines.h"
|
||||
|
||||
#include "datalogging.h"
|
||||
#include "chprintf.h"
|
||||
|
||||
#include "stm32f4xx_specific.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
|
||||
// todo: access some existing configuration field
|
||||
#define CORE_CLOCK 168000000
|
||||
|
||||
/**
|
||||
* number of SysClock ticks in one ms
|
||||
*/
|
||||
#define TICKS_IN_MS (CH_FREQUENCY / 1000)
|
||||
|
||||
#define Delay(ms) chThdSleepMilliseconds(ms)
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
void updateHD44780lcd(void);
|
||||
int systicks2ms(int systicks);
|
||||
|
||||
int lockAnyContext(void);
|
||||
void unlockAnyContext(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* MAIN_H_ */
|
|
@ -0,0 +1,278 @@
|
|||
/**
|
||||
* @file rusefi.c
|
||||
* @brief Initialization code and main status reporting look
|
||||
*
|
||||
* @date Dec 25, 2013
|
||||
* @author Andrey Belomutskiy, (c) 2012-2014
|
||||
*/
|
||||
|
||||
/**
|
||||
* @mainpage
|
||||
*
|
||||
* @section sec_main Brief overview
|
||||
*
|
||||
* rusEfi runs on crankshaft or camshaft ('trigger') position sensor events.
|
||||
* Once per crankshaft revolution we evaluate the amount of needed fuel and
|
||||
* the spark timing. Once we have decided on the parameters for this revolution
|
||||
* we schedule all the actions to be triggered by the closest trigger event.
|
||||
*
|
||||
* We also have some utility threads like idle control thread and communication threads.
|
||||
*
|
||||
*
|
||||
*
|
||||
* @section sec_trigger Trigger Decoding
|
||||
*
|
||||
* Our primary trigger decoder is based on the idea of synchronizing the primary shaft signal and simply counting events on
|
||||
* the secondary signal. A typical scenario would be when camshaft positions sensor is the primary signal and crankshaft is secondary,
|
||||
* but sometimes there would be two signals generated by two camshaft sensors.
|
||||
* Another scenario is when we only have crankshaft position sensor, this would make it the primary signal and there would be no secondary signal.
|
||||
*
|
||||
* There is no software filtering so the signals are expected to be valid. TODO: in reality we are still catching engine stop noise as unrealisticly high RPM.
|
||||
*
|
||||
* The decoder is configured to act either on the primary signal rise or on the primary signal fall. It then compares the duration
|
||||
* of time from the previous signal to the duration of time from the signal before previous, and if the ratio falls into the configurable
|
||||
* range between 'syncRatioFrom' and 'syncRatioTo' this is assumed to be the synchronizing event.
|
||||
*
|
||||
* For instance, for a 36/1 skipped tooth wheel the ratio range for synchronization is from 1.5 to 3
|
||||
*
|
||||
* Some triggers do not require synchronization, this case we just count signals.
|
||||
* A single tooth primary signal would be a typical example when synchronization is not needed.
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
* @section sec_scheduler Event Scheduler
|
||||
*
|
||||
* It is a general agreement to measure all angles in crankshaft angles. In a four stroke
|
||||
* engine, a full cycle consists of two revolutions of the crankshaft, so all the angles are
|
||||
* running between 0 and 720 degrees.
|
||||
*
|
||||
* Ignition timing is a great example of a process which highlights the need of a hybrid
|
||||
* approach to event scheduling.
|
||||
* The most important part of controlling ignition
|
||||
* is firing up the spark at the right moment - so, for this job we need 'angle-based' timing,
|
||||
* for example we would need to fire up the spark at 700 degrees. Before we can fire up the spark
|
||||
* at 700 degrees, we need to charge the ignition coil, for example this dwell time is 4ms - that
|
||||
* means we need to turn on the coil at '4 ms before 700 degrees'. Let's assume that the engine is
|
||||
* current at 600 RPM - that means 360 degrees would take 100ms so 4ms is 14.4 degrees at current RPM which
|
||||
* means we need to start charting the coil at 685.6 degrees.
|
||||
*
|
||||
* The position sensors at our disposal are not providing us the current position at any moment of time -
|
||||
* all we've got is a set of events which are happening at the knows positions. For instance, let's assume that
|
||||
* our sensor sends as an event at 0 degrees, at 90 degrees, at 600 degrees and and 690 degrees.
|
||||
*
|
||||
* So, for this particular sensor the most precise scheduling would be possible if we schedule coil charting
|
||||
* as '85.6 degrees after the 600 degrees position sensor event', and spark firing as
|
||||
* '10 degrees after the 690 position sensor event'. Considering current RPM, we calculate that '10 degress after' is
|
||||
* 2.777ms, so we schedule spark firing at '2.777ms after the 690 position sensor event', thus combining trigger events
|
||||
* with time-based offset.
|
||||
*
|
||||
*
|
||||
* @section sec_fuel_injection Fuel Injection
|
||||
*
|
||||
*
|
||||
* @sectuion sec_misc
|
||||
*
|
||||
* <BR>See main_trigger_callback.cpp for main trigger event handler
|
||||
* <BR>See fuel_math.cpp for details on fuel amount logic
|
||||
* <BR>See rpm_calculator.c for details on how getRpm() is calculated
|
||||
*
|
||||
*/
|
||||
|
||||
extern "C" {
|
||||
|
||||
#include "global.h"
|
||||
|
||||
#include "main.h"
|
||||
#include "rusefi.h"
|
||||
#include "eficonsole.h"
|
||||
#include "hardware.h"
|
||||
#include "engine_controller.h"
|
||||
#include "lcd_HD44780.h"
|
||||
#include "status_loop.h"
|
||||
#include "pin_repository.h"
|
||||
|
||||
#include "status_loop.h"
|
||||
#include "memstreams.h"
|
||||
}
|
||||
|
||||
#if EFI_ENGINE_EMULATOR
|
||||
#include "engine_emulator.h"
|
||||
#endif /* EFI_ENGINE_EMULATOR */
|
||||
|
||||
static Logging logging;
|
||||
|
||||
int main_loop_started = FALSE;
|
||||
|
||||
static MemoryStream errorMessageStream;
|
||||
uint8_t errorMessageBuffer[200];
|
||||
bool hasFirmwareError = FALSE;
|
||||
|
||||
void runRusEfi(void) {
|
||||
msObjectInit(&errorMessageStream, errorMessageBuffer, sizeof(errorMessageBuffer), 0);
|
||||
|
||||
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");
|
||||
|
||||
addConsoleAction("reset", scheduleReset);
|
||||
|
||||
/**
|
||||
* Initialize hardware drivers
|
||||
*/
|
||||
initHardware();
|
||||
|
||||
initStatusLoop();
|
||||
/**
|
||||
* Now let's initialize actual engine control logic
|
||||
* todo: should we initialize some? most? controllers before hardware?
|
||||
*/
|
||||
initEngineContoller();
|
||||
|
||||
#if EFI_ENGINE_EMULATOR
|
||||
initEngineEmulator();
|
||||
#endif
|
||||
startStatusThreads();
|
||||
|
||||
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) {
|
||||
#if EFI_CLI_SUPPORT
|
||||
// sensor state + all pending messages for our own dev console
|
||||
updateDevConsoleState();
|
||||
#endif /* EFI_CLI_SUPPORT */
|
||||
|
||||
chThdSleepMilliseconds(5);
|
||||
}
|
||||
}
|
||||
|
||||
int systicks2ms(int systicks) {
|
||||
return systicks / TICKS_IN_MS;
|
||||
}
|
||||
|
||||
static VirtualTimer resetTimer;
|
||||
|
||||
static void rebootNow(void) {
|
||||
NVIC_SystemReset();
|
||||
}
|
||||
/**
|
||||
* Some configuration changes require full firmware reset.
|
||||
* Once day we will write graceful shutdown, but that would be one day.
|
||||
*/
|
||||
void scheduleReset(void) {
|
||||
scheduleMsg(&logging, "Rebooting in 5 seconds...");
|
||||
lockAnyContext();
|
||||
chVTSetI(&resetTimer, 5 * CH_FREQUENCY, (vtfunc_t) rebootNow, NULL);
|
||||
unlockAnyContext();
|
||||
}
|
||||
|
||||
extern "C" {
|
||||
void onFatalError(const char *msg, char * file, int line);
|
||||
}
|
||||
|
||||
void onFatalError(const char *msg, char * file, int line) {
|
||||
onDbgPanic();
|
||||
lcdShowFatalMessage((char *) msg);
|
||||
if (!main_loop_started) {
|
||||
print("fatal %s %s:%d\r\n", msg, file, line);
|
||||
chThdSleepSeconds(1);
|
||||
chSysHalt();
|
||||
}
|
||||
}
|
||||
|
||||
void DebugMonitorVector(void) {
|
||||
|
||||
chDbgPanic3("DebugMonitorVector", __FILE__, __LINE__);
|
||||
|
||||
while (TRUE)
|
||||
;
|
||||
}
|
||||
|
||||
void UsageFaultVector(void) {
|
||||
|
||||
chDbgPanic3("UsageFaultVector", __FILE__, __LINE__);
|
||||
|
||||
while (TRUE)
|
||||
;
|
||||
}
|
||||
|
||||
void BusFaultVector(void) {
|
||||
|
||||
chDbgPanic3("BusFaultVector", __FILE__, __LINE__);
|
||||
|
||||
while (TRUE)
|
||||
;
|
||||
}
|
||||
|
||||
void HardFaultVector(void) {
|
||||
|
||||
chDbgPanic3("HardFaultVector", __FILE__, __LINE__);
|
||||
|
||||
while (TRUE)
|
||||
;
|
||||
}
|
||||
|
||||
|
||||
extern int main_loop_started;
|
||||
|
||||
int hasFatalError(void);
|
||||
|
||||
void onFatalError(const char *msg, char * file, int line);
|
||||
|
||||
char *dbg_panic_file;
|
||||
int dbg_panic_line;
|
||||
|
||||
extern "C" {
|
||||
void chDbgPanic3(const char *msg, char * file, int line);
|
||||
}
|
||||
|
||||
void chDbgPanic3(const char *msg, char * file, int line) {
|
||||
if (hasFatalError())
|
||||
return;
|
||||
dbg_panic_file = file;
|
||||
dbg_panic_line = line;
|
||||
dbg_panic_msg = msg;
|
||||
onFatalError(dbg_panic_msg, dbg_panic_file, dbg_panic_line);
|
||||
}
|
||||
|
||||
static char panicMessage[200];
|
||||
|
||||
void chDbgStackOverflowPanic(Thread *otp) {
|
||||
strcpy(panicMessage, "stack overflow: ");
|
||||
#ifdef CH_USE_REGISTRY
|
||||
strcat(panicMessage, otp->p_name);
|
||||
#endif
|
||||
chDbgPanic3(panicMessage, __FILE__, __LINE__);
|
||||
}
|
||||
|
||||
|
||||
void firmwareError(const char *fmt, ...) {
|
||||
if (hasFirmwareError)
|
||||
return;
|
||||
hasFirmwareError = TRUE;
|
||||
errorMessageStream.eos = 0; // reset
|
||||
va_list ap;
|
||||
va_start(ap, fmt);
|
||||
chvprintf((BaseSequentialStream *) &errorMessageStream, fmt, ap);
|
||||
va_end(ap);
|
||||
|
||||
errorMessageStream.buffer[errorMessageStream.eos] = 0; // need to terminate explicitly
|
||||
}
|
||||
|
||||
int getRusEfiVersion(void) {
|
||||
return 20140424;
|
||||
}
|
|
@ -0,0 +1,4 @@
|
|||
// This file was generated by Version2Header
|
||||
#ifndef SVN_VERSION
|
||||
#define SVN_VERSION 2853
|
||||
#endif
|
|
@ -0,0 +1 @@
|
|||
java -jar ../java_tools/version2header.jar
|
Loading…
Reference in New Issue