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 === === FW 3.49 ===
* New watchdog implementation. * New watchdog implementation.
* HW updates. * HW updates.

View File

@ -149,6 +149,7 @@ CSRC = $(STARTUPSRC) \
mc_interface.c \ mc_interface.c \
mcpwm_foc.c \ mcpwm_foc.c \
gpdrive.c \ gpdrive.c \
confgenerator.c \
$(HWSRC) \ $(HWSRC) \
$(APPSRC) \ $(APPSRC) \
$(NRFSRC) \ $(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 "encoder.h"
#include "nrf_driver.h" #include "nrf_driver.h"
#include "gpdrive.h" #include "gpdrive.h"
#include "confgenerator.h"
#include <math.h> #include <math.h>
#include <string.h> #include <string.h>
@ -349,39 +350,7 @@ void commands_process_packet(unsigned char *data, unsigned int len) {
case COMM_SET_MCCONF: case COMM_SET_MCCONF:
mcconf = *mc_interface_get_configuration(); mcconf = *mc_interface_get_configuration();
ind = 0; if (confgenerator_deserialize_mcconf(data, &mcconf)) {
mcconf.pwm_mode = data[ind++];
mcconf.comm_mode = data[ind++];
mcconf.motor_type = data[ind++];
mcconf.sensor_mode = data[ind++];
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);
utils_truncate_number(&mcconf.l_current_max_scale , 0.0, 1.0); utils_truncate_number(&mcconf.l_current_max_scale , 0.0, 1.0);
utils_truncate_number(&mcconf.l_current_min_scale , 0.0, 1.0); utils_truncate_number(&mcconf.l_current_min_scale , 0.0, 1.0);
@ -392,95 +361,6 @@ void commands_process_packet(unsigned char *data, unsigned int len) {
mcconf.lo_current_motor_max_now = mcconf.lo_current_max; mcconf.lo_current_motor_max_now = mcconf.lo_current_max;
mcconf.lo_current_motor_min_now = mcconf.lo_current_min; 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); commands_apply_mcconf_hw_limits(&mcconf);
conf_general_store_mc_configuration(&mcconf); conf_general_store_mc_configuration(&mcconf);
mc_interface_set_configuration(&mcconf); mc_interface_set_configuration(&mcconf);
@ -489,6 +369,9 @@ void commands_process_packet(unsigned char *data, unsigned int len) {
ind = 0; ind = 0;
send_buffer[ind++] = packet_id; send_buffer[ind++] = packet_id;
commands_send_packet(send_buffer, ind); commands_send_packet(send_buffer, ind);
} else {
commands_printf("Warning: Could not set mcconf due to wrong signature");
}
break; break;
case COMM_GET_MCCONF: case COMM_GET_MCCONF:
@ -496,7 +379,7 @@ void commands_process_packet(unsigned char *data, unsigned int len) {
if (packet_id == COMM_GET_MCCONF) { if (packet_id == COMM_GET_MCCONF) {
mcconf = *mc_interface_get_configuration(); mcconf = *mc_interface_get_configuration();
} else { } else {
conf_general_get_default_mc_configuration(&mcconf); confgenerator_set_defaults_mcconf(&mcconf);
} }
commands_send_mcconf(packet_id, &mcconf); commands_send_mcconf(packet_id, &mcconf);
@ -505,84 +388,7 @@ void commands_process_packet(unsigned char *data, unsigned int len) {
case COMM_SET_APPCONF: case COMM_SET_APPCONF:
appconf = *app_get_configuration(); appconf = *app_get_configuration();
ind = 0; if (confgenerator_deserialize_appconf(data, &appconf)) {
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++];
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); conf_general_store_app_configuration(&appconf);
app_set_configuration(&appconf); app_set_configuration(&appconf);
timeout_configure(appconf.timeout_msec, appconf.timeout_brake_current); timeout_configure(appconf.timeout_msec, appconf.timeout_brake_current);
@ -591,6 +397,9 @@ void commands_process_packet(unsigned char *data, unsigned int len) {
ind = 0; ind = 0;
send_buffer[ind++] = packet_id; send_buffer[ind++] = packet_id;
commands_send_packet(send_buffer, ind); commands_send_packet(send_buffer, ind);
} else {
commands_printf("Warning: Could not set appconf due to wrong signature");
}
break; break;
case COMM_GET_APPCONF: case COMM_GET_APPCONF:
@ -598,7 +407,7 @@ void commands_process_packet(unsigned char *data, unsigned int len) {
if (packet_id == COMM_GET_APPCONF) { if (packet_id == COMM_GET_APPCONF) {
appconf = *app_get_configuration(); appconf = *app_get_configuration();
} else { } else {
conf_general_get_default_app_configuration(&appconf); confgenerator_set_defaults_appconf(&appconf);
} }
commands_send_appconf(packet_id, &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) { void commands_send_mcconf(COMM_PACKET_ID packet_id, mc_configuration *mcconf) {
int32_t ind = 0; send_buffer_global[0] = packet_id;
uint8_t *send_buffer = send_buffer_global; int32_t len = confgenerator_serialize_mcconf(send_buffer_global + 1, mcconf);
commands_send_packet(send_buffer_global, len + 1);
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);
} }
void commands_send_appconf(COMM_PACKET_ID packet_id, app_configuration *appconf) { void commands_send_appconf(COMM_PACKET_ID packet_id, app_configuration *appconf) {
int32_t ind = 0; send_buffer_global[0] = packet_id;
uint8_t *send_buffer = send_buffer_global; int32_t len = confgenerator_serialize_appconf(send_buffer_global + 1, appconf);
commands_send_packet(send_buffer_global, len + 1);
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);
} }
void commands_apply_mcconf_hw_limits(mc_configuration *mcconf) { 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_max_scale, 0.0, 1.0);
utils_truncate_number(&mcconf->l_current_min_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 #ifndef DISABLE_HW_LIMITS
#ifdef HW_LIM_CURRENT #ifdef HW_LIM_CURRENT
utils_truncate_number(&mcconf->l_current_max, 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_start, HW_LIM_TEMP_FET);
utils_truncate_number(&mcconf->l_temp_fet_end, HW_LIM_TEMP_FET); utils_truncate_number(&mcconf->l_temp_fet_end, HW_LIM_TEMP_FET);
#endif #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 #endif
} }

View File

@ -23,7 +23,6 @@
#include "mcpwm.h" #include "mcpwm.h"
#include "mcpwm_foc.h" #include "mcpwm_foc.h"
#include "mc_interface.h" #include "mc_interface.h"
#include "hw.h"
#include "utils.h" #include "utils.h"
#include "stm32f4xx_conf.h" #include "stm32f4xx_conf.h"
#include "timeout.h" #include "timeout.h"
@ -31,6 +30,7 @@
#include "encoder.h" #include "encoder.h"
#include "comm_can.h" #include "comm_can.h"
#include "app.h" #include "app.h"
#include "confgenerator.h"
#include <string.h> #include <string.h>
#include <math.h> #include <math.h>
@ -67,242 +67,6 @@ void conf_general_init(void) {
EE_Init(); 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. * 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 // Set the default configuration
if (!is_ok) { 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(); utils_sys_lock_cnt();
mc_interface_lock(); mc_interface_lock();
RCC_APB1PeriphClockCmd(RCC_APB1Periph_WWDG, DISABLE);
timeout_configure_IWDT_slowest(); timeout_configure_IWDT_slowest();
bool is_ok = true; 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(); timeout_configure_IWDT();
chThdSleepMilliseconds(100); chThdSleepMilliseconds(100);
@ -395,7 +157,7 @@ void conf_general_read_mc_configuration(mc_configuration *conf) {
} }
if (!is_ok) { 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(); utils_sys_lock_cnt();
mc_interface_lock(); mc_interface_lock();
RCC_APB1PeriphClockCmd(RCC_APB1Periph_WWDG, DISABLE);
timeout_configure_IWDT_slowest(); timeout_configure_IWDT_slowest();
bool is_ok = true; 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(); timeout_configure_IWDT();
chThdSleepMilliseconds(100); chThdSleepMilliseconds(100);

View File

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

View File

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

@ -313,8 +313,7 @@ void encoder_reset(void) {
} }
// returns true for even number of ones (no parity error according to AS5047 datasheet // returns true for even number of ones (no parity error according to AS5047 datasheet
bool spi_check_parity(uint16_t x) bool spi_check_parity(uint16_t x) {
{
x ^= x >> 8; x ^= x >> 8;
x ^= x >> 4; x ^= x >> 4;
x ^= x >> 2; x ^= x >> 2;

View File

@ -90,7 +90,6 @@ uint16_t flash_helper_erase_new_app(uint32_t new_app_size) {
mc_interface_unlock(); mc_interface_unlock();
mc_interface_release_motor(); mc_interface_release_motor();
utils_sys_lock_cnt(); utils_sys_lock_cnt();
RCC_APB1PeriphClockCmd(RCC_APB1Periph_WWDG, DISABLE);
timeout_configure_IWDT_slowest(); timeout_configure_IWDT_slowest();
for (int i = 0;i < NEW_APP_SECTORS;i++) { 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(); timeout_configure_IWDT();
utils_sys_unlock_cnt(); 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_unlock();
mc_interface_release_motor(); mc_interface_release_motor();
utils_sys_lock_cnt(); utils_sys_lock_cnt();
RCC_APB1PeriphClockCmd(RCC_APB1Periph_WWDG, DISABLE);
timeout_configure_IWDT_slowest(); timeout_configure_IWDT_slowest();
for (uint32_t i = 0;i < len;i++) { 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(); timeout_configure_IWDT();
utils_sys_unlock_cnt(); 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); palSetPadMode(HW_UART_RX_PORT, HW_UART_RX_PIN, PAL_MODE_INPUT);
// Disable watchdog // Disable watchdog
RCC_APB1PeriphClockCmd(RCC_APB1Periph_WWDG, DISABLE);
timeout_configure_IWDT_slowest(); timeout_configure_IWDT_slowest();
chSysDisable(); chSysDisable();

View File

@ -257,14 +257,13 @@ void gpdrive_init(volatile mc_configuration *configuration) {
timer_thd_stop = false; timer_thd_stop = false;
chThdCreateStatic(timer_thread_wa, sizeof(timer_thread_wa), NORMALPRIO, timer_thread, NULL); 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(); 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; m_init_done = true;
} }
@ -275,8 +274,6 @@ void gpdrive_deinit(void) {
m_init_done = false; m_init_done = false;
WWDG_DeInit();
timer_thd_stop = true; timer_thd_stop = true;
while (timer_thd_stop) { while (timer_thd_stop) {
@ -514,7 +511,7 @@ static void adc_int_handler(void *p, uint32_t flags) {
TIM12->CNT = 0; TIM12->CNT = 0;
// Reset the watchdog // Reset the watchdog
WWDG_SetCounter(100); timeout_feed_WDT(THREAD_MCPWM);
int curr0 = GET_CURRENT1(); int curr0 = GET_CURRENT1();
int curr1 = GET_CURRENT2(); int curr1 = GET_CURRENT2();

View File

@ -166,6 +166,10 @@
#define HW_LIM_CURRENT_ABS 0.0, 140.0 #define HW_LIM_CURRENT_ABS 0.0, 140.0
#endif #endif
#ifndef HW_LIM_FOC_CTRL_LOOP_FREQ
#define HW_LIM_FOC_CTRL_LOOP_FREQ 3000.0, 30000.0
#endif
// Functions // Functions
void hw_init_gpio(void); void hw_init_gpio(void);
void hw_setup_adc_channels(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_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_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_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; 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 #define MCCONF_M_BLDC_F_SW_MIN 3000 // Minimum switching frequency in bldc mode
#endif #endif
#ifndef MCCONF_M_BLDC_F_SW_MAX #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 #endif
#ifndef MCCONF_M_DC_F_SW #ifndef MCCONF_M_DC_F_SW
#define MCCONF_M_DC_F_SW 25000 // Switching frequency in dc mode #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); chThdCreateStatic(rpm_thread_wa, sizeof(rpm_thread_wa), NORMALPRIO, rpm_thread, NULL);
// Check if the system has resumed from IWDG reset // 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); mc_interface_fault_stop(FAULT_CODE_BOOTING_FROM_WATCHDOG_RESET);
}
// Reset tachometers again // Reset tachometers again
tachometer = 0; tachometer = 0;
@ -487,8 +488,6 @@ void mcpwm_deinit(void) {
init_done = false; init_done = false;
WWDG_DeInit();
timer_thd_stop = true; timer_thd_stop = true;
rpm_thd_stop = true; rpm_thd_stop = true;

View File

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

View File

@ -639,9 +639,10 @@ void terminal_process_string(char *str) {
commands_printf("This command requires one argument.\n"); commands_printf("This command requires one argument.\n");
} }
} else if (strcmp(argv[0], "encoder") == 0) { } else if (strcmp(argv[0], "encoder") == 0) {
commands_printf("SPI val:%x, errors:%d, rate:%.5f", (unsigned int)encoder_spi_get_val(), commands_printf("SPI val: %x, errors: %d, error rate: %.3f %%",
(unsigned int)encoder_spi_get_val(),
encoder_spi_get_error_cnt(), encoder_spi_get_error_cnt(),
(double)encoder_spi_get_error_rate()); (double)encoder_spi_get_error_rate() * (double)100.0);
} }
// The help command // 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_WORKING_AREA(timeout_thread_wa, 512);
static THD_FUNCTION(timeout_thread, arg); static THD_FUNCTION(timeout_thread, arg);
void timeout_init_IWDT(void);
void timeout_init(void) { void timeout_init(void) {
timeout_msec = 1000; timeout_msec = 1000;
last_update_time = 0; last_update_time = 0;
timeout_brake_current = 0.0; timeout_brake_current = 0.0;
has_timeout = false; has_timeout = false;
// WWDG configuration IWDG_WriteAccessCmd(IWDG_WriteAccess_Enable);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_WWDG, ENABLE);
// Timeout = t_PCLK1 (ms) * 4096 * 2^(WDGTB [1:0]) * (T[5:0] + 1)
// CLK1 = 42MHz
// Window set between 6.24ms and 12.48ms. Mcu will reset if watchdog is fed outside the window // IWDG counter clock: LSI/4
WWDG_SetPrescaler(WWDG_Prescaler_2); IWDG_SetPrescaler(IWDG_Prescaler_4);
WWDG_SetWindowValue(127);
WWDG_Enable(127); //0x7F
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); chThdSleepMilliseconds(10);
@ -82,40 +99,6 @@ void timeout_feed_WDT(uint8_t index) {
++feed_counter[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) { void timeout_configure_IWDT_slowest(void) {
while(((IWDG->SR & IWDG_SR_RVU) != 0) || ((IWDG->SR & IWDG_SR_PVU) != 0)) { while(((IWDG->SR & IWDG_SR_RVU) != 0) || ((IWDG->SR & IWDG_SR_PVU) != 0)) {
// Continue to kick the dog // Continue to kick the dog
@ -125,7 +108,7 @@ void timeout_configure_IWDT_slowest(void) {
// Unlock register // Unlock register
IWDG_WriteAccessCmd(IWDG_WriteAccess_Enable); IWDG_WriteAccessCmd(IWDG_WriteAccess_Enable);
// Update configuration // Update configuration
IWDG_SetReload(1400); IWDG_SetReload(4000);
IWDG_SetPrescaler(IWDG_Prescaler_256); IWDG_SetPrescaler(IWDG_Prescaler_256);
// Wait for the new configuration to be taken into account // Wait for the new configuration to be taken into account
@ -163,14 +146,6 @@ bool timeout_had_IWDG_reset(void) {
return true; 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; return false;
} }
@ -210,8 +185,7 @@ static THD_FUNCTION(timeout_thread, arg) {
} }
if (threads_ok == true) { if (threads_ok == true) {
// Feed WDT's // Feed WDT
WWDG_SetCounter(127); // must reload in >6.24ms and <12.48ms
IWDG_ReloadCounter(); // must reload in <12ms IWDG_ReloadCounter(); // must reload in <12ms
} else { } else {
// not reloading the watchdog will produce a reset. // not reloading the watchdog will produce a reset.