/* * image.c * * Copyright (c) 2022 - 2023 Thomas Buck (thomas@xythobuz.de) * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * See . */ #include #include #include "config.h" #include "lcd.h" #include "text.h" #include "lipo.h" #include "util.h" #include "wifi.h" #include "image.h" #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wtrigraphs" #include "logo.h" #pragma GCC diagnostic pop #define BATT_INTERVAL_MS 777 void image_draw(const char *data, uint width, uint height) { for (uint y = 0; y < height; y++) { for (uint x = 0; x < width; x++) { uint32_t pixel[3]; HEADER_PIXEL(data, pixel); uint32_t color = RGB_565(pixel[0], pixel[1], pixel[2]); lcd_write_point(x, y, color); } } } void draw_splash(void) { image_draw(logo_rgb_data, logo_width, logo_height); struct text_font font_big = { .fontname = "DejaVuSerif32", }; text_prepare_font(&font_big); struct text_font font_small = { .fontname = "DejaVuSerif16", }; text_prepare_font(&font_small); struct text_conf text1 = { .text = "xythobuz.de", .x = 0, .y = 0, .justify = false, .alignment = MF_ALIGN_CENTER, .width = 240, .height = 240, .margin = 2, .fg = RGB_565(0xFF, 0xFF, 0xFF), .bg = RGB_565(0x00, 0x00, 0x00), .font = &font_big, }; text_draw(&text1); struct text_conf text2 = { .text = __DATE__ " @ " __TIME__, .x = 0, .y = 195, .justify = false, .alignment = MF_ALIGN_CENTER, .width = 240, .height = 240, .margin = 2, .fg = RGB_565(0xFF, 0xFF, 0xFF), .bg = RGB_565(0x00, 0x00, 0x00), .font = &font_small, }; text_draw(&text2); } void draw_battery_indicator(void) { static const float batt_warn_limit = 0.0f; static char prev_s[30] = {0}; static uint32_t prev_c = 0; char s[30] = {0}; float v = lipo_voltage(); uint32_t c = RGB_565(0xFF, 0x00, 0x00); if (lipo_charging()) { // "Batt: 99.9% (4.20V)" snprintf(s, sizeof(s), "Batt: Charging "); c = RGB_565(0xFF, 0xFF, 0x00); } else { float percentage = lipo_percentage(v); snprintf(s, sizeof(s), "Batt: %02.1f%% (%.2fV)", percentage, v); if (percentage > batt_warn_limit) { float hue = map(percentage, batt_warn_limit, 100, 0.0, 0.333); c = from_hsv(hue, 1.0, 1.0); } } // only re-draw battery indicator when it has changed if ((strcmp(s, prev_s) == 0) && (prev_c == c)) { return; } strcpy(prev_s, s); prev_c = c; static struct text_font font = { .fontname = "fixed_10x20", .font = NULL, }; if (font.font == NULL) { text_prepare_font(&font); } struct text_conf text = { .text = s, .x = 0, .y = 219, .justify = false, .alignment = MF_ALIGN_CENTER, .width = 240, .height = 240, .margin = 2, .fg = c, .bg = LCD_BLACK, .font = &font, }; text_draw(&text); } void draw_wifi_indicator(void) { static char prev_s[30] = {0}; char s[30] = {0}; snprintf(s, sizeof(s), "WiFi: %17s", wifi_state()); if (strcmp(s, prev_s) == 0) { return; } strcpy(prev_s, s); static struct text_font font = { .fontname = "fixed_10x20", .font = NULL, }; if (font.font == NULL) { text_prepare_font(&font); } struct text_conf text = { .text = s, .x = 0, .y = 219 - 50, .justify = false, .alignment = MF_ALIGN_CENTER, .width = 240, .height = 240, .margin = 2, .fg = LCD_WHITE, .bg = LCD_BLACK, .font = &font, }; text_draw(&text); } void battery_run(void) { static uint32_t last_run = 0; uint32_t now = to_ms_since_boot(get_absolute_time()); if ((now >= (last_run + BATT_INTERVAL_MS)) || (last_run == 0)) { last_run = now; draw_battery_indicator(); draw_wifi_indicator(); } }