add pointer mode
This commit is contained in:
parent
0b8875b90a
commit
09d687dcdf
@ -1,5 +1,7 @@
|
||||
#include <stdint.h>
|
||||
#include "global.h"
|
||||
#include "ui.h"
|
||||
#include "time.h"
|
||||
#include "st7735.h"
|
||||
#include "Images/digi18x32.h"
|
||||
#include "monoimg.h"
|
||||
@ -74,51 +76,52 @@ void ui_com_title_bar(uint8_t clear, uint8_t *text, uint32_t bytes_len) {
|
||||
bmf_draw_text(font_unifont_16x16, text, bytes_len, off_x, 1, ST7735_WIDTH - 2, 16, ST7735_YELLOW);
|
||||
}
|
||||
|
||||
void ui_com_freq_digital(uint8_t clear) {
|
||||
void ui_com_freq_digital(uint8_t clear, uint8_t only_pointer) {
|
||||
// 5位数字, 即高32+2(小数点高度),宽90
|
||||
uint16_t off_x = (ST7735_WIDTH - 90) / 2;
|
||||
uint16_t off_y = (ST7735_HEIGHT - 34 - 34 - 18) / 2 + 17;
|
||||
uint16_t freq_num;
|
||||
if (global_data.rf_mode == G_RF_MODE_AM) {
|
||||
freq_num = global_data.freq;
|
||||
} else {
|
||||
freq_num = global_data.freq * 5;
|
||||
}
|
||||
uint16_t color_orange = ST7735_COLOR565(0xFF, 0x7F, 0);
|
||||
if (clear) {
|
||||
if (global_data.rf_mode == G_RF_MODE_AM) {
|
||||
ST7735_FillRectangle(off_x, off_y+32, 90, 3, ST7735_BLACK); // 清除小数点
|
||||
} else {
|
||||
ST7735_FillRectangle(off_x, off_y + 32, 18 * 3 - 1, 3, ST7735_BLACK); // 清除小数点
|
||||
ST7735_FillRectangle(off_x + (18 * 3) + 1, off_y + 32, 18 * 2 - 1, 3, ST7735_BLACK); // 清除小数点
|
||||
ST7735_FillRectangle(off_x + (18 * 3) - 1, off_y + 34, 2, 1, ST7735_BLACK);
|
||||
}
|
||||
}
|
||||
if (global_data.rf_mode == G_RF_MODE_FM) {
|
||||
// 绘制小数点
|
||||
ST7735_FillRectangle(off_x + (18 * 3) - 1, off_y + 32, 2, 2, color_orange);
|
||||
}
|
||||
if (global_data.point_mode & G_PMOD_MODE_MASK) {
|
||||
// 绘制光标
|
||||
uint8_t blink_state = (ticks_ms() / UI_BLINK_MS) % 2;
|
||||
uint8_t blink_state2 = !(global_data.point_mode & G_PMOD_PBLINK_MASK);
|
||||
if (!(global_data.point_mode & G_PMOD_PMOVE_MASK) || (blink_state ^ blink_state2)) {
|
||||
uint8_t p_pos = (global_data.point_mode & G_POMD_POS_MASK) >> G_POMD_POS_BOFF;
|
||||
uint16_t p_off = (4 - p_pos) * 18 + 2 + off_x;
|
||||
ST7735_FillRectangle(p_off, off_y + 33, 14, 2, color_orange);
|
||||
global_data.point_mode = global_data.point_mode | G_PMOD_PBLINK2_MASK;
|
||||
} else {
|
||||
global_data.point_mode = global_data.point_mode & (~G_PMOD_PBLINK2_MASK);
|
||||
}
|
||||
}
|
||||
uint16_t scale = 10000;
|
||||
uint32_t tmp = 0;
|
||||
if (clear) {
|
||||
ST7735_FillRectangle(off_x, off_y+32, 90, 2, ST7735_BLACK); // 清除小数点
|
||||
}
|
||||
if (!only_pointer) {
|
||||
while (scale > 0) {
|
||||
tmp = (freq_num / scale) % 10;
|
||||
if (clear) {
|
||||
ui_text_number18x32_with_bg(tmp, off_x, off_y, ST7735_COLOR565(0xFF, 0x7F, 0), ST7735_BLACK);
|
||||
ui_text_number18x32_with_bg(tmp, off_x, off_y, color_orange, ST7735_BLACK);
|
||||
} else {
|
||||
ui_text_number18x32(tmp, off_x, off_y, ST7735_COLOR565(0xFF, 0x7F, 0));
|
||||
}
|
||||
off_x += 18;
|
||||
scale /= 10;
|
||||
}
|
||||
} else {
|
||||
uint16_t fm_freq = global_data.freq / 20;
|
||||
uint8_t fm_freq_float = (global_data.freq % 20) * 5;
|
||||
uint16_t scale = 100;
|
||||
uint16_t tmp = 0;
|
||||
if (clear) {
|
||||
ST7735_FillRectangle(off_x, off_y + 32, 18 * 3 - 1, 2, ST7735_BLACK); // 清除小数点
|
||||
ST7735_FillRectangle(off_x + (18 * 3) + 1, off_y + 32, 18 * 2 - 1, 2, ST7735_BLACK); // 清除小数点
|
||||
}
|
||||
while (scale > 0) {
|
||||
tmp = (fm_freq / scale) % 10;
|
||||
if (clear) {
|
||||
ui_text_number18x32_with_bg(tmp, off_x, off_y, ST7735_COLOR565(0xFF, 0x7F, 0), ST7735_BLACK);
|
||||
} else {
|
||||
ui_text_number18x32(tmp, off_x, off_y, ST7735_COLOR565(0xFF, 0x7F, 0));
|
||||
}
|
||||
off_x += 18;
|
||||
scale /= 10;
|
||||
}
|
||||
scale = 10;
|
||||
while (scale > 0) {
|
||||
tmp = (fm_freq_float / scale) % 10;
|
||||
if (clear) {
|
||||
ui_text_number18x32_with_bg(tmp, off_x, off_y, ST7735_COLOR565(0xFF, 0x7F, 0), ST7735_BLACK);
|
||||
} else {
|
||||
ui_text_number18x32(tmp, off_x, off_y, ST7735_COLOR565(0xFF, 0x7F, 0));
|
||||
ui_text_number18x32(tmp, off_x, off_y, color_orange);
|
||||
}
|
||||
off_x += 18;
|
||||
scale /= 10;
|
||||
@ -200,7 +203,19 @@ void ui_screen_main() {
|
||||
ui_com_main_border();
|
||||
ui_com_title_bar(0, u8str("Radio"), 5);
|
||||
ui_com_fm_am(0);
|
||||
ui_com_freq_digital(0);
|
||||
ui_com_freq_digital(0, 0);
|
||||
ui_com_vol_bar(0);
|
||||
ui_com_sig_bar(0);
|
||||
}
|
||||
|
||||
void ui_screen_main_animation() {
|
||||
// 绘制闪烁效果
|
||||
if ((global_data.point_mode & G_PMOD_MODE_MASK) && (global_data.point_mode & G_PMOD_PMOVE_MASK)) {
|
||||
uint8_t blink_state = (ticks_ms() / UI_BLINK_MS) % 2;
|
||||
uint8_t blink_state2 = !(global_data.point_mode & G_PMOD_PBLINK_MASK);
|
||||
uint8_t blink_state3 = (global_data.point_mode & G_PMOD_PBLINK2_MASK) ? 1 : 0;
|
||||
if ((blink_state ^ blink_state2) ^ blink_state3) {
|
||||
ui_com_freq_digital(1, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,13 +1,16 @@
|
||||
#pragma once
|
||||
#include <stdint.h>
|
||||
|
||||
#define UI_BLINK_MS 250
|
||||
|
||||
void ui_text_number18x32(uint32_t num, uint16_t x, uint16_t y, uint16_t color);
|
||||
|
||||
/* 绘制界面元素 */
|
||||
void ui_com_title_bar(uint8_t clear, uint8_t *text, uint32_t bytes_len);
|
||||
void ui_com_freq_digital(uint8_t clear);
|
||||
void ui_com_freq_digital(uint8_t clear, uint8_t only_pointer);
|
||||
void ui_com_fm_am(uint8_t clear);
|
||||
void ui_com_vol_bar(uint8_t clear);
|
||||
void ui_com_sig_bar(uint8_t clear);
|
||||
/* 绘制主界面 */
|
||||
void ui_screen_main();
|
||||
void ui_screen_main_animation();
|
||||
|
165
Core/App/app.c
165
Core/App/app.c
@ -3,6 +3,29 @@
|
||||
#include "ui.h"
|
||||
#include "keypad.h"
|
||||
#include "global.h"
|
||||
#include "time.h"
|
||||
|
||||
void __limit_freq_range() {
|
||||
uint16_t limit_min = (global_data.rf_mode == G_RF_MODE_AM) ? G_AM_FREQ_MIN : G_FM_FREQ_MIN;
|
||||
uint16_t limit_max = (global_data.rf_mode == G_RF_MODE_AM) ? G_AM_FREQ_MAX : G_FM_FREQ_MAX;
|
||||
if (global_data.freq < limit_min) {
|
||||
global_data.freq = limit_min;
|
||||
} else if (global_data.freq > limit_max) {
|
||||
global_data.freq = limit_max;
|
||||
}
|
||||
}
|
||||
|
||||
void __send_freq() {
|
||||
// TODO: 发送频率
|
||||
}
|
||||
|
||||
void __switch_to_fm() {
|
||||
// TODO: 切换到FM模式
|
||||
}
|
||||
|
||||
void __switch_to_am() {
|
||||
// TODO: 切换到AM模式
|
||||
}
|
||||
|
||||
void app_init() {
|
||||
// 程序开始时执行一次
|
||||
@ -17,37 +40,151 @@ void app_main_loop() {
|
||||
uint8_t event_type = kp_Type(event);
|
||||
uint8_t event_value = kp_Value(event);
|
||||
if (event_type == kp_ROTATE_RIGHT || event_type == kp_ROTATE_LEFT) {
|
||||
// 调整频率
|
||||
if (global_data.point_mode & G_PMOD_MODE_MASK) {
|
||||
// 指针模式调整
|
||||
uint8_t p_pos = (global_data.point_mode & G_POMD_POS_MASK) >> G_POMD_POS_BOFF;
|
||||
if (global_data.point_mode & G_PMOD_PMOVE_MASK) {
|
||||
// 调整指针位置
|
||||
if (event_type == kp_ROTATE_RIGHT) {
|
||||
p_pos += 100;
|
||||
p_pos -= event_value;
|
||||
} else {
|
||||
p_pos += event_value;
|
||||
}
|
||||
p_pos %= 5; // 0~4, 右边第一个数值为0号位置
|
||||
global_data.point_mode = global_data.point_mode & (~G_POMD_POS_MASK);
|
||||
global_data.point_mode = global_data.point_mode | ((p_pos << G_POMD_POS_BOFF) & G_POMD_POS_MASK);
|
||||
printf("Adjust Point Pos: %u\n", p_pos);
|
||||
} else {
|
||||
// 调整指针位置的数字
|
||||
uint16_t num_freq;
|
||||
if (global_data.rf_mode == G_RF_MODE_AM) {
|
||||
num_freq = global_data.freq;
|
||||
} else {
|
||||
num_freq = global_data.freq * 5;
|
||||
}
|
||||
/* adjust number at all */
|
||||
uint16_t scale = 1;
|
||||
if (p_pos == 0 && global_data.rf_mode == G_RF_MODE_FM) {
|
||||
scale = 5;
|
||||
} else {
|
||||
uint8_t tmp;
|
||||
for (tmp = 0; tmp < p_pos; tmp ++) {
|
||||
scale *= 10;
|
||||
}
|
||||
}
|
||||
if (event_type == kp_ROTATE_RIGHT) {
|
||||
num_freq += scale * event_value;
|
||||
} else {
|
||||
if (scale * event_value < num_freq) {
|
||||
num_freq -= scale * event_value;
|
||||
} else {
|
||||
num_freq = 0;
|
||||
}
|
||||
}
|
||||
uint16_t limit_min = (global_data.rf_mode == G_RF_MODE_AM) ? G_AM_FREQ_MIN : G_FM_FREQ_MIN * 5;
|
||||
uint16_t limit_max = (global_data.rf_mode == G_RF_MODE_AM) ? G_AM_FREQ_MAX : G_FM_FREQ_MAX * 5;
|
||||
if (num_freq > limit_max || num_freq < limit_min) {
|
||||
return; // ignore if overflow
|
||||
}
|
||||
/* adjust number one by one */
|
||||
// uint8_t scale = 1;
|
||||
// uint16_t tmp;
|
||||
// uint16_t num_lower, num_upper;
|
||||
// uint8_t inc = (p_pos == 0 && global_data.rf_mode == G_RF_MODE_FM) ? 5 : 1;
|
||||
// uint8_t lim = 10;
|
||||
// if (p_pos == 4) {
|
||||
// if (global_data.rf_mode == G_RF_MODE_AM) {
|
||||
// lim = 3;
|
||||
// } else {
|
||||
// lim = 1;
|
||||
// }
|
||||
// }
|
||||
// for (tmp = 0; tmp < p_pos; tmp ++) {
|
||||
// scale *= 10;
|
||||
// }
|
||||
// num_lower = num_freq % scale;
|
||||
// num_upper = num_freq / scale / 10;
|
||||
// tmp = num_freq / scale % 10;
|
||||
// if (event_type == kp_ROTATE_RIGHT) {
|
||||
// tmp += (event_value * inc);
|
||||
// } else {
|
||||
// tmp += lim % 100;
|
||||
// tmp -= (event_value * inc);
|
||||
// }
|
||||
// tmp %= lim;
|
||||
// num_freq = (num_upper * scale * 10) + (tmp * scale) + num_lower;
|
||||
if (global_data.rf_mode == G_RF_MODE_AM) {
|
||||
global_data.freq = num_freq;
|
||||
} else {
|
||||
global_data.freq = num_freq / 5;
|
||||
}
|
||||
printf("Adjust Freq: %u\n", global_data.freq);
|
||||
}
|
||||
} else {
|
||||
// 直接调整频率
|
||||
if (event_type == kp_ROTATE_RIGHT) {
|
||||
global_data.freq += event_value;
|
||||
} else {
|
||||
global_data.freq -= event_value;
|
||||
}
|
||||
uint16_t limit_min = (global_data.rf_mode == G_RF_MODE_AM) ? G_AM_FREQ_MIN : G_FM_FREQ_MIN;
|
||||
uint16_t limit_max = (global_data.rf_mode == G_RF_MODE_AM) ? G_AM_FREQ_MAX : G_FM_FREQ_MAX;
|
||||
if (global_data.freq < limit_min) {
|
||||
global_data.freq = limit_min;
|
||||
} else if (global_data.freq > limit_max) {
|
||||
global_data.freq = limit_max;
|
||||
__limit_freq_range();
|
||||
__send_freq();
|
||||
printf("Adjust Freq: %u\n", global_data.freq);
|
||||
}
|
||||
printf("Freq: %d\n", global_data.freq);
|
||||
ui_com_freq_digital(1);
|
||||
ui_com_freq_digital(1, 0);
|
||||
} else if (event_type == kp_SHORT_CLICK) {
|
||||
if (event_value == kp_KEY1) {
|
||||
if (global_data.point_mode & G_PMOD_MODE_MASK) {
|
||||
if (event_value == kp_KEYENCODER) {
|
||||
if (global_data.point_mode & G_PMOD_PMOVE_MASK) {
|
||||
// 退出移动指针模式
|
||||
global_data.point_mode = global_data.point_mode & (~G_PMOD_PMOVE_MASK);
|
||||
printf("Exit Pointer Move Mode.\n");
|
||||
} else {
|
||||
// 进入移动指针模式
|
||||
global_data.point_mode = global_data.point_mode | G_PMOD_PMOVE_MASK;
|
||||
uint8_t blink_state = (ticks_ms() / UI_BLINK_MS) % 2; // 该时间段指示条消失
|
||||
if (blink_state) {
|
||||
global_data.point_mode = global_data.point_mode | G_PMOD_PBLINK_MASK;
|
||||
} else {
|
||||
global_data.point_mode = global_data.point_mode & (~G_PMOD_PBLINK_MASK);
|
||||
}
|
||||
printf("Enter Pointer Move Mode.\n");
|
||||
}
|
||||
ui_com_freq_digital(1, 0);
|
||||
}
|
||||
} else if (event_value == kp_KEY1) {
|
||||
// 切换FM和AM
|
||||
if (global_data.rf_mode == G_RF_MODE_AM) {
|
||||
global_data.rf_mode = G_RF_MODE_FM;
|
||||
global_data.freq = G_FM_FREQ_MIN;
|
||||
__switch_to_fm();
|
||||
} else {
|
||||
global_data.rf_mode = G_RF_MODE_AM;
|
||||
global_data.freq = G_AM_FREQ_MIN;
|
||||
__switch_to_am();
|
||||
}
|
||||
ui_com_fm_am(1);
|
||||
ui_com_freq_digital(1);
|
||||
ui_com_freq_digital(1, 0);
|
||||
}
|
||||
} else if (event_type == kp_LONG_PRESS) {
|
||||
//
|
||||
} else if (event_type != kp_NOP) {
|
||||
printf("event: %d, key: %d\n", event_type, event_value);
|
||||
if (event_value == kp_KEYENCODER) {
|
||||
if (global_data.point_mode & G_PMOD_MODE_MASK) {
|
||||
// 退出指针模式
|
||||
global_data.point_mode = global_data.point_mode & (~G_PMOD_MODE_MASK);
|
||||
__limit_freq_range();
|
||||
__send_freq();
|
||||
printf("Exit Pointer Mode.\n");
|
||||
} else {
|
||||
// 进入指针模式
|
||||
global_data.point_mode = global_data.point_mode | G_PMOD_MODE_MASK;
|
||||
global_data.point_mode = global_data.point_mode & (~G_PMOD_PMOVE_MASK);
|
||||
printf("Enter Pointer Mode.\n");
|
||||
}
|
||||
ui_com_freq_digital(1, 0);
|
||||
}
|
||||
} else if (event_type != kp_NOP) {
|
||||
printf("event: %u, key: %u\n", event_type, event_value);
|
||||
}
|
||||
ui_screen_main_animation();
|
||||
}
|
||||
|
@ -5,5 +5,6 @@ GlobalData global_data = {
|
||||
880 * 2, // freq
|
||||
G_RF_MODE_FM, //rf_mode
|
||||
16, // volumn
|
||||
97 //signal
|
||||
97, //signal
|
||||
0b00000000 //point_mode
|
||||
};
|
||||
|
@ -8,11 +8,28 @@
|
||||
#define G_AM_FREQ_MIN 100
|
||||
#define G_AM_FREQ_MAX 33000
|
||||
|
||||
#define G_PMOD_MODE_MASK 0b00000001
|
||||
#define G_PMOD_PMOVE_MASK 0b00000010
|
||||
#define G_POMD_POS_MASK 0b00011100
|
||||
#define G_POMD_POS_BOFF 2
|
||||
#define G_POMD_POS_BLEN 3
|
||||
#define G_PMOD_PBLINK_MASK 0b00100000
|
||||
#define G_PMOD_PBLINK2_MASK 0b01000000
|
||||
|
||||
typedef struct GlobalData {
|
||||
uint16_t freq; // FM x50kHz AM x1kHz
|
||||
/** FM x50kHz AM x1kHz */
|
||||
uint16_t freq;
|
||||
uint8_t rf_mode;
|
||||
uint8_t volumn;
|
||||
uint8_t signal;
|
||||
/** 指针模式变量
|
||||
* bit 0 标记是否进入指针模式
|
||||
* bit 1 标记是否正在移动指针
|
||||
* bit 2~4 记录了当前指针的位置
|
||||
* bit 5 标记了当前时间段指针指示是否要显示(用于闪烁动画)
|
||||
* bit 6 标记了当前指针的状态(用于闪烁动画)
|
||||
*/
|
||||
volatile uint8_t point_mode;
|
||||
} GlobalData;
|
||||
|
||||
extern GlobalData global_data;
|
||||
|
Loading…
x
Reference in New Issue
Block a user