Commit 56249627 authored by Pavel Semerad's avatar Pavel Semerad
Browse files

added up and down timers with throttle trigger

parent 925ef1c4
...@@ -3,6 +3,7 @@ ...@@ -3,6 +3,7 @@
added ability to select number of channels (2-MAX_CHANNELS) for each added ability to select number of channels (2-MAX_CHANNELS) for each
model, less channels means less delay model, less channels means less delay
poweron warn when not-centered now has separate global option poweron warn when not-centered now has separate global option
added up/down timers with throttle trigger start
*0.4.2 (13 Apr 2012) *0.4.2 (13 Apr 2012)
added global setting to disable center/reset value beep added global setting to disable center/reset value beep
......
...@@ -27,7 +27,11 @@ timer losikid ...@@ -27,7 +27,11 @@ timer losikid
ENTER selects timers settings ENTER selects timers settings
timer type timer type
lap timer - alarm, @lap, @stop, reset (at lap times screen) lap timer - alarm, @lap, @stop, reset (at lap times screen)
lap counter - @lap, @reset, alarm after num laps ignore lap button for 3s
show lap time for 3s
lap counter - @lap, @reset
alarm after num laps
ignore lap button for 3s
count up - alarm, @pause, @reset count up - alarm, @pause, @reset
cound down - alarm, @pause, @reset (save rest to lap timers) cound down - alarm, @pause, @reset (save rest to lap timers)
? lap timer down - laps_count ? lap timer down - laps_count
......
...@@ -368,6 +368,28 @@ static void check_inactivity(void) { ...@@ -368,6 +368,28 @@ static void check_inactivity(void) {
} }
// check throttle trigger and start timer
#define THROTTLE_TRIGGER_START 30
static void check_throttle_trigger(void) {
u8 i, tbit, type;
// nothing when throttle is not little forward
if (ADC_OVS(throttle) >= (cg.calib_throttle_mid - THROTTLE_TRIGGER_START)) return;
for (i =0, tbit = 1; i < TIMER_NUM; i++, tbit <<= 1) {
type = TIMER_TYPE(i);
// check if possible
if (type == TIMER_OFF || type == TIMER_LAPCNT) continue; // not for this type
if (!(menu_timer_throttle & tbit)) continue; // not set for this timer
// start timer
menu_timer_running |= tbit;
menu_timer_throttle &= (u8)~tbit;
// awake MENU to possibly display changing time
awake(MENU);
}
}
...@@ -400,6 +422,7 @@ void input_read_first_values(void) { ...@@ -400,6 +422,7 @@ void input_read_first_values(void) {
static void input_loop(void) { static void input_loop(void) {
while (1) { while (1) {
read_keys(); read_keys();
if (menu_timer_throttle) check_throttle_trigger();
check_inactivity(); check_inactivity();
update_battery(); update_battery();
stop(); stop();
......
...@@ -99,7 +99,7 @@ static void main_screen(u8 item) { ...@@ -99,7 +99,7 @@ static void main_screen(u8 item) {
} }
else { else {
// timers // timers
menu_timer_show((u8)(item - MS_TIMER1)); menu_timer_show((u8)(item - MS_TIMER0));
} }
lcd_update(); lcd_update();
} }
...@@ -666,9 +666,9 @@ static void menu_loop(void) { ...@@ -666,9 +666,9 @@ static void menu_loop(void) {
// Enter long key - global/calibrate/key-test // Enter long key - global/calibrate/key-test
if (btnl(BTN_ENTER)) { if (btnl(BTN_ENTER)) {
if (menu_main_screen >= MS_TIMER1) { if (menu_main_screen >= MS_TIMER0) {
key_beep(); key_beep();
menu_timer_lap_times((u8)(menu_main_screen - MS_TIMER1)); menu_timer_lap_times((u8)(menu_main_screen - MS_TIMER0));
btnra(); btnra();
} }
else if (adc_steering_ovs > (CALIB_ST_MID_HIGH << ADC_OVS_SHIFT)) else if (adc_steering_ovs > (CALIB_ST_MID_HIGH << ADC_OVS_SHIFT))
...@@ -681,8 +681,8 @@ static void menu_loop(void) { ...@@ -681,8 +681,8 @@ static void menu_loop(void) {
// Enter key - menu // Enter key - menu
else if (btn(BTN_ENTER)) { else if (btn(BTN_ENTER)) {
key_beep(); key_beep();
if (menu_main_screen >= MS_TIMER1) if (menu_main_screen >= MS_TIMER0)
menu_timer_setup((u8)(menu_main_screen - MS_TIMER1)); menu_timer_setup((u8)(menu_main_screen - MS_TIMER0));
else select_menu(); else select_menu();
btnra(); btnra();
} }
...@@ -744,6 +744,10 @@ void menu_init(void) { ...@@ -744,6 +744,10 @@ void menu_init(void) {
else if (cg.poweron_beep) beep(30); else if (cg.poweron_beep) beep(30);
} }
// reset global timers
menu_timer_clear(0, 1);
menu_timer_clear(1, 1);
// read model config from eeprom // read model config from eeprom
menu_load_model(); menu_load_model();
......
...@@ -122,8 +122,8 @@ extern void menu_buttons_initialize(void); ...@@ -122,8 +122,8 @@ extern void menu_buttons_initialize(void);
extern u8 menu_main_screen; extern u8 menu_main_screen;
#define MS_NAME 0 #define MS_NAME 0
#define MS_BATTERY 1 #define MS_BATTERY 1
#define MS_TIMER1 2 #define MS_TIMER0 2
#define MS_TIMER2 3 #define MS_TIMER1 3
#define MS_MAX 4 #define MS_MAX 4
// common menus, select item in 7SEG and then modify its setting at CHR3 // common menus, select item in 7SEG and then modify its setting at CHR3
// val_id: 1..num_values - which param of this item to change // val_id: 1..num_values - which param of this item to change
...@@ -156,6 +156,8 @@ extern void menu_common(menu_func_t *menu_funcs, u8 menu_nitems, u8 use_stop); ...@@ -156,6 +156,8 @@ extern void menu_common(menu_func_t *menu_funcs, u8 menu_nitems, u8 use_stop);
// menu task will be waked-up periodically to show timer value // menu task will be waked-up periodically to show timer value
extern _Bool menu_timer_wakeup; extern _Bool menu_timer_wakeup;
extern u8 menu_timer_running; // running timers, one bit for one timer extern u8 menu_timer_running; // running timers, one bit for one timer
extern u8 menu_timer_direction; // up(0)/down(1) timer direction
extern u8 menu_timer_alarmed; // down timer was over, one bit for one timer
extern @near u8 menu_timer_throttle; // throttle start, one bit for one timer extern @near u8 menu_timer_throttle; // throttle start, one bit for one timer
typedef struct { typedef struct {
...@@ -168,10 +170,12 @@ extern @near menu_timer_s menu_timer[]; // actual timer values ...@@ -168,10 +170,12 @@ extern @near menu_timer_s menu_timer[]; // actual timer values
tsec = pt->sec; \ tsec = pt->sec; \
thdr = pt->hdr; \ thdr = pt->hdr; \
rim(); rim();
extern @near u16 menu_timer_alarm[]; // alarm in seconds
void menu_timer_show(u8 tid); void menu_timer_show(u8 tid);
void menu_timer_setup(u8 tid); void menu_timer_setup(u8 tid);
void menu_timer_lap_times(u8 tid); void menu_timer_lap_times(u8 tid);
void menu_timer_clear(u8 tid, u8 laps);
void kf_menu_timer_start(u8 *id, u8 *param, u8 flags, s16 *pv); void kf_menu_timer_start(u8 *id, u8 *param, u8 flags, s16 *pv);
void kf_menu_timer_reset(u8 *id, u8 *param, u8 flags, s16 *pv); void kf_menu_timer_reset(u8 *id, u8 *param, u8 flags, s16 *pv);
......
...@@ -32,8 +32,11 @@ _Bool menu_timer_wakeup; ...@@ -32,8 +32,11 @@ _Bool menu_timer_wakeup;
// actual timer values // actual timer values
u8 menu_timer_running; // running timers u8 menu_timer_running; // running timers
u8 menu_timer_direction; // up(0)/down(1) timer direction
u8 menu_timer_alarmed; // down timer was over, one bit for one timer
@near u8 menu_timer_throttle; // throttle start for each timer @near u8 menu_timer_throttle; // throttle start for each timer
@near menu_timer_s menu_timer[TIMER_NUM]; // actual timer values @near menu_timer_s menu_timer[TIMER_NUM]; // actual timer values
@near u16 menu_timer_alarm[TIMER_NUM]; // alarm in seconds
// number of laps // number of laps
static @near u8 timer_lap_count[TIMER_NUM]; static @near u8 timer_lap_count[TIMER_NUM];
// time for each lap // time for each lap
...@@ -43,10 +46,76 @@ static @near menu_timer_s timer_lap_time[TIMER_NUM][TIMER_MAX_LAPS]; ...@@ -43,10 +46,76 @@ static @near menu_timer_s timer_lap_time[TIMER_NUM][TIMER_MAX_LAPS];
// show timer value on 3-char display
// time format - left-chars right-chars
// 00.0 % - 2-minutes, 1-10ths seconds
// 000 % - 1-minutes, 2-seconds
// 00.0 - 2-seconds, 1-0.1 seconds
// 000 - 1-seconds, 2-0.01 seconds
static void timer_value(menu_timer_s *pt) {
u16 tsec;
u8 min, sec, hdr;
// atomically read timer value
TIMER_READ(pt, tsec, hdr);
// convert to minutes, seconds, 0.01 seconds
min = (u8)(tsec / 60);
sec = (u8)(tsec % 60);
// show value
if (min) {
// show minutes
lcd_segment(LS_SYM_PERCENT, LS_ON);
// rounding up
if (hdr >= 50) sec++;
if (sec == 60) { sec = 0; min++; }
if (min >= 10) {
// format 00.0 %
lcd_segment(LS_SYM_DOT, LS_ON);
// rounding up
sec = (u8)((sec + 5) / 10);
if (sec == 6) { sec = 0; min++; }
lcd_char(LCHR1, (u8)(min / 10 + '0'));
lcd_char(LCHR2, (u8)(min % 10 + '0'));
lcd_char(LCHR3, (u8)(sec + '0'));
}
else {
// format 000 %
lcd_char(LCHR1, (u8)(min + '0'));
lcd_char(LCHR2, (u8)(sec / 10 + '0'));
lcd_char(LCHR3, (u8)(sec % 10 + '0'));
}
}
else {
// show seconds only
if (sec >= 10) {
// format 00.0
lcd_segment(LS_SYM_DOT, LS_ON);
// rounding up
hdr = (u8)((hdr + 5) / 10);
if (hdr == 10) { hdr = 0; sec++; }
lcd_char(LCHR1, (u8)(sec / 10 + '0'));
lcd_char(LCHR2, (u8)(sec % 10 + '0'));
lcd_char(LCHR3, (u8)(hdr + '0'));
}
else {
// format 000
lcd_char(LCHR1, (u8)(sec + '0'));
lcd_char(LCHR2, (u8)(hdr / 10 + '0'));
lcd_char(LCHR3, (u8)(hdr % 10 + '0'));
}
}
}
// show actual timer value // show actual timer value
void menu_timer_show(u8 tid) { void menu_timer_show(u8 tid) {
menu_timer_s *pt = &menu_timer[tid];
u8 type = TIMER_TYPE(tid); u8 type = TIMER_TYPE(tid);
u8 tbit = (u8)(1 << tid);
menu_clear_symbols(); menu_clear_symbols();
lcd_7seg((u8)(tid + 1)); lcd_7seg((u8)(tid + 1));
...@@ -55,14 +124,19 @@ void menu_timer_show(u8 tid) { ...@@ -55,14 +124,19 @@ void menu_timer_show(u8 tid) {
case TIMER_OFF: case TIMER_OFF:
lcd_chars("OFF"); lcd_chars("OFF");
return;
break; break;
case TIMER_UP: case TIMER_UP:
lcd_chars("NDY"); // XXX timer_value(pt);
break; break;
case TIMER_DOWN: case TIMER_DOWN:
lcd_chars("NDY"); // XXX timer_value(pt);
if (menu_timer_alarmed & tbit) {
lcd_segment(LS_SYM_VOLTS, LS_ON);
lcd_segment_blink(LS_SYM_VOLTS, LS_ON);
}
break; break;
case TIMER_LAP: case TIMER_LAP:
...@@ -71,22 +145,50 @@ void menu_timer_show(u8 tid) { ...@@ -71,22 +145,50 @@ void menu_timer_show(u8 tid) {
case TIMER_LAPCNT: case TIMER_LAPCNT:
lcd_char_num3(timer_lap_count[tid]); lcd_char_num3(timer_lap_count[tid]);
return;
break; break;
} }
// if timer is running, set it to wakeup this task
if (menu_timer_running & (u8)tbit)
menu_timer_wakeup = 1;
} }
// clear timer // clear timer
static void timer_clear(u8 tid) { void menu_timer_clear(u8 tid, u8 laps) {
menu_timer_s *pt = &menu_timer[tid]; menu_timer_s *pt = &menu_timer[tid];
pt->sec = 0; u8 type = TIMER_TYPE(tid);
u8 tbit = (u8)(1 << tid);
// set it not running
menu_timer_running &= (u8)~tbit;
// zero values, laps only when requested
pt->hdr = 0; pt->hdr = 0;
menu_timer_running &= (u8)~(u8)(1 << tid); menu_timer_alarmed &= (u8)~tbit;
timer_lap_count[tid] = 0; if (laps == 1 || (laps == 2 && type != TIMER_DOWN)) {
memset(&timer_lap_time[tid], 0, TIMER_MAX_LAPS * sizeof(menu_timer_s)); timer_lap_count[tid] = 0;
memset(&timer_lap_time[tid], 0, TIMER_MAX_LAPS * sizeof(menu_timer_s));
}
// set alarm
menu_timer_alarm[tid] = TIMER_ALARM(tid) * 60;
// set direction and seconds
if (type == TIMER_DOWN) {
// down timer
pt->sec = menu_timer_alarm[tid];
menu_timer_direction |= tbit;
}
else {
// up timer
pt->sec = 0;
menu_timer_direction &= (u8)~tbit;
}
} }
...@@ -101,7 +203,7 @@ static u8 timer_setup_throttle(u8 val_id, u8 action, u8 *chars_blink) { ...@@ -101,7 +203,7 @@ static u8 timer_setup_throttle(u8 val_id, u8 action, u8 *chars_blink) {
menu_timer_throttle ^= (u8)(1 << timer_id); menu_timer_throttle ^= (u8)(1 << timer_id);
// select next value // select next value
else if (action == 2) timer_clear(timer_id); else if (action == 2) menu_timer_clear(timer_id, 2);
// show value // show value
lcd_7seg(L7_H); lcd_7seg(L7_H);
...@@ -117,10 +219,11 @@ static u8 timer_setup_alarm(u8 val_id, u8 action, u8 *chars_blink) { ...@@ -117,10 +219,11 @@ static u8 timer_setup_alarm(u8 val_id, u8 action, u8 *chars_blink) {
if (action == 1) { if (action == 1) {
val = (u8)menu_change_val(val, 0, 255, TIMER_ALARM_FAST, 0); val = (u8)menu_change_val(val, 0, 255, TIMER_ALARM_FAST, 0);
TIMER_ALARM_SET(timer_id, val); TIMER_ALARM_SET(timer_id, val);
menu_timer_alarm[timer_id] = val * 60;
} }
// select next value // select next value
else if (action == 2) timer_clear(timer_id); else if (action == 2) menu_timer_clear(timer_id, 2);
// show value // show value
lcd_7seg(L7_A); lcd_7seg(L7_A);
...@@ -142,7 +245,7 @@ static u8 timer_setup_type(u8 val_id, u8 action, u8 *chars_blink) { ...@@ -142,7 +245,7 @@ static u8 timer_setup_type(u8 val_id, u8 action, u8 *chars_blink) {
} }
// select next value // select next value
else if (action == 2) timer_clear(timer_id); else if (action == 2) menu_timer_clear(timer_id, 1);
// show value // show value
lcd_7seg(L7_P); lcd_7seg(L7_P);
...@@ -182,10 +285,11 @@ void menu_timer_lap_times(u8 tid) { ...@@ -182,10 +285,11 @@ void menu_timer_lap_times(u8 tid) {
case TIMER_DOWN: case TIMER_DOWN:
case TIMER_LAP: case TIMER_LAP:
// show lap times XXX
break; break;
} }
// show lap times XXX
} }
...@@ -194,8 +298,9 @@ void menu_timer_lap_times(u8 tid) { ...@@ -194,8 +298,9 @@ void menu_timer_lap_times(u8 tid) {
// key functions // key functions
void kf_menu_timer_start(u8 *id, u8 *param, u8 flags, s16 *pv) { void kf_menu_timer_start(u8 *id, u8 *param, u8 flags, s16 *pv) {
u8 tid = (u8)(u16)param; u8 tid = (u8)(u16)param;
u8 type = TIMER_TYPE(tid);
menu_timer_s *pt = &menu_timer[tid]; menu_timer_s *pt = &menu_timer[tid];
u8 type = TIMER_TYPE(tid);
u8 tbit = (u8)(1 << tid);
switch (type) { switch (type) {
...@@ -204,11 +309,10 @@ void kf_menu_timer_start(u8 *id, u8 *param, u8 flags, s16 *pv) { ...@@ -204,11 +309,10 @@ void kf_menu_timer_start(u8 *id, u8 *param, u8 flags, s16 *pv) {
break; break;
case TIMER_UP: case TIMER_UP:
// XXX
break;
case TIMER_DOWN: case TIMER_DOWN:
// XXX // start/pause timer
menu_timer_running ^= tbit;
menu_timer_throttle &= (u8)~tbit;
break; break;
case TIMER_LAP: case TIMER_LAP:
...@@ -221,13 +325,14 @@ void kf_menu_timer_start(u8 *id, u8 *param, u8 flags, s16 *pv) { ...@@ -221,13 +325,14 @@ void kf_menu_timer_start(u8 *id, u8 *param, u8 flags, s16 *pv) {
} }
menu_main_screen = (u8)(MS_TIMER1 + tid); menu_main_screen = (u8)(MS_TIMER0 + tid);
} }
void kf_menu_timer_reset(u8 *id, u8 *param, u8 flags, s16 *pv) { void kf_menu_timer_reset(u8 *id, u8 *param, u8 flags, s16 *pv) {
u8 tid = (u8)(u16)param; u8 tid = (u8)(u16)param;
u8 type = TIMER_TYPE(tid);
menu_timer_s *pt = &menu_timer[tid]; menu_timer_s *pt = &menu_timer[tid];
u8 type = TIMER_TYPE(tid);
u8 tbit = (u8)(1 << tid);
switch (type) { switch (type) {
...@@ -236,11 +341,18 @@ void kf_menu_timer_reset(u8 *id, u8 *param, u8 flags, s16 *pv) { ...@@ -236,11 +341,18 @@ void kf_menu_timer_reset(u8 *id, u8 *param, u8 flags, s16 *pv) {
break; break;
case TIMER_UP: case TIMER_UP:
// XXX // stop and reset timer
menu_timer_clear(tid, 1);
menu_timer_throttle &= (u8)~tbit;
break; break;
case TIMER_DOWN: case TIMER_DOWN:
// XXX // stop and reset timer
menu_timer_running &= (u8)~(u8)(1 << tid);
// save rest value to lap count XXX
// reset timer
menu_timer_clear(tid, 0);
menu_timer_throttle &= (u8)~tbit;
break; break;
case TIMER_LAP: case TIMER_LAP:
...@@ -253,6 +365,6 @@ void kf_menu_timer_reset(u8 *id, u8 *param, u8 flags, s16 *pv) { ...@@ -253,6 +365,6 @@ void kf_menu_timer_reset(u8 *id, u8 *param, u8 flags, s16 *pv) {
} }
menu_main_screen = (u8)(MS_TIMER1 + tid); menu_main_screen = (u8)(MS_TIMER0 + tid);
} }
...@@ -85,7 +85,7 @@ static u16 menu_delay; // timer for delay in MENU task ...@@ -85,7 +85,7 @@ static u16 menu_delay; // timer for delay in MENU task
if (++time_1ms < 5) return; if (++time_1ms < 5) return;
time_1ms = 0; time_1ms = 0;
// increment time from start // increment time from start in 5ms steps
if (++time_5ms >= 200) { if (++time_5ms >= 200) {
// each 1s // each 1s
...@@ -141,11 +141,81 @@ static u16 menu_delay; // timer for delay in MENU task ...@@ -141,11 +141,81 @@ static u16 menu_delay; // timer for delay in MENU task
} }
} }
// menu timers
#define PROCESS_TIMER(tid) \
if (menu_timer_running & (u8)(1 << tid)) { \
if (!(time_5ms & 0b00000001)) { /* only every 10ms */ \
if (menu_timer_direction & (u8)(1 << tid)) { \
/* down timer */ \
if (menu_timer[tid].hdr) \
menu_timer[tid].hdr--; \
else { \
/* hdr is zero */ \
if (--menu_timer[tid].sec == 0) { \
/* trigger alarm */ \
buzzer_cnt_on = buzzer_cnt = 60; \
buzzer_cnt_off = 0; \
buzzer_count = 1; \
BUZZER1; \
buzzer_running = 1; \
/* backlight on */ \
if (!lcd_bck_on) { \
LCD_BCK1; \
lcd_bck_count = 5; \
lcd_bck_on = 1; \
} \
else if (lcd_bck_count < 5) lcd_bck_count = 5; \
/* change timer to upcounting, disable up-count alarm */ \
menu_timer_alarmed |= (u8)(1 << tid); \
menu_timer_direction &= (u8)~(u8)(1 << tid); \
menu_timer_alarm[tid] = 0; \
/* switch main screen */ \
menu_main_screen = MS_TIMER ## tid ; \
awake(MENU); \
} \
else \
menu_timer[tid].hdr = 99; \
} \
} \
else { \
/* up timer */ \
if (++menu_timer[tid].hdr == 100) { \
menu_timer[tid].hdr = 0; \
if (++menu_timer[tid].sec == menu_timer_alarm[tid]) { \
/* trigger alarm */ \
buzzer_cnt_on = buzzer_cnt = 60; \
buzzer_cnt_off = 0; \
buzzer_count = 1; \
BUZZER1; \
buzzer_running = 1; \
/* backlight on */ \
if (!lcd_bck_on) { \
LCD_BCK1; \
lcd_bck_count = 5; \
lcd_bck_on = 1; \
} \
else if (lcd_bck_count < 5) lcd_bck_count = 5; \
/* flag alarm */ \
menu_timer_alarmed |= (u8)(1 << tid); \
/* switch main screen */ \
menu_main_screen = MS_TIMER ## tid ; \
awake(MENU); \
} \
} \
} \
} \
}
PROCESS_TIMER(0);
PROCESS_TIMER(1);
// wakeup INPUT task