449 lines
12 KiB
C
449 lines
12 KiB
C
#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("<FG> 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("<FG> 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("<FG> 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("<FG> 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("<PWM> 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("<PWM> 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("<PWM> 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("<PWM> 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("<PWM> 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},
|
|
},
|
|
|
|
}; |