From 12c72cf284a5f59621a3b4870b4fd610ab57118c Mon Sep 17 00:00:00 2001 From: Oskar Weigl Date: Fri, 23 Feb 2018 23:36:46 -0800 Subject: [PATCH] change how default configs are done for now --- Firmware/MotorControl/commands.cpp | 8 +- Firmware/MotorControl/config.cpp | 121 ++++++++++++----------------- Firmware/MotorControl/config.h | 2 +- Firmware/MotorControl/low_level.c | 103 +++++++++++++++++++++--- Firmware/MotorControl/low_level.h | 3 +- Firmware/MotorControl/nvm.c | 48 ++++++------ 6 files changed, 175 insertions(+), 110 deletions(-) diff --git a/Firmware/MotorControl/commands.cpp b/Firmware/MotorControl/commands.cpp index 7ab94b06..98dea15d 100644 --- a/Firmware/MotorControl/commands.cpp +++ b/Firmware/MotorControl/commands.cpp @@ -94,7 +94,6 @@ void motors_1_set_current_setpoint_func(void) { // clang-format off const Endpoint endpoints[] = { Endpoint::make_property("vbus_voltage", const_cast(&vbus_voltage)), - Endpoint::make_property("elec_rad_per_enc", const_cast(&elec_rad_per_enc)), Endpoint::make_property("UUID_0", (const uint32_t*)(ID_UNIQUE_ADDRESS + 0*4)), Endpoint::make_property("UUID_1", (const uint32_t*)(ID_UNIQUE_ADDRESS + 1*4)), Endpoint::make_property("UUID_2", (const uint32_t*)(ID_UNIQUE_ADDRESS + 2*4)), @@ -212,10 +211,13 @@ const Endpoint endpoints[] = { Endpoint::make_property("current_setpoint", &motors[1].set_current_setpoint_args.current_setpoint), Endpoint::close_tree(), Endpoint::close_tree(), // motor1 - Endpoint::make_function("save_config", &save_configuration), + Endpoint::make_function("save_configuration", &save_configuration), // no arguments Endpoint::close_tree(), - Endpoint::make_function("reset", &reset), + Endpoint::make_function("erase_configuration", &erase_configuration), + // no arguments + Endpoint::close_tree(), + Endpoint::make_function("reboot", &NVIC_SystemReset), // no arguments Endpoint::close_tree() }; diff --git a/Firmware/MotorControl/config.cpp b/Firmware/MotorControl/config.cpp index f3991f3f..63ef8fe4 100644 --- a/Firmware/MotorControl/config.cpp +++ b/Firmware/MotorControl/config.cpp @@ -14,57 +14,30 @@ /* Private defines -----------------------------------------------------------*/ #define CRC16_INIT 0xabcd -#if HW_VERSION_MAJOR == 3 -#if HW_VERSION_MINOR <= 3 -#define SHUNT_RESISTANCE (675e-6f) -#else -#define SHUNT_RESISTANCE (500e-6f) -#endif -#endif - /* Private macros ------------------------------------------------------------*/ /* Private typedef -----------------------------------------------------------*/ typedef struct { - Motor_control_mode_t control_mode = CTRL_MODE_POSITION_CONTROL; //see: Motor_control_mode_t - bool enable_step_dir = false; //auto enabled after calibration - float counts_per_step = 2.0f; - float pos_setpoint = 0.0f; - float pos_gain = 20.0f; // [(counts/s) / counts] - float vel_setpoint = 0.0f; - //float vel_setpoint = 800.0f; - float vel_gain = 5.0f / 10000.0f; // [A/(counts/s)] - //float vel_gain = 15.0f / 200.0f; // [A/(rad/s)] - float vel_integrator_gain = 10.0f / 10000.0f; // [A/(counts/s * s)] - //float vel_integrator_gain = 0.0f; // [A/(rad/s * s)] - float vel_integrator_current = 0.0f; // [A] - float vel_limit = 20000.0f; // [counts/s] - float current_setpoint = 0.0f; // [A] - float calibration_current = 10.0f; // [A] - float resistance_calib_max_voltage = 1.0f; // [V] - You may need to increase this if this voltage isn't sufficient to drive calibration_current through the motor. - float phase_inductance = 0.0f; // to be set by measure_phase_inductance - float phase_resistance = 0.0f; // to be set by measure_phase_resistance - Motor_type_t motor_type = MOTOR_TYPE_HIGH_CURRENT; - //Motor_type_t motor_type = MOTOR_TYPE_GIMBAL; - float shunt_conductance = 1.0f / SHUNT_RESISTANCE; //[S] - float phase_current_rev_gain = 0.0f; // to be set by DRV8301_setup - Current_control_t current_control = { - // Read out max_allowed_current to see max supported value for current_lim. - // You can change DRV8301_ShuntAmpGain to get a different range. - // .current_lim = 75.0f, //[A] - .current_lim = 10.0f, //[A] - .p_gain = 0.0f, // [V/A] should be auto set after resistance and inductance measurement - .i_gain = 0.0f, // [V/As] should be auto set after resistance and inductance measurement - .v_current_control_integral_d = 0.0f, - .v_current_control_integral_q = 0.0f, - .Ibus = 0.0f, - .final_v_alpha = 0.0f, - .final_v_beta = 0.0f, - .Iq_setpoint = 0.0f, - .Iq_measured = 0.0f, - .max_allowed_current = 0.0f, - }; - Rotor_mode_t rotor_mode = ROTOR_MODE_ENCODER; + Motor_control_mode_t control_mode; + float counts_per_step; + int32_t pole_pairs; + float pos_gain; + float vel_gain; + float vel_integrator_gain; + float vel_limit; + float calibration_current; + float resistance_calib_max_voltage; + float phase_inductance; + float phase_resistance; + Motor_type_t motor_type; + Rotor_mode_t rotor_mode; + float current_control_current_lim; + bool encoder_use_index; + bool encoder_calibrated; + float encoder_idx_search_speed; + int32_t encoder_cpr; + int32_t encoder_offset; + int32_t motor_dir; } MotorConfig_t; /* Global constant data ------------------------------------------------------*/ @@ -108,7 +81,7 @@ struct Config { return 0; } - static int store_config(size_t offset, uint16_t* crc16, T* val0, Ts* ... vals) { + static int store_config(size_t offset, uint16_t* crc16, const T* val0, const Ts* ... vals) { size_t size = sizeof(T); if (NVM_write(offset, (uint8_t *)val0, size)) return -1; @@ -132,7 +105,7 @@ struct Config { return 0; } - static int store_config(T* val0, Ts* ... vals) { + static int store_config(const T* val0, const Ts* ... vals) { size_t size = Config::get_size() + 2; //printf("config is %d bytes\r\n", size); osDelay(5); if (size > NVM_get_max_write_length()) @@ -152,52 +125,56 @@ struct Config { // This function is obviously stupid and should go away (make MotorConfig_t a member of Motor_t) // TODO: make this go away as part of the C++ refactoring -void set_motor_config(MotorConfig_t *config, Motor_t *motor) { +void set_motor_config(const MotorConfig_t* config, Motor_t* motor) { motor->control_mode = config->control_mode; - motor->enable_step_dir = config->enable_step_dir; motor->counts_per_step = config->counts_per_step; - motor->pos_setpoint = config->pos_setpoint; + motor->pole_pairs = config->pole_pairs; motor->pos_gain = config->pos_gain; - motor->vel_setpoint = config->vel_setpoint; motor->vel_gain = config->vel_gain; motor->vel_integrator_gain = config->vel_integrator_gain; - motor->vel_integrator_current = config->vel_integrator_current; motor->vel_limit = config->vel_limit; - motor->current_setpoint = config->current_setpoint; motor->calibration_current = config->calibration_current; motor->resistance_calib_max_voltage = config->resistance_calib_max_voltage; motor->phase_inductance = config->phase_inductance; motor->phase_resistance = config->phase_resistance; motor->motor_type = config->motor_type; - motor->shunt_conductance = config->shunt_conductance; - motor->phase_current_rev_gain = config->phase_current_rev_gain; - motor->current_control = config->current_control; motor->rotor_mode = config->rotor_mode; + + motor->current_control.current_lim = config->current_control_current_lim; + + motor->encoder.use_index = config->encoder_use_index; + motor->encoder.calibrated = config->encoder_calibrated; + motor->encoder.idx_search_speed = config->encoder_idx_search_speed; + motor->encoder.encoder_cpr = config->encoder_cpr; + motor->encoder.encoder_offset = config->encoder_offset; + motor->encoder.motor_dir = config->motor_dir; } // This function is obviously stupid and should go away (make MotorConfig_t a member of Motor_t) // TODO: make this go away as part of the C++ refactoring -void get_motor_config(Motor_t *motor, MotorConfig_t *config) { +void get_motor_config(const Motor_t* motor, MotorConfig_t* config) { config->control_mode = motor->control_mode; - config->enable_step_dir = motor->enable_step_dir; config->counts_per_step = motor->counts_per_step; - config->pos_setpoint = motor->pos_setpoint; + config->pole_pairs = motor->pole_pairs; config->pos_gain = motor->pos_gain; - config->vel_setpoint = motor->vel_setpoint; config->vel_gain = motor->vel_gain; config->vel_integrator_gain = motor->vel_integrator_gain; - config->vel_integrator_current = motor->vel_integrator_current; config->vel_limit = motor->vel_limit; - config->current_setpoint = motor->current_setpoint; config->calibration_current = motor->calibration_current; config->resistance_calib_max_voltage = motor->resistance_calib_max_voltage; config->phase_inductance = motor->phase_inductance; config->phase_resistance = motor->phase_resistance; config->motor_type = motor->motor_type; - config->shunt_conductance = motor->shunt_conductance; - config->phase_current_rev_gain = motor->phase_current_rev_gain; - config->current_control = motor->current_control; config->rotor_mode = motor->rotor_mode; + + config->current_control_current_lim = motor->current_control.current_lim; + + config->encoder_use_index = motor->encoder.use_index; + config->encoder_calibrated = motor->encoder.calibrated; + config->encoder_idx_search_speed = motor->encoder.idx_search_speed; + config->encoder_cpr = motor->encoder.encoder_cpr; + config->encoder_offset = motor->encoder.encoder_offset; + config->motor_dir = motor->encoder.motor_dir; } @@ -206,8 +183,11 @@ void init_configuration(void) { if (NVM_init() || Config::load_config(&motor_config[0], &motor_config[1])) { //printf("no config found\r\n"); osDelay(5); // load default config - motor_config[0] = MotorConfig_t(); - motor_config[1] = MotorConfig_t(); + // motor_config[0] = MotorConfig_t(); + // motor_config[1] = MotorConfig_t(); + + // Default config coming from flashed Motor_t + return; } else { //printf("load config successful\r\n"); osDelay(5); } @@ -225,7 +205,6 @@ void save_configuration(void) { } } -void reset(void) { +void erase_configuration(void) { NVM_erase(); - NVIC_SystemReset(); } diff --git a/Firmware/MotorControl/config.h b/Firmware/MotorControl/config.h index 2bd6556b..57fafcca 100644 --- a/Firmware/MotorControl/config.h +++ b/Firmware/MotorControl/config.h @@ -7,7 +7,7 @@ extern "C" { void init_configuration(void); void save_configuration(void); -void reset(void); +void erase_configuration(void); #ifdef __cplusplus } diff --git a/Firmware/MotorControl/low_level.c b/Firmware/MotorControl/low_level.c index 02b9c692..802c91c1 100644 --- a/Firmware/MotorControl/low_level.c +++ b/Firmware/MotorControl/low_level.c @@ -33,11 +33,13 @@ // Arbitrary non-zero inital value to avoid division by zero if ADC reading is late float vbus_voltage = 12.0f; -// TODO stick parameter into struct -#define ENCODER_CPR (2048 * 4) // Default resolution of CUI-AMT102 encoder -#define POLE_PAIRS 7 // This value is correct for N5065 motors and Turnigy SK3 series. -const float elec_rad_per_enc = POLE_PAIRS * 2 * M_PI * (1.0f / (float)ENCODER_CPR); - +#if HW_VERSION_MAJOR == 3 +#if HW_VERSION_MINOR <= 3 +#define SHUNT_RESISTANCE (675e-6f) +#else +#define SHUNT_RESISTANCE (500e-6f) +#endif +#endif // TODO: Migrate to C++, clearly we are actually doing object oriented code here... // TODO: For nice encapsulation, consider not having the motor objects public @@ -48,7 +50,26 @@ const float elec_rad_per_enc = POLE_PAIRS * 2 * M_PI * (1.0f / (float)ENCODER_CP Motor_t motors[] = { { // M0 + .control_mode = CTRL_MODE_POSITION_CONTROL, //see: Motor_control_mode_t + .enable_step_dir = false, //auto enabled after calibration + .counts_per_step = 2.0f, .error = ERROR_NO_ERROR, + .pole_pairs = 7, // This value is correct for N5065 motors and Turnigy SK3 series. + .pos_setpoint = 0.0f, + .pos_gain = 20.0f, // [(counts/s) / counts] + .vel_setpoint = 0.0f, + // .vel_setpoint = 800.0f, + .vel_gain = 5.0f / 10000.0f, // [A/(counts/s)] + // .vel_gain = 15.0f / 200.0f, // [A/(rad/s)] + .vel_integrator_gain = 10.0f / 10000.0f, // [A/(counts/s * s)] + // .vel_integrator_gain = 0.0f, // [A/(rad/s * s)] + .vel_integrator_current = 0.0f, // [A] + .vel_limit = 20000.0f, // [counts/s] + .current_setpoint = 0.0f, // [A] + .calibration_current = 10.0f, // [A] + .resistance_calib_max_voltage = 1.0f, // [V] - You may need to increase this if this voltage isn't sufficient to drive calibration_current through the motor. + .phase_inductance = 0.0f, // to be set by measure_phase_inductance + .phase_resistance = 0.0f, // to be set by measure_phase_resistance .motor_thread = 0, .thread_ready = false, // .enable_control = true, @@ -71,13 +92,36 @@ Motor_t motors[] = { .enableTimeOut = false, }, // .gate_driver_regs Init by DRV8301_setup + .motor_type = MOTOR_TYPE_HIGH_CURRENT, + // .motor_type = MOTOR_TYPE_GIMBAL, + .shunt_conductance = 1.0f / SHUNT_RESISTANCE, //[S] + .phase_current_rev_gain = 0.0f, // to be set by DRV8301_setup + .current_control = { + // Read out max_allowed_current to see max supported value for current_lim. + // You can change DRV8301_ShuntAmpGain to get a different range. + // .current_lim = 75.0f, //[A] + .current_lim = 10.0f, //[A] + .p_gain = 0.0f, // [V/A] should be auto set after resistance and inductance measurement + .i_gain = 0.0f, // [V/As] should be auto set after resistance and inductance measurement + .v_current_control_integral_d = 0.0f, + .v_current_control_integral_q = 0.0f, + .Ibus = 0.0f, + .final_v_alpha = 0.0f, + .final_v_beta = 0.0f, + .Iq_setpoint = 0.0f, + .Iq_measured = 0.0f, + .max_allowed_current = 0.0f, + }, + // .rotor_mode = ROTOR_MODE_SENSORLESS, + // .rotor_mode = ROTOR_MODE_RUN_ENCODER_TEST_SENSORLESS, + .rotor_mode = ROTOR_MODE_ENCODER, .encoder = { .encoder_timer = &htim3, .use_index = false, .index_found = false, .calibrated = false, .idx_search_speed = 10.0f, // [rad/s electrical] - .encoder_cpr = ENCODER_CPR, + .encoder_cpr = (2048 * 4), // Default resolution of CUI-AMT102 encoder, .encoder_offset = 0, .encoder_state = 0, .motor_dir = 1, // 1 or -1 @@ -115,7 +159,23 @@ Motor_t motors[] = { }, }, { // M1 + .control_mode = CTRL_MODE_POSITION_CONTROL, //see: Motor_control_mode_t + .enable_step_dir = false, //auto enabled after calibration + .counts_per_step = 2.0f, .error = ERROR_NO_ERROR, + .pole_pairs = 7, // This value is correct for N5065 motors and Turnigy SK3 series. + .pos_setpoint = 0.0f, + .pos_gain = 20.0f, // [(counts/s) / counts] + .vel_setpoint = 0.0f, + .vel_gain = 5.0f / 10000.0f, // [A/(counts/s)] + .vel_integrator_gain = 10.0f / 10000.0f, // [A/(counts/s * s)] + .vel_integrator_current = 0.0f, // [A] + .vel_limit = 20000.0f, // [counts/s] + .current_setpoint = 0.0f, // [A] + .calibration_current = 10.0f, // [A] + .resistance_calib_max_voltage = 1.0f, // [V] - You may need to increase this if this voltage isn't sufficient to drive calibration_current through the motor. + .phase_inductance = 0.0f, // to be set by measure_phase_inductance + .phase_resistance = 0.0f, // to be set by measure_phase_resistance .motor_thread = 0, .thread_ready = false, // .enable_control = true, @@ -138,13 +198,33 @@ Motor_t motors[] = { .enableTimeOut = false, }, // .gate_driver_regs Init by DRV8301_setup + .motor_type = MOTOR_TYPE_HIGH_CURRENT, + .shunt_conductance = 1.0f / SHUNT_RESISTANCE, //[S] + .phase_current_rev_gain = 0.0f, // to be set by DRV8301_setup + .current_control = { + // Read out max_allowed_current to see max supported value for current_lim. + // You can change DRV8301_ShuntAmpGain to get a different range. + // .current_lim = 75.0f, //[A] + .current_lim = 10.0f, //[A] + .p_gain = 0.0f, // [V/A] should be auto set after resistance and inductance measurement + .i_gain = 0.0f, // [V/As] should be auto set after resistance and inductance measurement + .v_current_control_integral_d = 0.0f, + .v_current_control_integral_q = 0.0f, + .Ibus = 0.0f, + .final_v_alpha = 0.0f, + .final_v_beta = 0.0f, + .Iq_setpoint = 0.0f, + .Iq_measured = 0.0f, + .max_allowed_current = 0.0f, + }, + .rotor_mode = ROTOR_MODE_ENCODER, .encoder = { .encoder_timer = &htim4, .use_index = false, .index_found = false, .calibrated = false, .idx_search_speed = 10.0f, // [rad/s electrical] - .encoder_cpr = ENCODER_CPR, + .encoder_cpr = (2048 * 4), // Default resolution of CUI-AMT102 encoder, .encoder_offset = 0, .encoder_state = 0, .motor_dir = 1, // 1 or -1 @@ -806,7 +886,7 @@ bool anti_cogging_calibration(Motor_t* motor) { fabsf(motor->encoder.pll_vel) < motor->anticogging.calib_vel_threshold) { motor->anticogging.cogging_map[motor->anticogging.index++] = motor->vel_integrator_current; } - if (motor->anticogging.index < ENCODER_CPR) { + if (motor->anticogging.index < motor->encoder.encoder_cpr) { set_pos_setpoint(motor, motor->anticogging.index, 0.0f, 0.0f); return false; } else { @@ -862,9 +942,10 @@ void update_rotor(Motor_t* motor) { encoder->encoder_state += (int32_t)delta_enc; // compute electrical phase - int corrected_enc = encoder->encoder_state % ENCODER_CPR; + int corrected_enc = encoder->encoder_state % motor->encoder.encoder_cpr; corrected_enc -= encoder->encoder_offset; corrected_enc *= encoder->motor_dir; + float elec_rad_per_enc = motor->pole_pairs * 2 * M_PI * (1.0f / (float)(motor->encoder.encoder_cpr)); float ph = elec_rad_per_enc * (float)corrected_enc; // ph = fmodf(ph, 2*M_PI); encoder->phase = wrap_pm_pi(ph); @@ -1235,9 +1316,9 @@ void control_motor_loop(Motor_t* motor) { // Anti-cogging is enabled after calibration // We get the current position and apply a current feed-forward - // ensuring that we handle negative encoder positions properly (-1 == ENCODER_CPR - 1) + // ensuring that we handle negative encoder positions properly (-1 == motor->encoder.encoder_cpr - 1) if (motor->anticogging.use_anticogging) { - Iq += motor->anticogging.cogging_map[mod(motor->encoder.pll_pos, ENCODER_CPR)]; + Iq += motor->anticogging.cogging_map[mod(motor->encoder.pll_pos, motor->encoder.encoder_cpr)]; } float v_err = vel_des - get_pll_vel(motor); diff --git a/Firmware/MotorControl/low_level.h b/Firmware/MotorControl/low_level.h index 9045b1d9..b5625a25 100644 --- a/Firmware/MotorControl/low_level.h +++ b/Firmware/MotorControl/low_level.h @@ -115,7 +115,7 @@ typedef struct { bool index_found; bool calibrated; float idx_search_speed; - int encoder_cpr; + int32_t encoder_cpr; int32_t encoder_offset; int32_t encoder_state; int32_t motor_dir; // 1/-1 for fwd/rev alignment to encoder. @@ -137,6 +137,7 @@ typedef struct { bool enable_step_dir; float counts_per_step; Error_t error; + int32_t pole_pairs; float pos_setpoint; float pos_gain; float vel_setpoint; diff --git a/Firmware/MotorControl/nvm.c b/Firmware/MotorControl/nvm.c index 4d9c843a..e581beee 100644 --- a/Firmware/MotorControl/nvm.c +++ b/Firmware/MotorControl/nvm.c @@ -9,18 +9,21 @@ * Setting any bit in these sectors to 0 is always possible, but setting them * to 1 requires erasing the whole sector. * -* We consider each sector as an array of 64-bit fields and use the beginning -* as an allocation block. The allocation block keeps track of the state of each -* field (erased, invalid, valid). +* We consider each sector as an array of 64-bit fields except the first N bytes, which we +* instead use as an allocation block. The allocation block is a compact bit-field (2 bit per entry) +* that keeps track of the state of each field (erased, invalid, valid). * * One sector is always considered the valid (read) sector and the other one is the -* victim for the next write access. On startup, if there is exactly one sector +* target for the next write access: they can be considered to be ping-pong or double buffred. +* +* When writing a block of data, instead of always erasing the whole writable sector the +* new data is appended in the erased area. This presumably increases flash life span. +* The writable sector is only erased if there is not enough space for the new data. +* +* On startup, if there is exactly one sector * whose last non-erased value has the state "valid" that sector is considered * the valid sector. In any other case the selection is undefined. * -* When writing a block of data, instead of always erasing the whole victim sector the -* new data is appended in the erased area. This presumably increases flash life span. -* The victim sector is only erased if there is not enough space for the new data. * * To write a new block of data atomically we first mark all associated fields * as "invalid" (in the allocation table) then write the data and then mark the @@ -36,7 +39,7 @@ #if defined(STM32F405xx) // refer to page 75 of datasheet: -// http://www.st.com/content/ccc/resource/technical/document/reference_manual/3d/6d/5a/66/b4/99/40/d4/DM00031020.pdf/files/DM00031020.pdf +// http://www.st.com/content/ccc/resource/technical/document/reference_manual/3d/6d/5a/66/b4/99/40/d4/DM00031020.pdf/files/DM00031020.pdf/jcr:content/translations/en.DM00031020.pdf #define FLASH_SECTOR_10_BASE (const volatile uint8_t*)0x80C0000UL #define FLASH_SECTOR_10_SIZE 0x20000UL #define FLASH_SECTOR_11_BASE (const volatile uint8_t*)0x80E0000UL @@ -254,8 +257,8 @@ size_t NVM_get_max_read_length(void) { // @brief Returns the maximum length (in bytes) that can passed to NVM_start_write. // This holds until NVM_commit is called. size_t NVM_get_max_write_length(void) { - sector_t *victim = §ors[1 - read_sector_]; - return (victim->n_data - victim->n_reserved) << 3; + sector_t *target = §ors[1 - read_sector_]; + return (target->n_data - target->n_reserved) << 3; } // @brief Reads from the latest committed block in the non-volatile memory. @@ -272,7 +275,7 @@ int NVM_read(size_t offset, uint8_t *data, size_t length) { return 0; } -// @brief Starts an atomic write operation. The length must be at most equal to the size. +// @brief Starts an atomic write operation. // // The most recent valid NVM data is not modified or invalidated until NVM_commit is called. // The length must be at most equal to the size indicated by NVM_get_max_write_length(). @@ -280,19 +283,19 @@ int NVM_read(size_t offset, uint8_t *data, size_t length) { // @param length: Length of the staging block that should be created int NVM_start_write(size_t length) { int status = 0; - sector_t *victim = §ors[1 - read_sector_]; + sector_t *target = §ors[1 - read_sector_]; length = (length + 7) >> 3; // round to multiple of 64 bit - if (length > victim->n_data - victim->n_reserved) + if (length > target->n_data - target->n_reserved) return -1; // make room for the new data - if (length > victim->n_data - victim->index) - if ((status = erase(victim))) + if (length > target->n_data - target->index) + if ((status = erase(target))) return status; // invalidate the fields we're about to write - status = set_allocation_state(victim, victim->index, length, INVALID); + status = set_allocation_state(target, target->index, length, INVALID); if (status) return status; @@ -313,7 +316,7 @@ int NVM_start_write(size_t length) { int NVM_write(size_t offset, uint8_t *data, size_t length) { if (offset + length > (n_staging_area_ << 3)) return -1; - sector_t *victim = §ors[1 - read_sector_]; + sector_t *target = §ors[1 - read_sector_]; HAL_FLASH_Unlock(); HAL_FLASH_ClearError(); @@ -321,19 +324,19 @@ int NVM_write(size_t offset, uint8_t *data, size_t length) { // handle unaligned start for (; (offset & 0x3) && length; ++data, ++offset, --length) if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_BYTE, - ((uintptr_t)&victim->data[victim->index]) + offset, *data) != HAL_OK) + ((uintptr_t)&target->data[target->index]) + offset, *data) != HAL_OK) goto fail; // write 32-bit values (64-bit doesn't work) for (; length >= 4; data += 4, offset += 4, length -=4) if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, - ((uintptr_t)&victim->data[victim->index]) + offset, *(uint32_t*)data) != HAL_OK) + ((uintptr_t)&target->data[target->index]) + offset, *(uint32_t*)data) != HAL_OK) goto fail; // handle unaligned end for (; length; ++data, ++offset, --length) if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_BYTE, - ((uintptr_t)&victim->data[victim->index]) + offset, *data) != HAL_OK) + ((uintptr_t)&target->data[target->index]) + offset, *data) != HAL_OK) goto fail; HAL_FLASH_Lock(); @@ -363,9 +366,8 @@ int NVM_commit(void) { status = set_allocation_state(read_sector, read_sector->index, 1, INVALID); else status = erase(read_sector); - if (status) - return status; - return 0; + + return status; }