163 lines
4.9 KiB
C
163 lines
4.9 KiB
C
/**
|
|
* Frame-Scroller - rollende Liste der letzten Frames
|
|
* Verwendet st7735_draw_pixel statt esp_lcd_panel_draw_bitmap
|
|
*/
|
|
|
|
#include "esp_log.h"
|
|
#include "v2x_display.h"
|
|
#include "st7735.h"
|
|
#include "freertos/FreeRTOS.h"
|
|
#include "freertos/task.h"
|
|
#include "freertos/queue.h"
|
|
|
|
extern bool s_initialized;
|
|
extern void *s_dev;
|
|
|
|
// static const char *TAG = "v2x-scroller";
|
|
|
|
#define SCROLLER_FRAMES_VISIBLE 7
|
|
#define SCROLLER_LINE_HEIGHT 13
|
|
#define SCROLLER_START_Y 28
|
|
#define SCROLLER_MAX_ENTRIES 64
|
|
|
|
typedef struct {
|
|
char msg_char;
|
|
int8_t rssi;
|
|
uint8_t ch;
|
|
char bssid_hex[9];
|
|
} scroller_entry_t;
|
|
|
|
static scroller_entry_t s_entries[SCROLLER_MAX_ENTRIES];
|
|
static uint32_t s_entry_count = 0;
|
|
|
|
void scroller_add_entry(uint8_t msg_type, int8_t rssi, uint8_t ch, const uint8_t *bssid)
|
|
{
|
|
scroller_entry_t *e = &s_entries[s_entry_count % SCROLLER_MAX_ENTRIES];
|
|
|
|
switch (msg_type) {
|
|
case 1: e->msg_char = 'B'; break;
|
|
case 2: e->msg_char = 'C'; break;
|
|
case 3: e->msg_char = 'D'; break;
|
|
default: e->msg_char = '?'; break;
|
|
}
|
|
|
|
e->rssi = rssi;
|
|
e->ch = ch;
|
|
if (bssid) {
|
|
snprintf(e->bssid_hex, 9, "%02X-%02X-%02X", bssid[0], bssid[1], bssid[2]);
|
|
} else {
|
|
snprintf(e->bssid_hex, 9, "-----");
|
|
}
|
|
|
|
s_entry_count++;
|
|
}
|
|
|
|
/* Zeile pixel-weise löschen */
|
|
static void scroller_clear_line(int16_t y)
|
|
{
|
|
for (int16_t py = 0; py < SCROLLER_LINE_HEIGHT; py++) {
|
|
for (int16_t px = 0; px < DISP_W; px++) {
|
|
st7735_draw_pixel((void *)s_dev, px, y + py, DISP_COLOR_BLACK);
|
|
}
|
|
}
|
|
}
|
|
|
|
/* RSSI-Balk pixel-weise zeichnen */
|
|
static void scroller_draw_rssi_bar(int16_t x, int16_t y, int16_t w, int16_t h, int8_t rssi)
|
|
{
|
|
if (rssi < -100) rssi = -100;
|
|
if (rssi > -20) rssi = -20;
|
|
float pct = (float)(rssi + 100) / 80.0f;
|
|
|
|
uint16_t bar_color = DISP_COLOR_RED;
|
|
if (pct > 0.6f) bar_color = DISP_COLOR_GREEN;
|
|
else if (pct > 0.3f) bar_color = DISP_COLOR_YELLOW;
|
|
|
|
int filled_w = (int16_t)(w * pct);
|
|
|
|
for (int16_t py = 0; py < h; py++) {
|
|
for (int16_t px = 0; px < w; px++) {
|
|
uint16_t color = (px < filled_w) ? bar_color : DISP_COLOR_BLACK;
|
|
st7735_draw_pixel((void *)s_dev, x + px, y + py, color);
|
|
}
|
|
}
|
|
}
|
|
|
|
void scroller_redraw(void)
|
|
{
|
|
if (!s_initialized) return;
|
|
|
|
int32_t total = s_entry_count;
|
|
int start = (total > SCROLLER_FRAMES_VISIBLE) ?
|
|
(total - SCROLLER_FRAMES_VISIBLE) : 0;
|
|
|
|
/* Ganzes Display schwarz */
|
|
st7735_fill_screen((void *)s_dev, DISP_COLOR_BLACK);
|
|
|
|
for (int i = SCROLLER_FRAMES_VISIBLE - 1; i >= 0; i--) {
|
|
int idx = (start + i) % SCROLLER_MAX_ENTRIES;
|
|
scroller_entry_t *e = &s_entries[idx];
|
|
int y = SCROLLER_START_Y + (SCROLLER_FRAMES_VISIBLE - 1 - i) * SCROLLER_LINE_HEIGHT;
|
|
|
|
/* RSSI-Farbbalk links (5px breit, 11px hoch) */
|
|
scroller_draw_rssi_bar(2, y + 1, 5, 11, e->rssi);
|
|
|
|
/* Msg-Type Zeichen */
|
|
uint16_t msg_color = DISP_COLOR_GRAY;
|
|
if (e->msg_char == 'B') msg_color = DISP_COLOR_GREEN;
|
|
else if (e->msg_char == 'C') msg_color = DISP_COLOR_CYAN;
|
|
else if (e->msg_char == 'D') msg_color = DISP_COLOR_RED;
|
|
|
|
char msg_line[2] = { e->msg_char, '\0' };
|
|
v2x_display_text(9, y + 1, msg_line, msg_color, FONT_6x8);
|
|
|
|
/* BSSID als Hex */
|
|
v2x_display_text(16, y + 1, e->bssid_hex, DISP_COLOR_BLUE, FONT_6x8);
|
|
|
|
/* Kanal + RSSI */
|
|
char ch_buf[20];
|
|
snprintf(ch_buf, sizeof(ch_buf), "CH:%d %3d", e->ch, e->rssi);
|
|
v2x_display_text(60, y + 1, ch_buf, DISP_COLOR_WHITE, FONT_6x8);
|
|
}
|
|
}
|
|
|
|
void scroller_redraw_line(uint32_t entry_idx)
|
|
{
|
|
if (!s_initialized) return;
|
|
|
|
int32_t total = s_entry_count;
|
|
if (entry_idx < (total > SCROLLER_FRAMES_VISIBLE ? total - SCROLLER_FRAMES_VISIBLE : 0)) {
|
|
return;
|
|
}
|
|
|
|
int start = (total > SCROLLER_FRAMES_VISIBLE) ?
|
|
(total - SCROLLER_FRAMES_VISIBLE) : 0;
|
|
|
|
int line_idx = (int)(entry_idx - start);
|
|
if (line_idx < 0 || line_idx >= SCROLLER_FRAMES_VISIBLE) return;
|
|
|
|
int idx = entry_idx % SCROLLER_MAX_ENTRIES;
|
|
scroller_entry_t *e = &s_entries[idx];
|
|
int y = SCROLLER_START_Y + (SCROLLER_FRAMES_VISIBLE - 1 - line_idx) * SCROLLER_LINE_HEIGHT;
|
|
|
|
/* Zeile löschen */
|
|
scroller_clear_line(y);
|
|
|
|
/* Neu zeichnen */
|
|
scroller_draw_rssi_bar(2, y + 1, 5, 11, e->rssi);
|
|
|
|
uint16_t msg_color = DISP_COLOR_GRAY;
|
|
if (e->msg_char == 'B') msg_color = DISP_COLOR_GREEN;
|
|
else if (e->msg_char == 'C') msg_color = DISP_COLOR_CYAN;
|
|
else if (e->msg_char == 'D') msg_color = DISP_COLOR_RED;
|
|
|
|
char msg_line[2] = { e->msg_char, '\0' };
|
|
v2x_display_text(9, y + 1, msg_line, msg_color, FONT_6x8);
|
|
|
|
v2x_display_text(16, y + 1, e->bssid_hex, DISP_COLOR_BLUE, FONT_6x8);
|
|
|
|
char ch_buf[20];
|
|
snprintf(ch_buf, sizeof(ch_buf), "CH:%d %3d", e->ch, e->rssi);
|
|
v2x_display_text(60, y + 1, ch_buf, DISP_COLOR_WHITE, FONT_6x8);
|
|
}
|