Prepared applications for runtime configuration

This commit is contained in:
Benjamin Vedder 2014-09-17 21:05:57 +02:00
parent 8d091c9a60
commit 6d4e55051c
11 changed files with 211 additions and 62 deletions

View File

@ -25,20 +25,49 @@
#include "app.h"
#include "ch.h"
#include "hal.h"
#include "stm32f4xx_conf.h"
#include "servo.h"
void app_init(void) {
#ifdef USE_APP_RCCAR
app_rccar_init();
#endif
// Private variables
static app_configuration app_conf;
void app_init(app_configuration *conf) {
app_conf = *conf;
switch (app_conf.app_to_use) {
case APP_PPM:
app_ppm_configure(app_conf.app_ppm_ctrl_type, app_conf.app_ppm_pid_max_erpm, app_conf.app_ppm_use_rev);
app_ppm_start();
break;
case APP_UARTCOMM:
app_uartcomm_init();
break;
case APP_CUSTOM:
#ifdef USE_APP_STEN
app_sten_init();
app_sten_init();
#endif
#ifdef USE_APP_GURGALOF
app_gurgalof_init();
#endif
#ifdef USE_APP_UARTCOMM
app_uartcomm_init();
app_gurgalof_init();
#endif
break;
default:
break;
}
}
const app_configuration* app_get_configuration(void) {
return &app_conf;
}
/**
* Reconfigure all apps. Note that this will not start apps that are not already running, that
* should be done at boot. Some apps don't have any configuration options.
*
* @param conf
* The new configuration to use.
*/
void app_set_configuration(app_configuration *conf) {
app_conf = *conf;
app_ppm_configure(app_conf.app_ppm_ctrl_type, app_conf.app_ppm_pid_max_erpm, app_conf.app_ppm_use_rev);
}

View File

@ -28,12 +28,19 @@
#include "conf_general.h"
// Functions
void app_init(void);
void app_init(app_configuration *conf);
const app_configuration* app_get_configuration(void);
// The init functions for all applications
void app_rccar_init(void);
void app_sten_init(void);
void app_gurgalof_init(void);
// The init and deinit functions for all applications
void app_ppm_configure(ppm_control_type ctrlt, float pme, bool rev);
void app_set_configuration(app_configuration *conf);
// Standard apps
void app_ppm_start(void);
void app_uartcomm_init(void);
// Custom apps
void app_gurgalof_init(void);
void app_sten_init(void);
#endif /* APP_H_ */

View File

@ -56,7 +56,7 @@ static msg_t gurgalof_thread(void *arg) {
mcpwm_set_current(0.0);
} else {
mcpwm_set_duty(pwr);
// mcpwm_set_current(pwr * MCPWM_CURRENT_MAX);
// mcpwm_set_current(pwr * mcpwm_get_configuration()->l_current_max);
}
chThdSleepMilliseconds(10);

View File

@ -16,14 +16,13 @@
*/
/*
* app_rccar.c
* app_ppm.c
*
* Created on: 18 apr 2014
* Author: benjamin
*/
#include "app.h"
#ifdef USE_APP_RCCAR
#include "ch.h"
#include "hal.h"
@ -33,17 +32,28 @@
#include <math.h>
// Threads
static msg_t rccar_thread(void *arg);
static WORKING_AREA(rccar_thread_wa, 1024);
static Thread *rccar_tp;
static msg_t ppm_thread(void *arg);
static WORKING_AREA(ppm_thread_wa, 1024);
static Thread *ppm_tp;
static VirtualTimer vt;
// Private functions
static void servodec_func(void);
static void trig_func(void *p);
void app_rccar_init(void) {
chThdCreateStatic(rccar_thread_wa, sizeof(rccar_thread_wa), NORMALPRIO, rccar_thread, NULL);
// Private variables
static volatile ppm_control_type ctrl_type;
static volatile float pid_max_erpm;
static volatile bool use_rev;
void app_ppm_configure(ppm_control_type ctrlt, float pme, bool rev) {
ctrl_type = ctrlt;
pid_max_erpm = pme;
use_rev = rev;
}
void app_ppm_start(void) {
chThdCreateStatic(ppm_thread_wa, sizeof(ppm_thread_wa), NORMALPRIO, ppm_thread, NULL);
}
static void trig_func(void *p) {
@ -53,20 +63,20 @@ static void trig_func(void *p) {
chVTSetI(&vt, MS2ST(10), trig_func, NULL);
chSysUnlock();
chEvtSignalI(rccar_tp, (eventmask_t) 1);
chEvtSignalI(ppm_tp, (eventmask_t) 1);
}
static void servodec_func(void) {
chSysLockFromIsr();
chEvtSignalI(rccar_tp, (eventmask_t) 1);
chEvtSignalI(ppm_tp, (eventmask_t) 1);
chSysUnlockFromIsr();
}
static msg_t rccar_thread(void *arg) {
static msg_t ppm_thread(void *arg) {
(void)arg;
chRegSetThreadName("APP_RCCAR");
rccar_tp = chThdSelf();
chRegSetThreadName("APP_PPM");
ppm_tp = chThdSelf();
servodec_init(servodec_func);
@ -78,11 +88,16 @@ static msg_t rccar_thread(void *arg) {
chEvtWaitAny((eventmask_t) 1);
#define HYST 0.15
#define USE_PID 0
#define PID_MAX_RPM 15000
if (servodec_get_time_since_update() < 500) {
float servo_val = servodec_get_servo_as_float(0);
if (!use_rev) {
servo_val += 1.0;
servo_val /= 2.0;
servo_val /= (1.0 - HYST);
}
servo_val /= (1.0 - HYST);
if (servo_val > HYST) {
@ -93,11 +108,22 @@ static msg_t rccar_thread(void *arg) {
servo_val = 0.0;
}
#if USE_PID
mcpwm_set_pid_speed(servo_val * PID_MAX_RPM);
#else
mcpwm_set_current(servo_val * mcpwm_get_configuration()->l_current_max);
#endif
switch (ctrl_type) {
case PPM_CTRL_TYPE_CURRENT:
mcpwm_set_current(servo_val * mcpwm_get_configuration()->l_current_max);
break;
case PPM_CTRL_TYPE_DUTY:
mcpwm_set_duty(servo_val);
break;
case PPM_CTRL_TYPE_PID:
mcpwm_set_pid_speed(servo_val * pid_max_erpm);
break;
default:
break;
}
} else {
mcpwm_set_current(0.0);
}
@ -105,5 +131,3 @@ static msg_t rccar_thread(void *arg) {
return 0;
}
#endif

View File

@ -165,14 +165,14 @@ static void set_output(float output) {
const float rpm = mcpwm_get_rpm();
if (output > 0.0 && rpm > -MCPWM_MIN_RPM) {
float current = output * MCPWM_CURRENT_MAX;
if (output > 0.0 && rpm > -mcpwm_get_configuration()->l_min_erpm) {
float current = output * mcpwm_get_configuration()->l_current_max;
// Soft RPM limit
if (rpm > RPM_MAX_2) {
current = -MCPWM_CURRENT_CONTROL_MIN;
current = -mcpwm_get_configuration()->cc_min_current;
} else if (rpm > RPM_MAX_1) {
current = utils_map(rpm, RPM_MAX_1, RPM_MAX_2, current, -MCPWM_CURRENT_CONTROL_MIN);
current = utils_map(rpm, RPM_MAX_1, RPM_MAX_2, current, -mcpwm_get_configuration()->cc_min_current);
}
// Some low-pass filtering
@ -182,13 +182,13 @@ static void set_output(float output) {
current_p2 = current_p1;
current_p1 = current;
if (fabsf(current) < MCPWM_CURRENT_CONTROL_MIN) {
current = -MCPWM_CURRENT_CONTROL_MIN;
if (fabsf(current) < mcpwm_get_configuration()->cc_min_current) {
current = -mcpwm_get_configuration()->cc_min_current;
}
mcpwm_set_current(current);
} else {
mcpwm_set_brake_current(output * MCPWM_CURRENT_MIN);
mcpwm_set_brake_current(output * mcpwm_get_configuration()->l_current_min);
}
}

View File

@ -23,7 +23,6 @@
*/
#include "app.h"
#ifdef USE_APP_UARTCOMM
#include "ch.h"
#include "hal.h"
@ -219,5 +218,3 @@ static msg_t packet_process_thread(void *arg) {
return 0;
}
#endif

View File

@ -1,5 +1,5 @@
APPSRC = applications/app.c \
applications/app_rccar.c \
applications/app_ppm.c \
applications/app_sten.c \
applications/app_gurgalof.c \
applications/app_uartcomm.c

View File

@ -11,6 +11,8 @@
#include "mcpwm.h"
#include "hw.h"
#include <string.h>
// Default configuration file
#ifdef MCCONF_OUTRUNNER1
#include "mcconf_outrunner1.h"
@ -80,7 +82,8 @@
#endif
// EEPROM settings
#define EEPROM_BASE_MCCONF 100
#define EEPROM_BASE_MCCONF 1000
#define EEPROM_BASE_GENCONF 2000
// Global variables
uint16_t VirtAddVarTab[NB_OF_VAR];
@ -90,6 +93,61 @@ void conf_general_init(void) {
EE_Init();
}
/**
* Read app_configuration from EEPROM. If this fails, default values will be used.
*
* @param conf
* A pointer to a app_configuration struct to write the read configuration to.
*/
void conf_general_read_app_configuration(app_configuration *conf) {
bool is_ok = true;
uint8_t *conf_addr = (uint8_t*)conf;
uint16_t var;
for (unsigned int i = 0;i < (sizeof(app_configuration) / 2);i++) {
if (EE_ReadVariable(EEPROM_BASE_GENCONF + i, &var) == 0) {
conf_addr[2 * i] = (var >> 8) & 0xFF;
conf_addr[2 * i + 1] = var & 0xFF;
} else {
is_ok = false;
break;
}
}
// Set the default configuration
if (!is_ok) {
memset(conf, 0, sizeof(app_configuration));
conf->app_to_use = APP_NONE;
conf->app_ppm_use_rev = true;
conf->app_ppm_ctrl_type = PPM_CTRL_TYPE_CURRENT;
conf->app_ppm_pid_max_erpm = 15000;
}
}
/**
* Write app_configuration to EEPROM.
*
* @param conf
* A pointer to the configuration that should be stored.
*/
bool conf_general_store_app_configuration(app_configuration *conf) {
bool is_ok = true;
uint8_t *conf_addr = (uint8_t*)conf;
uint16_t var;
for (unsigned int i = 0;i < (sizeof(app_configuration) / 2);i++) {
var = (conf_addr[2 * i] << 8) & 0xFF00;
var |= conf_addr[2 * i + 1] & 0xFF;
if (EE_WriteVariable(EEPROM_BASE_GENCONF + i, var) != FLASH_COMPLETE) {
is_ok = false;
break;
}
}
return is_ok;
}
/**
* Read mc_configuration from EEPROM. If this fails, default values will be used.
*

View File

@ -41,7 +41,7 @@
//#define HW_VERSION_R2
/*
* Select only one motor configuration
* Select only one (default) motor configuration
*/
//#define MCCONF_OUTRUNNER1
#define MCCONF_OUTRUNNER2
@ -54,15 +54,17 @@
//#define MCCONF_HDD
/*
* Select which application to use (if any)
* Select which custom application to use. To configure the default applications and
* their settings, go to conf_general_read_app_configuration and enter the default init
* values.
*/
//#define USE_APP_RCCAR
//#define USE_APP_STEN
//#define USE_APP_GURGALOF
//#define USE_APP_UARTCOMM
// Functions
void conf_general_init(void);
void conf_general_read_app_configuration(app_configuration *conf);
bool conf_general_store_app_configuration(app_configuration *conf);
void conf_general_read_mc_configuration(mc_configuration *conf);
bool conf_general_store_mc_configuration(mc_configuration *conf);
bool conf_general_detect_motor_param(float current, float min_rpm, float low_duty,

View File

@ -47,13 +47,13 @@ typedef enum {
} mc_control_mode;
typedef struct {
volatile float cycle_int_limit;
volatile float cycle_int_limit_running;
volatile float cycle_int_limit_max;
volatile float comm_time_sum;
volatile float comm_time_sum_min_rpm;
volatile int32_t comms;
volatile uint32_t time_at_comm;
float cycle_int_limit;
float cycle_int_limit_running;
float cycle_int_limit_max;
float comm_time_sum;
float comm_time_sum_min_rpm;
int32_t comms;
uint32_t time_at_comm;
} mc_rpm_dep_struct;
typedef struct {
@ -96,4 +96,29 @@ typedef struct {
float cc_gain;
} mc_configuration;
// Applications to use
typedef enum {
APP_NONE = 0,
APP_PPM,
APP_UARTCOMM,
APP_CUSTOM
} app_use;
// PPM control types
typedef enum {
PPM_CTRL_TYPE_CURRENT = 0,
PPM_CTRL_TYPE_DUTY,
PPM_CTRL_TYPE_PID
} ppm_control_type;
typedef struct {
// Application to use
app_use app_to_use;
// PPM application settings
ppm_control_type app_ppm_ctrl_type;
float app_ppm_pid_max_erpm;
bool app_ppm_use_rev;
} app_configuration;
#endif /* DATATYPES_H_ */

9
main.c
View File

@ -248,6 +248,10 @@ float main_get_last_adc_isr_duration(void) {
}
void main_sample_print_data(bool at_start, uint16_t len, uint8_t decimation) {
if (len > ADC_SAMPLE_MAX_LEN) {
len = ADC_SAMPLE_MAX_LEN;
}
sample_len = len;
sample_int = decimation;
@ -275,7 +279,10 @@ int main(void) {
mcpwm_init(&mcconf);
comm_init();
app_init();
app_configuration appconf;
conf_general_read_app_configuration(&appconf);
app_init(&appconf);
// Threads
chThdCreateStatic(periodic_thread_wa, sizeof(periodic_thread_wa), NORMALPRIO, periodic_thread, NULL);