From 905c35931f8920d0c81f440502d53e8f01b10cbd Mon Sep 17 00:00:00 2001 From: Mitch Lustig Date: Thu, 12 Sep 2024 21:01:30 -0700 Subject: [PATCH 1/4] Little FOCer V4 packaging fix --- package_firmware.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package_firmware.py b/package_firmware.py index 06599c1eb..35073dc4f 100755 --- a/package_firmware.py +++ b/package_firmware.py @@ -100,7 +100,7 @@ def get_git_revision_short_hash() -> str: package_dict["Little_FOCer"] = [['Little_FOCer', default_name]] package_dict["Little_FOCer_V3"] = [['Little_FOCer_V3', default_name]] package_dict["Little_FOCer_V3_1"] = [['Little_FOCer_V3_1', default_name]] -package_dict["Little_FOCer_4"] = [['Little_FOCer_4', default_name]] +package_dict["Little_FOCer_V4"] = [['Little_FOCer_V4', default_name]] package_dict["TRONIC_250R"] = [['TRONIC_250R', default_name]] package_dict["X12_PRO24"] = [['x12_pro24', default_name]] package_dict["X12_PRO30"] = [['x12_pro30', default_name]] From 53e95a3e5ceb51abfbb969747c689a45aedf7c53 Mon Sep 17 00:00:00 2001 From: Syler Clayton <2224238+Relys@users.noreply.github.com> Date: Fri, 13 Sep 2024 19:40:26 -0700 Subject: [PATCH 2/4] "Fix critical shutdown bug in spintend ubox" --- hwconf/Ubox/100v/hw_ubox_100_core.c | 48 +++++++++++++++++++---------- hwconf/Ubox/100v/hw_ubox_100_core.h | 2 ++ hwconf/shutdown.c | 4 ++- 3 files changed, 37 insertions(+), 17 deletions(-) mode change 100644 => 100755 hwconf/Ubox/100v/hw_ubox_100_core.c mode change 100644 => 100755 hwconf/Ubox/100v/hw_ubox_100_core.h diff --git a/hwconf/Ubox/100v/hw_ubox_100_core.c b/hwconf/Ubox/100v/hw_ubox_100_core.c old mode 100644 new mode 100755 index a5a27702c..06bc5bd05 --- a/hwconf/Ubox/100v/hw_ubox_100_core.c +++ b/hwconf/Ubox/100v/hw_ubox_100_core.c @@ -42,7 +42,7 @@ #define UBOX_QUERY_POWER_KEY_IO() (palReadPad(GPIOC, 13)) -void shutdown_ubox_init(void); +void shutdown_init(void); // Variables static volatile bool i2c_running = false; @@ -131,8 +131,8 @@ void hw_init_gpio(void) { palSetPadMode(GPIOC, 13, PAL_MODE_OUTPUT_OPENDRAIN | PAL_MODE_INPUT_PULLUP); UBOX_POWER_KEY_IO_RELEASE(); - - shutdown_ubox_init(); + + shutdown_init(); } void hw_setup_adc_channels(void) { @@ -287,21 +287,37 @@ float hw100_250_get_temp(void) { // Private variables static bool volatile m_button_pressed = false; static volatile float m_inactivity_time = 0.0; -static THD_WORKING_AREA(shutdown_ubox_thread_wa, 256); +static THD_WORKING_AREA(shutdown_thread_wa, 256); static mutex_t m_sample_mutex; static volatile bool m_init_done = false; static volatile bool m_sampling_disabled = false; // Private functions -static THD_FUNCTION(shutdown_ubox_thread, arg); +static THD_FUNCTION(shutdown_thread, arg); -void shutdown_ubox_init(void) { - chMtxObjectInit(&m_sample_mutex); - chThdCreateStatic(shutdown_ubox_thread_wa, sizeof(shutdown_ubox_thread_wa), NORMALPRIO, shutdown_ubox_thread, NULL); - m_init_done = true; +void shutdown_init(void) { + if(!m_init_done){ + chMtxObjectInit(&m_sample_mutex); + chThdCreateStatic(shutdown_thread_wa, sizeof(shutdown_thread_wa), NORMALPRIO, shutdown_thread, NULL); + m_init_done = true; + } } -static bool do_shutdown_ubox(void) { +void shutdown_reset_timer(void) { + m_inactivity_time = 0.0; +} + +float shutdown_get_inactivity_time(void) { + return m_inactivity_time; +} + +void shutdown_hold(bool hold) { + (void)hold; +} + +// TODO: Doesn't use resample. Maybe in future allow resampling if enPOWER_KEY_TYPE is momentary? +bool do_shutdown(bool resample) { + (void)resample; conf_general_store_backup_data(); chThdSleepMilliseconds(100); @@ -310,7 +326,6 @@ static bool do_shutdown_ubox(void) { return true; } - typedef enum { power_key_type_undecided = 0, power_key_type_momentary, @@ -321,7 +336,7 @@ static enPOWER_KEY_TYPE power_key_type = power_key_type_undecided; static uint32_t power_key_pressed_ms = 0; static bool power_key_pressed_when_power_on = false; -static THD_FUNCTION(shutdown_ubox_thread, arg) { +static THD_FUNCTION(shutdown_thread, arg) { (void)arg; chRegSetThreadName("Shutdown_ubox"); @@ -352,6 +367,7 @@ static THD_FUNCTION(shutdown_ubox_thread, arg) { } } else { if((power_key_pressed_ms > 50) && (power_key_pressed_ms < 500)) { + // TODO: Could toggle different led types here?? power_key_click = 1; } power_key_pressed_ms = 0; @@ -394,7 +410,7 @@ static THD_FUNCTION(shutdown_ubox_thread, arg) { //Inactive after 10 seconds, MCU cancels the enable signal, regulator shuts down if button released. m_inactivity_time += dt; if (m_inactivity_time >= 10.0f) { - do_shutdown_ubox(); + do_shutdown(false); } break; case SHUTDOWN_MODE_ALWAYS_ON: @@ -414,7 +430,7 @@ static THD_FUNCTION(shutdown_ubox_thread, arg) { break; case SHUTDOWN_MODE_TOGGLE_BUTTON_ONLY: if(clicked) { - do_shutdown_ubox(); + do_shutdown(true); } break; default: break; @@ -434,7 +450,7 @@ static THD_FUNCTION(shutdown_ubox_thread, arg) { default: break; } if (m_inactivity_time >= shutdown_timeout) { - do_shutdown_ubox(); + do_shutdown(false); } } else { //Because SHUTDOWN_MODE_ALWAYS_OFF's implementation will check m_inactivity_time. @@ -444,7 +460,7 @@ static THD_FUNCTION(shutdown_ubox_thread, arg) { } if(power_key_pressed_ms > 2000) { - do_shutdown_ubox(); + do_shutdown(true); } } else { m_inactivity_time += dt; diff --git a/hwconf/Ubox/100v/hw_ubox_100_core.h b/hwconf/Ubox/100v/hw_ubox_100_core.h old mode 100644 new mode 100755 index 1257c0af5..9cd288655 --- a/hwconf/Ubox/100v/hw_ubox_100_core.h +++ b/hwconf/Ubox/100v/hw_ubox_100_core.h @@ -22,6 +22,8 @@ #ifndef HW_UBOX_V2_100_CORE_H_ #define HW_UBOX_V2_100_CORE_H_ +#define HW_SHUTDOWN_CUSTOM + #ifdef HW_UBOX_V2_100 #define HW_NAME "UBOX_V2_100" #elif defined (HW_UBOX_SINGLE_100) diff --git a/hwconf/shutdown.c b/hwconf/shutdown.c index 73e348575..07ef16764 100644 --- a/hwconf/shutdown.c +++ b/hwconf/shutdown.c @@ -26,7 +26,9 @@ #include "lispif.h" #endif -#ifdef HW_SHUTDOWN_HOLD_ON +#ifdef HW_SHUTDOWN_CUSTOM +// Do nothing. All shutdown functionality is handled in the hardware file. +#elif defined(HW_SHUTDOWN_HOLD_ON) // Private variables bool volatile m_button_pressed = false; From 08571f611b4eda57fb782c2e1e0d7ff184abb1a2 Mon Sep 17 00:00:00 2001 From: Dado Mista Date: Wed, 2 Oct 2024 04:43:14 -0700 Subject: [PATCH 3/4] ADV500 uses LSM6DS3 IMU Signed-off-by: Dado Mista --- hwconf/floatwheel/hw_adv_core.h | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/hwconf/floatwheel/hw_adv_core.h b/hwconf/floatwheel/hw_adv_core.h index 384a2d69b..5290af95d 100644 --- a/hwconf/floatwheel/hw_adv_core.h +++ b/hwconf/floatwheel/hw_adv_core.h @@ -194,11 +194,19 @@ #define HW_SPI_PORT_MISO GPIOA #define HW_SPI_PIN_MISO 6 +#ifdef ADV200 // IMU: BMI160 #define BMI160_SDA_GPIO GPIOB #define BMI160_SDA_PIN 2 #define BMI160_SCL_GPIO GPIOA #define BMI160_SCL_PIN 15 +#else +// LSM6DS3 +#define LSM6DS3_SDA_GPIO GPIOB +#define LSM6DS3_SDA_PIN 2 +#define LSM6DS3_SCL_GPIO GPIOA +#define LSM6DS3_SCL_PIN 15 +#endif // NRF SWD #define NRF5x_SWDIO_GPIO GPIOB From 92a9d45c3c22dd15683bc09aa317e259fed39211 Mon Sep 17 00:00:00 2001 From: rafe husain Date: Wed, 30 Oct 2024 23:09:37 -0700 Subject: [PATCH 4/4] bldc with autolock for 410 and 75100 --- comm/commands.c | 2 + main.c | 28 ++++- make/fw.mk | 1 + password.c | 322 ++++++++++++++++++++++++++++++++++++++++++++++++ password.h | 26 ++++ terminal.c | 1 + timeout.c | 6 + 7 files changed, 385 insertions(+), 1 deletion(-) create mode 100755 password.c create mode 100755 password.h diff --git a/comm/commands.c b/comm/commands.c index 327ef7f3e..92bae00a1 100644 --- a/comm/commands.c +++ b/comm/commands.c @@ -62,6 +62,7 @@ #include #include #include +#include "password.h" // Settings #define PRINT_BUFFER_SIZE 400 @@ -697,6 +698,7 @@ void commands_process_packet(unsigned char *data, unsigned int len, case COMM_ALIVE: SHUTDOWN_RESET(); + password_timeout_reset(); timeout_reset(); break; diff --git a/main.c b/main.c index a997d13c7..de1059931 100644 --- a/main.c +++ b/main.c @@ -70,7 +70,7 @@ #ifdef USE_LISPBM #include "lispif.h" #endif - +#include "password.h" /* * HW resources used: * @@ -205,6 +205,32 @@ static THD_FUNCTION(periodic_thread, arg) { HW_TRIM_HSI(); // Compensate HSI for temperature + static volatile uint16_t time_to_print_ms = 0; + + if( time_to_print_ms++ > 1000 ){ + time_to_print_ms = 0; + if(password_get_system_locked_flag()){ + commands_printf("system locked by user password"); + } + + if(password_get_system_connection_alive()){ + password_set_system_connection_alive(false); + commands_printf("system alive received"); + } + } + + static volatile float current_now_filtered = 0.0; + UTILS_LP_FAST(current_now_filtered,mc_interface_get_tot_current(),0.1); + + if((!password_get_system_locked_flag()) && + password_get_system_enable_flag() ){ + if( fabsf(current_now_filtered) < 0.2){ + password_timeout_increment(10);//argument should match the timer loop time + }else{ + password_timeout_reset();//if current is higher than threshold, we reinit timer. this prevents that a mobile disconnect issue can lock the system while the bike is still being used. + } + } + chThdSleepMilliseconds(10); } } diff --git a/make/fw.mk b/make/fw.mk index 8f7503a8e..00378ebc6 100755 --- a/make/fw.mk +++ b/make/fw.mk @@ -132,6 +132,7 @@ CSRC = $(STARTUPSRC) \ main.c \ irq_handlers.c \ terminal.c \ + password.c \ conf_general.c \ timeout.c \ flash_helper.c \ diff --git a/password.c b/password.c new file mode 100755 index 000000000..788115928 --- /dev/null +++ b/password.c @@ -0,0 +1,322 @@ +/* + * password.c + * + * Created on: Nov 11, 2019 + * Author: motorcontrol + */ + +#include "password.h" +#include "commands.h" +#include "terminal.h" +#include "string.h" +#include "stdio.h" +#include "conf_general.h" + +#define EEPROM_ADDR_USER_PASSWORD 1 +static volatile uint8_t user_password[40]; +static volatile uint8_t user_password_read[10]; + +#define EEPROM_ADDR_PASSWORD_SYSTEM_ENABLE (EEPROM_ADDR_USER_PASSWORD + 2) +static volatile uint8_t system_enable_argument[40]; +static volatile uint8_t pass_system_enable[10];//0 is false, 1 is true + +static volatile bool system_locked = true;//this will be true until the user password is entered +static volatile bool password_is_erased = false;//this will be false if there is a valid password saved, or true if a new firmware was loaded, that erase the password +static volatile bool system_connection_alive = false; +static volatile bool password_system_enable = false; //this flag enables / disables the password system. it is set by the "ul command. +static volatile uint32_t password_timeout_counter = 0; +static volatile uint32_t password_timeout_limit = 0; + +static void terminal_cmd_enter_user_password(int argc, const char **argv) { + (void)argc; + (void)argv; + + if(password_is_erased){ + //initialize password to Calibike + password_is_erased = 0; + strcpy(user_password,"Calibike"); + // Store data in eeprom + conf_general_store_eeprom_var_hw((eeprom_var*)user_password, EEPROM_ADDR_USER_PASSWORD); + conf_general_store_eeprom_var_hw((eeprom_var*)(user_password+4), EEPROM_ADDR_USER_PASSWORD+1); + + //initialize password system enable to false = 0 + uint8_t index; + for( index = 0; index<4 ; index++) + { + pass_system_enable[index] = 0; + } + conf_general_store_eeprom_var_hw((eeprom_var*)(pass_system_enable), EEPROM_ADDR_PASSWORD_SYSTEM_ENABLE); + } + + if( argc == 3 ) { + sscanf(argv[1], "%s", user_password); + sscanf(argv[2], "%s", system_enable_argument); + + uint8_t pass_length = strlen((const char*)user_password); + + if( pass_length != 8){ + commands_printf("wrong password, it needs to be 8 characters long"); + }else{ + + if( (strncmp(system_enable_argument, "enable",6) == 0) || + ( strncmp(system_enable_argument, "disable",7) == 0) + ) + { + // Read stored password in eeprom + conf_general_read_eeprom_var_hw((eeprom_var*)user_password_read,EEPROM_ADDR_USER_PASSWORD); + conf_general_read_eeprom_var_hw((eeprom_var*)(user_password_read+4),EEPROM_ADDR_USER_PASSWORD+1); + + if( strncmp(user_password, user_password_read,8) == 0){ + system_locked = false; + commands_printf("good password --> system unlocked"); + password_timeout_configure(300000);//5 minutes in msec + + if( strncmp(system_enable_argument, "enable",6) == 0){ + password_system_enable = true; + uint8_t index; + for( index = 0; index<4 ; index++) + { + pass_system_enable[index] = 1; + } + commands_printf("password system is enabled"); + }else{ + password_system_enable = false; + uint8_t index; + for( index = 0; index<4 ; index++) + { + pass_system_enable[index] = 0; + } + commands_printf("password system is disabled"); + } + + conf_general_store_eeprom_var_hw((eeprom_var*)(pass_system_enable), EEPROM_ADDR_PASSWORD_SYSTEM_ENABLE); + + }else{ + commands_printf("wrong password, it does not match current password"); + } + } + else + { + commands_printf("wrong command! second argument should be \"enable\" or \"disable\" "); + } + + } + + } + else { + + if( argc == 2 ) { + sscanf(argv[1], "%s", user_password); + + uint8_t pass_length = strlen((const char*)user_password); + + if( pass_length != 8){ + commands_printf("wrong password, it needs to be 8 characters long"); + }else{ + + // Read stored password in eeprom + conf_general_read_eeprom_var_hw((eeprom_var*)user_password_read,EEPROM_ADDR_USER_PASSWORD); + conf_general_read_eeprom_var_hw((eeprom_var*)(user_password_read+4),EEPROM_ADDR_USER_PASSWORD+1); + + if( strncmp(user_password, user_password_read,8) == 0){ + system_locked = false; + commands_printf("good password --> system unlocked"); + password_timeout_configure(300000);//5 minutes in msec + + }else{ + commands_printf("wrong password, it does not match current password"); + } + } + } + else + { + commands_printf("wrong command, please use 1 argument like \"ul \" or 2 arguments such as \"ul "); + } + + } + + commands_printf(" "); + return; +} + +static void terminal_cmd_new_user_password(int argc, const char **argv) { + (void)argc; + (void)argv; + + if( password_system_enable ) + { + if( system_locked ){ + commands_printf("system is locked, first unlock it, then you will be able to load a new password."); + }else{ + if( argc == 2 ) { + + sscanf(argv[1], "%s", user_password); + + uint8_t pass_length = strlen((const char*)user_password); + + if( pass_length != 8){ + commands_printf("wrong password, it needs to be 8 characters long"); + }else{ + commands_printf("good password, User password will change to: %s", user_password); + + // Store data in eeprom + conf_general_store_eeprom_var_hw((eeprom_var*)user_password, EEPROM_ADDR_USER_PASSWORD); + conf_general_store_eeprom_var_hw((eeprom_var*)(user_password+4), EEPROM_ADDR_USER_PASSWORD+1); + + //read back written data + conf_general_read_eeprom_var_hw((eeprom_var*)user_password_read,EEPROM_ADDR_USER_PASSWORD); + conf_general_read_eeprom_var_hw((eeprom_var*)(user_password_read+4),EEPROM_ADDR_USER_PASSWORD+1); + + commands_printf("password saved:%s", user_password_read); + } + + } + else { + commands_printf("1 argument required. For example: new_user_password Calibike"); + commands_printf(" "); + } + } + } + else + { + commands_printf("password system is disabled, you need first to enable it by the \"ul enable\" command." ); + } + + commands_printf(" "); + return; +} + +static void terminal_cmd_lock_system(int argc, const char **argv) +{ + if( password_system_enable ) + { + system_locked = true; + commands_printf("system has been locked\r\n"); + } + else + { + commands_printf("password system is disabled, you need first to enable it by the \"ul enable\" command." ); + } + return; +} + +void password_init(void){ + // Register terminal callbacks + + terminal_register_command_callback( + "ul", + "Unlocks system, and enables or disables password settings , command: unlock ", + 0, + terminal_cmd_enter_user_password); + + terminal_register_command_callback( + "Ul", + "same as ul", + 0, + terminal_cmd_enter_user_password); + + terminal_register_command_callback( + "sp", + "Sets a new user password for lock function, that must be 8 characters long, example: sp ", + 0, + terminal_cmd_new_user_password); + + terminal_register_command_callback( + "Sp", + "same as sp", + 0, + terminal_cmd_new_user_password); + + terminal_register_command_callback( + "lk", + "locks system with password set in memory", + 0, + terminal_cmd_lock_system); + + terminal_register_command_callback( + "Lk", + "same as lk", + 0, + terminal_cmd_lock_system); + + // check if flash was erased during a firmware upgrade, then initialize the password to Calibike + conf_general_read_eeprom_var_hw((eeprom_var*)user_password_read,EEPROM_ADDR_USER_PASSWORD); + conf_general_read_eeprom_var_hw((eeprom_var*)(user_password_read+4),EEPROM_ADDR_USER_PASSWORD+1); + + conf_general_read_eeprom_var_hw((eeprom_var*)pass_system_enable,EEPROM_ADDR_PASSWORD_SYSTEM_ENABLE); + + if( (user_password_read[0] == 0) && + (user_password_read[1] == 0) && + (user_password_read[2] == 0) && + (user_password_read[3] == 0) && + (user_password_read[4] == 0) && + (user_password_read[5] == 0) && + (user_password_read[6] == 0) && + (user_password_read[7] == 0) ) + { + //this means flash memory was just programmed, and we need to set default settings, password erased true, and password enable false and system unlocked + password_is_erased = true; + password_system_enable = false; + system_locked = false; + }else + { + if(pass_system_enable[0] == 0) + { + password_system_enable = false; + system_locked = false; + } + else + { + password_system_enable = true; + system_locked = true; + } + } + +} + +bool password_get_system_locked_flag(void){ + return system_locked; +} + +void password_set_system_locked_flag( bool value){ + system_locked = value; +} + +bool password_get_system_enable_flag(void){ + return password_system_enable; +} + +void password_set_system_enable_flag( bool value){ + password_system_enable = value; +} + +bool password_get_system_connection_alive(void){ + return system_connection_alive; +} + +void password_set_system_connection_alive(bool value){ + system_connection_alive = value; +} + +void password_timeout_deinit(void){ + password_timeout_limit = 0; + password_timeout_counter = 0; +} + +void password_timeout_configure( uint32_t timeout_msec ){ + password_timeout_limit = timeout_msec; + password_timeout_counter = 0; +} + +void password_timeout_reset(void){ + password_timeout_counter = 0; +} + +void password_timeout_increment(uint16_t delta_msec){ + if( password_timeout_limit > 0 ){ + password_timeout_counter += delta_msec;//this is called from main timer that has a 10 msec tick + if( password_timeout_counter > password_timeout_limit ){ + system_locked = true; + } + } +} diff --git a/password.h b/password.h new file mode 100755 index 000000000..caf63c297 --- /dev/null +++ b/password.h @@ -0,0 +1,26 @@ +/* + * password.h + * + * Created on: Nov 11, 2019 + * Author: motorcontrol + */ + +#ifndef PASSWORD_H_ +#define PASSWORD_H_ + +#include "stdbool.h" +#include "stdint.h" + +void password_init(void); +bool password_get_system_locked_flag(void); +void password_set_system_locked_flag( bool value); +bool password_get_system_enable_flag(void); +void password_set_system_enable_flag( bool value); +bool password_get_system_connection_alive(void); +void password_set_system_connection_alive(bool value); +void password_timeout_deinit(void); +void password_timeout_configure( uint32_t timeout_msec ); +void password_timeout_reset(void); +void password_timeout_increment(uint16_t delta_msec); + +#endif /* PASSWORD_H_ */ diff --git a/terminal.c b/terminal.c index a23be8456..9d304b460 100644 --- a/terminal.c +++ b/terminal.c @@ -39,6 +39,7 @@ #include "mempools.h" #include "crc.h" #include "firmware_metadata.h" +#include "password.h" #include #include diff --git a/timeout.c b/timeout.c index 4554e7d66..cff711f4c 100644 --- a/timeout.c +++ b/timeout.c @@ -22,6 +22,7 @@ #include "stm32f4xx_conf.h" #include "shutdown.h" #include "utils.h" +#include "password.h" // Private variables static volatile bool init_done = false; @@ -222,6 +223,11 @@ static THD_FUNCTION(timeout_thread, arg) { mc_interface_set_brake_current(timeout_brake_current); mc_interface_select_motor_thread(2); mc_interface_set_brake_current(timeout_brake_current); + has_timeout = true; + if(password_get_system_enable_flag()) + { + password_set_system_locked_flag(true); + } if (kill_sw) { mc_interface_ignore_input_both(20);