Пример #1
0
void menu_key_test(void) {
    u8 i;
    u16 bit;
    
    // cleanup screen and disable possible low bat warning
    buzzer_off();
    key_beep();
    menu_battery_low = 0;	// it will be set automatically again
    battery_low_shutup = 0;

    // do full screen blink
    lcd_set_full_on();
    delay_menu_always(2);
    while (btns(BTN_ENTER))  stop();  // wait for release of ENTER
    lcd_clear();

    button_autorepeat(0);	// disable autorepeats
    btnra();

    // show intro text
    lcd_chars("KEY");
    lcd_update_stop();		// wait for key

    while (1) {
	if (btnl(BTN_BACK | BTN_ENTER))  break;

	for (i = 0, bit = 1; i < 16; i++, bit <<= 1) {
	    if (btn(bit)) {
		key_beep();
		lcd_chars(key_ids[i]);
		if (btnl(bit))  lcd_7seg(L7_L);
		else lcd_set(L7SEG, LB_EMPTY);
		lcd_update();
		break;
	    }
	}
	btnra();
	stop();
    }
    key_beep();
    apply_model_config();
}
Пример #2
0
int main(void) {
    WDTCTL = WDTPW | WDTHOLD;	// Stop watchdog timer

    BCSCTL1 = CALBC1_8MHZ; // Set DCO to 8Mhz
    DCOCTL = CALDCO_8MHZ; // Set DCO to 8Mhz

    P2DIR |= (BIT0|BIT1|BIT2|BIT3);

    P2OUT |=  BIT0|BIT1|BIT2|BIT3;
    uart_init();

    __bis_SR_register(GIE);

    unsigned char i;

    while(1) {

        i = uart_get();
        btns(i);
    }

    return 0;
}
Пример #3
0
// change val, temporary show new value (not always)
// end when another key pressed
static u8 menu_popup_key(u8 key_id) {
    u16 delay_time;
    u16 buttons_state_last;
    u16 btnx;
    config_key_map_s *km = &ck.key_map[key_id];
    key_functions_s *kf;
    key_functions_s *kfl;
    u8 flags;
    u8 is_long = 0;
    u8 *mbs = &menu_buttons_state[key_id];
    s16 *pv = &menu_buttons_previous_values[key_id];

    // do nothing when both short and long set to OFF
    if (!km->function && !km->function_long)  return 0;

    // prepare more variables
    kf = &key_functions[km->function];
    btnx = key_buttons[key_id];

    // remember buttons state
    buttons_state_last = buttons_state & ~btnx;


    // check momentary setting
    //   when something changed, show value for 5s while checking buttons
    //   during initialize show nothing
    if (km->function && (kf->flags & KF_2STATE) && km->momentary) {
	static @near u8 ch3_has_middle; // set to 1 if ch3 has middle state
	u8 state;			// new button state
	u8 value_showed = 0;
	u16 btnx_orig = btnx;

	// for CH3 button add MIDDLE state also
	if (key_id == 0)  btnx |= BTN_CH3_MID;

	while (1) {
	    // set actual state of btnx to buttons_state_last
	    buttons_state_last &= ~btnx;
	    buttons_state_last |= buttons_state & btnx;

	    // check button
	    flags = FF_NONE;
	    state = MBS_RELEASED;
	    if (key_id == 0 && btns(BTN_CH3_MID)) {
		// special check for CH3 button middle
		flags |= FF_MID;
		state = MBS_MIDDLE;
		ch3_has_middle = 1;
	    }
	    else if (btns(btnx_orig)) {
		flags |= FF_ON;
		state = MBS_PRESSED;
	    }
	    if (km->reverse)	    flags |= FF_REVERSE;
	    if (key_id == 0 && ch3_has_middle)
				    flags |= FF_HAS_MID;
	    if (km->previous_val)   flags |= FF_PREVIOUS;

	    // end if button state didn't changed
	    if (state == *mbs)  break;

	    // end when initialize
	    if (*mbs == MBS_INITIALIZE) {
		// call func when not previous_val
		if (!km->previous_val || state == MBS_PRESSED)
		    kf->func(kf->name, kf->param, flags, pv);
		*mbs = state;
		break;
	    }
	    *mbs = state;
	    btnr(btnx);
	    key_beep();

	    // if value showing disabled, exit
	    if (kf->flags & KF_NOSHOW)  break;

	    // if another button was pressed, leave this screen
	    if (buttons)  break;
	    if (buttons_state != buttons_state_last) break;

	    // show function id first time
	    if (!value_showed) {
		value_showed = 1;
		menu_key_empty_id();
	    }

	    // call function to set value and show it
	    flags |= FF_SHOW;
	    kf->func(kf->name, kf->param, flags, pv);
	    lcd_update();

	    // sleep 5s, and if no button was changed during, end this screen
	    delay_time = POPUP_DELAY * 200;
	    while (delay_time && !(buttons & ~btnx) &&
		   (buttons_state == buttons_state_last))
		delay_time = delay_menu(delay_time);

	    if ((buttons_state & btnx) == (buttons_state_last & btnx))
		break;
	}

	btnr(btnx);
	if (value_showed)  lcd_menu(0);		// set MENU off
	return value_showed;
    }


    // non-momentary key
    kfl = &key_functions[km->function_long];

    // if button is not initialized, do it
    if (*mbs == MBS_INITIALIZE) {
	if (km->function && (kf->flags & KF_2STATE) && !km->previous_val)
	    kf->func(kf->name, kf->param, (u8)(km->reverse ? FF_REVERSE : 0),
	             pv);
	if (km->function_long && (kfl->flags & KF_2STATE)
	    && !km->previous_val_long)
	    kfl->func(kfl->name, kfl->param,
		      (u8)(km->reverse_long ? FF_REVERSE : 0), pv);
	*mbs = 0;  // both are OFF
    }

    // return when key was not pressed
    if (!btn(btnx))	 return 0;

    // clear some lcd segments
    menu_key_empty_id();

    while (1) {
	if (km->function_long && btnl(btnx)) {
	    // long key press
	    key_beep();
	    flags = 0;
	    if (!(kfl->flags & KF_NOSHOW))  flags = FF_SHOW;
	    if (kfl->flags & KF_2STATE) {	// ON/OFF is only for 2-state
		if (*mbs & MBS_ON_LONG) {
		    // is ON, switch to OFF
		    *mbs &= (u8)~MBS_ON_LONG;
		}
		else {
		    // is OFF, switch to ON
		    *mbs |= MBS_ON_LONG;
		    flags |= FF_ON;
		}
		if (km->reverse_long)       flags |= FF_REVERSE;
		if (km->previous_val_long)  flags |= FF_PREVIOUS;
	    }
	    kfl->func(kfl->name, kfl->param, flags, pv);  // switch value
	    if (kfl->flags & KF_NOSHOW) {
		btnr(btnx);
		return 0;
	    }
	    lcd_update();
	    is_long = 1;
	}
	else if (km->function && btn(btnx)) {
	    // short key press
	    key_beep();
	    flags = 0;
	    if (!(kf->flags & KF_NOSHOW))  flags = FF_SHOW;
	    if (kf->flags & KF_2STATE) {	// ON/OFF is only for 2-state
		if (*mbs & MBS_ON) {
		    // is ON, switch to OFF
		    *mbs &= (u8)~MBS_ON;
		}
		else {
		    // is OFF, switch to ON
		    *mbs |= MBS_ON;
		    flags |= FF_ON;
		}
		if (km->reverse)       flags |= FF_REVERSE;
		if (km->previous_val)  flags |= FF_PREVIOUS;
	    }
	    kf->func(kf->name, kf->param, flags, pv);  // switch value
	    if (kf->flags & KF_NOSHOW) {
		btnr(btnx);
		return 0;
	    }
	    lcd_update();
	}
	else {
	    // nothing to do
	    btnr(btnx);
	    return 0;
	}
	btnr(btnx);

	// if another button was pressed, leave this screen
	if (buttons)  break;
	if ((buttons_state & ~btnx) != buttons_state_last)  break;

	// sleep 5s, and if no button was changed during, end this screen
	delay_time = POPUP_DELAY * 200;
	while (delay_time && !buttons &&
	       ((buttons_state & ~btnx) == buttons_state_last))
	    delay_time = delay_menu(delay_time);

	if (!buttons)  break;  // timeouted without button press
	if (is_long) {
	    // if long required but short pressed, end
	    if (!btnl(btnx))  break;
	}
	else {
	    // if short required, but long pressed with function_long
	    //   specified, end
	    if (km->function_long && btnl(btnx))  break;
	}
    }

    // set MENU off
    lcd_menu(0);

    return 1;  // popup was showed
}
Пример #4
0
static u8 menu_popup_et(u8 trim_id) {
    u16 delay_time;
    s16 val;
    u8  step;
    u16 buttons_state_last;
    u16 btn_l = ETB_L(trim_id);
    u16 btn_r = ETB_R(trim_id);
    u16 btn_lr = btn_l | btn_r;
    config_et_map_s *etm = &ck.et_map[trim_id];
#define SF_ROTATE  etm->rotate
    et_functions_s *etf = &et_functions[etm->function];
    u8 *mbs = &menu_buttons_state[NUM_KEYS + 2 * trim_id];

    // read value
    RVAL(val);

    // remember buttons state
    buttons_state_last = buttons_state & ~btn_lr;

    // handle momentary keys
    //   when something changed, show value for 5s while checking buttons
    //   during initialize show nothing
    if (etm->buttons == ETB_MOMENTARY) {
	s16 *pv = &menu_buttons_previous_values[NUM_KEYS + 2 * trim_id];
	u8 value_showed = 0;
	u8 state;

	while (1) {
	    // set actual state of btn_lr to buttons_state_last
	    buttons_state_last &= ~btn_lr;
	    buttons_state_last |= buttons_state & btn_lr;

	    // check buttons
	    if (btns(btn_l)) {
		// left
		if (*mbs == MBS_LEFT)  break;	// already was left
		state = MBS_LEFT;
		*pv = val;			// save previous value
		val = etm->reverse ? etf->max : etf->min;
	    }
	    else if (btns(btn_r)) {
		// right
		if (*mbs == MBS_RIGHT)  break;	// already was right
		state = MBS_RIGHT;
		*pv = val;			// save previous value
		val = etm->reverse ? etf->min : etf->max;
	    }
	    else {
		// center
		if (*mbs == MBS_RELEASED)  break;  // already was center
		state = MBS_RELEASED;
		if (etm->previous_val) {
		    if (*mbs != MBS_INITIALIZE)  val = *pv;
		}
		else  val = etf->reset;
	    }
	    AVAL(val);
	    if (*mbs == MBS_INITIALIZE) {
		// show nothing when doing initialize
		*mbs = state;
		break;
	    }
	    *mbs = state;
	    btnr(btn_lr);
	    key_beep();

	    // if another button was pressed, leave this screen
	    if (buttons)  break;
	    if (buttons_state != buttons_state_last) break;

	    // show function id first time
	    if (!value_showed) {
		value_showed = 1;
		menu_et_function_show_id(etf);
	    }

	    // show current value
	    if (etf->show_func)  etf->show_func(etf->name, val);
	    else		 lcd_char_num3(val);
	    lcd_update();

	    // sleep 5s, and if no button was changed during, end this screen
	    delay_time = POPUP_DELAY * 200;
	    while (delay_time && !(buttons & ~btn_lr) &&
		   (buttons_state == buttons_state_last))
		delay_time = delay_menu(delay_time);

	    if ((buttons_state & btn_lr) == (buttons_state_last & btn_lr))
		break;
	}

	btnr(btn_lr);
	if (value_showed)  lcd_menu(0);		// set MENU off
	return value_showed;
    }

    // if button is not initialized, do it
    if (*mbs == MBS_INITIALIZE) {
	// set value to default only for non-config values (mixes, channels...)
	if (etf->flags & EF_NOCONFIG) {
	    val = etf->reset;
	    AVAL(val);
	}
	*mbs = MBS_RELEASED;
    }

    // return when key was not pressed
    if (!btn(btn_lr))	 return 0;

    // convert steps
    step = steps_map[etm->step];

    // show MENU and CHANNEL
    menu_et_function_show_id(etf);

    while (1) {
	u8  val_set_to_reset = 0;

	// check value left/right
	if (btnl_all(btn_lr)) {
	    // both long keys together
	    key_beep();
	    if (etf->long_func && etm->buttons == ETB_SPECIAL)
		// special handling
		etf->long_func(etf->name, &val, btn_l, btn_r);
	    else {
		// reset to given reset value
		val = etf->reset;
	    }
	    AVAL(val);
	    if (val == etf->reset)  val_set_to_reset = 1;
	    btnr(btn_lr);
	}
	else if (btn(btn_lr)) {
	    if (!btns_all(btn_lr)) {
		// only one key is currently pressed
		key_beep();
		if (etf->long_func && etm->buttons == ETB_SPECIAL &&
		    btnl(btn_lr))
		    // special handling
		    etf->long_func(etf->name, &val, btn_l, btn_r);
		else if ((etm->buttons == ETB_LONG_RESET ||
			  etm->buttons == ETB_LONG_ENDVAL) && btnl(btn_lr)) {
		    // handle long key press
		    if (etm->buttons == ETB_LONG_RESET) {
			val = etf->reset;
		    }
		    else {
			// set side value
			if ((u8)(btn(btn_l) ? 1 : 0) ^ etm->reverse)
			    val = etf->min;
			else
			    val = etf->max;
		    }
		}
		else {
		    // handle short key press
		    if ((u8)(btn(btn_l) ? 1 : 0) ^ etm->reverse) {
			val -= step;
			if (val < etf->min) {
			    if (etm->rotate)  val = etf->max;
			    else	      val = etf->min;
			}
			if (etm->opposite_reset &&
			    val > etf->reset)  val = etf->reset;
		    }
		    else {
			val += step;
			if (val > etf->max) {
			    if (etm->rotate)  val = etf->min;
			    else	      val = etf->max;
			}
			if (etm->opposite_reset &&
			    val < etf->reset)  val = etf->reset;
		    }
		}
		AVAL(val);
		if (val == etf->reset)  val_set_to_reset = 1;
		btnr(btn_lr);
	    }
	    else btnr_nolong(btn_lr);  // keep long-presses for testing-both
	}
	else if (btn(BTN_ROT_ALL)) {
	    s16 val2 = val;
	    val = menu_change_val(val, etf->min, etf->max, etf->rot_fast_step,
	                          etm->rotate);
	    // if encoder skipped reset value, set it to reset value
	    if (val2 < etf->reset && val > etf->reset ||
	        val2 > etf->reset && val < etf->reset)  val = etf->reset;
	    AVAL(val);
	    if (val == etf->reset)  val_set_to_reset = 1;
	}
	btnr(BTN_ROT_ALL);

	// longer beep at value reset value
	if (val_set_to_reset)  BEEP_RESET;

	// if another button was pressed, leave this screen
	if (buttons)  break;
	if ((buttons_state & ~btn_lr) != buttons_state_last)  break;

	// show current value
	if (etf->show_func)  etf->show_func(etf->name, val);
	else		 lcd_char_num3(val);
	lcd_update();

	// if reset value was reached, ignore rotate/btn_lr for some time
	delay_time = POPUP_DELAY * 200;
	if (val_set_to_reset) {
	    u8 delay = RESET_VALUE_DELAY;
	    while (delay && !(buttons & ~(btn_lr | BTN_ROT_ALL)) &&
		   ((buttons_state & ~btn_lr) == buttons_state_last))
		delay = (u8)delay_menu(delay);
	    btnr(BTN_ROT_ALL | btn_lr);
	    delay_time -= RESET_VALUE_DELAY;
	}

	// sleep 5s, and if no button was changed during, end this screen
	while (delay_time && !buttons &&
	       ((buttons_state & ~btn_lr) == buttons_state_last))
	    delay_time = delay_menu(delay_time);

	if (!buttons)  break;  // timeouted without button press
    }

    btnr(btn_lr);  // reset also long values

    // set MENU off
    lcd_menu(0);

    // save model config
    config_model_save();
    return 1;
}