#include "main.h" #include "hw_button.h" #include "ctrl_bottom_button.h" #include "ctrl_channel_button.h" #include "ctrl_encoder.h" #include "ctrl_app.h" typedef void (*btn_action_t)(void); typedef struct { btn_action_t command; BITMAP_buttonName_t bitmap_name; } CMD_button_t; static GEN_fg_t func_gen[3]; static GEN_pwm_t pwm_gen[3]; static const CMD_button_t btn_command[BTN_STATE_MAX][DISP_BTN_MAX]; static const LAY_dispBtn_t btn_hw_to_disp[BTN_BOT_MAX] = {DISP_BTN_1, DISP_BTN_2, DISP_BTN_3, DISP_BTN_4, DISP_BTN_5}; static const uint32_t pow_of_10[7] = {1, 10, 100, 1000, 10000, 100000, 1000000}; static HW_BotBtnName_t last_key; static APP_data_t *_app_data; static const GENERATOR_t generators[CHANNEL_MAX] = { {.gen_type = GEN_FG_TYPE, .gen = &func_gen[0]}, {.gen_type = GEN_FG_TYPE, .gen = &func_gen[1]}, {.gen_type = GEN_FG_TYPE, .gen = &func_gen[2]}, {.gen_type = GEN_PWM_TYPE, .gen = &pwm_gen[0]}, {.gen_type = GEN_PWM_TYPE, .gen = &pwm_gen[1]}, {.gen_type = GEN_PWM_TYPE, .gen = &pwm_gen[2]}, }; void APP_init(APP_data_t *app_data) { _app_data = app_data; _app_data->freq_focus_digit = 4; _app_data->ampl_focus_digit = 1; _app_data->offs_focus_digit = 1; _app_data->phas_focus_digit = 0; _app_data->duty_focus_digit = 0; _app_data->curr_gen_type = GEN_FG_TYPE; _app_data->generator = generators[CHANNEL1].gen; _app_data->curr_state_lay = LAY_MAIN; _app_data->curr_state_btn = BTN_MAIN_FG; _app_data->isChannelChange = 1; _app_data->isGraphChange = 1; _app_data->isValueChange = 1; _app_data->isButtonChange = 1; _app_data->isButtonBlink = 1; CTRL_buttonsInit(); } void CTRL_buttonsInit(void) { CTRL_bottomButtonInit(); // CTRL_channelButtonInit(); } void CTRL_buttonsHandler(void) { CTRL_bottomButtonsHandler(); CTRL_channelButtonsHandler(); CTRL_encoderHandler(); } void CTRL_pushedDispBtnEvent(ButtonKey_t *key) { ULOG_TRACE("Disp btn: %d", key->instance); last_key = btn_hw_to_disp[key->instance]; btn_command[_app_data->curr_state_btn][last_key].command(); } void CTRL_pushedChanBtnEvent(ButtonKey_t *key) { ULOG_TRACE("Chan btn: %d", key->instance); UNUSED(key); } static void _changeValueFunGen(int8_t dir) { GEN_fg_t *gen = (GEN_fg_t *)_app_data->generator; switch (_app_data->curr_state_lay) { case LAY_FREQ: { uint32_t new_freq = dir * pow_of_10[_app_data->freq_focus_digit] + gen->frequency; ULOG_DEBUG(" New freq: %lu", new_freq); if (new_freq > MAX_FREQ) { return; } gen->frequency = new_freq; break; } case LAY_AMPL: { uint16_t new_ampl = dir * pow_of_10[_app_data->ampl_focus_digit] + gen->amplitude; ULOG_DEBUG(" New ampl: %u", new_ampl); if (gen->offset + new_ampl > MAX_VOLT_POS || gen->offset - new_ampl < MAX_VOLT_NEG) { return; } gen->amplitude = new_ampl; break; } case LAY_OFFS: { int16_t new_offs = dir * pow_of_10[_app_data->offs_focus_digit] + gen->offset; ULOG_DEBUG(" New offs: %i", new_offs); if (new_offs + gen->amplitude > MAX_VOLT_POS || new_offs - gen->amplitude < MAX_VOLT_NEG) { return; } gen->offset = new_offs; break; } case LAY_PHAS: { uint16_t new_phas = dir * pow_of_10[_app_data->phas_focus_digit] + gen->phase; ULOG_DEBUG(" New phas: %u", new_phas); if (new_phas > MAX_PHAS) { return; } gen->phase = new_phas; break; } default: ULOG_ERROR("%s:%d: Unknown layout: %d", __FILE__, __LINE__, _app_data->curr_state_lay); return; } _app_data->isValueChange = 1; _app_data->isGraphChange = 1; } static void _changeValuePwmGen(int8_t dir) { GEN_pwm_t *gen = (GEN_pwm_t *)_app_data->generator; switch (_app_data->curr_state_lay) { case LAY_FREQ: { uint32_t new_freq = dir * pow_of_10[_app_data->freq_focus_digit] + gen->frequency; ULOG_DEBUG(" New freq: %lu", new_freq); if (new_freq > MAX_FREQ) { return; } gen->frequency = new_freq; break; } case LAY_AMPL: { uint16_t new_ampl = dir * pow_of_10[_app_data->ampl_focus_digit] + gen->amplitude; ULOG_DEBUG(" New ampl: %u", new_ampl); if (gen->offset + new_ampl > MAX_VOLT_POS || gen->offset - new_ampl < MAX_VOLT_NEG) { return; } gen->amplitude = new_ampl; break; } case LAY_OFFS: { int16_t new_offs = dir * pow_of_10[_app_data->offs_focus_digit] + gen->offset; ULOG_DEBUG(" New offs: %i", new_offs); if (new_offs + gen->amplitude > MAX_VOLT_POS || new_offs - gen->amplitude < MAX_VOLT_NEG) { return; } gen->offset = new_offs; break; } case LAY_PHAS: { uint16_t new_phas = dir * pow_of_10[_app_data->phas_focus_digit] + gen->phase; ULOG_DEBUG(" New phas: %u", new_phas); if (new_phas > MAX_PHAS) { return; } gen->phase = new_phas; break; } case LAY_DUTY: { uint8_t new_duty = dir * pow_of_10[_app_data->duty_focus_digit] + gen->duty; ULOG_DEBUG(" New duty: %u", new_duty); if (new_duty > MAX_DUTY) { return; } gen->duty = new_duty; break; } default: ULOG_ERROR("%s:%d: Unknown layout: %d", __FILE__, __LINE__, _app_data->curr_state_lay); return; } _app_data->isValueChange = 1; _app_data->isGraphChange = 1; } void CTRL_encoderEvent(int8_t enc) { ULOG_TRACE("Enco event: %i", enc); switch (_app_data->curr_gen_type) { case GEN_FG_TYPE: _changeValueFunGen(enc / 2); break; case GEN_PWM_TYPE: _changeValuePwmGen(enc / 2); break; default: ULOG_ERROR("%s:%d: Unknown generator type: %d", __FILE__, __LINE__, _app_data->curr_gen_type); break; } } inline BITMAP_buttonName_t CTRL_getBitmapName(LAY_dispBtn_t disp_btn) { return btn_command[_app_data->curr_state_btn][disp_btn].bitmap_name; } static void _doNoting(void) { return; } static void _backToMain(void) { _app_data->curr_state_lay = LAY_MAIN; switch (_app_data->curr_gen_type) { case GEN_FG_TYPE: _app_data->curr_state_btn = BTN_MAIN_FG; break; case GEN_PWM_TYPE: _app_data->curr_state_btn = BTN_MAIN_PWM; break; default: break; } _app_data->isButtonChange = 1; _app_data->isGraphChange = 1; _app_data->isValueChange = 1; _app_data->isGraphChange = 1; } static void _blockFocusAtMaxAndMin(void) { switch (_app_data->curr_state_btn) { case BTN_FREQ_MIN: if (_app_data->freq_focus_digit > 0) { _app_data->curr_state_btn = BTN_FREQ; _app_data->isButtonChange = 1; } break; case BTN_FREQ_MAX: if (_app_data->freq_focus_digit < FUN_GEN_FOCUS_MAX) { _app_data->curr_state_btn = BTN_FREQ; _app_data->isButtonChange = 1; } break; case BTN_FREQ: if (_app_data->freq_focus_digit == 0) { _app_data->curr_state_btn = BTN_FREQ_MIN; _app_data->isButtonChange = 1; } else if (_app_data->freq_focus_digit == FUN_GEN_FOCUS_MAX) { _app_data->curr_state_btn = BTN_FREQ_MAX; _app_data->isButtonChange = 1; } break; default: break; } } static void _enterToFreqLayout(void) { _app_data->curr_state_lay = LAY_FREQ; _app_data->curr_state_btn = BTN_FREQ; _blockFocusAtMaxAndMin(); _app_data->isButtonChange = 1; _app_data->isGraphChange = 1; _app_data->isValueChange = 1; } static void _enterToAmplLayout(void) { _app_data->curr_state_lay = LAY_AMPL; _app_data->curr_state_btn = BTN_AMPL; _app_data->isButtonChange = 1; _app_data->isGraphChange = 1; _app_data->isValueChange = 1; } static void _enterToOffslLayout(void) { _app_data->curr_state_lay = LAY_OFFS; _app_data->curr_state_btn = BTN_OFFS; _app_data->isButtonChange = 1; _app_data->isGraphChange = 1; _app_data->isValueChange = 1; } static void _enterToPhasLayout(void) { _app_data->curr_state_lay = LAY_PHAS; _app_data->curr_state_btn = BTN_PHAS; _app_data->isButtonChange = 1; _app_data->isGraphChange = 1; _app_data->isValueChange = 1; } static void _enterToDutyLayout(void) { _app_data->curr_state_lay = LAY_DUTY; _app_data->curr_state_btn = BTN_DUTY; _app_data->isButtonChange = 1; _app_data->isGraphChange = 1; _app_data->isValueChange = 1; } static void _enterToWavelLayout(void) { _app_data->curr_state_lay = LAY_WAVE; _app_data->curr_state_btn = BTN_WAVE; _app_data->isButtonChange = 1; _app_data->isGraphChange = 1; _app_data->isValueChange = 1; } static void _moveToLeftFocusFreqNumber(void) { _app_data->freq_focus_digit += 1; _app_data->isValueChange = 1; _blockFocusAtMaxAndMin(); _app_data->timer_blink[last_key] = 2; _app_data->isButtonBlink |= (1 << last_key); } static void _moveToRighttFocusFreqNumber(void) { _app_data->freq_focus_digit -= 1; _app_data->isValueChange = 1; _blockFocusAtMaxAndMin(); _app_data->timer_blink[last_key] = 2; _app_data->isButtonBlink |= (1 << last_key); } static void _setTo0_01xFocusNumber(void) { switch (_app_data->curr_state_lay) { case LAY_AMPL: _app_data->ampl_focus_digit = 0; break; case LAY_OFFS: _app_data->offs_focus_digit = 0; break; default: break; } _app_data->timer_blink[last_key] = 2; _app_data->isButtonBlink |= (1 << last_key); _app_data->isValueChange = 1; } static void _setTo0_1xFocusNumber(void) { switch (_app_data->curr_state_lay) { case LAY_AMPL: _app_data->ampl_focus_digit = 1; break; case LAY_OFFS: _app_data->offs_focus_digit = 1; break; default: break; } _app_data->timer_blink[last_key] = 2; _app_data->isButtonBlink |= (1 << last_key); _app_data->isValueChange = 1; } static void _setTo1xFocusNumber(void) { switch (_app_data->curr_state_lay) { case LAY_AMPL: _app_data->ampl_focus_digit = 2; break; case LAY_OFFS: _app_data->offs_focus_digit = 2; break; case LAY_PHAS: _app_data->phas_focus_digit = 0; break; case LAY_DUTY: _app_data->duty_focus_digit = 0; break; default: break; } _app_data->timer_blink[last_key] = 2; _app_data->isButtonBlink |= (1 << last_key); _app_data->isValueChange = 1; } static void _setTo10xFocusNumber(void) { switch (_app_data->curr_state_lay) { case LAY_AMPL: _app_data->ampl_focus_digit = 3; break; case LAY_OFFS: _app_data->offs_focus_digit = 3; break; case LAY_PHAS: _app_data->phas_focus_digit = 1; break; case LAY_DUTY: _app_data->duty_focus_digit = 1; break; default: break; } _app_data->timer_blink[last_key] = 2; _app_data->isButtonBlink |= (1 << last_key); _app_data->isValueChange = 1; } static const CMD_button_t btn_command[BTN_STATE_MAX][DISP_BTN_MAX] = { { // BTN_MAIN_FG {_enterToFreqLayout, BITMAP_BTN_FREQ}, {_enterToAmplLayout, BITMAP_BTN_AMPL}, {_enterToOffslLayout, BITMAP_BTN_OFFS}, {_enterToPhasLayout, BITMAP_BTN_PHAS}, {_enterToWavelLayout, BITMAP_BTN_WAVE}, }, { // BTN_MAIN_PWM {_enterToFreqLayout, BITMAP_BTN_FREQ}, {_enterToAmplLayout, BITMAP_BTN_AMPL}, {_enterToOffslLayout, BITMAP_BTN_OFFS}, {_enterToPhasLayout, BITMAP_BTN_PHAS}, {_enterToDutyLayout, BITMAP_BTN_NONE}, }, { // BTN_FREQ {_moveToLeftFocusFreqNumber, BITMAP_BTN_LEFT}, {_moveToRighttFocusFreqNumber, BITMAP_BTN_RIGHT}, {_doNoting, BITMAP_BTN_NONE}, {_doNoting, BITMAP_BTN_NONE}, {_backToMain, BITMAP_BTN_BACK}, }, { // BTN_FREQ_MIN {_moveToLeftFocusFreqNumber, BITMAP_BTN_LEFT}, {_doNoting, BITMAP_BTN_EMPTY}, {_doNoting, BITMAP_BTN_NONE}, {_doNoting, BITMAP_BTN_NONE}, {_backToMain, BITMAP_BTN_BACK}, }, { // BTN_FREQ_MAX {_doNoting, BITMAP_BTN_EMPTY}, {_moveToRighttFocusFreqNumber, BITMAP_BTN_RIGHT}, {_doNoting, BITMAP_BTN_NONE}, {_doNoting, BITMAP_BTN_NONE}, {_backToMain, BITMAP_BTN_BACK}, }, { // BTN_AMPL {_setTo1xFocusNumber, BITMAP_BTN_X1}, {_setTo0_1xFocusNumber, BITMAP_BTN_X0_1}, {_setTo0_01xFocusNumber, BITMAP_BTN_X0_01}, {_doNoting, BITMAP_BTN_NONE}, {_backToMain, BITMAP_BTN_BACK}, }, { // BTN_OFFS {_setTo1xFocusNumber, BITMAP_BTN_X1}, {_setTo0_1xFocusNumber, BITMAP_BTN_X0_1}, {_setTo0_01xFocusNumber, BITMAP_BTN_X0_01}, {_doNoting, BITMAP_BTN_NONE}, {_backToMain, BITMAP_BTN_BACK}, }, { // BTN_PHAS {_setTo10xFocusNumber, BITMAP_BTN_X10}, {_setTo1xFocusNumber, BITMAP_BTN_X1}, {_doNoting, BITMAP_BTN_NONE}, {_doNoting, BITMAP_BTN_NONE}, {_backToMain, BITMAP_BTN_BACK}, }, { // BTN_DUTY {_setTo10xFocusNumber, BITMAP_BTN_X10}, {_setTo1xFocusNumber, BITMAP_BTN_X1}, {_doNoting, BITMAP_BTN_NONE}, {_doNoting, BITMAP_BTN_NONE}, {_backToMain, BITMAP_BTN_BACK}, }, { // BTN_WAVE {_doNoting, BITMAP_BTN_NONE}, {_doNoting, BITMAP_BTN_NONE}, {_doNoting, BITMAP_BTN_NONE}, {_doNoting, BITMAP_BTN_NONE}, {_backToMain, BITMAP_BTN_BACK}, }, };