From 092bd3b3aca1c8d219a2da248ef0eff4ab6fa130 Mon Sep 17 00:00:00 2001 From: Pavel Semerad Date: Wed, 18 May 2011 14:11:55 +0200 Subject: [PATCH] dualrate split throttle to forward/back, expo/dualrate menu use arrows at channel 2 --- TODO | 1 - calc.c | 12 ++++++++++-- config.c | 5 +++-- config.h | 13 ++++++++----- menu.c | 49 +++++++++++++++++++++++++++++++++++-------------- 5 files changed, 56 insertions(+), 24 deletions(-) diff --git a/TODO b/TODO index 9b0bc58..7b2a118 100644 --- a/TODO +++ b/TODO @@ -1,6 +1,5 @@ ? CH3 button momentary model specific -? D/R split forward/back diff --git a/calc.c b/calc.c index 8610d56..3a903f4 100644 --- a/calc.c +++ b/calc.c @@ -50,6 +50,7 @@ void calc_init(void) { // limit adc value to -5000..5000 (standard servo signal * 10) +// also apply trim static s16 channel_calib(u16 adc_ovs, u16 call, u16 calm, u16 calr, u16 dead, s16 trim) { s16 val; @@ -70,6 +71,7 @@ static s16 channel_calib(u16 adc_ovs, u16 call, u16 calm, u16 calr, } // apply reverse, endpoint, subtrim +// set value to ppm channel static void rev_epo_subtrim(u8 channel, s16 inval) { s16 val = (s16)(((s32)inval * cm.endpoint[channel-1][(u8)(inval < 0 ? 0 : 1)] + 50) / 100); @@ -100,6 +102,11 @@ static s16 expo(s16 inval, s8 exp) { return neg ? -val : val; } +// apply dualrate +@inline static s16 dualrate(s16 val, u8 dr) { + return (s16)(((s32)val * dr + 50) / 100); +} + @@ -121,7 +128,7 @@ static void calc_loop(void) { cg.steering_dead_zone << ADC_OVS_SHIFT, cm.trim[0] * 10); val = expo(val, cm.expo_steering); - rev_epo_subtrim(1, (s16)(((s32)val * cm.dualrate[0] + 50) / 100)); + rev_epo_subtrim(1, dualrate(val, cm.dr_steering)); @@ -159,7 +166,8 @@ static void calc_loop(void) { abs_state = 0; } } - rev_epo_subtrim(2, (s16)(((s32)val * cm.dualrate[1] + 50) / 100)); + rev_epo_subtrim(2, dualrate(val, + (u8)(val < 0 ? cm.dr_forward : cm.dr_back))); diff --git a/config.c b/config.c index 9dc07c0..f94d66a 100644 --- a/config.c +++ b/config.c @@ -85,8 +85,9 @@ void config_model_set_default(void) { memset(cm.endpoint, 100, MAX_CHANNELS * 2); cm.trim[0] = 0; cm.trim[1] = 0; - cm.dualrate[0] = 100; - cm.dualrate[1] = 100; + cm.dr_steering = 100; + cm.dr_forward = 100; + cm.dr_back = 100; cm.expo_steering = 0; cm.expo_forward = 0; cm.expo_back = 0; diff --git a/config.h b/config.h index 13c42c1..de38451 100644 --- a/config.h +++ b/config.h @@ -70,7 +70,7 @@ extern config_global_s config_global; // change MAGIC number when changing model config // also add code to setting default values -#define CONFIG_MODEL_MAGIC (0xe718 | (MAX_CHANNELS - 1)) +#define CONFIG_MODEL_MAGIC (0xff20 | (MAX_CHANNELS - 1)) typedef struct { u8 channels; // number of channels for this model u8 name[3]; @@ -78,16 +78,19 @@ typedef struct { s8 subtrim[MAX_CHANNELS]; u8 endpoint[MAX_CHANNELS][2]; s8 trim[2]; // for steering and throttle - u8 dualrate[2]; // for steering and throttle + u8 dualrate[3]; // for steering and throttle s8 expo[3]; // steering/forward/back u8 abs_type; } config_model_s; extern config_model_s config_model; #define cm config_model -#define expo_steering expo[0] -#define expo_forward expo[1] -#define expo_back expo[2] +#define dr_steering dualrate[0] +#define dr_forward dualrate[1] +#define dr_back dualrate[2] +#define expo_steering expo[0] +#define expo_forward expo[1] +#define expo_back expo[2] diff --git a/menu.c b/menu.c index fa4e9f0..2242833 100644 --- a/menu.c +++ b/menu.c @@ -196,26 +196,44 @@ static void menu_set_adc_direction(u8 channel) { } } } -static void menu_channel(u8 end_channel, u8 use_adc, void (*subfunc)(u8, u8)) { - u8 channel = 1; - u8 chan_val = 0; // now in channel - u8 last_direction = menu_adc_direction; - - if (use_adc) { +static _Bool menu_set_adc(u8 channel, u8 use_adc) { + if ((u8)(use_adc & (1 << (channel - 1)))) { + // use ADC + if (menu_adc_direction) { + lcd_segment(LS_SYM_LEFT, LS_OFF); + lcd_segment(LS_SYM_RIGHT, LS_ON); + } + else { + lcd_segment(LS_SYM_LEFT, LS_ON); + lcd_segment(LS_SYM_RIGHT, LS_OFF); + } menu_wants_adc = 1; menu_set_adc_direction(channel); + return 1; } + else { + // don't use ADC + lcd_segment(LS_SYM_LEFT, LS_OFF); + lcd_segment(LS_SYM_RIGHT, LS_OFF); + menu_wants_adc = 0; + return 0; + } +} +static void menu_channel(u8 end_channel, u8 use_adc, void (*subfunc)(u8, u8)) { + u8 channel = 1; + _Bool chan_val = 0; // now in channel + _Bool adc_active; + u8 last_direction; // show CHANNEL lcd_segment(LS_SYM_MODELNO, LS_OFF); - lcd_segment(LS_SYM_LEFT, (u8)(use_adc ? LS_ON : LS_OFF)); - lcd_segment(LS_SYM_RIGHT, LS_OFF); lcd_segment(LS_SYM_CHANNEL, LS_ON); + // show channel number and possible direction + menu_adc_direction = 0; lcd_7seg(channel); lcd_set_blink(L7SEG, LB_SPC); - menu_adc_direction = 0; - if (use_adc) menu_set_adc_direction(channel); + adc_active = menu_set_adc(channel, use_adc); subfunc((u8)(channel - 1), 0); // show current value lcd_update(); @@ -226,7 +244,7 @@ static void menu_channel(u8 end_channel, u8 use_adc, void (*subfunc)(u8, u8)) { if (btn(BTN_BACK | BTN_ENTER)) break; last_direction = menu_adc_direction; - if (use_adc) menu_set_adc_direction(channel); + if (adc_active) menu_set_adc_direction(channel); if (btn(BTN_ROT_ALL)) { if (chan_val) { @@ -244,6 +262,7 @@ static void menu_channel(u8 end_channel, u8 use_adc, void (*subfunc)(u8, u8)) { } lcd_7seg(channel); lcd_set_blink(L7SEG, LB_SPC); + adc_active = menu_set_adc(channel, use_adc); subfunc((u8)(channel - 1), 0); } lcd_update(); @@ -499,7 +518,7 @@ void sf_endpoint(u8 channel, u8 change) { } static void menu_endpoint(void) { lcd_segment(LS_SYM_PERCENT, LS_ON); - menu_channel(MAX_CHANNELS, 1, sf_endpoint); + menu_channel(MAX_CHANNELS, 0xff, sf_endpoint); lcd_segment(LS_SYM_PERCENT, LS_OFF); } @@ -533,12 +552,13 @@ static void menu_subtrim(void) { // set dualrate static void sf_dualrate(u8 channel, u8 change) { u8 *addr = &cm.dualrate[channel]; + if (channel == 1 && menu_adc_direction) addr = &cm.dualrate[2]; if (change) *addr = (u8)menu_change_val(*addr, 0, 100, 5, 0); lcd_char_num3(*addr); } static void menu_dualrate(void) { lcd_segment(LS_SYM_PERCENT, LS_ON); - menu_channel(2, 0, sf_dualrate); + menu_channel(2, 0x2, sf_dualrate); lcd_segment(LS_SYM_PERCENT, LS_OFF); } @@ -546,12 +566,13 @@ static void menu_dualrate(void) { // set expos static void sf_expo(u8 channel, u8 change) { s8 *addr = &cm.expo[channel]; + if (channel == 1 && menu_adc_direction) addr = &cm.expo[2]; if (change) *addr = (s8)menu_change_val(*addr, -99, 99, 5, 0); lcd_char_num2(*addr); } static void menu_expo(void) { lcd_segment(LS_SYM_PERCENT, LS_ON); - menu_channel(3, 0, sf_expo); + menu_channel(2, 0x2, sf_expo); lcd_segment(LS_SYM_PERCENT, LS_OFF); }