Skip to content

Commit

Permalink
PPM dec fix, current sampling updates, ADC cruise control, commutatio…
Browse files Browse the repository at this point in the history
…n fix, higher switching frequency, refactoring
  • Loading branch information
vedderb committed Aug 23, 2015
1 parent 383208b commit 58d8929
Show file tree
Hide file tree
Showing 29 changed files with 490 additions and 582 deletions.
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
# Compiler options here.
ifeq ($(USE_OPT),)
USE_OPT = -O2 -ggdb -fomit-frame-pointer -falign-functions=16 -std=gnu99
USE_OPT += -DBOARD_OTG_NOVBUSSENS
USE_OPT += -DBOARD_OTG_NOVBUSSENS $(build_args)
endif

# C specific options here (added to USE_OPT).
Expand Down
4 changes: 2 additions & 2 deletions applications/app.c
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ void app_init(app_configuration *conf) {
break;

case APP_ADC:
app_adc_start();
app_adc_start(true);
break;

case APP_UART:
Expand All @@ -56,7 +56,7 @@ void app_init(app_configuration *conf) {

case APP_ADC_UART:
hw_stop_i2c();
app_adc_start();
app_adc_start(false);
app_uartcomm_start();
break;

Expand Down
2 changes: 1 addition & 1 deletion applications/app.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ void app_set_configuration(app_configuration *conf);
// Standard apps
void app_ppm_start(void);
void app_ppm_configure(ppm_config *conf);
void app_adc_start(void);
void app_adc_start(bool use_rx_tx);
void app_adc_configure(adc_config *conf);
float app_adc_get_decoded_level(void);
float app_adc_get_voltage(void);
Expand Down
99 changes: 90 additions & 9 deletions applications/app_adc.c
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
#define MAX_CAN_AGE 0.1
#define MIN_MS_WITHOUT_POWER 500
#define FILTER_SAMPLES 5
#define RPM_FILTER_SAMPLES 8

// Threads
static msg_t adc_thread(void *arg);
Expand All @@ -48,13 +49,15 @@ static volatile adc_config config;
static volatile float ms_without_power = 0;
static volatile float decoded_level = 0.0;
static volatile float read_voltage = 0.0;
static volatile bool use_rx_tx_as_buttons = false;

void app_adc_configure(adc_config *conf) {
config = *conf;
ms_without_power = 0.0;
}

void app_adc_start(void) {
void app_adc_start(bool use_rx_tx) {
use_rx_tx_as_buttons = use_rx_tx;
chThdCreateStatic(adc_thread_wa, sizeof(adc_thread_wa), NORMALPRIO, adc_thread, NULL);
}

Expand All @@ -72,7 +75,12 @@ static msg_t adc_thread(void *arg) {
chRegSetThreadName("APP_ADC");

// Set servo pin as an input with pullup
palSetPadMode(HW_ICU_GPIO, HW_ICU_PIN, PAL_MODE_INPUT_PULLUP);
if (use_rx_tx_as_buttons) {
palSetPadMode(HW_UART_TX_PORT, HW_UART_TX_PIN, PAL_MODE_INPUT_PULLUP);
palSetPadMode(HW_UART_RX_PORT, HW_UART_RX_PIN, PAL_MODE_INPUT_PULLUP);
} else {
palSetPadMode(HW_ICU_GPIO, HW_ICU_PIN, PAL_MODE_INPUT_PULLUP);
}

for(;;) {
// Sleep for a time according to the specified rate
Expand All @@ -84,6 +92,11 @@ static msg_t adc_thread(void *arg) {
}
chThdSleep(sleep_time);

// For safe start when fault codes occur
if (mcpwm_get_fault() != FAULT_CODE_NONE) {
ms_without_power = 0;
}

// Read the external ADC pin and convert the value to a voltage.
float pwr = (float)ADC_Value[ADC_IND_EXT];
pwr /= 4095;
Expand Down Expand Up @@ -119,10 +132,33 @@ static msg_t adc_thread(void *arg) {

decoded_level = pwr;

// Read the servo pin and optionally invert it.
bool button_val = !palReadPad(HW_ICU_GPIO, HW_ICU_PIN);
if (config.button_inverted) {
button_val = !button_val;
// Read the button pins
bool cc_button = false;
bool rev_button = false;
if (use_rx_tx_as_buttons) {
cc_button = !palReadPad(HW_UART_TX_PORT, HW_UART_TX_PIN);
if (config.cc_button_inverted) {
cc_button = !cc_button;
}
rev_button = !palReadPad(HW_UART_RX_PORT, HW_UART_RX_PIN);
if (config.rev_button_inverted) {
rev_button = !rev_button;
}
} else {
// When only one button input is available, use it differently depending on the control mode
if (config.ctrl_type == ADC_CTRL_TYPE_CURRENT_REV_BUTTON ||
config.ctrl_type == ADC_CTRL_TYPE_CURRENT_NOREV_BRAKE_BUTTON ||
config.ctrl_type == ADC_CTRL_TYPE_DUTY_REV_BUTTON) {
rev_button = !palReadPad(HW_ICU_GPIO, HW_ICU_PIN);
if (config.rev_button_inverted) {
rev_button = !rev_button;
}
} else {
cc_button = !palReadPad(HW_ICU_GPIO, HW_ICU_PIN);
if (config.cc_button_inverted) {
cc_button = !cc_button;
}
}
}

switch (config.ctrl_type) {
Expand All @@ -138,7 +174,7 @@ static msg_t adc_thread(void *arg) {
case ADC_CTRL_TYPE_CURRENT_NOREV_BRAKE_BUTTON:
case ADC_CTRL_TYPE_DUTY_REV_BUTTON:
// Invert the voltage if the button is pressed
if (button_val) {
if (rev_button) {
pwr = -pwr;
}
break;
Expand All @@ -147,10 +183,10 @@ static msg_t adc_thread(void *arg) {
break;
}

// Apply a deadband
// Apply deadband
utils_deadband(&pwr, config.hyst, 1.0);

float current = 0;
float current = 0.0;
bool current_mode = false;
bool current_mode_brake = false;
const volatile mc_configuration *mcconf = mcpwm_get_configuration();
Expand Down Expand Up @@ -219,6 +255,51 @@ static msg_t adc_thread(void *arg) {
// Reset timeout
timeout_reset();

// If c is pressed and no throttle is used, maintain the current speed with PID control
static bool was_pid = false;

// Filter RPM to avoid glitches
static float filter_buffer[RPM_FILTER_SAMPLES];
static int filter_ptr = 0;
filter_buffer[filter_ptr++] = mcpwm_get_rpm();
if (filter_ptr >= RPM_FILTER_SAMPLES) {
filter_ptr = 0;
}

float rpm_filtered = 0.0;
for (int i = 0;i < RPM_FILTER_SAMPLES;i++) {
rpm_filtered += filter_buffer[i];
}
rpm_filtered /= RPM_FILTER_SAMPLES;

if (current_mode && cc_button && fabsf(pwr) < 0.001) {
static float pid_rpm = 0.0;

if (!was_pid) {
was_pid = true;
pid_rpm = rpm_filtered;
}

mcpwm_set_pid_speed(pid_rpm);

// Send the same duty cycle to the other controllers
if (config.multi_esc) {
float duty = mcpwm_get_duty_cycle_now();

for (int i = 0;i < CAN_STATUS_MSGS_TO_STORE;i++) {
can_status_msg *msg = comm_can_get_status_msg_index(i);

if (msg->id >= 0 && UTILS_AGE_S(msg->rx_time) < MAX_CAN_AGE) {
comm_can_set_duty(msg->id, duty);
}
}
}

continue;
}

was_pid = false;

// Find lowest RPM (for traction control)
float rpm_local = mcpwm_get_rpm();
float rpm_lowest = rpm_local;
Expand Down
5 changes: 2 additions & 3 deletions applications/app_nunchuk.c
Original file line number Diff line number Diff line change
Expand Up @@ -235,13 +235,12 @@ static msg_t output_thread(void *arg) {
// Filter RPM to avoid glitches
static float filter_buffer[RPM_FILTER_SAMPLES];
static int filter_ptr = 0;
float rpm_filtered = mcpwm_get_rpm();
filter_buffer[filter_ptr++] = rpm_filtered;
filter_buffer[filter_ptr++] = mcpwm_get_rpm();
if (filter_ptr >= RPM_FILTER_SAMPLES) {
filter_ptr = 0;
}

rpm_filtered = 0.0;
float rpm_filtered = 0.0;
for (int i = 0;i < RPM_FILTER_SAMPLES;i++) {
rpm_filtered += filter_buffer[i];
}
Expand Down
6 changes: 4 additions & 2 deletions commands.c
Original file line number Diff line number Diff line change
Expand Up @@ -390,7 +390,8 @@ void commands_process_packet(unsigned char *data, unsigned int len) {
appconf.app_adc_conf.voltage_end = (float)buffer_get_int32(data, &ind) / 1000.0;
appconf.app_adc_conf.use_filter = data[ind++];
appconf.app_adc_conf.safe_start = data[ind++];
appconf.app_adc_conf.button_inverted = 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.rpm_lim_start = (float)buffer_get_int32(data, &ind) / 1000.0;
appconf.app_adc_conf.rpm_lim_end = (float)buffer_get_int32(data, &ind) / 1000.0;
Expand Down Expand Up @@ -452,7 +453,8 @@ void commands_process_packet(unsigned char *data, unsigned int len) {
buffer_append_int32(send_buffer, (int32_t)(appconf.app_adc_conf.voltage_end * 1000.0), &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.button_inverted;
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;
buffer_append_int32(send_buffer, (int32_t)(appconf.app_adc_conf.rpm_lim_start * 1000.0), &ind);
buffer_append_int32(send_buffer, (int32_t)(appconf.app_adc_conf.rpm_lim_end * 1000.0), &ind);
Expand Down
5 changes: 3 additions & 2 deletions conf_general.c
Original file line number Diff line number Diff line change
Expand Up @@ -139,9 +139,9 @@ void conf_general_init(void) {
VirtAddVarTab[ind++] = EEPROM_BASE_APPCONF + i;
}

FLASH_Unlock();
FLASH_ClearFlag(FLASH_FLAG_OPERR | FLASH_FLAG_WRPERR | FLASH_FLAG_PGAERR |
FLASH_FLAG_PGPERR | FLASH_FLAG_PGSERR);
FLASH_Unlock();
EE_Init();
}

Expand Down Expand Up @@ -198,7 +198,8 @@ void conf_general_read_app_configuration(app_configuration *conf) {
conf->app_adc_conf.voltage_end = 3.0;
conf->app_adc_conf.use_filter = true;
conf->app_adc_conf.safe_start = true;
conf->app_adc_conf.button_inverted = false;
conf->app_adc_conf.cc_button_inverted = false;
conf->app_adc_conf.rev_button_inverted = false;
conf->app_adc_conf.voltage_inverted = false;
conf->app_adc_conf.rpm_lim_start = 150000;
conf->app_adc_conf.rpm_lim_end = 200000;
Expand Down
25 changes: 17 additions & 8 deletions conf_general.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@

// Firmware version
#define FW_VERSION_MAJOR 1
#define FW_VERSION_MINOR 10
#define FW_VERSION_MINOR 11

#include "datatypes.h"

Expand All @@ -38,19 +38,17 @@
#define SYSTEM_CORE_CLOCK 168000000

// Component parameters to override
//#define V_REG 3.3
#define VIN_R1 39000.0
//#define VIN_R1 33000.0
//#define VIN_R2 2200.0
//#define CURRENT_AMP_GAIN 10.0
//#define CURRENT_SHUNT_RES 0.001

// Correction factor for computations that depend on the old resistor division factor
#define VDIV_CORR ((VIN_R2 / (VIN_R2 + VIN_R1)) / (2.2 / (2.2 + 33.0)))
//#define CURRENT_SHUNT_RES 0.0005
//#define WS2811_ENABLE 1
//#define CURR1_DOUBLE_SAMPLE 0
//#define CURR2_DOUBLE_SAMPLE 0

/*
* Select only one hardware version
*/
//#define HW_VERSION_BW
//#define HW_VERSION_40
//#define HW_VERSION_45
#define HW_VERSION_46 // Also for 4.7
Expand Down Expand Up @@ -94,20 +92,31 @@
* Output WS2811 signal on the HALL1 pin. Notice that hall sensors can't be used
* at the same time.
*/
#ifndef WS2811_ENABLE
#define WS2811_ENABLE 0
#endif
#define WS2811_CLK_HZ 800000
#define WS2811_LED_NUM 14
#define WS2811_USE_CH2 1 // 0: CH1 (PB6) 1: CH2 (PB7)

/*
* Servo output driver
*/
#ifndef SERVO_OUT_ENABLE
#define SERVO_OUT_ENABLE 0 // Enable servo output
#endif
#define SERVO_OUT_SIMPLE 1 // Use simple HW-based driver (recommended)
#define SERVO_OUT_PULSE_MIN_US 1000 // Minimum pulse length in microseconds
#define SERVO_OUT_PULSE_MAX_US 2000 // Maximum pulse length in microseconds
#define SERVO_OUT_RATE_HZ 50 // Update rate in Hz

// Correction factor for computations that depend on the old resistor division factor
#define VDIV_CORR ((VIN_R2 / (VIN_R2 + VIN_R1)) / (2.2 / (2.2 + 33.0)))

// Actual voltage on 3.3V net based on internal reference
//#define V_REG (1.21 / ((float)ADC_Value[ADC_IND_VREFINT] / 4095.0))
#define V_REG 3.3

// Functions
void conf_general_init(void);
void conf_general_read_app_configuration(app_configuration *conf);
Expand Down
9 changes: 6 additions & 3 deletions datatypes.h
Original file line number Diff line number Diff line change
Expand Up @@ -208,7 +208,8 @@ typedef struct {
float voltage_end;
bool use_filter;
bool safe_start;
bool button_inverted;
bool cc_button_inverted;
bool rev_button_inverted;
bool voltage_inverted;
float rpm_lim_start;
float rpm_lim_end;
Expand Down Expand Up @@ -316,8 +317,10 @@ typedef struct {
float duty;
float rpm;
int tacho;
int tim_pwm_cnt;
int tim_samp_cnt;
int cycles_running;
int tim_val_samp;
int tim_current_samp;
int tim_top;
int comm_step;
float temperature;
} fault_data;
Expand Down
12 changes: 7 additions & 5 deletions hwconf/hw_40.c
Original file line number Diff line number Diff line change
Expand Up @@ -114,27 +114,29 @@ void hw_init_gpio(void) {
}

void hw_setup_adc_channels(void) {
// ADC1 regular channels 0, 5, 10, 13
// ADC1 regular channels
ADC_RegularChannelConfig(ADC1, ADC_Channel_0, 1, ADC_SampleTime_15Cycles);
ADC_RegularChannelConfig(ADC1, ADC_Channel_5, 2, ADC_SampleTime_15Cycles);
ADC_RegularChannelConfig(ADC1, ADC_Channel_10, 3, ADC_SampleTime_15Cycles);
ADC_RegularChannelConfig(ADC1, ADC_Channel_Vrefint, 3, ADC_SampleTime_15Cycles);
ADC_RegularChannelConfig(ADC1, ADC_Channel_13, 4, ADC_SampleTime_15Cycles);

// ADC2 regular channels 1, 6, 11, 15
// ADC2 regular channels
ADC_RegularChannelConfig(ADC2, ADC_Channel_1, 1, ADC_SampleTime_15Cycles);
ADC_RegularChannelConfig(ADC2, ADC_Channel_6, 2, ADC_SampleTime_15Cycles);
ADC_RegularChannelConfig(ADC2, ADC_Channel_11, 3, ADC_SampleTime_15Cycles);
ADC_RegularChannelConfig(ADC2, ADC_Channel_15, 4, ADC_SampleTime_15Cycles);

// ADC3 regular channels 2, 3, 12, 3
// ADC3 regular channels
ADC_RegularChannelConfig(ADC3, ADC_Channel_2, 1, ADC_SampleTime_15Cycles);
ADC_RegularChannelConfig(ADC3, ADC_Channel_3, 2, ADC_SampleTime_15Cycles);
ADC_RegularChannelConfig(ADC3, ADC_Channel_12, 3, ADC_SampleTime_15Cycles);
ADC_RegularChannelConfig(ADC3, ADC_Channel_3, 4, ADC_SampleTime_15Cycles);
ADC_RegularChannelConfig(ADC3, ADC_Channel_10, 4, ADC_SampleTime_15Cycles);

// Injected channels
ADC_InjectedChannelConfig(ADC1, ADC_Channel_6, 1, ADC_SampleTime_15Cycles);
ADC_InjectedChannelConfig(ADC2, ADC_Channel_5, 1, ADC_SampleTime_15Cycles);
ADC_InjectedChannelConfig(ADC1, ADC_Channel_5, 2, ADC_SampleTime_15Cycles);
ADC_InjectedChannelConfig(ADC2, ADC_Channel_6, 2, ADC_SampleTime_15Cycles);
}

void hw_setup_servo_outputs(void) {
Expand Down
Loading

0 comments on commit 58d8929

Please sign in to comment.