mirror of
https://gitee.com/dlmu-cone/tronone-h7-scaffold
synced 2026-07-24 03:27:45 +08:00
321 lines
10 KiB
C
321 lines
10 KiB
C
#include "prts.h"
|
|
|
|
#include "lvgl.h"
|
|
#include "prts_lvgl_port.h"
|
|
#include <limits.h>
|
|
#include <stddef.h>
|
|
#include <stdio.h>
|
|
|
|
#define PRTS_CARD_BG_COLOR 0x0E1B24
|
|
#define PRTS_VALUE_BG_COLOR 0x132530
|
|
#define PRTS_VALUE_PANEL_WIDTH 228
|
|
#define PRTS_VALUE_PANEL_HEIGHT 34
|
|
#define PRTS_VALUE_LABEL_WIDTH 210
|
|
#define PRTS_VALUE_LABEL_HEIGHT 28
|
|
#define PRTS_VALUE_LABEL_X 12
|
|
#define PRTS_VALUE_LABEL_Y 4
|
|
#define PRTS_VALUE_ACCENT_WIDTH 4
|
|
|
|
static bool prts_initialized = false;
|
|
static bool prts_lvgl_initialized = false;
|
|
static lv_obj_t *prts_temperature_panel = NULL;
|
|
static lv_obj_t *prts_temperature_label = NULL;
|
|
static lv_obj_t *prts_temperature_accent = NULL;
|
|
static lv_obj_t *prts_mode_panel = NULL;
|
|
static lv_obj_t *prts_mode_label = NULL;
|
|
static lv_obj_t *prts_mode_accent = NULL;
|
|
static lv_obj_t *prts_status_bar = NULL;
|
|
static int16_t prts_last_temperature_tenths = INT16_MIN;
|
|
static RobotMode_t prts_last_mode = (RobotMode_t) 0xFF;
|
|
|
|
static int16_t prts_temperature_to_tenths(float temperature_c)
|
|
{
|
|
return (int16_t) ((temperature_c * 10.0f) + (temperature_c >= 0.0f ? 0.5f : -0.5f));
|
|
}
|
|
|
|
static void prts_format_temperature(char *buf, size_t len, int16_t temperature_tenths)
|
|
{
|
|
uint16_t abs_temp;
|
|
uint16_t integer;
|
|
uint8_t decimal;
|
|
|
|
if (buf == NULL || len == 0U)
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (temperature_tenths < 0)
|
|
{
|
|
abs_temp = (uint16_t) (-temperature_tenths);
|
|
integer = abs_temp / 10U;
|
|
decimal = (uint8_t) (abs_temp % 10U);
|
|
(void) snprintf(buf, len, "-%u.%u C", (unsigned int) integer, (unsigned int) decimal);
|
|
}
|
|
else
|
|
{
|
|
abs_temp = (uint16_t) temperature_tenths;
|
|
integer = abs_temp / 10U;
|
|
decimal = (uint8_t) (abs_temp % 10U);
|
|
(void) snprintf(buf, len, "%u.%u C", (unsigned int) integer, (unsigned int) decimal);
|
|
}
|
|
}
|
|
|
|
static const char *prts_robot_mode_text(RobotMode_t mode)
|
|
{
|
|
switch (mode)
|
|
{
|
|
case NORMAL_MODE:
|
|
return "NORMAL";
|
|
case SYS_ERROR_OCCURRED:
|
|
return "ERROR";
|
|
case REMOTE_NOT_CONNECTED:
|
|
return "REMOTE OFF";
|
|
case REMOTE_CONNECTED:
|
|
return "REMOTE ON";
|
|
case AUTO_SHOOTING_MODE:
|
|
return "AUTO SHOOT";
|
|
case IMU_CALIBERATION_MODE:
|
|
return "IMU CAL";
|
|
default:
|
|
return "UNKNOWN";
|
|
}
|
|
}
|
|
|
|
static lv_color_t prts_robot_mode_color(RobotMode_t mode)
|
|
{
|
|
switch (mode)
|
|
{
|
|
case NORMAL_MODE:
|
|
return lv_color_hex(0x25D366);
|
|
case SYS_ERROR_OCCURRED:
|
|
case REMOTE_NOT_CONNECTED:
|
|
return lv_color_hex(0xFF4D4F);
|
|
case REMOTE_CONNECTED:
|
|
return lv_color_hex(0xFFD666);
|
|
case AUTO_SHOOTING_MODE:
|
|
return lv_color_hex(0x40C4FF);
|
|
case IMU_CALIBERATION_MODE:
|
|
return lv_color_hex(0xC678FF);
|
|
default:
|
|
return lv_color_hex(0xD9D9D9);
|
|
}
|
|
}
|
|
|
|
static lv_color_t prts_robot_mode_text_color(RobotMode_t mode)
|
|
{
|
|
switch (mode)
|
|
{
|
|
case SYS_ERROR_OCCURRED:
|
|
case REMOTE_NOT_CONNECTED:
|
|
return lv_color_hex(0xFFE2E2);
|
|
case REMOTE_CONNECTED:
|
|
return lv_color_hex(0xFFF3C4);
|
|
default:
|
|
return lv_color_hex(0xFFFFFF);
|
|
}
|
|
}
|
|
|
|
static void prts_style_label(lv_obj_t *label, lv_color_t color)
|
|
{
|
|
lv_obj_set_style_bg_opa(label, LV_OPA_TRANSP, 0);
|
|
lv_obj_set_style_text_color(label, color, 0);
|
|
}
|
|
|
|
static lv_obj_t *prts_create_value_panel(lv_obj_t *parent, int32_t x, int32_t y)
|
|
{
|
|
lv_obj_t *panel = lv_obj_create(parent);
|
|
lv_obj_remove_flag(panel, LV_OBJ_FLAG_SCROLLABLE);
|
|
lv_obj_set_pos(panel, x, y);
|
|
lv_obj_set_size(panel, PRTS_VALUE_PANEL_WIDTH, PRTS_VALUE_PANEL_HEIGHT);
|
|
lv_obj_set_style_radius(panel, 0, 0);
|
|
lv_obj_set_style_border_width(panel, 0, 0);
|
|
lv_obj_set_style_pad_all(panel, 0, 0);
|
|
lv_obj_set_style_bg_color(panel, lv_color_hex(PRTS_VALUE_BG_COLOR), 0);
|
|
lv_obj_set_style_bg_opa(panel, LV_OPA_COVER, 0);
|
|
return panel;
|
|
}
|
|
|
|
static lv_obj_t *prts_create_value_accent(lv_obj_t *parent, lv_color_t color)
|
|
{
|
|
lv_obj_t *accent = lv_obj_create(parent);
|
|
lv_obj_remove_flag(accent, LV_OBJ_FLAG_SCROLLABLE);
|
|
lv_obj_set_pos(accent, 0, 0);
|
|
lv_obj_set_size(accent, PRTS_VALUE_ACCENT_WIDTH, PRTS_VALUE_PANEL_HEIGHT);
|
|
lv_obj_set_style_radius(accent, 0, 0);
|
|
lv_obj_set_style_border_width(accent, 0, 0);
|
|
lv_obj_set_style_pad_all(accent, 0, 0);
|
|
lv_obj_set_style_bg_color(accent, color, 0);
|
|
lv_obj_set_style_bg_opa(accent, LV_OPA_COVER, 0);
|
|
return accent;
|
|
}
|
|
|
|
static void prts_style_value_label(lv_obj_t *label, lv_color_t color)
|
|
{
|
|
lv_label_set_long_mode(label, LV_LABEL_LONG_MODE_CLIP);
|
|
lv_obj_set_size(label, PRTS_VALUE_LABEL_WIDTH, PRTS_VALUE_LABEL_HEIGHT);
|
|
lv_obj_set_style_radius(label, 0, 0);
|
|
lv_obj_set_style_border_width(label, 0, 0);
|
|
lv_obj_set_style_pad_all(label, 0, 0);
|
|
lv_obj_set_style_bg_opa(label, LV_OPA_TRANSP, 0);
|
|
lv_obj_set_style_text_align(label, LV_TEXT_ALIGN_LEFT, 0);
|
|
lv_obj_set_style_text_color(label, color, 0);
|
|
}
|
|
|
|
static lv_obj_t *prts_create_card(lv_obj_t *parent, int32_t x, int32_t y, int32_t w, int32_t h)
|
|
{
|
|
lv_obj_t *card = lv_obj_create(parent);
|
|
lv_obj_remove_flag(card, LV_OBJ_FLAG_SCROLLABLE);
|
|
lv_obj_set_pos(card, x, y);
|
|
lv_obj_set_size(card, w, h);
|
|
lv_obj_set_style_radius(card, 4, 0);
|
|
lv_obj_set_style_border_width(card, 1, 0);
|
|
lv_obj_set_style_border_color(card, lv_color_hex(0x27475A), 0);
|
|
lv_obj_set_style_bg_color(card, lv_color_hex(PRTS_CARD_BG_COLOR), 0);
|
|
lv_obj_set_style_bg_opa(card, LV_OPA_COVER, 0);
|
|
lv_obj_set_style_pad_all(card, 10, 0);
|
|
return card;
|
|
}
|
|
|
|
static void prts_create_status_screen(void)
|
|
{
|
|
lv_obj_t *screen = lv_obj_create(NULL);
|
|
lv_obj_t *title;
|
|
lv_obj_t *subtitle;
|
|
lv_obj_t *temp_card;
|
|
lv_obj_t *mode_card;
|
|
lv_obj_t *caption;
|
|
|
|
lv_obj_remove_flag(screen, LV_OBJ_FLAG_SCROLLABLE);
|
|
lv_obj_set_style_bg_color(screen, lv_color_hex(0x071016), 0);
|
|
lv_obj_set_style_bg_opa(screen, LV_OPA_COVER, 0);
|
|
lv_obj_set_style_pad_all(screen, 0, 0);
|
|
|
|
title = lv_label_create(screen);
|
|
lv_label_set_text(title, "PRTS");
|
|
prts_style_label(title, lv_color_hex(0x6EE7F9));
|
|
lv_obj_set_pos(title, 16, 12);
|
|
|
|
subtitle = lv_label_create(screen);
|
|
lv_label_set_text(subtitle, "PORTABLE RM TELEMETRY");
|
|
prts_style_label(subtitle, lv_color_hex(0xB5C8D5));
|
|
lv_obj_set_pos(subtitle, 16, 34);
|
|
|
|
prts_status_bar = lv_obj_create(screen);
|
|
lv_obj_remove_flag(prts_status_bar, LV_OBJ_FLAG_SCROLLABLE);
|
|
lv_obj_set_pos(prts_status_bar, 190, 16);
|
|
lv_obj_set_size(prts_status_bar, 74, 8);
|
|
lv_obj_set_style_radius(prts_status_bar, 2, 0);
|
|
lv_obj_set_style_border_width(prts_status_bar, 0, 0);
|
|
lv_obj_set_style_bg_color(prts_status_bar, lv_color_hex(0xD9D9D9), 0);
|
|
lv_obj_set_style_bg_opa(prts_status_bar, LV_OPA_COVER, 0);
|
|
|
|
temp_card = prts_create_card(screen, 16, 62, 248, 68);
|
|
caption = lv_label_create(temp_card);
|
|
lv_label_set_text(caption, "TEMPERATURE");
|
|
prts_style_label(caption, lv_color_hex(0xFFD666));
|
|
lv_obj_set_pos(caption, 0, 0);
|
|
|
|
prts_temperature_panel = prts_create_value_panel(temp_card, 0, 25);
|
|
prts_temperature_accent = prts_create_value_accent(prts_temperature_panel, lv_color_hex(0x40C4FF));
|
|
prts_temperature_label = lv_label_create(prts_temperature_panel);
|
|
lv_label_set_text(prts_temperature_label, "--.- C");
|
|
prts_style_value_label(prts_temperature_label, lv_color_hex(0xFFFFFF));
|
|
lv_obj_set_pos(prts_temperature_label, PRTS_VALUE_LABEL_X, PRTS_VALUE_LABEL_Y);
|
|
|
|
mode_card = prts_create_card(screen, 16, 146, 248, 68);
|
|
caption = lv_label_create(mode_card);
|
|
lv_label_set_text(caption, "CURRENT STATE");
|
|
prts_style_label(caption, lv_color_hex(0xFFD666));
|
|
lv_obj_set_pos(caption, 0, 0);
|
|
|
|
prts_mode_panel = prts_create_value_panel(mode_card, 0, 25);
|
|
prts_mode_accent = prts_create_value_accent(prts_mode_panel, lv_color_hex(0xD9D9D9));
|
|
prts_mode_label = lv_label_create(prts_mode_panel);
|
|
lv_label_set_text(prts_mode_label, "UNKNOWN");
|
|
prts_style_value_label(prts_mode_label, lv_color_hex(0xD9D9D9));
|
|
lv_obj_set_pos(prts_mode_label, PRTS_VALUE_LABEL_X, PRTS_VALUE_LABEL_Y);
|
|
|
|
lv_screen_load(screen);
|
|
}
|
|
|
|
bool PRTS_Init(void)
|
|
{
|
|
if (prts_initialized)
|
|
{
|
|
return true;
|
|
}
|
|
|
|
if (!prts_lvgl_initialized)
|
|
{
|
|
lv_init();
|
|
prts_lvgl_initialized = true;
|
|
}
|
|
|
|
if (!PRTS_LVGLPortInit())
|
|
{
|
|
return false;
|
|
}
|
|
|
|
prts_create_status_screen();
|
|
prts_initialized = true;
|
|
return true;
|
|
}
|
|
|
|
void PRTS_UpdateStatus(float temperature_c, RobotMode_t mode)
|
|
{
|
|
int16_t temperature_tenths;
|
|
lv_color_t mode_color;
|
|
char temperature_text[16];
|
|
|
|
if (!prts_initialized)
|
|
{
|
|
return;
|
|
}
|
|
|
|
temperature_tenths = prts_temperature_to_tenths(temperature_c);
|
|
if (temperature_tenths != prts_last_temperature_tenths)
|
|
{
|
|
bool temperature_warning = temperature_tenths >= 550;
|
|
prts_format_temperature(temperature_text, sizeof(temperature_text), temperature_tenths);
|
|
lv_obj_invalidate(prts_temperature_panel);
|
|
lv_label_set_text(prts_temperature_label, temperature_text);
|
|
lv_obj_set_style_bg_color(prts_temperature_accent,
|
|
temperature_warning ? lv_color_hex(0xFF4D4F) : lv_color_hex(0x40C4FF),
|
|
0);
|
|
lv_obj_set_style_text_color(prts_temperature_label,
|
|
temperature_warning ? lv_color_hex(0xFFE2E2) : lv_color_hex(0xFFFFFF),
|
|
0);
|
|
lv_obj_invalidate(prts_temperature_panel);
|
|
prts_last_temperature_tenths = temperature_tenths;
|
|
}
|
|
|
|
if (mode != prts_last_mode)
|
|
{
|
|
mode_color = prts_robot_mode_color(mode);
|
|
lv_obj_invalidate(prts_mode_panel);
|
|
lv_label_set_text(prts_mode_label, prts_robot_mode_text(mode));
|
|
lv_obj_set_style_text_color(prts_mode_label, prts_robot_mode_text_color(mode), 0);
|
|
lv_obj_set_style_bg_color(prts_mode_accent, mode_color, 0);
|
|
lv_obj_set_style_bg_color(prts_status_bar, mode_color, 0);
|
|
lv_obj_invalidate(prts_mode_panel);
|
|
prts_last_mode = mode;
|
|
}
|
|
}
|
|
|
|
uint32_t PRTS_Task(void)
|
|
{
|
|
uint32_t next_ms;
|
|
|
|
if (!prts_initialized)
|
|
{
|
|
return 10U;
|
|
}
|
|
|
|
next_ms = lv_timer_handler();
|
|
if (next_ms == 0U || next_ms > 10U)
|
|
{
|
|
next_ms = 10U;
|
|
}
|
|
return next_ms;
|
|
}
|