From 5d2606315201a91bc56b04dfac6d607d92126349 Mon Sep 17 00:00:00 2001 From: Till Rosenband Date: Wed, 16 Sep 2020 11:19:36 -0400 Subject: [PATCH] Store odometer in emulated EEPROM (update at shutdown). * New "dist" terminal command shows odometer and trip distances. * Odometer value is sent to UI via COMM_GET_VALUES_SETUP. * UI can set the odometer via COMM_SET_ODOMETER. * Unfortunately, the bootloader clears the odometer to 0 when FW is reprogrammed. --- commands.c | 9 +++++++++ datatypes.h | 5 ++++- mc_interface.c | 40 ++++++++++++++++++++++++++++++++++++++++ mc_interface.h | 6 ++++++ shutdown.c | 20 +++++++++++--------- terminal.c | 4 ++++ 6 files changed, 74 insertions(+), 10 deletions(-) diff --git a/commands.c b/commands.c index 4acfbf11..6b497aad 100644 --- a/commands.c +++ b/commands.c @@ -774,9 +774,18 @@ void commands_process_packet(unsigned char *data, unsigned int len, if (mask & ((uint32_t)1 << 19)) { buffer_append_float32(send_buffer, wh_batt_left, 1e3, &ind); } + if (mask & ((uint32_t)1 << 20)) { + buffer_append_uint32(send_buffer, mc_interface_get_odometer(), &ind); + } reply_func(send_buffer, ind); chMtxUnlock(&send_buffer_mutex); + } break; + + case COMM_SET_ODOMETER: { + int32_t ind = 0; + mc_interface_set_odometer(buffer_get_uint32(data, &ind)); + timeout_reset(); } break; case COMM_SET_MCCONF_TEMP: diff --git a/datatypes.h b/datatypes.h index 401d44e1..743f2ac4 100644 --- a/datatypes.h +++ b/datatypes.h @@ -785,7 +785,8 @@ typedef enum { COMM_SET_BLE_PIN, COMM_SET_CAN_MODE, COMM_GET_IMU_CALIBRATION, - COMM_GET_MCCONF_TEMP + COMM_GET_MCCONF_TEMP, + COMM_SET_ODOMETER } COMM_PACKET_ID; // CAN commands @@ -983,6 +984,8 @@ typedef union { #define EEPROM_VARS_HW 64 #define EEPROM_VARS_CUSTOM 64 +#define EEPROM_ADDR_ODOMETER 1 + typedef struct { float ah_tot; float ah_charge_tot; diff --git a/mc_interface.c b/mc_interface.c index 848f328f..65cdbac7 100644 --- a/mc_interface.c +++ b/mc_interface.c @@ -114,6 +114,8 @@ static volatile bool m_sample_is_second_motor; static volatile mc_fault_code m_fault_stop_fault; static volatile bool m_fault_stop_is_second_motor; +static volatile uint32_t m_odometer_meters; + // Private functions static void update_override_limits(volatile motor_if_state_t *motor, volatile mc_configuration *conf); static void run_timer_tasks(volatile motor_if_state_t *motor); @@ -156,6 +158,12 @@ void mc_interface_init(void) { m_sample_mode = DEBUG_SAMPLING_OFF; m_sample_mode_last = DEBUG_SAMPLING_OFF; m_sample_is_second_motor = false; + //initialize odometer to EEPROM value + m_odometer_meters = 0; + eeprom_var v; + if(conf_general_read_eeprom_var_custom(&v, EEPROM_ADDR_ODOMETER)) { + m_odometer_meters = v.as_u32; + } // Start threads chThdCreateStatic(timer_thread_wa, sizeof(timer_thread_wa), NORMALPRIO, timer_thread, NULL); @@ -2394,3 +2402,35 @@ unsigned mc_interface_calc_crc(mc_configuration* conf_in, bool is_motor_2) { conf->crc = crc_old; return crc_new; } + +/** + * Set odometer value in meters. + * + * @param new_odometer_meters + * new odometer value in meters + */ +void mc_interface_set_odometer(uint32_t new_odometer_meters) { + m_odometer_meters = new_odometer_meters - roundf(mc_interface_get_distance_abs()); +} + +/** + * Return current odometer value in meters. + * + * @return + * Odometer value in meters, including current trip + */ +uint32_t mc_interface_get_odometer(void) { + return m_odometer_meters + roundf(mc_interface_get_distance_abs()); +} + +/** + * Save current odometer value to persistent memory + * + * @return + * success + */ +bool mc_interface_save_odometer(void) { + eeprom_var v; + v.as_u32 = mc_interface_get_odometer(); + return conf_general_store_eeprom_var_custom(&v, EEPROM_ADDR_ODOMETER); +} diff --git a/mc_interface.h b/mc_interface.h index 6a27dc41..ffb96a0b 100644 --- a/mc_interface.h +++ b/mc_interface.h @@ -84,6 +84,12 @@ float mc_interface_get_battery_level(float *wh_left); float mc_interface_get_speed(void); float mc_interface_get_distance(void); float mc_interface_get_distance_abs(void); + +// odometer +uint32_t mc_interface_get_odometer(void); +void mc_interface_set_odometer(uint32_t new_odometer_meters); +bool mc_interface_save_odometer(void); + setup_values mc_interface_get_setup_values(void); // MC implementation functions diff --git a/shutdown.c b/shutdown.c index 24ce429c..9b6003e8 100644 --- a/shutdown.c +++ b/shutdown.c @@ -19,6 +19,7 @@ #include "shutdown.h" #include "app.h" +#include "mc_interface.h" #ifdef HW_SHUTDOWN_HOLD_ON @@ -61,6 +62,13 @@ void shutdown_set_sampling_disabled(bool disabled) { chMtxUnlock(&m_sample_mutex); } +bool do_shutdown(void) { + mc_interface_save_odometer(); + DISABLE_GATE(); + HW_SHUTDOWN_HOLD_OFF(); + return true; +} + static THD_FUNCTION(shutdown_thread, arg) { (void)arg; @@ -96,9 +104,7 @@ static THD_FUNCTION(shutdown_thread, arg) { switch (conf->shutdown_mode) { case SHUTDOWN_MODE_ALWAYS_OFF: if (m_button_pressed) { - DISABLE_GATE(); - gates_disabled_here = true; - HW_SHUTDOWN_HOLD_OFF(); + gates_disabled_here = do_shutdown(); } break; @@ -108,9 +114,7 @@ static THD_FUNCTION(shutdown_thread, arg) { default: if (clicked) { - DISABLE_GATE(); - gates_disabled_here = true; - HW_SHUTDOWN_HOLD_OFF(); + gates_disabled_here = do_shutdown(); } break; } @@ -143,9 +147,7 @@ static THD_FUNCTION(shutdown_thread, arg) { } if (m_inactivity_time >= shutdown_timeout && m_button_pressed) { - DISABLE_GATE(); - gates_disabled_here = true; - HW_SHUTDOWN_HOLD_OFF(); + gates_disabled_here = do_shutdown(); } } else { m_inactivity_time = 0.0; diff --git a/terminal.c b/terminal.c index 55ebd265..9d081bde 100644 --- a/terminal.c +++ b/terminal.c @@ -162,6 +162,10 @@ void terminal_process_string(char *str) { commands_printf("Electrical RPM: %.2f rpm\n", (double)mc_interface_get_rpm()); } else if (strcmp(argv[0], "tacho") == 0) { commands_printf("Tachometer counts: %i\n", mc_interface_get_tachometer_value(0)); + } else if (strcmp(argv[0], "dist") == 0) { + commands_printf("Trip dist. : %.2f m", (double)mc_interface_get_distance()); + commands_printf("Trip dist. (ABS): %.2f m", (double)mc_interface_get_distance_abs()); + commands_printf("Odometer : %u m\n", mc_interface_get_odometer()); } else if (strcmp(argv[0], "tim") == 0) { chSysLock(); volatile int t1_cnt = TIM1->CNT;