From bb9d4f5225562c0df3a7a9dc6a98a3a973c39a2a Mon Sep 17 00:00:00 2001 From: Nick Knudson Date: Wed, 1 Mar 2017 21:44:06 -0800 Subject: [PATCH 01/53] added travis-ci --- .travis.yml | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 .travis.yml diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 00000000..ba888a75 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,23 @@ +# adapted from https://github.com/andysworkshop/stm32plus/blob/master/.travis.yml + +language: c +sudo: false + +addons: + apt: + packages: + libc6-i386 + +cache: + directories: + - $HOME/dl + +install: + - export GCC_DIR=$HOME/dl/gcc-arm-none-eabi-5_2-2015q4 + - export GCC_ARCHIVE=$HOME/dl/gcc-arm-none-eabi-5_2-2015q4-20151219-linux.tar.bz2 + - export GCC_URL=https://launchpad.net/gcc-arm-embedded/5.0/5-2015-q4-major/+download/gcc-arm-none-eabi-5_2-2015q4-20151219-linux.tar.bz2 + - if [ ! -e $GCC_DIR/bin/arm-none-eabi-gcc ]; then wget $GCC_URL -O $GCC_ARCHIVE; tar xfj $GCC_ARCHIVE -C $HOME/dl; fi + - export PATH=$PATH:$GCC_DIR/bin + +script: + - make clean && make From 72efd17f31e370721f5bfe0de28b2d08f1bc9e0f Mon Sep 17 00:00:00 2001 From: Oskar Weigl Date: Mon, 19 Feb 2018 00:32:01 -0800 Subject: [PATCH 02/53] implement dc bus brownout check --- Firmware/MotorControl/axis.cpp | 4 +- Firmware/MotorControl/low_level.c | 69 +++++++++++++++++++++++++++---- Firmware/MotorControl/low_level.h | 4 ++ 3 files changed, 66 insertions(+), 11 deletions(-) diff --git a/Firmware/MotorControl/axis.cpp b/Firmware/MotorControl/axis.cpp index aaac53b5..bd000916 100644 --- a/Firmware/MotorControl/axis.cpp +++ b/Firmware/MotorControl/axis.cpp @@ -62,8 +62,8 @@ void Axis::StateMachineLoop() { for (;;) { // Keep rotor estimation up to date while idling osSignalWait(M_SIGNAL_PH_CURRENT_MEAS, osWaitForever); - update_rotor(legacy_motor_ref_); - + loop_updates(legacy_motor_ref_); + if (do_calibration_) { do_calibration_ = false; diff --git a/Firmware/MotorControl/low_level.c b/Firmware/MotorControl/low_level.c index c49b95ea..3819fa43 100644 --- a/Firmware/MotorControl/low_level.c +++ b/Firmware/MotorControl/low_level.c @@ -72,6 +72,7 @@ Motor_t motors[] = { .current_setpoint = 0.0f, // [A] .calibration_current = 10.0f, // [A] .resistance_calib_max_voltage = 1.0f, // [V] + .dc_bus_brownout_trip_level = 8.0f, // [V] .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, @@ -177,6 +178,7 @@ Motor_t motors[] = { .current_setpoint = 0.0f, // [A] .calibration_current = 10.0f, // [A] .resistance_calib_max_voltage = 1.0f, // [V] + .dc_bus_brownout_trip_level = 8.0f, // [V] .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, @@ -553,6 +555,7 @@ void step_cb(uint16_t GPIO_Pin) { } // Triggered when an encoder passes over the "Index" pin +// TODO: only arm index edge interrupt when we know encoder has powered up void enc_index_cb(uint16_t GPIO_Pin, uint8_t motor_index) { Motor_t* motor = &motors[motor_index]; if (!motor->encoder.index_found) { @@ -685,6 +688,9 @@ bool measure_phase_resistance(Motor_t* motor, float test_current, float max_volt motor->error = ERROR_PHASE_RESISTANCE_MEASUREMENT_TIMEOUT; return false; } + if (!do_checks(motor)) + return false; + float Ialpha = -(motor->current_meas.phB + motor->current_meas.phC); test_voltage += (kI * current_meas_period) * (test_current - Ialpha); if (test_voltage > max_voltage) test_voltage = max_voltage; @@ -724,6 +730,9 @@ bool measure_phase_inductance(Motor_t* motor, float voltage_low, float voltage_h motor->error = ERROR_PHASE_INDUCTANCE_MEASUREMENT_TIMEOUT; return false; } + if (!do_checks(motor)) + return false; + Ialphas[i] += -motor->current_meas.phB - motor->current_meas.phC; // Test voltage along phase A @@ -774,6 +783,8 @@ bool calib_enc_offset(Motor_t* motor, float voltage_magnitude) { motor->error = ERROR_ENCODER_MEASUREMENT_TIMEOUT; return false; } + if (!do_checks(motor)) + return false; queue_voltage_timings(motor, voltage_magnitude, 0.0f); } // scan forwards @@ -783,6 +794,8 @@ bool calib_enc_offset(Motor_t* motor, float voltage_magnitude) { motor->error = ERROR_ENCODER_MEASUREMENT_TIMEOUT; return false; } + if (!do_checks(motor)) + return false; float v_alpha = voltage_magnitude * arm_cos_f32(ph); float v_beta = voltage_magnitude * arm_sin_f32(ph); queue_voltage_timings(motor, v_alpha, v_beta); @@ -808,6 +821,8 @@ bool calib_enc_offset(Motor_t* motor, float voltage_magnitude) { motor->error = ERROR_ENCODER_MEASUREMENT_TIMEOUT; return false; } + if (!do_checks(motor)) + return false; float v_alpha = voltage_magnitude * arm_cos_f32(ph); float v_beta = voltage_magnitude * arm_sin_f32(ph); queue_voltage_timings(motor, v_alpha, v_beta); @@ -911,6 +926,8 @@ bool scan_for_enc_idx(Motor_t* motor, float omega, float voltage_magnitude) { for (;;) { for (float ph = 0.0f; ph < 2.0f * M_PI; ph += omega * current_meas_period) { osSignalWait(M_SIGNAL_PH_CURRENT_MEAS, osWaitForever); + if (!do_checks(motor)) + return false; if (motor->encoder.index_found) return true; @@ -1101,8 +1118,13 @@ bool spin_up_timestep(Motor_t* motor, float phase, float I_mag) { motor->error = ERROR_SPIN_UP_TIMEOUT; return false; } + + if (!do_checks(motor)) + return false; // run estimator - update_rotor(motor); + if (!loop_updates(motor)) + return false; + // override the phase during spinup motor->sensorless.phase = phase; // run current control (with the phase override) @@ -1191,6 +1213,8 @@ void queue_voltage_timings(Motor_t* motor, float v_alpha, float v_beta) { queue_modulation_timings(motor, mod_alpha, mod_beta); } +// TODO: This doesn't update brake current +// We should probably make FOC Current call FOC Voltage to avoid duplication. bool FOC_voltage(Motor_t* motor, float v_d, float v_q) { float phase = get_rotor_phase(motor); float c = arm_cos_f32(phase); @@ -1273,14 +1297,40 @@ bool FOC_current(Motor_t* motor, float Id_des, float Iq_des) { motor->error = ERROR_FOC_TIMING; return false; } + + update_brake_current(); return true; } -//Returns true if the fault line is asserted +//Returns true if everything is OK (no fault) bool check_DRV_fault(Motor_t* motor) { //TODO: make this pin configurable per motor ch GPIO_PinState nFAULT_state = HAL_GPIO_ReadPin(nFAULT_GPIO_Port, nFAULT_Pin); - return (nFAULT_state == GPIO_PIN_RESET) ? true : false; + return (nFAULT_state == GPIO_PIN_RESET) ? false : true; +} + +//Returns true if everything is OK (no fault) +bool check_PSU_brownout(Motor_t* motor) { + if(vbus_voltage < motor->dc_bus_brownout_trip_level) { + motor->error = ERROR_DC_BUS_BROWNOUT; + return false; + } + return true; +} + +// Returns true if everything is ok. Sets motor->error and returns false otherwise. +bool do_checks(Motor_t* motor) { + // Checks + if (!check_DRV_fault(motor)) { + motor->error = ERROR_DRV_FAULT; + return false; + } + return true; +} + +bool loop_updates(Motor_t* motor) { + update_rotor(motor); + return true; } void control_motor_loop(Motor_t* motor) { @@ -1289,12 +1339,14 @@ void control_motor_loop(Motor_t* motor) { motor->error = ERROR_FOC_MEASUREMENT_TIMEOUT; break; } - if (check_DRV_fault(motor)) { - motor->error = ERROR_DRV_FAULT; + + if (!do_checks(motor)) break; - } - update_rotor(motor); - anti_cogging_calibration(motor); // Only runs if anticogging.calib_anticogging is true; non-blocking + if (!loop_updates(motor)) + break; + + // Only runs if anticogging.calib_anticogging is true; non-blocking + anti_cogging_calibration(motor); // Position control // TODO Decide if we want to use encoder or pll position here @@ -1377,7 +1429,6 @@ void control_motor_loop(Motor_t* motor) { break; } - update_brake_current(); ++(motor->loop_counter); } diff --git a/Firmware/MotorControl/low_level.h b/Firmware/MotorControl/low_level.h index 9045b1d9..e8f4bcc5 100644 --- a/Firmware/MotorControl/low_level.h +++ b/Firmware/MotorControl/low_level.h @@ -50,6 +50,7 @@ typedef enum { ERROR_SPIN_UP_TIMEOUT, ERROR_DRV_FAULT, ERROR_NOT_IMPLEMENTED_MOTOR_TYPE, + ERROR_DC_BUS_BROWNOUT, } Error_t; // Note: these should be sorted from lowest level of control to @@ -147,6 +148,7 @@ typedef struct { float current_setpoint; float calibration_current; float resistance_calib_max_voltage; + float dc_bus_brownout_trip_level; float phase_inductance; float phase_resistance; osThreadId motor_thread; @@ -243,6 +245,8 @@ bool anti_cogging_calibration(Motor_t* motor); // Test functions void scan_motor_loop(Motor_t* motor, float omega, float voltage_magnitude); // Main motor control +bool do_checks(Motor_t* motor); +bool loop_updates(Motor_t* motor); void update_rotor(Motor_t* motor); bool using_encoder(Motor_t* motor); bool using_sensorless(Motor_t* motor); From 06ab4d7bae930c46dd98c75c55ca6a136f5a61f1 Mon Sep 17 00:00:00 2001 From: Paul Guenette Date: Mon, 19 Feb 2018 19:42:47 -0500 Subject: [PATCH 03/53] Add Encoder CPR range checking --- Firmware/MotorControl/low_level.c | 17 ++++++++++++++--- Firmware/MotorControl/low_level.h | 2 ++ 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/Firmware/MotorControl/low_level.c b/Firmware/MotorControl/low_level.c index 96826b0d..d0a7ff5f 100644 --- a/Firmware/MotorControl/low_level.c +++ b/Firmware/MotorControl/low_level.c @@ -129,6 +129,7 @@ Motor_t motors[] = { .encoder_offset = 0, .encoder_state = 0, .motor_dir = 1, // 1 or -1 + .encoder_calib_range = 0.02, .phase = 0.0f, // [rad] .pll_pos = 0.0f, // [rad] .pll_vel = 0.0f, // [rad/s] @@ -231,6 +232,7 @@ Motor_t motors[] = { .encoder_offset = 0, .encoder_state = 0, .motor_dir = 1, // 1 or -1 + .encoder_calib_range = 0.02, .phase = 0.0f, // [rad] .pll_pos = 0.0f, // [rad] .pll_vel = 0.0f, // [rad/s] @@ -765,9 +767,6 @@ bool calib_enc_offset(Motor_t* motor, float voltage_magnitude) { static const float scan_range = 4.0f * M_PI; const float step_size = scan_range / (float)num_steps; // TODO handle const expressions better (maybe switch to C++ ?) - int32_t init_enc_val = (int16_t)motor->encoder.encoder_timer->Instance->CNT; - int32_t encvaluesum = 0; - // go to motor zero phase for start_lock_duration to get ready to scan for (int i = 0; i < start_lock_duration * current_meas_hz; ++i) { if (osSignalWait(M_SIGNAL_PH_CURRENT_MEAS, PH_CURRENT_MEAS_TIMEOUT).status != osEventSignal) { @@ -776,6 +775,10 @@ bool calib_enc_offset(Motor_t* motor, float voltage_magnitude) { } queue_voltage_timings(motor, voltage_magnitude, 0.0f); } + + int32_t init_enc_val = (int16_t)motor->encoder.encoder_timer->Instance->CNT; + int32_t encvaluesum = 0; + // scan forwards for (float ph = -scan_range / 2.0f; ph < scan_range / 2.0f; ph += step_size) { for (int i = 0; i < dt_step * (float)current_meas_hz; ++i) { @@ -789,6 +792,14 @@ bool calib_enc_offset(Motor_t* motor, float voltage_magnitude) { } encvaluesum += (int16_t)motor->encoder.encoder_timer->Instance->CNT; } + + float estEnc = scan_range / elec_rad_per_enc; + float adjustedCount = fabsf((int16_t)motor->encoder.encoder_timer->Instance->CNT)-init_enc_val; + if(fabsf(adjustedCount-estEnc)/estEnc > motor->encoder.encoder_calib_range) + { + motor->error = ERROR_ENCODER_CPR_OUT_OF_RANGE; + return false; + } // check direction if ((int16_t)motor->encoder.encoder_timer->Instance->CNT > init_enc_val + 8) { // motor same dir as encoder diff --git a/Firmware/MotorControl/low_level.h b/Firmware/MotorControl/low_level.h index 9045b1d9..deb89f3c 100644 --- a/Firmware/MotorControl/low_level.h +++ b/Firmware/MotorControl/low_level.h @@ -50,6 +50,7 @@ typedef enum { ERROR_SPIN_UP_TIMEOUT, ERROR_DRV_FAULT, ERROR_NOT_IMPLEMENTED_MOTOR_TYPE, + ERROR_ENCODER_CPR_OUT_OF_RANGE } Error_t; // Note: these should be sorted from lowest level of control to @@ -119,6 +120,7 @@ typedef struct { int32_t encoder_offset; int32_t encoder_state; int32_t motor_dir; // 1/-1 for fwd/rev alignment to encoder. + float encoder_calib_range; float phase; float pll_pos; float pll_vel; From 4d0366f8dff70e8b356c7a0b3f539407685531f1 Mon Sep 17 00:00:00 2001 From: Paul Guenette Date: Mon, 19 Feb 2018 20:01:45 -0500 Subject: [PATCH 04/53] Change the calibration distance & number of steps for accuracy --- Firmware/MotorControl/low_level.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Firmware/MotorControl/low_level.c b/Firmware/MotorControl/low_level.c index d0a7ff5f..afc63053 100644 --- a/Firmware/MotorControl/low_level.c +++ b/Firmware/MotorControl/low_level.c @@ -762,9 +762,9 @@ bool measure_phase_inductance(Motor_t* motor, float voltage_low, float voltage_h // TODO: add check_timing bool calib_enc_offset(Motor_t* motor, float voltage_magnitude) { static const float start_lock_duration = 1.0f; - static const int num_steps = 1024; + static const int num_steps = 1024*4; static const float dt_step = 1.0f / 500.0f; - static const float scan_range = 4.0f * M_PI; + static const float scan_range = 16.0f * M_PI; const float step_size = scan_range / (float)num_steps; // TODO handle const expressions better (maybe switch to C++ ?) // go to motor zero phase for start_lock_duration to get ready to scan From ef0f8dbf85c1a4d4ec69b8e2ba0543d5bc979ae1 Mon Sep 17 00:00:00 2001 From: Quincy Jones Date: Wed, 21 Feb 2018 13:41:42 -0600 Subject: [PATCH 05/53] Add microsecond delay functions. Add DRV register/fault status reporting. --- Firmware/Drivers/DRV8301/drv8301.c | 23 ++++++++++++++--------- Firmware/Drivers/DRV8301/drv8301.h | 5 +++++ Firmware/MotorControl/commands.cpp | 14 ++++++++++++++ Firmware/MotorControl/low_level.c | 12 +++++++++++- Firmware/MotorControl/low_level.h | 1 + Firmware/MotorControl/utils.c | 21 +++++++++++++++++++++ Firmware/MotorControl/utils.h | 4 ++++ tools/drv_status.py | 28 ++++++++++++++++++++++++++++ 8 files changed, 98 insertions(+), 10 deletions(-) create mode 100644 tools/drv_status.py diff --git a/Firmware/Drivers/DRV8301/drv8301.c b/Firmware/Drivers/DRV8301/drv8301.c index db3a8081..765d7d49 100644 --- a/Firmware/Drivers/DRV8301/drv8301.c +++ b/Firmware/Drivers/DRV8301/drv8301.c @@ -45,6 +45,8 @@ // drivers #include "drv8301.h" +#include "utils.h" + // ************************************************************************** // the defines @@ -362,7 +364,7 @@ uint16_t DRV8301_readSpi(DRV8301_Handle handle, const DRV8301_RegName_e regName) // Actuate chipselect HAL_GPIO_WritePin(handle->nCSgpioHandle, handle->nCSgpioNumber, GPIO_PIN_RESET); - osDelay(1); + delay_us(1); // Do blocking read uint16_t zerobuff = 0; @@ -374,17 +376,17 @@ uint16_t DRV8301_readSpi(DRV8301_Handle handle, const DRV8301_RegName_e regName) // but for some reason you actually need to pulse it. // Actuate chipselect HAL_GPIO_WritePin(handle->nCSgpioHandle, handle->nCSgpioNumber, GPIO_PIN_SET); - osDelay(1); + delay_us(1); // Actuate chipselect HAL_GPIO_WritePin(handle->nCSgpioHandle, handle->nCSgpioNumber, GPIO_PIN_RESET); - osDelay(1); + delay_us(1); HAL_SPI_TransmitReceive(handle->spiHandle, (uint8_t*)(&zerobuff), (uint8_t*)(&recbuff), 1, 1000); - osDelay(1); + delay_us(1); // Actuate chipselect HAL_GPIO_WritePin(handle->nCSgpioHandle, handle->nCSgpioNumber, GPIO_PIN_SET); - osDelay(1); + delay_us(1); assert(recbuff != 0xbeef); @@ -590,16 +592,16 @@ void DRV8301_writeSpi(DRV8301_Handle handle, const DRV8301_RegName_e regName,con { // Actuate chipselect HAL_GPIO_WritePin(handle->nCSgpioHandle, handle->nCSgpioNumber, GPIO_PIN_RESET); - osDelay(1); + delay_us(5); // Do blocking write uint16_t controlword = (uint16_t)DRV8301_buildCtrlWord(DRV8301_CtrlMode_Write, regName, data); HAL_SPI_Transmit(handle->spiHandle, (uint8_t*)(&controlword), 1, 1000); - osDelay(1); + delay_us(5); // Actuate chipselect HAL_GPIO_WritePin(handle->nCSgpioHandle, handle->nCSgpioNumber, GPIO_PIN_SET); - osDelay(1); + delay_us(5); return; } // end of DRV8301_writeSpi() function @@ -659,12 +661,14 @@ void DRV8301_readData(DRV8301_Handle handle, DRV_SPI_8301_Vars_t *Spi_8301_Vars) Spi_8301_Vars->Stat_Reg_1.FETLB_OC = (bool)(drvDataNew & (uint16_t)DRV8301_STATUS1_FETLB_OC_BITS); Spi_8301_Vars->Stat_Reg_1.FETHC_OC = (bool)(drvDataNew & (uint16_t)DRV8301_STATUS1_FETHC_OC_BITS); Spi_8301_Vars->Stat_Reg_1.FETLC_OC = (bool)(drvDataNew & (uint16_t)DRV8301_STATUS1_FETLC_OC_BITS); + Spi_8301_Vars->Stat_Reg_1_Value = drvDataNew; // Update Status Register 2 drvRegName = DRV8301_RegName_Status_2; drvDataNew = DRV8301_readSpi(handle,drvRegName); Spi_8301_Vars->Stat_Reg_2.GVDD_OV = (bool)(drvDataNew & (uint16_t)DRV8301_STATUS2_GVDD_OV_BITS); Spi_8301_Vars->Stat_Reg_2.DeviceID = (uint16_t)(drvDataNew & (uint16_t)DRV8301_STATUS2_ID_BITS); + Spi_8301_Vars->Stat_Reg_2_Value = drvDataNew; // Update Control Register 1 drvRegName = DRV8301_RegName_Control_1; @@ -674,6 +678,7 @@ void DRV8301_readData(DRV8301_Handle handle, DRV_SPI_8301_Vars_t *Spi_8301_Vars) Spi_8301_Vars->Ctrl_Reg_1.PWM_MODE = (DRV8301_PwmMode_e)(drvDataNew & (uint16_t)DRV8301_CTRL1_PWM_MODE_BITS); Spi_8301_Vars->Ctrl_Reg_1.OC_MODE = (DRV8301_OcMode_e)(drvDataNew & (uint16_t)DRV8301_CTRL1_OC_MODE_BITS); Spi_8301_Vars->Ctrl_Reg_1.OC_ADJ_SET = (DRV8301_VdsLevel_e)(drvDataNew & (uint16_t)DRV8301_CTRL1_OC_ADJ_SET_BITS); + Spi_8301_Vars->Ctrl_Reg_1_Value = drvDataNew; // Update Control Register 2 drvRegName = DRV8301_RegName_Control_2; @@ -682,7 +687,7 @@ void DRV8301_readData(DRV8301_Handle handle, DRV_SPI_8301_Vars_t *Spi_8301_Vars) Spi_8301_Vars->Ctrl_Reg_2.GAIN = (DRV8301_ShuntAmpGain_e)(drvDataNew & (uint16_t)DRV8301_CTRL2_GAIN_BITS); Spi_8301_Vars->Ctrl_Reg_2.DC_CAL_CH1p2 = (DRV8301_DcCalMode_e)(drvDataNew & (uint16_t)(DRV8301_CTRL2_DC_CAL_1_BITS | DRV8301_CTRL2_DC_CAL_2_BITS)); Spi_8301_Vars->Ctrl_Reg_2.OC_TOFF = (DRV8301_OcOffTimeMode_e)(drvDataNew & (uint16_t)DRV8301_CTRL2_OC_TOFF_BITS); - + Spi_8301_Vars->Ctrl_Reg_2_Value = drvDataNew; Spi_8301_Vars->RcvCmd = false; } diff --git a/Firmware/Drivers/DRV8301/drv8301.h b/Firmware/Drivers/DRV8301/drv8301.h index bdf9fa50..e3c3e3f3 100644 --- a/Firmware/Drivers/DRV8301/drv8301.h +++ b/Firmware/Drivers/DRV8301/drv8301.h @@ -412,8 +412,13 @@ typedef struct _DRV_SPI_8301_Vars_t_ DRV_SPI_8301_Stat2_t_ Stat_Reg_2; DRV_SPI_8301_CTRL1_t_ Ctrl_Reg_1; DRV_SPI_8301_CTRL2_t_ Ctrl_Reg_2; + uint16_t Stat_Reg_1_Value; + uint16_t Stat_Reg_2_Value; + uint16_t Ctrl_Reg_1_Value; + uint16_t Ctrl_Reg_2_Value; bool SndCmd; bool RcvCmd; + }DRV_SPI_8301_Vars_t; diff --git a/Firmware/MotorControl/commands.cpp b/Firmware/MotorControl/commands.cpp index 35e5651d..7c84e00c 100644 --- a/Firmware/MotorControl/commands.cpp +++ b/Firmware/MotorControl/commands.cpp @@ -131,6 +131,13 @@ const Endpoint endpoints[] = { Endpoint::make_property("Iq_measured", &motors[0].current_control.Iq_measured), Endpoint::make_property("Ibus", const_cast(&motors[0].current_control.Ibus)), Endpoint::close_tree(), + Endpoint::make_object("gate_driver"), + Endpoint::make_property("drv_error", reinterpret_cast(&motors[0].drv_fault)), + Endpoint::make_property("status_reg_1", (&motors[0].gate_driver_regs.Stat_Reg_1_Value)), + Endpoint::make_property("status_reg_2", (&motors[0].gate_driver_regs.Stat_Reg_2_Value)), + Endpoint::make_property("ctrl_reg_1", (&motors[0].gate_driver_regs.Ctrl_Reg_1_Value)), + Endpoint::make_property("ctrl_reg_2", (&motors[0].gate_driver_regs.Ctrl_Reg_2_Value)), + Endpoint::close_tree(), Endpoint::make_object("encoder"), Endpoint::make_property("phase", const_cast(&motors[0].encoder.phase)), Endpoint::make_property("pll_pos", &motors[0].encoder.pll_pos), @@ -188,6 +195,13 @@ const Endpoint endpoints[] = { Endpoint::make_property("Iq_measured", &motors[1].current_control.Iq_measured), Endpoint::make_property("Ibus", const_cast(&motors[1].current_control.Ibus)), Endpoint::close_tree(), + Endpoint::make_object("gate_driver"), + Endpoint::make_property("drv_error", reinterpret_cast(&motors[1].drv_fault)), + Endpoint::make_property("status_reg_1", (&motors[1].gate_driver_regs.Stat_Reg_1_Value)), + Endpoint::make_property("status_reg_2", (&motors[1].gate_driver_regs.Stat_Reg_2_Value)), + Endpoint::make_property("ctrl_reg_1", (&motors[1].gate_driver_regs.Ctrl_Reg_1_Value)), + Endpoint::make_property("ctrl_reg_2", (&motors[1].gate_driver_regs.Ctrl_Reg_2_Value)), + Endpoint::close_tree(), Endpoint::make_object("encoder"), Endpoint::make_property("phase", const_cast(&motors[1].encoder.phase)), Endpoint::make_property("pll_pos", &motors[1].encoder.pll_pos), diff --git a/Firmware/MotorControl/low_level.c b/Firmware/MotorControl/low_level.c index c49b95ea..d1e1dd66 100644 --- a/Firmware/MotorControl/low_level.c +++ b/Firmware/MotorControl/low_level.c @@ -34,7 +34,7 @@ float vbus_voltage = 12.0f; // TODO stick parameter into struct -#define ENCODER_CPR (2048 * 4) // Default resolution of CUI-AMT102 encoder +#define ENCODER_CPR (1000 * 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); @@ -59,6 +59,7 @@ Motor_t motors[] = { .enable_step_dir = false, //auto enabled after calibration .counts_per_step = 2.0f, .error = ERROR_NO_ERROR, + .drv_fault = DRV8301_FaultType_NoFault, .pos_setpoint = 0.0f, .pos_gain = 20.0f, // [(counts/s) / counts] .vel_setpoint = 0.0f, @@ -167,6 +168,7 @@ Motor_t motors[] = { .enable_step_dir = false, //auto enabled after calibration .counts_per_step = 2.0f, .error = ERROR_NO_ERROR, + .drv_fault = DRV8301_FaultType_NoFault, .pos_setpoint = 0.0f, .pos_gain = 20.0f, // [(counts/s) / counts] .vel_setpoint = 0.0f, @@ -1291,6 +1293,14 @@ void control_motor_loop(Motor_t* motor) { } if (check_DRV_fault(motor)) { motor->error = ERROR_DRV_FAULT; + + // Update DRV Fault Code + motor->drv_fault = DRV8301_getFaultType(&motor->gate_driver); + + // Update/Cache all SPI device registers + DRV_SPI_8301_Vars_t* local_regs = &motor->gate_driver_regs; + local_regs->RcvCmd = true; + DRV8301_readData(&motor->gate_driver, local_regs); break; } update_rotor(motor); diff --git a/Firmware/MotorControl/low_level.h b/Firmware/MotorControl/low_level.h index 9045b1d9..337c933c 100644 --- a/Firmware/MotorControl/low_level.h +++ b/Firmware/MotorControl/low_level.h @@ -137,6 +137,7 @@ typedef struct { bool enable_step_dir; float counts_per_step; Error_t error; + DRV8301_FaultType_e drv_fault; float pos_setpoint; float pos_gain; float vel_setpoint; diff --git a/Firmware/MotorControl/utils.c b/Firmware/MotorControl/utils.c index b6fbd0d5..032a996a 100644 --- a/Firmware/MotorControl/utils.c +++ b/Firmware/MotorControl/utils.c @@ -2,6 +2,7 @@ #include #include #include +#include static const float one_by_sqrt3 = 0.57735026919f; static const float two_by_sqrt3 = 1.15470053838f; @@ -183,3 +184,23 @@ uint32_t timeout_to_deadline(uint32_t timeout_ms) { uint32_t now_ms = (uint32_t)((1000ull * (uint64_t)osKernelSysTick()) / osKernelSysTickFrequency); return now_ms + timeout_ms; } + +// @brief: Returns number of microseconds since system startup +uint32_t micros(void) { + uint32_t usTicks = HAL_RCC_GetSysClockFreq() / 1000000; + register uint32_t ms, cycle_cnt; + do { + ms = HAL_GetTick(); + cycle_cnt = SysTick->VAL; + } while (ms != HAL_GetTick()); + return (ms * 1000) + (usTicks * 1000 - cycle_cnt) / usTicks; +} + +// @brief: Busy wait delay for given amount of microseconds (us) +void delay_us(uint32_t us) +{ + uint32_t start = micros(); + while (micros() - start < (uint32_t) us) { + __ASM("nop"); + } +} \ No newline at end of file diff --git a/Firmware/MotorControl/utils.h b/Firmware/MotorControl/utils.h index 92436b74..004d00cf 100644 --- a/Firmware/MotorControl/utils.h +++ b/Firmware/MotorControl/utils.h @@ -91,6 +91,10 @@ int mod(int dividend, int divisor); uint32_t deadline_to_timeout(uint32_t deadline_ms); uint32_t timeout_to_deadline(uint32_t timeout_ms); +uint32_t micros(void); + +void delay_us(uint32_t us); + #ifdef __cplusplus } #endif diff --git a/tools/drv_status.py b/tools/drv_status.py new file mode 100644 index 00000000..5f16575f --- /dev/null +++ b/tools/drv_status.py @@ -0,0 +1,28 @@ +#!/usr/bin/env python3 +""" +Example usage of the ODrive python library to monitor and control ODrive devices +""" + +from __future__ import print_function + +import odrive.core +import time +import math + +# Find a connected ODrive (this will block until you connect one) +my_drive = odrive.core.find_any(consider_usb=True, consider_serial=False, printer=print) + +# Print DRV device regs for Motor 0 +fault = my_drive.motor0.gate_driver.drv_error +status_reg_1 = my_drive.motor0.gate_driver.status_reg_1 +status_reg_2 = my_drive.motor0.gate_driver.status_reg_2 +ctrl_reg_1 = my_drive.motor0.gate_driver.ctrl_reg_1 +ctrl_reg_2 = my_drive.motor0.gate_driver.ctrl_reg_2 + +print("DRV Fault Code: " + str(fault)) +print("Status Reg 1: " + str(status_reg_1) + " (" + format(status_reg_1, '#010b') + ")") +print("Status Reg 2: " + str(status_reg_2) + " (" + format(status_reg_2, '#010b') + ")") +print("Control Reg 1: " + str(ctrl_reg_1) + " (" + format(ctrl_reg_1, '#010b') + ")") +print("Control Reg 2: " + str(ctrl_reg_2) + " (" + format(ctrl_reg_2, '#010b') + ")") + + From aee5398ba2e5f0188d99cfce880f36dafb3de951 Mon Sep 17 00:00:00 2001 From: Quincy Jones Date: Wed, 21 Feb 2018 13:46:47 -0600 Subject: [PATCH 06/53] Revert CPR back to default. Fix delay block times --- Firmware/Drivers/DRV8301/drv8301.c | 6 +++--- Firmware/MotorControl/low_level.c | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Firmware/Drivers/DRV8301/drv8301.c b/Firmware/Drivers/DRV8301/drv8301.c index 765d7d49..0e90a652 100644 --- a/Firmware/Drivers/DRV8301/drv8301.c +++ b/Firmware/Drivers/DRV8301/drv8301.c @@ -592,16 +592,16 @@ void DRV8301_writeSpi(DRV8301_Handle handle, const DRV8301_RegName_e regName,con { // Actuate chipselect HAL_GPIO_WritePin(handle->nCSgpioHandle, handle->nCSgpioNumber, GPIO_PIN_RESET); - delay_us(5); + delay_us(1); // Do blocking write uint16_t controlword = (uint16_t)DRV8301_buildCtrlWord(DRV8301_CtrlMode_Write, regName, data); HAL_SPI_Transmit(handle->spiHandle, (uint8_t*)(&controlword), 1, 1000); - delay_us(5); + delay_us(1); // Actuate chipselect HAL_GPIO_WritePin(handle->nCSgpioHandle, handle->nCSgpioNumber, GPIO_PIN_SET); - delay_us(5); + delay_us(1); return; } // end of DRV8301_writeSpi() function diff --git a/Firmware/MotorControl/low_level.c b/Firmware/MotorControl/low_level.c index d1e1dd66..280bc6bf 100644 --- a/Firmware/MotorControl/low_level.c +++ b/Firmware/MotorControl/low_level.c @@ -34,7 +34,7 @@ float vbus_voltage = 12.0f; // TODO stick parameter into struct -#define ENCODER_CPR (1000 * 4) // Default resolution of CUI-AMT102 encoder +#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); From f75799fd3ceb162ab2f4580ce57ec253a5791f7e Mon Sep 17 00:00:00 2001 From: Quincy Jones Date: Wed, 21 Feb 2018 14:23:12 -0600 Subject: [PATCH 07/53] Fix a naming bug on drv_error -> drv_fault --- Firmware/MotorControl/commands.cpp | 4 ++-- Firmware/MotorControl/low_level.h | 2 +- tools/drv_status.py | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Firmware/MotorControl/commands.cpp b/Firmware/MotorControl/commands.cpp index 7c84e00c..1e9d0117 100644 --- a/Firmware/MotorControl/commands.cpp +++ b/Firmware/MotorControl/commands.cpp @@ -132,7 +132,7 @@ const Endpoint endpoints[] = { Endpoint::make_property("Ibus", const_cast(&motors[0].current_control.Ibus)), Endpoint::close_tree(), Endpoint::make_object("gate_driver"), - Endpoint::make_property("drv_error", reinterpret_cast(&motors[0].drv_fault)), + Endpoint::make_property("drv_fault", reinterpret_cast(&motors[0].drv_fault)), Endpoint::make_property("status_reg_1", (&motors[0].gate_driver_regs.Stat_Reg_1_Value)), Endpoint::make_property("status_reg_2", (&motors[0].gate_driver_regs.Stat_Reg_2_Value)), Endpoint::make_property("ctrl_reg_1", (&motors[0].gate_driver_regs.Ctrl_Reg_1_Value)), @@ -196,7 +196,7 @@ const Endpoint endpoints[] = { Endpoint::make_property("Ibus", const_cast(&motors[1].current_control.Ibus)), Endpoint::close_tree(), Endpoint::make_object("gate_driver"), - Endpoint::make_property("drv_error", reinterpret_cast(&motors[1].drv_fault)), + Endpoint::make_property("drv_fault", reinterpret_cast(&motors[1].drv_fault)), Endpoint::make_property("status_reg_1", (&motors[1].gate_driver_regs.Stat_Reg_1_Value)), Endpoint::make_property("status_reg_2", (&motors[1].gate_driver_regs.Stat_Reg_2_Value)), Endpoint::make_property("ctrl_reg_1", (&motors[1].gate_driver_regs.Ctrl_Reg_1_Value)), diff --git a/Firmware/MotorControl/low_level.h b/Firmware/MotorControl/low_level.h index 337c933c..c0345a0f 100644 --- a/Firmware/MotorControl/low_level.h +++ b/Firmware/MotorControl/low_level.h @@ -137,7 +137,6 @@ typedef struct { bool enable_step_dir; float counts_per_step; Error_t error; - DRV8301_FaultType_e drv_fault; float pos_setpoint; float pos_gain; float vel_setpoint; @@ -187,6 +186,7 @@ typedef struct { float current_setpoint; } set_current_setpoint_args; Anticogging_t anticogging; + DRV8301_FaultType_e drv_fault; } Motor_t; typedef struct{ diff --git a/tools/drv_status.py b/tools/drv_status.py index 5f16575f..fda6c292 100644 --- a/tools/drv_status.py +++ b/tools/drv_status.py @@ -13,7 +13,7 @@ import math my_drive = odrive.core.find_any(consider_usb=True, consider_serial=False, printer=print) # Print DRV device regs for Motor 0 -fault = my_drive.motor0.gate_driver.drv_error +fault = my_drive.motor0.gate_driver.drv_fault status_reg_1 = my_drive.motor0.gate_driver.status_reg_1 status_reg_2 = my_drive.motor0.gate_driver.status_reg_2 ctrl_reg_1 = my_drive.motor0.gate_driver.ctrl_reg_1 From e87b2d4a410cd39710afe5e03ae3819ee99a0445 Mon Sep 17 00:00:00 2001 From: Quincy Jones Date: Wed, 21 Feb 2018 17:46:43 -0600 Subject: [PATCH 08/53] Update Changelog.md --- Firmware/CHANGELOG.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/Firmware/CHANGELOG.md b/Firmware/CHANGELOG.md index cd09a09d..4d6c5602 100644 --- a/Firmware/CHANGELOG.md +++ b/Firmware/CHANGELOG.md @@ -1,3 +1,10 @@ +## [0.3.4] - 2018-02-21 + +### Added +* Reporting of DRV status/control registers and fault codes +* DRV status read script +* Microsecond delay function + ## [0.3.3] - 2018-02-12 ### Added From 95d1d3ff0fa4b0edc3e24e8aaafb17aeaaa1855c Mon Sep 17 00:00:00 2001 From: Paul Guenette Date: Wed, 21 Feb 2018 18:46:51 -0500 Subject: [PATCH 09/53] Fix fabsf bracket, make variable names more descriptive --- Firmware/MotorControl/low_level.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Firmware/MotorControl/low_level.c b/Firmware/MotorControl/low_level.c index afc63053..f3624eef 100644 --- a/Firmware/MotorControl/low_level.c +++ b/Firmware/MotorControl/low_level.c @@ -793,9 +793,9 @@ bool calib_enc_offset(Motor_t* motor, float voltage_magnitude) { encvaluesum += (int16_t)motor->encoder.encoder_timer->Instance->CNT; } - float estEnc = scan_range / elec_rad_per_enc; - float adjustedCount = fabsf((int16_t)motor->encoder.encoder_timer->Instance->CNT)-init_enc_val; - if(fabsf(adjustedCount-estEnc)/estEnc > motor->encoder.encoder_calib_range) + float expected_encoder_delta = scan_range / elec_rad_per_enc; + float actual_encoder_delta_abs = fabsf((int16_t)motor->encoder.encoder_timer->Instance->CNT-init_enc_val); + if(fabsf(actual_encoder_delta_abs - expected_encoder_delta)/expected_encoder_delta > motor->encoder.encoder_calib_range) { motor->error = ERROR_ENCODER_CPR_OUT_OF_RANGE; return false; From 48cbcc7d37d0446098dca26fa595bb5acc1637a9 Mon Sep 17 00:00:00 2001 From: Paul Guenette Date: Wed, 21 Feb 2018 20:41:00 -0500 Subject: [PATCH 10/53] Add usb command for anticogging --- Firmware/MotorControl/commands.cpp | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/Firmware/MotorControl/commands.cpp b/Firmware/MotorControl/commands.cpp index 35e5651d..3ffc70b8 100644 --- a/Firmware/MotorControl/commands.cpp +++ b/Firmware/MotorControl/commands.cpp @@ -87,6 +87,14 @@ void motors_1_set_current_setpoint_func(void) { set_current_setpoint(&motors[1], motors[1].set_current_setpoint_args.current_setpoint); } +void motors_run_anticogging_calibration_func() { + for (uint8_t i = 0; i < num_motors; i++) { + // Ensure the cogging map was correctly allocated earlier and that the motor is capable of calibrating + if (motors[i].anticogging.cogging_map != NULL && motors[i].error == ERROR_NO_ERROR) { + motors[i].anticogging.calib_anticogging = true; + } + } +} // This table specifies which fields and functions are exposed on the USB and UART ports. // TODO: Autogenerate this table. It will come up again very soon in the Arduino library. @@ -97,6 +105,9 @@ const Endpoint endpoints[] = { 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)), + Endpoint::make_function("run_anticogging_calibration", &motors_run_anticogging_calibration_func), + // No parameters, but still requires a close_tree() + Endpoint::close_tree(), Endpoint::make_object("motor0"), Endpoint::make_property("control_mode", reinterpret_cast(&motors[0].control_mode)), Endpoint::make_property("error", reinterpret_cast(&motors[0].error)), From eea847545829791f3c05916adecc012a849d8f3c Mon Sep 17 00:00:00 2001 From: Samuel Sadok Date: Mon, 20 Nov 2017 20:59:49 +0100 Subject: [PATCH 11/53] Add low level non-volatile memory implementation --- Firmware/Makefile | 1 + Firmware/MotorControl/nvm.c | 444 ++++++++++++++++++++++++++++++++ Firmware/MotorControl/nvm.h | 33 +++ Firmware/STM32F405RGTx_FLASH.ld | 5 +- 4 files changed, 481 insertions(+), 2 deletions(-) create mode 100644 Firmware/MotorControl/nvm.c create mode 100644 Firmware/MotorControl/nvm.h diff --git a/Firmware/Makefile b/Firmware/Makefile index 3ad6d167..811fb1e9 100644 --- a/Firmware/Makefile +++ b/Firmware/Makefile @@ -81,6 +81,7 @@ C_SOURCES = \ Src/syscalls.c \ MotorControl/utils.c \ MotorControl/legacy_commands.c \ + MotorControl/nvm.c \ MotorControl/low_level.c CPP_SOURCES = \ MotorControl/axis.cpp \ diff --git a/Firmware/MotorControl/nvm.c b/Firmware/MotorControl/nvm.c new file mode 100644 index 00000000..2ee998f0 --- /dev/null +++ b/Firmware/MotorControl/nvm.c @@ -0,0 +1,444 @@ +/* +* Flash-based Non-Volatile Memory (NVM) +* +* This file supports storing and loading persistent configuration based on +* the STM32 builtin flash memory. +* +* The STM32F405xx has 12 flash sectors of heterogeneous size. We use the last +* two sectors for configuration data. These pages have a size of 128kB each. +* 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). +* +* 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 +* 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 +* fields as "valid" (in the direction of increasing address). +*/ + +#include "nvm.h" + +#include +#include +#include + +#if defined(STM32F405xx) +#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 +#define FLASH_SECTOR_11_SIZE 0x20000UL + +#define HAL_FLASH_ClearError() __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP | FLASH_FLAG_OPERR | FLASH_FLAG_WRPERR | FLASH_FLAG_PGAERR | FLASH_FLAG_PGSERR | FLASH_FLAG_PGPERR) +#else +#error "unknown flash sector size" +#endif + +typedef enum { + VALID = 0, + INVALID = 1, + ERASED = 3 +} field_state_t; + +typedef struct { + size_t index; //!< next field to be written to (can be equal to n_data) + const uint32_t sector_id; //!< HAL ID of this sector + const size_t n_data; //!< number of 64-bit fields in this sector + const size_t n_reserved; //!< number of 64-bit fields in this sector that are reserved for the allocation table + const volatile uint8_t* const alloc_table; + const volatile uint64_t* const data; +} sector_t; + +sector_t sectors[] = { { + .sector_id = FLASH_SECTOR_10, + .n_data = FLASH_SECTOR_10_SIZE >> 3, + .n_reserved = (FLASH_SECTOR_10_SIZE >> 3) >> 5, + .alloc_table = FLASH_SECTOR_10_BASE, + .data = (uint64_t *)FLASH_SECTOR_10_BASE +}, { + .sector_id = FLASH_SECTOR_11, + .n_data = FLASH_SECTOR_11_SIZE >> 3, + .n_reserved = (FLASH_SECTOR_11_SIZE >> 3) >> 5, + .alloc_table = FLASH_SECTOR_11_BASE, + .data = (uint64_t *)FLASH_SECTOR_11_BASE +}}; + +uint8_t read_sector_; // 0 or 1 to indicate which sector to read from and which to write to +size_t n_staging_area_; // number of 64-bit values that were reserved using NVM_start_write +size_t n_valid_; // number of 64-bit fields that can be read + +// @brief Erases a flash sector. This sets all bits in the sector to 1. +// The sector's current index is reset to the minimum value (n_reserved). +// @returns 0 on success or a non-zero error code otherwise +int erase(sector_t *sector) { + FLASH_EraseInitTypeDef erase_struct = { + .TypeErase = FLASH_TYPEERASE_SECTORS, + .Banks = 0, // only used for mass erase + .Sector = sector->sector_id, + .NbSectors = 1, + .VoltageRange = FLASH_VOLTAGE_RANGE_3 + }; + HAL_FLASH_Unlock(); + HAL_FLASH_ClearError(); + uint32_t sector_error; + if (HAL_FLASHEx_Erase(&erase_struct, §or_error) != HAL_OK) + goto fail; + sector->index = sector->n_reserved; + + HAL_FLASH_Lock(); + return 0; +fail: + HAL_FLASH_Lock(); + //printf("erase failed: %u \r\n", HAL_FLASH_GetError()); + return HAL_FLASH_GetError(); // non-zero +} + + +// @brief Writes states into the allocation table. +// The write operation goes in the direction of increasing indices. +// @param state: 11: erased, 10: writing, 00: valid data +// @returns 0 on success or a non-zero error code otherwise +int set_allocation_state(sector_t *sector, size_t index, size_t count, field_state_t state) { + if (index < sector->n_reserved) + return -1; + if (index + count >= sector->n_data) + return -1; + + // expand state to state for 4 values + const uint8_t states = (state << 0) | (state << 2) | (state << 4) | (state << 6); + + // handle unaligned start + uint8_t mask = ~(0xff << ((index & 0x3) << 1)); + count += index & 0x3; + index -= index & 0x3; + + HAL_FLASH_Unlock(); + HAL_FLASH_ClearError(); + + // write states + for (; count >= 4; count -= 4, index += 4) { + if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_BYTE, (uintptr_t)§or->alloc_table[index >> 2], states | mask) != HAL_OK) + goto fail; + mask = 0; + } + + // handle unaligned end + if (count) { + mask |= ~(0xff >> ((4 - count) << 1)); + if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_BYTE, (uintptr_t)§or->alloc_table[index >> 2], states | mask) != HAL_OK) + goto fail; + } + + HAL_FLASH_Lock(); + return 0; +fail: + HAL_FLASH_Lock(); + return HAL_FLASH_GetError(); // non-zero +} + +// @brief Reads the allocation table from behind to determine how many fields match the +// reference state. +// @param sector: The sector on which to perform the search +// @param max_index: The maximum index that should be considered +// @param ref_state: The reference state +// @param state: Set to the first encountered state that is unequal to ref_state. +// Set to ref_state if all encountered states are equal to ref_state. +// @returns The smallest index that points to a field with ref_state. +// This value is at least sector->n_reserved and at most max_index. +size_t scan_allocation_table(sector_t *sector, size_t max_index, field_state_t ref_state, field_state_t *state) { + const uint8_t ref_states = (ref_state << 0) | (ref_state << 2) | (ref_state << 4) | (ref_state << 6); + size_t index = (((max_index + 3) >> 2) << 2); // start at the max index but round up to a multiple of 4 + size_t ignore = index - max_index; + uint8_t states = ref_states; + + //printf("scan from %08x to %08x for %02x\r\n", index, sector->n_reserved, ref_states); osDelay(5); + + // read 4 states at a time + for (; index >= (sector->n_reserved + 4); index -= 4) { + states = sector->alloc_table[(index - 1) >> 2]; + if (ignore) { // ignore the upper 1, 2 or 3 states if max_index was unaligned + uint8_t ignore_mask = ~(0xff >> (ignore << 1)); + states = (states & ~ignore_mask) | (ref_states & ignore_mask); + ignore = 0; + } + if (states != ref_states) + break; + } + + // once we encounterd a byte with any state mismatch determine which of the 4 states it is + for (; ((states >> 6) == (ref_states & 0x3)) && (index > sector->n_reserved); index--) { + states <<= 2; + } + + *state = states >> 6; + //printf("(it's %02x)\r\n", index); osDelay(5); + return index; +} + +// Loads the head of the NVM data. +// If this function fails subsequent calls to NVM functions (other than NVM_init or NVM_erase) +// cause undefined behavior. +// @returns 0 on success or a non-zero error code otherwise +int NVM_init(void) { + field_state_t sector0_state, sector1_state; + sectors[0].index = scan_allocation_table(§ors[0], sectors[0].n_data, + ERASED, §or0_state); + sectors[1].index = scan_allocation_table(§ors[1], sectors[1].n_data, + ERASED, §or1_state); + //printf("sector states: %02x, %02x\r\n", sector0_state, sector1_state); osDelay(5); + + // Select valid sector on a best effort basis + // (in unfortunate cases valid_sector might actually point + // to an invalid or erased sector) + read_sector_ = 0; + if (sector1_state == VALID) + read_sector_ = 1; + + // count the number of valid fields + sector_t *read_sector = §ors[read_sector_]; + uint8_t first_nonvalid_state; + size_t min_valid_index = scan_allocation_table(read_sector, read_sector->index, + VALID, &first_nonvalid_state); + n_valid_ = read_sector->index - min_valid_index; + + n_staging_area_ = 0; + + int status = 0; + /*// bring non-valid sectors into a known state + this is not absolutely required + if (sector0_state != VALID) + status |= erase(§ors[0]); + if (sector1_state != VALID) + status |= erase(§ors[1]); + */ + return status; +} + +// @brief Erases all data in the NVM. +// +// If this function fails subsequent calls to NVM functions (other than NVM_init or NVM_erase) +// cause undefined behavior. +// Caution: this function may take a long time (like 1 second) +// +// @returns 0 on success or a non-zero error code otherwise +int NVM_erase(void) { + read_sector_ = 0; + sectors[0].index = sectors[0].n_reserved; + sectors[1].index = sectors[1].n_reserved; + + int state = 0; + state |= erase(§ors[0]); + state |= erase(§ors[1]); + return state; +} + +// @brief Returns the maximum number of bytes that can be read using NVM_read. +// This holds until NVM_commit is called. +size_t NVM_get_max_read_length(void) { + return n_valid_ << 3; +} + +// @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; +} + +// @brief Reads from the latest committed block in the non-volatile memory. +// @param offset: offset in bytes (0 meaning the beginning of the valid area) +// @param data: buffer to write to +// @param length: length in bytes (if (offset + length) is out of range, the function fails) +// @returns 0 on success or a non-zero error code otherwise +int NVM_read(size_t offset, uint8_t *data, size_t length) { + if (offset + length > (n_valid_ << 3)) + return -1; + sector_t *read_sector = §ors[read_sector_]; + const uint8_t *src_ptr = ((const uint8_t *)&read_sector->data[read_sector->index - n_valid_]) + offset; + memcpy(data, src_ptr, length); + return 0; +} + +// @brief Starts an atomic write operation. The length must be at most equal to the size. +// +// 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(). +// +// @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_]; + + length = (length + 7) >> 3; // round to multiple of 64 bit + if (length > victim->n_data - victim->n_reserved) + return -1; + + // make room for the new data + if (length > victim->n_data - victim->index) + if ((status = erase(victim))) + return status; + + // invalidate the fields we're about to write + status = set_allocation_state(victim, victim->index, length, INVALID); + if (status) + return status; + + n_staging_area_ = length; + return 0; +} + +// @brief Writes to the current data block that was opened with NVM_start_write. +// +// The operation fails if (offset + length) is larger than the length passed to NVM_start_write. +// The most recent valid NVM data is not modified or invalidated until NVM_commit is called. +// +// @param offset: The offset in bytes, 0 being the beginning of the staging block. +// @param data: Pointer to the data that should be written +// @param length: Data length in bytes +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_]; + + HAL_FLASH_Unlock(); + HAL_FLASH_ClearError(); + + // 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) + 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) + 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) + goto fail; + + HAL_FLASH_Lock(); + return 0; +fail: + HAL_FLASH_Lock(); + return HAL_FLASH_GetError(); // non-zero +} + +// @brief Commits the new data to NVM atomically. +int NVM_commit(void) { + sector_t *read_sector = §ors[read_sector_]; + sector_t *write_sector = §ors[1 - read_sector_]; + + // mark the newly-written fields as valid + int status = set_allocation_state(write_sector, write_sector->index, n_staging_area_, VALID); + if (status) + return status; + + write_sector->index += n_staging_area_; + n_valid_ = n_staging_area_; + n_staging_area_ = 0; + read_sector_ = 1 - read_sector_; + + // invalidate the other sector + if (read_sector->index < read_sector->n_data) + status = set_allocation_state(read_sector, read_sector->index, 1, INVALID); + else + status = erase(read_sector); + if (status) + return status; + return 0; +} + + +#include +/** @brief Call this at startup to test/demo the NVM driver + + Expected output when starting with a fully erased NVM + + [1st boot] + === NVM TEST === + NVM is empty + write 0x00, ..., 0x25 to NVM + new data committed to NVM + + [2nd boot] + === NVM TEST === + NVM contains 40 valid bytes: + 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f + 10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f + 20 21 22 23 24 25 ff ff + write 0xbd, ..., 0xe2 to NVM + new data committed to NVM + + [3rd boot] + === NVM TEST === + NVM contains 40 valid bytes: + bd be bf c0 c1 c2 c3 c4 c5 c6 c7 c8 c9 ca cb cc + cd ce cf d0 d1 d2 d3 d4 d5 d6 d7 d8 d9 da db dc + dd de df e0 e1 e2 ff ff + write 0xcb, ..., 0xf0 to NVM + new data committed to NVM +*/ +void NVM_demo(void) { + const size_t len = 38; + uint8_t data[len]; + int progress = 0; + uint8_t seed = 0; + + osDelay(100); + printf("=== NVM TEST ===\r\n"); osDelay(5); + //NVM_erase(); + if (progress++, NVM_init() != 0) + goto fail; + + // load bytes from NVM and print them + size_t available = NVM_get_max_read_length(); + if (available) { + printf("NVM contains %d valid bytes:\r\n", available); osDelay(5); + uint8_t buf[available]; + if (progress++, NVM_read(0, buf, available) != 0) + goto fail; + for (size_t pos = 0; pos < available; ++pos) { + seed += buf[pos]; + printf(" %02x", buf[pos]); + if ((((pos + 1) % 16) == 0) || ((pos + 1) == available)) + printf("\r\n"); + osDelay(2); + } + } else { + printf("NVM is empty\r\n"); osDelay(5); + } + + // store new bytes in NVM (data based on seed) + printf("write 0x%02x, ..., 0x%02x to NVM\r\n", seed, seed + len - 1); osDelay(5); + for (size_t i = 0; i < len; i++) + data[i] = seed++; + if (progress++, NVM_start_write(len) != 0) + goto fail; + if (progress++, NVM_write(0, data, len / 2)) + goto fail; + if (progress++, NVM_write(len / 2, &data[len / 2], len - (len / 2))) + goto fail; + if (progress++, NVM_commit()) + goto fail; + printf("new data committed to NVM\r\n"); osDelay(5); + + return; + +fail: + printf("NVM test failed at %d!\r\n", progress); +} diff --git a/Firmware/MotorControl/nvm.h b/Firmware/MotorControl/nvm.h new file mode 100644 index 00000000..efffa174 --- /dev/null +++ b/Firmware/MotorControl/nvm.h @@ -0,0 +1,33 @@ +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __NVML_H +#define __NVM_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include +#include + +/* Exported types ------------------------------------------------------------*/ +/* Exported constants --------------------------------------------------------*/ +/* Exported variables --------------------------------------------------------*/ +/* Exported macro ------------------------------------------------------------*/ +/* Exported functions --------------------------------------------------------*/ + +int NVM_init(void); +int NVM_erase(void); +size_t NVM_get_max_read_length(void); +size_t NVM_get_max_write_length(void); +int NVM_read(size_t offset, uint8_t *data, size_t length); +int NVM_start_write(size_t length); +int NVM_write(size_t offset, uint8_t *data, size_t length); +int NVM_commit(void); +void NVM_demo(void); + +#ifdef __cplusplus +} +#endif + +#endif //__NVM_H \ No newline at end of file diff --git a/Firmware/STM32F405RGTx_FLASH.ld b/Firmware/STM32F405RGTx_FLASH.ld index 2685ffab..efd7949c 100644 --- a/Firmware/STM32F405RGTx_FLASH.ld +++ b/Firmware/STM32F405RGTx_FLASH.ld @@ -43,7 +43,8 @@ MEMORY { RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 128K CCMRAM (rw) : ORIGIN = 0x10000000, LENGTH = 64K -FLASH (rx) : ORIGIN = 0x8000000, LENGTH = 1024K +FLASH (rx) : ORIGIN = 0x8000000, LENGTH = 768K +NVM (r) : ORIGIN = 0x80C0000, LENGTH = 256K } /* Define output sections */ @@ -173,7 +174,7 @@ SECTIONS . = ALIGN(8); } >RAM - + /* Remove information from the standard libraries */ /DISCARD/ : From b672d8e0ef620efed31bcb81e0d0450cefb61151 Mon Sep 17 00:00:00 2001 From: Samuel Sadok Date: Mon, 27 Nov 2017 19:07:27 +0100 Subject: [PATCH 12/53] Add persistent storage of certain motor parameters. The persistent storage can be controlled through the "save_config" and "reset" RPC functions. If a valid configuration is present, it's automatically loaded on startup. For now only a few parameters are saved (see config.cpp). --- Firmware/Makefile | 1 + Firmware/MotorControl/commands.cpp | 9 +- Firmware/MotorControl/config.cpp | 231 +++++++++++++++++++++++++++++ Firmware/MotorControl/config.h | 16 ++ Firmware/MotorControl/low_level.c | 83 ----------- Firmware/MotorControl/nvm.c | 2 + Firmware/STM32F405RGTx_FLASH.ld | 2 +- Firmware/Src/freertos.c | 4 + 8 files changed, 263 insertions(+), 85 deletions(-) create mode 100644 Firmware/MotorControl/config.cpp create mode 100644 Firmware/MotorControl/config.h diff --git a/Firmware/Makefile b/Firmware/Makefile index 811fb1e9..00765992 100644 --- a/Firmware/Makefile +++ b/Firmware/Makefile @@ -85,6 +85,7 @@ C_SOURCES = \ MotorControl/low_level.c CPP_SOURCES = \ MotorControl/axis.cpp \ + MotorControl/config.cpp \ MotorControl/commands.cpp \ MotorControl/protocol.cpp ASM_SOURCES = \ diff --git a/Firmware/MotorControl/commands.cpp b/Firmware/MotorControl/commands.cpp index 35e5651d..7ab94b06 100644 --- a/Firmware/MotorControl/commands.cpp +++ b/Firmware/MotorControl/commands.cpp @@ -11,6 +11,7 @@ #include "protocol.hpp" #include "freertos_vars.h" #include "utils.h" +#include "config.h" #ifdef ENABLE_LEGACY_PROTOCOL #include "legacy_commands.h" @@ -210,7 +211,13 @@ const Endpoint endpoints[] = { Endpoint::make_function("set_current_setpoint", &motors_1_set_current_setpoint_func), Endpoint::make_property("current_setpoint", &motors[1].set_current_setpoint_args.current_setpoint), Endpoint::close_tree(), - Endpoint::close_tree() // motor1 + Endpoint::close_tree(), // motor1 + Endpoint::make_function("save_config", &save_configuration), + // no arguments + Endpoint::close_tree(), + Endpoint::make_function("reset", &reset), + // no arguments + Endpoint::close_tree() }; // clang-format on diff --git a/Firmware/MotorControl/config.cpp b/Firmware/MotorControl/config.cpp new file mode 100644 index 00000000..57efec31 --- /dev/null +++ b/Firmware/MotorControl/config.cpp @@ -0,0 +1,231 @@ + +/* Includes ------------------------------------------------------------------*/ + +#include "config.h" + +#include +#include +#include + +#include "nvm.h" +#include "crc.hpp" +#include "low_level.h" + +/* 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; +} MotorConfig_t; + +/* Global constant data ------------------------------------------------------*/ +/* Global variables ----------------------------------------------------------*/ +/* Private constant data -----------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ +/* Function implementations --------------------------------------------------*/ + +template +struct Config; + +template<> +struct Config<> { + static size_t get_size() { + return 0; + } + static int load_config(size_t offset, uint16_t* crc16) { + return 0; + } + static int store_config(size_t offset, uint16_t* crc16) { + return 0; + } +}; + +template +struct Config { + static size_t get_size() { + return sizeof(T) + Config::get_size(); + } + + static int load_config(size_t offset, uint16_t* crc16, T* val0, Ts* ... vals) { + size_t size = sizeof(T); + // save current CRC (in case val0 and crc16 point to the same address) + size_t previous_crc16 = *crc16; + if (NVM_read(offset, (uint8_t *)val0, size)) + return -1; + *crc16 = calc_crc16(previous_crc16, (uint8_t *)val0, size); + if (Config::load_config(offset + size, crc16, vals...)) + return -1; + return 0; + } + + static int store_config(size_t offset, uint16_t* crc16, T* val0, Ts* ... vals) { + size_t size = sizeof(T); + if (NVM_write(offset, (uint8_t *)val0, size)) + return -1; + // update CRC _after_ writing (in case val0 and crc16 point to the same address) + if (crc16) + *crc16 = calc_crc16(*crc16, (uint8_t *)val0, size); + if (Config::store_config(offset + size, crc16, vals...)) + return -1; + return 0; + } + + static int load_config(T* val0, Ts* ... vals) { + //printf("have %d bytes\r\n", NVM_get_max_read_length()); osDelay(5); + if (Config::get_size() > NVM_get_max_read_length()) + return -1; + uint16_t crc16 = CRC16_INIT; + if (Config::load_config(0, &crc16, val0, vals..., &crc16)) + return -1; + if (crc16) + return -1; + return 0; + } + + static int store_config(T* val0, 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()) + return -1; + if (NVM_start_write(size)) + return -1; + uint16_t crc16 = CRC16_INIT; + if (Config::store_config(0, &crc16, val0, vals...)) + return -1; + if (Config::store_config(size - 2, nullptr, (uint8_t *)&crc16 + 1, (uint8_t *)&crc16)) + return -1; + if (NVM_commit()) + return -1; + return 0; + } +}; + +// 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) { + 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->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; +} + +// 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) { + 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->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; +} + + +void init_configuration(void) { + MotorConfig_t motor_config[2]; + 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(); + } else { + //printf("load config successful\r\n"); osDelay(5); + } + + set_motor_config(&motor_config[0], &motors[0]); + set_motor_config(&motor_config[1], &motors[1]); +} + +void save_configuration(void) { + MotorConfig_t motor_config[2]; + get_motor_config(&motors[0], &motor_config[0]); + get_motor_config(&motors[1], &motor_config[1]); + if (Config::store_config(&motor_config[0], &motor_config[1])) { + //printf("saving configuration failed\r\n"); osDelay(5); + } +} + +void reset(void) { + NVM_erase(); + NVIC_SystemReset(); +} diff --git a/Firmware/MotorControl/config.h b/Firmware/MotorControl/config.h new file mode 100644 index 00000000..2bd6556b --- /dev/null +++ b/Firmware/MotorControl/config.h @@ -0,0 +1,16 @@ +#ifndef __CONFIG_H +#define __CONFIG_H + +#ifdef __cplusplus +extern "C" { +#endif + +void init_configuration(void); +void save_configuration(void); +void reset(void); + +#ifdef __cplusplus +} +#endif + +#endif /* __CONFIG_H */ diff --git a/Firmware/MotorControl/low_level.c b/Firmware/MotorControl/low_level.c index 96826b0d..02b9c692 100644 --- a/Firmware/MotorControl/low_level.c +++ b/Firmware/MotorControl/low_level.c @@ -38,13 +38,6 @@ float vbus_voltage = 12.0f; #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 @@ -55,25 +48,7 @@ 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, - .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, @@ -96,29 +71,6 @@ 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, @@ -163,22 +115,7 @@ 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, - .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, @@ -201,26 +138,6 @@ 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, diff --git a/Firmware/MotorControl/nvm.c b/Firmware/MotorControl/nvm.c index 2ee998f0..c3bc1b6e 100644 --- a/Firmware/MotorControl/nvm.c +++ b/Firmware/MotorControl/nvm.c @@ -301,6 +301,8 @@ int NVM_start_write(size_t length) { // // The operation fails if (offset + length) is larger than the length passed to NVM_start_write. // The most recent valid NVM data is not modified or invalidated until NVM_commit is called. +// Warning: Writing different data to the same area multiple times during a single transaction +// will cause data corruption. // // @param offset: The offset in bytes, 0 being the beginning of the staging block. // @param data: Pointer to the data that should be written diff --git a/Firmware/STM32F405RGTx_FLASH.ld b/Firmware/STM32F405RGTx_FLASH.ld index efd7949c..3b96fa83 100644 --- a/Firmware/STM32F405RGTx_FLASH.ld +++ b/Firmware/STM32F405RGTx_FLASH.ld @@ -174,7 +174,7 @@ SECTIONS . = ALIGN(8); } >RAM - + /* Remove information from the standard libraries */ /DISCARD/ : diff --git a/Firmware/Src/freertos.c b/Firmware/Src/freertos.c index 9e136bd6..7794558c 100644 --- a/Firmware/Src/freertos.c +++ b/Firmware/Src/freertos.c @@ -56,6 +56,7 @@ #include "low_level.h" #include "axis_c_interface.h" #include "commands.h" +#include "config.h" /* USER CODE END Includes */ /* Variables -----------------------------------------------------------------*/ @@ -141,6 +142,9 @@ void StartDefaultTask(void const * argument) /* USER CODE BEGIN StartDefaultTask */ + // Init and load persistent configuration + init_configuration(); + // Init communications init_communication(); From d558e40513d61b5f7a1593aa5a4ca0cc342741e0 Mon Sep 17 00:00:00 2001 From: Samuel Sadok Date: Mon, 4 Dec 2017 11:19:25 +0100 Subject: [PATCH 13/53] add reference to datasheet --- Firmware/MotorControl/nvm.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Firmware/MotorControl/nvm.c b/Firmware/MotorControl/nvm.c index c3bc1b6e..4d9c843a 100644 --- a/Firmware/MotorControl/nvm.c +++ b/Firmware/MotorControl/nvm.c @@ -34,6 +34,9 @@ #include #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 #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 From c200bf495ea88d77e0ec388ee49d68a0de5c9dc2 Mon Sep 17 00:00:00 2001 From: Samuel Sadok Date: Thu, 22 Feb 2018 19:30:51 -0800 Subject: [PATCH 14/53] add note about firmware update --- Firmware/MotorControl/config.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Firmware/MotorControl/config.cpp b/Firmware/MotorControl/config.cpp index 57efec31..f3991f3f 100644 --- a/Firmware/MotorControl/config.cpp +++ b/Firmware/MotorControl/config.cpp @@ -139,7 +139,7 @@ struct Config { return -1; if (NVM_start_write(size)) return -1; - uint16_t crc16 = CRC16_INIT; + uint16_t crc16 = CRC16_INIT; // TODO: this is not a sufficient method to protect against changes of the struct signature if (Config::store_config(0, &crc16, val0, vals...)) return -1; if (Config::store_config(size - 2, nullptr, (uint8_t *)&crc16 + 1, (uint8_t *)&crc16)) From 430e4088754e76843da96579060aee9d8c762fe3 Mon Sep 17 00:00:00 2001 From: Oskar Weigl Date: Fri, 23 Feb 2018 12:48:27 -0800 Subject: [PATCH 15/53] default calib speed a bit faster --- Firmware/MotorControl/low_level.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Firmware/MotorControl/low_level.c b/Firmware/MotorControl/low_level.c index f3624eef..40ac40ad 100644 --- a/Firmware/MotorControl/low_level.c +++ b/Firmware/MotorControl/low_level.c @@ -762,7 +762,7 @@ bool measure_phase_inductance(Motor_t* motor, float voltage_low, float voltage_h // TODO: add check_timing bool calib_enc_offset(Motor_t* motor, float voltage_magnitude) { static const float start_lock_duration = 1.0f; - static const int num_steps = 1024*4; + static const int num_steps = 1024*2; static const float dt_step = 1.0f / 500.0f; static const float scan_range = 16.0f * M_PI; const float step_size = scan_range / (float)num_steps; // TODO handle const expressions better (maybe switch to C++ ?) From dea9df65badb736d339717e7bf4477dfd21b14d4 Mon Sep 17 00:00:00 2001 From: Oskar Weigl Date: Fri, 23 Feb 2018 12:57:58 -0800 Subject: [PATCH 16/53] update CHANGELOG.md --- Firmware/CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/Firmware/CHANGELOG.md b/Firmware/CHANGELOG.md index 2247daf8..9c2fb38d 100644 --- a/Firmware/CHANGELOG.md +++ b/Firmware/CHANGELOG.md @@ -2,6 +2,7 @@ Please add a note of your changes below this heading if you make a PR ### Added +* Reporting error if your encoder CPR is incorrect * Reporting of DRV status/control registers and fault codes * DRV status read script * Microsecond delay function From 4801c4a8b5b197d07db690d001aee61104c28ea7 Mon Sep 17 00:00:00 2001 From: Oskar Weigl Date: Fri, 23 Feb 2018 13:05:49 -0800 Subject: [PATCH 17/53] add psu brownout check to do_checks --- Firmware/MotorControl/low_level.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/Firmware/MotorControl/low_level.c b/Firmware/MotorControl/low_level.c index 263fdf79..88014cd9 100644 --- a/Firmware/MotorControl/low_level.c +++ b/Firmware/MotorControl/low_level.c @@ -1324,16 +1324,13 @@ bool check_DRV_fault(Motor_t* motor) { //Returns true if everything is OK (no fault) bool check_PSU_brownout(Motor_t* motor) { - if(vbus_voltage < motor->dc_bus_brownout_trip_level) { - motor->error = ERROR_DC_BUS_BROWNOUT; + if(vbus_voltage < motor->dc_bus_brownout_trip_level) return false; - } return true; } // Returns true if everything is ok. Sets motor->error and returns false otherwise. bool do_checks(Motor_t* motor) { - // Checks if (!check_DRV_fault(motor)) { motor->error = ERROR_DRV_FAULT; // Update DRV Fault Code @@ -1344,6 +1341,10 @@ bool do_checks(Motor_t* motor) { DRV8301_readData(&motor->gate_driver, local_regs); return false; } + if (!check_PSU_brownout(motor)) { + motor->error = ERROR_DC_BUS_BROWNOUT; + return false; + } return true; } From 12c72cf284a5f59621a3b4870b4fd610ab57118c Mon Sep 17 00:00:00 2001 From: Oskar Weigl Date: Fri, 23 Feb 2018 23:36:46 -0800 Subject: [PATCH 18/53] 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; } From 368b4d5cbb1c4ffa254542b450aaef34ef4ec322 Mon Sep 17 00:00:00 2001 From: Oskar Weigl Date: Sat, 24 Feb 2018 00:24:47 -0800 Subject: [PATCH 19/53] add axis to config --- Firmware/MotorControl/axis.cpp | 10 ++++++---- Firmware/MotorControl/axis.h | 5 ++++- Firmware/MotorControl/config.cpp | 7 +++++-- 3 files changed, 15 insertions(+), 7 deletions(-) diff --git a/Firmware/MotorControl/axis.cpp b/Firmware/MotorControl/axis.cpp index aaac53b5..266e8f68 100644 --- a/Firmware/MotorControl/axis.cpp +++ b/Firmware/MotorControl/axis.cpp @@ -8,6 +8,9 @@ extern "C" { #include "low_level.h" } +//TODO: Make it really clear where this is loaded. +AxisConfig axis_configs[2]; //TODO: get a constexpr for num motors + // C interface extern "C" { void axis_thread_entry(void const* temp_motor_ptr) { @@ -19,9 +22,7 @@ void axis_thread_entry(void const* temp_motor_ptr) { while (&motors[ax_number] != motor) ++ax_number; - static const AxisConfig default_config; - - Axis axis(default_config, ax_number, motor); + Axis axis(axis_configs[ax_number], ax_number, motor); axis.StateMachineLoop(); } } // extern "C" @@ -36,10 +37,11 @@ void Axis::SetupLegacyMappings() { exposed_bools[4 * axis_number_ + 2] = &do_calibration_; } -Axis::Axis(const AxisConfig& config, uint8_t axis_number, Motor_t* legacy_motor_ref) +Axis::Axis(AxisConfig& config, uint8_t axis_number, Motor_t* legacy_motor_ref) : axis_number_(axis_number), enable_control_(config.enable_control_at_start), do_calibration_(config.do_calibration_at_start), + config_(config), legacy_motor_ref_(legacy_motor_ref) { SetupLegacyMappings(); } diff --git a/Firmware/MotorControl/axis.h b/Firmware/MotorControl/axis.h index b3cdf543..455515b1 100644 --- a/Firmware/MotorControl/axis.h +++ b/Firmware/MotorControl/axis.h @@ -15,6 +15,7 @@ struct AxisConfig { bool enable_control_at_start = true; bool do_calibration_at_start = true; }; +extern AxisConfig axis_configs[]; class Axis { public: @@ -40,7 +41,7 @@ public: //step/dir handler // Object operation requires ptr to legacy object for now, TODO: get rid of this dep - Axis(const AxisConfig& config, uint8_t axis_number, Motor_t* legacy_motor_ref); + Axis(AxisConfig& config, uint8_t axis_number, Motor_t* legacy_motor_ref); // Infinite loop that does calibration and enters main control loop as appropriate void StateMachineLoop(); @@ -50,6 +51,8 @@ public: bool enable_control_; bool do_calibration_; + AxisConfig& config_; + Motor_t* legacy_motor_ref_; private: diff --git a/Firmware/MotorControl/config.cpp b/Firmware/MotorControl/config.cpp index 63ef8fe4..f7528509 100644 --- a/Firmware/MotorControl/config.cpp +++ b/Firmware/MotorControl/config.cpp @@ -10,6 +10,7 @@ #include "nvm.h" #include "crc.hpp" #include "low_level.h" +#include "axis.h" /* Private defines -----------------------------------------------------------*/ #define CRC16_INIT 0xabcd @@ -180,7 +181,8 @@ void get_motor_config(const Motor_t* motor, MotorConfig_t* config) { void init_configuration(void) { MotorConfig_t motor_config[2]; - if (NVM_init() || Config::load_config(&motor_config[0], &motor_config[1])) { + //TODO: we really shouldn't be hardcoding like this + if (NVM_init() || Config::load_config(&motor_config[0], &motor_config[1], &axis_configs[0], &axis_configs[1])) { //printf("no config found\r\n"); osDelay(5); // load default config // motor_config[0] = MotorConfig_t(); @@ -200,7 +202,8 @@ void save_configuration(void) { MotorConfig_t motor_config[2]; get_motor_config(&motors[0], &motor_config[0]); get_motor_config(&motors[1], &motor_config[1]); - if (Config::store_config(&motor_config[0], &motor_config[1])) { + //TODO: we really shouldn't be hardcoding like this + if (Config::store_config(&motor_config[0], &motor_config[1], &axis_configs[0], &axis_configs[1])) { //printf("saving configuration failed\r\n"); osDelay(5); } } From 99ca88a8c8848faf9d9144e08ccb0d629081014b Mon Sep 17 00:00:00 2001 From: Samuel Sadok Date: Fri, 23 Feb 2018 16:23:58 -0800 Subject: [PATCH 20/53] This replaces Makefile and at the same time prepares for future build requirements (like multiple active board versions). Developers will need to install tup, as described in the README. A stub Makefile is still available for convenience, so the main "make ..." commands can still be used. --- .gitignore | 33 +-- .travis.yml | 10 +- .../Device/ST/STM32F4xx/Include/stm32f405xx.h | 0 .../Device/ST/STM32F4xx/Include/stm32f4xx.h | 0 .../ST/STM32F4xx/Include/system_stm32f4xx.h | 0 .../Drivers/CMSIS/Include/arm_common_tables.h | 0 .../Drivers/CMSIS/Include/arm_const_structs.h | 0 .../v3.3}/Drivers/CMSIS/Include/arm_math.h | 0 .../v3.3}/Drivers/CMSIS/Include/cmsis_armcc.h | 0 .../Drivers/CMSIS/Include/cmsis_armcc_V6.h | 0 .../v3.3}/Drivers/CMSIS/Include/cmsis_gcc.h | 0 .../v3.3}/Drivers/CMSIS/Include/core_cm0.h | 0 .../Drivers/CMSIS/Include/core_cm0plus.h | 0 .../v3.3}/Drivers/CMSIS/Include/core_cm3.h | 0 .../v3.3}/Drivers/CMSIS/Include/core_cm4.h | 0 .../v3.3}/Drivers/CMSIS/Include/core_cm7.h | 0 .../v3.3}/Drivers/CMSIS/Include/core_cmFunc.h | 0 .../Drivers/CMSIS/Include/core_cmInstr.h | 0 .../v3.3}/Drivers/CMSIS/Include/core_cmSimd.h | 0 .../v3.3}/Drivers/CMSIS/Include/core_sc000.h | 0 .../v3.3}/Drivers/CMSIS/Include/core_sc300.h | 0 .../CMSIS/Lib/libarm_cortexM4lf_math.a | Bin .../v3.3}/Drivers/DRV8301/drv8301.c | 0 .../v3.3}/Drivers/DRV8301/drv8301.h | 0 .../Inc/Legacy/stm32_hal_legacy.h | 0 .../STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal.h | 0 .../Inc/stm32f4xx_hal_adc.h | 0 .../Inc/stm32f4xx_hal_adc_ex.h | 0 .../Inc/stm32f4xx_hal_can.h | 0 .../Inc/stm32f4xx_hal_cortex.h | 0 .../Inc/stm32f4xx_hal_def.h | 0 .../Inc/stm32f4xx_hal_dma.h | 0 .../Inc/stm32f4xx_hal_dma_ex.h | 0 .../Inc/stm32f4xx_hal_flash.h | 0 .../Inc/stm32f4xx_hal_flash_ex.h | 0 .../Inc/stm32f4xx_hal_flash_ramfunc.h | 0 .../Inc/stm32f4xx_hal_gpio.h | 0 .../Inc/stm32f4xx_hal_gpio_ex.h | 0 .../Inc/stm32f4xx_hal_pcd.h | 0 .../Inc/stm32f4xx_hal_pcd_ex.h | 0 .../Inc/stm32f4xx_hal_pwr.h | 0 .../Inc/stm32f4xx_hal_pwr_ex.h | 0 .../Inc/stm32f4xx_hal_rcc.h | 0 .../Inc/stm32f4xx_hal_rcc_ex.h | 0 .../Inc/stm32f4xx_hal_spi.h | 0 .../Inc/stm32f4xx_hal_tim.h | 0 .../Inc/stm32f4xx_hal_tim_ex.h | 0 .../Inc/stm32f4xx_hal_uart.h | 0 .../Inc/stm32f4xx_ll_usb.h | 0 .../STM32F4xx_HAL_Driver/Src/stm32f4xx_hal.c | 0 .../Src/stm32f4xx_hal_adc.c | 0 .../Src/stm32f4xx_hal_adc_ex.c | 0 .../Src/stm32f4xx_hal_can.c | 0 .../Src/stm32f4xx_hal_cortex.c | 0 .../Src/stm32f4xx_hal_dma.c | 0 .../Src/stm32f4xx_hal_dma_ex.c | 0 .../Src/stm32f4xx_hal_flash.c | 0 .../Src/stm32f4xx_hal_flash_ex.c | 0 .../Src/stm32f4xx_hal_flash_ramfunc.c | 0 .../Src/stm32f4xx_hal_gpio.c | 0 .../Src/stm32f4xx_hal_pcd.c | 0 .../Src/stm32f4xx_hal_pcd_ex.c | 0 .../Src/stm32f4xx_hal_pwr.c | 0 .../Src/stm32f4xx_hal_pwr_ex.c | 0 .../Src/stm32f4xx_hal_rcc.c | 0 .../Src/stm32f4xx_hal_rcc_ex.c | 0 .../Src/stm32f4xx_hal_spi.c | 0 .../Src/stm32f4xx_hal_tim.c | 0 .../Src/stm32f4xx_hal_tim_ex.c | 0 .../Src/stm32f4xx_hal_uart.c | 0 .../Src/stm32f4xx_ll_usb.c | 0 .../{ => Board/v3.3}/Inc/FreeRTOSConfig.h | 0 Firmware/{ => Board/v3.3}/Inc/adc.h | 0 Firmware/{ => Board/v3.3}/Inc/can.h | 0 Firmware/{ => Board/v3.3}/Inc/dma.h | 0 Firmware/{ => Board/v3.3}/Inc/freertos_vars.h | 0 Firmware/{ => Board/v3.3}/Inc/gpio.h | 0 Firmware/{ => Board/v3.3}/Inc/main.h | 0 Firmware/{ => Board/v3.3}/Inc/mxconstants.h | 0 .../v3.3}/Inc/prev_board_ver/main_V3_2.h | 0 Firmware/{ => Board/v3.3}/Inc/spi.h | 0 .../{ => Board/v3.3}/Inc/stm32f4xx_hal_conf.h | 0 Firmware/{ => Board/v3.3}/Inc/stm32f4xx_it.h | 0 Firmware/{ => Board/v3.3}/Inc/tim.h | 0 Firmware/{ => Board/v3.3}/Inc/usart.h | 0 Firmware/{ => Board/v3.3}/Inc/usb_device.h | 0 Firmware/{ => Board/v3.3}/Inc/usbd_cdc_if.h | 0 Firmware/{ => Board/v3.3}/Inc/usbd_conf.h | 0 Firmware/{ => Board/v3.3}/Inc/usbd_desc.h | 0 Firmware/Board/v3.3/Makefile | 78 +++++++ .../Class/CDC/Inc/usbd_cdc.h | 0 .../Class/CDC/Src/usbd_cdc.c | 0 .../Core/Inc/usbd_core.h | 0 .../Core/Inc/usbd_ctlreq.h | 0 .../Core/Inc/usbd_def.h | 0 .../Core/Inc/usbd_ioreq.h | 0 .../Core/Src/usbd_core.c | 0 .../Core/Src/usbd_ctlreq.c | 0 .../Core/Src/usbd_ioreq.c | 0 .../FreeRTOS/Source/CMSIS_RTOS/cmsis_os.c | 0 .../FreeRTOS/Source/CMSIS_RTOS/cmsis_os.h | 0 .../Third_Party/FreeRTOS/Source/croutine.c | 0 .../FreeRTOS/Source/event_groups.c | 0 .../FreeRTOS/Source/include/FreeRTOS.h | 0 .../Source/include/FreeRTOSConfig_template.h | 0 .../FreeRTOS/Source/include/StackMacros.h | 0 .../FreeRTOS/Source/include/croutine.h | 0 .../Source/include/deprecated_definitions.h | 0 .../FreeRTOS/Source/include/event_groups.h | 0 .../FreeRTOS/Source/include/list.h | 0 .../FreeRTOS/Source/include/mpu_prototypes.h | 0 .../FreeRTOS/Source/include/mpu_wrappers.h | 0 .../FreeRTOS/Source/include/portable.h | 0 .../FreeRTOS/Source/include/projdefs.h | 0 .../FreeRTOS/Source/include/queue.h | 0 .../FreeRTOS/Source/include/semphr.h | 0 .../FreeRTOS/Source/include/task.h | 0 .../FreeRTOS/Source/include/timers.h | 0 .../Third_Party/FreeRTOS/Source/list.c | 0 .../Source/portable/GCC/ARM_CM4F/port.c | 0 .../Source/portable/GCC/ARM_CM4F/portmacro.h | 0 .../FreeRTOS/Source/portable/MemMang/heap_4.c | 0 .../Third_Party/FreeRTOS/Source/queue.c | 0 .../Third_Party/FreeRTOS/Source/tasks.c | 0 .../Third_Party/FreeRTOS/Source/timers.c | 0 Firmware/{ => Board/v3.3}/Odrive.ioc | 0 .../{ => Board/v3.3}/STM32F405RGTx_FLASH.ld | 0 Firmware/{ => Board/v3.3}/Src/adc.c | 0 Firmware/{ => Board/v3.3}/Src/can.c | 0 Firmware/{ => Board/v3.3}/Src/dma.c | 0 Firmware/{ => Board/v3.3}/Src/freertos.c | 0 Firmware/{ => Board/v3.3}/Src/gpio.c | 0 Firmware/{ => Board/v3.3}/Src/main.c | 0 .../v3.3}/Src/prev_board_ver/adc_V3_2.c | 0 .../v3.3}/Src/prev_board_ver/gpio_V3_2.c | 0 Firmware/{ => Board/v3.3}/Src/spi.c | 0 .../{ => Board/v3.3}/Src/stm32f4xx_hal_msp.c | 0 .../v3.3}/Src/stm32f4xx_hal_timebase_TIM.c | 0 Firmware/{ => Board/v3.3}/Src/stm32f4xx_it.c | 0 Firmware/{ => Board/v3.3}/Src/syscalls.c | 0 .../{ => Board/v3.3}/Src/system_stm32f4xx.c | 0 Firmware/{ => Board/v3.3}/Src/tim.c | 0 Firmware/{ => Board/v3.3}/Src/usart.c | 0 Firmware/{ => Board/v3.3}/Src/usb_device.c | 0 Firmware/{ => Board/v3.3}/Src/usbd_cdc_if.c | 0 Firmware/{ => Board/v3.3}/Src/usbd_conf.c | 0 Firmware/{ => Board/v3.3}/Src/usbd_desc.c | 0 .../v3.3}/startup/startup_stm32f405xx.s | 0 Firmware/Makefile | 214 +----------------- Firmware/README.md | 12 +- Firmware/Tupfile.lua | 76 +++++++ Firmware/build.lua | 166 ++++++++++++++ README.md | 5 + Tupfile.ini | 0 154 files changed, 374 insertions(+), 220 deletions(-) rename Firmware/{ => Board/v3.3}/Drivers/CMSIS/Device/ST/STM32F4xx/Include/stm32f405xx.h (100%) rename Firmware/{ => Board/v3.3}/Drivers/CMSIS/Device/ST/STM32F4xx/Include/stm32f4xx.h (100%) rename Firmware/{ => Board/v3.3}/Drivers/CMSIS/Device/ST/STM32F4xx/Include/system_stm32f4xx.h (100%) rename Firmware/{ => Board/v3.3}/Drivers/CMSIS/Include/arm_common_tables.h (100%) rename Firmware/{ => Board/v3.3}/Drivers/CMSIS/Include/arm_const_structs.h (100%) rename Firmware/{ => Board/v3.3}/Drivers/CMSIS/Include/arm_math.h (100%) rename Firmware/{ => Board/v3.3}/Drivers/CMSIS/Include/cmsis_armcc.h (100%) rename Firmware/{ => Board/v3.3}/Drivers/CMSIS/Include/cmsis_armcc_V6.h (100%) rename Firmware/{ => Board/v3.3}/Drivers/CMSIS/Include/cmsis_gcc.h (100%) rename Firmware/{ => Board/v3.3}/Drivers/CMSIS/Include/core_cm0.h (100%) rename Firmware/{ => Board/v3.3}/Drivers/CMSIS/Include/core_cm0plus.h (100%) rename Firmware/{ => Board/v3.3}/Drivers/CMSIS/Include/core_cm3.h (100%) rename Firmware/{ => Board/v3.3}/Drivers/CMSIS/Include/core_cm4.h (100%) rename Firmware/{ => Board/v3.3}/Drivers/CMSIS/Include/core_cm7.h (100%) rename Firmware/{ => Board/v3.3}/Drivers/CMSIS/Include/core_cmFunc.h (100%) rename Firmware/{ => Board/v3.3}/Drivers/CMSIS/Include/core_cmInstr.h (100%) rename Firmware/{ => Board/v3.3}/Drivers/CMSIS/Include/core_cmSimd.h (100%) rename Firmware/{ => Board/v3.3}/Drivers/CMSIS/Include/core_sc000.h (100%) rename Firmware/{ => Board/v3.3}/Drivers/CMSIS/Include/core_sc300.h (100%) rename Firmware/{ => Board/v3.3}/Drivers/CMSIS/Lib/libarm_cortexM4lf_math.a (100%) rename Firmware/{ => Board/v3.3}/Drivers/DRV8301/drv8301.c (100%) rename Firmware/{ => Board/v3.3}/Drivers/DRV8301/drv8301.h (100%) rename Firmware/{ => Board/v3.3}/Drivers/STM32F4xx_HAL_Driver/Inc/Legacy/stm32_hal_legacy.h (100%) rename Firmware/{ => Board/v3.3}/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal.h (100%) rename Firmware/{ => Board/v3.3}/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_adc.h (100%) rename Firmware/{ => Board/v3.3}/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_adc_ex.h (100%) rename Firmware/{ => Board/v3.3}/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_can.h (100%) rename Firmware/{ => Board/v3.3}/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_cortex.h (100%) rename Firmware/{ => Board/v3.3}/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_def.h (100%) rename Firmware/{ => Board/v3.3}/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_dma.h (100%) rename Firmware/{ => Board/v3.3}/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_dma_ex.h (100%) rename Firmware/{ => Board/v3.3}/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_flash.h (100%) rename Firmware/{ => Board/v3.3}/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_flash_ex.h (100%) rename Firmware/{ => Board/v3.3}/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_flash_ramfunc.h (100%) rename Firmware/{ => Board/v3.3}/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_gpio.h (100%) rename Firmware/{ => Board/v3.3}/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_gpio_ex.h (100%) rename Firmware/{ => Board/v3.3}/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_pcd.h (100%) rename Firmware/{ => Board/v3.3}/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_pcd_ex.h (100%) rename Firmware/{ => Board/v3.3}/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_pwr.h (100%) rename Firmware/{ => Board/v3.3}/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_pwr_ex.h (100%) rename Firmware/{ => Board/v3.3}/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_rcc.h (100%) rename Firmware/{ => Board/v3.3}/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_rcc_ex.h (100%) rename Firmware/{ => Board/v3.3}/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_spi.h (100%) rename Firmware/{ => Board/v3.3}/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_tim.h (100%) rename Firmware/{ => Board/v3.3}/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_tim_ex.h (100%) rename Firmware/{ => Board/v3.3}/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_uart.h (100%) rename Firmware/{ => Board/v3.3}/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_ll_usb.h (100%) rename Firmware/{ => Board/v3.3}/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal.c (100%) rename Firmware/{ => Board/v3.3}/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_adc.c (100%) rename Firmware/{ => Board/v3.3}/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_adc_ex.c (100%) rename Firmware/{ => Board/v3.3}/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_can.c (100%) rename Firmware/{ => Board/v3.3}/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_cortex.c (100%) rename Firmware/{ => Board/v3.3}/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_dma.c (100%) rename Firmware/{ => Board/v3.3}/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_dma_ex.c (100%) rename Firmware/{ => Board/v3.3}/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_flash.c (100%) rename Firmware/{ => Board/v3.3}/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_flash_ex.c (100%) rename Firmware/{ => Board/v3.3}/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_flash_ramfunc.c (100%) rename Firmware/{ => Board/v3.3}/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_gpio.c (100%) rename Firmware/{ => Board/v3.3}/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_pcd.c (100%) rename Firmware/{ => Board/v3.3}/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_pcd_ex.c (100%) rename Firmware/{ => Board/v3.3}/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_pwr.c (100%) rename Firmware/{ => Board/v3.3}/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_pwr_ex.c (100%) rename Firmware/{ => Board/v3.3}/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_rcc.c (100%) rename Firmware/{ => Board/v3.3}/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_rcc_ex.c (100%) rename Firmware/{ => Board/v3.3}/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_spi.c (100%) rename Firmware/{ => Board/v3.3}/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_tim.c (100%) rename Firmware/{ => Board/v3.3}/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_tim_ex.c (100%) rename Firmware/{ => Board/v3.3}/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_uart.c (100%) rename Firmware/{ => Board/v3.3}/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_ll_usb.c (100%) rename Firmware/{ => Board/v3.3}/Inc/FreeRTOSConfig.h (100%) rename Firmware/{ => Board/v3.3}/Inc/adc.h (100%) rename Firmware/{ => Board/v3.3}/Inc/can.h (100%) rename Firmware/{ => Board/v3.3}/Inc/dma.h (100%) rename Firmware/{ => Board/v3.3}/Inc/freertos_vars.h (100%) rename Firmware/{ => Board/v3.3}/Inc/gpio.h (100%) rename Firmware/{ => Board/v3.3}/Inc/main.h (100%) rename Firmware/{ => Board/v3.3}/Inc/mxconstants.h (100%) rename Firmware/{ => Board/v3.3}/Inc/prev_board_ver/main_V3_2.h (100%) rename Firmware/{ => Board/v3.3}/Inc/spi.h (100%) rename Firmware/{ => Board/v3.3}/Inc/stm32f4xx_hal_conf.h (100%) rename Firmware/{ => Board/v3.3}/Inc/stm32f4xx_it.h (100%) rename Firmware/{ => Board/v3.3}/Inc/tim.h (100%) rename Firmware/{ => Board/v3.3}/Inc/usart.h (100%) rename Firmware/{ => Board/v3.3}/Inc/usb_device.h (100%) rename Firmware/{ => Board/v3.3}/Inc/usbd_cdc_if.h (100%) rename Firmware/{ => Board/v3.3}/Inc/usbd_conf.h (100%) rename Firmware/{ => Board/v3.3}/Inc/usbd_desc.h (100%) create mode 100644 Firmware/Board/v3.3/Makefile rename Firmware/{ => Board/v3.3}/Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Inc/usbd_cdc.h (100%) rename Firmware/{ => Board/v3.3}/Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Src/usbd_cdc.c (100%) rename Firmware/{ => Board/v3.3}/Middlewares/ST/STM32_USB_Device_Library/Core/Inc/usbd_core.h (100%) rename Firmware/{ => Board/v3.3}/Middlewares/ST/STM32_USB_Device_Library/Core/Inc/usbd_ctlreq.h (100%) rename Firmware/{ => Board/v3.3}/Middlewares/ST/STM32_USB_Device_Library/Core/Inc/usbd_def.h (100%) rename Firmware/{ => Board/v3.3}/Middlewares/ST/STM32_USB_Device_Library/Core/Inc/usbd_ioreq.h (100%) rename Firmware/{ => Board/v3.3}/Middlewares/ST/STM32_USB_Device_Library/Core/Src/usbd_core.c (100%) rename Firmware/{ => Board/v3.3}/Middlewares/ST/STM32_USB_Device_Library/Core/Src/usbd_ctlreq.c (100%) rename Firmware/{ => Board/v3.3}/Middlewares/ST/STM32_USB_Device_Library/Core/Src/usbd_ioreq.c (100%) rename Firmware/{ => Board/v3.3}/Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS/cmsis_os.c (100%) rename Firmware/{ => Board/v3.3}/Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS/cmsis_os.h (100%) rename Firmware/{ => Board/v3.3}/Middlewares/Third_Party/FreeRTOS/Source/croutine.c (100%) rename Firmware/{ => Board/v3.3}/Middlewares/Third_Party/FreeRTOS/Source/event_groups.c (100%) rename Firmware/{ => Board/v3.3}/Middlewares/Third_Party/FreeRTOS/Source/include/FreeRTOS.h (100%) rename Firmware/{ => Board/v3.3}/Middlewares/Third_Party/FreeRTOS/Source/include/FreeRTOSConfig_template.h (100%) rename Firmware/{ => Board/v3.3}/Middlewares/Third_Party/FreeRTOS/Source/include/StackMacros.h (100%) rename Firmware/{ => Board/v3.3}/Middlewares/Third_Party/FreeRTOS/Source/include/croutine.h (100%) rename Firmware/{ => Board/v3.3}/Middlewares/Third_Party/FreeRTOS/Source/include/deprecated_definitions.h (100%) rename Firmware/{ => Board/v3.3}/Middlewares/Third_Party/FreeRTOS/Source/include/event_groups.h (100%) rename Firmware/{ => Board/v3.3}/Middlewares/Third_Party/FreeRTOS/Source/include/list.h (100%) rename Firmware/{ => Board/v3.3}/Middlewares/Third_Party/FreeRTOS/Source/include/mpu_prototypes.h (100%) rename Firmware/{ => Board/v3.3}/Middlewares/Third_Party/FreeRTOS/Source/include/mpu_wrappers.h (100%) rename Firmware/{ => Board/v3.3}/Middlewares/Third_Party/FreeRTOS/Source/include/portable.h (100%) rename Firmware/{ => Board/v3.3}/Middlewares/Third_Party/FreeRTOS/Source/include/projdefs.h (100%) rename Firmware/{ => Board/v3.3}/Middlewares/Third_Party/FreeRTOS/Source/include/queue.h (100%) rename Firmware/{ => Board/v3.3}/Middlewares/Third_Party/FreeRTOS/Source/include/semphr.h (100%) rename Firmware/{ => Board/v3.3}/Middlewares/Third_Party/FreeRTOS/Source/include/task.h (100%) rename Firmware/{ => Board/v3.3}/Middlewares/Third_Party/FreeRTOS/Source/include/timers.h (100%) rename Firmware/{ => Board/v3.3}/Middlewares/Third_Party/FreeRTOS/Source/list.c (100%) rename Firmware/{ => Board/v3.3}/Middlewares/Third_Party/FreeRTOS/Source/portable/GCC/ARM_CM4F/port.c (100%) rename Firmware/{ => Board/v3.3}/Middlewares/Third_Party/FreeRTOS/Source/portable/GCC/ARM_CM4F/portmacro.h (100%) rename Firmware/{ => Board/v3.3}/Middlewares/Third_Party/FreeRTOS/Source/portable/MemMang/heap_4.c (100%) rename Firmware/{ => Board/v3.3}/Middlewares/Third_Party/FreeRTOS/Source/queue.c (100%) rename Firmware/{ => Board/v3.3}/Middlewares/Third_Party/FreeRTOS/Source/tasks.c (100%) rename Firmware/{ => Board/v3.3}/Middlewares/Third_Party/FreeRTOS/Source/timers.c (100%) rename Firmware/{ => Board/v3.3}/Odrive.ioc (100%) rename Firmware/{ => Board/v3.3}/STM32F405RGTx_FLASH.ld (100%) rename Firmware/{ => Board/v3.3}/Src/adc.c (100%) rename Firmware/{ => Board/v3.3}/Src/can.c (100%) rename Firmware/{ => Board/v3.3}/Src/dma.c (100%) rename Firmware/{ => Board/v3.3}/Src/freertos.c (100%) rename Firmware/{ => Board/v3.3}/Src/gpio.c (100%) rename Firmware/{ => Board/v3.3}/Src/main.c (100%) rename Firmware/{ => Board/v3.3}/Src/prev_board_ver/adc_V3_2.c (100%) rename Firmware/{ => Board/v3.3}/Src/prev_board_ver/gpio_V3_2.c (100%) rename Firmware/{ => Board/v3.3}/Src/spi.c (100%) rename Firmware/{ => Board/v3.3}/Src/stm32f4xx_hal_msp.c (100%) rename Firmware/{ => Board/v3.3}/Src/stm32f4xx_hal_timebase_TIM.c (100%) rename Firmware/{ => Board/v3.3}/Src/stm32f4xx_it.c (100%) rename Firmware/{ => Board/v3.3}/Src/syscalls.c (100%) rename Firmware/{ => Board/v3.3}/Src/system_stm32f4xx.c (100%) rename Firmware/{ => Board/v3.3}/Src/tim.c (100%) rename Firmware/{ => Board/v3.3}/Src/usart.c (100%) rename Firmware/{ => Board/v3.3}/Src/usb_device.c (100%) rename Firmware/{ => Board/v3.3}/Src/usbd_cdc_if.c (100%) rename Firmware/{ => Board/v3.3}/Src/usbd_conf.c (100%) rename Firmware/{ => Board/v3.3}/Src/usbd_desc.c (100%) rename Firmware/{ => Board/v3.3}/startup/startup_stm32f405xx.s (100%) create mode 100644 Firmware/Tupfile.lua create mode 100644 Firmware/build.lua create mode 100644 Tupfile.ini diff --git a/.gitignore b/.gitignore index 1dbc687d..4f119819 100644 --- a/.gitignore +++ b/.gitignore @@ -8,21 +8,21 @@ __pycache__/ # Distribution / packaging .Python -env/ -build/ -develop-eggs/ -dist/ -downloads/ -eggs/ -.eggs/ -lib/ -lib64/ -parts/ -sdist/ -var/ -*.egg-info/ -.installed.cfg -*.egg +#env/ +#build/ +#develop-eggs/ +#dist/ +#downloads/ +#eggs/ +#.eggs/ +#lib/ +#lib64/ +#parts/ +#sdist/ +#var/ +#*.egg-info/ +#.installed.cfg +#*.egg # PyInstaller # Usually these files are written by a python script from a template @@ -60,3 +60,6 @@ target/ #Ipython Notebook .ipynb_checkpoints + +# Tup +.tup diff --git a/.travis.yml b/.travis.yml index ba888a75..bad65bb3 100644 --- a/.travis.yml +++ b/.travis.yml @@ -18,6 +18,14 @@ install: - export GCC_URL=https://launchpad.net/gcc-arm-embedded/5.0/5-2015-q4-major/+download/gcc-arm-none-eabi-5_2-2015q4-20151219-linux.tar.bz2 - if [ ! -e $GCC_DIR/bin/arm-none-eabi-gcc ]; then wget $GCC_URL -O $GCC_ARCHIVE; tar xfj $GCC_ARCHIVE -C $HOME/dl; fi - export PATH=$PATH:$GCC_DIR/bin + - export TUP_DIR=$HOME/dl/tup_0.7.2.12+ga582fee_amd64 + - export TUP_ARCHIVE=$HOME/dl/tup_0.7.2.12+ga582fee_amd64.deb + - export TUP_URL=http://ppa.launchpad.net/anatol/tup/ubuntu/pool/main/t/tup/tup_0.7.2.12+ga582fee_amd64.deb + - if [ ! -e $TUP_DIR/bin/tup ]; then wget $TUP_URL -O $TUP_ARCHIVE; dpkg-deb -R $TUP_ARCHIVE $TUP_DIR; fi + - export PATH=$PATH:$TUP_DIR/usr/bin script: - - make clean && make + - cd Firmware + - mkdir -p build + - tup generate ./build.sh + - bash -x ./build.sh diff --git a/Firmware/Drivers/CMSIS/Device/ST/STM32F4xx/Include/stm32f405xx.h b/Firmware/Board/v3.3/Drivers/CMSIS/Device/ST/STM32F4xx/Include/stm32f405xx.h similarity index 100% rename from Firmware/Drivers/CMSIS/Device/ST/STM32F4xx/Include/stm32f405xx.h rename to Firmware/Board/v3.3/Drivers/CMSIS/Device/ST/STM32F4xx/Include/stm32f405xx.h diff --git a/Firmware/Drivers/CMSIS/Device/ST/STM32F4xx/Include/stm32f4xx.h b/Firmware/Board/v3.3/Drivers/CMSIS/Device/ST/STM32F4xx/Include/stm32f4xx.h similarity index 100% rename from Firmware/Drivers/CMSIS/Device/ST/STM32F4xx/Include/stm32f4xx.h rename to Firmware/Board/v3.3/Drivers/CMSIS/Device/ST/STM32F4xx/Include/stm32f4xx.h diff --git a/Firmware/Drivers/CMSIS/Device/ST/STM32F4xx/Include/system_stm32f4xx.h b/Firmware/Board/v3.3/Drivers/CMSIS/Device/ST/STM32F4xx/Include/system_stm32f4xx.h similarity index 100% rename from Firmware/Drivers/CMSIS/Device/ST/STM32F4xx/Include/system_stm32f4xx.h rename to Firmware/Board/v3.3/Drivers/CMSIS/Device/ST/STM32F4xx/Include/system_stm32f4xx.h diff --git a/Firmware/Drivers/CMSIS/Include/arm_common_tables.h b/Firmware/Board/v3.3/Drivers/CMSIS/Include/arm_common_tables.h similarity index 100% rename from Firmware/Drivers/CMSIS/Include/arm_common_tables.h rename to Firmware/Board/v3.3/Drivers/CMSIS/Include/arm_common_tables.h diff --git a/Firmware/Drivers/CMSIS/Include/arm_const_structs.h b/Firmware/Board/v3.3/Drivers/CMSIS/Include/arm_const_structs.h similarity index 100% rename from Firmware/Drivers/CMSIS/Include/arm_const_structs.h rename to Firmware/Board/v3.3/Drivers/CMSIS/Include/arm_const_structs.h diff --git a/Firmware/Drivers/CMSIS/Include/arm_math.h b/Firmware/Board/v3.3/Drivers/CMSIS/Include/arm_math.h similarity index 100% rename from Firmware/Drivers/CMSIS/Include/arm_math.h rename to Firmware/Board/v3.3/Drivers/CMSIS/Include/arm_math.h diff --git a/Firmware/Drivers/CMSIS/Include/cmsis_armcc.h b/Firmware/Board/v3.3/Drivers/CMSIS/Include/cmsis_armcc.h similarity index 100% rename from Firmware/Drivers/CMSIS/Include/cmsis_armcc.h rename to Firmware/Board/v3.3/Drivers/CMSIS/Include/cmsis_armcc.h diff --git a/Firmware/Drivers/CMSIS/Include/cmsis_armcc_V6.h b/Firmware/Board/v3.3/Drivers/CMSIS/Include/cmsis_armcc_V6.h similarity index 100% rename from Firmware/Drivers/CMSIS/Include/cmsis_armcc_V6.h rename to Firmware/Board/v3.3/Drivers/CMSIS/Include/cmsis_armcc_V6.h diff --git a/Firmware/Drivers/CMSIS/Include/cmsis_gcc.h b/Firmware/Board/v3.3/Drivers/CMSIS/Include/cmsis_gcc.h similarity index 100% rename from Firmware/Drivers/CMSIS/Include/cmsis_gcc.h rename to Firmware/Board/v3.3/Drivers/CMSIS/Include/cmsis_gcc.h diff --git a/Firmware/Drivers/CMSIS/Include/core_cm0.h b/Firmware/Board/v3.3/Drivers/CMSIS/Include/core_cm0.h similarity index 100% rename from Firmware/Drivers/CMSIS/Include/core_cm0.h rename to Firmware/Board/v3.3/Drivers/CMSIS/Include/core_cm0.h diff --git a/Firmware/Drivers/CMSIS/Include/core_cm0plus.h b/Firmware/Board/v3.3/Drivers/CMSIS/Include/core_cm0plus.h similarity index 100% rename from Firmware/Drivers/CMSIS/Include/core_cm0plus.h rename to Firmware/Board/v3.3/Drivers/CMSIS/Include/core_cm0plus.h diff --git a/Firmware/Drivers/CMSIS/Include/core_cm3.h b/Firmware/Board/v3.3/Drivers/CMSIS/Include/core_cm3.h similarity index 100% rename from Firmware/Drivers/CMSIS/Include/core_cm3.h rename to Firmware/Board/v3.3/Drivers/CMSIS/Include/core_cm3.h diff --git a/Firmware/Drivers/CMSIS/Include/core_cm4.h b/Firmware/Board/v3.3/Drivers/CMSIS/Include/core_cm4.h similarity index 100% rename from Firmware/Drivers/CMSIS/Include/core_cm4.h rename to Firmware/Board/v3.3/Drivers/CMSIS/Include/core_cm4.h diff --git a/Firmware/Drivers/CMSIS/Include/core_cm7.h b/Firmware/Board/v3.3/Drivers/CMSIS/Include/core_cm7.h similarity index 100% rename from Firmware/Drivers/CMSIS/Include/core_cm7.h rename to Firmware/Board/v3.3/Drivers/CMSIS/Include/core_cm7.h diff --git a/Firmware/Drivers/CMSIS/Include/core_cmFunc.h b/Firmware/Board/v3.3/Drivers/CMSIS/Include/core_cmFunc.h similarity index 100% rename from Firmware/Drivers/CMSIS/Include/core_cmFunc.h rename to Firmware/Board/v3.3/Drivers/CMSIS/Include/core_cmFunc.h diff --git a/Firmware/Drivers/CMSIS/Include/core_cmInstr.h b/Firmware/Board/v3.3/Drivers/CMSIS/Include/core_cmInstr.h similarity index 100% rename from Firmware/Drivers/CMSIS/Include/core_cmInstr.h rename to Firmware/Board/v3.3/Drivers/CMSIS/Include/core_cmInstr.h diff --git a/Firmware/Drivers/CMSIS/Include/core_cmSimd.h b/Firmware/Board/v3.3/Drivers/CMSIS/Include/core_cmSimd.h similarity index 100% rename from Firmware/Drivers/CMSIS/Include/core_cmSimd.h rename to Firmware/Board/v3.3/Drivers/CMSIS/Include/core_cmSimd.h diff --git a/Firmware/Drivers/CMSIS/Include/core_sc000.h b/Firmware/Board/v3.3/Drivers/CMSIS/Include/core_sc000.h similarity index 100% rename from Firmware/Drivers/CMSIS/Include/core_sc000.h rename to Firmware/Board/v3.3/Drivers/CMSIS/Include/core_sc000.h diff --git a/Firmware/Drivers/CMSIS/Include/core_sc300.h b/Firmware/Board/v3.3/Drivers/CMSIS/Include/core_sc300.h similarity index 100% rename from Firmware/Drivers/CMSIS/Include/core_sc300.h rename to Firmware/Board/v3.3/Drivers/CMSIS/Include/core_sc300.h diff --git a/Firmware/Drivers/CMSIS/Lib/libarm_cortexM4lf_math.a b/Firmware/Board/v3.3/Drivers/CMSIS/Lib/libarm_cortexM4lf_math.a similarity index 100% rename from Firmware/Drivers/CMSIS/Lib/libarm_cortexM4lf_math.a rename to Firmware/Board/v3.3/Drivers/CMSIS/Lib/libarm_cortexM4lf_math.a diff --git a/Firmware/Drivers/DRV8301/drv8301.c b/Firmware/Board/v3.3/Drivers/DRV8301/drv8301.c similarity index 100% rename from Firmware/Drivers/DRV8301/drv8301.c rename to Firmware/Board/v3.3/Drivers/DRV8301/drv8301.c diff --git a/Firmware/Drivers/DRV8301/drv8301.h b/Firmware/Board/v3.3/Drivers/DRV8301/drv8301.h similarity index 100% rename from Firmware/Drivers/DRV8301/drv8301.h rename to Firmware/Board/v3.3/Drivers/DRV8301/drv8301.h diff --git a/Firmware/Drivers/STM32F4xx_HAL_Driver/Inc/Legacy/stm32_hal_legacy.h b/Firmware/Board/v3.3/Drivers/STM32F4xx_HAL_Driver/Inc/Legacy/stm32_hal_legacy.h similarity index 100% rename from Firmware/Drivers/STM32F4xx_HAL_Driver/Inc/Legacy/stm32_hal_legacy.h rename to Firmware/Board/v3.3/Drivers/STM32F4xx_HAL_Driver/Inc/Legacy/stm32_hal_legacy.h diff --git a/Firmware/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal.h b/Firmware/Board/v3.3/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal.h similarity index 100% rename from Firmware/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal.h rename to Firmware/Board/v3.3/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal.h diff --git a/Firmware/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_adc.h b/Firmware/Board/v3.3/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_adc.h similarity index 100% rename from Firmware/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_adc.h rename to Firmware/Board/v3.3/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_adc.h diff --git a/Firmware/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_adc_ex.h b/Firmware/Board/v3.3/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_adc_ex.h similarity index 100% rename from Firmware/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_adc_ex.h rename to Firmware/Board/v3.3/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_adc_ex.h diff --git a/Firmware/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_can.h b/Firmware/Board/v3.3/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_can.h similarity index 100% rename from Firmware/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_can.h rename to Firmware/Board/v3.3/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_can.h diff --git a/Firmware/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_cortex.h b/Firmware/Board/v3.3/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_cortex.h similarity index 100% rename from Firmware/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_cortex.h rename to Firmware/Board/v3.3/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_cortex.h diff --git a/Firmware/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_def.h b/Firmware/Board/v3.3/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_def.h similarity index 100% rename from Firmware/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_def.h rename to Firmware/Board/v3.3/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_def.h diff --git a/Firmware/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_dma.h b/Firmware/Board/v3.3/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_dma.h similarity index 100% rename from Firmware/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_dma.h rename to Firmware/Board/v3.3/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_dma.h diff --git a/Firmware/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_dma_ex.h b/Firmware/Board/v3.3/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_dma_ex.h similarity index 100% rename from Firmware/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_dma_ex.h rename to Firmware/Board/v3.3/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_dma_ex.h diff --git a/Firmware/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_flash.h b/Firmware/Board/v3.3/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_flash.h similarity index 100% rename from Firmware/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_flash.h rename to Firmware/Board/v3.3/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_flash.h diff --git a/Firmware/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_flash_ex.h b/Firmware/Board/v3.3/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_flash_ex.h similarity index 100% rename from Firmware/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_flash_ex.h rename to Firmware/Board/v3.3/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_flash_ex.h diff --git a/Firmware/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_flash_ramfunc.h b/Firmware/Board/v3.3/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_flash_ramfunc.h similarity index 100% rename from Firmware/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_flash_ramfunc.h rename to Firmware/Board/v3.3/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_flash_ramfunc.h diff --git a/Firmware/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_gpio.h b/Firmware/Board/v3.3/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_gpio.h similarity index 100% rename from Firmware/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_gpio.h rename to Firmware/Board/v3.3/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_gpio.h diff --git a/Firmware/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_gpio_ex.h b/Firmware/Board/v3.3/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_gpio_ex.h similarity index 100% rename from Firmware/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_gpio_ex.h rename to Firmware/Board/v3.3/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_gpio_ex.h diff --git a/Firmware/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_pcd.h b/Firmware/Board/v3.3/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_pcd.h similarity index 100% rename from Firmware/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_pcd.h rename to Firmware/Board/v3.3/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_pcd.h diff --git a/Firmware/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_pcd_ex.h b/Firmware/Board/v3.3/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_pcd_ex.h similarity index 100% rename from Firmware/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_pcd_ex.h rename to Firmware/Board/v3.3/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_pcd_ex.h diff --git a/Firmware/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_pwr.h b/Firmware/Board/v3.3/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_pwr.h similarity index 100% rename from Firmware/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_pwr.h rename to Firmware/Board/v3.3/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_pwr.h diff --git a/Firmware/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_pwr_ex.h b/Firmware/Board/v3.3/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_pwr_ex.h similarity index 100% rename from Firmware/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_pwr_ex.h rename to Firmware/Board/v3.3/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_pwr_ex.h diff --git a/Firmware/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_rcc.h b/Firmware/Board/v3.3/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_rcc.h similarity index 100% rename from Firmware/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_rcc.h rename to Firmware/Board/v3.3/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_rcc.h diff --git a/Firmware/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_rcc_ex.h b/Firmware/Board/v3.3/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_rcc_ex.h similarity index 100% rename from Firmware/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_rcc_ex.h rename to Firmware/Board/v3.3/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_rcc_ex.h diff --git a/Firmware/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_spi.h b/Firmware/Board/v3.3/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_spi.h similarity index 100% rename from Firmware/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_spi.h rename to Firmware/Board/v3.3/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_spi.h diff --git a/Firmware/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_tim.h b/Firmware/Board/v3.3/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_tim.h similarity index 100% rename from Firmware/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_tim.h rename to Firmware/Board/v3.3/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_tim.h diff --git a/Firmware/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_tim_ex.h b/Firmware/Board/v3.3/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_tim_ex.h similarity index 100% rename from Firmware/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_tim_ex.h rename to Firmware/Board/v3.3/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_tim_ex.h diff --git a/Firmware/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_uart.h b/Firmware/Board/v3.3/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_uart.h similarity index 100% rename from Firmware/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_uart.h rename to Firmware/Board/v3.3/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_uart.h diff --git a/Firmware/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_ll_usb.h b/Firmware/Board/v3.3/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_ll_usb.h similarity index 100% rename from Firmware/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_ll_usb.h rename to Firmware/Board/v3.3/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_ll_usb.h diff --git a/Firmware/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal.c b/Firmware/Board/v3.3/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal.c similarity index 100% rename from Firmware/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal.c rename to Firmware/Board/v3.3/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal.c diff --git a/Firmware/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_adc.c b/Firmware/Board/v3.3/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_adc.c similarity index 100% rename from Firmware/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_adc.c rename to Firmware/Board/v3.3/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_adc.c diff --git a/Firmware/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_adc_ex.c b/Firmware/Board/v3.3/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_adc_ex.c similarity index 100% rename from Firmware/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_adc_ex.c rename to Firmware/Board/v3.3/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_adc_ex.c diff --git a/Firmware/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_can.c b/Firmware/Board/v3.3/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_can.c similarity index 100% rename from Firmware/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_can.c rename to Firmware/Board/v3.3/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_can.c diff --git a/Firmware/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_cortex.c b/Firmware/Board/v3.3/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_cortex.c similarity index 100% rename from Firmware/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_cortex.c rename to Firmware/Board/v3.3/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_cortex.c diff --git a/Firmware/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_dma.c b/Firmware/Board/v3.3/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_dma.c similarity index 100% rename from Firmware/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_dma.c rename to Firmware/Board/v3.3/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_dma.c diff --git a/Firmware/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_dma_ex.c b/Firmware/Board/v3.3/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_dma_ex.c similarity index 100% rename from Firmware/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_dma_ex.c rename to Firmware/Board/v3.3/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_dma_ex.c diff --git a/Firmware/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_flash.c b/Firmware/Board/v3.3/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_flash.c similarity index 100% rename from Firmware/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_flash.c rename to Firmware/Board/v3.3/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_flash.c diff --git a/Firmware/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_flash_ex.c b/Firmware/Board/v3.3/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_flash_ex.c similarity index 100% rename from Firmware/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_flash_ex.c rename to Firmware/Board/v3.3/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_flash_ex.c diff --git a/Firmware/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_flash_ramfunc.c b/Firmware/Board/v3.3/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_flash_ramfunc.c similarity index 100% rename from Firmware/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_flash_ramfunc.c rename to Firmware/Board/v3.3/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_flash_ramfunc.c diff --git a/Firmware/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_gpio.c b/Firmware/Board/v3.3/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_gpio.c similarity index 100% rename from Firmware/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_gpio.c rename to Firmware/Board/v3.3/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_gpio.c diff --git a/Firmware/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_pcd.c b/Firmware/Board/v3.3/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_pcd.c similarity index 100% rename from Firmware/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_pcd.c rename to Firmware/Board/v3.3/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_pcd.c diff --git a/Firmware/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_pcd_ex.c b/Firmware/Board/v3.3/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_pcd_ex.c similarity index 100% rename from Firmware/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_pcd_ex.c rename to Firmware/Board/v3.3/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_pcd_ex.c diff --git a/Firmware/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_pwr.c b/Firmware/Board/v3.3/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_pwr.c similarity index 100% rename from Firmware/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_pwr.c rename to Firmware/Board/v3.3/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_pwr.c diff --git a/Firmware/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_pwr_ex.c b/Firmware/Board/v3.3/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_pwr_ex.c similarity index 100% rename from Firmware/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_pwr_ex.c rename to Firmware/Board/v3.3/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_pwr_ex.c diff --git a/Firmware/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_rcc.c b/Firmware/Board/v3.3/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_rcc.c similarity index 100% rename from Firmware/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_rcc.c rename to Firmware/Board/v3.3/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_rcc.c diff --git a/Firmware/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_rcc_ex.c b/Firmware/Board/v3.3/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_rcc_ex.c similarity index 100% rename from Firmware/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_rcc_ex.c rename to Firmware/Board/v3.3/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_rcc_ex.c diff --git a/Firmware/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_spi.c b/Firmware/Board/v3.3/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_spi.c similarity index 100% rename from Firmware/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_spi.c rename to Firmware/Board/v3.3/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_spi.c diff --git a/Firmware/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_tim.c b/Firmware/Board/v3.3/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_tim.c similarity index 100% rename from Firmware/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_tim.c rename to Firmware/Board/v3.3/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_tim.c diff --git a/Firmware/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_tim_ex.c b/Firmware/Board/v3.3/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_tim_ex.c similarity index 100% rename from Firmware/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_tim_ex.c rename to Firmware/Board/v3.3/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_tim_ex.c diff --git a/Firmware/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_uart.c b/Firmware/Board/v3.3/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_uart.c similarity index 100% rename from Firmware/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_uart.c rename to Firmware/Board/v3.3/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_uart.c diff --git a/Firmware/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_ll_usb.c b/Firmware/Board/v3.3/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_ll_usb.c similarity index 100% rename from Firmware/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_ll_usb.c rename to Firmware/Board/v3.3/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_ll_usb.c diff --git a/Firmware/Inc/FreeRTOSConfig.h b/Firmware/Board/v3.3/Inc/FreeRTOSConfig.h similarity index 100% rename from Firmware/Inc/FreeRTOSConfig.h rename to Firmware/Board/v3.3/Inc/FreeRTOSConfig.h diff --git a/Firmware/Inc/adc.h b/Firmware/Board/v3.3/Inc/adc.h similarity index 100% rename from Firmware/Inc/adc.h rename to Firmware/Board/v3.3/Inc/adc.h diff --git a/Firmware/Inc/can.h b/Firmware/Board/v3.3/Inc/can.h similarity index 100% rename from Firmware/Inc/can.h rename to Firmware/Board/v3.3/Inc/can.h diff --git a/Firmware/Inc/dma.h b/Firmware/Board/v3.3/Inc/dma.h similarity index 100% rename from Firmware/Inc/dma.h rename to Firmware/Board/v3.3/Inc/dma.h diff --git a/Firmware/Inc/freertos_vars.h b/Firmware/Board/v3.3/Inc/freertos_vars.h similarity index 100% rename from Firmware/Inc/freertos_vars.h rename to Firmware/Board/v3.3/Inc/freertos_vars.h diff --git a/Firmware/Inc/gpio.h b/Firmware/Board/v3.3/Inc/gpio.h similarity index 100% rename from Firmware/Inc/gpio.h rename to Firmware/Board/v3.3/Inc/gpio.h diff --git a/Firmware/Inc/main.h b/Firmware/Board/v3.3/Inc/main.h similarity index 100% rename from Firmware/Inc/main.h rename to Firmware/Board/v3.3/Inc/main.h diff --git a/Firmware/Inc/mxconstants.h b/Firmware/Board/v3.3/Inc/mxconstants.h similarity index 100% rename from Firmware/Inc/mxconstants.h rename to Firmware/Board/v3.3/Inc/mxconstants.h diff --git a/Firmware/Inc/prev_board_ver/main_V3_2.h b/Firmware/Board/v3.3/Inc/prev_board_ver/main_V3_2.h similarity index 100% rename from Firmware/Inc/prev_board_ver/main_V3_2.h rename to Firmware/Board/v3.3/Inc/prev_board_ver/main_V3_2.h diff --git a/Firmware/Inc/spi.h b/Firmware/Board/v3.3/Inc/spi.h similarity index 100% rename from Firmware/Inc/spi.h rename to Firmware/Board/v3.3/Inc/spi.h diff --git a/Firmware/Inc/stm32f4xx_hal_conf.h b/Firmware/Board/v3.3/Inc/stm32f4xx_hal_conf.h similarity index 100% rename from Firmware/Inc/stm32f4xx_hal_conf.h rename to Firmware/Board/v3.3/Inc/stm32f4xx_hal_conf.h diff --git a/Firmware/Inc/stm32f4xx_it.h b/Firmware/Board/v3.3/Inc/stm32f4xx_it.h similarity index 100% rename from Firmware/Inc/stm32f4xx_it.h rename to Firmware/Board/v3.3/Inc/stm32f4xx_it.h diff --git a/Firmware/Inc/tim.h b/Firmware/Board/v3.3/Inc/tim.h similarity index 100% rename from Firmware/Inc/tim.h rename to Firmware/Board/v3.3/Inc/tim.h diff --git a/Firmware/Inc/usart.h b/Firmware/Board/v3.3/Inc/usart.h similarity index 100% rename from Firmware/Inc/usart.h rename to Firmware/Board/v3.3/Inc/usart.h diff --git a/Firmware/Inc/usb_device.h b/Firmware/Board/v3.3/Inc/usb_device.h similarity index 100% rename from Firmware/Inc/usb_device.h rename to Firmware/Board/v3.3/Inc/usb_device.h diff --git a/Firmware/Inc/usbd_cdc_if.h b/Firmware/Board/v3.3/Inc/usbd_cdc_if.h similarity index 100% rename from Firmware/Inc/usbd_cdc_if.h rename to Firmware/Board/v3.3/Inc/usbd_cdc_if.h diff --git a/Firmware/Inc/usbd_conf.h b/Firmware/Board/v3.3/Inc/usbd_conf.h similarity index 100% rename from Firmware/Inc/usbd_conf.h rename to Firmware/Board/v3.3/Inc/usbd_conf.h diff --git a/Firmware/Inc/usbd_desc.h b/Firmware/Board/v3.3/Inc/usbd_desc.h similarity index 100% rename from Firmware/Inc/usbd_desc.h rename to Firmware/Board/v3.3/Inc/usbd_desc.h diff --git a/Firmware/Board/v3.3/Makefile b/Firmware/Board/v3.3/Makefile new file mode 100644 index 00000000..82cdc7d2 --- /dev/null +++ b/Firmware/Board/v3.3/Makefile @@ -0,0 +1,78 @@ + +###################################### +# source +###################################### +C_SOURCES = \ + Middlewares/Third_Party/FreeRTOS/Source/queue.c \ + Middlewares/Third_Party/FreeRTOS/Source/tasks.c \ + Middlewares/Third_Party/FreeRTOS/Source/list.c \ + Middlewares/Third_Party/FreeRTOS/Source/event_groups.c \ + Middlewares/Third_Party/FreeRTOS/Source/croutine.c \ + Middlewares/Third_Party/FreeRTOS/Source/timers.c \ + Middlewares/Third_Party/FreeRTOS/Source/portable/GCC/ARM_CM4F/port.c \ + Middlewares/Third_Party/FreeRTOS/Source/portable/MemMang/heap_4.c \ + Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS/cmsis_os.c \ + Middlewares/ST/STM32_USB_Device_Library/Core/Src/usbd_core.c \ + Middlewares/ST/STM32_USB_Device_Library/Core/Src/usbd_ioreq.c \ + Middlewares/ST/STM32_USB_Device_Library/Core/Src/usbd_ctlreq.c \ + Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Src/usbd_cdc.c \ + Src/system_stm32f4xx.c \ + Src/stm32f4xx_it.c \ + Src/stm32f4xx_hal_msp.c \ + Src/stm32f4xx_hal_timebase_TIM.c \ + Src/tim.c \ + Src/gpio.c \ + Src/main.c \ + Src/adc.c \ + Src/freertos.c \ + Src/spi.c \ + Src/can.c \ + Src/usart.c \ + Src/dma.c \ + Src/usbd_conf.c \ + Src/usbd_desc.c \ + Src/usb_device.c \ + Drivers/DRV8301/drv8301.c \ + Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal.c \ + Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_rcc.c \ + Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_tim_ex.c \ + Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_flash_ramfunc.c \ + Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_spi.c \ + Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_rcc_ex.c \ + Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_flash.c \ + Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_flash_ex.c \ + Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_can.c \ + Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_adc.c \ + Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_dma.c \ + Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_cortex.c \ + Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_pwr_ex.c \ + Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_tim.c \ + Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_gpio.c \ + Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_dma_ex.c \ + Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_pwr.c \ + Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_adc_ex.c \ + Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_pcd.c \ + Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_pcd_ex.c \ + Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_uart.c \ + Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_ll_usb.c \ + Src/usbd_cdc_if.c \ + Src/syscalls.c +CPP_SOURCES = +ASM_SOURCES = \ + startup/startup_stm32f405xx.s + +####################################### +# Includes +####################################### +AS_INCLUDES = +C_INCLUDES = -IMiddlewares/Third_Party/FreeRTOS/Source/portable/GCC/ARM_CM4F \ + -IMiddlewares/Third_Party/FreeRTOS/Source/include \ + -IMiddlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS \ + -IDrivers/DRV8301 \ + -IMiddlewares/ST/STM32_USB_Device_Library/Core/Inc \ + -IMiddlewares/ST/STM32_USB_Device_Library/Class/CDC/Inc \ + -IDrivers/STM32F4xx_HAL_Driver/Inc \ + -IDrivers/STM32F4xx_HAL_Driver/Inc/Legacy \ + -IDrivers/CMSIS/Device/ST/STM32F4xx/Include \ + -IDrivers/CMSIS/Include \ + -IInc diff --git a/Firmware/Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Inc/usbd_cdc.h b/Firmware/Board/v3.3/Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Inc/usbd_cdc.h similarity index 100% rename from Firmware/Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Inc/usbd_cdc.h rename to Firmware/Board/v3.3/Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Inc/usbd_cdc.h diff --git a/Firmware/Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Src/usbd_cdc.c b/Firmware/Board/v3.3/Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Src/usbd_cdc.c similarity index 100% rename from Firmware/Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Src/usbd_cdc.c rename to Firmware/Board/v3.3/Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Src/usbd_cdc.c diff --git a/Firmware/Middlewares/ST/STM32_USB_Device_Library/Core/Inc/usbd_core.h b/Firmware/Board/v3.3/Middlewares/ST/STM32_USB_Device_Library/Core/Inc/usbd_core.h similarity index 100% rename from Firmware/Middlewares/ST/STM32_USB_Device_Library/Core/Inc/usbd_core.h rename to Firmware/Board/v3.3/Middlewares/ST/STM32_USB_Device_Library/Core/Inc/usbd_core.h diff --git a/Firmware/Middlewares/ST/STM32_USB_Device_Library/Core/Inc/usbd_ctlreq.h b/Firmware/Board/v3.3/Middlewares/ST/STM32_USB_Device_Library/Core/Inc/usbd_ctlreq.h similarity index 100% rename from Firmware/Middlewares/ST/STM32_USB_Device_Library/Core/Inc/usbd_ctlreq.h rename to Firmware/Board/v3.3/Middlewares/ST/STM32_USB_Device_Library/Core/Inc/usbd_ctlreq.h diff --git a/Firmware/Middlewares/ST/STM32_USB_Device_Library/Core/Inc/usbd_def.h b/Firmware/Board/v3.3/Middlewares/ST/STM32_USB_Device_Library/Core/Inc/usbd_def.h similarity index 100% rename from Firmware/Middlewares/ST/STM32_USB_Device_Library/Core/Inc/usbd_def.h rename to Firmware/Board/v3.3/Middlewares/ST/STM32_USB_Device_Library/Core/Inc/usbd_def.h diff --git a/Firmware/Middlewares/ST/STM32_USB_Device_Library/Core/Inc/usbd_ioreq.h b/Firmware/Board/v3.3/Middlewares/ST/STM32_USB_Device_Library/Core/Inc/usbd_ioreq.h similarity index 100% rename from Firmware/Middlewares/ST/STM32_USB_Device_Library/Core/Inc/usbd_ioreq.h rename to Firmware/Board/v3.3/Middlewares/ST/STM32_USB_Device_Library/Core/Inc/usbd_ioreq.h diff --git a/Firmware/Middlewares/ST/STM32_USB_Device_Library/Core/Src/usbd_core.c b/Firmware/Board/v3.3/Middlewares/ST/STM32_USB_Device_Library/Core/Src/usbd_core.c similarity index 100% rename from Firmware/Middlewares/ST/STM32_USB_Device_Library/Core/Src/usbd_core.c rename to Firmware/Board/v3.3/Middlewares/ST/STM32_USB_Device_Library/Core/Src/usbd_core.c diff --git a/Firmware/Middlewares/ST/STM32_USB_Device_Library/Core/Src/usbd_ctlreq.c b/Firmware/Board/v3.3/Middlewares/ST/STM32_USB_Device_Library/Core/Src/usbd_ctlreq.c similarity index 100% rename from Firmware/Middlewares/ST/STM32_USB_Device_Library/Core/Src/usbd_ctlreq.c rename to Firmware/Board/v3.3/Middlewares/ST/STM32_USB_Device_Library/Core/Src/usbd_ctlreq.c diff --git a/Firmware/Middlewares/ST/STM32_USB_Device_Library/Core/Src/usbd_ioreq.c b/Firmware/Board/v3.3/Middlewares/ST/STM32_USB_Device_Library/Core/Src/usbd_ioreq.c similarity index 100% rename from Firmware/Middlewares/ST/STM32_USB_Device_Library/Core/Src/usbd_ioreq.c rename to Firmware/Board/v3.3/Middlewares/ST/STM32_USB_Device_Library/Core/Src/usbd_ioreq.c diff --git a/Firmware/Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS/cmsis_os.c b/Firmware/Board/v3.3/Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS/cmsis_os.c similarity index 100% rename from Firmware/Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS/cmsis_os.c rename to Firmware/Board/v3.3/Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS/cmsis_os.c diff --git a/Firmware/Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS/cmsis_os.h b/Firmware/Board/v3.3/Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS/cmsis_os.h similarity index 100% rename from Firmware/Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS/cmsis_os.h rename to Firmware/Board/v3.3/Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS/cmsis_os.h diff --git a/Firmware/Middlewares/Third_Party/FreeRTOS/Source/croutine.c b/Firmware/Board/v3.3/Middlewares/Third_Party/FreeRTOS/Source/croutine.c similarity index 100% rename from Firmware/Middlewares/Third_Party/FreeRTOS/Source/croutine.c rename to Firmware/Board/v3.3/Middlewares/Third_Party/FreeRTOS/Source/croutine.c diff --git a/Firmware/Middlewares/Third_Party/FreeRTOS/Source/event_groups.c b/Firmware/Board/v3.3/Middlewares/Third_Party/FreeRTOS/Source/event_groups.c similarity index 100% rename from Firmware/Middlewares/Third_Party/FreeRTOS/Source/event_groups.c rename to Firmware/Board/v3.3/Middlewares/Third_Party/FreeRTOS/Source/event_groups.c diff --git a/Firmware/Middlewares/Third_Party/FreeRTOS/Source/include/FreeRTOS.h b/Firmware/Board/v3.3/Middlewares/Third_Party/FreeRTOS/Source/include/FreeRTOS.h similarity index 100% rename from Firmware/Middlewares/Third_Party/FreeRTOS/Source/include/FreeRTOS.h rename to Firmware/Board/v3.3/Middlewares/Third_Party/FreeRTOS/Source/include/FreeRTOS.h diff --git a/Firmware/Middlewares/Third_Party/FreeRTOS/Source/include/FreeRTOSConfig_template.h b/Firmware/Board/v3.3/Middlewares/Third_Party/FreeRTOS/Source/include/FreeRTOSConfig_template.h similarity index 100% rename from Firmware/Middlewares/Third_Party/FreeRTOS/Source/include/FreeRTOSConfig_template.h rename to Firmware/Board/v3.3/Middlewares/Third_Party/FreeRTOS/Source/include/FreeRTOSConfig_template.h diff --git a/Firmware/Middlewares/Third_Party/FreeRTOS/Source/include/StackMacros.h b/Firmware/Board/v3.3/Middlewares/Third_Party/FreeRTOS/Source/include/StackMacros.h similarity index 100% rename from Firmware/Middlewares/Third_Party/FreeRTOS/Source/include/StackMacros.h rename to Firmware/Board/v3.3/Middlewares/Third_Party/FreeRTOS/Source/include/StackMacros.h diff --git a/Firmware/Middlewares/Third_Party/FreeRTOS/Source/include/croutine.h b/Firmware/Board/v3.3/Middlewares/Third_Party/FreeRTOS/Source/include/croutine.h similarity index 100% rename from Firmware/Middlewares/Third_Party/FreeRTOS/Source/include/croutine.h rename to Firmware/Board/v3.3/Middlewares/Third_Party/FreeRTOS/Source/include/croutine.h diff --git a/Firmware/Middlewares/Third_Party/FreeRTOS/Source/include/deprecated_definitions.h b/Firmware/Board/v3.3/Middlewares/Third_Party/FreeRTOS/Source/include/deprecated_definitions.h similarity index 100% rename from Firmware/Middlewares/Third_Party/FreeRTOS/Source/include/deprecated_definitions.h rename to Firmware/Board/v3.3/Middlewares/Third_Party/FreeRTOS/Source/include/deprecated_definitions.h diff --git a/Firmware/Middlewares/Third_Party/FreeRTOS/Source/include/event_groups.h b/Firmware/Board/v3.3/Middlewares/Third_Party/FreeRTOS/Source/include/event_groups.h similarity index 100% rename from Firmware/Middlewares/Third_Party/FreeRTOS/Source/include/event_groups.h rename to Firmware/Board/v3.3/Middlewares/Third_Party/FreeRTOS/Source/include/event_groups.h diff --git a/Firmware/Middlewares/Third_Party/FreeRTOS/Source/include/list.h b/Firmware/Board/v3.3/Middlewares/Third_Party/FreeRTOS/Source/include/list.h similarity index 100% rename from Firmware/Middlewares/Third_Party/FreeRTOS/Source/include/list.h rename to Firmware/Board/v3.3/Middlewares/Third_Party/FreeRTOS/Source/include/list.h diff --git a/Firmware/Middlewares/Third_Party/FreeRTOS/Source/include/mpu_prototypes.h b/Firmware/Board/v3.3/Middlewares/Third_Party/FreeRTOS/Source/include/mpu_prototypes.h similarity index 100% rename from Firmware/Middlewares/Third_Party/FreeRTOS/Source/include/mpu_prototypes.h rename to Firmware/Board/v3.3/Middlewares/Third_Party/FreeRTOS/Source/include/mpu_prototypes.h diff --git a/Firmware/Middlewares/Third_Party/FreeRTOS/Source/include/mpu_wrappers.h b/Firmware/Board/v3.3/Middlewares/Third_Party/FreeRTOS/Source/include/mpu_wrappers.h similarity index 100% rename from Firmware/Middlewares/Third_Party/FreeRTOS/Source/include/mpu_wrappers.h rename to Firmware/Board/v3.3/Middlewares/Third_Party/FreeRTOS/Source/include/mpu_wrappers.h diff --git a/Firmware/Middlewares/Third_Party/FreeRTOS/Source/include/portable.h b/Firmware/Board/v3.3/Middlewares/Third_Party/FreeRTOS/Source/include/portable.h similarity index 100% rename from Firmware/Middlewares/Third_Party/FreeRTOS/Source/include/portable.h rename to Firmware/Board/v3.3/Middlewares/Third_Party/FreeRTOS/Source/include/portable.h diff --git a/Firmware/Middlewares/Third_Party/FreeRTOS/Source/include/projdefs.h b/Firmware/Board/v3.3/Middlewares/Third_Party/FreeRTOS/Source/include/projdefs.h similarity index 100% rename from Firmware/Middlewares/Third_Party/FreeRTOS/Source/include/projdefs.h rename to Firmware/Board/v3.3/Middlewares/Third_Party/FreeRTOS/Source/include/projdefs.h diff --git a/Firmware/Middlewares/Third_Party/FreeRTOS/Source/include/queue.h b/Firmware/Board/v3.3/Middlewares/Third_Party/FreeRTOS/Source/include/queue.h similarity index 100% rename from Firmware/Middlewares/Third_Party/FreeRTOS/Source/include/queue.h rename to Firmware/Board/v3.3/Middlewares/Third_Party/FreeRTOS/Source/include/queue.h diff --git a/Firmware/Middlewares/Third_Party/FreeRTOS/Source/include/semphr.h b/Firmware/Board/v3.3/Middlewares/Third_Party/FreeRTOS/Source/include/semphr.h similarity index 100% rename from Firmware/Middlewares/Third_Party/FreeRTOS/Source/include/semphr.h rename to Firmware/Board/v3.3/Middlewares/Third_Party/FreeRTOS/Source/include/semphr.h diff --git a/Firmware/Middlewares/Third_Party/FreeRTOS/Source/include/task.h b/Firmware/Board/v3.3/Middlewares/Third_Party/FreeRTOS/Source/include/task.h similarity index 100% rename from Firmware/Middlewares/Third_Party/FreeRTOS/Source/include/task.h rename to Firmware/Board/v3.3/Middlewares/Third_Party/FreeRTOS/Source/include/task.h diff --git a/Firmware/Middlewares/Third_Party/FreeRTOS/Source/include/timers.h b/Firmware/Board/v3.3/Middlewares/Third_Party/FreeRTOS/Source/include/timers.h similarity index 100% rename from Firmware/Middlewares/Third_Party/FreeRTOS/Source/include/timers.h rename to Firmware/Board/v3.3/Middlewares/Third_Party/FreeRTOS/Source/include/timers.h diff --git a/Firmware/Middlewares/Third_Party/FreeRTOS/Source/list.c b/Firmware/Board/v3.3/Middlewares/Third_Party/FreeRTOS/Source/list.c similarity index 100% rename from Firmware/Middlewares/Third_Party/FreeRTOS/Source/list.c rename to Firmware/Board/v3.3/Middlewares/Third_Party/FreeRTOS/Source/list.c diff --git a/Firmware/Middlewares/Third_Party/FreeRTOS/Source/portable/GCC/ARM_CM4F/port.c b/Firmware/Board/v3.3/Middlewares/Third_Party/FreeRTOS/Source/portable/GCC/ARM_CM4F/port.c similarity index 100% rename from Firmware/Middlewares/Third_Party/FreeRTOS/Source/portable/GCC/ARM_CM4F/port.c rename to Firmware/Board/v3.3/Middlewares/Third_Party/FreeRTOS/Source/portable/GCC/ARM_CM4F/port.c diff --git a/Firmware/Middlewares/Third_Party/FreeRTOS/Source/portable/GCC/ARM_CM4F/portmacro.h b/Firmware/Board/v3.3/Middlewares/Third_Party/FreeRTOS/Source/portable/GCC/ARM_CM4F/portmacro.h similarity index 100% rename from Firmware/Middlewares/Third_Party/FreeRTOS/Source/portable/GCC/ARM_CM4F/portmacro.h rename to Firmware/Board/v3.3/Middlewares/Third_Party/FreeRTOS/Source/portable/GCC/ARM_CM4F/portmacro.h diff --git a/Firmware/Middlewares/Third_Party/FreeRTOS/Source/portable/MemMang/heap_4.c b/Firmware/Board/v3.3/Middlewares/Third_Party/FreeRTOS/Source/portable/MemMang/heap_4.c similarity index 100% rename from Firmware/Middlewares/Third_Party/FreeRTOS/Source/portable/MemMang/heap_4.c rename to Firmware/Board/v3.3/Middlewares/Third_Party/FreeRTOS/Source/portable/MemMang/heap_4.c diff --git a/Firmware/Middlewares/Third_Party/FreeRTOS/Source/queue.c b/Firmware/Board/v3.3/Middlewares/Third_Party/FreeRTOS/Source/queue.c similarity index 100% rename from Firmware/Middlewares/Third_Party/FreeRTOS/Source/queue.c rename to Firmware/Board/v3.3/Middlewares/Third_Party/FreeRTOS/Source/queue.c diff --git a/Firmware/Middlewares/Third_Party/FreeRTOS/Source/tasks.c b/Firmware/Board/v3.3/Middlewares/Third_Party/FreeRTOS/Source/tasks.c similarity index 100% rename from Firmware/Middlewares/Third_Party/FreeRTOS/Source/tasks.c rename to Firmware/Board/v3.3/Middlewares/Third_Party/FreeRTOS/Source/tasks.c diff --git a/Firmware/Middlewares/Third_Party/FreeRTOS/Source/timers.c b/Firmware/Board/v3.3/Middlewares/Third_Party/FreeRTOS/Source/timers.c similarity index 100% rename from Firmware/Middlewares/Third_Party/FreeRTOS/Source/timers.c rename to Firmware/Board/v3.3/Middlewares/Third_Party/FreeRTOS/Source/timers.c diff --git a/Firmware/Odrive.ioc b/Firmware/Board/v3.3/Odrive.ioc similarity index 100% rename from Firmware/Odrive.ioc rename to Firmware/Board/v3.3/Odrive.ioc diff --git a/Firmware/STM32F405RGTx_FLASH.ld b/Firmware/Board/v3.3/STM32F405RGTx_FLASH.ld similarity index 100% rename from Firmware/STM32F405RGTx_FLASH.ld rename to Firmware/Board/v3.3/STM32F405RGTx_FLASH.ld diff --git a/Firmware/Src/adc.c b/Firmware/Board/v3.3/Src/adc.c similarity index 100% rename from Firmware/Src/adc.c rename to Firmware/Board/v3.3/Src/adc.c diff --git a/Firmware/Src/can.c b/Firmware/Board/v3.3/Src/can.c similarity index 100% rename from Firmware/Src/can.c rename to Firmware/Board/v3.3/Src/can.c diff --git a/Firmware/Src/dma.c b/Firmware/Board/v3.3/Src/dma.c similarity index 100% rename from Firmware/Src/dma.c rename to Firmware/Board/v3.3/Src/dma.c diff --git a/Firmware/Src/freertos.c b/Firmware/Board/v3.3/Src/freertos.c similarity index 100% rename from Firmware/Src/freertos.c rename to Firmware/Board/v3.3/Src/freertos.c diff --git a/Firmware/Src/gpio.c b/Firmware/Board/v3.3/Src/gpio.c similarity index 100% rename from Firmware/Src/gpio.c rename to Firmware/Board/v3.3/Src/gpio.c diff --git a/Firmware/Src/main.c b/Firmware/Board/v3.3/Src/main.c similarity index 100% rename from Firmware/Src/main.c rename to Firmware/Board/v3.3/Src/main.c diff --git a/Firmware/Src/prev_board_ver/adc_V3_2.c b/Firmware/Board/v3.3/Src/prev_board_ver/adc_V3_2.c similarity index 100% rename from Firmware/Src/prev_board_ver/adc_V3_2.c rename to Firmware/Board/v3.3/Src/prev_board_ver/adc_V3_2.c diff --git a/Firmware/Src/prev_board_ver/gpio_V3_2.c b/Firmware/Board/v3.3/Src/prev_board_ver/gpio_V3_2.c similarity index 100% rename from Firmware/Src/prev_board_ver/gpio_V3_2.c rename to Firmware/Board/v3.3/Src/prev_board_ver/gpio_V3_2.c diff --git a/Firmware/Src/spi.c b/Firmware/Board/v3.3/Src/spi.c similarity index 100% rename from Firmware/Src/spi.c rename to Firmware/Board/v3.3/Src/spi.c diff --git a/Firmware/Src/stm32f4xx_hal_msp.c b/Firmware/Board/v3.3/Src/stm32f4xx_hal_msp.c similarity index 100% rename from Firmware/Src/stm32f4xx_hal_msp.c rename to Firmware/Board/v3.3/Src/stm32f4xx_hal_msp.c diff --git a/Firmware/Src/stm32f4xx_hal_timebase_TIM.c b/Firmware/Board/v3.3/Src/stm32f4xx_hal_timebase_TIM.c similarity index 100% rename from Firmware/Src/stm32f4xx_hal_timebase_TIM.c rename to Firmware/Board/v3.3/Src/stm32f4xx_hal_timebase_TIM.c diff --git a/Firmware/Src/stm32f4xx_it.c b/Firmware/Board/v3.3/Src/stm32f4xx_it.c similarity index 100% rename from Firmware/Src/stm32f4xx_it.c rename to Firmware/Board/v3.3/Src/stm32f4xx_it.c diff --git a/Firmware/Src/syscalls.c b/Firmware/Board/v3.3/Src/syscalls.c similarity index 100% rename from Firmware/Src/syscalls.c rename to Firmware/Board/v3.3/Src/syscalls.c diff --git a/Firmware/Src/system_stm32f4xx.c b/Firmware/Board/v3.3/Src/system_stm32f4xx.c similarity index 100% rename from Firmware/Src/system_stm32f4xx.c rename to Firmware/Board/v3.3/Src/system_stm32f4xx.c diff --git a/Firmware/Src/tim.c b/Firmware/Board/v3.3/Src/tim.c similarity index 100% rename from Firmware/Src/tim.c rename to Firmware/Board/v3.3/Src/tim.c diff --git a/Firmware/Src/usart.c b/Firmware/Board/v3.3/Src/usart.c similarity index 100% rename from Firmware/Src/usart.c rename to Firmware/Board/v3.3/Src/usart.c diff --git a/Firmware/Src/usb_device.c b/Firmware/Board/v3.3/Src/usb_device.c similarity index 100% rename from Firmware/Src/usb_device.c rename to Firmware/Board/v3.3/Src/usb_device.c diff --git a/Firmware/Src/usbd_cdc_if.c b/Firmware/Board/v3.3/Src/usbd_cdc_if.c similarity index 100% rename from Firmware/Src/usbd_cdc_if.c rename to Firmware/Board/v3.3/Src/usbd_cdc_if.c diff --git a/Firmware/Src/usbd_conf.c b/Firmware/Board/v3.3/Src/usbd_conf.c similarity index 100% rename from Firmware/Src/usbd_conf.c rename to Firmware/Board/v3.3/Src/usbd_conf.c diff --git a/Firmware/Src/usbd_desc.c b/Firmware/Board/v3.3/Src/usbd_desc.c similarity index 100% rename from Firmware/Src/usbd_desc.c rename to Firmware/Board/v3.3/Src/usbd_desc.c diff --git a/Firmware/startup/startup_stm32f405xx.s b/Firmware/Board/v3.3/startup/startup_stm32f405xx.s similarity index 100% rename from Firmware/startup/startup_stm32f405xx.s rename to Firmware/Board/v3.3/startup/startup_stm32f405xx.s diff --git a/Firmware/Makefile b/Firmware/Makefile index 3ad6d167..680d59de 100644 --- a/Firmware/Makefile +++ b/Firmware/Makefile @@ -1,213 +1,23 @@ -###################################### -# Makefile by CubeMX2Makefile.py -###################################### -###################################### -# target -###################################### -TARGET = ODriveFirmware +# This is only a stub for various commands. +# Tup is used for the actual compilation. -###################################### -# building variables -###################################### -# debug build? -DEBUG = 1 -# optimization -OPT = -Og -ffast-math +FIRMWARE = build/ODriveFirmware.elf -####################################### -# pathes -####################################### -# Build path -BUILD_DIR = build +all: + tup -###################################### -# source -###################################### -C_SOURCES = \ - Middlewares/Third_Party/FreeRTOS/Source/queue.c \ - Middlewares/Third_Party/FreeRTOS/Source/tasks.c \ - Middlewares/Third_Party/FreeRTOS/Source/list.c \ - Middlewares/Third_Party/FreeRTOS/Source/event_groups.c \ - Middlewares/Third_Party/FreeRTOS/Source/croutine.c \ - Middlewares/Third_Party/FreeRTOS/Source/timers.c \ - Middlewares/Third_Party/FreeRTOS/Source/portable/GCC/ARM_CM4F/port.c \ - Middlewares/Third_Party/FreeRTOS/Source/portable/MemMang/heap_4.c \ - Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS/cmsis_os.c \ - Middlewares/ST/STM32_USB_Device_Library/Core/Src/usbd_core.c \ - Middlewares/ST/STM32_USB_Device_Library/Core/Src/usbd_ioreq.c \ - Middlewares/ST/STM32_USB_Device_Library/Core/Src/usbd_ctlreq.c \ - Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Src/usbd_cdc.c \ - Src/system_stm32f4xx.c \ - Src/stm32f4xx_it.c \ - Src/stm32f4xx_hal_msp.c \ - Src/stm32f4xx_hal_timebase_TIM.c \ - Src/tim.c \ - Src/gpio.c \ - Src/main.c \ - Src/adc.c \ - Src/freertos.c \ - Src/spi.c \ - Src/can.c \ - Src/usart.c \ - Src/dma.c \ - Src/usbd_conf.c \ - Src/usbd_desc.c \ - Src/usb_device.c \ - Drivers/DRV8301/drv8301.c \ - Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal.c \ - Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_rcc.c \ - Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_tim_ex.c \ - Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_flash_ramfunc.c \ - Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_spi.c \ - Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_rcc_ex.c \ - Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_flash.c \ - Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_flash_ex.c \ - Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_can.c \ - Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_adc.c \ - Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_dma.c \ - Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_cortex.c \ - Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_pwr_ex.c \ - Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_tim.c \ - Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_gpio.c \ - Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_dma_ex.c \ - Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_pwr.c \ - Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_adc_ex.c \ - Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_pcd.c \ - Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_pcd_ex.c \ - Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_uart.c \ - Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_ll_usb.c \ - Src/usbd_cdc_if.c \ - Src/syscalls.c \ - MotorControl/utils.c \ - MotorControl/legacy_commands.c \ - MotorControl/low_level.c -CPP_SOURCES = \ - MotorControl/axis.cpp \ - MotorControl/commands.cpp \ - MotorControl/protocol.cpp -ASM_SOURCES = \ - startup/startup_stm32f405xx.s +flash: all + openocd -f interface/stlink-v2.cfg -f target/stm32f4x.cfg -c init -c reset\ halt -c flash\ write_image\ erase\ $(FIRMWARE) -c reset\ run -c exit -####################################### -# binaries -####################################### -CC = arm-none-eabi-gcc -CXX = arm-none-eabi-g++ -AS = arm-none-eabi-gcc -x assembler-with-cpp -CP = arm-none-eabi-objcopy -AR = arm-none-eabi-ar -SZ = arm-none-eabi-size -HEX = $(CP) -O ihex -BIN = $(CP) -O binary -S - -####################################### -# CFLAGS -####################################### -# macros for gcc -AS_DEFS = -C_DEFS = -D__weak="__attribute__((weak))" -D__packed="__attribute__((__packed__))" -DUSE_HAL_DRIVER -DSTM32F405xx -# includes for gcc -AS_INCLUDES = -C_INCLUDES = -IMiddlewares/Third_Party/FreeRTOS/Source/portable/GCC/ARM_CM4F -C_INCLUDES += -IMiddlewares/Third_Party/FreeRTOS/Source/include -C_INCLUDES += -IMiddlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS -C_INCLUDES += -IDrivers/DRV8301 -C_INCLUDES += -IMiddlewares/ST/STM32_USB_Device_Library/Core/Inc -C_INCLUDES += -IMiddlewares/ST/STM32_USB_Device_Library/Class/CDC/Inc -C_INCLUDES += -IDrivers/STM32F4xx_HAL_Driver/Inc -C_INCLUDES += -IDrivers/STM32F4xx_HAL_Driver/Inc/Legacy -C_INCLUDES += -IDrivers/CMSIS/Device/ST/STM32F4xx/Include -C_INCLUDES += -IDrivers/CMSIS/Include -C_INCLUDES += -IInc -C_INCLUDES += -IMotorControl -# compile gcc flags -ASFLAGS = -mthumb -mcpu=cortex-m4 -mfpu=fpv4-sp-d16 -mfloat-abi=hard $(AS_DEFS) $(AS_INCLUDES) $(OPT) -Wall -fdata-sections -ffunction-sections -CFLAGS = -mthumb -mcpu=cortex-m4 -mfpu=fpv4-sp-d16 -mfloat-abi=hard $(C_DEFS) $(C_INCLUDES) $(OPT) -Wall -fdata-sections -ffunction-sections -CXXFLAGS = -mthumb -mcpu=cortex-m4 -mfpu=fpv4-sp-d16 -mfloat-abi=hard $(C_DEFS) $(C_INCLUDES) $(OPT) -Wall -fdata-sections -ffunction-sections -ifeq ($(DEBUG), 1) -CFLAGS += -g -gdwarf-2 -CXXFLAGS += -g -gdwarf-2 -endif -# Generate dependency information -CFLAGS += -std=c99 -MD -MP -MF .dep/$(@F).d -CXXFLAGS += -std=c++14 -MD -MP -MF .dep/$(@F).d +gdb: all + arm-none-eabi-gdb $(FIRMWARE) -x openocd.gdbinit -####################################### -# LDFLAGS -####################################### -# link script -LDSCRIPT = STM32F405RGTx_FLASH.ld -# libraries -LIBS = -lc -lm -lnosys -larm_cortexM4lf_math -LIBDIR = -LDrivers/CMSIS/Lib -LDFLAGS = -mthumb -mcpu=cortex-m4 -mfpu=fpv4-sp-d16 -mfloat-abi=hard -specs=nosys.specs -specs=nano.specs -u _printf_float -u _scanf_float $(OPT) -T$(LDSCRIPT) $(LIBDIR) $(LIBS) -Wl,-Map=$(BUILD_DIR)/$(TARGET).map,--cref -Wl,--gc-sections - -# default action: build all -all: $(BUILD_DIR)/$(TARGET).elf $(BUILD_DIR)/$(TARGET).hex $(BUILD_DIR)/$(TARGET).bin - -####################################### -# build the application -####################################### -# list of objects -OBJECTS = $(addprefix $(BUILD_DIR)/,$(notdir $(C_SOURCES:.c=.o))) -vpath %.c $(sort $(dir $(C_SOURCES))) -# list of C++ objects -OBJECTS += $(addprefix $(BUILD_DIR)/,$(notdir $(CPP_SOURCES:.cpp=.o))) -vpath %.cpp $(sort $(dir $(CPP_SOURCES))) -# list of ASM program objects -OBJECTS += $(addprefix $(BUILD_DIR)/,$(notdir $(ASM_SOURCES:.s=.o))) -vpath %.s $(sort $(dir $(ASM_SOURCES))) - -$(BUILD_DIR)/%.o: %.c Makefile | $(BUILD_DIR) - @$(CC) -c $(CFLAGS) -Wa,-a,-ad,-alms=$(BUILD_DIR)/$(notdir $(<:.c=.lst)) $< -o $@ - -$(BUILD_DIR)/%.o: %.cpp Makefile | $(BUILD_DIR) - @$(CXX) -c $(CXXFLAGS) -Wa,-a,-ad,-alms=$(BUILD_DIR)/$(notdir $(<:.cpp=.lst)) $< -o $@ - -$(BUILD_DIR)/%.o: %.s Makefile | $(BUILD_DIR) - @$(AS) -c $(CFLAGS) $< -o $@ - -$(BUILD_DIR)/$(TARGET).elf: $(OBJECTS) Makefile - @$(CXX) $(OBJECTS) $(LDFLAGS) -o $@ - $(SZ) $@ - -$(BUILD_DIR)/%.hex: $(BUILD_DIR)/%.elf | $(BUILD_DIR) - @$(HEX) $< $@ - -$(BUILD_DIR)/%.bin: $(BUILD_DIR)/%.elf | $(BUILD_DIR) - @$(BIN) $< $@ - -$(BUILD_DIR): - mkdir -p $@ - -####################################### -# clean up -####################################### -clean: - -rm -fR .dep $(BUILD_DIR) - -####################################### -# flashing / debug -####################################### - -flash: $(BUILD_DIR)/$(TARGET).elf - openocd -f interface/stlink-v2.cfg -f target/stm32f4x.cfg -c init -c reset\ halt -c flash\ write_image\ erase\ $(BUILD_DIR)/$(TARGET).elf -c reset\ run -c exit - -gdb: $(BUILD_DIR)/$(TARGET).elf - arm-none-eabi-gdb $(BUILD_DIR)/$(TARGET).elf -x openocd.gdbinit - -bmp: $(BUILD_DIR)/$(TARGET).elf +bmp: all arm-none-eabi-gdb --ex 'target extended-remote /dev/stlink' \ --ex 'monitor swdp_scan' \ --ex 'attach 1' \ - --ex 'load' $(BUILD_DIR)/$(TARGET).elf + --ex 'load' $(FIRMWARE) -####################################### -# dependencies -####################################### --include $(shell mkdir .dep 2>/dev/null) $(wildcard .dep/*) +.PHONY: all flash gdb bmp -.PHONY: clean all flash gdb - -# *** EOF *** diff --git a/Firmware/README.md b/Firmware/README.md index bd9602bd..f0f7e8be 100644 --- a/Firmware/README.md +++ b/Firmware/README.md @@ -120,26 +120,34 @@ To compile the program, you first need to install the prerequisite tools: #### Linux: * `gcc-arm-none-eabi`: GCC compilation toolchain for ARM microcontrollers. * Installing on Ubuntu: `sudo apt-get install gcc-arm-none-eabi` + * Installing on Arch Linux: `sudo pacman -S arm-none-eabi-gcc arm-none-eabi-binutils` * `gdb-arm-none-eabi`: GNU project debugger for ARM microcontrollers. * Installing on Ubuntu: `sudo apt-get install gdb-arm-none-eabi` + * Installing on Arch Linux: `sudo pacman -S arm-none-eabi-gdb` * `OpenOCD`: Open On-Chip Debugging tools. This is what we use to flash the code onto the microcontroller. * Installing on Ubuntu: `sudo apt-get install openocd` + * Installing on Arch Linux: build and install the [AUR package](https://aur.archlinux.org/packages/openocd/) +* `tup`: Used as a build tool + * Installing on Ubuntu: `sudo apt-add-repository 'deb http://ppa.launchpad.net/anatol/tup/ubuntu precise main'; sudo apt-get update; sudo apt-get install tup` + * Installing on Arch Linux: `sudo pacman -S tup` * No additional USB CDC driver should be required on Linux. #### Mac: * `brew cask install gcc-arm-embedded`: GCC toolchain+debugger +* `brew tap homebrew/fuse; brew install homebrew/fuse/tup`: Build tool * `brew install openocd`: Programmer #### Windows: Install the following: * [Git for windows](https://git-scm.com/download/win). This intalls the Git Bash, which is a unix style command line interface that we will be using. * [GNU ARM Embedded Toolchain](https://developer.arm.com/open-source/gnu-toolchain/gnu-rm/downloads). The cross-compiler used to compile the code. Download and install the "Windows 32-bit" version. Make sure to tick the "add to path" option. -* [Make for Windows](http://gnuwin32.sourceforge.net/packages/make.htm). Make is used to script the compilation process. Download and run the complete package setup program. Add the path of the binaries to your PATH environment variable. For me this was at `C:\Program Files (x86)\GnuWin32\bin`. For details on how to set your path envirment in windows see [these instructions.](https://www.java.com/en/download/help/path.xml) +* [Tup](http://gittup.org/tup/index.html) is used to script the compilation process. Unpack the zip-folder. Then add the path that contains the executable (something like `C:\Users\yourname\Downloads\tup-latest`) to your PATH environment variable. For details on how to set your path envirment in windows see [these instructions.](https://www.java.com/en/download/help/path.xml) +* [Make for Windows](http://gnuwin32.sourceforge.net/packages/make.htm). This is optional and mainly used because commands are short and developers are used to it. If you don't want to use it, you can look at the Makefile to get the corresponding commands. Download and run the complete package setup program. Add the path of the binaries to your PATH environment variable. For me this was at `C:\Program Files (x86)\GnuWin32\bin`. * OpenOCD. Follow the instructions at [GNU ARM Eclipse - How to install the OpenOCD binaries](http://gnuarmeclipse.github.io/openocd/install/), including the part about ST-LINK/V2 drivers. Add the path of the binaries to your PATH environment variable. For me this was at `C:\Program Files\GNU ARM Eclipse\OpenOCD\0.10.0-201704182147-dev\bin`.

## Setting up an IDE -ODrive is a Makefile project. It does not require an IDE, but the open-source IDE VSCode is recommended. It is also possible to use Eclipse. If you'd like to go that route, please see the respective configuration document: +For working with the ODrive code you don't need an IDE, but the open-source IDE VSCode is recommended. It is also possible to use Eclipse. If you'd like to go that route, please see the respective configuration document: * [Configuring VSCode](configuring-vscode.md) * [Configuring Eclipse](configuring-eclipse.md) diff --git a/Firmware/Tupfile.lua b/Firmware/Tupfile.lua new file mode 100644 index 00000000..171c0d43 --- /dev/null +++ b/Firmware/Tupfile.lua @@ -0,0 +1,76 @@ + +tup.include('build.lua') + +boarddir = 'Board/v3.3' + + +-- C-specific flags +FLAGS += '-D__weak="__attribute__((weak))"' +FLAGS += '-D__packed="__attribute__((__packed__))"' +FLAGS += '-DUSE_HAL_DRIVER' +FLAGS += '-DSTM32F405xx' + +FLAGS += '-mthumb' +FLAGS += '-mcpu=cortex-m4' +FLAGS += '-mfpu=fpv4-sp-d16' +FLAGS += '-mfloat-abi=hard' +FLAGS += { '-Wall', '-fdata-sections', '-ffunction-sections'} + +if tup.getconfig('DEBUG') == 'y' then + --C_FLAGS += '-g -gdwarf-2' + FLAGS += '-g -gdwarf-2' +end + +-- linker flags +LDFLAGS += '-T'..boarddir..'/STM32F405RGTx_FLASH.ld' +LDFLAGS += '-L'..boarddir..'/Drivers/CMSIS/Lib' -- lib dir +LDFLAGS += '-lc -lm -lnosys -larm_cortexM4lf_math' -- libs +LDFLAGS += '-mthumb -mcpu=cortex-m4 -mfpu=fpv4-sp-d16 -mfloat-abi=hard -specs=nosys.specs -specs=nano.specs -u _printf_float -u _scanf_float -Wl,--cref -Wl,--gc-sections' + + +-- common flags for ASM, C and C++ +OPT += '-Og' +OPT += '-ffast-math' +tup.append_table(FLAGS, OPT) +tup.append_table(LDFLAGS, OPT) + +toolchain = GCCToolchain('arm-none-eabi-', 'build', FLAGS, LDFLAGS) + + +-- Load list of source files Makefile that was autogenerated by CubeMX +vars = parse_makefile_vars(boarddir..'/Makefile') +all_stm_sources = (vars['C_SOURCES'] or '')..' '..(vars['CPP_SOURCES'] or '')..' '..(vars['ASM_SOURCES'] or '') +for src in string.gmatch(all_stm_sources, "%S+") do + stm_sources += boarddir..'/'..src +end +for src in string.gmatch(vars['C_INCLUDES'] or '', "%S+") do + stm_includes += boarddir..'/'..string.sub(src, 3, -1) -- remove "-I" from each include path +end + +stm_includes += 'MotorControl' +build{ + name='stm_platform', + type='objects', + toolchains={toolchain}, + packages={}, + sources=stm_sources, + includes=stm_includes +} + +build{ + name='ODriveFirmware', + toolchains={toolchain}, + --toolchains={LLVMToolchain('x86_64', {'-Ofast'}, {'-flto'})}, + packages={'stm_platform'}, + sources={ + 'MotorControl/utils.c', + 'MotorControl/legacy_commands.c', + 'MotorControl/low_level.c', + 'MotorControl/axis.cpp', + 'MotorControl/commands.cpp', + 'MotorControl/protocol.cpp' + }, + includes={ + 'MotorControl' + } +} diff --git a/Firmware/build.lua b/Firmware/build.lua new file mode 100644 index 00000000..6e4ecdd9 --- /dev/null +++ b/Firmware/build.lua @@ -0,0 +1,166 @@ + +-- This file contains support functions for Tupfile.lua + +function trim(s) + return (s:gsub("^%s*(.-)%s*$", "%1")) +end + +function string:split(sep) + local sep, fields = sep or ":", {} + local pattern = string.format("([^%s]+)", sep) + self:gsub(pattern, function(c) fields[#fields+1] = c end) + return fields +end + +-- Very basic parser to retrieve variables from a Makefile +function parse_makefile_vars(makefile) + vars = {} + current_var = nil + for line in io.lines(tup.getcwd()..'/'..makefile) do + if current_var == nil then + i,j = string.find(line, "+=") + if not i then + i,j = string.find(line, "=") + end + if i then + current_var = trim(string.sub(line, 1, i-1)) + vars[current_var] = vars[current_var] or '' + line = string.sub(line, j+1, -1) + --print("varname: "..varname.." the rest: "..line) + end + end + + if current_var != nil then + --print("append chunk "..trim(line).." to "..current_var) + vars[current_var] = vars[current_var]..' '..trim(line) + if string.sub(vars[current_var], -1) == '\\' then + vars[current_var] = string.sub(vars[current_var], 1, -2) + else + current_var = nil + end + end + end + return vars +end + + + + +function GCCToolchain(prefix, builddir, compiler_flags, linker_flags) + + -- add some default compiler flags + compiler_flags += '-fstack-usage' + + gcc_generic_compiler = function(compiler, compiler_flags, gen_su_file, src, flags, includes, outputs) + -- convert include list to flags + inc_flags = {} + for _,inc in pairs(includes) do + inc_flags += "-I"..inc + end + -- todo: vary build directory + obj_file = builddir.."/"..src:gsub("/","_")..".o" + outputs.object_files += obj_file + if gen_su_file then + su_file = builddir.."/"..src:gsub("/","_")..".su" + extra_outputs = { su_file } + outputs.su_files += su_file + else + extra_outputs = {} + end + tup.frule{ + inputs= { src }, + command=compiler..' -c %f '.. + tostring(compiler_flags)..' '.. -- CFLAGS for this compiler + tostring(inc_flags)..' '.. -- CFLAGS for this translation unit + tostring(flags).. -- CFLAGS for this translation unit + ' -o %o', + outputs={obj_file,extra_outputs=extra_outputs} + } + end + return { + compile_c = function(src, flags, includes, outputs) gcc_generic_compiler(prefix..'gcc -std=c99', compiler_flags, true, src, flags, includes, outputs) end, + compile_cpp = function(src, flags, includes, outputs) gcc_generic_compiler(prefix..'g++ -std=c++14', compiler_flags, true, src, flags, includes, outputs) end, + compile_asm = function(src, flags, includes, outputs) gcc_generic_compiler(prefix..'gcc -x assembler-with-cpp', compiler_flags, false, src, flags, includes, outputs) end, + link = function(objects, output_name) + output_name = builddir..'/'..output_name + tup.frule{ + inputs=objects, + command=prefix..'g++ %f '.. + tostring(linker_flags)..' '.. + '-Wl,-Map=%O.map'.. + ' -o %o; '.. + prefix..'size %o', + outputs={output_name..'.elf', extra_outputs={output_name..'.map'}} + } + tup.frule{inputs={output_name..'.elf'}, command=prefix..'objcopy -O ihex %f %o', outputs={output_name..'.hex'}} + tup.frule{inputs={output_name..'.elf'}, command=prefix..'objcopy -O binary -S %f %o', outputs={output_name..'.bin'}} + end + } +end + +all_packages = {} + +-- toolchains: Each element of this list is a collection of functions, such as compile_c, link, ... +-- You can create a new toolchain object for each platform you want to build for. +function build(args) + if args.toolchain == nil then args.toolchain = {} end + if args.sources == nil then args.sources = {} end + if args.includes == nil then args.includes = {} end + if args.packages == nil then args.packages = {} end + if args.c_flags == nil then args.c_flags = {} end + if args.cpp_flags == nil then args.cpp_flags = {} end + if args.asm_flags == nil then args.asm_flags = {} end + if args.ld_flags == nil then args.ld_flags = {} end + if args.linker_objects == nil then args.linker_objects = {} end + + -- add includes of other packages + for _,pkg_name in pairs(args.packages) do + --print('depend on package '..pkg_name) + pkg = all_packages[pkg_name] + if pkg == nil then + error("unknown package "..pkg_name) + end + -- add path of each include + for _,inc in pairs(pkg.includes or {}) do + args.includes += tostring(inc) + end + tup.append_table(args.linker_objects, pkg.object_files) + end + + -- run everything once for every toolchain + for _,toolchain in pairs(args.toolchains) do + -- compile + outputs = {} + for _,src in pairs(args.sources) do + --print("compile "..src) + if tup.ext(src) == 'c' then + toolchain.compile_c(src, args.c_flags, args.includes, outputs) + elseif tup.ext(src) == 'cpp' then + toolchain.compile_cpp(src, args.cpp_flags, args.includes, outputs) + elseif tup.ext(src) == 's' or tup.ext(src) == 'asm' then + toolchain.compile_asm(src, args.asm_flags, args.includes, outputs) + else + error('unrecognized file ending') + end + end + + -- link + if outputs.object_files != nil and args.type != 'objects' then + tup.append_table(args.linker_objects, outputs.object_files) + toolchain.link(args.linker_objects, args.name) + end + + outputs.includes = {} + for _,inc in pairs(args.includes) do + table.insert(outputs.includes, tup.nodevariable(inc)) + end + if args.name != nil then + all_packages[args.name] = outputs + end + end + + --for k,v in pairs(all_packages) do + -- print('have package '..k) + --end +end + diff --git a/README.md b/README.md index 2c93fd63..192a3c6b 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,11 @@ This project is all about accurately driving brushless motors, for cheap. The aim is to make it possible to use inexpensive brushless motors in high performance robotics projects, like [this](https://www.youtube.com/watch?v=WT4E5nb3KtY). +| Branch | Build Status | +|--------|--------------| +| master | [![Build Status](https://travis-ci.org/madcowswe/ODrive.png?branch=master)](https://travis-ci.org/madcowswe/ODrive) | +| devel | [![Build Status](https://travis-ci.org/madcowswe/ODrive.png?branch=devel)](https://travis-ci.org/madcowswe/ODrive) | + ## Getting Started It is perfectly fine, and even recommended, to start testing with just a single motor and encoder. Make sure you have a good mechanical connection between the encoder and the motor, slip can cause disasterous oscillations. diff --git a/Tupfile.ini b/Tupfile.ini new file mode 100644 index 00000000..e69de29b From 36b451a2784fdd6905b40701f21682a2c2093559 Mon Sep 17 00:00:00 2001 From: Samuel Sadok Date: Sun, 25 Feb 2018 15:29:56 -0800 Subject: [PATCH 21/53] add version number for NVM config, add code comments --- Firmware/MotorControl/config.cpp | 38 ++++++++++++++++++++++++++++++-- 1 file changed, 36 insertions(+), 2 deletions(-) diff --git a/Firmware/MotorControl/config.cpp b/Firmware/MotorControl/config.cpp index f7528509..41e97ea6 100644 --- a/Firmware/MotorControl/config.cpp +++ b/Firmware/MotorControl/config.cpp @@ -12,6 +12,10 @@ #include "low_level.h" #include "axis.h" +// IMPORTANT: if you change, reorder or otherwise modify any of the fields in +// the config structs, make sure to increment this number: +uint16_t config_version = 0x0001; + /* Private defines -----------------------------------------------------------*/ #define CRC16_INIT 0xabcd @@ -48,6 +52,15 @@ typedef struct { /* Private function prototypes -----------------------------------------------*/ /* Function implementations --------------------------------------------------*/ +// @brief Manages configuration load and store operations from and to NVM +// +// The NVM stores consecutive one-to-one copies of arbitrary objects. +// The types of these objects are passed as template arguments to Config. +// +// Config has two template specializations to implement template recursion: +// - Config handles loading/storing of the first object (type T) and leaves +// the rest of the objects to an "inner" class Config. +// - Config<> represents the leaf of the recursion. template struct Config; @@ -70,6 +83,12 @@ struct Config { return sizeof(T) + Config::get_size(); } + // @brief Loads one or more consecutive objects from the NVM. + // During loading this function also calculates the CRC over the loaded data. + // @param offset: 0 means that the function should start reading at the beginning + // of the last comitted NVM block + // @param crc16: the result of the CRC calculation is written to this address + // @param val0, vals: the values to be loaded static int load_config(size_t offset, uint16_t* crc16, T* val0, Ts* ... vals) { size_t size = sizeof(T); // save current CRC (in case val0 and crc16 point to the same address) @@ -82,6 +101,12 @@ struct Config { return 0; } + // @brief Stores one or more consecutive objects to the NVM. + // During storing this function also calculates the CRC over the stored data. + // @param offset: 0 means that the function should start writing at the beginning + // of the currently active NVM write block + // @param crc16: the result of the CRC calculation is written to this address + // @param val0, vals: the values to be stored 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)) @@ -94,11 +119,13 @@ struct Config { return 0; } + // @brief Loads one or more consecutive objects from the NVM. The loaded data + // is validated using a CRC value that is stored at the beginning of the data. static int load_config(T* val0, Ts* ... vals) { //printf("have %d bytes\r\n", NVM_get_max_read_length()); osDelay(5); if (Config::get_size() > NVM_get_max_read_length()) return -1; - uint16_t crc16 = CRC16_INIT; + uint16_t crc16 = CRC16_INIT ^ config_version; if (Config::load_config(0, &crc16, val0, vals..., &crc16)) return -1; if (crc16) @@ -106,6 +133,13 @@ struct Config { return 0; } + // @brief Stores one or more consecutive objects to the NVM. In addition to the + // provided objects, a CRC of the data is stored. + // + // The CRC includes a version number and thus adds some protection against + // changes of the config structs during firmware update. Note that if the total + // config data length changes, the CRC validation will fail even if the developer + // forgets to update the config version number. 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); @@ -113,7 +147,7 @@ struct Config { return -1; if (NVM_start_write(size)) return -1; - uint16_t crc16 = CRC16_INIT; // TODO: this is not a sufficient method to protect against changes of the struct signature + uint16_t crc16 = CRC16_INIT ^ config_version; if (Config::store_config(0, &crc16, val0, vals...)) return -1; if (Config::store_config(size - 2, nullptr, (uint8_t *)&crc16 + 1, (uint8_t *)&crc16)) From 472cf0b3aec62770b6efa2352e3bb20d0ea07ebb Mon Sep 17 00:00:00 2001 From: Oskar Weigl Date: Sun, 25 Feb 2018 19:36:27 -0800 Subject: [PATCH 22/53] Update README.md --- Firmware/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Firmware/README.md b/Firmware/README.md index f0f7e8be..424042a7 100644 --- a/Firmware/README.md +++ b/Firmware/README.md @@ -141,7 +141,7 @@ To compile the program, you first need to install the prerequisite tools: Install the following: * [Git for windows](https://git-scm.com/download/win). This intalls the Git Bash, which is a unix style command line interface that we will be using. * [GNU ARM Embedded Toolchain](https://developer.arm.com/open-source/gnu-toolchain/gnu-rm/downloads). The cross-compiler used to compile the code. Download and install the "Windows 32-bit" version. Make sure to tick the "add to path" option. -* [Tup](http://gittup.org/tup/index.html) is used to script the compilation process. Unpack the zip-folder. Then add the path that contains the executable (something like `C:\Users\yourname\Downloads\tup-latest`) to your PATH environment variable. For details on how to set your path envirment in windows see [these instructions.](https://www.java.com/en/download/help/path.xml) +* [Tup](http://gittup.org/tup/index.html) is used to script the compilation process. Unpack the zip-folder. Then add the path that contains the executable (something like `C:\Users\yourname\the\place\you\unzipped\tup-latest`) to your PATH environment variable. For details on how to set your path envirment in windows see [these instructions.](https://www.java.com/en/download/help/path.xml) * [Make for Windows](http://gnuwin32.sourceforge.net/packages/make.htm). This is optional and mainly used because commands are short and developers are used to it. If you don't want to use it, you can look at the Makefile to get the corresponding commands. Download and run the complete package setup program. Add the path of the binaries to your PATH environment variable. For me this was at `C:\Program Files (x86)\GnuWin32\bin`. * OpenOCD. Follow the instructions at [GNU ARM Eclipse - How to install the OpenOCD binaries](http://gnuarmeclipse.github.io/openocd/install/), including the part about ST-LINK/V2 drivers. Add the path of the binaries to your PATH environment variable. For me this was at `C:\Program Files\GNU ARM Eclipse\OpenOCD\0.10.0-201704182147-dev\bin`. From facb3f33e75a78a54092dc1f6b9e39d50b06ae21 Mon Sep 17 00:00:00 2001 From: Samuel Sadok Date: Sun, 25 Feb 2018 19:38:06 -0800 Subject: [PATCH 23/53] add support for bool to protocol --- Firmware/MotorControl/protocol.hpp | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/Firmware/MotorControl/protocol.hpp b/Firmware/MotorControl/protocol.hpp index cde1e2ab..8b2e1edd 100644 --- a/Firmware/MotorControl/protocol.hpp +++ b/Firmware/MotorControl/protocol.hpp @@ -33,10 +33,16 @@ inline size_t write_le(T value, uint8_t* buffer); template inline size_t read_le(T* value, const uint8_t* buffer); +template<> +inline size_t write_le(bool value, uint8_t* buffer) { + buffer[0] = value ? 1 : 0; + return 1; +} + template<> inline size_t write_le(uint8_t value, uint8_t* buffer) { buffer[0] = value; - return 2; + return 1; } template<> @@ -71,10 +77,16 @@ inline size_t write_le(float value, uint8_t* buffer) { return write_le(*reinterpret_cast(&value), buffer); } +template<> +inline size_t read_le(bool* value, const uint8_t* buffer) { + *value = buffer[0]; + return 1; +} + template<> inline size_t read_le(uint8_t* value, const uint8_t* buffer) { *value = buffer[0]; - return 2; + return 1; } template<> @@ -358,6 +370,14 @@ template<> inline const char* get_default_json_modifier() { return "\"type\":\"uint8\",\"access\":\"rw\""; } +template<> +inline const char* get_default_json_modifier() { + return "\"type\":\"bool\",\"access\":\"r\""; +} +template<> +inline const char* get_default_json_modifier() { + return "\"type\":\"bool\",\"access\":\"rw\""; +} class Endpoint { public: From 0420015ec67aeec9fd89e973877ee50506ccb768 Mon Sep 17 00:00:00 2001 From: Oskar Weigl Date: Sun, 25 Feb 2018 19:38:50 -0800 Subject: [PATCH 24/53] add clean command --- Firmware/Makefile | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/Firmware/Makefile b/Firmware/Makefile index 680d59de..2dd304b4 100644 --- a/Firmware/Makefile +++ b/Firmware/Makefile @@ -2,7 +2,8 @@ # This is only a stub for various commands. # Tup is used for the actual compilation. -FIRMWARE = build/ODriveFirmware.elf +BUILD_DIR = build +FIRMWARE = $(BUILD_DIR)/ODriveFirmware.elf all: tup @@ -19,5 +20,8 @@ bmp: all --ex 'attach 1' \ --ex 'load' $(FIRMWARE) -.PHONY: all flash gdb bmp +clean: + -rm -fR .dep $(BUILD_DIR) + +.PHONY: all flash gdb bmp clean From dbdefabd7697b3722f8ed8ddc52aa91d2485fbf7 Mon Sep 17 00:00:00 2001 From: Oskar Weigl Date: Sun, 25 Feb 2018 19:59:26 -0800 Subject: [PATCH 25/53] Update CHANGELOG.md --- Firmware/CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/Firmware/CHANGELOG.md b/Firmware/CHANGELOG.md index 9c2fb38d..10c8cadd 100644 --- a/Firmware/CHANGELOG.md +++ b/Firmware/CHANGELOG.md @@ -6,6 +6,7 @@ Please add a note of your changes below this heading if you make a PR * Reporting of DRV status/control registers and fault codes * DRV status read script * Microsecond delay function +* Ability to start anticogging calibration over USB protocol ## [0.3.4] - 2018-02-13 From 50436709dbbbcb3fb00acf9f76671c851ef72c00 Mon Sep 17 00:00:00 2001 From: Samuel Sadok Date: Sun, 25 Feb 2018 19:59:29 -0800 Subject: [PATCH 26/53] Reorganize config parameters All configurable parameters are now exposed on the protocol in objects called "[...].config". Those are the same parameters that are saved to NVM. --- Firmware/MotorControl/commands.cpp | 93 +++++++++++++++++++++++------- Firmware/MotorControl/config.cpp | 10 ++-- Firmware/MotorControl/low_level.c | 4 +- Firmware/MotorControl/low_level.h | 15 ++--- Firmware/README.md | 58 ++++++++++++------- tools/explore_odrive.py | 11 ++++ 6 files changed, 136 insertions(+), 55 deletions(-) diff --git a/Firmware/MotorControl/commands.cpp b/Firmware/MotorControl/commands.cpp index 98dea15d..deec308d 100644 --- a/Firmware/MotorControl/commands.cpp +++ b/Firmware/MotorControl/commands.cpp @@ -8,6 +8,7 @@ #include "commands.h" #include "low_level.h" +#include "axis.h" #include "protocol.hpp" #include "freertos_vars.h" #include "utils.h" @@ -88,41 +89,60 @@ void motors_1_set_current_setpoint_func(void) { set_current_setpoint(&motors[1], motors[1].set_current_setpoint_args.current_setpoint); } - +bool test_bool = true; // This table specifies which fields and functions are exposed on the USB and UART ports. // TODO: Autogenerate this table. It will come up again very soon in the Arduino library. // clang-format off const Endpoint endpoints[] = { Endpoint::make_property("vbus_voltage", const_cast(&vbus_voltage)), + Endpoint::make_property("test_bool", &test_bool), 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)), + Endpoint::make_object("config"), + Endpoint::make_property("brake_resistance", &brake_resistance), + Endpoint::close_tree(), + Endpoint::make_object("axis0"), + Endpoint::make_object("config"), + Endpoint::make_property("enable_control", &axis_configs[0].enable_control_at_start), + Endpoint::make_property("do_calibration", &axis_configs[0].do_calibration_at_start), + Endpoint::close_tree(), + Endpoint::close_tree(), Endpoint::make_object("motor0"), - Endpoint::make_property("control_mode", reinterpret_cast(&motors[0].control_mode)), + Endpoint::make_object("config"), + Endpoint::make_property("control_mode", reinterpret_cast(&motors[0].control_mode)), + Endpoint::make_property("counts_per_step", &motors[0].counts_per_step), + Endpoint::make_property("pole_pairs", &motors[0].pole_pairs), + Endpoint::make_property("pos_gain", &motors[0].pos_gain), + Endpoint::make_property("vel_gain", &motors[0].vel_gain), + Endpoint::make_property("vel_integrator_gain", &motors[0].vel_integrator_gain), + Endpoint::make_property("vel_limit", &motors[0].vel_limit), + Endpoint::make_property("calibration_current", &motors[0].calibration_current), + Endpoint::make_property("resistance_calib_max_voltage", &motors[0].resistance_calib_max_voltage), + Endpoint::make_property("phase_inductance", &motors[0].phase_inductance), + Endpoint::make_property("phase_resistance", &motors[0].phase_resistance), + Endpoint::make_property("motor_type", reinterpret_cast(&motors[0].motor_type)), + Endpoint::make_property("rotor_mode", reinterpret_cast(&motors[0].rotor_mode)), + Endpoint::close_tree(), Endpoint::make_property("error", reinterpret_cast(&motors[0].error)), Endpoint::make_property("pos_setpoint", &motors[0].pos_setpoint), - Endpoint::make_property("pos_gain", &motors[0].pos_gain), Endpoint::make_property("vel_setpoint", &motors[0].vel_setpoint), - Endpoint::make_property("vel_gain", &motors[0].vel_gain), - Endpoint::make_property("vel_integrator_gain", &motors[0].vel_integrator_gain), Endpoint::make_property("vel_integrator_current", &motors[0].vel_integrator_current), - Endpoint::make_property("vel_limit", &motors[0].vel_limit), Endpoint::make_property("current_setpoint", &motors[0].current_setpoint), - Endpoint::make_property("calibration_current", &motors[0].calibration_current), - Endpoint::make_property("phase_inductance", const_cast(&motors[0].phase_inductance)), - Endpoint::make_property("phase_resistance", const_cast(&motors[0].phase_resistance)), Endpoint::make_property("current_meas_phB", const_cast(&motors[0].current_meas.phB)), Endpoint::make_property("current_meas_phC", const_cast(&motors[0].current_meas.phC)), Endpoint::make_property("DC_calib.phB", &motors[0].DC_calib.phB), Endpoint::make_property("DC_calib.phC", &motors[0].DC_calib.phC), Endpoint::make_property("shunt_conductance", &motors[0].shunt_conductance), Endpoint::make_property("phase_current_rev_gain", &motors[0].phase_current_rev_gain), - Endpoint::make_property("thread_ready", reinterpret_cast(&motors[0].thread_ready)), + Endpoint::make_property("thread_ready", &motors[0].thread_ready), Endpoint::make_property("control_deadline", &motors[0].control_deadline), Endpoint::make_property("last_cpu_time", &motors[0].last_cpu_time), Endpoint::make_property("loop_counter", &motors[0].loop_counter), Endpoint::make_object("current_control"), - Endpoint::make_property("current_lim", &motors[0].current_control.current_lim), + Endpoint::make_object("config"), + Endpoint::make_property("current_lim", &motors[0].current_control.current_lim), + Endpoint::close_tree(), Endpoint::make_property("p_gain", &motors[0].current_control.p_gain), Endpoint::make_property("i_gain", &motors[0].current_control.i_gain), Endpoint::make_property("v_current_control_integral_d", &motors[0].current_control.v_current_control_integral_d), @@ -132,6 +152,14 @@ const Endpoint endpoints[] = { Endpoint::make_property("Ibus", const_cast(&motors[0].current_control.Ibus)), Endpoint::close_tree(), Endpoint::make_object("encoder"), + Endpoint::make_object("config"), + Endpoint::make_property("use_index", &motors[0].encoder.use_index), + Endpoint::make_property("calibrated", &motors[0].encoder.calibrated), + Endpoint::make_property("idx_search_speed", &motors[0].encoder.idx_search_speed), + Endpoint::make_property("cpr", &motors[0].encoder.encoder_cpr), + Endpoint::make_property("offset", &motors[0].encoder.encoder_offset), + Endpoint::make_property("motor_dir", &motors[0].encoder.motor_dir), + Endpoint::close_tree(), Endpoint::make_property("phase", const_cast(&motors[0].encoder.phase)), Endpoint::make_property("pll_pos", &motors[0].encoder.pll_pos), Endpoint::make_property("pll_vel", &motors[0].encoder.pll_vel), @@ -154,32 +182,47 @@ const Endpoint endpoints[] = { Endpoint::make_property("current_setpoint", &motors[0].set_current_setpoint_args.current_setpoint), Endpoint::close_tree(), Endpoint::close_tree(), // motor0 + Endpoint::make_object("axis1"), + Endpoint::make_object("config"), + Endpoint::make_property("enable_control", &axis_configs[1].enable_control_at_start), + Endpoint::make_property("do_calibration", &axis_configs[1].do_calibration_at_start), + Endpoint::close_tree(), + Endpoint::close_tree(), Endpoint::make_object("motor1"), - Endpoint::make_property("control_mode", reinterpret_cast(&motors[1].control_mode)), + Endpoint::make_object("config"), + Endpoint::make_property("control_mode", reinterpret_cast(&motors[1].control_mode)), + Endpoint::make_property("counts_per_step", &motors[1].counts_per_step), + Endpoint::make_property("pole_pairs", &motors[1].pole_pairs), + Endpoint::make_property("pos_gain", &motors[1].pos_gain), + Endpoint::make_property("vel_gain", &motors[1].vel_gain), + Endpoint::make_property("vel_integrator_gain", &motors[1].vel_integrator_gain), + Endpoint::make_property("vel_limit", &motors[1].vel_limit), + Endpoint::make_property("calibration_current", &motors[1].calibration_current), + Endpoint::make_property("resistance_calib_max_voltage", &motors[1].resistance_calib_max_voltage), + Endpoint::make_property("phase_inductance", &motors[1].phase_inductance), + Endpoint::make_property("phase_resistance", &motors[1].phase_resistance), + Endpoint::make_property("motor_type", reinterpret_cast(&motors[1].motor_type)), + Endpoint::make_property("rotor_mode", reinterpret_cast(&motors[1].rotor_mode)), + Endpoint::close_tree(), Endpoint::make_property("error", reinterpret_cast(&motors[1].error)), Endpoint::make_property("pos_setpoint", &motors[1].pos_setpoint), - Endpoint::make_property("pos_gain", &motors[1].pos_gain), Endpoint::make_property("vel_setpoint", &motors[1].vel_setpoint), - Endpoint::make_property("vel_gain", &motors[1].vel_gain), - Endpoint::make_property("vel_integrator_gain", &motors[1].vel_integrator_gain), Endpoint::make_property("vel_integrator_current", &motors[1].vel_integrator_current), - Endpoint::make_property("vel_limit", &motors[1].vel_limit), Endpoint::make_property("current_setpoint", &motors[1].current_setpoint), - Endpoint::make_property("calibration_current", &motors[1].calibration_current), - Endpoint::make_property("phase_inductance", const_cast(&motors[1].phase_inductance)), - Endpoint::make_property("phase_resistance", const_cast(&motors[1].phase_resistance)), Endpoint::make_property("current_meas_phB", const_cast(&motors[1].current_meas.phB)), Endpoint::make_property("current_meas_phC", const_cast(&motors[1].current_meas.phC)), Endpoint::make_property("DC_calib.phB", &motors[1].DC_calib.phB), Endpoint::make_property("DC_calib.phC", &motors[1].DC_calib.phC), Endpoint::make_property("shunt_conductance", &motors[1].shunt_conductance), Endpoint::make_property("phase_current_rev_gain", &motors[1].phase_current_rev_gain), - Endpoint::make_property("thread_ready", reinterpret_cast(&motors[1].thread_ready)), + Endpoint::make_property("thread_ready", &motors[1].thread_ready), Endpoint::make_property("control_deadline", &motors[1].control_deadline), Endpoint::make_property("last_cpu_time", &motors[1].last_cpu_time), Endpoint::make_property("loop_counter", &motors[1].loop_counter), Endpoint::make_object("current_control"), - Endpoint::make_property("current_lim", &motors[1].current_control.current_lim), + Endpoint::make_object("config"), + Endpoint::make_property("current_lim", &motors[1].current_control.current_lim), + Endpoint::close_tree(), Endpoint::make_property("p_gain", &motors[1].current_control.p_gain), Endpoint::make_property("i_gain", &motors[1].current_control.i_gain), Endpoint::make_property("v_current_control_integral_d", &motors[1].current_control.v_current_control_integral_d), @@ -189,6 +232,14 @@ const Endpoint endpoints[] = { Endpoint::make_property("Ibus", const_cast(&motors[1].current_control.Ibus)), Endpoint::close_tree(), Endpoint::make_object("encoder"), + Endpoint::make_object("config"), + Endpoint::make_property("use_index", &motors[1].encoder.use_index), + Endpoint::make_property("calibrated", &motors[1].encoder.calibrated), + Endpoint::make_property("idx_search_speed", &motors[1].encoder.idx_search_speed), + Endpoint::make_property("cpr", &motors[1].encoder.encoder_cpr), + Endpoint::make_property("offset", &motors[1].encoder.encoder_offset), + Endpoint::make_property("motor_dir", &motors[1].encoder.motor_dir), + Endpoint::close_tree(), Endpoint::make_property("phase", const_cast(&motors[1].encoder.phase)), Endpoint::make_property("pll_pos", &motors[1].encoder.pll_pos), Endpoint::make_property("pll_vel", &motors[1].encoder.pll_vel), diff --git a/Firmware/MotorControl/config.cpp b/Firmware/MotorControl/config.cpp index 41e97ea6..847a8938 100644 --- a/Firmware/MotorControl/config.cpp +++ b/Firmware/MotorControl/config.cpp @@ -42,7 +42,7 @@ typedef struct { float encoder_idx_search_speed; int32_t encoder_cpr; int32_t encoder_offset; - int32_t motor_dir; + int32_t encoder_motor_dir; } MotorConfig_t; /* Global constant data ------------------------------------------------------*/ @@ -182,7 +182,7 @@ void set_motor_config(const MotorConfig_t* config, Motor_t* motor) { 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; + motor->encoder.motor_dir = config->encoder_motor_dir; } // This function is obviously stupid and should go away (make MotorConfig_t a member of Motor_t) @@ -209,14 +209,14 @@ void get_motor_config(const Motor_t* motor, MotorConfig_t* config) { 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; + config->encoder_motor_dir = motor->encoder.motor_dir; } void init_configuration(void) { MotorConfig_t motor_config[2]; //TODO: we really shouldn't be hardcoding like this - if (NVM_init() || Config::load_config(&motor_config[0], &motor_config[1], &axis_configs[0], &axis_configs[1])) { + if (NVM_init() || Config::load_config(&motor_config[0], &motor_config[1], &axis_configs[0], &axis_configs[1], &brake_resistance)) { //printf("no config found\r\n"); osDelay(5); // load default config // motor_config[0] = MotorConfig_t(); @@ -237,7 +237,7 @@ void save_configuration(void) { get_motor_config(&motors[0], &motor_config[0]); get_motor_config(&motors[1], &motor_config[1]); //TODO: we really shouldn't be hardcoding like this - if (Config::store_config(&motor_config[0], &motor_config[1], &axis_configs[0], &axis_configs[1])) { + if (Config::store_config(&motor_config[0], &motor_config[1], &axis_configs[0], &axis_configs[1], &brake_resistance)) { //printf("saving configuration failed\r\n"); osDelay(5); } } diff --git a/Firmware/MotorControl/low_level.c b/Firmware/MotorControl/low_level.c index 802c91c1..7aadb847 100644 --- a/Firmware/MotorControl/low_level.c +++ b/Firmware/MotorControl/low_level.c @@ -264,6 +264,8 @@ Motor_t motors[] = { }; const size_t num_motors = sizeof(motors) / sizeof(motors[0]); +float brake_resistance = 0.47f; // [ohm] + /* Private constant data -----------------------------------------------------*/ static const float one_by_sqrt3 = 0.57735026919f; static const float sqrt3_by_2 = 0.86602540378f; @@ -271,8 +273,6 @@ static const float current_meas_period = CURRENT_MEAS_PERIOD; static const int current_meas_hz = CURRENT_MEAS_HZ; /* Private variables ---------------------------------------------------------*/ -static float brake_resistance = 0.47f; // [ohm] - /* Function implementations --------------------------------------------------*/ //-------------------------------- diff --git a/Firmware/MotorControl/low_level.h b/Firmware/MotorControl/low_level.h index b5625a25..cd02276d 100644 --- a/Firmware/MotorControl/low_level.h +++ b/Firmware/MotorControl/low_level.h @@ -55,16 +55,16 @@ typedef enum { // Note: these should be sorted from lowest level of control to // highest level of control, to allow "<" style comparisons. typedef enum { - CTRL_MODE_VOLTAGE_CONTROL, - CTRL_MODE_CURRENT_CONTROL, - CTRL_MODE_VELOCITY_CONTROL, - CTRL_MODE_POSITION_CONTROL + CTRL_MODE_VOLTAGE_CONTROL = 0, + CTRL_MODE_CURRENT_CONTROL = 1, + CTRL_MODE_VELOCITY_CONTROL = 2, + CTRL_MODE_POSITION_CONTROL = 3 } Motor_control_mode_t; typedef enum { - MOTOR_TYPE_HIGH_CURRENT, - // MOTOR_TYPE_LOW_CURRENT, //Not yet implemented - MOTOR_TYPE_GIMBAL + MOTOR_TYPE_HIGH_CURRENT = 0, + // MOTOR_TYPE_LOW_CURRENT = 1, //Not yet implemented + MOTOR_TYPE_GIMBAL = 2 } Motor_type_t; typedef struct { @@ -199,6 +199,7 @@ extern const size_t num_motors; extern const float elec_rad_per_enc; /* Exported variables --------------------------------------------------------*/ extern float vbus_voltage; +extern float brake_resistance; extern Motor_t motors[]; /* Exported macro ------------------------------------------------------------*/ /* Exported functions --------------------------------------------------------*/ diff --git a/Firmware/README.md b/Firmware/README.md index bd9602bd..2663138e 100644 --- a/Firmware/README.md +++ b/Firmware/README.md @@ -22,8 +22,8 @@ The project is under active development, so make sure to check the [Changelog](C -## Configuring parameters -To correctly operate the ODrive, you need to supply some parameters. Some are mandatory, and if supplied incorrectly will cause the drive to malfunction. To get good performance you must also tune the drive. +## Configuring the build +To correctly operate the ODrive, you need to supply some parameters. Some are mandatory, and if supplied incorrectly will cause the drive to malfunction. The first thing to set is your board hardware version, located at the top of [Inc/main.h](Inc/main.h). If, for example, you are using the hardware: ODrive v3.2, then you should set it like this: ```C @@ -61,21 +61,38 @@ Note that UART is only supported on ODrive v3.3 and higher. - `UART_PROTOCOL_NONE`: Ignore UART communication - `USE_GPIO_MODE_STEP_DIR`: Step/direction control mode (use in conjunction with `UART_PROTOCOL_NONE`) -### Motor control parameters -The rest of all the parameters are at the top of the [MotorControl/low_level.c](MotorControl/low_level.c) file. Please note that many parameters occur twice, once for each motor. -In it's current state, the motor structs contain both tuning parameters, meant to be set by the developer, and static variables, meant to be modified by the software. Unfortunatly these are mixed together right now, but cleaning this up is a high priority task. +## Controller Configuration +To get good performance you need to tune the ODrive after flashing. -It may be helpful to know that the entry point of each of the motor threads is `void axis_thread_entry` at the top of [MotorControl/axis.cpp](MotorControl/axis.cpp). This is like `main` for each motor, and is probably where you should start reading the code. +The general configuration procedure goes like this: + + 1. Launch `./tools/explore_odrive.py`. This will give you a command prompt where you can modify using simple assignments. + 2. Configure parameters inside the `my_odrive.[...].config` objects. For example to adjust the position gain: `my_odrive.motor0.config.pos_gain = 30` Enter + + The complete list of configurable parameters is: + - `my_odrive.motorN.config.*` + - `my_odrive.axisN.config.*` + + where N is a valid motor number (0 or 1). + + 3. Save the configuration into non-volatile memory: `my_odrive.save_configuration()` Enter + + This will save the properties of all the `[...].config` objects and no other parameters. + 4. Reboot the drive: `my_odrive.reboot()` Enter + +Note that a firmware upgrade at this point will preserve the configuration if and only if the parameters of both firmware versions are identical. Should you need to reset the configuration, you can run `my_odrive.erase_configuration()`. + +__Developers__: Be aware that you can also modify the compile-time defaults for all of these parameters. Most of them you will find at the top of [MotorControl/low_level.c](MotorControl/low_level.c#L50). Note that the configuration parameters there are somewhat intertwined with runtime variables and hardware specific configuration that should not be changed. Also note that all parameters occur twice. ### Mandatory parameters -You must set: -* `ENCODER_CPR`: Encoder Count Per Revolution (CPR). This is 4x the Pulse Per Revolution (PPR) value. -* `POLE_PAIRS`: This is the number of magnet poles in the rotor, **divided by two**. You can simply count the number of permanent magnets in the rotor, if you can see them. Note: this is not the same as the number of coils in the stator. -* `brake_resistance`: This is the resistance of the brake resistor. If you are not using it, you may set it to 0.0f. -* `motor_type`: This is the type of motor being used. Currently two types of motors are supported -- High-current motors (`MOTOR_TYPE_HIGH_CURRENT`) and Gimbal motors (`MOTOR_TYPE_GIMBAL`). +You must set for every motor: +* `my_odrive.motorN.encoder.config.cpr`: Encoder Count Per Revolution (CPR). This is 4x the Pulse Per Revolution (PPR) value. +* `my_odrive.motorN.config.pole_pairs`: This is the number of magnet poles in the rotor, **divided by two**. You can simply count the number of permanent magnets in the rotor, if you can see them. Note: this is not the same as the number of coils in the stator. +* `my_odrive.config.brake_resistance` [Ohm]: This is the resistance of the brake resistor. If you are not using it, you may set it to 0.0f. +* `my_odrive.motorN.config.motor_type`: This is the type of motor being used. Currently two types of motors are supported -- High-current motors (`MOTOR_TYPE_HIGH_CURRENT`) and Gimbal motors (`MOTOR_TYPE_GIMBAL`). ### Motor Modes -The firwmare currently supports two different types of motors, high-current motors, and Gimbal motors. If you're using a regular hobby brushless motor like [this](https://hobbyking.com/en_us/turnigy-aerodrive-sk3-5065-236kv-brushless-outrunner-motor.html) one, you should set `motor_mode` to `MOTOR_TYPE_HIGH_CURRENT`. For high-torque gimbal motors like [this](https://hobbyking.com/en_us/turnigy-hd-5208-brushless-gimbal-motor-bldc.html) one, you should choose `MOTOR_TYPE_GIMBAL`. +The firwmare currently supports two different types of motors, high-current motors, and Gimbal motors. If you're using a regular hobby brushless motor like [this](https://hobbyking.com/en_us/turnigy-aerodrive-sk3-5065-236kv-brushless-outrunner-motor.html) one, you should set `my_odrive.motorN.config.motor_type` to `MOTOR_TYPE_HIGH_CURRENT`. For high-torque gimbal motors like [this](https://hobbyking.com/en_us/turnigy-hd-5208-brushless-gimbal-motor-bldc.html) one, you should choose `MOTOR_TYPE_GIMBAL`. **Further detail:** @@ -86,15 +103,15 @@ If 100's of mA current noise is "large" for you, and you intend to spin the moto ### Tuning parameters The most important parameters are the limits: -* The current limit: `.current_lim = 75.0f, //[A] // Note: consistent with 40v/v gain`. The default current limit, for safety reasons, is set to 10A. This is quite weak, and good for making sure the drive is stable. Once you have tuned the drive, you can increase this to 75A to get some performance. Note that above 75A, you must change the current amplifier gains. +* The current limit: `my_odrive.motorN.current_control.config.current_lim` [A]. The default current limit, for safety reasons, is set to 10A. This is quite weak, and good for making sure the drive is stable. Once you have tuned the drive, you can increase this to 75A to get some performance. Note that above 75A, you must change the current amplifier gains. * Note: The motor current and the current drawn from the power supply is not the same in general. You should not look at the power supply current to see what is going on with the motor current. -* The velocity limit: `.vel_limit = 20000.0f, // [counts/s]`. The motor will be limited to this speed; again the default value is quite slow. -* You can change `.calibration_current` to the largest value you feel comfortable leaving running through the motor continously when the motor is stationary. +* The velocity limit: `my_odrive.motorN.config.vel_limit` [counts/s]. The motor will be limited to this speed; again the default value is quite slow. +* You can change `my_odrive.motorN.config.calibration_current` [A] to the largest value you feel comfortable leaving running through the motor continously when the motor is stationary. The motion control gains are currently manually tuned: -* `.pos_gain = 20.0f, // [(counts/s) / counts]` -* `.vel_gain = 15.0f / 10000.0f, // [A/(counts/s)]` -* `.vel_integrator_gain = 10.0f / 10000.0f, // [A/(counts/s * s)]` +* `my_odrive.motorN.config.pos_gain = 20.0f` [(counts/s) / counts] +* `my_odrive.motorN.config.vel_gain = 15.0f / 10000.0f` [A/(counts/s)] +* `my_odrive.motorN.config.vel_integrator_gain = 10.0f / 10000.0f` [A/(counts/s * s)] An upcoming feature will enable automatic tuning. Until then, here is a rough tuning procedure: * Set the integrator gain to 0 @@ -107,7 +124,8 @@ An upcoming feature will enable automatic tuning. Until then, here is a rough tu ### Optional parameters By default both motors are enabled, and the default control mode is position control. -If you want a different mode, you can change `.control_mode`. To disable a motor, set `.enable_control` and `.do_calibration` to false. +If you want a different mode, you can change `my_odrive.motorN.config.control_mode`. Possible values are `CTRL_MODE_VOLTAGE_CONTROL`, `CTRL_MODE_CURRENT_CONTROL`, `CTRL_MODE_VELOCITY_CONTROL` and `CTRL_MODE_POSITION_CONTROL`. +To disable a motor, set `my_odrive.axisN.config.enable_control` and `my_odrive.axisN.config.do_calibration` to `False`.

## Compiling and downloading firmware @@ -209,7 +227,7 @@ See the [protocol specification](protocol.md) or the [legacy protocol specificat By default the encoder-to-motor calibration will run on every startup. During encoder calibration the rotor must be allowed to rotate without any biased load during startup. That means mass and weak friction loads are fine, but gravity or spring loads are not okay. ### Encoder with Index signal -If you have an encoder with an index (Z) signal, you may avoid having to do the calibration on every startup, and instead use the index signal to re-sync the encoder to a stored calibration. Bleow are the steps to do the one-time calibration and configuration. Note that you can follow these steps with one motor at a time, or all motors together, as you wish. +If you have an encoder with an index (Z) signal, you may avoid having to do the calibration on every startup, and instead use the index signal to re-sync the encoder to a stored calibration. Below are the steps to do the one-time calibration and configuration. Note that you can follow these steps with one motor at a time, or all motors together, as you wish. * Since you will only do this once, it is recommended that you mechanically disengage the motor from anything other than the encoder, so it can spin freely. * All the parameters we will be modifying are in the motor structs at the top of [MotorControl/low_level.c](MotorControl/low_level.c). diff --git a/tools/explore_odrive.py b/tools/explore_odrive.py index 7afb8009..59492a30 100755 --- a/tools/explore_odrive.py +++ b/tools/explore_odrive.py @@ -7,6 +7,17 @@ import odrive.core import argparse import sys +# some enums described in the README +# TODO: transmit as part of the JSON +MOTOR_TYPE_HIGH_CURRENT = 0 +#MOTOR_TYPE_LOW_CURRENT = 1 +MOTOR_TYPE_GIMBAL = 2 + +CTRL_MODE_VOLTAGE_CONTROL = 0, +CTRL_MODE_CURRENT_CONTROL = 1, +CTRL_MODE_VELOCITY_CONTROL = 2, +CTRL_MODE_POSITION_CONTROL = 3 + # Parse arguments parser = argparse.ArgumentParser(description='Load an odrive object to play with in the IPython interactive shell.') From 7e88c46458599617475c8591f28aea30f5edc081 Mon Sep 17 00:00:00 2001 From: Oskar Weigl Date: Sun, 25 Feb 2018 20:12:09 -0800 Subject: [PATCH 27/53] Update README.md --- Firmware/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Firmware/README.md b/Firmware/README.md index 2663138e..15493d1f 100644 --- a/Firmware/README.md +++ b/Firmware/README.md @@ -67,7 +67,7 @@ To get good performance you need to tune the ODrive after flashing. The general configuration procedure goes like this: 1. Launch `./tools/explore_odrive.py`. This will give you a command prompt where you can modify using simple assignments. - 2. Configure parameters inside the `my_odrive.[...].config` objects. For example to adjust the position gain: `my_odrive.motor0.config.pos_gain = 30` Enter + 2. Configure parameters inside the `my_odrive.[...].config` objects. For example to adjust the position gain: `my_odrive.motor0.config.pos_gain = 30` Return The complete list of configurable parameters is: - `my_odrive.motorN.config.*` From 308d6edbd2019469cb4cc9730f9edc210d7dc14d Mon Sep 17 00:00:00 2001 From: Oskar Weigl Date: Sun, 25 Feb 2018 20:13:54 -0800 Subject: [PATCH 28/53] Update README.md --- Firmware/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Firmware/README.md b/Firmware/README.md index 15493d1f..2663138e 100644 --- a/Firmware/README.md +++ b/Firmware/README.md @@ -67,7 +67,7 @@ To get good performance you need to tune the ODrive after flashing. The general configuration procedure goes like this: 1. Launch `./tools/explore_odrive.py`. This will give you a command prompt where you can modify using simple assignments. - 2. Configure parameters inside the `my_odrive.[...].config` objects. For example to adjust the position gain: `my_odrive.motor0.config.pos_gain = 30` Return + 2. Configure parameters inside the `my_odrive.[...].config` objects. For example to adjust the position gain: `my_odrive.motor0.config.pos_gain = 30` Enter The complete list of configurable parameters is: - `my_odrive.motorN.config.*` From 19c3967a0e1f15866ebb68c9f4da98fc4ba067d7 Mon Sep 17 00:00:00 2001 From: Samuel Sadok Date: Sun, 25 Feb 2018 20:45:24 -0800 Subject: [PATCH 29/53] make tup build quieter and work on windows --- Firmware/Makefile | 2 +- Firmware/Tupfile.lua | 2 +- Firmware/build.lua | 6 ++++-- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/Firmware/Makefile b/Firmware/Makefile index 2dd304b4..347ae37d 100644 --- a/Firmware/Makefile +++ b/Firmware/Makefile @@ -6,7 +6,7 @@ BUILD_DIR = build FIRMWARE = $(BUILD_DIR)/ODriveFirmware.elf all: - tup + @tup --quiet flash: all openocd -f interface/stlink-v2.cfg -f target/stm32f4x.cfg -c init -c reset\ halt -c flash\ write_image\ erase\ $(FIRMWARE) -c reset\ run -c exit diff --git a/Firmware/Tupfile.lua b/Firmware/Tupfile.lua index 171c0d43..3885d8bd 100644 --- a/Firmware/Tupfile.lua +++ b/Firmware/Tupfile.lua @@ -62,7 +62,7 @@ build{ toolchains={toolchain}, --toolchains={LLVMToolchain('x86_64', {'-Ofast'}, {'-flto'})}, packages={'stm_platform'}, - sources={ + sources={ 'MotorControl/utils.c', 'MotorControl/legacy_commands.c', 'MotorControl/low_level.c', diff --git a/Firmware/build.lua b/Firmware/build.lua index 6e4ecdd9..87878b4b 100644 --- a/Firmware/build.lua +++ b/Firmware/build.lua @@ -88,10 +88,12 @@ function GCCToolchain(prefix, builddir, compiler_flags, linker_flags) command=prefix..'g++ %f '.. tostring(linker_flags)..' '.. '-Wl,-Map=%O.map'.. - ' -o %o; '.. - prefix..'size %o', + ' -o %o', outputs={output_name..'.elf', extra_outputs={output_name..'.map'}} } + -- display the size + tup.frule{inputs=output_name..'.elf', command=prefix..'size %f'} + -- create *.hex and *.bin output formats tup.frule{inputs={output_name..'.elf'}, command=prefix..'objcopy -O ihex %f %o', outputs={output_name..'.hex'}} tup.frule{inputs={output_name..'.elf'}, command=prefix..'objcopy -O binary -S %f %o', outputs={output_name..'.bin'}} end From 1344876a2a74dd4c74c8a4acfc6380627d6e6d73 Mon Sep 17 00:00:00 2001 From: Samuel Sadok Date: Sun, 25 Feb 2018 20:55:27 -0800 Subject: [PATCH 30/53] fix travis --- Firmware/build.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Firmware/build.lua b/Firmware/build.lua index 87878b4b..ba5ecc30 100644 --- a/Firmware/build.lua +++ b/Firmware/build.lua @@ -92,7 +92,7 @@ function GCCToolchain(prefix, builddir, compiler_flags, linker_flags) outputs={output_name..'.elf', extra_outputs={output_name..'.map'}} } -- display the size - tup.frule{inputs=output_name..'.elf', command=prefix..'size %f'} + tup.frule{inputs={output_name..'.elf'}, command=prefix..'size %f'} -- create *.hex and *.bin output formats tup.frule{inputs={output_name..'.elf'}, command=prefix..'objcopy -O ihex %f %o', outputs={output_name..'.hex'}} tup.frule{inputs={output_name..'.elf'}, command=prefix..'objcopy -O binary -S %f %o', outputs={output_name..'.bin'}} From 8c714987c63dff637fa5fb21465b879cb622aa44 Mon Sep 17 00:00:00 2001 From: Samuel Sadok Date: Sun, 25 Feb 2018 20:56:16 -0800 Subject: [PATCH 31/53] update changelog --- Firmware/CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Firmware/CHANGELOG.md b/Firmware/CHANGELOG.md index 9c2fb38d..11ee6e82 100644 --- a/Firmware/CHANGELOG.md +++ b/Firmware/CHANGELOG.md @@ -6,6 +6,10 @@ Please add a note of your changes below this heading if you make a PR * Reporting of DRV status/control registers and fault codes * DRV status read script * Microsecond delay function +* Travis-CI + +### Changed +* Build system is now tup instead of make ## [0.3.4] - 2018-02-13 From 39dada52090769ed6940270ba68a1ebe7e4b6400 Mon Sep 17 00:00:00 2001 From: Oskar Weigl Date: Sun, 25 Feb 2018 21:03:41 -0800 Subject: [PATCH 32/53] Remove c lib dep --- .travis.yml | 5 ----- 1 file changed, 5 deletions(-) diff --git a/.travis.yml b/.travis.yml index bad65bb3..91cb5a02 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,11 +3,6 @@ language: c sudo: false -addons: - apt: - packages: - libc6-i386 - cache: directories: - $HOME/dl From b34e8587a1c2f123cb5261cc2bbb490fd67b6970 Mon Sep 17 00:00:00 2001 From: Oskar Weigl Date: Sun, 25 Feb 2018 21:14:45 -0800 Subject: [PATCH 33/53] Update .travis.yml --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 91cb5a02..239e74b7 100644 --- a/.travis.yml +++ b/.travis.yml @@ -23,4 +23,4 @@ script: - cd Firmware - mkdir -p build - tup generate ./build.sh - - bash -x ./build.sh + - bash -xe ./build.sh From 415ddbba32cf101bb68c10227fb0a18a34a25db1 Mon Sep 17 00:00:00 2001 From: Oskar Weigl Date: Sun, 25 Feb 2018 21:17:45 -0800 Subject: [PATCH 34/53] Update .travis.yml --- .travis.yml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.travis.yml b/.travis.yml index 239e74b7..531bce18 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,6 +3,11 @@ language: c sudo: false +addons: + apt: + packages: + libc6-i386 + cache: directories: - $HOME/dl From bb9050e3d4b66962a11cc160aa2e97a2d0be5772 Mon Sep 17 00:00:00 2001 From: Paul Guenette Date: Mon, 26 Feb 2018 01:21:06 -0500 Subject: [PATCH 35/53] Rename the ODrive VSCode workspace file to something more useful --- Firmware/configuring-vscode.md | 2 +- ...eWorkspace.code-workspace => ODrive_Workspace.code-workspace | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename VSCodeWorkspace.code-workspace => ODrive_Workspace.code-workspace (100%) diff --git a/Firmware/configuring-vscode.md b/Firmware/configuring-vscode.md index ec9b0adb..add9ff45 100644 --- a/Firmware/configuring-vscode.md +++ b/Firmware/configuring-vscode.md @@ -19,7 +19,7 @@ Before doing the VSCode setup, make sure you've installed all of your [prerequis * Path Autocomplete * Auto Comment Blocks 1. Restart VSCode -1. Open the VSCode Workspace file, which is located in the root of the ODrive repository. It is called `VSCodeWorkspace.code-workspace`. The first time you open it, VSCode will install some dependencies. If it fails, you may need to [change your proxy settings](https://code.visualstudio.com/docs/getstarted/settings). +1. Open the VSCode Workspace file, which is located in the root of the ODrive repository. It is called `ODrive_Workspace.code-workspace`. The first time you open it, VSCode will install some dependencies. If it fails, you may need to [change your proxy settings](https://code.visualstudio.com/docs/getstarted/settings). You should now be ready to compile and test the ODrive project. diff --git a/VSCodeWorkspace.code-workspace b/ODrive_Workspace.code-workspace similarity index 100% rename from VSCodeWorkspace.code-workspace rename to ODrive_Workspace.code-workspace From 91af7eb5be2cb11a41eeb4c019cd554d2ee8649b Mon Sep 17 00:00:00 2001 From: Paul Guenette Date: Mon, 26 Feb 2018 01:23:56 -0500 Subject: [PATCH 36/53] Add two missing errors to README --- Firmware/README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Firmware/README.md b/Firmware/README.md index 424042a7..fb89c2b1 100644 --- a/Firmware/README.md +++ b/Firmware/README.md @@ -262,6 +262,8 @@ The error nummber corresponds to the following: 19. `ERROR_SPIN_UP_TIMEOUT` 20. `ERROR_DRV_FAULT` 21. `ERROR_NOT_IMPLEMENTED_MOTOR_TYPE` +22. `ERROR_ENCODER_CPR_OUT_OF_RANGE` +23. `ERROR_DC_BUS_BROWNOUT` If you get an error code larger than this, it may be the case that someone added a code and forgot to update the documentation. In that case, please check [MotorControl/low_level.h](MotorControl/low_level.h) for the full enum. From 243bf8fd632403d3f1e31005651057d0a8b9dca8 Mon Sep 17 00:00:00 2001 From: Paul Guenette Date: Mon, 26 Feb 2018 01:25:26 -0500 Subject: [PATCH 37/53] Use 8 threads for building by default Tup is smart enough to only spin up as many threads as you have logical cores, e.g. on quad core machines this only uses 4 threads. --- Firmware/.vscode/tasks.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Firmware/.vscode/tasks.json b/Firmware/.vscode/tasks.json index 33956da9..b32c5b1a 100644 --- a/Firmware/.vscode/tasks.json +++ b/Firmware/.vscode/tasks.json @@ -6,7 +6,7 @@ { "taskName": "build", "type": "shell", - "command": "make -j4", + "command": "make -j8", "group": { "kind": "build", "isDefault": true From 1457cb2ec5487499536973cf3ebbff3108fd4d4d Mon Sep 17 00:00:00 2001 From: Oskar Weigl Date: Sun, 25 Feb 2018 22:43:56 -0800 Subject: [PATCH 38/53] Update tasks.json --- Firmware/.vscode/tasks.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Firmware/.vscode/tasks.json b/Firmware/.vscode/tasks.json index b32c5b1a..2376b650 100644 --- a/Firmware/.vscode/tasks.json +++ b/Firmware/.vscode/tasks.json @@ -6,7 +6,7 @@ { "taskName": "build", "type": "shell", - "command": "make -j8", + "command": "make", "group": { "kind": "build", "isDefault": true From e2540d7eda1cb331ebbc13637eeb520bf65536f5 Mon Sep 17 00:00:00 2001 From: Oskar Weigl Date: Sun, 25 Feb 2018 22:47:37 -0800 Subject: [PATCH 39/53] Update utils.h --- Firmware/MotorControl/utils.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Firmware/MotorControl/utils.h b/Firmware/MotorControl/utils.h index 004d00cf..bf329605 100644 --- a/Firmware/MotorControl/utils.h +++ b/Firmware/MotorControl/utils.h @@ -70,9 +70,10 @@ extern "C" { */ #define STM_ID_GetUUID(x) ((x >= 0 && x < 3) ? (*(uint32_t *)(ID_UNIQUE_ADDRESS + 4 * (x))) : 0) -#ifndef M_PI -#define M_PI 3.14159265358979323846f +#ifdef M_PI +#undef M_PI #endif +#define M_PI 3.14159265358979323846f #define MACRO_MAX(x, y) (((x) > (y)) ? (x) : (y)) #define MACRO_MIN(x, y) (((x) < (y)) ? (x) : (y)) From 2f28a3d60edfbc3c3e30723ebaf681e26553232b Mon Sep 17 00:00:00 2001 From: Oskar Weigl Date: Sun, 25 Feb 2018 23:29:16 -0800 Subject: [PATCH 40/53] refactor readme --- Firmware/README.md | 142 +++++++++++++++++++++++---------------------- 1 file changed, 72 insertions(+), 70 deletions(-) diff --git a/Firmware/README.md b/Firmware/README.md index 2663138e..b3a7ffc2 100644 --- a/Firmware/README.md +++ b/Firmware/README.md @@ -10,11 +10,11 @@ The project is under active development, so make sure to check the [Changelog](C -- [Configuring parameters](#configuring-parameters) +- [Configuring the build](#configuring-the-build) - [Compiling and downloading firmware](#compiling-and-downloading-firmware) -- [Setting up an IDE](#setting-up-an-ide) -- [Continuing without an IDE](#no-ide-instructions) +- [Setting up an IDE](#setting-up-an-ide) or [Continuing without an IDE](#no-ide-instructions) - [Communicating over USB or UART](#communicating-over-usb-or-uart) +- [Configuring parameters](#configuring-parameters) - [Encoder Calibration](#encoder-calibration) - [Checking for error codes](#checking-for-error-codes) - [Generating startup code](#generating-startup-code) @@ -22,8 +22,10 @@ The project is under active development, so make sure to check the [Changelog](C +

## Configuring the build To correctly operate the ODrive, you need to supply some parameters. Some are mandatory, and if supplied incorrectly will cause the drive to malfunction. +In this section we will set the compile-time parameters, later we will also set the [run time parameters](#configuring-parameters). The first thing to set is your board hardware version, located at the top of [Inc/main.h](Inc/main.h). If, for example, you are using the hardware: ODrive v3.2, then you should set it like this: ```C @@ -61,72 +63,6 @@ Note that UART is only supported on ODrive v3.3 and higher. - `UART_PROTOCOL_NONE`: Ignore UART communication - `USE_GPIO_MODE_STEP_DIR`: Step/direction control mode (use in conjunction with `UART_PROTOCOL_NONE`) -## Controller Configuration -To get good performance you need to tune the ODrive after flashing. - -The general configuration procedure goes like this: - - 1. Launch `./tools/explore_odrive.py`. This will give you a command prompt where you can modify using simple assignments. - 2. Configure parameters inside the `my_odrive.[...].config` objects. For example to adjust the position gain: `my_odrive.motor0.config.pos_gain = 30` Enter - - The complete list of configurable parameters is: - - `my_odrive.motorN.config.*` - - `my_odrive.axisN.config.*` - - where N is a valid motor number (0 or 1). - - 3. Save the configuration into non-volatile memory: `my_odrive.save_configuration()` Enter - - This will save the properties of all the `[...].config` objects and no other parameters. - 4. Reboot the drive: `my_odrive.reboot()` Enter - -Note that a firmware upgrade at this point will preserve the configuration if and only if the parameters of both firmware versions are identical. Should you need to reset the configuration, you can run `my_odrive.erase_configuration()`. - -__Developers__: Be aware that you can also modify the compile-time defaults for all of these parameters. Most of them you will find at the top of [MotorControl/low_level.c](MotorControl/low_level.c#L50). Note that the configuration parameters there are somewhat intertwined with runtime variables and hardware specific configuration that should not be changed. Also note that all parameters occur twice. - -### Mandatory parameters -You must set for every motor: -* `my_odrive.motorN.encoder.config.cpr`: Encoder Count Per Revolution (CPR). This is 4x the Pulse Per Revolution (PPR) value. -* `my_odrive.motorN.config.pole_pairs`: This is the number of magnet poles in the rotor, **divided by two**. You can simply count the number of permanent magnets in the rotor, if you can see them. Note: this is not the same as the number of coils in the stator. -* `my_odrive.config.brake_resistance` [Ohm]: This is the resistance of the brake resistor. If you are not using it, you may set it to 0.0f. -* `my_odrive.motorN.config.motor_type`: This is the type of motor being used. Currently two types of motors are supported -- High-current motors (`MOTOR_TYPE_HIGH_CURRENT`) and Gimbal motors (`MOTOR_TYPE_GIMBAL`). - -### Motor Modes -The firwmare currently supports two different types of motors, high-current motors, and Gimbal motors. If you're using a regular hobby brushless motor like [this](https://hobbyking.com/en_us/turnigy-aerodrive-sk3-5065-236kv-brushless-outrunner-motor.html) one, you should set `my_odrive.motorN.config.motor_type` to `MOTOR_TYPE_HIGH_CURRENT`. For high-torque gimbal motors like [this](https://hobbyking.com/en_us/turnigy-hd-5208-brushless-gimbal-motor-bldc.html) one, you should choose `MOTOR_TYPE_GIMBAL`. - -**Further detail:** - -If 100's of mA of current noise is "small" for you, you can choose `MOTOR_TYPE_HIGH_CURRENT`. -If 100's of mA of current noise is "large" for you, and you do not intend to spin the motor very fast (omega * L << R), and the motor is fairly large resistance (1 ohm or larger), you can chose `MOTOR_TYPE_GIMBAL`. - -If 100's of mA current noise is "large" for you, and you intend to spin the motor fast, then you need to replace the shunt resistors on the ODrive. - -### Tuning parameters -The most important parameters are the limits: -* The current limit: `my_odrive.motorN.current_control.config.current_lim` [A]. The default current limit, for safety reasons, is set to 10A. This is quite weak, and good for making sure the drive is stable. Once you have tuned the drive, you can increase this to 75A to get some performance. Note that above 75A, you must change the current amplifier gains. - * Note: The motor current and the current drawn from the power supply is not the same in general. You should not look at the power supply current to see what is going on with the motor current. -* The velocity limit: `my_odrive.motorN.config.vel_limit` [counts/s]. The motor will be limited to this speed; again the default value is quite slow. -* You can change `my_odrive.motorN.config.calibration_current` [A] to the largest value you feel comfortable leaving running through the motor continously when the motor is stationary. - -The motion control gains are currently manually tuned: -* `my_odrive.motorN.config.pos_gain = 20.0f` [(counts/s) / counts] -* `my_odrive.motorN.config.vel_gain = 15.0f / 10000.0f` [A/(counts/s)] -* `my_odrive.motorN.config.vel_integrator_gain = 10.0f / 10000.0f` [A/(counts/s * s)] - -An upcoming feature will enable automatic tuning. Until then, here is a rough tuning procedure: -* Set the integrator gain to 0 -* Make sure you have a stable system. If it is not, decrease all gains until you have one. -* Increase `vel_gain` by around 30% per iteration until the motor exhibits some vibration. -* Back down `vel_gain` to 50% of the vibrating value. -* Increase `pos_gain` by around 30% per iteration until you see some overshoot. -* Back down `pos_gain` until you do not have overshoot anymore. -* The integrator is not easily tuned, nor is it strictly required. Tune at your own discression. - -### Optional parameters -By default both motors are enabled, and the default control mode is position control. -If you want a different mode, you can change `my_odrive.motorN.config.control_mode`. Possible values are `CTRL_MODE_VOLTAGE_CONTROL`, `CTRL_MODE_CURRENT_CONTROL`, `CTRL_MODE_VELOCITY_CONTROL` and `CTRL_MODE_POSITION_CONTROL`. -To disable a motor, set `my_odrive.axisN.config.enable_control` and `my_odrive.axisN.config.do_calibration` to `False`. -

## Compiling and downloading firmware ### Getting a programmer @@ -162,7 +98,6 @@ ODrive is a Makefile project. It does not require an IDE, but the open-source I * [Configuring VSCode](configuring-vscode.md) * [Configuring Eclipse](configuring-eclipse.md) -

## No IDE Instructions After installing all of the above, open a Git Bash shell. Continue at section [Building the firmware](#building-the-firmware). @@ -222,6 +157,73 @@ pip install pyusb pyserial ### Other platforms See the [protocol specification](protocol.md) or the [legacy protocol specification](legacy-protocol.md). +

+## Configuring parameters +The majority of the important parameters you would want to set after flashing the ODrive with firmware are configurable over the USB communication interface. These include some mandatory parameters that you must set for correct operation, as well as tuning and optional parameters. +To start the configuration session: + +* Launch `./tools/explore_odrive.py`. This will give you a command prompt where you can modify using simple assignments. +* Configure parameters of the `my_odrive.[...].config` objects. + * For example to adjust the position gain: `my_odrive.motor0.config.pos_gain = 30` Enter. + * The complete list of configurable parameters is: + * `my_odrive.motorN.config.*` + * `my_odrive.axisN.config.*` + * where N is a valid motor number (0 or 1). +* Save the configuration into non-volatile memory: `my_odrive.save_configuration()` Enter + * This will save the properties of all the `[...].config` objects and no other parameters. +* Reboot the drive: `my_odrive.reboot()` Enter + +Note that a firmware upgrade at this point will preserve the configuration if and only if the parameters of both firmware versions are identical. Should you need to reset the configuration, you can run `my_odrive.erase_configuration()`. + +__Developers__: Be aware that you can also modify the compile-time defaults for all of these parameters. Most of them you will find at the top of [MotorControl/low_level.c](MotorControl/low_level.c#L50). Note that the configuration parameters there are somewhat intertwined with runtime variables and hardware specific configuration that should not be changed. Also note that all parameters occur twice. + +### Mandatory parameters +You must set for every motor: +* `my_odrive.motorN.encoder.config.cpr`: Encoder Count Per Revolution (CPR). This is 4x the Pulse Per Revolution (PPR) value. +* `my_odrive.motorN.config.pole_pairs`: This is the number of magnet poles in the rotor, **divided by two**. You can simply count the number of permanent magnets in the rotor, if you can see them. Note: this is not the same as the number of coils in the stator. +* `my_odrive.config.brake_resistance` [Ohm]: This is the resistance of the brake resistor. If you are not using it, you may set it to 0.0f. +* `my_odrive.motorN.config.motor_type`: This is the type of motor being used. Currently two types of motors are supported -- High-current motors (`MOTOR_TYPE_HIGH_CURRENT`) and Gimbal motors (`MOTOR_TYPE_GIMBAL`). + +#### Motor Modes +The firwmare currently supports two different types of motors, high-current motors, and Gimbal motors. If you're using a regular hobby brushless motor like [this](https://hobbyking.com/en_us/turnigy-aerodrive-sk3-5065-236kv-brushless-outrunner-motor.html) one, you should set `my_odrive.motorN.config.motor_type` to `MOTOR_TYPE_HIGH_CURRENT`. For high-torque gimbal motors like [this](https://hobbyking.com/en_us/turnigy-hd-5208-brushless-gimbal-motor-bldc.html) one, you should choose `MOTOR_TYPE_GIMBAL`. + +**Further detail:** +If 100's of mA of current noise is "small" for you, you can choose `MOTOR_TYPE_HIGH_CURRENT`. +If 100's of mA of current noise is "large" for you, and you do not intend to spin the motor very fast (omega * L << R), and the motor is fairly large resistance (1 ohm or larger), you can chose `MOTOR_TYPE_GIMBAL`. +If 100's of mA current noise is "large" for you, and you intend to spin the motor fast, then you need to replace the shunt resistors on the ODrive. + +### Tuning parameters +The most important parameters are the limits: +* The current limit: `my_odrive.motorN.current_control.config.current_lim` [A]. The default current limit, for safety reasons, is set to 10A. This is quite weak, and good for making sure the drive is stable. Once you have tuned the drive, you can increase this to 75A to get some performance. Note that above 75A, you must change the current amplifier gains. + * Note: The motor current and the current drawn from the power supply is not the same in general. You should not look at the power supply current to see what is going on with the motor current. +* The velocity limit: `my_odrive.motorN.config.vel_limit` [counts/s]. The motor will be limited to this speed; again the default value is quite slow. +* You can change `my_odrive.motorN.config.calibration_current` [A] to the largest value you feel comfortable leaving running through the motor continously when the motor is stationary. + +The motion control gains are currently manually tuned: +* `my_odrive.motorN.config.pos_gain = 20.0f` [(counts/s) / counts] +* `my_odrive.motorN.config.vel_gain = 15.0f / 10000.0f` [A/(counts/s)] +* `my_odrive.motorN.config.vel_integrator_gain = 10.0f / 10000.0f` [A/(counts/s * s)] + +An upcoming feature will enable automatic tuning. Until then, here is a rough tuning procedure: +* Set the integrator gain to 0 +* Make sure you have a stable system. If it is not, decrease all gains until you have one. +* Increase `vel_gain` by around 30% per iteration until the motor exhibits some vibration. +* Back down `vel_gain` to 50% of the vibrating value. +* Increase `pos_gain` by around 30% per iteration until you see some overshoot. +* Back down `pos_gain` until you do not have overshoot anymore. +* The integrator is not easily tuned, nor is it strictly required. Tune at your own discression. + +### Optional parameters +By default both motors are enabled, and the default control mode is position control. +If you want a different mode, you can change `my_odrive.motorN.config.control_mode`. +Possible values are: +* `CTRL_MODE_POSITION_CONTROL` +* `CTRL_MODE_VELOCITY_CONTROL` +* `CTRL_MODE_CURRENT_CONTROL` +* `CTRL_MODE_VOLTAGE_CONTROL` - this one is not normally used. + +To disable a motor at startup, set `my_odrive.axisN.config.enable_control` and `my_odrive.axisN.config.do_calibration` to `False`. +

## Encoder Calibration By default the encoder-to-motor calibration will run on every startup. During encoder calibration the rotor must be allowed to rotate without any biased load during startup. That means mass and weak friction loads are fine, but gravity or spring loads are not okay. From 472728aeb93490b7009993fd479ebef1c64d88f5 Mon Sep 17 00:00:00 2001 From: Oskar Weigl Date: Sun, 25 Feb 2018 23:48:06 -0800 Subject: [PATCH 41/53] Update Tupfile.lua --- Firmware/Tupfile.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Firmware/Tupfile.lua b/Firmware/Tupfile.lua index 65aea209..dec05271 100644 --- a/Firmware/Tupfile.lua +++ b/Firmware/Tupfile.lua @@ -69,7 +69,7 @@ build{ 'MotorControl/nvm.c', 'MotorControl/axis.cpp', 'MotorControl/commands.cpp', - 'MotorControl/protocol.cpp' + 'MotorControl/protocol.cpp', 'MotorControl/config.cpp' }, includes={ From 2ed8d17fb8b2fb1d62533333213373c905484717 Mon Sep 17 00:00:00 2001 From: Oskar Weigl Date: Sun, 25 Feb 2018 23:50:43 -0800 Subject: [PATCH 42/53] fix comma --- Firmware/MotorControl/low_level.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Firmware/MotorControl/low_level.c b/Firmware/MotorControl/low_level.c index a3c1246b..3bd65cc4 100644 --- a/Firmware/MotorControl/low_level.c +++ b/Firmware/MotorControl/low_level.c @@ -264,7 +264,7 @@ Motor_t motors[] = { .calib_anticogging = false, .calib_pos_threshold = 1.0f, .calib_vel_threshold = 1.0f, - } + }, .drv_fault = DRV8301_FaultType_NoFault, } }; From 037f715dc2626f592edb7f33b99762180c3aa430 Mon Sep 17 00:00:00 2001 From: Oskar Weigl Date: Sun, 25 Feb 2018 23:54:17 -0800 Subject: [PATCH 43/53] elec_rad_per_enc also evaluated in check CPR --- Firmware/MotorControl/low_level.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Firmware/MotorControl/low_level.c b/Firmware/MotorControl/low_level.c index 3bd65cc4..ad06623f 100644 --- a/Firmware/MotorControl/low_level.c +++ b/Firmware/MotorControl/low_level.c @@ -805,6 +805,8 @@ bool calib_enc_offset(Motor_t* motor, float voltage_magnitude) { encvaluesum += (int16_t)motor->encoder.encoder_timer->Instance->CNT; } + //TODO avoid recomputing elec_rad_per_enc every time + float elec_rad_per_enc = motor->pole_pairs * 2 * M_PI * (1.0f / (float)(motor->encoder.encoder_cpr)); float expected_encoder_delta = scan_range / elec_rad_per_enc; float actual_encoder_delta_abs = fabsf((int16_t)motor->encoder.encoder_timer->Instance->CNT-init_enc_val); if(fabsf(actual_encoder_delta_abs - expected_encoder_delta)/expected_encoder_delta > motor->encoder.encoder_calib_range) @@ -975,6 +977,7 @@ void update_rotor(Motor_t* motor) { int corrected_enc = encoder->encoder_state % motor->encoder.encoder_cpr; corrected_enc -= encoder->encoder_offset; corrected_enc *= encoder->motor_dir; + //TODO avoid recomputing elec_rad_per_enc every time 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); From 5d87b7602f5afaba9ab476faebc0a5fd891d0fa2 Mon Sep 17 00:00:00 2001 From: Oskar Weigl Date: Sat, 17 Feb 2018 16:46:33 -0800 Subject: [PATCH 44/53] make timing log static --- Firmware/MotorControl/commands.cpp | 26 ++++++++++++++++++++++++++ Firmware/MotorControl/low_level.c | 27 ++++++++++++--------------- Firmware/MotorControl/low_level.h | 17 +++++++++++++++-- 3 files changed, 53 insertions(+), 17 deletions(-) diff --git a/Firmware/MotorControl/commands.cpp b/Firmware/MotorControl/commands.cpp index 87d46873..a3b704c1 100644 --- a/Firmware/MotorControl/commands.cpp +++ b/Firmware/MotorControl/commands.cpp @@ -171,6 +171,19 @@ const Endpoint endpoints[] = { Endpoint::make_function("set_current_setpoint", &motors_0_set_current_setpoint_func), Endpoint::make_property("current_setpoint", &motors[0].set_current_setpoint_args.current_setpoint), Endpoint::close_tree(), + Endpoint::make_object("timing_log"), + Endpoint::make_property("TIMING_LOG_GENERAL", &motors[0].timing_log[TIMING_LOG_GENERAL]), + Endpoint::make_property("TIMING_LOG_ADC_CB_M0_I", &motors[0].timing_log[TIMING_LOG_ADC_CB_M0_I]), + Endpoint::make_property("TIMING_LOG_ADC_CB_M0_DC", &motors[0].timing_log[TIMING_LOG_ADC_CB_M0_DC]), + Endpoint::make_property("TIMING_LOG_ADC_CB_M1_I", &motors[0].timing_log[TIMING_LOG_ADC_CB_M1_I]), + Endpoint::make_property("TIMING_LOG_ADC_CB_M1_DC", &motors[0].timing_log[TIMING_LOG_ADC_CB_M1_DC]), + Endpoint::make_property("TIMING_LOG_MEAS_R", &motors[0].timing_log[TIMING_LOG_MEAS_R]), + Endpoint::make_property("TIMING_LOG_MEAS_L", &motors[0].timing_log[TIMING_LOG_MEAS_L]), + Endpoint::make_property("TIMING_LOG_ENC_CALIB", &motors[0].timing_log[TIMING_LOG_ENC_CALIB]), + Endpoint::make_property("TIMING_LOG_IDX_SEARCH", &motors[0].timing_log[TIMING_LOG_IDX_SEARCH]), + Endpoint::make_property("TIMING_LOG_FOC_VOLTAGE", &motors[0].timing_log[TIMING_LOG_FOC_VOLTAGE]), + Endpoint::make_property("TIMING_LOG_FOC_CURRENT", &motors[0].timing_log[TIMING_LOG_FOC_CURRENT]), + Endpoint::close_tree(), Endpoint::close_tree(), // motor0 Endpoint::make_object("motor1"), Endpoint::make_property("control_mode", reinterpret_cast(&motors[1].control_mode)), @@ -235,6 +248,19 @@ const Endpoint endpoints[] = { Endpoint::make_function("set_current_setpoint", &motors_1_set_current_setpoint_func), Endpoint::make_property("current_setpoint", &motors[1].set_current_setpoint_args.current_setpoint), Endpoint::close_tree(), + Endpoint::make_object("timing_log"), + Endpoint::make_property("TIMING_LOG_GENERAL", &motors[1].timing_log[TIMING_LOG_GENERAL]), + Endpoint::make_property("TIMING_LOG_ADC_CB_M0_I", &motors[1].timing_log[TIMING_LOG_ADC_CB_M0_I]), + Endpoint::make_property("TIMING_LOG_ADC_CB_M0_DC", &motors[1].timing_log[TIMING_LOG_ADC_CB_M0_DC]), + Endpoint::make_property("TIMING_LOG_ADC_CB_M1_I", &motors[1].timing_log[TIMING_LOG_ADC_CB_M1_I]), + Endpoint::make_property("TIMING_LOG_ADC_CB_M1_DC", &motors[1].timing_log[TIMING_LOG_ADC_CB_M1_DC]), + Endpoint::make_property("TIMING_LOG_MEAS_R", &motors[1].timing_log[TIMING_LOG_MEAS_R]), + Endpoint::make_property("TIMING_LOG_MEAS_L", &motors[1].timing_log[TIMING_LOG_MEAS_L]), + Endpoint::make_property("TIMING_LOG_ENC_CALIB", &motors[1].timing_log[TIMING_LOG_ENC_CALIB]), + Endpoint::make_property("TIMING_LOG_IDX_SEARCH", &motors[1].timing_log[TIMING_LOG_IDX_SEARCH]), + Endpoint::make_property("TIMING_LOG_FOC_VOLTAGE", &motors[1].timing_log[TIMING_LOG_FOC_VOLTAGE]), + Endpoint::make_property("TIMING_LOG_FOC_CURRENT", &motors[1].timing_log[TIMING_LOG_FOC_CURRENT]), + Endpoint::close_tree(), Endpoint::close_tree() // motor1 }; // clang-format on diff --git a/Firmware/MotorControl/low_level.c b/Firmware/MotorControl/low_level.c index 88014cd9..4b4a096e 100644 --- a/Firmware/MotorControl/low_level.c +++ b/Firmware/MotorControl/low_level.c @@ -154,7 +154,6 @@ Motor_t motors[] = { .spin_up_target_vel = 400.0f, // [rad/s] }, .loop_counter = 0, - .timing_log_index = 0, .timing_log = {0}, .anticogging = { .index = 0, @@ -259,7 +258,6 @@ Motor_t motors[] = { .spin_up_target_vel = 400.0f, // [rad/s] }, .loop_counter = 0, - .timing_log_index = 0, .timing_log = {0}, .anticogging = { .index = 0, @@ -319,7 +317,7 @@ void set_current_setpoint(Motor_t* motor, float current_setpoint) { // Utility //-------------------------------- -uint16_t check_timing(Motor_t* motor) { +uint16_t check_timing(Motor_t* motor, TimingLog_t log_idx) { TIM_HandleTypeDef* htim = motor->motor_timer; uint16_t timing = htim->Instance->CNT; bool down = htim->Instance->CR1 & TIM_CR1_DIR; @@ -328,10 +326,9 @@ uint16_t check_timing(Motor_t* motor) { timing = TIM_1_8_PERIOD_CLOCKS + delta; } - if (++(motor->timing_log_index) == TIMING_LOG_SIZE) { - motor->timing_log_index = 0; + if (log_idx < TIMING_LOG_SIZE) { + motor->timing_log[log_idx] = timing; } - motor->timing_log[motor->timing_log_index] = timing; return timing; } @@ -611,7 +608,7 @@ void pwm_trig_adc_cb(ADC_HandleTypeDef* hadc, bool injected) { motors[0].motor_timer->Instance->CCR3 = motors[0].next_timings[2]; } // Check the timing of the sequencing - check_timing(motor); + check_timing(motor, TIMING_LOG_ADC_CB_M1_DC); } else if (motor == &motors[0] && !counting_down) { // We are measuring M0 current here @@ -623,19 +620,19 @@ void pwm_trig_adc_cb(ADC_HandleTypeDef* hadc, bool injected) { motors[1].motor_timer->Instance->CCR3 = motors[1].next_timings[2]; } // Check the timing of the sequencing - check_timing(motor); + check_timing(motor, TIMING_LOG_ADC_CB_M0_I); } else if (motor == &motors[1] && !counting_down) { // We are measuring M1 current here current_meas_not_DC_CAL = true; // Check the timing of the sequencing - check_timing(motor); + check_timing(motor, TIMING_LOG_ADC_CB_M1_I); } else if (motor == &motors[0] && counting_down) { // We are measuring M0 DC_CAL here current_meas_not_DC_CAL = false; // Check the timing of the sequencing - check_timing(motor); + check_timing(motor, TIMING_LOG_ADC_CB_M0_DC); } else { global_fault(ERROR_PWM_SRC_FAIL); @@ -704,7 +701,7 @@ bool measure_phase_resistance(Motor_t* motor, float test_current, float max_volt queue_voltage_timings(motor, test_voltage, 0.0f); // Check we meet deadlines after queueing - motor->last_cpu_time = check_timing(motor); + motor->last_cpu_time = check_timing(motor, TIMING_LOG_MEAS_R); if (!(motor->last_cpu_time < motor->control_deadline)) { motor->error = ERROR_PHASE_RESISTANCE_TIMING; return false; @@ -743,7 +740,7 @@ bool measure_phase_inductance(Motor_t* motor, float voltage_low, float voltage_h queue_voltage_timings(motor, test_voltages[i], 0.0f); // Check we meet deadlines after queueing - motor->last_cpu_time = check_timing(motor); + motor->last_cpu_time = check_timing(motor, TIMING_LOG_MEAS_L); if (!(motor->last_cpu_time < motor->control_deadline)) { motor->error = ERROR_PHASE_INDUCTANCE_TIMING; return false; @@ -950,7 +947,7 @@ bool scan_for_enc_idx(Motor_t* motor, float omega, float voltage_magnitude) { queue_voltage_timings(motor, v_alpha, v_beta); // Check we meet deadlines after queueing - motor->last_cpu_time = check_timing(motor); + motor->last_cpu_time = check_timing(motor, TIMING_LOG_IDX_SEARCH); if (!(motor->last_cpu_time < motor->control_deadline)) { motor->error = ERROR_SCAN_MOTOR_TIMING; return false; @@ -1237,7 +1234,7 @@ bool FOC_voltage(Motor_t* motor, float v_d, float v_q) { queue_voltage_timings(motor, v_alpha, v_beta); // Check we meet deadlines after queueing - if (!(check_timing(motor) < motor->control_deadline)) { + if (!(check_timing(motor, TIMING_LOG_FOC_VOLTAGE) < motor->control_deadline)) { motor->error = ERROR_FOC_VOLTAGE_TIMING; return false; } @@ -1305,7 +1302,7 @@ bool FOC_current(Motor_t* motor, float Id_des, float Iq_des) { queue_modulation_timings(motor, mod_alpha, mod_beta); // Check we meet deadlines after queueing - motor->last_cpu_time = check_timing(motor); + motor->last_cpu_time = check_timing(motor, TIMING_LOG_FOC_CURRENT); if (!(motor->last_cpu_time < motor->control_deadline)) { motor->error = ERROR_FOC_TIMING; return false; diff --git a/Firmware/MotorControl/low_level.h b/Firmware/MotorControl/low_level.h index baad486e..3f0e4f2b 100644 --- a/Firmware/MotorControl/low_level.h +++ b/Firmware/MotorControl/low_level.h @@ -174,7 +174,6 @@ typedef struct { Encoder_t encoder; Sensorless_t sensorless; uint32_t loop_counter; - int timing_log_index; uint16_t timing_log[TIMING_LOG_SIZE]; // Cache for remote procedure calls arguments struct { @@ -193,6 +192,20 @@ typedef struct { DRV8301_FaultType_e drv_fault; } Motor_t; +typedef enum { + TIMING_LOG_GENERAL, + TIMING_LOG_ADC_CB_M0_I, + TIMING_LOG_ADC_CB_M0_DC, + TIMING_LOG_ADC_CB_M1_I, + TIMING_LOG_ADC_CB_M1_DC, + TIMING_LOG_MEAS_R, + TIMING_LOG_MEAS_L, + TIMING_LOG_ENC_CALIB, + TIMING_LOG_IDX_SEARCH, + TIMING_LOG_FOC_VOLTAGE, + TIMING_LOG_FOC_CURRENT, +} TimingLog_t; + typedef struct{ int type; int index; @@ -228,7 +241,7 @@ bool motor_calibration(Motor_t* motor); //// Old private: // Utility -uint16_t check_timing(Motor_t* motor); +uint16_t check_timing(Motor_t* motor, TimingLog_t log_idx); void global_fault(int error); float phase_current_from_adcval(Motor_t* motor, uint32_t ADCValue); // Initalisation From f41bf4e7736a031558d3e24317c77d38c530c132 Mon Sep 17 00:00:00 2001 From: Oskar Weigl Date: Thu, 1 Mar 2018 21:51:23 -0800 Subject: [PATCH 45/53] Update README.md --- Firmware/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Firmware/README.md b/Firmware/README.md index fb89c2b1..b2ea4e45 100644 --- a/Firmware/README.md +++ b/Firmware/README.md @@ -128,7 +128,7 @@ To compile the program, you first need to install the prerequisite tools: * Installing on Ubuntu: `sudo apt-get install openocd` * Installing on Arch Linux: build and install the [AUR package](https://aur.archlinux.org/packages/openocd/) * `tup`: Used as a build tool - * Installing on Ubuntu: `sudo apt-add-repository 'deb http://ppa.launchpad.net/anatol/tup/ubuntu precise main'; sudo apt-get update; sudo apt-get install tup` + * Installing on Ubuntu: `sudo add-apt-repository ppa:jonathonf/tup; sudo apt-get update; sudo apt-get install tup` * Installing on Arch Linux: `sudo pacman -S tup` * No additional USB CDC driver should be required on Linux. From 8289e0a575c2fcb9c31ca086fdf91f08e5969eac Mon Sep 17 00:00:00 2001 From: Agustin Nunez Date: Fri, 2 Mar 2018 12:58:30 +0000 Subject: [PATCH 46/53] Add usbpermission command script --- usbpermission | 1 + 1 file changed, 1 insertion(+) create mode 100755 usbpermission diff --git a/usbpermission b/usbpermission new file mode 100755 index 00000000..5ea6d8e9 --- /dev/null +++ b/usbpermission @@ -0,0 +1 @@ +sudo udevadm control --reload-rules && sudo service udev restart && sudo udevadm trigger From 7cd68e0cffa7d3ef877f65614dfe09be6e39a0ac Mon Sep 17 00:00:00 2001 From: Oskar Weigl Date: Fri, 2 Mar 2018 15:38:18 -0800 Subject: [PATCH 47/53] move to tools --- usbpermission => tools/usbpermission | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename usbpermission => tools/usbpermission (100%) diff --git a/usbpermission b/tools/usbpermission similarity index 100% rename from usbpermission rename to tools/usbpermission From 8281ccafa7063c74ac1555aa7a05303d9905299a Mon Sep 17 00:00:00 2001 From: Paul Guenette Date: Fri, 2 Mar 2018 20:51:28 -0500 Subject: [PATCH 48/53] Clean up intellisense handling It's not perfect but much better than it was. --- Firmware/.vscode/c_cpp_properties.json | 211 +++++++++++-------------- Firmware/.vscode/settings.json | 2 + 2 files changed, 96 insertions(+), 117 deletions(-) diff --git a/Firmware/.vscode/c_cpp_properties.json b/Firmware/.vscode/c_cpp_properties.json index 691314ac..150b7c96 100644 --- a/Firmware/.vscode/c_cpp_properties.json +++ b/Firmware/.vscode/c_cpp_properties.json @@ -4,136 +4,113 @@ "name": "Win32", "includePath": [ "${workspaceRoot}", - "${workspaceRoot}/Middlewares/Third_Party/FreeRTOS/Source/portable/GCC/ARM_CM4F", - "${workspaceRoot}/Middlewares/Third_Party/FreeRTOS/Source/include", - "${workspaceRoot}/Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS", - "${workspaceRoot}/Drivers/DRV8301", - "${workspaceRoot}/Middlewares/ST/STM32_USB_Device_Library/Core/Inc", - "${workspaceRoot}/Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Inc", - "${workspaceRoot}/Drivers/STM32F4xx_HAL_Driver/Inc", - "${workspaceRoot}/Drivers/STM32F4xx_HAL_Driver/Inc/Legacy", - "${workspaceRoot}/Drivers/CMSIS/Device/ST/STM32F4xx/Include", - "${workspaceRoot}/Drivers/CMSIS/Include", - "${workspaceRoot}/Inc", "${workspaceRoot}/MotorControl", - "C:/Program Files (x86)/GNU Tools ARM Embedded/6 2017-q1-update/arm-none-eabi/include/c++/6.3.1", - "C:/Program Files (x86)/GNU Tools ARM Embedded/6 2017-q1-update/arm-none-eabi/include/c++/6.3.1/arm-none-eabi", - "C:/Program Files (x86)/GNU Tools ARM Embedded/6 2017-q1-update/lib/gcc/arm-none-eabi/6.3.1/include", - "C:/Program Files (x86)/GNU Tools ARM Embedded/6 2017-q1-update/arm-none-eabi/include" + "${workspaceRoot}/Board/v3.3/Inc", + "${workspaceRoot}/Board/v3.3/Drivers/CMSIS/Include", + "${workspaceRoot}/Board/v3.3/Drivers/CMSIS/Device/ST/STM32F4xx/Include", + "${workspaceRoot}/Board/v3.3/Drivers/DRV8301", + "${workspaceRoot}/Board/v3.3/Drivers/STM32F4xx_HAL_Driver/Inc", + "${workspaceRoot}/Board/v3.3/Drivers/STM32F4xx_HAL_Driver/Inc/Legacy", + "${workspaceRoot}/Board/v3.3/Middlewares/ST/STM32_USB_Device_Library/Core/Inc", + "${workspaceRoot}/Board/v3.3/Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Inc", + "${workspaceRoot}/Board/v3.3/Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS", + "${workspaceRoot}/Board/v3.3/Middlewares/Third_Party/FreeRTOS/Source/include", + "${workspaceRoot}/Board/v3.3/Middlewares/Third_Party/FreeRTOS/Source/portable/GCC/ARM_CM4F", + "c:/program files (x86)/gnu tools arm embedded/6 2017-q1-update/arm-none-eabi/include/c++/6.3.1", + "c:/program files (x86)/gnu tools arm embedded/6 2017-q1-update/arm-none-eabi/include/c++/6.3.1/arm-none-eabi", + "c:/program files (x86)/gnu tools arm embedded/6 2017-q1-update/arm-none-eabi/include/c++/6.3.1/backward", + "c:/program files (x86)/gnu tools arm embedded/6 2017-q1-update/lib/gcc/arm-none-eabi/6.3.1/include", + "c:/program files (x86)/gnu tools arm embedded/6 2017-q1-update/arm-none-eabi/include" ], "defines": [ - "_DEBUG", - "UNICODE" + "STM32F405xx", + "USE_HAL_DRIVER", + "__weak=\"__attribute__((weak))\"", + "__packed=\"__attribute__((__packed__))\"", + "__GNUC__" ], "intelliSenseMode": "clang-x64", "browse": { "path": [ "${workspaceRoot}", - "${workspaceRoot}/Middlewares/Third_Party/FreeRTOS/Source/portable/GCC/ARM_CM4F", - "${workspaceRoot}/Middlewares/Third_Party/FreeRTOS/Source/include", - "${workspaceRoot}/Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS", - "${workspaceRoot}/Drivers/DRV8301", - "${workspaceRoot}/Middlewares/ST/STM32_USB_Device_Library/Core/Inc", - "${workspaceRoot}/Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Inc", - "${workspaceRoot}/Drivers/STM32F4xx_HAL_Driver/Inc", - "${workspaceRoot}/Drivers/STM32F4xx_HAL_Driver/Inc/Legacy", - "${workspaceRoot}/Drivers/CMSIS/Device/ST/STM32F4xx/Include", - "${workspaceRoot}/Drivers/CMSIS/Include", - "${workspaceRoot}/Inc", - "${workspaceRoot}/MotorControl" + "C:/Program Files (x86)/GNU Tools ARM Embedded" ], - "limitSymbolsToIncludedHeaders": true, - "databaseFilename": "" + "limitSymbolsToIncludedHeaders": true } }, - { - "name": "Linux", - "includePath": [ - "${workspaceRoot}", - "${workspaceRoot}/Middlewares/Third_Party/FreeRTOS/Source/portable/GCC/ARM_CM4F", - "${workspaceRoot}/Middlewares/Third_Party/FreeRTOS/Source/include", - "${workspaceRoot}/Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS", - "${workspaceRoot}/Drivers/DRV8301", - "${workspaceRoot}/Middlewares/ST/STM32_USB_Device_Library/Core/Inc", - "${workspaceRoot}/Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Inc", - "${workspaceRoot}/Drivers/STM32F4xx_HAL_Driver/Inc", - "${workspaceRoot}/Drivers/STM32F4xx_HAL_Driver/Inc/Legacy", - "${workspaceRoot}/Drivers/CMSIS/Device/ST/STM32F4xx/Include", - "${workspaceRoot}/Drivers/CMSIS/Include", - "${workspaceRoot}/Inc", - "${workspaceRoot}/MotorControl", - "/usr/lib/gcc/arm-none-eabi/4.9.3/include", - "/usr/lib/arm-none-eabi/include" - ], - "defines": [ - "_DEBUG", - "UNICODE" - ], - "intelliSenseMode": "clang-x64", - "browse": { - "path": [ + { + "name": "Linux", + "includePath": [ + "${workspaceRoot}", + "${workspaceRoot}/Middlewares/Third_Party/FreeRTOS/Source/portable/GCC/ARM_CM4F", + "${workspaceRoot}/Middlewares/Third_Party/FreeRTOS/Source/include", + "${workspaceRoot}/Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS", + "${workspaceRoot}/Drivers/DRV8301", + "${workspaceRoot}/Middlewares/ST/STM32_USB_Device_Library/Core/Inc", + "${workspaceRoot}/Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Inc", + "${workspaceRoot}/Drivers/STM32F4xx_HAL_Driver/Inc", + "${workspaceRoot}/Drivers/STM32F4xx_HAL_Driver/Inc/Legacy", + "${workspaceRoot}/Drivers/CMSIS/Device/ST/STM32F4xx/Include", + "${workspaceRoot}/Drivers/CMSIS/Include", + "${workspaceRoot}/Inc", + "${workspaceRoot}/MotorControl", + "/usr/lib/gcc/arm-none-eabi/4.9.3/include", + "/usr/lib/arm-none-eabi/include" + ], + "defines": [ + "STM32F405xx", + "USE_HAL_DRIVER", + "__weak=\"__attribute__((weak))\"", + "__packed=\"__attribute__((__packed__))\"", + "__GNUC__" + ], + "intelliSenseMode": "clang-x64", + "browse": { + "path": [ "${workspaceRoot}", - "${workspaceRoot}/Middlewares/Third_Party/FreeRTOS/Source/portable/GCC/ARM_CM4F", - "${workspaceRoot}/Middlewares/Third_Party/FreeRTOS/Source/include", - "${workspaceRoot}/Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS", - "${workspaceRoot}/Drivers/DRV8301", - "${workspaceRoot}/Middlewares/ST/STM32_USB_Device_Library/Core/Inc", - "${workspaceRoot}/Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Inc", - "${workspaceRoot}/Drivers/STM32F4xx_HAL_Driver/Inc", - "${workspaceRoot}/Drivers/STM32F4xx_HAL_Driver/Inc/Legacy", - "${workspaceRoot}/Drivers/CMSIS/Device/ST/STM32F4xx/Include", - "${workspaceRoot}/Drivers/CMSIS/Include", - "${workspaceRoot}/Inc", - "${workspaceRoot}/MotorControl" - ], - "limitSymbolsToIncludedHeaders": true, - "databaseFilename": "" - } - }, - { - "name": "MacOS", - "includePath": [ - "${workspaceRoot}", - "${workspaceRoot}/Middlewares/Third_Party/FreeRTOS/Source/portable/GCC/ARM_CM4F", - "${workspaceRoot}/Middlewares/Third_Party/FreeRTOS/Source/include", - "${workspaceRoot}/Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS", - "${workspaceRoot}/Drivers/DRV8301", - "${workspaceRoot}/Middlewares/ST/STM32_USB_Device_Library/Core/Inc", - "${workspaceRoot}/Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Inc", - "${workspaceRoot}/Drivers/STM32F4xx_HAL_Driver/Inc", - "${workspaceRoot}/Drivers/STM32F4xx_HAL_Driver/Inc/Legacy", - "${workspaceRoot}/Drivers/CMSIS/Device/ST/STM32F4xx/Include", - "${workspaceRoot}/Drivers/CMSIS/Include", - "${workspaceRoot}/Inc", - "${workspaceRoot}/MotorControl", - "/usr/local/Caskroom/gcc-arm-embedded/6-2017-q2-update/gcc-arm-none-eabi-6-2017-q2-update/arm-none-eabi/include", - "/usr/local/Caskroom/gcc-arm-embedded/6-2017-q2-update/gcc-arm-none-eabi-6-2017-q2-update/arm-none-eabi/include/c++/6.3.1", - "/usr/local/Caskroom/gcc-arm-embedded/6-2017-q2-update/gcc-arm-none-eabi-6-2017-q2-update/arm-none-eabi/include/c++/6.3.1/arm-none-eabi", - "/usr/local/Caskroom/gcc-arm-embedded/6-2017-q2-update/gcc-arm-none-eabi-6-2017-q2-update/lib/gcc/arm-none-eabi/6.3.1/include" - ], - "defines": [ - "_DEBUG", - "UNICODE" - ], - "intelliSenseMode": "clang-x64", - "browse": { - "path": [ + "/usr/lib/gcc/arm-none-eabi/4.9.3/include", + "/usr/lib/arm-none-eabi/include" + ], + "limitSymbolsToIncludedHeaders": true, + "databaseFilename": "" + } + }, + { + "name": "MacOS", + "includePath": [ + "${workspaceRoot}", + "${workspaceRoot}/Middlewares/Third_Party/FreeRTOS/Source/portable/GCC/ARM_CM4F", + "${workspaceRoot}/Middlewares/Third_Party/FreeRTOS/Source/include", + "${workspaceRoot}/Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS", + "${workspaceRoot}/Drivers/DRV8301", + "${workspaceRoot}/Middlewares/ST/STM32_USB_Device_Library/Core/Inc", + "${workspaceRoot}/Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Inc", + "${workspaceRoot}/Drivers/STM32F4xx_HAL_Driver/Inc", + "${workspaceRoot}/Drivers/STM32F4xx_HAL_Driver/Inc/Legacy", + "${workspaceRoot}/Drivers/CMSIS/Device/ST/STM32F4xx/Include", + "${workspaceRoot}/Drivers/CMSIS/Include", + "${workspaceRoot}/Inc", + "${workspaceRoot}/MotorControl", + "/usr/local/Caskroom/gcc-arm-embedded/6-2017-q2-update/gcc-arm-none-eabi-6-2017-q2-update/arm-none-eabi/include", + "/usr/local/Caskroom/gcc-arm-embedded/6-2017-q2-update/gcc-arm-none-eabi-6-2017-q2-update/arm-none-eabi/include/c++/6.3.1", + "/usr/local/Caskroom/gcc-arm-embedded/6-2017-q2-update/gcc-arm-none-eabi-6-2017-q2-update/arm-none-eabi/include/c++/6.3.1/arm-none-eabi", + "/usr/local/Caskroom/gcc-arm-embedded/6-2017-q2-update/gcc-arm-none-eabi-6-2017-q2-update/lib/gcc/arm-none-eabi/6.3.1/include" + ], + "defines": [ + "STM32F405xx", + "USE_HAL_DRIVER", + "__weak=\"__attribute__((weak))\"", + "__packed=\"__attribute__((__packed__))\"", + "__GNUC__" + ], + "intelliSenseMode": "clang-x64", + "browse": { + "path": [ "${workspaceRoot}", - "${workspaceRoot}/Middlewares/Third_Party/FreeRTOS/Source/portable/GCC/ARM_CM4F", - "${workspaceRoot}/Middlewares/Third_Party/FreeRTOS/Source/include", - "${workspaceRoot}/Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS", - "${workspaceRoot}/Drivers/DRV8301", - "${workspaceRoot}/Middlewares/ST/STM32_USB_Device_Library/Core/Inc", - "${workspaceRoot}/Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Inc", - "${workspaceRoot}/Drivers/STM32F4xx_HAL_Driver/Inc", - "${workspaceRoot}/Drivers/STM32F4xx_HAL_Driver/Inc/Legacy", - "${workspaceRoot}/Drivers/CMSIS/Device/ST/STM32F4xx/Include", - "${workspaceRoot}/Drivers/CMSIS/Include", - "${workspaceRoot}/Inc", - "${workspaceRoot}/MotorControl" - ], - "limitSymbolsToIncludedHeaders": true, - "databaseFilename": "" + "/usr/local/Caskroom/gcc-arm-embedded/" + ], + "limitSymbolsToIncludedHeaders": true, + "databaseFilename": "" } } ], diff --git a/Firmware/.vscode/settings.json b/Firmware/.vscode/settings.json index 8f45c82a..63c1463b 100644 --- a/Firmware/.vscode/settings.json +++ b/Firmware/.vscode/settings.json @@ -1,5 +1,7 @@ { "C_Cpp.clang_format_style": "{ BasedOnStyle: Google, IndentWidth: 4, ColumnLimit: 0 }", + "C_Cpp.intelliSenseEngine": "Default", + "C_Cpp.intelliSenseEngineFallback": "Disabled", "files.exclude": { "build": true }, From 898d9c64b4e103621e0396407e39da5655a7a7fe Mon Sep 17 00:00:00 2001 From: Oskar Weigl Date: Fri, 2 Mar 2018 23:05:40 -0800 Subject: [PATCH 49/53] fix saving of calibrated flag --- Firmware/MotorControl/commands.cpp | 12 ++++++------ Firmware/MotorControl/config.cpp | 6 +++--- Firmware/MotorControl/low_level.c | 7 +++---- Firmware/MotorControl/low_level.h | 2 +- Firmware/Tupfile.lua | 6 ++---- 5 files changed, 15 insertions(+), 18 deletions(-) diff --git a/Firmware/MotorControl/commands.cpp b/Firmware/MotorControl/commands.cpp index e2a133f6..22d08a6c 100644 --- a/Firmware/MotorControl/commands.cpp +++ b/Firmware/MotorControl/commands.cpp @@ -114,8 +114,8 @@ const Endpoint endpoints[] = { Endpoint::close_tree(), Endpoint::make_object("axis0"), Endpoint::make_object("config"), - Endpoint::make_property("enable_control", &axis_configs[0].enable_control_at_start), - Endpoint::make_property("do_calibration", &axis_configs[0].do_calibration_at_start), + Endpoint::make_property("enable_control_at_start", &axis_configs[0].enable_control_at_start), + Endpoint::make_property("do_calibration_at_start", &axis_configs[0].do_calibration_at_start), Endpoint::close_tree(), Endpoint::close_tree(), Endpoint::make_object("motor0"), @@ -171,7 +171,7 @@ const Endpoint endpoints[] = { Endpoint::make_object("encoder"), Endpoint::make_object("config"), Endpoint::make_property("use_index", &motors[0].encoder.use_index), - Endpoint::make_property("calibrated", &motors[0].encoder.calibrated), + Endpoint::make_property("manually_calibrated", &motors[0].encoder.manually_calibrated), Endpoint::make_property("idx_search_speed", &motors[0].encoder.idx_search_speed), Endpoint::make_property("cpr", &motors[0].encoder.encoder_cpr), Endpoint::make_property("offset", &motors[0].encoder.encoder_offset), @@ -214,8 +214,8 @@ const Endpoint endpoints[] = { Endpoint::close_tree(), // motor0 Endpoint::make_object("axis1"), Endpoint::make_object("config"), - Endpoint::make_property("enable_control", &axis_configs[1].enable_control_at_start), - Endpoint::make_property("do_calibration", &axis_configs[1].do_calibration_at_start), + Endpoint::make_property("enable_control_at_start", &axis_configs[1].enable_control_at_start), + Endpoint::make_property("do_calibration_at_start", &axis_configs[1].do_calibration_at_start), Endpoint::close_tree(), Endpoint::close_tree(), Endpoint::make_object("motor1"), @@ -271,7 +271,7 @@ const Endpoint endpoints[] = { Endpoint::make_object("encoder"), Endpoint::make_object("config"), Endpoint::make_property("use_index", &motors[1].encoder.use_index), - Endpoint::make_property("calibrated", &motors[1].encoder.calibrated), + Endpoint::make_property("manually_calibrated", &motors[1].encoder.manually_calibrated), Endpoint::make_property("idx_search_speed", &motors[1].encoder.idx_search_speed), Endpoint::make_property("cpr", &motors[1].encoder.encoder_cpr), Endpoint::make_property("offset", &motors[1].encoder.encoder_offset), diff --git a/Firmware/MotorControl/config.cpp b/Firmware/MotorControl/config.cpp index 847a8938..e61a8102 100644 --- a/Firmware/MotorControl/config.cpp +++ b/Firmware/MotorControl/config.cpp @@ -38,7 +38,7 @@ typedef struct { Rotor_mode_t rotor_mode; float current_control_current_lim; bool encoder_use_index; - bool encoder_calibrated; + bool encoder_manually_calibrated; float encoder_idx_search_speed; int32_t encoder_cpr; int32_t encoder_offset; @@ -178,7 +178,7 @@ void set_motor_config(const MotorConfig_t* config, Motor_t* motor) { 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.manually_calibrated = config->encoder_manually_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; @@ -205,7 +205,7 @@ void get_motor_config(const Motor_t* motor, MotorConfig_t* config) { 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_manually_calibrated = motor->encoder.manually_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; diff --git a/Firmware/MotorControl/low_level.c b/Firmware/MotorControl/low_level.c index 8171c938..c1e99742 100644 --- a/Firmware/MotorControl/low_level.c +++ b/Firmware/MotorControl/low_level.c @@ -120,7 +120,7 @@ Motor_t motors[] = { .encoder_timer = &htim3, .use_index = false, .index_found = false, - .calibrated = false, + .manually_calibrated = false, .idx_search_speed = 10.0f, // [rad/s electrical] .encoder_cpr = (2048 * 4), // Default resolution of CUI-AMT102 encoder, .encoder_offset = 0, @@ -225,7 +225,7 @@ Motor_t motors[] = { .encoder_timer = &htim4, .use_index = false, .index_found = false, - .calibrated = false, + .manually_calibrated = false, .idx_search_speed = 10.0f, // [rad/s electrical] .encoder_cpr = (2048 * 4), // Default resolution of CUI-AMT102 encoder, .encoder_offset = 0, @@ -841,7 +841,6 @@ bool calib_enc_offset(Motor_t* motor, float voltage_magnitude) { int offset = encvaluesum / (num_steps * 2); motor->encoder.encoder_offset = offset; - motor->encoder.calibrated = true; return true; } @@ -870,7 +869,7 @@ bool motor_calibration(Motor_t* motor) { (float)(motor->encoder.motor_dir) * motor->encoder.idx_search_speed, enc_calibration_voltage)) return false; - if (!motor->encoder.calibrated) + if (!motor->encoder.manually_calibrated) if (!calib_enc_offset(motor, enc_calibration_voltage)) return false; } diff --git a/Firmware/MotorControl/low_level.h b/Firmware/MotorControl/low_level.h index 21e73b83..e92774e4 100644 --- a/Firmware/MotorControl/low_level.h +++ b/Firmware/MotorControl/low_level.h @@ -115,7 +115,7 @@ typedef struct { TIM_HandleTypeDef* encoder_timer; bool use_index; bool index_found; - bool calibrated; + bool manually_calibrated; float idx_search_speed; int32_t encoder_cpr; int32_t encoder_offset; diff --git a/Firmware/Tupfile.lua b/Firmware/Tupfile.lua index dec05271..a4e8dd03 100644 --- a/Firmware/Tupfile.lua +++ b/Firmware/Tupfile.lua @@ -16,10 +16,8 @@ FLAGS += '-mfpu=fpv4-sp-d16' FLAGS += '-mfloat-abi=hard' FLAGS += { '-Wall', '-fdata-sections', '-ffunction-sections'} -if tup.getconfig('DEBUG') == 'y' then - --C_FLAGS += '-g -gdwarf-2' - FLAGS += '-g -gdwarf-2' -end +FLAGS += '-g -gdwarf-2' + -- linker flags LDFLAGS += '-T'..boarddir..'/STM32F405RGTx_FLASH.ld' From 2aa9ae99a253a9711f08ffe8cd59403ddc5d1bdd Mon Sep 17 00:00:00 2001 From: Oskar Weigl Date: Fri, 2 Mar 2018 23:07:19 -0800 Subject: [PATCH 50/53] Update CHANGELOG.md --- Firmware/CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/Firmware/CHANGELOG.md b/Firmware/CHANGELOG.md index 7c9738c1..9d3e620e 100644 --- a/Firmware/CHANGELOG.md +++ b/Firmware/CHANGELOG.md @@ -2,6 +2,7 @@ Please add a note of your changes below this heading if you make a PR ### Added +* **Storing of configuration parameters to Non Volatile Memory** * Reporting error if your encoder CPR is incorrect * Reporting of DRV status/control registers and fault codes * DRV status read script From 9e776027fada16f450b9e403683b2fa01bc1492a Mon Sep 17 00:00:00 2001 From: Oskar Weigl Date: Sun, 4 Mar 2018 00:57:09 -0800 Subject: [PATCH 51/53] Update legacy-protocol.md --- Firmware/legacy-protocol.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Firmware/legacy-protocol.md b/Firmware/legacy-protocol.md index 5693a039..2898432f 100644 --- a/Firmware/legacy-protocol.md +++ b/Firmware/legacy-protocol.md @@ -52,7 +52,7 @@ s type index value ** `0` is float ** `1` is int ** `2` is bool -* `index` is the index in the corresponding [exposed variable table](MotorControl/commands.c). +* `index` is the index in the corresponding [exposed variable table](MotorControl/legacy_commands.c). For example * `g 0 12` will return the phase resistance of M0 From 5985447374a789d9b99327a5e05bd500c87f5121 Mon Sep 17 00:00:00 2001 From: Oskar Weigl Date: Sun, 4 Mar 2018 00:59:56 -0800 Subject: [PATCH 52/53] Update README.md --- Firmware/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Firmware/README.md b/Firmware/README.md index 8c540021..865cd06f 100644 --- a/Firmware/README.md +++ b/Firmware/README.md @@ -167,7 +167,7 @@ If the flashing worked, you can start sending commands. If you want to do that n ## Communicating over USB or UART Warning: If testing USB or UART communication for the first time it is recommend that your motors are free to spin continuously and are not connected to a drivetrain with limited travel. ### From Linux/Windows/macOS -There are two example python scripts to help you get started with controlling the ODrive using python. One will drop you into an interactive shell to query settings, parameters, and variables, and let you send setpoints manually ([tools/explore_odrive.py](tools/explore_odrive.py)). The other is a demo application to show you how to control the ODrive programmatically ([tools/demo.py](tools/demo.py)). Below follows a step-by-step guide on how to run these. +There are two example python scripts to help you get started with controlling the ODrive using python. One will drop you into an interactive shell to query settings, parameters, and variables, and let you send setpoints manually ([tools/explore_odrive.py](../tools/explore_odrive.py)). The other is a demo application to show you how to control the ODrive programmatically ([tools/demo.py](../tools/demo.py)). Below follows a step-by-step guide on how to run these. * __Windows__: It is recommended to use a Unix style command prompt, such as Git Bash that comes with [Git for windows](https://git-scm.com/download/win). From f9a846537a149052c0895700d4b4567de70d58ff Mon Sep 17 00:00:00 2001 From: Oskar Weigl Date: Sun, 4 Mar 2018 01:57:29 -0800 Subject: [PATCH 53/53] add include-fixed to VSCode include --- Firmware/.vscode/c_cpp_properties.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Firmware/.vscode/c_cpp_properties.json b/Firmware/.vscode/c_cpp_properties.json index 150b7c96..b337bc20 100644 --- a/Firmware/.vscode/c_cpp_properties.json +++ b/Firmware/.vscode/c_cpp_properties.json @@ -20,6 +20,7 @@ "c:/program files (x86)/gnu tools arm embedded/6 2017-q1-update/arm-none-eabi/include/c++/6.3.1/arm-none-eabi", "c:/program files (x86)/gnu tools arm embedded/6 2017-q1-update/arm-none-eabi/include/c++/6.3.1/backward", "c:/program files (x86)/gnu tools arm embedded/6 2017-q1-update/lib/gcc/arm-none-eabi/6.3.1/include", + "c:/program files (x86)/gnu tools arm embedded/6 2017-q1-update/lib/gcc/arm-none-eabi/6.3.1/include-fixed", "c:/program files (x86)/gnu tools arm embedded/6 2017-q1-update/arm-none-eabi/include" ], "defines": [ @@ -76,7 +77,7 @@ } }, { - "name": "MacOS", + "name": "Mac", "includePath": [ "${workspaceRoot}", "${workspaceRoot}/Middlewares/Third_Party/FreeRTOS/Source/portable/GCC/ARM_CM4F",