diff --git a/Core/Inc/graphics/display.h b/Core/Inc/graphics/display.h index fb37146..42bd499 100644 --- a/Core/Inc/graphics/display.h +++ b/Core/Inc/graphics/display.h @@ -34,6 +34,9 @@ typedef rgb888_pixel_t pixel_t; (((r & 0xFF) << 16) | ((g & 0xFF) << 8) | (b & 0xFF)) #endif // PIXEL_FORMAT_888 -extern volatile pixel_t framebuffer[DISPLAY_HEIGHT * DISPLAY_WIDTH]; +extern volatile pixel_t *current_framebuffer; +extern volatile pixel_t *next_framebuffer; + +void swap_framebuffers(void); #endif \ No newline at end of file diff --git a/Core/Inc/graphics/menu.h b/Core/Inc/graphics/menu.h index 932e7ed..1bb10bf 100644 --- a/Core/Inc/graphics/menu.h +++ b/Core/Inc/graphics/menu.h @@ -45,7 +45,7 @@ void draw_menu(volatile pixel_t *const framebuffer, const graphical_menu_t *cons void partial_redraw_menu(volatile pixel_t *const framebuffer, graphical_menu_t *const menu, uint8_t old_highlighted_entry_idx, uint8_t new_highlighted_entry_idx); void select_menu_entry(graphical_menu_t *const menu); void set_selected_menu_entry_idx(volatile pixel_t *const framebuffer, graphical_menu_t *const menu, uint8_t idx); -void decrement_selected_menu_entry_idx(graphical_menu_t *const menu); -void increment_selected_menu_entry_idx(graphical_menu_t *const menu); +void decrement_selected_menu_entry_idx(volatile pixel_t *const framebuffer, graphical_menu_t *const menu); +void increment_selected_menu_entry_idx(volatile pixel_t *const framebuffer, graphical_menu_t *const menu); #endif \ No newline at end of file diff --git a/Core/Src/graphics/display.c b/Core/Src/graphics/display.c index 07b0d31..58c8758 100644 --- a/Core/Src/graphics/display.c +++ b/Core/Src/graphics/display.c @@ -1,4 +1,40 @@ +#include "main.h" #include "display.h" __attribute__((section(".sdram"))) -volatile pixel_t framebuffer[DISPLAY_HEIGHT * DISPLAY_WIDTH]; +volatile pixel_t framebuffer1[DISPLAY_HEIGHT * DISPLAY_WIDTH]; +volatile pixel_t framebuffer2[DISPLAY_HEIGHT * DISPLAY_WIDTH]; + +volatile pixel_t *current_framebuffer = framebuffer1; +volatile pixel_t *next_framebuffer = framebuffer2; + +extern LTDC_HandleTypeDef hltdc; +extern DMA2D_HandleTypeDef hdma2d; + +void HAL_LTDC_LineEventCallback(LTDC_HandleTypeDef *hltdc) +{ + // Swap the LTDC's active framebuffer address to the back buffer + HAL_LTDC_SetAddress(hltdc, (uint32_t)current_framebuffer, 0); + + // Clear the Line Interrupt pending bit + HAL_NVIC_DisableIRQ(LTDC_IRQn); +} + +void copy_current_to_next_framebuffer(void) +{ + for (uint32_t i = 0; i < DISPLAY_HEIGHT * DISPLAY_WIDTH; i++) + { + next_framebuffer[i] = current_framebuffer[i]; + } +} + +void swap_framebuffers(void) +{ + volatile pixel_t *temp = current_framebuffer; + current_framebuffer = next_framebuffer; + next_framebuffer = temp; + HAL_LTDC_ProgramLineEvent(&hltdc, 296); + HAL_NVIC_EnableIRQ(LTDC_IRQn); + + copy_current_to_next_framebuffer(); +} \ No newline at end of file diff --git a/Core/Src/graphics/graphics.c b/Core/Src/graphics/graphics.c index 43b14c9..eedcd86 100644 --- a/Core/Src/graphics/graphics.c +++ b/Core/Src/graphics/graphics.c @@ -1,4 +1,5 @@ #include "graphics.h" +#include "display.h" void DisplayTest(pixel_t color) { @@ -6,7 +7,7 @@ void DisplayTest(pixel_t color) { for (uint16_t w = 0; w < DISPLAY_WIDTH; w++) { - framebuffer[(h * DISPLAY_WIDTH) + w] = color; + next_framebuffer[(h * DISPLAY_WIDTH) + w] = color; } } @@ -20,7 +21,7 @@ void DrawBox(uint32_t topleft_x_loc, uint32_t topleft_y_loc, uint32_t width, uin { if (x < DISPLAY_WIDTH && y < DISPLAY_HEIGHT) { - framebuffer[(y * DISPLAY_WIDTH) + x] = color; + next_framebuffer[(y * DISPLAY_WIDTH) + x] = color; } } } diff --git a/Core/Src/graphics/menu.c b/Core/Src/graphics/menu.c index ceddff7..0e49f48 100644 --- a/Core/Src/graphics/menu.c +++ b/Core/Src/graphics/menu.c @@ -6,10 +6,10 @@ static const uint16_t entry_height = 40; static const uint16_t padding_x = 10; static const uint16_t padding_y = 0; -static const pixel_t enabled_text_color = MAKE_PIXEL(0, 0, 0); +static const pixel_t enabled_text_color = MAKE_PIXEL(255, 255, 255); static const pixel_t disabled_text_color = MAKE_PIXEL(128, 128, 128); -static const pixel_t entry_bg_color = MAKE_PIXEL(255, 255, 255); -static const pixel_t highlighted_bg_color = MAKE_PIXEL(0, 0, 0); +static const pixel_t entry_bg_color = MAKE_PIXEL(0, 0, 0); +static const pixel_t highlighted_bg_color = MAKE_PIXEL(50, 50, 50); static const pixel_t highlighted_text_color = MAKE_PIXEL(255, 255, 0); void draw_menu_entry(volatile pixel_t *const framebuffer, const graphical_menu_t *const menu, uint8_t entry_idx) @@ -112,7 +112,7 @@ void set_selected_menu_entry_idx(volatile pixel_t *const framebuffer, graphical_ partial_redraw_menu(framebuffer, menu, old_highlighted_entry_idx, idx); } -void decrement_selected_menu_entry_idx(graphical_menu_t *const menu) +void decrement_selected_menu_entry_idx(volatile pixel_t *const framebuffer, graphical_menu_t *const menu) { if (menu->selected_entry_idx == 0) { @@ -122,7 +122,7 @@ void decrement_selected_menu_entry_idx(graphical_menu_t *const menu) set_selected_menu_entry_idx(framebuffer, menu, menu->selected_entry_idx - 1); } -void increment_selected_menu_entry_idx(graphical_menu_t *const menu) +void increment_selected_menu_entry_idx(volatile pixel_t *const framebuffer, graphical_menu_t *const menu) { if (menu->selected_entry_idx == menu->layout->num_entries - 1) { diff --git a/Core/Src/main.c b/Core/Src/main.c index 23ae4cd..8ec0a4e 100644 --- a/Core/Src/main.c +++ b/Core/Src/main.c @@ -474,15 +474,20 @@ static void MX_DMA2D_Init(void) /* USER CODE END DMA2D_Init 0 */ + // Configure DMA2D for RGB565 memory-to-memory copy + hdma2d.Init.ColorMode = DMA2D_OUTPUT_RGB565; + HAL_DMA2D_Init(&hdma2d); + HAL_DMA2D_ConfigLayer(&hdma2d, 1); + /* USER CODE BEGIN DMA2D_Init 1 */ /* USER CODE END DMA2D_Init 1 */ hdma2d.Instance = DMA2D; hdma2d.Init.Mode = DMA2D_M2M; - hdma2d.Init.ColorMode = DMA2D_OUTPUT_ARGB8888; + hdma2d.Init.ColorMode = DMA2D_OUTPUT_RGB565; hdma2d.Init.OutputOffset = 0; hdma2d.LayerCfg[1].InputOffset = 0; - hdma2d.LayerCfg[1].InputColorMode = DMA2D_INPUT_ARGB8888; + hdma2d.LayerCfg[1].InputColorMode = DMA2D_INPUT_RGB565; hdma2d.LayerCfg[1].AlphaMode = DMA2D_NO_MODIF_ALPHA; hdma2d.LayerCfg[1].InputAlpha = 0; if (HAL_DMA2D_Init(&hdma2d) != HAL_OK) @@ -593,7 +598,7 @@ static void MX_LTDC_Init(void) pLayerCfg.Alpha0 = 0; pLayerCfg.BlendingFactor1 = LTDC_BLENDING_FACTOR1_PAxCA; pLayerCfg.BlendingFactor2 = LTDC_BLENDING_FACTOR2_PAxCA; - pLayerCfg.FBStartAdress = (uint32_t)(&framebuffer); + pLayerCfg.FBStartAdress = (uint32_t)(¤t_framebuffer); pLayerCfg.ImageWidth = 240; pLayerCfg.ImageHeight = 320; pLayerCfg.Backcolor.Blue = 0; diff --git a/Core/Src/ui.c b/Core/Src/ui.c index 93f1b19..adb1526 100644 --- a/Core/Src/ui.c +++ b/Core/Src/ui.c @@ -1,6 +1,6 @@ #include "ui.h" -#include "graphics.h" #include "menu.h" +#include "display.h" void ui_enter_submenu(void *const args); @@ -61,7 +61,7 @@ enum ui_state_t { }; static bool redraw_requested = true; -static enum ui_state_t ui_state = UI_STATE_MENU; +// static enum ui_state_t ui_state = UI_STATE_MENU; static graphical_menu_t *current_menu = &main_menu; /************************* */ @@ -97,12 +97,14 @@ void ui_right_button_pressed(void) void ui_up_button_pressed(void) { - decrement_selected_menu_entry_idx(current_menu); + decrement_selected_menu_entry_idx(next_framebuffer, current_menu); + swap_framebuffers(); } void ui_down_button_pressed(void) { - increment_selected_menu_entry_idx(current_menu); + increment_selected_menu_entry_idx(next_framebuffer, current_menu); + swap_framebuffers(); } void ui_ok_button_pressed(void) @@ -120,6 +122,7 @@ void ui_task(void) if (redraw_requested) { redraw_requested = false; - draw_menu(framebuffer, current_menu); + draw_menu(next_framebuffer, current_menu); + swap_framebuffers(); } } \ No newline at end of file