#include "main.h" #include "tim.h" #include "ctrl_bottom_button.h" #include "ctrl_channel_button.h" #include "ctrl_encoder.h" #include "ctrl_disp_button.h" #include "ctrl_signal_gen.h" #include "ctrl_app.h" typedef void (*btn_action_t)(APP_data_t *app_data); typedef struct { btn_action_t command; BITMAP_buttonName_t bitmap_name; } CMD_button_t; 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 GEN_channel_t btn_ch_to_chan[CHANNEL_MAX] = {CHANNEL1, CHANNEL2, CHANNEL3, CHANNEL4, CHANNEL5, CHANNEL6}; static const uint32_t pow_of_10[7] = {1, 10, 100, 1000, 10000, 100000, 1000000}; static APP_data_t *_app_data; static dds_gen_t dds_gen[DDS_CH_MAX] = { {.super.type = GEN_FG_TYPE, .dds_ch = DDS_CH1}, {.super.type = GEN_FG_TYPE, .dds_ch = DDS_CH2}, {.super.type = GEN_FG_TYPE, .dds_ch = DDS_CH3}, }; static pwm_gen_t pwm_gen[PWM_CH_MAX] = { {.super.type = GEN_PWM_TYPE, .pwm_ch = PWM_CH1}, {.super.type = GEN_PWM_TYPE, .pwm_ch = PWM_CH2}, {.super.type = GEN_PWM_TYPE, .pwm_ch = PWM_CH3}, }; static signal_gen_t *signal_gen[CHANNEL_MAX] = { &dds_gen[DDS_CH1].super, &dds_gen[DDS_CH2].super, &dds_gen[DDS_CH3].super, &pwm_gen[PWM_CH1].super, &pwm_gen[PWM_CH2].super, &pwm_gen[PWM_CH3].super, }; static void _setGenInitailState(GEN_channel_t channel); static void _signalGenDefaultValues(void); static void _changeValueDdsGen(int8_t dir); static void _changeValuePwmGen(int8_t dir); //**************************** // Initialization //**************************** void CTRL_buttonsInit(void) { CTRL_bottomButtonInit(); CTRL_channelButtonInit(); } 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 = signal_gen[CHANNEL1]; _app_data->curr_state_lay = LAY_MAIN; _app_data->curr_state_btn = BTN_MAIN_FG; _app_data->curr_channel = CHANNEL1; // _app_data->isChannelChange = 1; // _app_data->isGraphChange = 1; // _app_data->isValueChange = 1; // _app_data->isButtonChange = 1; // _app_data->isButtonBlink = 1; _app_data->disp_update |= UPDATE_BUTTON | UPDATE_GRAPH | UPDATE_VALUE | UPDATE_CHANNEL; CTRL_buttonsInit(); _signalGenDefaultValues(); GEN_init(signal_gen); _setGenInitailState(CHANNEL1); _setGenInitailState(CHANNEL2); } //**************************** // Handlers //**************************** void CTRL_buttonsHandler(void) { CTRL_bottomButtonsHandler(); CTRL_channelButtonsHandler(); CTRL_encoderHandler(); } //**************************** // Events //**************************** void CTRL_pushedDispBtnEvent(ButtonKey_t *key) { ULOG_TRACE("Disp btn: %d", key->instance); _app_data->last_key = btn_hw_to_disp[key->instance]; btn_command[_app_data->curr_state_btn][_app_data->last_key].command(_app_data); } void CTRL_encoderEvent(int8_t enc) { ULOG_TRACE("Enco event: %i", enc); switch (_app_data->curr_gen->type) { case GEN_FG_TYPE: _changeValueDdsGen(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; } } void CTRL_pushedChanBtnEvent(ButtonKey_t *key) { ULOG_TRACE("Chan btn: %d", key->instance); GEN_channel_t channel = btn_ch_to_chan[key->instance]; _app_data->curr_gen = signal_gen[channel]; _app_data->curr_state_lay = LAY_MAIN; _app_data->curr_state_btn = BTN_MAIN_FG; _app_data->curr_channel = channel; // _app_data->isChannelChange = 1; // _app_data->isGraphChange = 1; // _app_data->isValueChange = 1; // _app_data->isButtonChange = 1; // _app_data->isButtonBlink = 1; _app_data->disp_update |= UPDATE_BUTTON | UPDATE_GRAPH | UPDATE_VALUE | UPDATE_CHANNEL; } void CTRL_longPushedChanBtnEvent(ButtonKey_t *key) { ULOG_TRACE("Chan btn(long): %d", key->instance); GEN_channel_t channel = btn_ch_to_chan[key->instance]; switch (signal_gen[channel]->type) { case GEN_FG_TYPE: { dds_gen_t *dds_gen = (dds_gen_t *)signal_gen[channel]; dds_gen->settings.enabled = dds_gen->settings.enabled ? FALSE : TRUE; setEnabled(signal_gen[channel]); break; } case GEN_PWM_TYPE: { pwm_gen_t *pwm_gen = (pwm_gen_t *)signal_gen[channel]; pwm_gen->settings.enabled = pwm_gen->settings.enabled ? FALSE : TRUE; setEnabled(signal_gen[channel]); break; } default: ULOG_ERROR("%s:%d: Unknown generator type: %d", __FILE__, __LINE__, _app_data->curr_gen->type); break; } } //******************************************************************* static void _changeValueDdsGen(int8_t dir) { dds_gen_t *dds_gen = (dds_gen_t *)_app_data->curr_gen; switch (_app_data->curr_state_lay) { case LAY_FREQ: { uint32_t new_freq = dir * pow_of_10[_app_data->freq_focus_digit] + dds_gen->settings.frequency; ULOG_DEBUG(" New freq: %lu", new_freq); if (new_freq > MAX_FREQ) { return; } dds_gen->settings.frequency = new_freq; setFrequency(&dds_gen->super); break; } case LAY_AMPL: { uint16_t new_ampl = dir * pow_of_10[_app_data->ampl_focus_digit] + dds_gen->settings.amplitude; ULOG_DEBUG(" New ampl: %u", new_ampl); if (dds_gen->settings.offset + new_ampl > MAX_VOLT_POS || dds_gen->settings.offset - new_ampl < MAX_VOLT_NEG) { return; } dds_gen->settings.amplitude = new_ampl; setAmplitude(&dds_gen->super); break; } case LAY_OFFS: { int16_t new_offs = dir * pow_of_10[_app_data->offs_focus_digit] + dds_gen->settings.offset; ULOG_DEBUG(" New offs: %i", new_offs); if (new_offs + dds_gen->settings.amplitude > MAX_VOLT_POS || new_offs - dds_gen->settings.amplitude < MAX_VOLT_NEG) { return; } dds_gen->settings.offset = new_offs; setOfsset(&dds_gen->super); break; } case LAY_PHAS: { uint16_t new_phas = dir * pow_of_10[_app_data->phas_focus_digit] + dds_gen->settings.phase; ULOG_DEBUG(" New phas: %u", new_phas); if (new_phas > MAX_PHAS) { return; } dds_gen->settings.phase = new_phas; setPhase(&dds_gen->super); 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; _app_data->disp_update |= UPDATE_GRAPH | UPDATE_VALUE; } static void _changeValuePwmGen(int8_t dir) { pwm_gen_t *pwm_gen = (pwm_gen_t *)_app_data->curr_gen; switch (_app_data->curr_state_lay) { case LAY_FREQ: { uint32_t new_freq = dir * pow_of_10[_app_data->freq_focus_digit] + pwm_gen->settings.frequency; ULOG_DEBUG(" New freq: %lu", new_freq); if (new_freq > MAX_FREQ) { return; } pwm_gen->settings.frequency = new_freq; break; } case LAY_AMPL: { uint16_t new_ampl = dir * pow_of_10[_app_data->ampl_focus_digit] + pwm_gen->settings.amplitude; ULOG_DEBUG(" New ampl: %u", new_ampl); if (pwm_gen->settings.offset + new_ampl > MAX_VOLT_POS || pwm_gen->settings.offset - new_ampl < MAX_VOLT_NEG) { return; } pwm_gen->settings.amplitude = new_ampl; break; } case LAY_OFFS: { int16_t new_offs = dir * pow_of_10[_app_data->offs_focus_digit] + pwm_gen->settings.offset; ULOG_DEBUG(" New offs: %i", new_offs); if (new_offs + pwm_gen->settings.amplitude > MAX_VOLT_POS || new_offs - pwm_gen->settings.amplitude < MAX_VOLT_NEG) { return; } pwm_gen->settings.offset = new_offs; break; } case LAY_PHAS: { uint16_t new_phas = dir * pow_of_10[_app_data->phas_focus_digit] + pwm_gen->settings.phase; ULOG_DEBUG(" New phas: %u", new_phas); if (new_phas > MAX_PHAS) { return; } pwm_gen->settings.phase = new_phas; break; } case LAY_DUTY: { uint8_t new_duty = dir * pow_of_10[_app_data->duty_focus_digit] + pwm_gen->settings.duty; ULOG_DEBUG(" New duty: %u", new_duty); if (new_duty > MAX_DUTY) { return; } pwm_gen->settings.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; _app_data->disp_update |= UPDATE_GRAPH | UPDATE_VALUE; } void _signalGenDefaultValues(void) { for (GEN_channel_t channel = CHANNEL1; channel < CHANNEL_MAX; channel++) { switch (signal_gen[channel]->type) { case GEN_FG_TYPE: { dds_gen_t *dds_gen = (dds_gen_t *)signal_gen[channel]; dds_gen->settings.frequency = 1000; dds_gen->settings.amplitude = 100; dds_gen->settings.offset = 165; dds_gen->settings.phase = 0; dds_gen->settings.wave = GEN_SIN; dds_gen->settings.link = 0; dds_gen->settings.enabled = FALSE; break; } case GEN_PWM_TYPE: { pwm_gen_t *pwm_gen = (pwm_gen_t *)signal_gen[channel]; pwm_gen->settings.frequency = 1000; pwm_gen->settings.amplitude = 100; pwm_gen->settings.offset = 0; pwm_gen->settings.phase = 0; pwm_gen->settings.duty = 50; pwm_gen->settings.link = 0; pwm_gen->settings.enabled = FALSE; break; } default: break; } } } void _setGenInitailState(GEN_channel_t channel) { setFrequency(signal_gen[channel]); setWave(signal_gen[channel]); setPhase(signal_gen[channel]); setAmplitude(signal_gen[channel]); setEnabled(signal_gen[channel]); // setOfsset(signal_gen[channel]); } inline BITMAP_buttonName_t CTRL_getBitmapName(LAY_dispBtn_t disp_btn) { return btn_command[_app_data->curr_state_btn][disp_btn].bitmap_name; } 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}, }, };