Merge branch 'vedderb:master' into master

This commit is contained in:
ElwinBoots 2024-07-20 21:23:09 +02:00 committed by GitHub
commit f891bbcc12
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
9 changed files with 104 additions and 12 deletions

View File

@ -55,6 +55,7 @@
* Fixed some braking glitches. * Fixed some braking glitches.
* Configurable HFI error truncation to reject noise. * Configurable HFI error truncation to reject noise.
* Removed GPDrive. * Removed GPDrive.
* FOC: Option to short phases on 0 duty.
### 6.02 ### 6.02
#### 2023-03-12 #### 2023-03-12

View File

@ -24,7 +24,7 @@
#define FW_VERSION_MAJOR 6 #define FW_VERSION_MAJOR 6
#define FW_VERSION_MINOR 05 #define FW_VERSION_MINOR 05
// Set to 0 for building a release and iterate during beta test builds // Set to 0 for building a release and iterate during beta test builds
#define FW_TEST_VERSION_NUMBER 30 #define FW_TEST_VERSION_NUMBER 31
#include "datatypes.h" #include "datatypes.h"

View File

@ -141,6 +141,7 @@ int32_t confgenerator_serialize_mcconf(uint8_t *buffer, const mc_configuration *
buffer_append_float16(buffer, conf->foc_fw_ramp_time, 1000, &ind); buffer_append_float16(buffer, conf->foc_fw_ramp_time, 1000, &ind);
buffer_append_float16(buffer, conf->foc_fw_q_current_factor, 10000, &ind); buffer_append_float16(buffer, conf->foc_fw_q_current_factor, 10000, &ind);
buffer[ind++] = conf->foc_speed_soure; buffer[ind++] = conf->foc_speed_soure;
buffer[ind++] = conf->foc_short_ls_on_zero_duty;
buffer[ind++] = conf->sp_pid_loop_rate; buffer[ind++] = conf->sp_pid_loop_rate;
buffer_append_float32_auto(buffer, conf->s_pid_kp, &ind); buffer_append_float32_auto(buffer, conf->s_pid_kp, &ind);
buffer_append_float32_auto(buffer, conf->s_pid_ki, &ind); buffer_append_float32_auto(buffer, conf->s_pid_ki, &ind);
@ -476,6 +477,7 @@ bool confgenerator_deserialize_mcconf(const uint8_t *buffer, mc_configuration *c
conf->foc_fw_ramp_time = buffer_get_float16(buffer, 1000, &ind); conf->foc_fw_ramp_time = buffer_get_float16(buffer, 1000, &ind);
conf->foc_fw_q_current_factor = buffer_get_float16(buffer, 10000, &ind); conf->foc_fw_q_current_factor = buffer_get_float16(buffer, 10000, &ind);
conf->foc_speed_soure = buffer[ind++]; conf->foc_speed_soure = buffer[ind++];
conf->foc_short_ls_on_zero_duty = buffer[ind++];
conf->sp_pid_loop_rate = buffer[ind++]; conf->sp_pid_loop_rate = buffer[ind++];
conf->s_pid_kp = buffer_get_float32_auto(buffer, &ind); conf->s_pid_kp = buffer_get_float32_auto(buffer, &ind);
conf->s_pid_ki = buffer_get_float32_auto(buffer, &ind); conf->s_pid_ki = buffer_get_float32_auto(buffer, &ind);
@ -807,6 +809,7 @@ void confgenerator_set_defaults_mcconf(mc_configuration *conf) {
conf->foc_fw_ramp_time = MCCONF_FOC_FW_RAMP_TIME; conf->foc_fw_ramp_time = MCCONF_FOC_FW_RAMP_TIME;
conf->foc_fw_q_current_factor = MCCONF_FOC_FW_Q_CURRENT_FACTOR; conf->foc_fw_q_current_factor = MCCONF_FOC_FW_Q_CURRENT_FACTOR;
conf->foc_speed_soure = MCCONF_FOC_SPEED_SOURCE; conf->foc_speed_soure = MCCONF_FOC_SPEED_SOURCE;
conf->foc_short_ls_on_zero_duty = MCCONF_FOC_SHORT_LS_ON_ZERO_DUTY;
conf->sp_pid_loop_rate = MCCONF_SP_PID_LOOP_RATE; conf->sp_pid_loop_rate = MCCONF_SP_PID_LOOP_RATE;
conf->s_pid_kp = MCCONF_S_PID_KP; conf->s_pid_kp = MCCONF_S_PID_KP;
conf->s_pid_ki = MCCONF_S_PID_KI; conf->s_pid_ki = MCCONF_S_PID_KI;

View File

@ -8,7 +8,7 @@
#include <stdbool.h> #include <stdbool.h>
// Constants // Constants
#define MCCONF_SIGNATURE 4193379058 #define MCCONF_SIGNATURE 2490415037
#define APPCONF_SIGNATURE 2099347128 #define APPCONF_SIGNATURE 2099347128
// Functions // Functions

View File

@ -487,6 +487,7 @@ typedef struct {
float foc_fw_ramp_time; float foc_fw_ramp_time;
float foc_fw_q_current_factor; float foc_fw_q_current_factor;
FOC_SPEED_SRC foc_speed_soure; FOC_SPEED_SRC foc_speed_soure;
bool foc_short_ls_on_zero_duty;
PID_RATE sp_pid_loop_rate; PID_RATE sp_pid_loop_rate;

View File

@ -127,6 +127,12 @@ typedef struct {
float sample_voltage; float sample_voltage;
} mc_audio_state; } mc_audio_state;
typedef enum {
FOC_PWM_DISABLED = 0,
FOC_PWM_ENABLED,
FOC_PWM_FULL_BRAKE
} foc_pwm_mode;
typedef struct { typedef struct {
mc_configuration *m_conf; mc_configuration *m_conf;
mc_state m_state; mc_state m_state;
@ -143,7 +149,7 @@ typedef struct {
float m_current_off_delay; float m_current_off_delay;
float m_openloop_speed; float m_openloop_speed;
float m_openloop_phase; float m_openloop_phase;
bool m_output_on; foc_pwm_mode m_pwm_mode;
float m_pos_pid_set; float m_pos_pid_set;
float m_speed_pid_set_rpm; float m_speed_pid_set_rpm;
float m_speed_command_rpm; float m_speed_command_rpm;

View File

@ -2176,7 +2176,7 @@ void mc_interface_mc_timer_isr(bool is_second_motor) {
m_vzero_samples[m_sample_now] = zero; m_vzero_samples[m_sample_now] = zero;
m_curr_fir_samples[m_sample_now] = (int16_t)(current * (8.0 / FAC_CURRENT)); m_curr_fir_samples[m_sample_now] = (int16_t)(current * (8.0 / FAC_CURRENT));
m_f_sw_samples[m_sample_now] = (int16_t)(0.1 / t_samp); m_f_sw_samples[m_sample_now] = (int16_t)(0.1 / t_samp / m_sample_int);
m_status_samples[m_sample_now] = mcpwm_get_comm_step() | (mcpwm_read_hall_phase() << 3); m_status_samples[m_sample_now] = mcpwm_get_comm_step() | (mcpwm_read_hall_phase() << 3);
m_sample_now++; m_sample_now++;

View File

@ -493,6 +493,9 @@
#ifndef MCCONF_FOC_SPEED_SOURCE #ifndef MCCONF_FOC_SPEED_SOURCE
#define MCCONF_FOC_SPEED_SOURCE FOC_SPEED_SRC_CORRECTED // Position source for speed trackers #define MCCONF_FOC_SPEED_SOURCE FOC_SPEED_SRC_CORRECTED // Position source for speed trackers
#endif #endif
#ifndef MCCONF_FOC_SHORT_LS_ON_ZERO_DUTY
#define MCCONF_FOC_SHORT_LS_ON_ZERO_DUTY false // Short low-side phases on zero duty cycle
#endif
// GPD // GPD
#ifndef MCCONF_GPD_BUFFER_NOTIFY_LEFT #ifndef MCCONF_GPD_BUFFER_NOTIFY_LEFT

View File

@ -57,6 +57,7 @@ static void control_current(motor_all_state_t *motor, float dt);
static void update_valpha_vbeta(motor_all_state_t *motor, float mod_alpha, float mod_beta); static void update_valpha_vbeta(motor_all_state_t *motor, float mod_alpha, float mod_beta);
static void stop_pwm_hw(motor_all_state_t *motor); static void stop_pwm_hw(motor_all_state_t *motor);
static void start_pwm_hw(motor_all_state_t *motor); static void start_pwm_hw(motor_all_state_t *motor);
static void full_brake_hw(motor_all_state_t *motor);
static void terminal_tmp(int argc, const char **argv); static void terminal_tmp(int argc, const char **argv);
static void terminal_plot_hfi(int argc, const char **argv); static void terminal_plot_hfi(int argc, const char **argv);
static void timer_update(motor_all_state_t *motor, float dt); static void timer_update(motor_all_state_t *motor, float dt);
@ -4693,13 +4694,22 @@ static void control_current(motor_all_state_t *motor, float dt) {
#endif #endif
} }
// do not allow to turn on PWM outputs if virtual motor is used
if(virtual_motor_is_connected() == false) { if(virtual_motor_is_connected() == false) {
if (!motor->m_output_on) { // If all duty cycles are equal the phases should be shorted. Instead of
// modulating the short we keep all low-side FETs on - that will draw less
// power and not suffer from dead-time distortion. It also gives more
// braking torque at low speed.
if (conf_now->foc_short_ls_on_zero_duty && duty1 == duty2 && duty2 == duty3) {
if (motor->m_pwm_mode != FOC_PWM_FULL_BRAKE) {
full_brake_hw(motor);
}
} else {
if (motor->m_pwm_mode != FOC_PWM_ENABLED) {
start_pwm_hw(motor); start_pwm_hw(motor);
} }
} }
} }
}
static void update_valpha_vbeta(motor_all_state_t *motor, float mod_alpha, float mod_beta) { static void update_valpha_vbeta(motor_all_state_t *motor, float mod_alpha, float mod_beta) {
motor_state_t *state_m = &motor->m_motor_state; motor_state_t *state_m = &motor->m_motor_state;
@ -4895,8 +4905,6 @@ static void stop_pwm_hw(motor_all_state_t *motor) {
#ifdef HW_HAS_DRV8313 #ifdef HW_HAS_DRV8313
DISABLE_BR(); DISABLE_BR();
#endif #endif
motor->m_output_on = false;
PHASE_FILTER_OFF(); PHASE_FILTER_OFF();
} else { } else {
TIM_SelectOCxM(TIM8, TIM_Channel_1, TIM_ForcedAction_InActive); TIM_SelectOCxM(TIM8, TIM_Channel_1, TIM_ForcedAction_InActive);
@ -4917,9 +4925,10 @@ static void stop_pwm_hw(motor_all_state_t *motor) {
DISABLE_BR_2(); DISABLE_BR_2();
#endif #endif
motor->m_output_on = false;
PHASE_FILTER_OFF_M2(); PHASE_FILTER_OFF_M2();
} }
motor->m_pwm_mode = FOC_PWM_DISABLED;
} }
static void start_pwm_hw(motor_all_state_t *motor) { static void start_pwm_hw(motor_all_state_t *motor) {
@ -4950,6 +4959,10 @@ static void start_pwm_hw(motor_all_state_t *motor) {
TIM_CCxNCmd(TIM8, TIM_Channel_3, TIM_CCxN_Enable); TIM_CCxNCmd(TIM8, TIM_Channel_3, TIM_CCxN_Enable);
PHASE_FILTER_ON_M2(); PHASE_FILTER_ON_M2();
#ifdef HW_HAS_DRV8313_2
ENABLE_BR_2();
#endif
#endif #endif
// Generate COM event in ADC interrupt to get better synchronization // Generate COM event in ADC interrupt to get better synchronization
@ -4958,7 +4971,6 @@ static void start_pwm_hw(motor_all_state_t *motor) {
#ifdef HW_HAS_DRV8313 #ifdef HW_HAS_DRV8313
ENABLE_BR(); ENABLE_BR();
#endif #endif
motor->m_output_on = true;
PHASE_FILTER_ON(); PHASE_FILTER_ON();
} else { } else {
TIM_SelectOCxM(TIM8, TIM_Channel_1, TIM_OCMode_PWM1); TIM_SelectOCxM(TIM8, TIM_Channel_1, TIM_OCMode_PWM1);
@ -4976,9 +4988,75 @@ static void start_pwm_hw(motor_all_state_t *motor) {
#ifdef HW_HAS_DRV8313_2 #ifdef HW_HAS_DRV8313_2
ENABLE_BR_2(); ENABLE_BR_2();
#endif #endif
motor->m_output_on = true;
PHASE_FILTER_ON_M2(); PHASE_FILTER_ON_M2();
} }
motor->m_pwm_mode = FOC_PWM_ENABLED;
}
static void full_brake_hw(motor_all_state_t *motor) {
if (motor == &m_motor_1) {
TIM_SelectOCxM(TIM1, TIM_Channel_1, TIM_ForcedAction_InActive);
TIM_CCxCmd(TIM1, TIM_Channel_1, TIM_CCx_Enable);
TIM_CCxNCmd(TIM1, TIM_Channel_1, TIM_CCxN_Enable);
TIM_SelectOCxM(TIM1, TIM_Channel_2, TIM_ForcedAction_InActive);
TIM_CCxCmd(TIM1, TIM_Channel_2, TIM_CCx_Enable);
TIM_CCxNCmd(TIM1, TIM_Channel_2, TIM_CCxN_Enable);
TIM_SelectOCxM(TIM1, TIM_Channel_3, TIM_ForcedAction_InActive);
TIM_CCxCmd(TIM1, TIM_Channel_3, TIM_CCx_Enable);
TIM_CCxNCmd(TIM1, TIM_Channel_3, TIM_CCxN_Enable);
TIM_GenerateEvent(TIM1, TIM_EventSource_COM);
PHASE_FILTER_ON();
#ifdef HW_HAS_DRV8313
ENABLE_BR();
#endif
#ifdef HW_HAS_DUAL_PARALLEL
TIM_SelectOCxM(TIM8, TIM_Channel_1, TIM_ForcedAction_InActive);
TIM_CCxCmd(TIM8, TIM_Channel_1, TIM_CCx_Enable);
TIM_CCxNCmd(TIM8, TIM_Channel_1, TIM_CCxN_Enable);
TIM_SelectOCxM(TIM8, TIM_Channel_2, TIM_ForcedAction_InActive);
TIM_CCxCmd(TIM8, TIM_Channel_2, TIM_CCx_Enable);
TIM_CCxNCmd(TIM8, TIM_Channel_2, TIM_CCxN_Enable);
TIM_SelectOCxM(TIM8, TIM_Channel_3, TIM_ForcedAction_InActive);
TIM_CCxCmd(TIM8, TIM_Channel_3, TIM_CCx_Enable);
TIM_CCxNCmd(TIM8, TIM_Channel_3, TIM_CCxN_Enable);
TIM_GenerateEvent(TIM8, TIM_EventSource_COM);
PHASE_FILTER_ON_M2();
#ifdef HW_HAS_DRV8313_2
ENABLE_BR_2();
#endif
#endif
} else {
TIM_SelectOCxM(TIM8, TIM_Channel_1, TIM_ForcedAction_InActive);
TIM_CCxCmd(TIM8, TIM_Channel_1, TIM_CCx_Enable);
TIM_CCxNCmd(TIM8, TIM_Channel_1, TIM_CCxN_Enable);
TIM_SelectOCxM(TIM8, TIM_Channel_2, TIM_ForcedAction_InActive);
TIM_CCxCmd(TIM8, TIM_Channel_2, TIM_CCx_Enable);
TIM_CCxNCmd(TIM8, TIM_Channel_2, TIM_CCxN_Enable);
TIM_SelectOCxM(TIM8, TIM_Channel_3, TIM_ForcedAction_InActive);
TIM_CCxCmd(TIM8, TIM_Channel_3, TIM_CCx_Enable);
TIM_CCxNCmd(TIM8, TIM_Channel_3, TIM_CCxN_Enable);
TIM_GenerateEvent(TIM8, TIM_EventSource_COM);
PHASE_FILTER_ON_M2();
#ifdef HW_HAS_DRV8313_2
ENABLE_BR_2();
#endif
}
motor->m_pwm_mode = FOC_PWM_FULL_BRAKE;
} }
static void terminal_plot_hfi(int argc, const char **argv) { static void terminal_plot_hfi(int argc, const char **argv) {