diff --git a/firmware/console/console.mk b/firmware/console/console.mk index e75257e6eb..97ff010e9b 100644 --- a/firmware/console/console.mk +++ b/firmware/console/console.mk @@ -1,6 +1,5 @@ -CONSOLESRC = $(PROJECT_DIR)/console/eficonsole.c \ - $(PROJECT_DIR)/console/console_io.c +CONSOLESRC = $(PROJECT_DIR)/console/console_io.c -CONSOLE_SRC_CPP = $(PROJECT_DIR)/console/status_loop.cpp - \ No newline at end of file +CONSOLE_SRC_CPP = $(PROJECT_DIR)/console/status_loop.cpp \ + $(PROJECT_DIR)/controllers/error_handling.cpp diff --git a/firmware/console/eficonsole.c b/firmware/console/eficonsole.cpp similarity index 100% rename from firmware/console/eficonsole.c rename to firmware/console/eficonsole.cpp diff --git a/firmware/controllers/algo/auto_generated_enums.cpp b/firmware/controllers/algo/auto_generated_enums.cpp index f4faaa33e1..5c646ed7cf 100644 --- a/firmware/controllers/algo/auto_generated_enums.cpp +++ b/firmware/controllers/algo/auto_generated_enums.cpp @@ -3,61 +3,6 @@ #include "main.h" #include "io_pins.h" -const char *getIo_pin_e(io_pin_e value){ -switch(value) { -case INJECTOR_10_OUTPUT: - return "INJECTOR_10_OUTPUT"; -case INJECTOR_11_OUTPUT: - return "INJECTOR_11_OUTPUT"; -case INJECTOR_12_OUTPUT: - return "INJECTOR_12_OUTPUT"; -case INJECTOR_1_OUTPUT: - return "INJECTOR_1_OUTPUT"; -case INJECTOR_2_OUTPUT: - return "INJECTOR_2_OUTPUT"; -case INJECTOR_3_OUTPUT: - return "INJECTOR_3_OUTPUT"; -case INJECTOR_4_OUTPUT: - return "INJECTOR_4_OUTPUT"; -case INJECTOR_5_OUTPUT: - return "INJECTOR_5_OUTPUT"; -case INJECTOR_6_OUTPUT: - return "INJECTOR_6_OUTPUT"; -case INJECTOR_7_OUTPUT: - return "INJECTOR_7_OUTPUT"; -case INJECTOR_8_OUTPUT: - return "INJECTOR_8_OUTPUT"; -case INJECTOR_9_OUTPUT: - return "INJECTOR_9_OUTPUT"; -case IO_INVALID: - return "IO_INVALID"; -case SPARKOUT_10_OUTPUT: - return "SPARKOUT_10_OUTPUT"; -case SPARKOUT_11_OUTPUT: - return "SPARKOUT_11_OUTPUT"; -case SPARKOUT_12_OUTPUT: - return "SPARKOUT_12_OUTPUT"; -case SPARKOUT_1_OUTPUT: - return "SPARKOUT_1_OUTPUT"; -case SPARKOUT_2_OUTPUT: - return "SPARKOUT_2_OUTPUT"; -case SPARKOUT_3_OUTPUT: - return "SPARKOUT_3_OUTPUT"; -case SPARKOUT_4_OUTPUT: - return "SPARKOUT_4_OUTPUT"; -case SPARKOUT_5_OUTPUT: - return "SPARKOUT_5_OUTPUT"; -case SPARKOUT_6_OUTPUT: - return "SPARKOUT_6_OUTPUT"; -case SPARKOUT_7_OUTPUT: - return "SPARKOUT_7_OUTPUT"; -case SPARKOUT_8_OUTPUT: - return "SPARKOUT_8_OUTPUT"; -case SPARKOUT_9_OUTPUT: - return "SPARKOUT_9_OUTPUT"; - } - return NULL; -} // auto-generated from../../firmware/\controllers/algo/rusefi_enums.h // by enum2string.jar tool diff --git a/firmware/controllers/algo/auto_generated_enums.h b/firmware/controllers/algo/auto_generated_enums.h index 2101f2aa90..a56cd3be1d 100644 --- a/firmware/controllers/algo/auto_generated_enums.h +++ b/firmware/controllers/algo/auto_generated_enums.h @@ -4,7 +4,6 @@ #include "io_pins.h" -const char *getIo_pin_e(io_pin_e value); // auto-generated from../../firmware/controllers/algo/rusefi_enums.h diff --git a/firmware/controllers/algo/engine.h b/firmware/controllers/algo/engine.h index adbc65967f..99869d0713 100644 --- a/firmware/controllers/algo/engine.h +++ b/firmware/controllers/algo/engine.h @@ -134,18 +134,6 @@ public: uint32_t beforeIgnitionSch; uint32_t ignitionSchTime; - uint32_t time2; - uint32_t time3; - uint32_t time4; - uint32_t time5; - uint32_t time6; - - uint32_t before2; - uint32_t before3; - uint32_t before4; - uint32_t before5; - uint32_t before6; - float sparkAtable[DWELL_CURVE_SIZE]; float sparkBtable[DWELL_CURVE_SIZE]; diff --git a/firmware/controllers/algo/io_pins.h b/firmware/controllers/algo/io_pins.h index 0a5add83d4..d90d50a48c 100644 --- a/firmware/controllers/algo/io_pins.h +++ b/firmware/controllers/algo/io_pins.h @@ -31,37 +31,6 @@ typedef enum { INJECTOR_NONE, } injector_channel_e; -/** - * Logical pins. See brain_pin_e for physical pins. - */ -typedef enum { - SPARKOUT_1_OUTPUT, - SPARKOUT_2_OUTPUT, - SPARKOUT_3_OUTPUT, - SPARKOUT_4_OUTPUT, - SPARKOUT_5_OUTPUT, - SPARKOUT_6_OUTPUT, - SPARKOUT_7_OUTPUT, - SPARKOUT_8_OUTPUT, - SPARKOUT_9_OUTPUT, - SPARKOUT_10_OUTPUT, - SPARKOUT_11_OUTPUT, - SPARKOUT_12_OUTPUT, - - INJECTOR_1_OUTPUT, - INJECTOR_2_OUTPUT, - INJECTOR_3_OUTPUT, - INJECTOR_4_OUTPUT, - INJECTOR_5_OUTPUT, - INJECTOR_6_OUTPUT, - INJECTOR_7_OUTPUT, - INJECTOR_8_OUTPUT, - INJECTOR_9_OUTPUT, - INJECTOR_10_OUTPUT, - INJECTOR_11_OUTPUT, - INJECTOR_12_OUTPUT, - - IO_INVALID, /** * these seven segment display pins are related to unused external tachometer code @@ -94,13 +63,9 @@ typedef enum { // LED_HUGE_19, // LED_HUGE_20, -} io_pin_e; - void initPrimaryPins(void); void initOutputPins(void); -io_pin_e getPinByName(const char *name); - #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ diff --git a/firmware/controllers/algo/signal_executor.cpp b/firmware/controllers/algo/signal_executor.cpp index d4014d3ad8..ae4124e714 100644 --- a/firmware/controllers/algo/signal_executor.cpp +++ b/firmware/controllers/algo/signal_executor.cpp @@ -141,11 +141,3 @@ void scheduleOutput(OutputSignal *signal, float delayMs, float durationMs) { scheduleTask("out down", sDown, (int) MS2US(delayMs) + MS2US(durationMs), (schfunc_t) &turnPinLow, signal->output); #endif } - -io_pin_e getPinByName(const char *name) { - if (startsWith(name, "spa")) { - int index = atoi(name + 3); - return (io_pin_e) ((int) SPARKOUT_1_OUTPUT - 1 + index); - } - return IO_INVALID; -} diff --git a/firmware/controllers/controllers.mk b/firmware/controllers/controllers.mk index a1c7c2fd45..9e01fa9612 100644 --- a/firmware/controllers/controllers.mk +++ b/firmware/controllers/controllers.mk @@ -1,9 +1,9 @@ -CONTROLLERSSRC = \ - $(PROJECT_DIR)/controllers/error_handling.c +CONTROLLERSSRC = CONTROLLERS_SRC_CPP = $(PROJECT_DIR)/controllers/settings.cpp \ controllers/electronic_throttle.cpp \ + $(PROJECT_DIR)/controllers/error_handling.cpp \ controllers/map_averaging.cpp \ controllers/flash_main.cpp \ controllers/injector_central.cpp \ diff --git a/firmware/controllers/error_handling.c b/firmware/controllers/error_handling.cpp similarity index 100% rename from firmware/controllers/error_handling.c rename to firmware/controllers/error_handling.cpp diff --git a/firmware/controllers/injector_central.cpp b/firmware/controllers/injector_central.cpp index 660e71171f..d346001ad7 100644 --- a/firmware/controllers/injector_central.cpp +++ b/firmware/controllers/injector_central.cpp @@ -239,8 +239,6 @@ void initInjectorCentral(Engine *engine) { // todo: should we move this code closer to the injection logic? for (int i = 0; i < engineConfiguration->cylindersCount; i++) { - io_pin_e pin = (io_pin_e) ((int) INJECTOR_1_OUTPUT + i); - NamedOutputPin *output = &enginePins.coils[i]; outputPinRegisterExt2(output->name, output, boardConfiguration->injectionPins[i], diff --git a/firmware/controllers/math/engine_math.cpp b/firmware/controllers/math/engine_math.cpp index 23cd11340a..c04107c7f4 100644 --- a/firmware/controllers/math/engine_math.cpp +++ b/firmware/controllers/math/engine_math.cpp @@ -34,12 +34,6 @@ EXTERN_ENGINE extern engine_pins_s enginePins; -/** - * this cache allows us to find a close-enough (with one degree precision) trigger wheel index by - * given angle with fast constant speed - */ -static int triggerIndexByAngle[720]; - /* * default Volumetric Efficiency */ @@ -255,7 +249,7 @@ void findTriggerPosition(event_trigger_position_s *position, angle_t angleOffset angleOffset += CONFIG(globalTriggerAngleOffset); fixAngle(angleOffset); - int index = triggerIndexByAngle[(int)angleOffset]; + int index = TRIGGER_SHAPE(triggerIndexByAngle[(int)angleOffset]); angle_t eventAngle = TRIGGER_SHAPE(eventAngles[index]); if (angleOffset < eventAngle) { firmwareError("angle constraint violation in registerActuatorEventExt(): %f/%f", angleOffset, eventAngle); @@ -333,7 +327,7 @@ void prepareOutputSignals(DECLARE_ENGINE_PARAMETER_F) { } for (int angle = 0; angle < CONFIG(engineCycle); angle++) { - triggerIndexByAngle[angle] = findAngleIndex(angle PASS_ENGINE_PARAMETER); + TRIGGER_SHAPE(triggerIndexByAngle[angle]) = findAngleIndex(angle PASS_ENGINE_PARAMETER); } injectonSignals.reset(); diff --git a/firmware/controllers/math/engine_math.h b/firmware/controllers/math/engine_math.h index dcf2933270..637ff6343a 100644 --- a/firmware/controllers/math/engine_math.h +++ b/firmware/controllers/math/engine_math.h @@ -18,8 +18,6 @@ typedef ArrayList OutputSignalList; -#define INJECTOR_PIN_BY_INDEX(index) (io_pin_e) ((int) INJECTOR_1_OUTPUT + (index)) - void findTriggerPosition( event_trigger_position_s *position, float angleOffset DECLARE_ENGINE_PARAMETER_S); diff --git a/firmware/controllers/trigger/trigger_structure.h b/firmware/controllers/trigger/trigger_structure.h index 3d095cdbf3..f3cd104491 100644 --- a/firmware/controllers/trigger/trigger_structure.h +++ b/firmware/controllers/trigger/trigger_structure.h @@ -38,6 +38,12 @@ public: float dutyCycle[PWM_PHASE_MAX_WAVE_PER_PWM]; + /** + * this cache allows us to find a close-enough (with one degree precision) trigger wheel index by + * given angle with fast constant speed + */ + int triggerIndexByAngle[720]; + float syncRatioFrom; float syncRatioTo; diff --git a/firmware/development/development.mk b/firmware/development/development.mk index b26633ede1..d7452d211b 100644 --- a/firmware/development/development.mk +++ b/firmware/development/development.mk @@ -1,9 +1,9 @@ -DEV_SRC = development/hw_layer/poten.c \ - development/test/test.c \ +DEV_SRC = development/test/test.c \ development/test/testbmk.c DEV_SRC_CPP = development/trigger_emulator.cpp \ + development/hw_layer/poten.cpp \ development/analog_chart.cpp \ development/rfi_perftest.cpp \ development/engine_emulator.cpp \ diff --git a/firmware/development/engine_emulator.cpp b/firmware/development/engine_emulator.cpp index 2a1c73c2f7..2210cb185b 100644 --- a/firmware/development/engine_emulator.cpp +++ b/firmware/development/engine_emulator.cpp @@ -17,9 +17,7 @@ #include "pin_repository.h" #include "pwm_generator_logic.h" -extern "C" { #include "poten.h" -} #include "trigger_emulator.h" extern bool hasFirmwareErrorFlag; diff --git a/firmware/development/hw_layer/poten.c b/firmware/development/hw_layer/poten.cpp similarity index 100% rename from firmware/development/hw_layer/poten.c rename to firmware/development/hw_layer/poten.cpp diff --git a/firmware/hw_layer/hw_layer.mk b/firmware/hw_layer/hw_layer.mk index c04df5426b..064374110e 100644 --- a/firmware/hw_layer/hw_layer.mk +++ b/firmware/hw_layer/hw_layer.mk @@ -5,17 +5,17 @@ HW_LAYER_EGT_CPP = $(PROJECT_DIR)/hw_layer/can_hw.cpp \ $(PROJECT_DIR)/hw_layer/max31855.cpp HW_LAYER_EMS = $(HW_LAYER_EGT) \ - $(PROJECT_DIR)/hw_layer/pin_repository.c \ $(PROJECT_DIR)/hw_layer/mcp3208.c \ $(PROJECT_DIR)/hw_layer/microsecond_timer.c \ $(PROJECT_DIR)/hw_layer/flash.c \ $(PROJECT_DIR)/hw_layer/rtc_helper.c \ - $(PROJECT_DIR)/hw_layer/mmc_card.c \ - $(PROJECT_DIR)/hw_layer/neo6m.c \ $(PROJECT_DIR)/hw_layer/wave_analyzer_hw.c HW_LAYER_EMS_CPP = $(HW_LAYER_EGT_CPP) \ + $(PROJECT_DIR)/hw_layer/pin_repository.cpp \ $(PROJECT_DIR)/hw_layer/hardware.cpp \ + $(PROJECT_DIR)/hw_layer/neo6m.cpp \ + $(PROJECT_DIR)/hw_layer/mmc_card.cpp \ $(PROJECT_DIR)/hw_layer/lcd/lcd_HD44780.cpp \ $(PROJECT_DIR)/hw_layer/adc_inputs.cpp \ $(PROJECT_DIR)/hw_layer/board_test.cpp \ diff --git a/firmware/hw_layer/mmc_card.c b/firmware/hw_layer/mmc_card.cpp similarity index 95% rename from firmware/hw_layer/mmc_card.c rename to firmware/hw_layer/mmc_card.cpp index bc2582ad9c..3bc2b51073 100644 --- a/firmware/hw_layer/mmc_card.c +++ b/firmware/hw_layer/mmc_card.cpp @@ -1,276 +1,276 @@ -/** - * @file mmc_card.c - * - * @date Dec 28, 2013 - * @author Kot_dnz - * @author Andrey Belomutskiy, (c) 2012-2015 - * - * default pinouts in case of SPI2 connected to MMC: PB13 - SCK, PB14 - MISO, PB15 - MOSI, PD4 - CS, 3.3v - * default pinouts in case of SPI3 connected to MMC: PB3 - SCK, PB4 - MISO, PB5 - MOSI, PD4 - CS, 3.3v - * - */ - -#include "main.h" - -#if EFI_FILE_LOGGING || defined(__DOXYGEN__) - -#include -#include -#include "mmc_card.h" -#include "pin_repository.h" -#include "ff.h" -#include "hardware.h" -#include "engine_configuration.h" -#include "status_loop.h" - -extern board_configuration_s *boardConfiguration; - -#define PUSHPULLDELAY 500 - -static THD_WORKING_AREA(mmcThreadStack,UTILITY_THREAD_STACK_SIZE); // MMC monitor thread - -/** - * MMC driver instance. - */ -MMCDriver MMCD1; - -static SPIConfig hs_spicfg = { NULL, SPI_SD_MODULE_PORT, SPI_SD_MODULE_PIN, -SPI_BaudRatePrescaler_8 }; -static SPIConfig ls_spicfg = { NULL, SPI_SD_MODULE_PORT, SPI_SD_MODULE_PIN, -SPI_BaudRatePrescaler_256 }; - -/* MMC/SD over SPI driver configuration.*/ -// don't forget check if STM32_SPI_USE_SPI2 defined and spi has init with correct GPIO in hardware.c -static MMCConfig mmccfg = { &MMC_CARD_SPI, &ls_spicfg, &hs_spicfg }; - -static bool fs_ready = false; - -#define FILE_LOG_DELAY 200 - -/** - * fatfs MMC/SPI - */ -static FATFS MMC_FS; - -static Logging logger; - -// print FAT error function -static void printError(char *str, FRESULT f_error) { - scheduleMsg(&logger, "FATfs Error \"%s\" %d", str, f_error); -} - -static FIL FDLogFile; - -static int totalLoggedBytes = 0; - -static void printMmcPinout(void) { - scheduleMsg(&logger, "MMC CS %s:%d", portname(SPI_SD_MODULE_PORT), SPI_SD_MODULE_PIN); - // todo: we need to figure out the right SPI pinout, not just SPI2 -// scheduleMsg(&logger, "MMC SCK %s:%d", portname(EFI_SPI2_SCK_PORT), EFI_SPI2_SCK_PIN); -// scheduleMsg(&logger, "MMC MISO %s:%d", portname(EFI_SPI2_MISO_PORT), EFI_SPI2_MISO_PIN); -// scheduleMsg(&logger, "MMC MOSI %s:%d", portname(EFI_SPI2_MOSI_PORT), EFI_SPI2_MOSI_PIN); -} - -static void sdStatistics(void) { - printMmcPinout(); - scheduleMsg(&logger, "SD enabled: %s", boolToString(boardConfiguration->isSdCardEnabled)); - scheduleMsg(&logger, "fs_ready=%d totalLoggedBytes=%d", fs_ready, totalLoggedBytes); -} - -/** - * @brief Create a new file with the specified name - * - * This function saves the name of the file in a global variable - * so that we can later append to that file - */ -static void createLogFile(void) { - lockSpi(SPI_NONE); - memset(&FDLogFile, 0, sizeof(FIL)); // clear the memory - FRESULT err = f_open(&FDLogFile, "rusefi.log", FA_OPEN_ALWAYS | FA_WRITE); // Create new file - if (err != FR_OK && err != FR_EXIST) { - unlockSpi(); - printError("FS mount failed", err); // else - show error - return; - } - - err = f_lseek(&FDLogFile, f_size(&FDLogFile)); // Move to end of the file to append data - if (err) { - unlockSpi(); - printError("Seek error", err); - return; - } - f_sync(&FDLogFile); - fs_ready = true; // everything Ok - unlockSpi(); -} - -static void ff_cmd_dir(const char *pathx) { - char *path = (char *) pathx; // todo: fix this hack! - DIR dir; - FILINFO fno; - char *fn; - - if (!fs_ready) { - scheduleMsg(&logger, "Error: No File system is mounted"); - return; - } - - FRESULT res = f_opendir(&dir, path); - - if (res != FR_OK) { - scheduleMsg(&logger, "Error opening directory %s", path); - return; - } - - int i = strlen(path); - for (;;) { - res = f_readdir(&dir, &fno); - if (res != FR_OK || fno.fname[0] == 0) - break; - if (fno.lfname[0] == '.') - continue; - fn = fno.lfname; - if (fno.fattrib & AM_DIR) { - // TODO: WHAT? WE ARE APPENDING FILE NAME TO PARAMETER??? WEIRD!!! - path[i++] = '/'; - strcpy(&path[i], fn); - // res = ff_cmd_ls(path); - if (res != FR_OK) - break; - path[i] = 0; - } else { - scheduleMsg(&logger, "%c%c%c%c%c %u/%02u/%02u %02u:%02u %9lu %-12s", (fno.fattrib & AM_DIR) ? 'D' : '-', - (fno.fattrib & AM_RDO) ? 'R' : '-', (fno.fattrib & AM_HID) ? 'H' : '-', - (fno.fattrib & AM_SYS) ? 'S' : '-', (fno.fattrib & AM_ARC) ? 'A' : '-', (fno.fdate >> 9) + 1980, - (fno.fdate >> 5) & 15, fno.fdate & 31, (fno.ftime >> 11), (fno.ftime >> 5) & 63, fno.fsize, - fno.fname); - } - } -} - -static int errorReported = FALSE; // this is used to report the error only once - -/** - * @brief Appends specified line to the current log file - */ -void appendToLog(const char *line) { - UINT bytesWrited; - - if (!fs_ready) { - if (!errorReported) - scheduleMsg(&logger, "appendToLog Error: No File system is mounted"); - errorReported = TRUE; - return; - } - UINT lineLength = strlen(line); - totalLoggedBytes += lineLength; - lockSpi(SPI_NONE); - FRESULT err = f_write(&FDLogFile, line, lineLength, &bytesWrited); - if (bytesWrited < lineLength) { - printError("write error or disk full", err); // error or disk full - } - f_sync(&FDLogFile); - unlockSpi(); -} - -/* - * MMC card umount. - */ -static void MMCumount(void) { - if (!fs_ready) { - scheduleMsg(&logger, "Error: No File system is mounted. \"mountsd\" first"); - return; - } - f_close(&FDLogFile); // close file - f_sync(&FDLogFile); // sync ALL - mmcDisconnect(&MMCD1); // Brings the driver in a state safe for card removal. - mmcStop(&MMCD1); // Disables the MMC peripheral. - f_mount(0, NULL); // FATFS: Unregister work area prior to discard it - memset(&FDLogFile, 0, sizeof(FIL)); // clear FDLogFile - fs_ready = false; // status = false - scheduleMsg(&logger, "MMC/SD card removed"); -} - -/* - * MMC card mount. - */ -static void MMCmount(void) { -// printMmcPinout(); - - if (fs_ready) { - scheduleMsg(&logger, "Error: Already mounted. \"umountsd\" first"); - return; - } - // start to initialize MMC/SD - mmcObjectInit(&MMCD1); // Initializes an instance. - mmcStart(&MMCD1, &mmccfg); // Configures and activates the MMC peripheral. - - // Performs the initialization procedure on the inserted card. - lockSpi(SPI_NONE); - if (mmcConnect(&MMCD1) != CH_SUCCESS) { - warning(OBD_PCM_Processor_Fault, "Can't connect or mount MMC/SD"); - unlockSpi(); - return; - - } - unlockSpi(); - // if Ok - mount FS now - memset(&MMC_FS, 0, sizeof(FATFS)); - if (f_mount(0, &MMC_FS) == FR_OK) { - createLogFile(); - scheduleMsg(&logger, "MMC/SD mounted!"); - } -} - -#if defined __GNUC__ -__attribute__((noreturn)) static msg_t MMCmonThread(void) -#else -static msg_t MMCmonThread(void) -#endif -{ - chRegSetThreadName("MMC_Monitor"); - - while (true) { - // this returns TRUE if SD module is there, even without an SD card? - if (blkIsInserted(&MMCD1)) { - - if (!fs_ready) { - MMCmount(); - } - } - - if (isSdCardAlive()) - writeLogLine(); - - chThdSleepMilliseconds(FILE_LOG_DELAY); - } -} - -bool isSdCardAlive(void) { - return fs_ready; -} - -void initMmcCard(void) { - initLogging(&logger, "mmcCard"); - addConsoleAction("sdstat", sdStatistics); - if (!boardConfiguration->isSdCardEnabled) { - return; - } - - /** - * FYI: SPI does not work with CCM memory, be sure to have main() stack in RAM, not in CCMRAM - */ - - // start to initialize MMC/SD - mmcObjectInit(&MMCD1); - mmcStart(&MMCD1, &mmccfg); - - chThdCreateStatic(mmcThreadStack, sizeof(mmcThreadStack), LOWPRIO, (tfunc_t) MMCmonThread, NULL); - - addConsoleAction("mountsd", MMCmount); - addConsoleActionS("appendToLog", appendToLog); - addConsoleAction("umountsd", MMCumount); - addConsoleActionS("ls", ff_cmd_dir); -} - -#endif /* EFI_FILE_LOGGING */ +/** + * @file mmc_card.c + * + * @date Dec 28, 2013 + * @author Kot_dnz + * @author Andrey Belomutskiy, (c) 2012-2015 + * + * default pinouts in case of SPI2 connected to MMC: PB13 - SCK, PB14 - MISO, PB15 - MOSI, PD4 - CS, 3.3v + * default pinouts in case of SPI3 connected to MMC: PB3 - SCK, PB4 - MISO, PB5 - MOSI, PD4 - CS, 3.3v + * + */ + +#include "main.h" + +#if EFI_FILE_LOGGING || defined(__DOXYGEN__) + +#include +#include +#include "mmc_card.h" +#include "pin_repository.h" +#include "ff.h" +#include "hardware.h" +#include "engine_configuration.h" +#include "status_loop.h" + +extern board_configuration_s *boardConfiguration; + +#define PUSHPULLDELAY 500 + +static THD_WORKING_AREA(mmcThreadStack,UTILITY_THREAD_STACK_SIZE); // MMC monitor thread + +/** + * MMC driver instance. + */ +MMCDriver MMCD1; + +static SPIConfig hs_spicfg = { NULL, SPI_SD_MODULE_PORT, SPI_SD_MODULE_PIN, +SPI_BaudRatePrescaler_8 }; +static SPIConfig ls_spicfg = { NULL, SPI_SD_MODULE_PORT, SPI_SD_MODULE_PIN, +SPI_BaudRatePrescaler_256 }; + +/* MMC/SD over SPI driver configuration.*/ +// don't forget check if STM32_SPI_USE_SPI2 defined and spi has init with correct GPIO in hardware.c +static MMCConfig mmccfg = { &MMC_CARD_SPI, &ls_spicfg, &hs_spicfg }; + +static bool fs_ready = false; + +#define FILE_LOG_DELAY 200 + +/** + * fatfs MMC/SPI + */ +static FATFS MMC_FS; + +static Logging logger; + +// print FAT error function +static void printError(const char *str, FRESULT f_error) { + scheduleMsg(&logger, "FATfs Error \"%s\" %d", str, f_error); +} + +static FIL FDLogFile; + +static int totalLoggedBytes = 0; + +static void printMmcPinout(void) { + scheduleMsg(&logger, "MMC CS %s:%d", portname(SPI_SD_MODULE_PORT), SPI_SD_MODULE_PIN); + // todo: we need to figure out the right SPI pinout, not just SPI2 +// scheduleMsg(&logger, "MMC SCK %s:%d", portname(EFI_SPI2_SCK_PORT), EFI_SPI2_SCK_PIN); +// scheduleMsg(&logger, "MMC MISO %s:%d", portname(EFI_SPI2_MISO_PORT), EFI_SPI2_MISO_PIN); +// scheduleMsg(&logger, "MMC MOSI %s:%d", portname(EFI_SPI2_MOSI_PORT), EFI_SPI2_MOSI_PIN); +} + +static void sdStatistics(void) { + printMmcPinout(); + scheduleMsg(&logger, "SD enabled: %s", boolToString(boardConfiguration->isSdCardEnabled)); + scheduleMsg(&logger, "fs_ready=%d totalLoggedBytes=%d", fs_ready, totalLoggedBytes); +} + +/** + * @brief Create a new file with the specified name + * + * This function saves the name of the file in a global variable + * so that we can later append to that file + */ +static void createLogFile(void) { + lockSpi(SPI_NONE); + memset(&FDLogFile, 0, sizeof(FIL)); // clear the memory + FRESULT err = f_open(&FDLogFile, "rusefi.log", FA_OPEN_ALWAYS | FA_WRITE); // Create new file + if (err != FR_OK && err != FR_EXIST) { + unlockSpi(); + printError("FS mount failed", err); // else - show error + return; + } + + err = f_lseek(&FDLogFile, f_size(&FDLogFile)); // Move to end of the file to append data + if (err) { + unlockSpi(); + printError("Seek error", err); + return; + } + f_sync(&FDLogFile); + fs_ready = true; // everything Ok + unlockSpi(); +} + +static void ff_cmd_dir(const char *pathx) { + char *path = (char *) pathx; // todo: fix this hack! + DIR dir; + FILINFO fno; + char *fn; + + if (!fs_ready) { + scheduleMsg(&logger, "Error: No File system is mounted"); + return; + } + + FRESULT res = f_opendir(&dir, path); + + if (res != FR_OK) { + scheduleMsg(&logger, "Error opening directory %s", path); + return; + } + + int i = strlen(path); + for (;;) { + res = f_readdir(&dir, &fno); + if (res != FR_OK || fno.fname[0] == 0) + break; + if (fno.lfname[0] == '.') + continue; + fn = fno.lfname; + if (fno.fattrib & AM_DIR) { + // TODO: WHAT? WE ARE APPENDING FILE NAME TO PARAMETER??? WEIRD!!! + path[i++] = '/'; + strcpy(&path[i], fn); + // res = ff_cmd_ls(path); + if (res != FR_OK) + break; + path[i] = 0; + } else { + scheduleMsg(&logger, "%c%c%c%c%c %u/%02u/%02u %02u:%02u %9lu %-12s", (fno.fattrib & AM_DIR) ? 'D' : '-', + (fno.fattrib & AM_RDO) ? 'R' : '-', (fno.fattrib & AM_HID) ? 'H' : '-', + (fno.fattrib & AM_SYS) ? 'S' : '-', (fno.fattrib & AM_ARC) ? 'A' : '-', (fno.fdate >> 9) + 1980, + (fno.fdate >> 5) & 15, fno.fdate & 31, (fno.ftime >> 11), (fno.ftime >> 5) & 63, fno.fsize, + fno.fname); + } + } +} + +static int errorReported = FALSE; // this is used to report the error only once + +/** + * @brief Appends specified line to the current log file + */ +void appendToLog(const char *line) { + UINT bytesWrited; + + if (!fs_ready) { + if (!errorReported) + scheduleMsg(&logger, "appendToLog Error: No File system is mounted"); + errorReported = TRUE; + return; + } + UINT lineLength = strlen(line); + totalLoggedBytes += lineLength; + lockSpi(SPI_NONE); + FRESULT err = f_write(&FDLogFile, line, lineLength, &bytesWrited); + if (bytesWrited < lineLength) { + printError("write error or disk full", err); // error or disk full + } + f_sync(&FDLogFile); + unlockSpi(); +} + +/* + * MMC card umount. + */ +static void MMCumount(void) { + if (!fs_ready) { + scheduleMsg(&logger, "Error: No File system is mounted. \"mountsd\" first"); + return; + } + f_close(&FDLogFile); // close file + f_sync(&FDLogFile); // sync ALL + mmcDisconnect(&MMCD1); // Brings the driver in a state safe for card removal. + mmcStop(&MMCD1); // Disables the MMC peripheral. + f_mount(0, NULL); // FATFS: Unregister work area prior to discard it + memset(&FDLogFile, 0, sizeof(FIL)); // clear FDLogFile + fs_ready = false; // status = false + scheduleMsg(&logger, "MMC/SD card removed"); +} + +/* + * MMC card mount. + */ +static void MMCmount(void) { +// printMmcPinout(); + + if (fs_ready) { + scheduleMsg(&logger, "Error: Already mounted. \"umountsd\" first"); + return; + } + // start to initialize MMC/SD + mmcObjectInit(&MMCD1); // Initializes an instance. + mmcStart(&MMCD1, &mmccfg); // Configures and activates the MMC peripheral. + + // Performs the initialization procedure on the inserted card. + lockSpi(SPI_NONE); + if (mmcConnect(&MMCD1) != CH_SUCCESS) { + warning(OBD_PCM_Processor_Fault, "Can't connect or mount MMC/SD"); + unlockSpi(); + return; + + } + unlockSpi(); + // if Ok - mount FS now + memset(&MMC_FS, 0, sizeof(FATFS)); + if (f_mount(0, &MMC_FS) == FR_OK) { + createLogFile(); + scheduleMsg(&logger, "MMC/SD mounted!"); + } +} + +#if defined __GNUC__ +__attribute__((noreturn)) static msg_t MMCmonThread(void) +#else +static msg_t MMCmonThread(void) +#endif +{ + chRegSetThreadName("MMC_Monitor"); + + while (true) { + // this returns TRUE if SD module is there, even without an SD card? + if (blkIsInserted(&MMCD1)) { + + if (!fs_ready) { + MMCmount(); + } + } + + if (isSdCardAlive()) + writeLogLine(); + + chThdSleepMilliseconds(FILE_LOG_DELAY); + } +} + +bool isSdCardAlive(void) { + return fs_ready; +} + +void initMmcCard(void) { + initLogging(&logger, "mmcCard"); + addConsoleAction("sdstat", sdStatistics); + if (!boardConfiguration->isSdCardEnabled) { + return; + } + + /** + * FYI: SPI does not work with CCM memory, be sure to have main() stack in RAM, not in CCMRAM + */ + + // start to initialize MMC/SD + mmcObjectInit(&MMCD1); + mmcStart(&MMCD1, &mmccfg); + + chThdCreateStatic(mmcThreadStack, sizeof(mmcThreadStack), LOWPRIO, (tfunc_t) MMCmonThread, NULL); + + addConsoleAction("mountsd", MMCmount); + addConsoleActionS("appendToLog", appendToLog); + addConsoleAction("umountsd", MMCumount); + addConsoleActionS("ls", ff_cmd_dir); +} + +#endif /* EFI_FILE_LOGGING */ diff --git a/firmware/hw_layer/neo6m.c b/firmware/hw_layer/neo6m.cpp similarity index 100% rename from firmware/hw_layer/neo6m.c rename to firmware/hw_layer/neo6m.cpp diff --git a/firmware/hw_layer/pin_repository.c b/firmware/hw_layer/pin_repository.cpp similarity index 98% rename from firmware/hw_layer/pin_repository.c rename to firmware/hw_layer/pin_repository.cpp index 03ad2473e0..06d4bb6fa0 100644 --- a/firmware/hw_layer/pin_repository.c +++ b/firmware/hw_layer/pin_repository.cpp @@ -26,7 +26,7 @@ static int totalPinsUsed = 0; /** * @deprecated - use hwPortname() instead */ -char *portname(GPIO_TypeDef* GPIOx) { +const char *portname(GPIO_TypeDef* GPIOx) { if (GPIOx == GPIOA) return "PA"; if (GPIOx == GPIOB) @@ -103,7 +103,7 @@ brain_pin_e parseBrainPin(const char *str) { } const char *pinStr = str + 2; int pin = atoi(pinStr); - return basePin + pin; + return (brain_pin_e)(basePin + pin); } char *hwPortname(brain_pin_e brainPin) { diff --git a/firmware/hw_layer/pin_repository.h b/firmware/hw_layer/pin_repository.h index ca129f4720..9f6893e2a0 100644 --- a/firmware/hw_layer/pin_repository.h +++ b/firmware/hw_layer/pin_repository.h @@ -31,7 +31,7 @@ char *hwPortname(brain_pin_e brainPin); brain_pin_e parseBrainPin(const char *str); void mySetPadMode(const char *msg, ioportid_t port, ioportmask_t pin, iomode_t mode); void mySetPadMode2(const char *msg, brain_pin_e pin, iomode_t mode); -char *portname(GPIO_TypeDef* GPIOx); +const char *portname(GPIO_TypeDef* GPIOx); iomode_t getInputMode(pin_input_mode_e mode); ioportmask_t getHwPin(brain_pin_e brainPin); diff --git a/firmware/main.h b/firmware/main.h index 2563454b85..23e23778e6 100644 --- a/firmware/main.h +++ b/firmware/main.h @@ -26,7 +26,10 @@ extern "C" #include "efitime.h" #include "rusefi_enums.h" +#ifdef __cplusplus #include "datalogging.h" +#endif + #include "chprintf.h" #ifdef __cplusplus diff --git a/firmware/rusefi.cpp b/firmware/rusefi.cpp index f210481986..75148a5056 100644 --- a/firmware/rusefi.cpp +++ b/firmware/rusefi.cpp @@ -256,7 +256,7 @@ void firmwareError(const char *fmt, ...) { } } -static char UNUSED_RAM_SIZE[4000]; +static char UNUSED_RAM_SIZE[3000]; static char UNUSED_CCM_SIZE[8000] CCM_OPTIONAL; diff --git a/firmware/util/cli_registry.c b/firmware/util/cli_registry.cpp similarity index 99% rename from firmware/util/cli_registry.c rename to firmware/util/cli_registry.cpp index 19263d25da..2cc6b0552a 100644 --- a/firmware/util/cli_registry.c +++ b/firmware/util/cli_registry.cpp @@ -39,7 +39,7 @@ void resetConsoleActions(void) { consoleActionCount = 0; } -static void doAddAction(const char *token, int type, Void callback, void *param) { +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; diff --git a/firmware/util/datalogging.c b/firmware/util/datalogging.cpp similarity index 100% rename from firmware/util/datalogging.c rename to firmware/util/datalogging.cpp diff --git a/firmware/util/util.mk b/firmware/util/util.mk index 996e11125f..f476ee0ecc 100644 --- a/firmware/util/util.mk +++ b/firmware/util/util.mk @@ -1,14 +1,13 @@ UTIL_TEST_SRC = $(PROJECT_DIR)/util/crc.c \ $(PROJECT_DIR)/util/data_buffer.c \ - $(PROJECT_DIR)/util/histogram.c \ - $(PROJECT_DIR)/util/cli_registry.c - -UTILSRC = $(UTIL_TEST_SRC) \ - $(PROJECT_DIR)/console_util/datalogging.c + $(PROJECT_DIR)/util/histogram.c +UTILSRC = $(UTIL_TEST_SRC) UTILSRC_CPP = $(PROJECT_DIR)/util/cyclic_buffer.cpp \ + $(PROJECT_DIR)/console_util/datalogging.cpp \ $(PROJECT_DIR)/util/listener_array.cpp \ + $(PROJECT_DIR)/util/cli_registry.cpp \ $(PROJECT_DIR)/util/efilib.cpp \ $(PROJECT_DIR)/util/efilib2.cpp \ $(PROJECT_DIR)/util/LocalVersionHolder.cpp diff --git a/unit_tests/test_signal_executor.cpp b/unit_tests/test_signal_executor.cpp index 2555de183d..9832c90cef 100644 --- a/unit_tests/test_signal_executor.cpp +++ b/unit_tests/test_signal_executor.cpp @@ -14,15 +14,6 @@ #include "utlist.h" #include "event_queue.h" -static io_pin_e testLastToggledPin; -static int testToggleCounter; - -void setOutputPinValue(io_pin_e pin, int value) { - // this is a test implementation of the method - we use it to see what's going on - testLastToggledPin = pin; - testToggleCounter++; -} - EventQueue schedulingQueue; void scheduleTask(const char *msg, scheduling_s *scheduling, int delayUs, schfunc_t callback, void *param) {