diff --git a/.gitmodules b/.gitmodules index 7b62e9a260..55943fad1d 100644 --- a/.gitmodules +++ b/.gitmodules @@ -18,3 +18,6 @@ [submodule "firmware/ext/cmsis-svd"] path = firmware/ext/cmsis-svd url = https://github.com/posborne/cmsis-svd +[submodule "firmware/controllers/can/wideband_firmware"] + path = firmware/controllers/can/wideband_firmware + url = https://github.com/mck1117/wideband diff --git a/firmware/config/stm32f4ems/efifeatures.h b/firmware/config/stm32f4ems/efifeatures.h index a2164cdf8e..4e6a0b1cc9 100644 --- a/firmware/config/stm32f4ems/efifeatures.h +++ b/firmware/config/stm32f4ems/efifeatures.h @@ -202,6 +202,8 @@ #define EFI_CAN_SUPPORT TRUE #endif +#define EFI_WIDEBAND_FIRMWARE_UPDATE TRUE + #ifndef EFI_AUX_SERIAL #define EFI_AUX_SERIAL TRUE #endif diff --git a/firmware/controllers/bench_test.cpp b/firmware/controllers/bench_test.cpp index 18b294823a..f2f70cb00d 100644 --- a/firmware/controllers/bench_test.cpp +++ b/firmware/controllers/bench_test.cpp @@ -43,6 +43,10 @@ #include "malfunction_central.h" #include "tunerstudio_outputs.h" +#if EFI_WIDEBAND_FIRMWARE_UPDATE +#include "can.h" +#endif + #if EFI_PROD_CODE #include "rusefi.h" #include "mpu_util.h" @@ -86,6 +90,7 @@ static void runBench(brain_pin_e brainPin, OutputPin *output, float delayMs, flo } static volatile bool isBenchTestPending = false; +static bool widebandUpdatePending = false; static float onTime; static float offTime; static float delayMs; @@ -231,6 +236,13 @@ private: isBenchTestPending = false; runBench(brainPin, pinX, delayMs, onTime, offTime, count); } + + if (widebandUpdatePending) { +#if EFI_WIDEBAND_FIRMWARE_UPDATE + updateWidebandFirmware(logger); +#endif + widebandUpdatePending = false; + } } }; @@ -312,6 +324,9 @@ static void handleCommandX14(uint16_t index) { case 0xF: engine->directSelfStimulation = false; return; + case 0x12: + widebandUpdatePending = true; + return; } } @@ -385,6 +400,7 @@ void initBenchTest(Logging *sharedLogger) { addConsoleActionS("fuelpumpbench2", fuelPumpBenchExt); addConsoleAction("fanbench", fanBench); addConsoleActionS("fanbench2", fanBenchExt); + addConsoleAction("update_wideband", []() { widebandUpdatePending = true; }); addConsoleAction(CMD_STARTER_BENCH, starterRelayBench); addConsoleAction(CMD_MIL_BENCH, milBench); diff --git a/firmware/controllers/can/can.h b/firmware/controllers/can/can.h index b24a96643a..351dc00501 100644 --- a/firmware/controllers/can/can.h +++ b/firmware/controllers/can/can.h @@ -22,6 +22,11 @@ class CanSensorBase; void processCanRxMessage(const CANRxFrame& msg, Logging* logger, efitick_t nowNt); void registerCanSensor(CanSensorBase& sensor); +// Indicate that an ack response was received from the wideband bootloader +void handleWidebandBootloaderAck(); +// Update the firmware on any connected wideband controller +void updateWidebandFirmware(Logging*); + class CanWrite final : public PeriodicController<512> { public: CanWrite(); diff --git a/firmware/controllers/can/can_rx.cpp b/firmware/controllers/can/can_rx.cpp index 0723123963..5a1bee5eb1 100644 --- a/firmware/controllers/can/can_rx.cpp +++ b/firmware/controllers/can/can_rx.cpp @@ -64,6 +64,13 @@ void processCanRxMessage(const CANRxFrame& frame, Logging* logger, efitick_t now { obdOnCanPacketRx(frame); } + +#if EFI_WIDEBAND_FIRMWARE_UPDATE + // Bootloader acks with address 0x727573 aka ascii "rus" + if (frame.EID == 0x727573) { + handleWidebandBootloaderAck(); + } +#endif } #endif // EFI_CAN_SUPPORT diff --git a/firmware/controllers/can/wideband_bootloader.cpp b/firmware/controllers/can/wideband_bootloader.cpp new file mode 100644 index 0000000000..f4aa4f8727 --- /dev/null +++ b/firmware/controllers/can/wideband_bootloader.cpp @@ -0,0 +1,98 @@ +#include "global.h" + +#if EFI_WIDEBAND_FIRMWARE_UPDATE + +#include "ch.h" +#include "can_msg_tx.h" + +// This file contains an array called build_wideband_noboot_bin +// This array contains the firmware image for the wideband contoller +#include "wideband_firmware/for_rusefi/wideband_image.h" + +#define EVT_BOOTLOADER_ACK EVENT_MASK(0) + +static thread_t* waitingBootloaderThread = nullptr; + +void handleWidebandBootloaderAck() { + auto t = waitingBootloaderThread; + if (t) { + chEvtSignal(t, EVT_BOOTLOADER_ACK); + } +} + +bool waitAck() { + return chEvtWaitAnyTimeout(EVT_BOOTLOADER_ACK, TIME_MS2I(1000)) != 0; +} + +void updateWidebandFirmware(Logging* logging) { + // Clear any pending acks for this thread + chEvtGetAndClearEvents(EVT_BOOTLOADER_ACK); + + // Send messages to the current thread when acks come in + waitingBootloaderThread = chThdGetSelfX(); + + scheduleMsg(logging, "***************************************"); + scheduleMsg(logging, " WIDEBAND FIRMWARE UPDATE"); + scheduleMsg(logging, "***************************************"); + scheduleMsg(logging, "Wideband Update: Rebooting to bootloader..."); + + // The first request will reboot the chip (if necessary), and the second one will enable bootloader mode + // If the chip was already in bootloader (aka manual mode), then that's ok - the second request will + // just be safely ignored (but acked) + for (int i = 0; i < 2; i++) { + { + // Send bootloader entry command + CanTxMessage m(0xEF0'0000, 0, true); + } + + if (!waitAck()) { + scheduleMsg(logging, "Wideband Update ERROR: Expected ACK from entry to bootloader, didn't get one."); + return; + } + + // Let the controller reboot (and show blinky lights for a second before the update begins) + chThdSleepMilliseconds(200); + } + + scheduleMsg(logging, "Wideband Update: in update mode, erasing flash..."); + + { + // Erase flash - opcode 1, magic value 0x5A5A + CanTxMessage m(0xEF1'5A5A, 0, true); + } + + if (!waitAck()) { + scheduleMsg(logging, "Wideband Update ERROR: Expected ACK from flash erase command, didn't get one."); + return; + } + + size_t totalSize = sizeof(build_wideband_image_bin); + + scheduleMsg(logging, "Wideband Update: Flash erased! Sending %d bytes...", totalSize); + + // Send flash data 8 bytes at a time + for (size_t i = 0; i < totalSize; i += 8) { + { + CanTxMessage m(0xEF2'0000 + i, 8, true); + memcpy(&m[0], build_wideband_image_bin + i, 8); + } + + if (!waitAck()) { + scheduleMsg(logging, "Wideband Update ERROR: Expected ACK from data write, didn't get one."); + return; + } + } + + scheduleMsg(logging, "Wideband Update: Update complete! Rebooting controller."); + + { + // Reboot to firmware! + CanTxMessage m(0xEF3'0000, 0, true); + } + + waitAck(); + + waitingBootloaderThread = nullptr; +} + +#endif // EFI_WIDEBAND_FIRMWARE_UPDATE diff --git a/firmware/controllers/can/wideband_firmware b/firmware/controllers/can/wideband_firmware new file mode 160000 index 0000000000..3fe5b76975 --- /dev/null +++ b/firmware/controllers/can/wideband_firmware @@ -0,0 +1 @@ +Subproject commit 3fe5b76975d5b6a2e093709e50ca938ecd16347f diff --git a/firmware/controllers/controllers.mk b/firmware/controllers/controllers.mk index 86e65a4bea..5a7e271b10 100644 --- a/firmware/controllers/controllers.mk +++ b/firmware/controllers/controllers.mk @@ -42,6 +42,7 @@ CONTROLLERS_SRC_CPP = \ $(CONTROLLERS_DIR)/can/obd2.cpp \ $(CONTROLLERS_DIR)/can/can_verbose.cpp \ $(CONTROLLERS_DIR)/can/can_rx.cpp \ + $(CONTORLLERS_DIR)/can/wideband_bootloader.cpp \ $(CONTROLLERS_DIR)/can/can_tx.cpp \ $(CONTROLLERS_DIR)/can/can_dash.cpp \ $(CONTROLLERS_DIR)/can/can_vss.cpp \ diff --git a/firmware/controllers/generated/signature_all.h b/firmware/controllers/generated/signature_all.h index 9ed589c2f6..3d450adde5 100644 --- a/firmware/controllers/generated/signature_all.h +++ b/firmware/controllers/generated/signature_all.h @@ -3,6 +3,6 @@ // #define SIGNATURE_BOARD all -#define SIGNATURE_DATE 2020.12.15 -#define SIGNATURE_HASH 1394893573 -#define TS_SIGNATURE "rusEFI 2020.12.15.all.1394893573" +#define SIGNATURE_DATE 2020.12.16 +#define SIGNATURE_HASH 3147380267 +#define TS_SIGNATURE "rusEFI 2020.12.16.all.3147380267" diff --git a/firmware/controllers/generated/signature_frankenso_na6.h b/firmware/controllers/generated/signature_frankenso_na6.h index b0f5a9c919..3cf08baf2f 100644 --- a/firmware/controllers/generated/signature_frankenso_na6.h +++ b/firmware/controllers/generated/signature_frankenso_na6.h @@ -3,6 +3,6 @@ // #define SIGNATURE_BOARD frankenso_na6 -#define SIGNATURE_DATE 2020.12.15 -#define SIGNATURE_HASH 3310670590 -#define TS_SIGNATURE "rusEFI 2020.12.15.frankenso_na6.3310670590" +#define SIGNATURE_DATE 2020.12.16 +#define SIGNATURE_HASH 770279376 +#define TS_SIGNATURE "rusEFI 2020.12.16.frankenso_na6.770279376" diff --git a/firmware/controllers/generated/signature_hellen_cypress.h b/firmware/controllers/generated/signature_hellen_cypress.h index 9e689b32e4..d9fa7da983 100644 --- a/firmware/controllers/generated/signature_hellen_cypress.h +++ b/firmware/controllers/generated/signature_hellen_cypress.h @@ -3,6 +3,6 @@ // #define SIGNATURE_BOARD hellen_cypress -#define SIGNATURE_DATE 2020.12.15 -#define SIGNATURE_HASH 2597701062 -#define TS_SIGNATURE "rusEFI 2020.12.15.hellen_cypress.2597701062" +#define SIGNATURE_DATE 2020.12.16 +#define SIGNATURE_HASH 1919455464 +#define TS_SIGNATURE "rusEFI 2020.12.16.hellen_cypress.1919455464" diff --git a/firmware/controllers/generated/signature_kin.h b/firmware/controllers/generated/signature_kin.h index f19017a61e..3728547361 100644 --- a/firmware/controllers/generated/signature_kin.h +++ b/firmware/controllers/generated/signature_kin.h @@ -3,6 +3,6 @@ // #define SIGNATURE_BOARD kin -#define SIGNATURE_DATE 2020.12.15 -#define SIGNATURE_HASH 3419012924 -#define TS_SIGNATURE "rusEFI 2020.12.15.kin.3419012924" +#define SIGNATURE_DATE 2020.12.16 +#define SIGNATURE_HASH 594848274 +#define TS_SIGNATURE "rusEFI 2020.12.16.kin.594848274" diff --git a/firmware/controllers/generated/signature_mre_f4.h b/firmware/controllers/generated/signature_mre_f4.h index 8860ce9ee0..d0491f2c2e 100644 --- a/firmware/controllers/generated/signature_mre_f4.h +++ b/firmware/controllers/generated/signature_mre_f4.h @@ -3,6 +3,6 @@ // #define SIGNATURE_BOARD mre_f4 -#define SIGNATURE_DATE 2020.12.15 -#define SIGNATURE_HASH 1156889980 -#define TS_SIGNATURE "rusEFI 2020.12.15.mre_f4.1156889980" +#define SIGNATURE_DATE 2020.12.16 +#define SIGNATURE_HASH 2890524754 +#define TS_SIGNATURE "rusEFI 2020.12.16.mre_f4.2890524754" diff --git a/firmware/controllers/generated/signature_mre_f7.h b/firmware/controllers/generated/signature_mre_f7.h index 99e60c346b..f6ccdf7d28 100644 --- a/firmware/controllers/generated/signature_mre_f7.h +++ b/firmware/controllers/generated/signature_mre_f7.h @@ -3,6 +3,6 @@ // #define SIGNATURE_BOARD mre_f7 -#define SIGNATURE_DATE 2020.12.15 -#define SIGNATURE_HASH 1156889980 -#define TS_SIGNATURE "rusEFI 2020.12.15.mre_f7.1156889980" +#define SIGNATURE_DATE 2020.12.16 +#define SIGNATURE_HASH 2890524754 +#define TS_SIGNATURE "rusEFI 2020.12.16.mre_f7.2890524754" diff --git a/firmware/controllers/generated/signature_prometheus_405.h b/firmware/controllers/generated/signature_prometheus_405.h index c33b2bbf62..dd0c90c0a4 100644 --- a/firmware/controllers/generated/signature_prometheus_405.h +++ b/firmware/controllers/generated/signature_prometheus_405.h @@ -3,6 +3,6 @@ // #define SIGNATURE_BOARD prometheus_405 -#define SIGNATURE_DATE 2020.12.15 -#define SIGNATURE_HASH 301753684 -#define TS_SIGNATURE "rusEFI 2020.12.15.prometheus_405.301753684" +#define SIGNATURE_DATE 2020.12.16 +#define SIGNATURE_HASH 4181799034 +#define TS_SIGNATURE "rusEFI 2020.12.16.prometheus_405.4181799034" diff --git a/firmware/controllers/generated/signature_prometheus_469.h b/firmware/controllers/generated/signature_prometheus_469.h index 100a89d7c2..c08c96e9a7 100644 --- a/firmware/controllers/generated/signature_prometheus_469.h +++ b/firmware/controllers/generated/signature_prometheus_469.h @@ -3,6 +3,6 @@ // #define SIGNATURE_BOARD prometheus_469 -#define SIGNATURE_DATE 2020.12.15 -#define SIGNATURE_HASH 301753684 -#define TS_SIGNATURE "rusEFI 2020.12.15.prometheus_469.301753684" +#define SIGNATURE_DATE 2020.12.16 +#define SIGNATURE_HASH 4181799034 +#define TS_SIGNATURE "rusEFI 2020.12.16.prometheus_469.4181799034" diff --git a/firmware/controllers/generated/signature_proteus_f4.h b/firmware/controllers/generated/signature_proteus_f4.h index a2b1c7ee20..68f8cfe524 100644 --- a/firmware/controllers/generated/signature_proteus_f4.h +++ b/firmware/controllers/generated/signature_proteus_f4.h @@ -3,6 +3,6 @@ // #define SIGNATURE_BOARD proteus_f4 -#define SIGNATURE_DATE 2020.12.15 -#define SIGNATURE_HASH 2593008091 -#define TS_SIGNATURE "rusEFI 2020.12.15.proteus_f4.2593008091" +#define SIGNATURE_DATE 2020.12.16 +#define SIGNATURE_HASH 1915976949 +#define TS_SIGNATURE "rusEFI 2020.12.16.proteus_f4.1915976949" diff --git a/firmware/controllers/generated/signature_proteus_f7.h b/firmware/controllers/generated/signature_proteus_f7.h index 4db91a7fea..bb2fad14bc 100644 --- a/firmware/controllers/generated/signature_proteus_f7.h +++ b/firmware/controllers/generated/signature_proteus_f7.h @@ -3,6 +3,6 @@ // #define SIGNATURE_BOARD proteus_f7 -#define SIGNATURE_DATE 2020.12.15 -#define SIGNATURE_HASH 2593008091 -#define TS_SIGNATURE "rusEFI 2020.12.15.proteus_f7.2593008091" +#define SIGNATURE_DATE 2020.12.16 +#define SIGNATURE_HASH 1915976949 +#define TS_SIGNATURE "rusEFI 2020.12.16.proteus_f7.1915976949" diff --git a/firmware/tunerstudio/rusefi.input b/firmware/tunerstudio/rusefi.input index 7a9fa97301..4267c4c057 100644 --- a/firmware/tunerstudio/rusefi.input +++ b/firmware/tunerstudio/rusefi.input @@ -1521,6 +1521,7 @@ menuDialog = main subMenu = parkingLot, "Experimental/Broken" subMenu = multisparkSettings, "Multispark", 0, {isIgnitionEnabled == 1} subMenu = mc33Dialog, "GDI Dreams" + subMenu = widebandConfig, "rusEFI Wideband Controller", 0, { canReadEnabled && canWriteEnabled } subMenu = std_separator subMenu = hipFunction, "HIP9011 settings (knock sensor) (alpha version)" @@if_ts_show_hip9011 @@ -1623,9 +1624,10 @@ cmd_write_config = "@@TS_IO_TEST_COMMAND_char@@\x00\x14\x00\x0A" cmd_etb_autotune = "@@TS_IO_TEST_COMMAND_char@@\x00\x14\x00\x0C" cmd_enable_self_stim = "@@TS_IO_TEST_COMMAND_char@@\x00\x14\x00\x0D" cmb_etb_auto_calibrate = "@@TS_IO_TEST_COMMAND_char@@\x00\x14\x00\x0E" -cmb_etb_auto_calibrate_2 = "@@TS_IO_TEST_COMMAND_char@@\x00\x14\x00\x11" cmd_disable_self_stim = "@@TS_IO_TEST_COMMAND_char@@\x00\x14\x00\x0F" cmd_etb_autotune_stop = "@@TS_IO_TEST_COMMAND_char@@\x00\x14\x00\x10" +cmb_etb_auto_calibrate_2 = "@@TS_IO_TEST_COMMAND_char@@\x00\x14\x00\x11" +cmd_wideband_firmare_update = "@@TS_IO_TEST_COMMAND_char@@\x00\x14\x00\x12" cmd_cj125_calibrate = "@@TS_IO_TEST_COMMAND_char@@\x00\x18\x00\x00" cmd_call_from_pit = "@@TS_IO_TEST_COMMAND_char@@\x00\x20\x34\x56" @@ -3248,6 +3250,10 @@ cmd_set_engine_type_default = "@@TS_IO_TEST_COMMAND_char@@\x00\x31\x00\x00" panel = testInjectors panel = testFsio panel = testMisc + + dialog = widebandConfig, "rusEFI Wideband Config" + field = "!Please connect exactly one wideband controller before pressing this button!" + commandButton = "Update Firmware", cmd_wideband_firmare_update dialog = engineTypeDialog, "Popular vehicles" field = "!These buttons send a command to rusEFI controller to apply preset values"