Commit 8d15240e authored by Pavel Semerad's avatar Pavel Semerad
Browse files

added number of channels to model config to get lower delay with lower number of channels

parent 194a2db0
*0.5.0 ()
global menu was restructuralized
added ability to select number of channels (2-MAX_CHANNELS) for each
model, less channels means less delay
*0.4.2 (13 Apr 2012)
added global setting to disable center/reset value beep
......
......@@ -69,13 +69,15 @@ Standard menu:
> menu MODEL will blink
> choose memory position where to save model config
> press ENTER/BACK to save it
- Model reset
- Model number of channels and Model reset
> choose menu NAME and press ENTER-long
> menu NAME will blink
> choose "C" for number of model channels or "r" for model reset
- reset will show NO/YES
- Subtrims
> choose menu TRIM and press ENTER-long
> menu TRIM will blink
> set subtrims for each channel
> press ENTER/BACK to end this submenu
- channel speed
> choose menu D/R and press ENTER-long
> menu D/R wil blink
......@@ -230,7 +232,7 @@ Global setup menu:
number of ADC values A_4/A_1
b beeps
key beep K_N/K_Y
center/reset beep C_N/C_Y
value at center/reset beep C_N/C_Y
poweron beep P_N/P_Y
d long press key delay 100...1000 miliseconds
r global or all models reset
......
cm.channels - number of channels for model, settable because when using
lower number of channels, PPM frame length will be shorter
not-centered poweron warning with separate global option
? linear CH3 with potentiometer
......
......@@ -403,7 +403,7 @@ static void calc_loop(void) {
// channels 3-8, exclude mixed channels in the future
for (i = 3, bit = 0b100; i <= MAX_CHANNELS; i++, bit <<= 1) {
for (i = 3, bit = 0b100; i <= channels; i++, bit <<= 1) {
// check if channel was already mixed before (4WS, DIG)
if (menu_channels_mixed & bit) continue;
channel_params(i, channel_speed(menu_channel3_8[i - 3] * PPM(5), i));
......
......@@ -120,6 +120,8 @@ void config_model_set_default(void) {
NUM_MULTI_POSITION - 1);
memset(&cm.speed[0], 100, MAX_CHANNELS);
cm.stspd_return = 100;
cm.channels = MAX_CHANNELS - 1; // it is one lower to fit also 8
cm.unused = 0;
memcpy(&cm.key_mapping, &default_key_mapping, sizeof(config_key_mapping_s));
}
......
......@@ -57,7 +57,7 @@ typedef struct {
} config_global_s;
extern config_global_s config_global;
#define cg config_global
#define cg config_global
// threshold limits for steering/throttle
......@@ -115,8 +115,8 @@ typedef struct {
// change MAGIC number when changing model config
// also add code to setting default values
// 23 + 22(keys) + channels * 4 bytes
#define CONFIG_MODEL_MAGIC (0xfa20 | (MAX_CHANNELS - 1))
// 24 + 22(keys) + channels * 4 bytes
#define CONFIG_MODEL_MAGIC (0xf920 | (MAX_CHANNELS - 1))
typedef struct {
u8 name[3];
u8 reverse; // bit for each channel
......@@ -144,12 +144,14 @@ typedef struct {
#define stspd_turn speed[0]
#define thspd speed[1]
u8 stspd_return; // steering speed return
u8 channels:3; // number of channels for this model - 1
u8 unused:5;
config_key_mapping_s key_mapping;
} config_model_s;
extern config_model_s config_model;
#define cm config_model
#define ck cm.key_mapping
#define cm config_model
#define ck cm.key_mapping
......
......@@ -364,9 +364,53 @@ static void menu_name(void) {
}
// reset model to default values
static void menu_reset_model(void) {
config_model_set_default();
// set number of model channels
static u8 menu_channels(u8 val_id, u8 action, u8 *chars_blink) {
// change value
if (action == 1)
cm.channels = (u8)(menu_change_val(cm.channels + 1, 2,
MAX_CHANNELS, 1, 0) - 1);
// show value
lcd_7seg(L7_C);
lcd_segment(LS_SYM_CHANNEL, LS_ON);
lcd_char_num3(cm.channels + 1);
return 1; // only one value
}
// reset model to defaults
static u8 menu_reset_model(u8 val_id, u8 action, u8 *chars_blink) {
// change value
if (action == 1)
menu_tmp_flag ^= 1;
// select next value, reset when flag is set
else if (action == 2) {
if (menu_tmp_flag) {
menu_tmp_flag = 0;
config_model_set_default();
buzzer_on(60, 0, 1);
}
}
// show value
lcd_7seg(L7_R);
lcd_chars(menu_tmp_flag ? "YES" : "NO ");
return 1; // only one value
}
static const menu_func_t chanres_funcs[] = {
menu_channels,
menu_reset_model,
};
// set number of model channels, reset model to default values
static void menu_channels_reset(void) {
lcd_set_blink(LMENU, LB_SPC);
menu_common(chanres_funcs, sizeof(chanres_funcs) / sizeof(void *), 0);
lcd_set_blink(LMENU, LB_OFF);
config_model_save();
apply_model_config();
}
......@@ -380,7 +424,7 @@ void sf_reverse(u8 channel, u8 change) {
else lcd_chars("NOR");
}
@inline static void menu_reverse(void) {
menu_channel(MAX_CHANNELS, 0, 0, sf_reverse);
menu_channel(channels, 0, 0, sf_reverse);
}
......@@ -393,7 +437,7 @@ void sf_endpoint(u8 channel, u8 change) {
}
static void menu_endpoint(void) {
lcd_segment(LS_SYM_PERCENT, LS_ON);
menu_channel(MAX_CHANNELS, 0xff, 0xfc, sf_endpoint);
menu_channel(channels, 0xff, 0xfc, sf_endpoint);
lcd_segment(LS_SYM_PERCENT, LS_OFF);
}
......@@ -421,7 +465,7 @@ static void sf_subtrim(u8 channel, u8 change) {
}
static void menu_subtrim(void) {
lcd_set_blink(LMENU, LB_SPC);
menu_channel(MAX_CHANNELS, 0, 0xfc, sf_subtrim);
menu_channel(channels, 0, 0xfc, sf_subtrim);
lcd_set_blink(LMENU, LB_OFF);
}
......@@ -457,7 +501,7 @@ static void sf_speed(u8 channel, u8 change) {
static void menu_speed(void) {
lcd_set_blink(LMENU, LB_SPC);
lcd_segment(LS_SYM_PERCENT, LS_ON);
menu_channel(MAX_CHANNELS, 0x3, 0, sf_speed);
menu_channel(channels, 0x3, 0, sf_speed);
lcd_segment(LS_SYM_PERCENT, LS_OFF);
lcd_set_blink(LMENU, LB_OFF);
}
......@@ -544,7 +588,7 @@ static void select_menu(void) {
}
}
else if (menu == LM_NAME) {
if (btnl(BTN_ENTER)) menu_reset_model();
if (btnl(BTN_ENTER)) menu_channels_reset();
else menu_name();
}
else if (menu == LM_REV) {
......
......@@ -108,9 +108,11 @@ extern u8 *menu_et_function_name(u8 n);
extern s8 menu_et_function_idx(u8 n);
extern u8 menu_et_function_long_special(u8 n);
extern u8 menu_et_function_is_list(u8 n);
extern u8 menu_et_function_is_allowed(u8 n);
extern u8 *menu_key_function_name(u8 n);
extern s8 menu_key_function_idx(u8 n);
extern u8 menu_key_function_2state(u8 n);
extern u8 menu_key_function_is_allowed(u8 n);
extern const u8 steps_map[];
#define STEPS_MAP_SIZE 11
extern const u16 et_buttons[][2];
......
......@@ -54,7 +54,7 @@ void apply_model_config(void) {
u8 i, autorepeat = 0;
// set number of channels for this model
ppm_set_channels(MAX_CHANNELS);
ppm_set_channels((u8)(cm.channels + 1));
// set mixed channels to ignore them from menu_channel3_8
menu_channels_mixed = 0;
......
......@@ -56,7 +56,7 @@ static const u8 trim_buttons[][4] = {
static u8 km_trim(u8 trim_id, u8 val_id, u8 action) {
config_et_map_s *etm = &ck.et_map[trim_id];
u8 id = val_id;
u8 idx, btn;
u8 idx, btn, new_idx = 0;
if (action == 1) {
// change value
......@@ -74,12 +74,15 @@ static u8 km_trim(u8 trim_id, u8 val_id, u8 action) {
else {
if (++idx > trim_functions_max) idx = 0;
}
if (trim_functions[idx]) break; // we have it
new_idx = trim_functions[idx];
if (!new_idx) continue; // empty slot
new_idx--; // was one more
if (menu_et_function_is_allowed(new_idx)) break; // we have it
}
// set values to defaults
((u16 *)etm)[0] = 0;
((u16 *)etm)[1] = 0;
etm->function = (u8)(trim_functions[idx] - 1);
etm->function = new_idx;
if (etm->function)
etm->is_trim = etm->is_trim2 = 1;
break;
......@@ -219,7 +222,7 @@ static u8 km_trim(u8 trim_id, u8 val_id, u8 action) {
static u8 km_key(u8 key_id, u8 val_id, u8 action) {
config_key_map_s *km = &ck.key_map[key_id];
u8 id = val_id;
u8 idx;
u8 idx, new_idx = 0;
if (action == 1) {
// change value
......@@ -236,7 +239,10 @@ static u8 km_key(u8 key_id, u8 val_id, u8 action) {
else {
if (++idx > key_functions_max) idx = 0;
}
if (key_functions[idx]) break; // we have it
new_idx = key_functions[idx];
if (!new_idx) continue; // empty slot
new_idx--; // was one more
if (menu_key_function_is_allowed(new_idx)) break; // we have it
}
// set values to defaults
if (km->momentary) *(u16 *)km = 0; // was momentary, zero all
......@@ -245,7 +251,7 @@ static u8 km_key(u8 key_id, u8 val_id, u8 action) {
km->reverse = 0;
km->previous_val = 0;
}
km->function = (u8)(key_functions[idx] - 1);
km->function = new_idx;
break;
case 2:
// momentary setting
......@@ -275,12 +281,15 @@ static u8 km_key(u8 key_id, u8 val_id, u8 action) {
else {
if (++idx > key_functions_max) idx = 0;
}
if (key_functions[idx]) break; // we have it
new_idx = key_functions[idx];
if (!new_idx) continue; // empty slot
new_idx--; // was one more
if (menu_key_function_is_allowed(new_idx)) break; // we have it
}
// set values to defaults
km->reverse_long = 0;
km->previous_val_long = 0;
km->function_long = (u8)(key_functions[idx] - 1);
km->function_long = new_idx;
break;
case 6:
// reverse_long
......
......@@ -44,7 +44,7 @@ static u8 mix_4WS(u8 val_id, u8 action, u8 *chars_blink) {
// channel number/off
val = cm.channel_4WS;
if (!val) val = 2;
val = (u8)menu_change_val(val, 2, MAX_CHANNELS, 1, 1);
val = (u8)menu_change_val(val, 2, channels, 1, 1);
if (val == 2) cm.channel_4WS = 0;
else cm.channel_4WS = val;
break;
......@@ -103,7 +103,7 @@ static u8 mix_DIG(u8 val_id, u8 action, u8 *chars_blink) {
// channel number/off
val = cm.channel_DIG;
if (!val) val = 2;
val = (u8)menu_change_val(val, 1, MAX_CHANNELS, 1, 1);
val = (u8)menu_change_val(val, 1, channels, 1, 1);
if (val == 2) cm.channel_DIG = 0;
else cm.channel_DIG = val;
break;
......@@ -150,10 +150,10 @@ static u8 mix_MultiPosition(u8 val_id, u8 action, u8 *chars_blink) {
// channel number/off
val = cm.channel_MP;
if (!val) val = 2;
else if (val == MP_DIG) val = MAX_CHANNELS + 1;
val = (u8)menu_change_val(val, 2, MAX_CHANNELS + 1, 1, 1);
else if (val == MP_DIG) val = (s8)(channels + 1);
val = (u8)menu_change_val(val, 2, channels + 1, 1, 1);
if (val == 2) cm.channel_MP = 0;
else if (val == MAX_CHANNELS + 1) cm.channel_MP = MP_DIG;
else if (val == (s8)(channels + 1)) cm.channel_MP = MP_DIG;
else cm.channel_MP = val;
}
else {
......@@ -178,7 +178,7 @@ static u8 mix_MultiPosition(u8 val_id, u8 action, u8 *chars_blink) {
|| ++id > (NUM_MULTI_POSITION + 1)) id = 1;
}
// allow forcing channel value
if (id > 1 && cm.channel_MP && cm.channel_MP <= MAX_CHANNELS) {
if (id > 1 && cm.channel_MP && cm.channel_MP <= channels) {
menu_force_value_channel = cm.channel_MP;
}
else menu_force_value_channel = 0;
......
......@@ -102,6 +102,7 @@ typedef struct {
#define EF_LEFT 0b00000010
#define EF_PERCENT 0b00000100
#define EF_LIST 0b00001000
#define EF_NO2CHANNELS 0b00010000
#define EF_NOCONFIG 0b00100000
#define EF_NOCHANNEL 0b01000000
#define EF_BLINK 0b10000000
......@@ -223,11 +224,11 @@ static const et_functions_s et_functions[] = {
#endif
#endif
#endif
{ 36, "4WS", LM_EPO, EF_BLINK | EF_PERCENT | EF_NOCHANNEL | EF_NOCONFIG,
{ 36, "4WS", LM_EPO, EF_BLINK | EF_PERCENT | EF_NOCHANNEL | EF_NOCONFIG | EF_NO2CHANNELS,
4, &menu_4WS_mix, -100, 100, 0, MIX_FAST, NULL, NULL, NULL },
{ 37, "DIG", LM_EPO, EF_BLINK | EF_PERCENT | EF_NOCHANNEL | EF_NOCONFIG,
{ 37, "DIG", LM_EPO, EF_BLINK | EF_PERCENT | EF_NOCHANNEL | EF_NOCONFIG | EF_NO2CHANNELS,
L7_D, &menu_DIG_mix, -100, 100, 0, MIX_FAST, NULL, NULL, NULL },
{ 38, "MPO", 0, EF_LIST | EF_NOCONFIG, 0, &menu_MP_index,
{ 38, "MPO", 0, EF_LIST | EF_NOCONFIG | EF_NO2CHANNELS, 0, &menu_MP_index,
0, NUM_MULTI_POSITION - 1, 0, 1, set_MP, show_MP, NULL },
};
#define ET_FUNCTIONS_SIZE (sizeof(et_functions) / sizeof(et_functions_s))
......@@ -256,6 +257,18 @@ u8 menu_et_function_is_list(u8 n) {
return (u8)(et_functions[n].flags & EF_LIST);
}
// return 1 if given function is allowed
u8 menu_et_function_is_allowed(u8 n) {
et_functions_s *etf = &et_functions[n];
if (n == 0) return 1; // OFF is always allowed
// check number of channels
if ((etf->flags & EF_NO2CHANNELS) && channels == 2)
return 0; // not for 2 channels
if (etf->flags & EF_NOCHANNEL) return 1; // channel not used
if (etf->channel <= channels) return 1; // channel is OK
return 0; // channel too big
}
// find function by name
static et_functions_s *menu_et_function_find_name(u8 *name) {
u8 i, *n;
......@@ -584,6 +597,7 @@ typedef struct {
u8 flags; // bits below
void (*func)(u8 *id, u8 *param, u8 flags, s16 *prev_val); // function to process key, flags below
void *param; // param given to function
u8 channel; // which channel it operates, only to eliminate excess channels
} key_functions_s;
// flags bits
#define KF_NONE 0
......@@ -739,37 +753,37 @@ static void kf_battery_low_shutup(u8 *id, u8 *param, u8 flags, s16 *pv) {
// table of key functions
static const key_functions_s key_functions[] = {
{ 0, "OFF", KF_NONE, NULL, NULL },
{ 1, "CH3", KF_2STATE, kf_set_switch, NULL },
{ 7, "C3R", KF_NONE, kf_reset, "CH3" },
{ 0, "OFF", KF_NONE, NULL, NULL, 0 },
{ 1, "CH3", KF_2STATE, kf_set_switch, NULL, 3 },
{ 7, "C3R", KF_NONE, kf_reset, "CH3", 3 },
#if MAX_CHANNELS >= 4
{ 2, "CH4", KF_2STATE, kf_set_switch, NULL },
{ 8, "C4R", KF_NONE, kf_reset, "CH4" },
{ 2, "CH4", KF_2STATE, kf_set_switch, NULL, 4 },
{ 8, "C4R", KF_NONE, kf_reset, "CH4", 4 },
#if MAX_CHANNELS >= 5
{ 3, "CH5", KF_2STATE, kf_set_switch, NULL },
{ 9, "C5R", KF_NONE, kf_reset, "CH5" },
{ 3, "CH5", KF_2STATE, kf_set_switch, NULL, 5 },
{ 9, "C5R", KF_NONE, kf_reset, "CH5", 5 },
#if MAX_CHANNELS >= 6
{ 4, "CH6", KF_2STATE, kf_set_switch, NULL },
{ 10, "C6R", KF_NONE, kf_reset, "CH6" },
{ 4, "CH6", KF_2STATE, kf_set_switch, NULL, 6 },
{ 10, "C6R", KF_NONE, kf_reset, "CH6", 6 },
#if MAX_CHANNELS >= 7
{ 5, "CH7", KF_2STATE, kf_set_switch, NULL },
{ 11, "C7R", KF_NONE, kf_reset, "CH7" },
{ 5, "CH7", KF_2STATE, kf_set_switch, NULL, 7 },
{ 11, "C7R", KF_NONE, kf_reset, "CH7", 7 },
#if MAX_CHANNELS >= 8
{ 6, "CH8", KF_2STATE, kf_set_switch, NULL },
{ 12, "C8R", KF_NONE, kf_reset, "CH8" },
{ 6, "CH8", KF_2STATE, kf_set_switch, NULL, 8 },
{ 12, "C8R", KF_NONE, kf_reset, "CH8", 8 },
#endif
#endif
#endif
#endif
#endif
{ 13, "4WS", KF_2STATE, kf_4ws, NULL },
{ 14, "DIG", KF_2STATE, kf_set_switch, NULL },
{ 16, "MPO", KF_NONE, kf_multi_position, NULL },
{ 17, "MPR", KF_NONE, kf_multi_position_reset, NULL },
{ 15, "DGR", KF_NONE, kf_reset, "DIG" },
{ 18, "LCI", KF_NOSHOW, kf_lap_count, NULL },
{ 19, "LCR", KF_NOSHOW, kf_lap_count_reset, NULL },
{ 20, "BLS", KF_NOSHOW, kf_battery_low_shutup, NULL }, // default END-long
{ 13, "4WS", KF_2STATE, kf_4ws, NULL, 3 },
{ 14, "DIG", KF_2STATE, kf_set_switch, NULL, 3 },
{ 15, "DGR", KF_NONE, kf_reset, "DIG", 3 },
{ 16, "MPO", KF_NONE, kf_multi_position, NULL, 3 },
{ 17, "MPR", KF_NONE, kf_multi_position_reset, NULL, 3 },
{ 18, "LCI", KF_NOSHOW, kf_lap_count, NULL, 0 },
{ 19, "LCR", KF_NOSHOW, kf_lap_count_reset, NULL, 0 },
{ 20, "BLS", KF_NOSHOW, kf_battery_low_shutup, NULL, 0 }, // default END-long
};
#define KEY_FUNCTIONS_SIZE (sizeof(key_functions) / sizeof(key_functions_s))
......@@ -792,6 +806,15 @@ u8 menu_key_function_2state(u8 n) {
return (u8)(key_functions[n].flags & KF_2STATE);
}
// return 1 if given function is allowed
u8 menu_key_function_is_allowed(u8 n) {
key_functions_s *kf = &key_functions[n];
if (n == 0) return 1; // OFF is always allowed
// check number of channels
if (kf->channel <= channels) return 1; // channel is OK
return 0; // channel too big
}
// delete all symbols and clean 7seg
static void menu_key_empty_id(void) {
menu_clear_symbols();
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment