Autogenerated config parsing with signatures, fixed previous PRs

This commit is contained in:
Benjamin Vedder 2019-03-01 21:36:58 +01:00
parent a8b3f9d3e1
commit 01e72eb555
43 changed files with 773 additions and 775 deletions

View File

@ -1,3 +1,8 @@
=== FW 3.50 ===
* AS5047 parity check and fault code on error rates > 1%.
* Signature on mc and app configuration.
* FOC loop frequency truncation on all hardwares.
=== FW 3.49 ===
* New watchdog implementation.
* HW updates.

View File

@ -149,6 +149,7 @@ CSRC = $(STARTUPSRC) \
mc_interface.c \
mcpwm_foc.c \
gpdrive.c \
confgenerator.c \
$(HWSRC) \
$(APPSRC) \
$(NRFSRC) \

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -39,6 +39,7 @@
#include "encoder.h"
#include "nrf_driver.h"
#include "gpdrive.h"
#include "confgenerator.h"
#include <math.h>
#include <string.h>
@ -349,146 +350,28 @@ void commands_process_packet(unsigned char *data, unsigned int len) {
case COMM_SET_MCCONF:
mcconf = *mc_interface_get_configuration();
ind = 0;
mcconf.pwm_mode = data[ind++];
mcconf.comm_mode = data[ind++];
mcconf.motor_type = data[ind++];
mcconf.sensor_mode = data[ind++];
if (confgenerator_deserialize_mcconf(data, &mcconf)) {
utils_truncate_number(&mcconf.l_current_max_scale , 0.0, 1.0);
utils_truncate_number(&mcconf.l_current_min_scale , 0.0, 1.0);
mcconf.l_current_max = buffer_get_float32_auto(data, &ind);
mcconf.l_current_min = buffer_get_float32_auto(data, &ind);
mcconf.l_in_current_max = buffer_get_float32_auto(data, &ind);
mcconf.l_in_current_min = buffer_get_float32_auto(data, &ind);
mcconf.l_abs_current_max = buffer_get_float32_auto(data, &ind);
mcconf.l_min_erpm = buffer_get_float32_auto(data, &ind);
mcconf.l_max_erpm = buffer_get_float32_auto(data, &ind);
mcconf.l_erpm_start = buffer_get_float32_auto(data, &ind);
mcconf.l_max_erpm_fbrake = buffer_get_float32_auto(data, &ind);
mcconf.l_max_erpm_fbrake_cc = buffer_get_float32_auto(data, &ind);
mcconf.l_min_vin = buffer_get_float32_auto(data, &ind);
mcconf.l_max_vin = buffer_get_float32_auto(data, &ind);
mcconf.l_battery_cut_start = buffer_get_float32_auto(data, &ind);
mcconf.l_battery_cut_end = buffer_get_float32_auto(data, &ind);
mcconf.l_slow_abs_current = data[ind++];
mcconf.l_temp_fet_start = buffer_get_float32_auto(data, &ind);
mcconf.l_temp_fet_end = buffer_get_float32_auto(data, &ind);
mcconf.l_temp_motor_start = buffer_get_float32_auto(data, &ind);
mcconf.l_temp_motor_end = buffer_get_float32_auto(data, &ind);
mcconf.l_temp_accel_dec = buffer_get_float32_auto(data, &ind);
mcconf.l_min_duty = buffer_get_float32_auto(data, &ind);
mcconf.l_max_duty = buffer_get_float32_auto(data, &ind);
mcconf.l_watt_max = buffer_get_float32_auto(data, &ind);
mcconf.l_watt_min = buffer_get_float32_auto(data, &ind);
mcconf.l_current_max_scale = buffer_get_float32_auto(data, &ind);
mcconf.l_current_min_scale = buffer_get_float32_auto(data, &ind);
mcconf.lo_current_max = mcconf.l_current_max * mcconf.l_current_max_scale;
mcconf.lo_current_min = mcconf.l_current_min * mcconf.l_current_min_scale;
mcconf.lo_in_current_max = mcconf.l_in_current_max;
mcconf.lo_in_current_min = mcconf.l_in_current_min;
mcconf.lo_current_motor_max_now = mcconf.lo_current_max;
mcconf.lo_current_motor_min_now = mcconf.lo_current_min;
utils_truncate_number(&mcconf.l_current_max_scale , 0.0, 1.0);
utils_truncate_number(&mcconf.l_current_min_scale , 0.0, 1.0);
commands_apply_mcconf_hw_limits(&mcconf);
conf_general_store_mc_configuration(&mcconf);
mc_interface_set_configuration(&mcconf);
chThdSleepMilliseconds(200);
mcconf.lo_current_max = mcconf.l_current_max * mcconf.l_current_max_scale;
mcconf.lo_current_min = mcconf.l_current_min * mcconf.l_current_min_scale;
mcconf.lo_in_current_max = mcconf.l_in_current_max;
mcconf.lo_in_current_min = mcconf.l_in_current_min;
mcconf.lo_current_motor_max_now = mcconf.lo_current_max;
mcconf.lo_current_motor_min_now = mcconf.lo_current_min;
mcconf.sl_min_erpm = buffer_get_float32_auto(data, &ind);
mcconf.sl_min_erpm_cycle_int_limit = buffer_get_float32_auto(data, &ind);
mcconf.sl_max_fullbreak_current_dir_change = buffer_get_float32_auto(data, &ind);
mcconf.sl_cycle_int_limit = buffer_get_float32_auto(data, &ind);
mcconf.sl_phase_advance_at_br = buffer_get_float32_auto(data, &ind);
mcconf.sl_cycle_int_rpm_br = buffer_get_float32_auto(data, &ind);
mcconf.sl_bemf_coupling_k = buffer_get_float32_auto(data, &ind);
memcpy(mcconf.hall_table, data + ind, 8);
ind += 8;
mcconf.hall_sl_erpm = buffer_get_float32_auto(data, &ind);
mcconf.foc_current_kp = buffer_get_float32_auto(data, &ind);
mcconf.foc_current_ki = buffer_get_float32_auto(data, &ind);
mcconf.foc_f_sw = buffer_get_float32_auto(data, &ind);
mcconf.foc_dt_us = buffer_get_float32_auto(data, &ind);
mcconf.foc_encoder_inverted = data[ind++];
mcconf.foc_encoder_offset = buffer_get_float32_auto(data, &ind);
mcconf.foc_encoder_ratio = buffer_get_float32_auto(data, &ind);
mcconf.foc_sensor_mode = data[ind++];
mcconf.foc_pll_kp = buffer_get_float32_auto(data, &ind);
mcconf.foc_pll_ki = buffer_get_float32_auto(data, &ind);
mcconf.foc_motor_l = buffer_get_float32_auto(data, &ind);
mcconf.foc_motor_r = buffer_get_float32_auto(data, &ind);
mcconf.foc_motor_flux_linkage = buffer_get_float32_auto(data, &ind);
mcconf.foc_observer_gain = buffer_get_float32_auto(data, &ind);
mcconf.foc_observer_gain_slow = buffer_get_float32_auto(data, &ind);
mcconf.foc_duty_dowmramp_kp = buffer_get_float32_auto(data, &ind);
mcconf.foc_duty_dowmramp_ki = buffer_get_float32_auto(data, &ind);
mcconf.foc_openloop_rpm = buffer_get_float32_auto(data, &ind);
mcconf.foc_sl_openloop_hyst = buffer_get_float32_auto(data, &ind);
mcconf.foc_sl_openloop_time = buffer_get_float32_auto(data, &ind);
mcconf.foc_sl_d_current_duty = buffer_get_float32_auto(data, &ind);
mcconf.foc_sl_d_current_factor = buffer_get_float32_auto(data, &ind);
memcpy(mcconf.foc_hall_table, data + ind, 8);
ind += 8;
mcconf.foc_sl_erpm = buffer_get_float32_auto(data, &ind);
mcconf.foc_sample_v0_v7 = data[ind++];
mcconf.foc_sample_high_current = data[ind++];
mcconf.foc_sat_comp = buffer_get_float32_auto(data, &ind);
mcconf.foc_temp_comp = data[ind++];
mcconf.foc_temp_comp_base_temp = buffer_get_float32_auto(data, &ind);
mcconf.foc_current_filter_const = buffer_get_float32_auto(data, &ind);
mcconf.gpd_buffer_notify_left = buffer_get_int16(data, &ind);
mcconf.gpd_buffer_interpol = buffer_get_int16(data, &ind);
mcconf.gpd_current_filter_const = buffer_get_float32_auto(data, &ind);
mcconf.gpd_current_kp = buffer_get_float32_auto(data, &ind);
mcconf.gpd_current_ki = buffer_get_float32_auto(data, &ind);
mcconf.s_pid_kp = buffer_get_float32_auto(data, &ind);
mcconf.s_pid_ki = buffer_get_float32_auto(data, &ind);
mcconf.s_pid_kd = buffer_get_float32_auto(data, &ind);
mcconf.s_pid_kd_filter = buffer_get_float32_auto(data, &ind);
mcconf.s_pid_min_erpm = buffer_get_float32_auto(data, &ind);
mcconf.s_pid_allow_braking = data[ind++];
mcconf.p_pid_kp = buffer_get_float32_auto(data, &ind);
mcconf.p_pid_ki = buffer_get_float32_auto(data, &ind);
mcconf.p_pid_kd = buffer_get_float32_auto(data, &ind);
mcconf.p_pid_kd_filter = buffer_get_float32_auto(data, &ind);
mcconf.p_pid_ang_div = buffer_get_float32_auto(data, &ind);
mcconf.cc_startup_boost_duty = buffer_get_float32_auto(data, &ind);
mcconf.cc_min_current = buffer_get_float32_auto(data, &ind);
mcconf.cc_gain = buffer_get_float32_auto(data, &ind);
mcconf.cc_ramp_step_max = buffer_get_float32_auto(data, &ind);
mcconf.m_fault_stop_time_ms = buffer_get_int32(data, &ind);
mcconf.m_duty_ramp_step = buffer_get_float32_auto(data, &ind);
mcconf.m_current_backoff_gain = buffer_get_float32_auto(data, &ind);
mcconf.m_encoder_counts = buffer_get_uint32(data, &ind);
mcconf.m_sensor_port_mode = data[ind++];
mcconf.m_invert_direction = data[ind++];
mcconf.m_drv8301_oc_mode = data[ind++];
mcconf.m_drv8301_oc_adj = data[ind++];
mcconf.m_bldc_f_sw_min = buffer_get_float32_auto(data, &ind);
mcconf.m_bldc_f_sw_max = buffer_get_float32_auto(data, &ind);
mcconf.m_dc_f_sw = buffer_get_float32_auto(data, &ind);
mcconf.m_ntc_motor_beta = buffer_get_float32_auto(data, &ind);
mcconf.m_out_aux_mode = data[ind++];
mcconf.si_motor_poles = data[ind++];
mcconf.si_gear_ratio = buffer_get_float32_auto(data, &ind);
mcconf.si_wheel_diameter = buffer_get_float32_auto(data, &ind);
mcconf.si_battery_type = data[ind++];
mcconf.si_battery_cells = data[ind++];
mcconf.si_battery_ah = buffer_get_float32_auto(data, &ind);
commands_apply_mcconf_hw_limits(&mcconf);
conf_general_store_mc_configuration(&mcconf);
mc_interface_set_configuration(&mcconf);
chThdSleepMilliseconds(200);
ind = 0;
send_buffer[ind++] = packet_id;
commands_send_packet(send_buffer, ind);
ind = 0;
send_buffer[ind++] = packet_id;
commands_send_packet(send_buffer, ind);
} else {
commands_printf("Warning: Could not set mcconf due to wrong signature");
}
break;
case COMM_GET_MCCONF:
@ -496,7 +379,7 @@ void commands_process_packet(unsigned char *data, unsigned int len) {
if (packet_id == COMM_GET_MCCONF) {
mcconf = *mc_interface_get_configuration();
} else {
conf_general_get_default_mc_configuration(&mcconf);
confgenerator_set_defaults_mcconf(&mcconf);
}
commands_send_mcconf(packet_id, &mcconf);
@ -505,92 +388,18 @@ void commands_process_packet(unsigned char *data, unsigned int len) {
case COMM_SET_APPCONF:
appconf = *app_get_configuration();
ind = 0;
appconf.controller_id = data[ind++];
appconf.timeout_msec = buffer_get_uint32(data, &ind);
appconf.timeout_brake_current = buffer_get_float32_auto(data, &ind);
appconf.send_can_status = data[ind++];
appconf.send_can_status_rate_hz = buffer_get_uint16(data, &ind);
appconf.can_baud_rate = data[ind++];
appconf.pairing_done = data[ind++];
if (confgenerator_deserialize_appconf(data, &appconf)) {
conf_general_store_app_configuration(&appconf);
app_set_configuration(&appconf);
timeout_configure(appconf.timeout_msec, appconf.timeout_brake_current);
chThdSleepMilliseconds(200);
appconf.uavcan_enable = data[ind++];
appconf.uavcan_esc_index = data[ind++];
appconf.app_to_use = data[ind++];
appconf.app_ppm_conf.ctrl_type = data[ind++];
appconf.app_ppm_conf.pid_max_erpm = buffer_get_float32_auto(data, &ind);
appconf.app_ppm_conf.hyst = buffer_get_float32_auto(data, &ind);
appconf.app_ppm_conf.pulse_start = buffer_get_float32_auto(data, &ind);
appconf.app_ppm_conf.pulse_end = buffer_get_float32_auto(data, &ind);
appconf.app_ppm_conf.pulse_center = buffer_get_float32_auto(data, &ind);
appconf.app_ppm_conf.median_filter = data[ind++];
appconf.app_ppm_conf.safe_start = data[ind++];
appconf.app_ppm_conf.throttle_exp = buffer_get_float32_auto(data, &ind);
appconf.app_ppm_conf.throttle_exp_brake = buffer_get_float32_auto(data, &ind);
appconf.app_ppm_conf.throttle_exp_mode = data[ind++];
appconf.app_ppm_conf.ramp_time_pos = buffer_get_float32_auto(data, &ind);
appconf.app_ppm_conf.ramp_time_neg = buffer_get_float32_auto(data, &ind);
appconf.app_ppm_conf.multi_esc = data[ind++];
appconf.app_ppm_conf.tc = data[ind++];
appconf.app_ppm_conf.tc_max_diff = buffer_get_float32_auto(data, &ind);
appconf.app_adc_conf.ctrl_type = data[ind++];
appconf.app_adc_conf.hyst = buffer_get_float32_auto(data, &ind);
appconf.app_adc_conf.voltage_start = buffer_get_float32_auto(data, &ind);
appconf.app_adc_conf.voltage_end = buffer_get_float32_auto(data, &ind);
appconf.app_adc_conf.voltage_center = buffer_get_float32_auto(data, &ind);
appconf.app_adc_conf.voltage2_start = buffer_get_float32_auto(data, &ind);
appconf.app_adc_conf.voltage2_end = buffer_get_float32_auto(data, &ind);
appconf.app_adc_conf.use_filter = data[ind++];
appconf.app_adc_conf.safe_start = data[ind++];
appconf.app_adc_conf.cc_button_inverted = data[ind++];
appconf.app_adc_conf.rev_button_inverted = data[ind++];
appconf.app_adc_conf.voltage_inverted = data[ind++];
appconf.app_adc_conf.voltage2_inverted = data[ind++];
appconf.app_adc_conf.throttle_exp = buffer_get_float32_auto(data, &ind);
appconf.app_adc_conf.throttle_exp_brake = buffer_get_float32_auto(data, &ind);
appconf.app_adc_conf.throttle_exp_mode = data[ind++];
appconf.app_adc_conf.ramp_time_pos = buffer_get_float32_auto(data, &ind);
appconf.app_adc_conf.ramp_time_neg = buffer_get_float32_auto(data, &ind);
appconf.app_adc_conf.multi_esc = data[ind++];
appconf.app_adc_conf.tc = data[ind++];
appconf.app_adc_conf.tc_max_diff = buffer_get_float32_auto(data, &ind);
appconf.app_adc_conf.update_rate_hz = buffer_get_uint16(data, &ind);
appconf.app_uart_baudrate = buffer_get_uint32(data, &ind);
appconf.app_chuk_conf.ctrl_type = data[ind++];
appconf.app_chuk_conf.hyst = buffer_get_float32_auto(data, &ind);
appconf.app_chuk_conf.ramp_time_pos = buffer_get_float32_auto(data, &ind);
appconf.app_chuk_conf.ramp_time_neg = buffer_get_float32_auto(data, &ind);
appconf.app_chuk_conf.stick_erpm_per_s_in_cc = buffer_get_float32_auto(data, &ind);
appconf.app_chuk_conf.throttle_exp = buffer_get_float32_auto(data, &ind);
appconf.app_chuk_conf.throttle_exp_brake = buffer_get_float32_auto(data, &ind);
appconf.app_chuk_conf.throttle_exp_mode = data[ind++];
appconf.app_chuk_conf.multi_esc = data[ind++];
appconf.app_chuk_conf.tc = data[ind++];
appconf.app_chuk_conf.tc_max_diff = buffer_get_float32_auto(data, &ind);
appconf.app_nrf_conf.speed = data[ind++];
appconf.app_nrf_conf.power = data[ind++];
appconf.app_nrf_conf.crc_type = data[ind++];
appconf.app_nrf_conf.retry_delay = data[ind++];
appconf.app_nrf_conf.retries = data[ind++];
appconf.app_nrf_conf.channel = data[ind++];
memcpy(appconf.app_nrf_conf.address, data + ind, 3);
ind += 3;
appconf.app_nrf_conf.send_crc_ack = data[ind++];
conf_general_store_app_configuration(&appconf);
app_set_configuration(&appconf);
timeout_configure(appconf.timeout_msec, appconf.timeout_brake_current);
chThdSleepMilliseconds(200);
ind = 0;
send_buffer[ind++] = packet_id;
commands_send_packet(send_buffer, ind);
ind = 0;
send_buffer[ind++] = packet_id;
commands_send_packet(send_buffer, ind);
} else {
commands_printf("Warning: Could not set appconf due to wrong signature");
}
break;
case COMM_GET_APPCONF:
@ -598,7 +407,7 @@ void commands_process_packet(unsigned char *data, unsigned int len) {
if (packet_id == COMM_GET_APPCONF) {
appconf = *app_get_configuration();
} else {
conf_general_get_default_app_configuration(&appconf);
confgenerator_set_defaults_appconf(&appconf);
}
commands_send_appconf(packet_id, &appconf);
@ -1099,224 +908,32 @@ void commands_send_gpd_buffer_notify(void) {
}
void commands_send_mcconf(COMM_PACKET_ID packet_id, mc_configuration *mcconf) {
int32_t ind = 0;
uint8_t *send_buffer = send_buffer_global;
send_buffer[ind++] = packet_id;
send_buffer[ind++] = mcconf->pwm_mode;
send_buffer[ind++] = mcconf->comm_mode;
send_buffer[ind++] = mcconf->motor_type;
send_buffer[ind++] = mcconf->sensor_mode;
buffer_append_float32_auto(send_buffer, mcconf->l_current_max, &ind);
buffer_append_float32_auto(send_buffer, mcconf->l_current_min, &ind);
buffer_append_float32_auto(send_buffer, mcconf->l_in_current_max, &ind);
buffer_append_float32_auto(send_buffer, mcconf->l_in_current_min, &ind);
buffer_append_float32_auto(send_buffer, mcconf->l_abs_current_max, &ind);
buffer_append_float32_auto(send_buffer, mcconf->l_min_erpm, &ind);
buffer_append_float32_auto(send_buffer, mcconf->l_max_erpm, &ind);
buffer_append_float32_auto(send_buffer, mcconf->l_erpm_start, &ind);
buffer_append_float32_auto(send_buffer, mcconf->l_max_erpm_fbrake, &ind);
buffer_append_float32_auto(send_buffer, mcconf->l_max_erpm_fbrake_cc, &ind);
buffer_append_float32_auto(send_buffer, mcconf->l_min_vin, &ind);
buffer_append_float32_auto(send_buffer, mcconf->l_max_vin, &ind);
buffer_append_float32_auto(send_buffer, mcconf->l_battery_cut_start, &ind);
buffer_append_float32_auto(send_buffer, mcconf->l_battery_cut_end, &ind);
send_buffer[ind++] = mcconf->l_slow_abs_current;
buffer_append_float32_auto(send_buffer, mcconf->l_temp_fet_start, &ind);
buffer_append_float32_auto(send_buffer, mcconf->l_temp_fet_end, &ind);
buffer_append_float32_auto(send_buffer, mcconf->l_temp_motor_start, &ind);
buffer_append_float32_auto(send_buffer, mcconf->l_temp_motor_end, &ind);
buffer_append_float32_auto(send_buffer, mcconf->l_temp_accel_dec, &ind);
buffer_append_float32_auto(send_buffer, mcconf->l_min_duty, &ind);
buffer_append_float32_auto(send_buffer, mcconf->l_max_duty, &ind);
buffer_append_float32_auto(send_buffer, mcconf->l_watt_max, &ind);
buffer_append_float32_auto(send_buffer, mcconf->l_watt_min, &ind);
buffer_append_float32_auto(send_buffer, mcconf->l_current_max_scale, &ind);
buffer_append_float32_auto(send_buffer, mcconf->l_current_min_scale, &ind);
buffer_append_float32_auto(send_buffer, mcconf->sl_min_erpm, &ind);
buffer_append_float32_auto(send_buffer, mcconf->sl_min_erpm_cycle_int_limit, &ind);
buffer_append_float32_auto(send_buffer, mcconf->sl_max_fullbreak_current_dir_change, &ind);
buffer_append_float32_auto(send_buffer, mcconf->sl_cycle_int_limit, &ind);
buffer_append_float32_auto(send_buffer, mcconf->sl_phase_advance_at_br, &ind);
buffer_append_float32_auto(send_buffer, mcconf->sl_cycle_int_rpm_br, &ind);
buffer_append_float32_auto(send_buffer, mcconf->sl_bemf_coupling_k, &ind);
memcpy(send_buffer + ind, mcconf->hall_table, 8);
ind += 8;
buffer_append_float32_auto(send_buffer, mcconf->hall_sl_erpm, &ind);
buffer_append_float32_auto(send_buffer, mcconf->foc_current_kp, &ind);
buffer_append_float32_auto(send_buffer, mcconf->foc_current_ki, &ind);
buffer_append_float32_auto(send_buffer, mcconf->foc_f_sw, &ind);
buffer_append_float32_auto(send_buffer, mcconf->foc_dt_us, &ind);
send_buffer[ind++] = mcconf->foc_encoder_inverted;
buffer_append_float32_auto(send_buffer, mcconf->foc_encoder_offset, &ind);
buffer_append_float32_auto(send_buffer, mcconf->foc_encoder_ratio, &ind);
send_buffer[ind++] = mcconf->foc_sensor_mode;
buffer_append_float32_auto(send_buffer, mcconf->foc_pll_kp, &ind);
buffer_append_float32_auto(send_buffer, mcconf->foc_pll_ki, &ind);
buffer_append_float32_auto(send_buffer, mcconf->foc_motor_l, &ind);
buffer_append_float32_auto(send_buffer, mcconf->foc_motor_r, &ind);
buffer_append_float32_auto(send_buffer, mcconf->foc_motor_flux_linkage, &ind);
buffer_append_float32_auto(send_buffer, mcconf->foc_observer_gain, &ind);
buffer_append_float32_auto(send_buffer, mcconf->foc_observer_gain_slow, &ind);
buffer_append_float32_auto(send_buffer, mcconf->foc_duty_dowmramp_kp, &ind);
buffer_append_float32_auto(send_buffer, mcconf->foc_duty_dowmramp_ki, &ind);
buffer_append_float32_auto(send_buffer, mcconf->foc_openloop_rpm, &ind);
buffer_append_float32_auto(send_buffer, mcconf->foc_sl_openloop_hyst, &ind);
buffer_append_float32_auto(send_buffer, mcconf->foc_sl_openloop_time, &ind);
buffer_append_float32_auto(send_buffer, mcconf->foc_sl_d_current_duty, &ind);
buffer_append_float32_auto(send_buffer, mcconf->foc_sl_d_current_factor, &ind);
memcpy(send_buffer + ind, mcconf->foc_hall_table, 8);
ind += 8;
buffer_append_float32_auto(send_buffer, mcconf->foc_sl_erpm, &ind);
send_buffer[ind++] = mcconf->foc_sample_v0_v7;
send_buffer[ind++] = mcconf->foc_sample_high_current;
buffer_append_float32_auto(send_buffer, mcconf->foc_sat_comp, &ind);
send_buffer[ind++] = mcconf->foc_temp_comp;
buffer_append_float32_auto(send_buffer, mcconf->foc_temp_comp_base_temp, &ind);
buffer_append_float32_auto(send_buffer, mcconf->foc_current_filter_const, &ind);
buffer_append_int16(send_buffer, mcconf->gpd_buffer_notify_left, &ind);
buffer_append_int16(send_buffer, mcconf->gpd_buffer_interpol, &ind);
buffer_append_float32_auto(send_buffer, mcconf->gpd_current_filter_const, &ind);
buffer_append_float32_auto(send_buffer, mcconf->gpd_current_kp, &ind);
buffer_append_float32_auto(send_buffer, mcconf->gpd_current_ki, &ind);
buffer_append_float32_auto(send_buffer, mcconf->s_pid_kp, &ind);
buffer_append_float32_auto(send_buffer, mcconf->s_pid_ki, &ind);
buffer_append_float32_auto(send_buffer, mcconf->s_pid_kd, &ind);
buffer_append_float32_auto(send_buffer, mcconf->s_pid_kd_filter, &ind);
buffer_append_float32_auto(send_buffer, mcconf->s_pid_min_erpm, &ind);
send_buffer[ind++] = mcconf->s_pid_allow_braking;
buffer_append_float32_auto(send_buffer, mcconf->p_pid_kp, &ind);
buffer_append_float32_auto(send_buffer, mcconf->p_pid_ki, &ind);
buffer_append_float32_auto(send_buffer, mcconf->p_pid_kd, &ind);
buffer_append_float32_auto(send_buffer, mcconf->p_pid_kd_filter, &ind);
buffer_append_float32_auto(send_buffer, mcconf->p_pid_ang_div, &ind);
buffer_append_float32_auto(send_buffer, mcconf->cc_startup_boost_duty, &ind);
buffer_append_float32_auto(send_buffer, mcconf->cc_min_current, &ind);
buffer_append_float32_auto(send_buffer, mcconf->cc_gain, &ind);
buffer_append_float32_auto(send_buffer, mcconf->cc_ramp_step_max, &ind);
buffer_append_int32(send_buffer, mcconf->m_fault_stop_time_ms, &ind);
buffer_append_float32_auto(send_buffer, mcconf->m_duty_ramp_step, &ind);
buffer_append_float32_auto(send_buffer, mcconf->m_current_backoff_gain, &ind);
buffer_append_uint32(send_buffer, mcconf->m_encoder_counts, &ind);
send_buffer[ind++] = mcconf->m_sensor_port_mode;
send_buffer[ind++] = mcconf->m_invert_direction;
send_buffer[ind++] = mcconf->m_drv8301_oc_mode;
send_buffer[ind++] = mcconf->m_drv8301_oc_adj;
buffer_append_float32_auto(send_buffer, mcconf->m_bldc_f_sw_min, &ind);
buffer_append_float32_auto(send_buffer, mcconf->m_bldc_f_sw_max, &ind);
buffer_append_float32_auto(send_buffer, mcconf->m_dc_f_sw, &ind);
buffer_append_float32_auto(send_buffer, mcconf->m_ntc_motor_beta, &ind);
send_buffer[ind++] = mcconf->m_out_aux_mode;
send_buffer[ind++] = mcconf->si_motor_poles;
buffer_append_float32_auto(send_buffer, mcconf->si_gear_ratio, &ind);
buffer_append_float32_auto(send_buffer, mcconf->si_wheel_diameter, &ind);
send_buffer[ind++] = mcconf->si_battery_type;
send_buffer[ind++] = mcconf->si_battery_cells;
buffer_append_float32_auto(send_buffer, mcconf->si_battery_ah, &ind);
commands_send_packet(send_buffer, ind);
send_buffer_global[0] = packet_id;
int32_t len = confgenerator_serialize_mcconf(send_buffer_global + 1, mcconf);
commands_send_packet(send_buffer_global, len + 1);
}
void commands_send_appconf(COMM_PACKET_ID packet_id, app_configuration *appconf) {
int32_t ind = 0;
uint8_t *send_buffer = send_buffer_global;
send_buffer[ind++] = packet_id;
send_buffer[ind++] = appconf->controller_id;
buffer_append_uint32(send_buffer, appconf->timeout_msec, &ind);
buffer_append_float32_auto(send_buffer, appconf->timeout_brake_current, &ind);
send_buffer[ind++] = appconf->send_can_status;
buffer_append_uint16(send_buffer, appconf->send_can_status_rate_hz, &ind);
send_buffer[ind++] = appconf->can_baud_rate;
send_buffer[ind++] = appconf->pairing_done;
send_buffer[ind++] = appconf->uavcan_enable;
send_buffer[ind++] = appconf->uavcan_esc_index;
send_buffer[ind++] = appconf->app_to_use;
send_buffer[ind++] = appconf->app_ppm_conf.ctrl_type;
buffer_append_float32_auto(send_buffer, appconf->app_ppm_conf.pid_max_erpm, &ind);
buffer_append_float32_auto(send_buffer, appconf->app_ppm_conf.hyst, &ind);
buffer_append_float32_auto(send_buffer, appconf->app_ppm_conf.pulse_start, &ind);
buffer_append_float32_auto(send_buffer, appconf->app_ppm_conf.pulse_end, &ind);
buffer_append_float32_auto(send_buffer, appconf->app_ppm_conf.pulse_center, &ind);
send_buffer[ind++] = appconf->app_ppm_conf.median_filter;
send_buffer[ind++] = appconf->app_ppm_conf.safe_start;
buffer_append_float32_auto(send_buffer, appconf->app_ppm_conf.throttle_exp, &ind);
buffer_append_float32_auto(send_buffer, appconf->app_ppm_conf.throttle_exp_brake, &ind);
send_buffer[ind++] = appconf->app_ppm_conf.throttle_exp_mode;
buffer_append_float32_auto(send_buffer, appconf->app_ppm_conf.ramp_time_pos, &ind);
buffer_append_float32_auto(send_buffer, appconf->app_ppm_conf.ramp_time_neg, &ind);
send_buffer[ind++] = appconf->app_ppm_conf.multi_esc;
send_buffer[ind++] = appconf->app_ppm_conf.tc;
buffer_append_float32_auto(send_buffer, appconf->app_ppm_conf.tc_max_diff, &ind);
send_buffer[ind++] = appconf->app_adc_conf.ctrl_type;
buffer_append_float32_auto(send_buffer, appconf->app_adc_conf.hyst, &ind);
buffer_append_float32_auto(send_buffer, appconf->app_adc_conf.voltage_start, &ind);
buffer_append_float32_auto(send_buffer, appconf->app_adc_conf.voltage_end, &ind);
buffer_append_float32_auto(send_buffer, appconf->app_adc_conf.voltage_center, &ind);
buffer_append_float32_auto(send_buffer, appconf->app_adc_conf.voltage2_start, &ind);
buffer_append_float32_auto(send_buffer, appconf->app_adc_conf.voltage2_end, &ind);
send_buffer[ind++] = appconf->app_adc_conf.use_filter;
send_buffer[ind++] = appconf->app_adc_conf.safe_start;
send_buffer[ind++] = appconf->app_adc_conf.cc_button_inverted;
send_buffer[ind++] = appconf->app_adc_conf.rev_button_inverted;
send_buffer[ind++] = appconf->app_adc_conf.voltage_inverted;
send_buffer[ind++] = appconf->app_adc_conf.voltage2_inverted;
buffer_append_float32_auto(send_buffer, appconf->app_adc_conf.throttle_exp, &ind);
buffer_append_float32_auto(send_buffer, appconf->app_adc_conf.throttle_exp_brake, &ind);
send_buffer[ind++] = appconf->app_adc_conf.throttle_exp_mode;
buffer_append_float32_auto(send_buffer, appconf->app_adc_conf.ramp_time_pos, &ind);
buffer_append_float32_auto(send_buffer, appconf->app_adc_conf.ramp_time_neg, &ind);
send_buffer[ind++] = appconf->app_adc_conf.multi_esc;
send_buffer[ind++] = appconf->app_adc_conf.tc;
buffer_append_float32_auto(send_buffer, appconf->app_adc_conf.tc_max_diff, &ind);
buffer_append_uint16(send_buffer, appconf->app_adc_conf.update_rate_hz, &ind);
buffer_append_uint32(send_buffer, appconf->app_uart_baudrate, &ind);
send_buffer[ind++] = appconf->app_chuk_conf.ctrl_type;
buffer_append_float32_auto(send_buffer, appconf->app_chuk_conf.hyst, &ind);
buffer_append_float32_auto(send_buffer, appconf->app_chuk_conf.ramp_time_pos, &ind);
buffer_append_float32_auto(send_buffer, appconf->app_chuk_conf.ramp_time_neg, &ind);
buffer_append_float32_auto(send_buffer, appconf->app_chuk_conf.stick_erpm_per_s_in_cc, &ind);
buffer_append_float32_auto(send_buffer, appconf->app_chuk_conf.throttle_exp, &ind);
buffer_append_float32_auto(send_buffer, appconf->app_chuk_conf.throttle_exp_brake, &ind);
send_buffer[ind++] = appconf->app_chuk_conf.throttle_exp_mode;
send_buffer[ind++] = appconf->app_chuk_conf.multi_esc;
send_buffer[ind++] = appconf->app_chuk_conf.tc;
buffer_append_float32_auto(send_buffer, appconf->app_chuk_conf.tc_max_diff, &ind);
send_buffer[ind++] = appconf->app_nrf_conf.speed;
send_buffer[ind++] = appconf->app_nrf_conf.power;
send_buffer[ind++] = appconf->app_nrf_conf.crc_type;
send_buffer[ind++] = appconf->app_nrf_conf.retry_delay;
send_buffer[ind++] = appconf->app_nrf_conf.retries;
send_buffer[ind++] = appconf->app_nrf_conf.channel;
memcpy(send_buffer + ind, appconf->app_nrf_conf.address, 3);
ind += 3;
send_buffer[ind++] = appconf->app_nrf_conf.send_crc_ack;
commands_send_packet(send_buffer, ind);
send_buffer_global[0] = packet_id;
int32_t len = confgenerator_serialize_appconf(send_buffer_global + 1, appconf);
commands_send_packet(send_buffer_global, len + 1);
}
void commands_apply_mcconf_hw_limits(mc_configuration *mcconf) {
utils_truncate_number(&mcconf->l_current_max_scale, 0.0, 1.0);
utils_truncate_number(&mcconf->l_current_min_scale, 0.0, 1.0);
// This limit should always be active, as starving the threads never
// makes sense.
#ifdef HW_LIM_FOC_CTRL_LOOP_FREQ
if (mcconf->foc_sample_v0_v7 == true) {
//control loop executes twice per pwm cycle when sampling in v0 and v7
utils_truncate_number(&mcconf->foc_f_sw, HW_LIM_FOC_CTRL_LOOP_FREQ);
} else {
utils_truncate_number(&mcconf->foc_f_sw, HW_LIM_FOC_CTRL_LOOP_FREQ * 2.0);
}
#endif
#ifndef DISABLE_HW_LIMITS
#ifdef HW_LIM_CURRENT
utils_truncate_number(&mcconf->l_current_max, HW_LIM_CURRENT);
@ -1347,12 +964,6 @@ void commands_apply_mcconf_hw_limits(mc_configuration *mcconf) {
utils_truncate_number(&mcconf->l_temp_fet_start, HW_LIM_TEMP_FET);
utils_truncate_number(&mcconf->l_temp_fet_end, HW_LIM_TEMP_FET);
#endif
#ifdef HW_LIM_FOC_CTRL_LOOP_FREQ
if (mcconf->foc_sample_v0_v7 == true)
utils_truncate_number(&mcconf->foc_f_sw, HW_LIM_FOC_CTRL_LOOP_FREQ); //control loop executes twice per pwm cycle when sampling in v0 and v7
else
utils_truncate_number(&mcconf->foc_f_sw, HW_LIM_FOC_CTRL_LOOP_FREQ*2);
#endif
#endif
}

View File

@ -23,7 +23,6 @@
#include "mcpwm.h"
#include "mcpwm_foc.h"
#include "mc_interface.h"
#include "hw.h"
#include "utils.h"
#include "stm32f4xx_conf.h"
#include "timeout.h"
@ -31,6 +30,7 @@
#include "encoder.h"
#include "comm_can.h"
#include "app.h"
#include "confgenerator.h"
#include <string.h>
#include <math.h>
@ -67,242 +67,6 @@ void conf_general_init(void) {
EE_Init();
}
/**
* Load the compiled default app_configuration.
*
* @param conf
* A pointer to store the default configuration to.
*/
void conf_general_get_default_app_configuration(app_configuration *conf) {
memset(conf, 0, sizeof(app_configuration));
conf->controller_id = HW_DEFAULT_ID;
conf->timeout_msec = APPCONF_TIMEOUT_MSEC;
conf->timeout_brake_current = APPCONF_TIMEOUT_BRAKE_CURRENT;
conf->send_can_status = APPCONF_SEND_CAN_STATUS;
conf->send_can_status_rate_hz = APPCONF_SEND_CAN_STATUS_RATE_HZ;
conf->can_baud_rate = APPCONF_CAN_BAUD_RATE;
conf->pairing_done = APPCONF_PAIRING_DONE;
conf->uavcan_enable = APPCONF_UAVCAN_ENABLE;
conf->uavcan_esc_index = APPCONF_UAVCAN_ESC_INDEX;
conf->app_to_use = APPCONF_APP_TO_USE;
conf->app_ppm_conf.ctrl_type = APPCONF_PPM_CTRL_TYPE;
conf->app_ppm_conf.pid_max_erpm = APPCONF_PPM_PID_MAX_ERPM;
conf->app_ppm_conf.hyst = APPCONF_PPM_HYST;
conf->app_ppm_conf.pulse_start = APPCONF_PPM_PULSE_START;
conf->app_ppm_conf.pulse_end = APPCONF_PPM_PULSE_END;
conf->app_ppm_conf.pulse_center = APPCONF_PPM_PULSE_CENTER;
conf->app_ppm_conf.median_filter = APPCONF_PPM_MEDIAN_FILTER;
conf->app_ppm_conf.safe_start = APPCONF_PPM_SAFE_START;
conf->app_ppm_conf.throttle_exp = APPCONF_PPM_THROTTLE_EXP;
conf->app_ppm_conf.throttle_exp_brake = APPCONF_PPM_THROTTLE_EXP_BRAKE;
conf->app_ppm_conf.throttle_exp_mode = APPCONF_PPM_THROTTLE_EXP_MODE;
conf->app_ppm_conf.ramp_time_pos = APPCONF_PPM_RAMP_TIME_POS;
conf->app_ppm_conf.ramp_time_neg = APPCONF_PPM_RAMP_TIME_NEG;
conf->app_ppm_conf.multi_esc = APPCONF_PPM_MULTI_ESC;
conf->app_ppm_conf.tc = APPCONF_PPM_TC;
conf->app_ppm_conf.tc_max_diff = APPCONF_PPM_TC_MAX_DIFF;
conf->app_adc_conf.ctrl_type = APPCONF_ADC_CTRL_TYPE;
conf->app_adc_conf.hyst = APPCONF_ADC_HYST;
conf->app_adc_conf.voltage_start = APPCONF_ADC_VOLTAGE_START;
conf->app_adc_conf.voltage_end = APPCONF_ADC_VOLTAGE_END;
conf->app_adc_conf.voltage_center = APPCONF_ADC_VOLTAGE_CENTER;
conf->app_adc_conf.voltage2_start = APPCONF_ADC_VOLTAGE2_START;
conf->app_adc_conf.voltage2_end = APPCONF_ADC_VOLTAGE2_END;
conf->app_adc_conf.use_filter = APPCONF_ADC_USE_FILTER;
conf->app_adc_conf.safe_start = APPCONF_ADC_SAFE_START;
conf->app_adc_conf.cc_button_inverted = APPCONF_ADC_CC_BUTTON_INVERTED;
conf->app_adc_conf.rev_button_inverted = APPCONF_ADC_REV_BUTTON_INVERTED;
conf->app_adc_conf.voltage_inverted = APPCONF_ADC_VOLTAGE_INVERTED;
conf->app_adc_conf.voltage2_inverted = APPCONF_ADC_VOLTAGE2_INVERTED;
conf->app_adc_conf.throttle_exp = APPCONF_ADC_THROTTLE_EXP;
conf->app_adc_conf.throttle_exp_brake = APPCONF_ADC_THROTTLE_EXP_BRAKE;
conf->app_adc_conf.throttle_exp_mode = APPCONF_ADC_THROTTLE_EXP_MODE;
conf->app_adc_conf.ramp_time_pos = APPCONF_ADC_RAMP_TIME_POS;
conf->app_adc_conf.ramp_time_neg = APPCONF_ADC_RAMP_TIME_NEG;
conf->app_adc_conf.multi_esc = APPCONF_ADC_MULTI_ESC;
conf->app_adc_conf.tc = APPCONF_ADC_TC;
conf->app_adc_conf.tc_max_diff = APPCONF_ADC_TC_MAX_DIFF;
conf->app_adc_conf.update_rate_hz = APPCONF_ADC_UPDATE_RATE_HZ;
conf->app_uart_baudrate = APPCONF_UART_BAUDRATE;
conf->app_chuk_conf.ctrl_type = APPCONF_CHUK_CTRL_TYPE;
conf->app_chuk_conf.hyst = APPCONF_CHUK_HYST;
conf->app_chuk_conf.ramp_time_pos = APPCONF_CHUK_RAMP_TIME_POS;
conf->app_chuk_conf.ramp_time_neg = APPCONF_CHUK_RAMP_TIME_NEG;
conf->app_chuk_conf.stick_erpm_per_s_in_cc = APPCONF_STICK_ERPM_PER_S_IN_CC;
conf->app_chuk_conf.throttle_exp = APPCONF_CHUK_THROTTLE_EXP;
conf->app_chuk_conf.throttle_exp_brake = APPCONF_CHUK_THROTTLE_EXP_BRAKE;
conf->app_chuk_conf.throttle_exp_mode = APPCONF_CHUK_THROTTLE_EXP_MODE;
conf->app_chuk_conf.multi_esc = APPCONF_CHUK_MULTI_ESC;
conf->app_chuk_conf.tc = APPCONF_CHUK_TC;
conf->app_chuk_conf.tc_max_diff = APPCONF_CHUK_TC_MAX_DIFF;
conf->app_nrf_conf.speed = APPCONF_NRF_SPEED;
conf->app_nrf_conf.power = APPCONF_NRF_POWER;
conf->app_nrf_conf.crc_type = APPCONF_NRF_CRC;
conf->app_nrf_conf.retry_delay = APPCONF_NRF_RETR_DELAY;
conf->app_nrf_conf.retries = APPCONF_NRF_RETRIES;
conf->app_nrf_conf.channel = APPCONF_NRF_CHANNEL;
conf->app_nrf_conf.address[0] = APPCONF_NRF_ADDR_B0;
conf->app_nrf_conf.address[1] = APPCONF_NRF_ADDR_B1;
conf->app_nrf_conf.address[2] = APPCONF_NRF_ADDR_B2;
conf->app_nrf_conf.send_crc_ack = APPCONF_NRF_SEND_CRC_ACK;
}
/**
* Load the compiled default mc_configuration.
*
* @param conf
* A pointer to store the default configuration to.
*/
void conf_general_get_default_mc_configuration(mc_configuration *conf) {
memset(conf, 0, sizeof(mc_configuration));
conf->pwm_mode = MCCONF_PWM_MODE;
conf->comm_mode = MCCONF_COMM_MODE;
conf->motor_type = MCCONF_DEFAULT_MOTOR_TYPE;
conf->sensor_mode = MCCONF_SENSOR_MODE;
conf->l_current_max = MCCONF_L_CURRENT_MAX;
conf->l_current_min = MCCONF_L_CURRENT_MIN;
conf->l_in_current_max = MCCONF_L_IN_CURRENT_MAX;
conf->l_in_current_min = MCCONF_L_IN_CURRENT_MIN;
conf->l_abs_current_max = MCCONF_L_MAX_ABS_CURRENT;
conf->l_min_erpm = MCCONF_L_RPM_MIN;
conf->l_max_erpm = MCCONF_L_RPM_MAX;
conf->l_erpm_start = MCCONF_L_RPM_START;
conf->l_max_erpm_fbrake = MCCONF_L_CURR_MAX_RPM_FBRAKE;
conf->l_max_erpm_fbrake_cc = MCCONF_L_CURR_MAX_RPM_FBRAKE_CC;
conf->l_min_vin = MCCONF_L_MIN_VOLTAGE;
conf->l_max_vin = MCCONF_L_MAX_VOLTAGE;
conf->l_battery_cut_start = MCCONF_L_BATTERY_CUT_START;
conf->l_battery_cut_end = MCCONF_L_BATTERY_CUT_END;
conf->l_slow_abs_current = MCCONF_L_SLOW_ABS_OVERCURRENT;
conf->l_temp_fet_start = MCCONF_L_LIM_TEMP_FET_START;
conf->l_temp_fet_end = MCCONF_L_LIM_TEMP_FET_END;
conf->l_temp_motor_start = MCCONF_L_LIM_TEMP_MOTOR_START;
conf->l_temp_motor_end = MCCONF_L_LIM_TEMP_MOTOR_END;
conf->l_temp_accel_dec = MCCONF_L_LIM_TEMP_ACCEL_DEC;
conf->l_min_duty = MCCONF_L_MIN_DUTY;
conf->l_max_duty = MCCONF_L_MAX_DUTY;
conf->l_watt_max = MCCONF_L_WATT_MAX;
conf->l_watt_min = MCCONF_L_WATT_MIN;
conf->l_current_max_scale = MCCONF_L_CURRENT_MAX_SCALE;
conf->l_current_min_scale = MCCONF_L_CURRENT_MIN_SCALE;
conf->lo_current_max = conf->l_current_max * conf->l_current_max_scale;
conf->lo_current_min = conf->l_current_min * conf->l_current_min_scale;
conf->lo_in_current_max = conf->l_in_current_max;
conf->lo_in_current_min = conf->l_in_current_min;
conf->lo_current_motor_max_now = conf->lo_current_max;
conf->lo_current_motor_min_now = conf->lo_current_min;
conf->sl_min_erpm = MCCONF_SL_MIN_RPM;
conf->sl_max_fullbreak_current_dir_change = MCCONF_SL_MAX_FB_CURR_DIR_CHANGE;
conf->sl_min_erpm_cycle_int_limit = MCCONF_SL_MIN_ERPM_CYCLE_INT_LIMIT;
conf->sl_cycle_int_limit = MCCONF_SL_CYCLE_INT_LIMIT;
conf->sl_phase_advance_at_br = MCCONF_SL_PHASE_ADVANCE_AT_BR;
conf->sl_cycle_int_rpm_br = MCCONF_SL_CYCLE_INT_BR;
conf->sl_bemf_coupling_k = MCCONF_SL_BEMF_COUPLING_K;
conf->hall_table[0] = MCCONF_HALL_TAB_0;
conf->hall_table[1] = MCCONF_HALL_TAB_1;
conf->hall_table[2] = MCCONF_HALL_TAB_2;
conf->hall_table[3] = MCCONF_HALL_TAB_3;
conf->hall_table[4] = MCCONF_HALL_TAB_4;
conf->hall_table[5] = MCCONF_HALL_TAB_5;
conf->hall_table[6] = MCCONF_HALL_TAB_6;
conf->hall_table[7] = MCCONF_HALL_TAB_7;
conf->hall_sl_erpm = MCCONF_HALL_ERPM;
conf->foc_current_kp = MCCONF_FOC_CURRENT_KP;
conf->foc_current_ki = MCCONF_FOC_CURRENT_KI;
conf->foc_f_sw = MCCONF_FOC_F_SW;
conf->foc_dt_us = MCCONF_FOC_DT_US;
conf->foc_encoder_inverted = MCCONF_FOC_ENCODER_INVERTED;
conf->foc_encoder_offset = MCCONF_FOC_ENCODER_OFFSET;
conf->foc_encoder_ratio = MCCONF_FOC_ENCODER_RATIO;
conf->foc_sensor_mode = MCCONF_FOC_SENSOR_MODE;
conf->foc_pll_kp = MCCONF_FOC_PLL_KP;
conf->foc_pll_ki = MCCONF_FOC_PLL_KI;
conf->foc_motor_l = MCCONF_FOC_MOTOR_L;
conf->foc_motor_r = MCCONF_FOC_MOTOR_R;
conf->foc_motor_flux_linkage = MCCONF_FOC_MOTOR_FLUX_LINKAGE;
conf->foc_observer_gain = MCCONF_FOC_OBSERVER_GAIN;
conf->foc_observer_gain_slow = MCCONF_FOC_OBSERVER_GAIN_SLOW;
conf->foc_duty_dowmramp_kp = MCCONF_FOC_DUTY_DOWNRAMP_KP;
conf->foc_duty_dowmramp_ki = MCCONF_FOC_DUTY_DOWNRAMP_KI;
conf->foc_openloop_rpm = MCCONF_FOC_OPENLOOP_RPM;
conf->foc_sl_openloop_hyst = MCCONF_FOC_SL_OPENLOOP_HYST;
conf->foc_sl_openloop_time = MCCONF_FOC_SL_OPENLOOP_TIME;
conf->foc_sl_d_current_duty = MCCONF_FOC_SL_D_CURRENT_DUTY;
conf->foc_sl_d_current_factor = MCCONF_FOC_SL_D_CURRENT_FACTOR;
conf->foc_hall_table[0] = MCCONF_FOC_HALL_TAB_0;
conf->foc_hall_table[1] = MCCONF_FOC_HALL_TAB_1;
conf->foc_hall_table[2] = MCCONF_FOC_HALL_TAB_2;
conf->foc_hall_table[3] = MCCONF_FOC_HALL_TAB_3;
conf->foc_hall_table[4] = MCCONF_FOC_HALL_TAB_4;
conf->foc_hall_table[5] = MCCONF_FOC_HALL_TAB_5;
conf->foc_hall_table[6] = MCCONF_FOC_HALL_TAB_6;
conf->foc_hall_table[7] = MCCONF_FOC_HALL_TAB_7;
conf->foc_sl_erpm = MCCONF_FOC_SL_ERPM;
conf->foc_sample_v0_v7 = MCCONF_FOC_SAMPLE_V0_V7;
conf->foc_sample_high_current = MCCONF_FOC_SAMPLE_HIGH_CURRENT;
conf->foc_sat_comp = MCCONF_FOC_SAT_COMP;
conf->foc_temp_comp = MCCONF_FOC_TEMP_COMP;
conf->foc_temp_comp_base_temp = MCCONF_FOC_TEMP_COMP_BASE_TEMP;
conf->foc_current_filter_const = MCCONF_FOC_CURRENT_FILTER_CONST;
conf->gpd_buffer_notify_left = MCCONF_GPD_BUFFER_NOTIFY_LEFT;
conf->gpd_buffer_interpol = MCCONF_GPD_BUFFER_INTERPOL;
conf->gpd_current_filter_const = MCCONF_GPD_CURRENT_FILTER_CONST;
conf->gpd_current_kp = MCCONF_GPD_CURRENT_KP;
conf->gpd_current_ki = MCCONF_GPD_CURRENT_KI;
conf->s_pid_kp = MCCONF_S_PID_KP;
conf->s_pid_ki = MCCONF_S_PID_KI;
conf->s_pid_kd = MCCONF_S_PID_KD;
conf->s_pid_kd_filter = MCCONF_S_PID_KD_FILTER;
conf->s_pid_min_erpm = MCCONF_S_PID_MIN_RPM;
conf->s_pid_allow_braking = MCCONF_S_PID_ALLOW_BRAKING;
conf->p_pid_kp = MCCONF_P_PID_KP;
conf->p_pid_ki = MCCONF_P_PID_KI;
conf->p_pid_kd = MCCONF_P_PID_KD;
conf->p_pid_kd_filter = MCCONF_P_PID_KD_FILTER;
conf->p_pid_ang_div = MCCONF_P_PID_ANG_DIV;
conf->cc_startup_boost_duty = MCCONF_CC_STARTUP_BOOST_DUTY;
conf->cc_min_current = MCCONF_CC_MIN_CURRENT;
conf->cc_gain = MCCONF_CC_GAIN;
conf->cc_ramp_step_max = MCCONF_CC_RAMP_STEP;
conf->m_fault_stop_time_ms = MCCONF_M_FAULT_STOP_TIME;
conf->m_duty_ramp_step = MCCONF_M_RAMP_STEP;
conf->m_current_backoff_gain = MCCONF_M_CURRENT_BACKOFF_GAIN;
conf->m_encoder_counts = MCCONF_M_ENCODER_COUNTS;
conf->m_sensor_port_mode = MCCONF_M_SENSOR_PORT_MODE;
conf->m_invert_direction = MCCONF_M_INVERT_DIRECTION;
conf->m_drv8301_oc_mode = MCCONF_M_DRV8301_OC_MODE;
conf->m_drv8301_oc_adj = MCCONF_M_DRV8301_OC_ADJ;
conf->m_bldc_f_sw_min = MCCONF_M_BLDC_F_SW_MIN;
conf->m_bldc_f_sw_max = MCCONF_M_BLDC_F_SW_MAX;
conf->m_dc_f_sw = MCCONF_M_DC_F_SW;
conf->m_ntc_motor_beta = MCCONF_M_NTC_MOTOR_BETA;
conf->m_out_aux_mode = MCCONF_M_OUT_AUX_MODE;
conf->si_motor_poles = MCCONF_SI_MOTOR_POLES;
conf->si_gear_ratio = MCCONF_SI_GEAR_RATIO;
conf->si_wheel_diameter = MCCONF_SI_WHEEL_DIAMETER;
conf->si_battery_type = MCCONF_SI_BATTERY_TYPE;
conf->si_battery_cells = MCCONF_SI_BATTERY_CELLS;
conf->si_battery_ah = MCCONF_SI_BATTERY_AH;
}
/**
* Read app_configuration from EEPROM. If this fails, default values will be used.
*
@ -326,7 +90,7 @@ void conf_general_read_app_configuration(app_configuration *conf) {
// Set the default configuration
if (!is_ok) {
conf_general_get_default_app_configuration(conf);
confgenerator_set_defaults_appconf(conf);
}
}
@ -343,7 +107,6 @@ bool conf_general_store_app_configuration(app_configuration *conf) {
utils_sys_lock_cnt();
mc_interface_lock();
RCC_APB1PeriphClockCmd(RCC_APB1Periph_WWDG, DISABLE);
timeout_configure_IWDT_slowest();
bool is_ok = true;
@ -363,7 +126,6 @@ bool conf_general_store_app_configuration(app_configuration *conf) {
}
}
RCC_APB1PeriphClockCmd(RCC_APB1Periph_WWDG, ENABLE);
timeout_configure_IWDT();
chThdSleepMilliseconds(100);
@ -395,7 +157,7 @@ void conf_general_read_mc_configuration(mc_configuration *conf) {
}
if (!is_ok) {
conf_general_get_default_mc_configuration(conf);
confgenerator_set_defaults_mcconf(conf);
}
}
@ -412,7 +174,6 @@ bool conf_general_store_mc_configuration(mc_configuration *conf) {
utils_sys_lock_cnt();
mc_interface_lock();
RCC_APB1PeriphClockCmd(RCC_APB1Periph_WWDG, DISABLE);
timeout_configure_IWDT_slowest();
bool is_ok = true;
@ -431,7 +192,6 @@ bool conf_general_store_mc_configuration(mc_configuration *conf) {
}
}
RCC_APB1PeriphClockCmd(RCC_APB1Periph_WWDG, ENABLE);
timeout_configure_IWDT();
chThdSleepMilliseconds(100);

View File

@ -22,7 +22,7 @@
// Firmware version
#define FW_VERSION_MAJOR 3
#define FW_VERSION_MINOR 49
#define FW_VERSION_MINOR 50
#include "datatypes.h"
@ -218,8 +218,6 @@ extern bool conf_general_permanent_nrf_found;
// Functions
void conf_general_init(void);
void conf_general_get_default_app_configuration(app_configuration *conf);
void conf_general_get_default_mc_configuration(mc_configuration *conf);
void conf_general_read_app_configuration(app_configuration *conf);
bool conf_general_store_app_configuration(app_configuration *conf);
void conf_general_read_mc_configuration(mc_configuration *conf);

View File

@ -21,6 +21,7 @@
#define CONF_MC_APP_DEFAULT_H_
#include "conf_general.h"
#include "hw.h"
// User defined default motor configuration file
#ifdef MCCONF_DEFAULT_USER

629
confgenerator.c Normal file
View File

@ -0,0 +1,629 @@
// This file is autogenerated by VESC Tool
#include "buffer.h"
#include "conf_mc_app_default.h"
#include "confgenerator.h"
int32_t confgenerator_serialize_mcconf(uint8_t *buffer, const mc_configuration *conf) {
int32_t ind = 0;
buffer_append_uint32(buffer, MCCONF_SIGNATURE, &ind);
buffer[ind++] = conf->pwm_mode;
buffer[ind++] = conf->comm_mode;
buffer[ind++] = conf->motor_type;
buffer[ind++] = conf->sensor_mode;
buffer_append_float32_auto(buffer, conf->l_current_max, &ind);
buffer_append_float32_auto(buffer, conf->l_current_min, &ind);
buffer_append_float32_auto(buffer, conf->l_in_current_max, &ind);
buffer_append_float32_auto(buffer, conf->l_in_current_min, &ind);
buffer_append_float32_auto(buffer, conf->l_abs_current_max, &ind);
buffer_append_float32_auto(buffer, conf->l_min_erpm, &ind);
buffer_append_float32_auto(buffer, conf->l_max_erpm, &ind);
buffer_append_float32_auto(buffer, conf->l_erpm_start, &ind);
buffer_append_float32_auto(buffer, conf->l_max_erpm_fbrake, &ind);
buffer_append_float32_auto(buffer, conf->l_max_erpm_fbrake_cc, &ind);
buffer_append_float32_auto(buffer, conf->l_min_vin, &ind);
buffer_append_float32_auto(buffer, conf->l_max_vin, &ind);
buffer_append_float32_auto(buffer, conf->l_battery_cut_start, &ind);
buffer_append_float32_auto(buffer, conf->l_battery_cut_end, &ind);
buffer[ind++] = conf->l_slow_abs_current;
buffer_append_float32_auto(buffer, conf->l_temp_fet_start, &ind);
buffer_append_float32_auto(buffer, conf->l_temp_fet_end, &ind);
buffer_append_float32_auto(buffer, conf->l_temp_motor_start, &ind);
buffer_append_float32_auto(buffer, conf->l_temp_motor_end, &ind);
buffer_append_float32_auto(buffer, conf->l_temp_accel_dec, &ind);
buffer_append_float32_auto(buffer, conf->l_min_duty, &ind);
buffer_append_float32_auto(buffer, conf->l_max_duty, &ind);
buffer_append_float32_auto(buffer, conf->l_watt_max, &ind);
buffer_append_float32_auto(buffer, conf->l_watt_min, &ind);
buffer_append_float32_auto(buffer, conf->l_current_max_scale, &ind);
buffer_append_float32_auto(buffer, conf->l_current_min_scale, &ind);
buffer_append_float32_auto(buffer, conf->sl_min_erpm, &ind);
buffer_append_float32_auto(buffer, conf->sl_min_erpm_cycle_int_limit, &ind);
buffer_append_float32_auto(buffer, conf->sl_max_fullbreak_current_dir_change, &ind);
buffer_append_float32_auto(buffer, conf->sl_cycle_int_limit, &ind);
buffer_append_float32_auto(buffer, conf->sl_phase_advance_at_br, &ind);
buffer_append_float32_auto(buffer, conf->sl_cycle_int_rpm_br, &ind);
buffer_append_float32_auto(buffer, conf->sl_bemf_coupling_k, &ind);
buffer[ind++] = (uint8_t)conf->hall_table[0];
buffer[ind++] = (uint8_t)conf->hall_table[1];
buffer[ind++] = (uint8_t)conf->hall_table[2];
buffer[ind++] = (uint8_t)conf->hall_table[3];
buffer[ind++] = (uint8_t)conf->hall_table[4];
buffer[ind++] = (uint8_t)conf->hall_table[5];
buffer[ind++] = (uint8_t)conf->hall_table[6];
buffer[ind++] = (uint8_t)conf->hall_table[7];
buffer_append_float32_auto(buffer, conf->hall_sl_erpm, &ind);
buffer_append_float32_auto(buffer, conf->foc_current_kp, &ind);
buffer_append_float32_auto(buffer, conf->foc_current_ki, &ind);
buffer_append_float32_auto(buffer, conf->foc_f_sw, &ind);
buffer_append_float32_auto(buffer, conf->foc_dt_us, &ind);
buffer[ind++] = conf->foc_encoder_inverted;
buffer_append_float32_auto(buffer, conf->foc_encoder_offset, &ind);
buffer_append_float32_auto(buffer, conf->foc_encoder_ratio, &ind);
buffer[ind++] = conf->foc_sensor_mode;
buffer_append_float32_auto(buffer, conf->foc_pll_kp, &ind);
buffer_append_float32_auto(buffer, conf->foc_pll_ki, &ind);
buffer_append_float32_auto(buffer, conf->foc_motor_l, &ind);
buffer_append_float32_auto(buffer, conf->foc_motor_r, &ind);
buffer_append_float32_auto(buffer, conf->foc_motor_flux_linkage, &ind);
buffer_append_float32_auto(buffer, conf->foc_observer_gain, &ind);
buffer_append_float32_auto(buffer, conf->foc_observer_gain_slow, &ind);
buffer_append_float32_auto(buffer, conf->foc_duty_dowmramp_kp, &ind);
buffer_append_float32_auto(buffer, conf->foc_duty_dowmramp_ki, &ind);
buffer_append_float32_auto(buffer, conf->foc_openloop_rpm, &ind);
buffer_append_float32_auto(buffer, conf->foc_sl_openloop_hyst, &ind);
buffer_append_float32_auto(buffer, conf->foc_sl_openloop_time, &ind);
buffer_append_float32_auto(buffer, conf->foc_sl_d_current_duty, &ind);
buffer_append_float32_auto(buffer, conf->foc_sl_d_current_factor, &ind);
buffer[ind++] = (uint8_t)conf->foc_hall_table[0];
buffer[ind++] = (uint8_t)conf->foc_hall_table[1];
buffer[ind++] = (uint8_t)conf->foc_hall_table[2];
buffer[ind++] = (uint8_t)conf->foc_hall_table[3];
buffer[ind++] = (uint8_t)conf->foc_hall_table[4];
buffer[ind++] = (uint8_t)conf->foc_hall_table[5];
buffer[ind++] = (uint8_t)conf->foc_hall_table[6];
buffer[ind++] = (uint8_t)conf->foc_hall_table[7];
buffer_append_float32_auto(buffer, conf->foc_sl_erpm, &ind);
buffer[ind++] = conf->foc_sample_v0_v7;
buffer[ind++] = conf->foc_sample_high_current;
buffer_append_float32_auto(buffer, conf->foc_sat_comp, &ind);
buffer[ind++] = conf->foc_temp_comp;
buffer_append_float32_auto(buffer, conf->foc_temp_comp_base_temp, &ind);
buffer_append_float32_auto(buffer, conf->foc_current_filter_const, &ind);
buffer_append_int16(buffer, conf->gpd_buffer_notify_left, &ind);
buffer_append_int16(buffer, conf->gpd_buffer_interpol, &ind);
buffer_append_float32_auto(buffer, conf->gpd_current_filter_const, &ind);
buffer_append_float32_auto(buffer, conf->gpd_current_kp, &ind);
buffer_append_float32_auto(buffer, conf->gpd_current_ki, &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_kd, &ind);
buffer_append_float32_auto(buffer, conf->s_pid_kd_filter, &ind);
buffer_append_float32_auto(buffer, conf->s_pid_min_erpm, &ind);
buffer[ind++] = conf->s_pid_allow_braking;
buffer_append_float32_auto(buffer, conf->p_pid_kp, &ind);
buffer_append_float32_auto(buffer, conf->p_pid_ki, &ind);
buffer_append_float32_auto(buffer, conf->p_pid_kd, &ind);
buffer_append_float32_auto(buffer, conf->p_pid_kd_filter, &ind);
buffer_append_float32_auto(buffer, conf->p_pid_ang_div, &ind);
buffer_append_float32_auto(buffer, conf->cc_startup_boost_duty, &ind);
buffer_append_float32_auto(buffer, conf->cc_min_current, &ind);
buffer_append_float32_auto(buffer, conf->cc_gain, &ind);
buffer_append_float32_auto(buffer, conf->cc_ramp_step_max, &ind);
buffer_append_int32(buffer, conf->m_fault_stop_time_ms, &ind);
buffer_append_float32_auto(buffer, conf->m_duty_ramp_step, &ind);
buffer_append_float32_auto(buffer, conf->m_current_backoff_gain, &ind);
buffer_append_uint32(buffer, conf->m_encoder_counts, &ind);
buffer[ind++] = conf->m_sensor_port_mode;
buffer[ind++] = conf->m_invert_direction;
buffer[ind++] = conf->m_drv8301_oc_mode;
buffer[ind++] = (uint8_t)conf->m_drv8301_oc_adj;
buffer_append_float32_auto(buffer, conf->m_bldc_f_sw_min, &ind);
buffer_append_float32_auto(buffer, conf->m_bldc_f_sw_max, &ind);
buffer_append_float32_auto(buffer, conf->m_dc_f_sw, &ind);
buffer_append_float32_auto(buffer, conf->m_ntc_motor_beta, &ind);
buffer[ind++] = conf->m_out_aux_mode;
buffer[ind++] = (uint8_t)conf->si_motor_poles;
buffer_append_float32_auto(buffer, conf->si_gear_ratio, &ind);
buffer_append_float32_auto(buffer, conf->si_wheel_diameter, &ind);
buffer[ind++] = conf->si_battery_type;
buffer[ind++] = (uint8_t)conf->si_battery_cells;
buffer_append_float32_auto(buffer, conf->si_battery_ah, &ind);
return ind;
}
int32_t confgenerator_serialize_appconf(uint8_t *buffer, const app_configuration *conf) {
int32_t ind = 0;
buffer_append_uint32(buffer, APPCONF_SIGNATURE, &ind);
buffer[ind++] = (uint8_t)conf->controller_id;
buffer_append_uint32(buffer, conf->timeout_msec, &ind);
buffer_append_float32_auto(buffer, conf->timeout_brake_current, &ind);
buffer[ind++] = conf->send_can_status;
buffer_append_uint16(buffer, conf->send_can_status_rate_hz, &ind);
buffer[ind++] = conf->can_baud_rate;
buffer[ind++] = conf->pairing_done;
buffer[ind++] = conf->uavcan_enable;
buffer[ind++] = (uint8_t)conf->uavcan_esc_index;
buffer[ind++] = conf->app_to_use;
buffer[ind++] = conf->app_ppm_conf.ctrl_type;
buffer_append_float32_auto(buffer, conf->app_ppm_conf.pid_max_erpm, &ind);
buffer_append_float32_auto(buffer, conf->app_ppm_conf.hyst, &ind);
buffer_append_float32_auto(buffer, conf->app_ppm_conf.pulse_start, &ind);
buffer_append_float32_auto(buffer, conf->app_ppm_conf.pulse_end, &ind);
buffer_append_float32_auto(buffer, conf->app_ppm_conf.pulse_center, &ind);
buffer[ind++] = conf->app_ppm_conf.median_filter;
buffer[ind++] = conf->app_ppm_conf.safe_start;
buffer_append_float32_auto(buffer, conf->app_ppm_conf.throttle_exp, &ind);
buffer_append_float32_auto(buffer, conf->app_ppm_conf.throttle_exp_brake, &ind);
buffer[ind++] = conf->app_ppm_conf.throttle_exp_mode;
buffer_append_float32_auto(buffer, conf->app_ppm_conf.ramp_time_pos, &ind);
buffer_append_float32_auto(buffer, conf->app_ppm_conf.ramp_time_neg, &ind);
buffer[ind++] = conf->app_ppm_conf.multi_esc;
buffer[ind++] = conf->app_ppm_conf.tc;
buffer_append_float32_auto(buffer, conf->app_ppm_conf.tc_max_diff, &ind);
buffer[ind++] = conf->app_adc_conf.ctrl_type;
buffer_append_float32_auto(buffer, conf->app_adc_conf.hyst, &ind);
buffer_append_float32_auto(buffer, conf->app_adc_conf.voltage_start, &ind);
buffer_append_float32_auto(buffer, conf->app_adc_conf.voltage_end, &ind);
buffer_append_float32_auto(buffer, conf->app_adc_conf.voltage_center, &ind);
buffer_append_float32_auto(buffer, conf->app_adc_conf.voltage2_start, &ind);
buffer_append_float32_auto(buffer, conf->app_adc_conf.voltage2_end, &ind);
buffer[ind++] = conf->app_adc_conf.use_filter;
buffer[ind++] = conf->app_adc_conf.safe_start;
buffer[ind++] = conf->app_adc_conf.cc_button_inverted;
buffer[ind++] = conf->app_adc_conf.rev_button_inverted;
buffer[ind++] = conf->app_adc_conf.voltage_inverted;
buffer[ind++] = conf->app_adc_conf.voltage2_inverted;
buffer_append_float32_auto(buffer, conf->app_adc_conf.throttle_exp, &ind);
buffer_append_float32_auto(buffer, conf->app_adc_conf.throttle_exp_brake, &ind);
buffer[ind++] = conf->app_adc_conf.throttle_exp_mode;
buffer_append_float32_auto(buffer, conf->app_adc_conf.ramp_time_pos, &ind);
buffer_append_float32_auto(buffer, conf->app_adc_conf.ramp_time_neg, &ind);
buffer[ind++] = conf->app_adc_conf.multi_esc;
buffer[ind++] = conf->app_adc_conf.tc;
buffer_append_float32_auto(buffer, conf->app_adc_conf.tc_max_diff, &ind);
buffer_append_uint16(buffer, conf->app_adc_conf.update_rate_hz, &ind);
buffer_append_uint32(buffer, conf->app_uart_baudrate, &ind);
buffer[ind++] = conf->app_chuk_conf.ctrl_type;
buffer_append_float32_auto(buffer, conf->app_chuk_conf.hyst, &ind);
buffer_append_float32_auto(buffer, conf->app_chuk_conf.ramp_time_pos, &ind);
buffer_append_float32_auto(buffer, conf->app_chuk_conf.ramp_time_neg, &ind);
buffer_append_float32_auto(buffer, conf->app_chuk_conf.stick_erpm_per_s_in_cc, &ind);
buffer_append_float32_auto(buffer, conf->app_chuk_conf.throttle_exp, &ind);
buffer_append_float32_auto(buffer, conf->app_chuk_conf.throttle_exp_brake, &ind);
buffer[ind++] = conf->app_chuk_conf.throttle_exp_mode;
buffer[ind++] = conf->app_chuk_conf.multi_esc;
buffer[ind++] = conf->app_chuk_conf.tc;
buffer_append_float32_auto(buffer, conf->app_chuk_conf.tc_max_diff, &ind);
buffer[ind++] = conf->app_nrf_conf.speed;
buffer[ind++] = conf->app_nrf_conf.power;
buffer[ind++] = conf->app_nrf_conf.crc_type;
buffer[ind++] = conf->app_nrf_conf.retry_delay;
buffer[ind++] = (uint8_t)conf->app_nrf_conf.retries;
buffer[ind++] = (uint8_t)conf->app_nrf_conf.channel;
buffer[ind++] = (uint8_t)conf->app_nrf_conf.address[0];
buffer[ind++] = (uint8_t)conf->app_nrf_conf.address[1];
buffer[ind++] = (uint8_t)conf->app_nrf_conf.address[2];
buffer[ind++] = conf->app_nrf_conf.send_crc_ack;
return ind;
}
bool confgenerator_deserialize_mcconf(const uint8_t *buffer, mc_configuration *conf) {
int32_t ind = 0;
uint32_t signature = buffer_get_uint32(buffer, &ind);
if (signature != MCCONF_SIGNATURE) {
return false;
}
conf->pwm_mode = buffer[ind++];
conf->comm_mode = buffer[ind++];
conf->motor_type = buffer[ind++];
conf->sensor_mode = buffer[ind++];
conf->l_current_max = buffer_get_float32_auto(buffer, &ind);
conf->l_current_min = buffer_get_float32_auto(buffer, &ind);
conf->l_in_current_max = buffer_get_float32_auto(buffer, &ind);
conf->l_in_current_min = buffer_get_float32_auto(buffer, &ind);
conf->l_abs_current_max = buffer_get_float32_auto(buffer, &ind);
conf->l_min_erpm = buffer_get_float32_auto(buffer, &ind);
conf->l_max_erpm = buffer_get_float32_auto(buffer, &ind);
conf->l_erpm_start = buffer_get_float32_auto(buffer, &ind);
conf->l_max_erpm_fbrake = buffer_get_float32_auto(buffer, &ind);
conf->l_max_erpm_fbrake_cc = buffer_get_float32_auto(buffer, &ind);
conf->l_min_vin = buffer_get_float32_auto(buffer, &ind);
conf->l_max_vin = buffer_get_float32_auto(buffer, &ind);
conf->l_battery_cut_start = buffer_get_float32_auto(buffer, &ind);
conf->l_battery_cut_end = buffer_get_float32_auto(buffer, &ind);
conf->l_slow_abs_current = buffer[ind++];
conf->l_temp_fet_start = buffer_get_float32_auto(buffer, &ind);
conf->l_temp_fet_end = buffer_get_float32_auto(buffer, &ind);
conf->l_temp_motor_start = buffer_get_float32_auto(buffer, &ind);
conf->l_temp_motor_end = buffer_get_float32_auto(buffer, &ind);
conf->l_temp_accel_dec = buffer_get_float32_auto(buffer, &ind);
conf->l_min_duty = buffer_get_float32_auto(buffer, &ind);
conf->l_max_duty = buffer_get_float32_auto(buffer, &ind);
conf->l_watt_max = buffer_get_float32_auto(buffer, &ind);
conf->l_watt_min = buffer_get_float32_auto(buffer, &ind);
conf->l_current_max_scale = buffer_get_float32_auto(buffer, &ind);
conf->l_current_min_scale = buffer_get_float32_auto(buffer, &ind);
conf->sl_min_erpm = buffer_get_float32_auto(buffer, &ind);
conf->sl_min_erpm_cycle_int_limit = buffer_get_float32_auto(buffer, &ind);
conf->sl_max_fullbreak_current_dir_change = buffer_get_float32_auto(buffer, &ind);
conf->sl_cycle_int_limit = buffer_get_float32_auto(buffer, &ind);
conf->sl_phase_advance_at_br = buffer_get_float32_auto(buffer, &ind);
conf->sl_cycle_int_rpm_br = buffer_get_float32_auto(buffer, &ind);
conf->sl_bemf_coupling_k = buffer_get_float32_auto(buffer, &ind);
conf->hall_table[0] = (int8_t)buffer[ind++];
conf->hall_table[1] = (int8_t)buffer[ind++];
conf->hall_table[2] = (int8_t)buffer[ind++];
conf->hall_table[3] = (int8_t)buffer[ind++];
conf->hall_table[4] = (int8_t)buffer[ind++];
conf->hall_table[5] = (int8_t)buffer[ind++];
conf->hall_table[6] = (int8_t)buffer[ind++];
conf->hall_table[7] = (int8_t)buffer[ind++];
conf->hall_sl_erpm = buffer_get_float32_auto(buffer, &ind);
conf->foc_current_kp = buffer_get_float32_auto(buffer, &ind);
conf->foc_current_ki = buffer_get_float32_auto(buffer, &ind);
conf->foc_f_sw = buffer_get_float32_auto(buffer, &ind);
conf->foc_dt_us = buffer_get_float32_auto(buffer, &ind);
conf->foc_encoder_inverted = buffer[ind++];
conf->foc_encoder_offset = buffer_get_float32_auto(buffer, &ind);
conf->foc_encoder_ratio = buffer_get_float32_auto(buffer, &ind);
conf->foc_sensor_mode = buffer[ind++];
conf->foc_pll_kp = buffer_get_float32_auto(buffer, &ind);
conf->foc_pll_ki = buffer_get_float32_auto(buffer, &ind);
conf->foc_motor_l = buffer_get_float32_auto(buffer, &ind);
conf->foc_motor_r = buffer_get_float32_auto(buffer, &ind);
conf->foc_motor_flux_linkage = buffer_get_float32_auto(buffer, &ind);
conf->foc_observer_gain = buffer_get_float32_auto(buffer, &ind);
conf->foc_observer_gain_slow = buffer_get_float32_auto(buffer, &ind);
conf->foc_duty_dowmramp_kp = buffer_get_float32_auto(buffer, &ind);
conf->foc_duty_dowmramp_ki = buffer_get_float32_auto(buffer, &ind);
conf->foc_openloop_rpm = buffer_get_float32_auto(buffer, &ind);
conf->foc_sl_openloop_hyst = buffer_get_float32_auto(buffer, &ind);
conf->foc_sl_openloop_time = buffer_get_float32_auto(buffer, &ind);
conf->foc_sl_d_current_duty = buffer_get_float32_auto(buffer, &ind);
conf->foc_sl_d_current_factor = buffer_get_float32_auto(buffer, &ind);
conf->foc_hall_table[0] = buffer[ind++];
conf->foc_hall_table[1] = buffer[ind++];
conf->foc_hall_table[2] = buffer[ind++];
conf->foc_hall_table[3] = buffer[ind++];
conf->foc_hall_table[4] = buffer[ind++];
conf->foc_hall_table[5] = buffer[ind++];
conf->foc_hall_table[6] = buffer[ind++];
conf->foc_hall_table[7] = buffer[ind++];
conf->foc_sl_erpm = buffer_get_float32_auto(buffer, &ind);
conf->foc_sample_v0_v7 = buffer[ind++];
conf->foc_sample_high_current = buffer[ind++];
conf->foc_sat_comp = buffer_get_float32_auto(buffer, &ind);
conf->foc_temp_comp = buffer[ind++];
conf->foc_temp_comp_base_temp = buffer_get_float32_auto(buffer, &ind);
conf->foc_current_filter_const = buffer_get_float32_auto(buffer, &ind);
conf->gpd_buffer_notify_left = buffer_get_int16(buffer, &ind);
conf->gpd_buffer_interpol = buffer_get_int16(buffer, &ind);
conf->gpd_current_filter_const = buffer_get_float32_auto(buffer, &ind);
conf->gpd_current_kp = buffer_get_float32_auto(buffer, &ind);
conf->gpd_current_ki = 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_kd = buffer_get_float32_auto(buffer, &ind);
conf->s_pid_kd_filter = buffer_get_float32_auto(buffer, &ind);
conf->s_pid_min_erpm = buffer_get_float32_auto(buffer, &ind);
conf->s_pid_allow_braking = buffer[ind++];
conf->p_pid_kp = buffer_get_float32_auto(buffer, &ind);
conf->p_pid_ki = buffer_get_float32_auto(buffer, &ind);
conf->p_pid_kd = buffer_get_float32_auto(buffer, &ind);
conf->p_pid_kd_filter = buffer_get_float32_auto(buffer, &ind);
conf->p_pid_ang_div = buffer_get_float32_auto(buffer, &ind);
conf->cc_startup_boost_duty = buffer_get_float32_auto(buffer, &ind);
conf->cc_min_current = buffer_get_float32_auto(buffer, &ind);
conf->cc_gain = buffer_get_float32_auto(buffer, &ind);
conf->cc_ramp_step_max = buffer_get_float32_auto(buffer, &ind);
conf->m_fault_stop_time_ms = buffer_get_int32(buffer, &ind);
conf->m_duty_ramp_step = buffer_get_float32_auto(buffer, &ind);
conf->m_current_backoff_gain = buffer_get_float32_auto(buffer, &ind);
conf->m_encoder_counts = buffer_get_uint32(buffer, &ind);
conf->m_sensor_port_mode = buffer[ind++];
conf->m_invert_direction = buffer[ind++];
conf->m_drv8301_oc_mode = buffer[ind++];
conf->m_drv8301_oc_adj = buffer[ind++];
conf->m_bldc_f_sw_min = buffer_get_float32_auto(buffer, &ind);
conf->m_bldc_f_sw_max = buffer_get_float32_auto(buffer, &ind);
conf->m_dc_f_sw = buffer_get_float32_auto(buffer, &ind);
conf->m_ntc_motor_beta = buffer_get_float32_auto(buffer, &ind);
conf->m_out_aux_mode = buffer[ind++];
conf->si_motor_poles = buffer[ind++];
conf->si_gear_ratio = buffer_get_float32_auto(buffer, &ind);
conf->si_wheel_diameter = buffer_get_float32_auto(buffer, &ind);
conf->si_battery_type = buffer[ind++];
conf->si_battery_cells = buffer[ind++];
conf->si_battery_ah = buffer_get_float32_auto(buffer, &ind);
return true;
}
bool confgenerator_deserialize_appconf(const uint8_t *buffer, app_configuration *conf) {
int32_t ind = 0;
uint32_t signature = buffer_get_uint32(buffer, &ind);
if (signature != APPCONF_SIGNATURE) {
return false;
}
conf->controller_id = buffer[ind++];
conf->timeout_msec = buffer_get_uint32(buffer, &ind);
conf->timeout_brake_current = buffer_get_float32_auto(buffer, &ind);
conf->send_can_status = buffer[ind++];
conf->send_can_status_rate_hz = buffer_get_uint16(buffer, &ind);
conf->can_baud_rate = buffer[ind++];
conf->pairing_done = buffer[ind++];
conf->uavcan_enable = buffer[ind++];
conf->uavcan_esc_index = buffer[ind++];
conf->app_to_use = buffer[ind++];
conf->app_ppm_conf.ctrl_type = buffer[ind++];
conf->app_ppm_conf.pid_max_erpm = buffer_get_float32_auto(buffer, &ind);
conf->app_ppm_conf.hyst = buffer_get_float32_auto(buffer, &ind);
conf->app_ppm_conf.pulse_start = buffer_get_float32_auto(buffer, &ind);
conf->app_ppm_conf.pulse_end = buffer_get_float32_auto(buffer, &ind);
conf->app_ppm_conf.pulse_center = buffer_get_float32_auto(buffer, &ind);
conf->app_ppm_conf.median_filter = buffer[ind++];
conf->app_ppm_conf.safe_start = buffer[ind++];
conf->app_ppm_conf.throttle_exp = buffer_get_float32_auto(buffer, &ind);
conf->app_ppm_conf.throttle_exp_brake = buffer_get_float32_auto(buffer, &ind);
conf->app_ppm_conf.throttle_exp_mode = buffer[ind++];
conf->app_ppm_conf.ramp_time_pos = buffer_get_float32_auto(buffer, &ind);
conf->app_ppm_conf.ramp_time_neg = buffer_get_float32_auto(buffer, &ind);
conf->app_ppm_conf.multi_esc = buffer[ind++];
conf->app_ppm_conf.tc = buffer[ind++];
conf->app_ppm_conf.tc_max_diff = buffer_get_float32_auto(buffer, &ind);
conf->app_adc_conf.ctrl_type = buffer[ind++];
conf->app_adc_conf.hyst = buffer_get_float32_auto(buffer, &ind);
conf->app_adc_conf.voltage_start = buffer_get_float32_auto(buffer, &ind);
conf->app_adc_conf.voltage_end = buffer_get_float32_auto(buffer, &ind);
conf->app_adc_conf.voltage_center = buffer_get_float32_auto(buffer, &ind);
conf->app_adc_conf.voltage2_start = buffer_get_float32_auto(buffer, &ind);
conf->app_adc_conf.voltage2_end = buffer_get_float32_auto(buffer, &ind);
conf->app_adc_conf.use_filter = buffer[ind++];
conf->app_adc_conf.safe_start = buffer[ind++];
conf->app_adc_conf.cc_button_inverted = buffer[ind++];
conf->app_adc_conf.rev_button_inverted = buffer[ind++];
conf->app_adc_conf.voltage_inverted = buffer[ind++];
conf->app_adc_conf.voltage2_inverted = buffer[ind++];
conf->app_adc_conf.throttle_exp = buffer_get_float32_auto(buffer, &ind);
conf->app_adc_conf.throttle_exp_brake = buffer_get_float32_auto(buffer, &ind);
conf->app_adc_conf.throttle_exp_mode = buffer[ind++];
conf->app_adc_conf.ramp_time_pos = buffer_get_float32_auto(buffer, &ind);
conf->app_adc_conf.ramp_time_neg = buffer_get_float32_auto(buffer, &ind);
conf->app_adc_conf.multi_esc = buffer[ind++];
conf->app_adc_conf.tc = buffer[ind++];
conf->app_adc_conf.tc_max_diff = buffer_get_float32_auto(buffer, &ind);
conf->app_adc_conf.update_rate_hz = buffer_get_uint16(buffer, &ind);
conf->app_uart_baudrate = buffer_get_uint32(buffer, &ind);
conf->app_chuk_conf.ctrl_type = buffer[ind++];
conf->app_chuk_conf.hyst = buffer_get_float32_auto(buffer, &ind);
conf->app_chuk_conf.ramp_time_pos = buffer_get_float32_auto(buffer, &ind);
conf->app_chuk_conf.ramp_time_neg = buffer_get_float32_auto(buffer, &ind);
conf->app_chuk_conf.stick_erpm_per_s_in_cc = buffer_get_float32_auto(buffer, &ind);
conf->app_chuk_conf.throttle_exp = buffer_get_float32_auto(buffer, &ind);
conf->app_chuk_conf.throttle_exp_brake = buffer_get_float32_auto(buffer, &ind);
conf->app_chuk_conf.throttle_exp_mode = buffer[ind++];
conf->app_chuk_conf.multi_esc = buffer[ind++];
conf->app_chuk_conf.tc = buffer[ind++];
conf->app_chuk_conf.tc_max_diff = buffer_get_float32_auto(buffer, &ind);
conf->app_nrf_conf.speed = buffer[ind++];
conf->app_nrf_conf.power = buffer[ind++];
conf->app_nrf_conf.crc_type = buffer[ind++];
conf->app_nrf_conf.retry_delay = buffer[ind++];
conf->app_nrf_conf.retries = (int8_t)buffer[ind++];
conf->app_nrf_conf.channel = (int8_t)buffer[ind++];
conf->app_nrf_conf.address[0] = buffer[ind++];
conf->app_nrf_conf.address[1] = buffer[ind++];
conf->app_nrf_conf.address[2] = buffer[ind++];
conf->app_nrf_conf.send_crc_ack = buffer[ind++];
return true;
}
void confgenerator_set_defaults_mcconf(mc_configuration *conf) {
conf->pwm_mode = MCCONF_PWM_MODE;
conf->comm_mode = MCCONF_COMM_MODE;
conf->motor_type = MCCONF_DEFAULT_MOTOR_TYPE;
conf->sensor_mode = MCCONF_SENSOR_MODE;
conf->l_current_max = MCCONF_L_CURRENT_MAX;
conf->l_current_min = MCCONF_L_CURRENT_MIN;
conf->l_in_current_max = MCCONF_L_IN_CURRENT_MAX;
conf->l_in_current_min = MCCONF_L_IN_CURRENT_MIN;
conf->l_abs_current_max = MCCONF_L_MAX_ABS_CURRENT;
conf->l_min_erpm = MCCONF_L_RPM_MIN;
conf->l_max_erpm = MCCONF_L_RPM_MAX;
conf->l_erpm_start = MCCONF_L_RPM_START;
conf->l_max_erpm_fbrake = MCCONF_L_CURR_MAX_RPM_FBRAKE;
conf->l_max_erpm_fbrake_cc = MCCONF_L_CURR_MAX_RPM_FBRAKE_CC;
conf->l_min_vin = MCCONF_L_MIN_VOLTAGE;
conf->l_max_vin = MCCONF_L_MAX_VOLTAGE;
conf->l_battery_cut_start = MCCONF_L_BATTERY_CUT_START;
conf->l_battery_cut_end = MCCONF_L_BATTERY_CUT_END;
conf->l_slow_abs_current = MCCONF_L_SLOW_ABS_OVERCURRENT;
conf->l_temp_fet_start = MCCONF_L_LIM_TEMP_FET_START;
conf->l_temp_fet_end = MCCONF_L_LIM_TEMP_FET_END;
conf->l_temp_motor_start = MCCONF_L_LIM_TEMP_MOTOR_START;
conf->l_temp_motor_end = MCCONF_L_LIM_TEMP_MOTOR_END;
conf->l_temp_accel_dec = MCCONF_L_LIM_TEMP_ACCEL_DEC;
conf->l_min_duty = MCCONF_L_MIN_DUTY;
conf->l_max_duty = MCCONF_L_MAX_DUTY;
conf->l_watt_max = MCCONF_L_WATT_MAX;
conf->l_watt_min = MCCONF_L_WATT_MIN;
conf->l_current_max_scale = MCCONF_L_CURRENT_MAX_SCALE;
conf->l_current_min_scale = MCCONF_L_CURRENT_MIN_SCALE;
conf->sl_min_erpm = MCCONF_SL_MIN_RPM;
conf->sl_min_erpm_cycle_int_limit = MCCONF_SL_MIN_ERPM_CYCLE_INT_LIMIT;
conf->sl_max_fullbreak_current_dir_change = MCCONF_SL_MAX_FB_CURR_DIR_CHANGE;
conf->sl_cycle_int_limit = MCCONF_SL_CYCLE_INT_LIMIT;
conf->sl_phase_advance_at_br = MCCONF_SL_PHASE_ADVANCE_AT_BR;
conf->sl_cycle_int_rpm_br = MCCONF_SL_CYCLE_INT_BR;
conf->sl_bemf_coupling_k = MCCONF_SL_BEMF_COUPLING_K;
conf->hall_table[0] = MCCONF_HALL_TAB_0;
conf->hall_table[1] = MCCONF_HALL_TAB_1;
conf->hall_table[2] = MCCONF_HALL_TAB_2;
conf->hall_table[3] = MCCONF_HALL_TAB_3;
conf->hall_table[4] = MCCONF_HALL_TAB_4;
conf->hall_table[5] = MCCONF_HALL_TAB_5;
conf->hall_table[6] = MCCONF_HALL_TAB_6;
conf->hall_table[7] = MCCONF_HALL_TAB_7;
conf->hall_sl_erpm = MCCONF_HALL_ERPM;
conf->foc_current_kp = MCCONF_FOC_CURRENT_KP;
conf->foc_current_ki = MCCONF_FOC_CURRENT_KI;
conf->foc_f_sw = MCCONF_FOC_F_SW;
conf->foc_dt_us = MCCONF_FOC_DT_US;
conf->foc_encoder_inverted = MCCONF_FOC_ENCODER_INVERTED;
conf->foc_encoder_offset = MCCONF_FOC_ENCODER_OFFSET;
conf->foc_encoder_ratio = MCCONF_FOC_ENCODER_RATIO;
conf->foc_sensor_mode = MCCONF_FOC_SENSOR_MODE;
conf->foc_pll_kp = MCCONF_FOC_PLL_KP;
conf->foc_pll_ki = MCCONF_FOC_PLL_KI;
conf->foc_motor_l = MCCONF_FOC_MOTOR_L;
conf->foc_motor_r = MCCONF_FOC_MOTOR_R;
conf->foc_motor_flux_linkage = MCCONF_FOC_MOTOR_FLUX_LINKAGE;
conf->foc_observer_gain = MCCONF_FOC_OBSERVER_GAIN;
conf->foc_observer_gain_slow = MCCONF_FOC_OBSERVER_GAIN_SLOW;
conf->foc_duty_dowmramp_kp = MCCONF_FOC_DUTY_DOWNRAMP_KP;
conf->foc_duty_dowmramp_ki = MCCONF_FOC_DUTY_DOWNRAMP_KI;
conf->foc_openloop_rpm = MCCONF_FOC_OPENLOOP_RPM;
conf->foc_sl_openloop_hyst = MCCONF_FOC_SL_OPENLOOP_HYST;
conf->foc_sl_openloop_time = MCCONF_FOC_SL_OPENLOOP_TIME;
conf->foc_sl_d_current_duty = MCCONF_FOC_SL_D_CURRENT_DUTY;
conf->foc_sl_d_current_factor = MCCONF_FOC_SL_D_CURRENT_FACTOR;
conf->foc_hall_table[0] = MCCONF_FOC_HALL_TAB_0;
conf->foc_hall_table[1] = MCCONF_FOC_HALL_TAB_1;
conf->foc_hall_table[2] = MCCONF_FOC_HALL_TAB_2;
conf->foc_hall_table[3] = MCCONF_FOC_HALL_TAB_3;
conf->foc_hall_table[4] = MCCONF_FOC_HALL_TAB_4;
conf->foc_hall_table[5] = MCCONF_FOC_HALL_TAB_5;
conf->foc_hall_table[6] = MCCONF_FOC_HALL_TAB_6;
conf->foc_hall_table[7] = MCCONF_FOC_HALL_TAB_7;
conf->foc_sl_erpm = MCCONF_FOC_SL_ERPM;
conf->foc_sample_v0_v7 = MCCONF_FOC_SAMPLE_V0_V7;
conf->foc_sample_high_current = MCCONF_FOC_SAMPLE_HIGH_CURRENT;
conf->foc_sat_comp = MCCONF_FOC_SAT_COMP;
conf->foc_temp_comp = MCCONF_FOC_TEMP_COMP;
conf->foc_temp_comp_base_temp = MCCONF_FOC_TEMP_COMP_BASE_TEMP;
conf->foc_current_filter_const = MCCONF_FOC_CURRENT_FILTER_CONST;
conf->gpd_buffer_notify_left = MCCONF_GPD_BUFFER_NOTIFY_LEFT;
conf->gpd_buffer_interpol = MCCONF_GPD_BUFFER_INTERPOL;
conf->gpd_current_filter_const = MCCONF_GPD_CURRENT_FILTER_CONST;
conf->gpd_current_kp = MCCONF_GPD_CURRENT_KP;
conf->gpd_current_ki = MCCONF_GPD_CURRENT_KI;
conf->s_pid_kp = MCCONF_S_PID_KP;
conf->s_pid_ki = MCCONF_S_PID_KI;
conf->s_pid_kd = MCCONF_S_PID_KD;
conf->s_pid_kd_filter = MCCONF_S_PID_KD_FILTER;
conf->s_pid_min_erpm = MCCONF_S_PID_MIN_RPM;
conf->s_pid_allow_braking = MCCONF_S_PID_ALLOW_BRAKING;
conf->p_pid_kp = MCCONF_P_PID_KP;
conf->p_pid_ki = MCCONF_P_PID_KI;
conf->p_pid_kd = MCCONF_P_PID_KD;
conf->p_pid_kd_filter = MCCONF_P_PID_KD_FILTER;
conf->p_pid_ang_div = MCCONF_P_PID_ANG_DIV;
conf->cc_startup_boost_duty = MCCONF_CC_STARTUP_BOOST_DUTY;
conf->cc_min_current = MCCONF_CC_MIN_CURRENT;
conf->cc_gain = MCCONF_CC_GAIN;
conf->cc_ramp_step_max = MCCONF_CC_RAMP_STEP;
conf->m_fault_stop_time_ms = MCCONF_M_FAULT_STOP_TIME;
conf->m_duty_ramp_step = MCCONF_M_RAMP_STEP;
conf->m_current_backoff_gain = MCCONF_M_CURRENT_BACKOFF_GAIN;
conf->m_encoder_counts = MCCONF_M_ENCODER_COUNTS;
conf->m_sensor_port_mode = MCCONF_M_SENSOR_PORT_MODE;
conf->m_invert_direction = MCCONF_M_INVERT_DIRECTION;
conf->m_drv8301_oc_mode = MCCONF_M_DRV8301_OC_MODE;
conf->m_drv8301_oc_adj = MCCONF_M_DRV8301_OC_ADJ;
conf->m_bldc_f_sw_min = MCCONF_M_BLDC_F_SW_MIN;
conf->m_bldc_f_sw_max = MCCONF_M_BLDC_F_SW_MAX;
conf->m_dc_f_sw = MCCONF_M_DC_F_SW;
conf->m_ntc_motor_beta = MCCONF_M_NTC_MOTOR_BETA;
conf->m_out_aux_mode = MCCONF_M_OUT_AUX_MODE;
conf->si_motor_poles = MCCONF_SI_MOTOR_POLES;
conf->si_gear_ratio = MCCONF_SI_GEAR_RATIO;
conf->si_wheel_diameter = MCCONF_SI_WHEEL_DIAMETER;
conf->si_battery_type = MCCONF_SI_BATTERY_TYPE;
conf->si_battery_cells = MCCONF_SI_BATTERY_CELLS;
conf->si_battery_ah = MCCONF_SI_BATTERY_AH;
}
void confgenerator_set_defaults_appconf(app_configuration *conf) {
conf->controller_id = HW_DEFAULT_ID;
conf->timeout_msec = APPCONF_TIMEOUT_MSEC;
conf->timeout_brake_current = APPCONF_TIMEOUT_BRAKE_CURRENT;
conf->send_can_status = APPCONF_SEND_CAN_STATUS;
conf->send_can_status_rate_hz = APPCONF_SEND_CAN_STATUS_RATE_HZ;
conf->can_baud_rate = APPCONF_CAN_BAUD_RATE;
conf->pairing_done = APPCONF_PAIRING_DONE;
conf->uavcan_enable = APPCONF_UAVCAN_ENABLE;
conf->uavcan_esc_index = APPCONF_UAVCAN_ESC_INDEX;
conf->app_to_use = APPCONF_APP_TO_USE;
conf->app_ppm_conf.ctrl_type = APPCONF_PPM_CTRL_TYPE;
conf->app_ppm_conf.pid_max_erpm = APPCONF_PPM_PID_MAX_ERPM;
conf->app_ppm_conf.hyst = APPCONF_PPM_HYST;
conf->app_ppm_conf.pulse_start = APPCONF_PPM_PULSE_START;
conf->app_ppm_conf.pulse_end = APPCONF_PPM_PULSE_END;
conf->app_ppm_conf.pulse_center = APPCONF_PPM_PULSE_CENTER;
conf->app_ppm_conf.median_filter = APPCONF_PPM_MEDIAN_FILTER;
conf->app_ppm_conf.safe_start = APPCONF_PPM_SAFE_START;
conf->app_ppm_conf.throttle_exp = APPCONF_PPM_THROTTLE_EXP;
conf->app_ppm_conf.throttle_exp_brake = APPCONF_PPM_THROTTLE_EXP_BRAKE;
conf->app_ppm_conf.throttle_exp_mode = APPCONF_PPM_THROTTLE_EXP_MODE;
conf->app_ppm_conf.ramp_time_pos = APPCONF_PPM_RAMP_TIME_POS;
conf->app_ppm_conf.ramp_time_neg = APPCONF_PPM_RAMP_TIME_NEG;
conf->app_ppm_conf.multi_esc = APPCONF_PPM_MULTI_ESC;
conf->app_ppm_conf.tc = APPCONF_PPM_TC;
conf->app_ppm_conf.tc_max_diff = APPCONF_PPM_TC_MAX_DIFF;
conf->app_adc_conf.ctrl_type = APPCONF_ADC_CTRL_TYPE;
conf->app_adc_conf.hyst = APPCONF_ADC_HYST;
conf->app_adc_conf.voltage_start = APPCONF_ADC_VOLTAGE_START;
conf->app_adc_conf.voltage_end = APPCONF_ADC_VOLTAGE_END;
conf->app_adc_conf.voltage_center = APPCONF_ADC_VOLTAGE_CENTER;
conf->app_adc_conf.voltage2_start = APPCONF_ADC_VOLTAGE2_START;
conf->app_adc_conf.voltage2_end = APPCONF_ADC_VOLTAGE2_END;
conf->app_adc_conf.use_filter = APPCONF_ADC_USE_FILTER;
conf->app_adc_conf.safe_start = APPCONF_ADC_SAFE_START;
conf->app_adc_conf.cc_button_inverted = APPCONF_ADC_CC_BUTTON_INVERTED;
conf->app_adc_conf.rev_button_inverted = APPCONF_ADC_REV_BUTTON_INVERTED;
conf->app_adc_conf.voltage_inverted = APPCONF_ADC_VOLTAGE_INVERTED;
conf->app_adc_conf.voltage2_inverted = APPCONF_ADC_VOLTAGE2_INVERTED;
conf->app_adc_conf.throttle_exp = APPCONF_ADC_THROTTLE_EXP;
conf->app_adc_conf.throttle_exp_brake = APPCONF_ADC_THROTTLE_EXP_BRAKE;
conf->app_adc_conf.throttle_exp_mode = APPCONF_ADC_THROTTLE_EXP_MODE;
conf->app_adc_conf.ramp_time_pos = APPCONF_ADC_RAMP_TIME_POS;
conf->app_adc_conf.ramp_time_neg = APPCONF_ADC_RAMP_TIME_NEG;
conf->app_adc_conf.multi_esc = APPCONF_ADC_MULTI_ESC;
conf->app_adc_conf.tc = APPCONF_ADC_TC;
conf->app_adc_conf.tc_max_diff = APPCONF_ADC_TC_MAX_DIFF;
conf->app_adc_conf.update_rate_hz = APPCONF_ADC_UPDATE_RATE_HZ;
conf->app_uart_baudrate = APPCONF_UART_BAUDRATE;
conf->app_chuk_conf.ctrl_type = APPCONF_CHUK_CTRL_TYPE;
conf->app_chuk_conf.hyst = APPCONF_CHUK_HYST;
conf->app_chuk_conf.ramp_time_pos = APPCONF_CHUK_RAMP_TIME_POS;
conf->app_chuk_conf.ramp_time_neg = APPCONF_CHUK_RAMP_TIME_NEG;
conf->app_chuk_conf.stick_erpm_per_s_in_cc = APPCONF_STICK_ERPM_PER_S_IN_CC;
conf->app_chuk_conf.throttle_exp = APPCONF_CHUK_THROTTLE_EXP;
conf->app_chuk_conf.throttle_exp_brake = APPCONF_CHUK_THROTTLE_EXP_BRAKE;
conf->app_chuk_conf.throttle_exp_mode = APPCONF_CHUK_THROTTLE_EXP_MODE;
conf->app_chuk_conf.multi_esc = APPCONF_CHUK_MULTI_ESC;
conf->app_chuk_conf.tc = APPCONF_CHUK_TC;
conf->app_chuk_conf.tc_max_diff = APPCONF_CHUK_TC_MAX_DIFF;
conf->app_nrf_conf.speed = APPCONF_NRF_SPEED;
conf->app_nrf_conf.power = APPCONF_NRF_POWER;
conf->app_nrf_conf.crc_type = APPCONF_NRF_CRC;
conf->app_nrf_conf.retry_delay = APPCONF_NRF_RETR_DELAY;
conf->app_nrf_conf.retries = APPCONF_NRF_RETRIES;
conf->app_nrf_conf.channel = APPCONF_NRF_CHANNEL;
conf->app_nrf_conf.address[0] = APPCONF_NRF_ADDR_B0;
conf->app_nrf_conf.address[1] = APPCONF_NRF_ADDR_B1;
conf->app_nrf_conf.address[2] = APPCONF_NRF_ADDR_B2;
conf->app_nrf_conf.send_crc_ack = APPCONF_NRF_SEND_CRC_ACK;
}

25
confgenerator.h Normal file
View File

@ -0,0 +1,25 @@
// This file is autogenerated by VESC Tool
#ifndef CONFGENERATOR_H_
#define CONFGENERATOR_H_
#include "datatypes.h"
#include <stdint.h>
#include <stdbool.h>
// Constants
#define MCCONF_SIGNATURE 1753222668
#define APPCONF_SIGNATURE 3794395266
// Functions
int32_t confgenerator_serialize_mcconf(uint8_t *buffer, const mc_configuration *conf);
int32_t confgenerator_serialize_appconf(uint8_t *buffer, const app_configuration *conf);
bool confgenerator_deserialize_mcconf(const uint8_t *buffer, mc_configuration *conf);
bool confgenerator_deserialize_appconf(const uint8_t *buffer, app_configuration *conf);
void confgenerator_set_defaults_mcconf(mc_configuration *conf);
void confgenerator_set_defaults_appconf(app_configuration *conf);
// CONFGENERATOR_H_
#endif

View File

@ -86,15 +86,15 @@ static void spi_delay(void);
uint32_t encoder_spi_get_error_cnt(void) {
return spi_error_cnt;
return spi_error_cnt;
}
uint16_t encoder_spi_get_val(void) {
return spi_val;
return spi_val;
}
float encoder_spi_get_error_rate(void) {
return spi_error_rate;
return spi_error_rate;
}
@ -114,7 +114,7 @@ void encoder_deinit(void) {
index_found = false;
mode = ENCODER_MODE_NONE;
last_enc_angle = 0.0;
spi_error_rate = 0.0;
spi_error_rate = 0.0;
}
void encoder_init_abi(uint32_t counts) {
@ -313,13 +313,12 @@ void encoder_reset(void) {
}
// returns true for even number of ones (no parity error according to AS5047 datasheet
bool spi_check_parity(uint16_t x)
{
x ^= x >> 8;
x ^= x >> 4;
x ^= x >> 2;
x ^= x >> 1;
return (~x) & 1;
bool spi_check_parity(uint16_t x) {
x ^= x >> 8;
x ^= x >> 4;
x ^= x >> 2;
x ^= x >> 1;
return (~x) & 1;
}
/**

View File

@ -90,7 +90,6 @@ uint16_t flash_helper_erase_new_app(uint32_t new_app_size) {
mc_interface_unlock();
mc_interface_release_motor();
utils_sys_lock_cnt();
RCC_APB1PeriphClockCmd(RCC_APB1Periph_WWDG, DISABLE);
timeout_configure_IWDT_slowest();
for (int i = 0;i < NEW_APP_SECTORS;i++) {
@ -104,7 +103,6 @@ uint16_t flash_helper_erase_new_app(uint32_t new_app_size) {
}
}
RCC_APB1PeriphClockCmd(RCC_APB1Periph_WWDG, ENABLE);
timeout_configure_IWDT();
utils_sys_unlock_cnt();
@ -118,7 +116,6 @@ uint16_t flash_helper_write_new_app_data(uint32_t offset, uint8_t *data, uint32_
mc_interface_unlock();
mc_interface_release_motor();
utils_sys_lock_cnt();
RCC_APB1PeriphClockCmd(RCC_APB1Periph_WWDG, DISABLE);
timeout_configure_IWDT_slowest();
for (uint32_t i = 0;i < len;i++) {
@ -128,7 +125,6 @@ uint16_t flash_helper_write_new_app_data(uint32_t offset, uint8_t *data, uint32_
}
}
RCC_APB1PeriphClockCmd(RCC_APB1Periph_WWDG, ENABLE);
timeout_configure_IWDT();
utils_sys_unlock_cnt();
@ -152,7 +148,6 @@ void flash_helper_jump_to_bootloader(void) {
palSetPadMode(HW_UART_RX_PORT, HW_UART_RX_PIN, PAL_MODE_INPUT);
// Disable watchdog
RCC_APB1PeriphClockCmd(RCC_APB1Periph_WWDG, DISABLE);
timeout_configure_IWDT_slowest();
chSysDisable();

View File

@ -257,14 +257,13 @@ void gpdrive_init(volatile mc_configuration *configuration) {
timer_thd_stop = false;
chThdCreateStatic(timer_thread_wa, sizeof(timer_thread_wa), NORMALPRIO, timer_thread, NULL);
// WWDG
RCC_APB1PeriphClockCmd(RCC_APB1Periph_WWDG, ENABLE);
WWDG_SetPrescaler(WWDG_Prescaler_1);
WWDG_SetWindowValue(255);
WWDG_Enable(100);
stop_pwm_hw();
// Check if the system has resumed from IWDG reset
if (timeout_had_IWDG_reset()) {
mc_interface_fault_stop(FAULT_CODE_BOOTING_FROM_WATCHDOG_RESET);
}
m_init_done = true;
}
@ -275,8 +274,6 @@ void gpdrive_deinit(void) {
m_init_done = false;
WWDG_DeInit();
timer_thd_stop = true;
while (timer_thd_stop) {
@ -514,7 +511,7 @@ static void adc_int_handler(void *p, uint32_t flags) {
TIM12->CNT = 0;
// Reset the watchdog
WWDG_SetCounter(100);
timeout_feed_WDT(THREAD_MCPWM);
int curr0 = GET_CURRENT1();
int curr1 = GET_CURRENT2();

View File

@ -166,6 +166,10 @@
#define HW_LIM_CURRENT_ABS 0.0, 140.0
#endif
#ifndef HW_LIM_FOC_CTRL_LOOP_FREQ
#define HW_LIM_FOC_CTRL_LOOP_FREQ 3000.0, 30000.0
#endif
// Functions
void hw_init_gpio(void);
void hw_setup_adc_channels(void);

View File

@ -350,6 +350,7 @@ const char* mc_interface_fault_to_string(mc_fault_code fault) {
case FAULT_CODE_GATE_DRIVER_UNDER_VOLTAGE: return "FAULT_CODE_GATE_DRIVER_UNDER_VOLTAGE"; break;
case FAULT_CODE_MCU_UNDER_VOLTAGE: return "FAULT_CODE_MCU_UNDER_VOLTAGE"; break;
case FAULT_CODE_BOOTING_FROM_WATCHDOG_RESET: return "FAULT_CODE_BOOTING_FROM_WATCHDOG_RESET"; break;
case FAULT_CODE_ENCODER: return "FAULT_CODE_ENCODER"; break;
default: return "FAULT_UNKNOWN"; break;
}
}

View File

@ -376,7 +376,7 @@
#define MCCONF_M_BLDC_F_SW_MIN 3000 // Minimum switching frequency in bldc mode
#endif
#ifndef MCCONF_M_BLDC_F_SW_MAX
#define MCCONF_M_BLDC_F_SW_MAX 40000 // Maximum switching frequency in bldc mode
#define MCCONF_M_BLDC_F_SW_MAX 35000 // Maximum switching frequency in bldc mode
#endif
#ifndef MCCONF_M_DC_F_SW
#define MCCONF_M_DC_F_SW 25000 // Switching frequency in dc mode

View File

@ -470,8 +470,9 @@ void mcpwm_init(volatile mc_configuration *configuration) {
chThdCreateStatic(rpm_thread_wa, sizeof(rpm_thread_wa), NORMALPRIO, rpm_thread, NULL);
// Check if the system has resumed from IWDG reset
if (timeout_had_IWDG_reset())
if (timeout_had_IWDG_reset()) {
mc_interface_fault_stop(FAULT_CODE_BOOTING_FROM_WATCHDOG_RESET);
}
// Reset tachometers again
tachometer = 0;
@ -487,8 +488,6 @@ void mcpwm_deinit(void) {
init_done = false;
WWDG_DeInit();
timer_thd_stop = true;
rpm_thd_stop = true;

View File

@ -463,8 +463,6 @@ void mcpwm_foc_deinit(void) {
m_init_done = false;
WWDG_DeInit();
timer_thd_stop = true;
while (timer_thd_stop) {

View File

@ -639,9 +639,10 @@ void terminal_process_string(char *str) {
commands_printf("This command requires one argument.\n");
}
} else if (strcmp(argv[0], "encoder") == 0) {
commands_printf("SPI val:%x, errors:%d, rate:%.5f", (unsigned int)encoder_spi_get_val(),
encoder_spi_get_error_cnt(),
(double)encoder_spi_get_error_rate());
commands_printf("SPI val: %x, errors: %d, error rate: %.3f %%",
(unsigned int)encoder_spi_get_val(),
encoder_spi_get_error_cnt(),
(double)encoder_spi_get_error_rate() * (double)100.0);
}
// The help command

View File

@ -32,25 +32,42 @@ static volatile uint32_t feed_counter[MAX_THREADS_MONITOR];
static THD_WORKING_AREA(timeout_thread_wa, 512);
static THD_FUNCTION(timeout_thread, arg);
void timeout_init_IWDT(void);
void timeout_init(void) {
timeout_msec = 1000;
last_update_time = 0;
timeout_brake_current = 0.0;
has_timeout = false;
// WWDG configuration
RCC_APB1PeriphClockCmd(RCC_APB1Periph_WWDG, ENABLE);
// Timeout = t_PCLK1 (ms) * 4096 * 2^(WDGTB [1:0]) * (T[5:0] + 1)
// CLK1 = 42MHz
IWDG_WriteAccessCmd(IWDG_WriteAccess_Enable);
// Window set between 6.24ms and 12.48ms. Mcu will reset if watchdog is fed outside the window
WWDG_SetPrescaler(WWDG_Prescaler_2);
WWDG_SetWindowValue(127);
WWDG_Enable(127); //0x7F
// IWDG counter clock: LSI/4
IWDG_SetPrescaler(IWDG_Prescaler_4);
timeout_init_IWDT();
/* Set counter reload value to obtain 12ms IWDG TimeOut.
*
* LSI timer per datasheet is 32KHz typical, but 17KHz min
* and 47KHz max over the complete range of operating conditions,
* so reload time must ensure watchdog will work correctly under
* all conditions.
*
* Timeout threads runs every 10ms. Take 20% margin so wdt should
* be fed every 12ms. The worst condition occurs when the wdt clock
* runs at the max freq (47KHz) due to oscillator tolerances.
*
* t_IWDG(ms) = t_LSI(ms) * 4 * 2^(IWDG_PR[2:0]) * (IWDG_RLR[11:0] + 1)
* t_LSI(ms) [MAX] = 0.021276ms
* 12ms = 0.0212765 * 4 * 1 * (140 + 1)
*
* Counter Reload Value = 140
*
* When LSI clock runs the slowest, the IWDG will expire every 33.17ms
*/
IWDG_SetReload(140);
IWDG_ReloadCounter();
/* Enable IWDG (the LSI oscillator will be enabled by hardware) */
IWDG_Enable();
chThdSleepMilliseconds(10);
@ -82,40 +99,6 @@ void timeout_feed_WDT(uint8_t index) {
++feed_counter[index];
}
void timeout_init_IWDT(void) {
/* Enable write access to IWDG_PR and IWDG_RLR registers */
IWDG_WriteAccessCmd(IWDG_WriteAccess_Enable);
/* IWDG counter clock: LSI/4 */
IWDG_SetPrescaler(IWDG_Prescaler_4);
/* Set counter reload value to obtain 12ms IWDG TimeOut.
*
* LSI timer per datasheet is 32KHz typical, but 17KHz min
* and 47KHz max over the complete range of operating conditions,
* so reload time must ensure watchdog will work correctly under
* all conditions.
*
* Timeout threads runs every 10ms. Take 20% margin so wdt should
* be fed every 12ms. The worst condition occurs when the wdt clock
* runs at the max freq (47KHz) due to oscillator tolerances.
*
* t_IWDG(ms) = t_LSI(ms) * 4 * 2^(IWDG_PR[2:0]) * (IWDG_RLR[11:0] + 1)
* t_LSI(ms) [MAX] = 0.021276ms
* 12ms = 0.0212765 * 4 * 1 * (140 + 1)
Counter Reload Value = 140
When LSI clock runs the slowest, the IWDG will expire every 33.17ms
*/
IWDG_SetReload(140);
IWDG_ReloadCounter();
/* Enable IWDG (the LSI oscillator will be enabled by hardware) */
IWDG_Enable();
}
void timeout_configure_IWDT_slowest(void) {
while(((IWDG->SR & IWDG_SR_RVU) != 0) || ((IWDG->SR & IWDG_SR_PVU) != 0)) {
// Continue to kick the dog
@ -125,7 +108,7 @@ void timeout_configure_IWDT_slowest(void) {
// Unlock register
IWDG_WriteAccessCmd(IWDG_WriteAccess_Enable);
// Update configuration
IWDG_SetReload(1400);
IWDG_SetReload(4000);
IWDG_SetPrescaler(IWDG_Prescaler_256);
// Wait for the new configuration to be taken into account
@ -163,14 +146,6 @@ bool timeout_had_IWDG_reset(void) {
return true;
}
// Check if the system has resumed from WWDG reset
if (RCC_GetFlagStatus(RCC_FLAG_WWDGRST) != RESET) {
/* IWDGRST flag set */
/* Clear reset flags */
RCC_ClearFlag();
return true;
}
return false;
}
@ -210,8 +185,7 @@ static THD_FUNCTION(timeout_thread, arg) {
}
if (threads_ok == true) {
// Feed WDT's
WWDG_SetCounter(127); // must reload in >6.24ms and <12.48ms
// Feed WDT
IWDG_ReloadCounter(); // must reload in <12ms
} else {
// not reloading the watchdog will produce a reset.