This commit is contained in:
Dylan Smith
2026-01-12 14:40:36 -05:00
parent 2624b59564
commit 73005fc56b
16 changed files with 1685 additions and 28 deletions

View File

@@ -5,10 +5,14 @@
#define DISPLAY_WIDTH 240
#define DISPLAY_HEIGHT 320
#define PIXEL_FORMAT_565
//#define PIXEL_FORMAT_888
typedef uint16_t rgb565_pixel_t;
typedef uint32_t rgb888_pixel_t;
#ifdef PIXEL_FORMAT_565
typedef rgb565_pixel_t pixel_t;
#define PIXEL_RED(p) (((p) >> 11) & 0x1F)
#define PIXEL_GREEN(p) (((p) >> 5) & 0x3F)
@@ -16,13 +20,20 @@ typedef uint16_t rgb565_pixel_t;
#define MAKE_PIXEL(r,g,b) \
(((r & 0x1F) << 11) | ((g & 0x3F) << 5) | (b & 0x1F))
#endif // PIXEL_FORMAT_565
extern volatile rgb565_pixel_t framebuffer[DISPLAY_HEIGHT * DISPLAY_WIDTH];
extern volatile uint32_t times_changed;
#ifdef PIXEL_FORMAT_888
typedef rgb888_pixel_t pixel_t;
#define PIXEL_RED(p) (((p) >> 16) & 0xFF)
#define PIXEL_GREEN(p) (((p) >> 8) & 0xFF)
#define PIXEL_BLUE(p) ((p) & 0xFF)
void DisplayTest(uint16_t color);
#define MAKE_PIXEL(r,g,b) \
(((r & 0xFF) << 16) | ((g & 0xFF) << 8) | (b & 0xFF))
#endif // PIXEL_FORMAT_888
extern volatile pixel_t framebuffer[DISPLAY_HEIGHT * DISPLAY_WIDTH];
#endif

View File

@@ -5,6 +5,14 @@
#include "display.h"
#include "lvgl.h"
// Font declarations - fonts are defined in separate .c files to avoid static variable conflicts
#if LVGL_VERSION_MAJOR >= 8
extern const lv_font_t roboto_bold_font;
extern const lv_font_t roboto_bold_large_font;
#else
extern lv_font_t roboto_bold_font;
extern lv_font_t roboto_bold_large_font;
#endif
uint16_t draw_character(rgb565_pixel_t *framebuffer, const lv_font_t *font, const uint16_t x_loc, const uint16_t y_loc, const uint8_t character, rgb565_pixel_t color);

View File

@@ -7,6 +7,13 @@
*
* This layer includes a lot of code from lv_font_fmt_txt.h to define how
* a bitmapped font is expressed.
*
* See:
* - https://github.com/lvgl/lv_font_conv
* - https://github.com/lvgl/lvgl/blob/master/src/font/lv_font.h
* - https://github.com/lvgl/lvgl/blob/master/src/font/fmt_txt/lv_font_fmt_txt.h
*
* - Dylan
*/
#ifndef LVGL_H
@@ -15,13 +22,27 @@
#include "stdint.h"
#include "stdbool.h"
/* Dummy Defines */
#define LV_ATTRIBUTE_LARGE_CONST
#define LV_FONT_SUBPX_NONE 0
#ifndef NULL
#define NULL 0
#endif
/******************************************* */
/* Dummy defines for LVGL font compatibility */
#ifndef LV_ATTRIBUTE_LARGE_CONST
#define LV_ATTRIBUTE_LARGE_CONST
#endif
#ifndef LV_FONT_SUBPX_NONE
#define LV_FONT_SUBPX_NONE 0
#endif
#ifndef LVGL_VERSION_MAJOR
#define LVGL_VERSION_MAJOR 7
#define LV_VERSION_CHECK(X,Y,Z) 0
#endif
/******************** */
/* Struct Definitions */
typedef struct _lv_font_t lv_font_t;

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,10 @@
#ifndef GRAPHICS_H
#define GRAPHICS_H
#include "display.h"
#include "stdint.h"
void DisplayTest(pixel_t color);
void DrawBox(uint32_t topleft_x_loc, uint32_t topleft_y_loc, uint32_t height, uint32_t width, pixel_t color);
#endif

25
Core/Inc/graphics/menu.h Normal file
View File

@@ -0,0 +1,25 @@
#ifndef MENU_H
#define MENU_H
#include "stdint.h"
#include "stdbool.h"
typedef struct
{
uint8_t *title;
bool enabled; // not enabled = grayed out, unselectable
void *highlighted_callback_function;
void *selected_callback_function;
} graphical_menu_entry_t;
typedef struct _graphical_menu_t graphical_menu_t;
struct _graphical_menu_t {
graphical_menu_t *parent_menu;
uint8_t num_entries;
uint8_t highlighted_idx;
graphical_menu_entry_t *entries;
};
#endif

View File

@@ -0,0 +1,4 @@
#include "display.h"
__attribute__((section(".sdram")))
volatile pixel_t framebuffer[DISPLAY_HEIGHT * DISPLAY_WIDTH];

View File

@@ -17,6 +17,7 @@ static uint16_t find_glyph_id_in_cmap(const lv_font_fmt_txt_cmap_t * cmap, uint3
return 0;
}
bool lv_font_get_glyph_dsc_fmt_txt(const lv_font_t * font, lv_font_fmt_txt_glyph_dsc_t * dsc_out, uint32_t character)
{
lv_font_fmt_txt_dsc_t *font_dsc = (lv_font_fmt_txt_dsc_t *) font->dsc;
@@ -32,9 +33,10 @@ bool lv_font_get_glyph_dsc_fmt_txt(const lv_font_t * font, lv_font_fmt_txt_glyph
return false;
}
// Left as a dummy definition for LVGL font compatibility.
// We're not processing the bitmaps with draw buffers like LVGL does.
const void * lv_font_get_bitmap_fmt_txt(lv_font_fmt_txt_glyph_dsc_t * g_dsc, lv_draw_buf_t * draw_buf)
{
}
/**

View File

@@ -0,0 +1,7 @@
#include "fonts/roboto_bold_font.h"
// This file exists solely to include the font header in its own translation unit
// so that the static font_dsc variable doesn't conflict with other fonts.
// The font pointer (roboto_bold_font) is defined in the header and exported
// for use in other translation units.

View File

@@ -0,0 +1,7 @@
#include "fonts/roboto_bold_large_font.h"
// This file exists solely to include the font header in its own translation unit
// so that the static font_dsc variable doesn't conflict with other fonts.
// The font pointer (roboto_bold_large_font) is defined in the header and exported
// for use in other translation units.

View File

@@ -1,15 +1,7 @@
#include "display.h"
#include "stm32f4xx_hal_ltdc.h"
#include "graphics.h"
__attribute__((section(".sdram")))
volatile rgb565_pixel_t framebuffer[DISPLAY_HEIGHT * DISPLAY_WIDTH];
__attribute__((section(".sdram")))
volatile uint32_t times_changed;
void DisplayTest(uint16_t color)
void DisplayTest(pixel_t color)
{
times_changed++;
for (uint16_t h = 0; h < DISPLAY_HEIGHT; h++)
{
for (uint16_t w = 0; w < DISPLAY_WIDTH; w++)
@@ -18,4 +10,18 @@ void DisplayTest(uint16_t color)
}
}
}
void DrawBox(uint32_t topleft_x_loc, uint32_t topleft_y_loc, uint32_t height, uint32_t width, pixel_t color)
{
for (uint32_t y = topleft_y_loc; y < (topleft_y_loc + height); y++)
{
for (uint32_t x = topleft_x_loc; x < (topleft_x_loc + width); x++)
{
if (x < DISPLAY_WIDTH && y < DISPLAY_HEIGHT)
{
framebuffer[(y * DISPLAY_WIDTH) + x] = color;
}
}
}
}

6
Core/Src/graphics/menu.c Normal file
View File

@@ -0,0 +1,6 @@
#include "menu.h"
void draw_menu(graphical_menu_t *menu)
{
}

View File

@@ -27,7 +27,6 @@
/* USER CODE BEGIN Includes */
#include "display.h"
#include "font.h"
#include "roboto_bold_font.h"
/* USER CODE END Includes */
/* Private typedef -----------------------------------------------------------*/
@@ -89,6 +88,64 @@ void StartDefaultTask(void const * argument);
/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
/**
* @brief Convert a single digit (0-9) to its ASCII character
* @param digit: The digit to convert (0-9)
* @retval ASCII character '0' through '9'
*/
static char digit_to_ascii(uint8_t digit)
{
return (char)('0' + digit);
}
/**
* @brief Convert an unsigned 32-bit integer to a null-terminated string
* @param value: The number to convert
* @param buffer: Pointer to the output buffer
* @param buffer_size: Size of the buffer
* @retval None
*/
static void uint32_to_string(uint32_t value, uint8_t *buffer, uint8_t buffer_size)
{
uint8_t i = 0;
uint8_t digits[10]; // Maximum 10 digits for uint32_t
uint8_t digit_count = 0;
// Handle zero case
if (value == 0)
{
if (buffer_size > 0)
{
buffer[0] = '0';
buffer[1] = '\0';
}
return;
}
// Extract digits from right to left
while (value > 0 && digit_count < 10)
{
digits[digit_count] = (uint8_t)(value % 10);
value /= 10;
digit_count++;
}
// Convert digits to ASCII and store in buffer (reversed)
for (i = 0; i < digit_count && i < (buffer_size - 1); i++)
{
buffer[i] = digit_to_ascii(digits[digit_count - 1 - i]);
}
// Null terminate
if (i < buffer_size)
{
buffer[i] = '\0';
}
else if (buffer_size > 0)
{
buffer[buffer_size - 1] = '\0';
}
}
void LCD_Write_Cmd(uint8_t cmd)
{
@@ -862,16 +919,23 @@ void StartDefaultTask(void const * argument)
times_changed = 0;
ILI9341_Init();
uint8_t time_string[20] = {0};
DisplayTest(0xFFFF);
draw_string(framebuffer, &roboto_bold_font, 10, 75, "Number of beans:", 0x0000);
/* Infinite loop */
for(;;)
{
DisplayTest(0xffff);
draw_string(framebuffer, &roboto_bold_font, 25, 25, "Divide Voltage!", 0x0000);
osDelay(500);
DisplayTest(0x0000);
draw_string(framebuffer, &roboto_bold_font, 25, 25, "Divide Voltage!", 0xf800);
osDelay(500);
uint32_t t = HAL_GetTick() / 100;
// Convert milliseconds to string
uint32_to_string(t, time_string, sizeof(time_string));
DrawBox(25, 0, 40, 80, 0xffff);
draw_string(framebuffer, &roboto_bold_font, 25, 25, time_string, 0x0000);
DrawBox(25, 100, 40, 150, 0xffff);
draw_string(framebuffer, &roboto_bold_large_font, 25, 125, time_string, 0x001f);
osDelay(100);
}
/* USER CODE END 5 */
}