#include "main.h" #include "printf.h" #include "bitmap_fonts.h" #include "bitmap_disp_buttons.h" #include "disp_layout.h" #define abs(x) ((x) < 0 ? -(x) : (x)) #define FREQ_MAX_DIGIT 7 #define AMPL_MAX_DIGIT 3 const uint8_t btn_pos_x[DISP_BTN_MAX] = {0, 26, 52, 78, 104}; const uint8_t marker_freq_pos_x[FREQ_MAX_DIGIT] = {76, 84, 90, 96, 105, 111, 118}; const uint8_t marker_ampl_pos_x[AMPL_MAX_DIGIT] = {82, 94, 100}; // clang-format off const GFX_bitmap_t marker = {05, 03, (uint8_t[]){0xF9,0xFB,0xFF,0xFB,0xF9,}}; // clang-format on static void _drawFreqValue(GFX_display_t *disp, uint32_t freq, uint8_t pos_y) { uint8_t data[8]; snprintf((char *)data, 8, "%07u", freq); DISP_writeString(disp, &font5x7Info, (uint8_t[]){data[0], 0}, 76, pos_y, BM_NORMAL); DISP_writeString(disp, &font5x7Info, (uint8_t[]){data[0], 0}, 76, pos_y, BM_NORMAL); DISP_writeString(disp, &font5x7Info, (uint8_t[]){data[1], data[2], data[3], 0}, 84, pos_y, BM_NORMAL); DISP_writeString(disp, &font5x7Info, (uint8_t[]){data[4], data[5], data[6], 0}, 105, pos_y, BM_NORMAL); } static void _drawAmplValue(GFX_display_t *disp, uint16_t ampl, uint8_t pos_y) { uint8_t data[8]; snprintf((char *)data, 8, "%02d.%02d V", ampl / 100, ampl % 100); DISP_writeString(disp, &font5x7Info, data, 76, pos_y, BM_NORMAL); } static void _drawOffsValue(GFX_display_t *disp, int16_t offs, uint8_t pos_y) { uint8_t data[8]; snprintf((char *)data, 8, "%+01d.%02d V", offs / 100, abs(offs) % 100); DISP_writeString(disp, &font5x7Info, data, 76, pos_y, BM_NORMAL); } static void _drawPhasValue(GFX_display_t *disp, uint16_t phase, uint8_t pos_y) { uint8_t data[8]; snprintf((char *)data, 8, "%03u'", phase); DISP_writeString(disp, &font5x7Info, data, 76, pos_y, BM_NORMAL); } static void _drawDutyValue(GFX_display_t *disp, uint8_t duty, uint8_t pos_y) { uint8_t data[8]; snprintf((char *)data, 8, "%03u%%", duty); DISP_writeString(disp, &font5x7Info, data, 76, pos_y, BM_NORMAL); } static void _blinkButtons(GFX_display_t *disp, APP_data_t *app_data) { // input: display buttons, invert BITMAP_buttonName_t bitmap_idx; for (LAY_dispBtn_t btn_idx = DISP_BTN_1; btn_idx < DISP_BTN_MAX; btn_idx++) { if (!(app_data->isButtonBlink & (1 << btn_idx))) { continue; } bitmap_idx = CTRL_getBitmapName(btn_idx); if (app_data->timer_blink[btn_idx] > 0) { DISP_drawBitmap(disp, &bitmap_btnBottom[bitmap_idx + 1], btn_pos_x[btn_idx], 53, BM_NORMAL); app_data->timer_blink[btn_idx]--; } else { DISP_drawBitmap(disp, &bitmap_btnBottom[bitmap_idx], btn_pos_x[btn_idx], 53, BM_NORMAL); app_data->isButtonBlink &= ~(1 << btn_idx); } } } static void _drawButtons(GFX_display_t *disp, APP_data_t *app_data) { // input: display buttons, invert BITMAP_buttonName_t bitmap_idx; DISP_clearRegion(disp, 0, 53, disp->width, 11); for (LAY_dispBtn_t btn_idx = DISP_BTN_1; btn_idx < DISP_BTN_MAX; btn_idx++) { bitmap_idx = CTRL_getBitmapName(btn_idx); DISP_drawBitmap(disp, &bitmap_btnBottom[bitmap_idx], btn_pos_x[btn_idx], 53, BM_NORMAL); } app_data->isButtonChange = 0; } static uint8_t _calcMarkePos(uint32_t value, uint32_t max) { return ((62 * value) + (max / 2)) / max; // return (value < 0) ? ((62 * value) - (max / 2)) / max : ((62 * value) + (max / 2)) / max; } static uint8_t _sizeOfCharArray(char *array) { uint8_t size = 0; while (*array++) { size++; } return size; } static void _drawMeterHelper(GFX_display_t *disp, char *min, char *max, uint8_t pos) { uint8_t max_size = _sizeOfCharArray(max); DISP_drawPixel(disp, 64, 40, GFX_WHITE); DISP_drawPixel(disp, 125, 40, GFX_WHITE); DISP_drawHorizontalLine(disp, 64, 41, 62, GFX_WHITE); DISP_writeString(disp, &font5x7Info, (uint8_t *)min, 62, 43, BM_NORMAL); DISP_writeString(disp, &font5x7Info, (uint8_t *)max, 127 - (6 * max_size), 43, BM_NORMAL); // marker 0% - 62, 100% - 123 DISP_drawBitmap(disp, &marker, 62 + pos, 35, BM_NORMAL); } static void _drawFreqValueHelper(GFX_display_t *disp, uint32_t freq, uint8_t focus_digit) { DISP_clearRegion(disp, 64, 13, 66, 40); DISP_writeString(disp, &font5x7Info, (uint8_t *)"F:", 64, 20, BM_NORMAL); _drawFreqValue(disp, freq, 20); DISP_drawBitmap(disp, &marker, marker_freq_pos_x[(FREQ_MAX_DIGIT - 1) - focus_digit], 15, BM_NORMAL); } static void _drawAmplValueHelper(GFX_display_t *disp, uint32_t ampl, uint8_t focus_digit) { DISP_clearRegion(disp, 64, 13, 66, 40); DISP_writeString(disp, &font5x7Info, (uint8_t *)"A:", 64, 20, BM_NORMAL); _drawAmplValue(disp, ampl, 20); DISP_drawBitmap(disp, &marker, marker_ampl_pos_x[(AMPL_MAX_DIGIT - 1) - focus_digit], 15, BM_NORMAL); } static void _drawOffsValueHelper(GFX_display_t *disp, int32_t offs, uint8_t focus_digit) { DISP_clearRegion(disp, 64, 13, 66, 40); DISP_writeString(disp, &font5x7Info, (uint8_t *)"O:", 64, 20, BM_NORMAL); _drawOffsValue(disp, offs, 20); DISP_drawBitmap(disp, &marker, marker_ampl_pos_x[(AMPL_MAX_DIGIT - 1) - focus_digit], 15, BM_NORMAL); } static void _drawPhaseValueHelper(GFX_display_t *disp, uint32_t phase, uint8_t focus_digit) { DISP_clearRegion(disp, 64, 13, 66, 40); DISP_writeString(disp, &font5x7Info, (uint8_t *)"P:", 64, 20, BM_NORMAL); _drawPhasValue(disp, phase, 20); DISP_drawBitmap(disp, &marker, marker_ampl_pos_x[(AMPL_MAX_DIGIT - 1) - focus_digit], 15, BM_NORMAL); } static void _drawFuncGenValues(GFX_display_t *disp, APP_data_t *app_data) { GEN_fg_t *fun_gen = (GEN_fg_t *)app_data->generator; switch (app_data->curr_state_lay) { case LAY_FREQ: _drawFreqValueHelper(disp, fun_gen->frequency, app_data->freq_focus_digit); _drawMeterHelper(disp, "1", "1M", _calcMarkePos(990000, 1000000)); break; case LAY_AMPL: _drawAmplValueHelper(disp, fun_gen->amplitude, app_data->ampl_focus_digit); _drawMeterHelper(disp, "0V", "5V", _calcMarkePos(100, 500)); break; case LAY_OFFS: fun_gen->offset = -123; _drawOffsValueHelper(disp, fun_gen->offset, app_data->offs_focus_digit); _drawMeterHelper(disp, "-5V", "+5V", _calcMarkePos(100 + 250, 500 + 250)); break; case LAY_PHAS: _drawPhaseValueHelper(disp, fun_gen->phase, app_data->phas_focus_digit); _drawMeterHelper(disp, "0", "360", _calcMarkePos(100, 500)); break; case LAY_MAIN: DISP_clearRegion(disp, 62, 13, 66, 40); DISP_writeString(disp, &font5x7Info, (uint8_t *)"F:", 64, 13, BM_NORMAL); DISP_writeString(disp, &font5x7Info, (uint8_t *)"A:", 64, 23, BM_NORMAL); DISP_writeString(disp, &font5x7Info, (uint8_t *)"O:", 64, 33, BM_NORMAL); DISP_writeString(disp, &font5x7Info, (uint8_t *)"P:", 64, 43, BM_NORMAL); _drawFreqValue(disp, fun_gen->frequency, 13); _drawAmplValue(disp, fun_gen->amplitude, 23); _drawOffsValue(disp, fun_gen->offset, 33); _drawPhasValue(disp, fun_gen->phase, 43); break; default: // focus break; } } static void _drawPwmGenValues(GFX_display_t *disp, APP_data_t *app_data) { GEN_pwm_t *pwm_gen = app_data->generator; } static void _drawValues(GFX_display_t *disp, APP_data_t *app_data) { // input: frequency(value), amplitiude(value), offset(value), phase(value), duty(value), invert(info), position(value) switch (app_data->curr_gen_type) { case GEN_FG_TYPE: _drawFuncGenValues(disp, app_data); break; case GEN_PWM_TYPE: _drawPwmGenValues(disp, app_data); break; default: break; } app_data->isValueChange = 0; } static void _drawGraph(GFX_display_t *disp, APP_data_t *app_data) { // input: graph type(sin, triangle, squere, pwm), frequency(info), amplitiude(value), offset(value), phase(value), invert(pwm), // DISP_drawSin(disp, 4, 32, 16, 0, 0); DISP_drawHorizontalLine(disp, 2, 32, 56, GFX_WHITE); app_data->isGraphChange = 0; } static void _drawChannels(GFX_display_t *disp, APP_data_t *app_data) { // input: active channel DISP_writeString(disp, &font5x7Info, (uint8_t *)"CH1", 2, 2, CHANNEL1 == app_data->curr_channel ? BM_INVERSE : BM_NORMAL); DISP_writeString(disp, &font5x7Info, (uint8_t *)"CH2", 23, 2, CHANNEL2 == app_data->curr_channel ? BM_INVERSE : BM_NORMAL); DISP_writeString(disp, &font5x7Info, (uint8_t *)"CH3", 44, 2, CHANNEL3 == app_data->curr_channel ? BM_INVERSE : BM_NORMAL); DISP_writeString(disp, &font5x7Info, (uint8_t *)"CH4", 65, 2, CHANNEL4 == app_data->curr_channel ? BM_INVERSE : BM_NORMAL); DISP_writeString(disp, &font5x7Info, (uint8_t *)"CH5", 86, 2, CHANNEL5 == app_data->curr_channel ? BM_INVERSE : BM_NORMAL); DISP_writeString(disp, &font5x7Info, (uint8_t *)"CH6", 107, 2, CHANNEL6 == app_data->curr_channel ? BM_INVERSE : BM_NORMAL); DISP_drawHorizontalLine(disp, 0, 10, 127, GFX_WHITE); app_data->isChannelChange = 0; } void LAY_drawDisplayLayout(GFX_display_t *disp, APP_data_t *app_data) { if (app_data->isChannelChange) _drawChannels(disp, app_data); if (app_data->isGraphChange) _drawGraph(disp, app_data); if (app_data->isValueChange) _drawValues(disp, app_data); if (app_data->isButtonChange) _drawButtons(disp, app_data); if (app_data->isButtonBlink) _blinkButtons(disp, app_data); }