Display UI: ST7735 Treiber + Frame-Scroller + Speicheranzeige
- ST7735 SPI-Treiber für 0.96 Zoll Display (80x160 Pixel) - ASCII-Font 6x8 mit Text-Ausgabe - Frame-Counter (gross, rot) - SD-Speicher-Balken (grün/gelb/rot) - Frame-Scroller: rollende Liste der letzten 7 Frames - RSSI-Farbbalken (rot/gelb/grün) - Message-Type (B=BSM, C=CAM, D=DENM) - BSSID Hex + Kanal/RSSI - Display UI Task aktualisiert alle 2 Sekunden - Frame Writer sendet Frames an Scroller Queue - Channel Hopper aktualisiert g_v2x_channel_idx
This commit is contained in:
+83
-1
@@ -51,8 +51,10 @@
|
||||
#include "nvs_flash.h"
|
||||
#include "esp_timer.h"
|
||||
#include "driver/gpio.h"
|
||||
#include "esp_codec_dev.h"
|
||||
#include "esp_lcd_panel_ops.h"
|
||||
#include "esp_lcd_panel_vendor.h"
|
||||
#include "v2x_db.h"
|
||||
#include "v2x_display.h"
|
||||
|
||||
static const char *TAG = "V2X-Sniffer";
|
||||
|
||||
@@ -74,10 +76,23 @@ static const uint32_t v2x_freqs[] = {
|
||||
#define STAT_DUMP_INTERVAL_MS (60 * 1000)
|
||||
/* CSV-Flush alle 200 Frames */
|
||||
#define CSV_FLUSH_INTERVAL 200
|
||||
/* Display Refresh */
|
||||
#define DISPLAY_REFRESH_MS 2000
|
||||
|
||||
/* Frame Queue */
|
||||
static QueueHandle_t s_frame_queue;
|
||||
|
||||
/* Scroller Queue */
|
||||
#define SCROLLER_QUEUE_SIZE 16
|
||||
static QueueHandle_t s_scroller_queue;
|
||||
|
||||
/* Globale Variablen für Display */
|
||||
extern bool g_disp_initialized;
|
||||
extern esp_lcd_panel_handle_t g_disp_panel;
|
||||
uint32_t g_v2x_frame_count = 0;
|
||||
int8_t g_v2x_max_rssi = -120;
|
||||
int g_v2x_channel_idx = 0;
|
||||
|
||||
/* ====== Message-Type Erkennung ====== */
|
||||
static v2x_msg_type_t detect_msg_type(const uint8_t *data, uint16_t len)
|
||||
{
|
||||
@@ -158,6 +173,11 @@ static void v2x_promiscuous_cb(void *arg, wifi_promiscuous_pkt_type_t pkt_type)
|
||||
|
||||
/* Message-Type */
|
||||
frame.msg_type = detect_msg_type(frame.raw_data, frame.raw_len);
|
||||
|
||||
/* RSSI-Update */
|
||||
if (frame.rssi_dbm > g_v2x_max_rssi) {
|
||||
g_v2x_max_rssi = frame.rssi_dbm;
|
||||
}
|
||||
}
|
||||
|
||||
/* Auf Queue pushen (non-blocking) */
|
||||
@@ -185,6 +205,21 @@ static void v2x_frame_writer_task(void *pvParameters)
|
||||
ESP_LOGW(TAG, "SD-Schreibfehler");
|
||||
}
|
||||
|
||||
/* Frame-Counter hochzählen */
|
||||
g_v2x_frame_count++;
|
||||
|
||||
/* An Scroller senden (wenn Display an) */
|
||||
if (g_disp_initialized && s_scroller_queue) {
|
||||
disp_frame_info_t fi;
|
||||
memset(&fi, 0, sizeof(fi));
|
||||
fi.msg_type = frame.msg_type;
|
||||
fi.rssi = frame.rssi_dbm;
|
||||
extern uint32_t g_v2x_current_freq;
|
||||
fi.channel = (uint8_t)(g_v2x_current_freq / 1000 - 5);
|
||||
memcpy(fi.bssid_last3, frame.bssid + 3, 3);
|
||||
xQueueSend(s_scroller_queue, &fi, 0);
|
||||
}
|
||||
|
||||
/* Periodisch flushen */
|
||||
flush_counter++;
|
||||
if (flush_counter % CSV_FLUSH_INTERVAL == 0) {
|
||||
@@ -214,6 +249,7 @@ static void v2x_channel_hopper_task(void *pvParameters)
|
||||
/* Frequenz/Kanal wechseln */
|
||||
v2x_phy_init(freq);
|
||||
g_v2x_current_freq = freq;
|
||||
g_v2x_channel_idx = hop_idx;
|
||||
|
||||
ESP_LOGI(TAG, "CH %d: %lu MHz", hop_idx, (unsigned long)freq);
|
||||
|
||||
@@ -241,6 +277,24 @@ static void v2x_stats_task(void *pvParameters)
|
||||
}
|
||||
}
|
||||
|
||||
/* ====== Scroller Task ====== */
|
||||
static void scroller_task(void *pvParameters)
|
||||
{
|
||||
disp_frame_info_t fi;
|
||||
|
||||
while (1) {
|
||||
if (xQueueReceive(s_scroller_queue, &fi, pdMS_TO_TICKS(500)) == pdTRUE) {
|
||||
/* Frame als Zeile hinzufügen */
|
||||
scroller_add_entry(fi.msg_type, fi.rssi, fi.channel, fi.bssid_last3);
|
||||
|
||||
/* Scroller aktualisieren */
|
||||
if (g_disp_initialized) {
|
||||
scroller_redraw();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* ====== Application Entry Point ====== */
|
||||
void app_main(void)
|
||||
{
|
||||
@@ -285,6 +339,16 @@ void app_main(void)
|
||||
}
|
||||
}
|
||||
|
||||
/* === Display initialisieren === */
|
||||
ESP_LOGI(TAG, "Initialisiere ST7735 Display (GPIO10/1/0/2/6)...");
|
||||
ret = v2x_display_init();
|
||||
if (ret != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Display fehlgeschlagen: %s", esp_err_to_name(ret));
|
||||
ESP_LOGW(TAG, "Fahre ohne Display fort");
|
||||
} else {
|
||||
ESP_LOGI(TAG, "ST7735 Display bereit (80x160)");
|
||||
}
|
||||
|
||||
/* === Frame Queue erstellen === */
|
||||
s_frame_queue = xQueueCreate(FRAME_QUEUE_SIZE, sizeof(v2x_frame_t));
|
||||
if (!s_frame_queue) {
|
||||
@@ -295,6 +359,24 @@ void app_main(void)
|
||||
/* === Stats initialisieren === */
|
||||
v2x_sd_reset_stats();
|
||||
|
||||
/* === Scroller Queue erstellen === */
|
||||
s_scroller_queue = xQueueCreate(SCROLLER_QUEUE_SIZE, sizeof(disp_frame_info_t));
|
||||
if (!s_scroller_queue) {
|
||||
ESP_LOGW(TAG, "Scroller Queue fehlgeschlagen");
|
||||
}
|
||||
|
||||
/* === Display UI Task starten === */
|
||||
if (g_disp_initialized) {
|
||||
xTaskCreate(v2x_display_ui_task, "display_ui", 4096, NULL, 2, NULL);
|
||||
ESP_LOGI(TAG, "Display UI Task gestartet");
|
||||
}
|
||||
|
||||
/* === Scroller Task starten === */
|
||||
if (s_scroller_queue && g_disp_initialized) {
|
||||
xTaskCreate(scroller_task, "scroller", 2048, NULL, 2, NULL);
|
||||
ESP_LOGI(TAG, "Scroller Task gestartet");
|
||||
}
|
||||
|
||||
/* === Tasks starten === */
|
||||
/* Channel Hopper */
|
||||
xTaskCreate(v2x_channel_hopper_task, "channel_hopper", 4096, NULL, 3, NULL);
|
||||
|
||||
Reference in New Issue
Block a user