diff --git a/docs/lcd_api.md b/docs/lcd_api.md index 3ca9766..a5f82da 100644 --- a/docs/lcd_api.md +++ b/docs/lcd_api.md @@ -104,7 +104,7 @@ void main(void) { #### Drawing text on the screen ```c -void lcd_display_text(const char* text, uint16_t x_pos, uint16_t y_pos, uint32_t color, uint32_t bg_color, sFONT *font); +void lcd_display_text(const char* text, uint16_t x_pos, uint16_t y_pos, uint32_t color, sFONT *font); ``` ```c @@ -116,7 +116,7 @@ void main(void) { ... lcd_init(true); ... - lcd_display_text("This is a text string.", 10, 10, LCD_GREEN, LCD_BLACK, LCD_FONT16); + lcd_display_text("This is a text string.", 10, 10, LCD_GREEN, LCD_FONT16); } ``` Display text on the LCD screen in a certain color. When text width exceeds BSP_LCD_GetXSize(), a text wrap will be performed. If the text wrap is between two will be injected. @@ -194,13 +194,13 @@ void main(void) { ... lcd_init(true); ... - + // From a C-array lcd_gif_t* gif = lcd_draw_gif(gif_array, gif_size, 0, 0); - + // From the filesystem lcd_gif_t* gif = lcd_draw_gif_from_fs("st.gif", 0, 0); - + if (gif == NULL) { LOG_WARNING("GIF could not be drawn"); } @@ -229,15 +229,22 @@ Call this function before drawing over the GIF. This function should not be called on a GIF that has already been stopped (GIFs with a loop count will stop automatically). It is possible that the handler has been assigned to a new GIF, so it would stop the new GIF instead. +#### Stopping all GIF animations +```c +void lcd_stop_all_gifs(void); +``` +This function stops all the GIF animations and frees the memory allocated for the GIF. +Call this function before drawing over the GIF. + #### Checking if a GIF is still running ```c bool lcd_gif_is_playing(lcd_gif_t* gif); ``` NOTE: It is possible that the GIF has stopped playing, but another GIF has taken its slot and is still playing. -#### Clearing the LCD screen +#### Clearing the text on the LCD screen ```c -void lcd_clear(uint32_t color); +void lcd_clear_text(void); ``` ```c @@ -246,9 +253,29 @@ void lcd_clear(uint32_t color); void main(void) { ... lcd_init(true); + lcd_display_text("Hello world!", 0, 0, LCD_GREEN, LCD_FONT20); ... - lcd_clear(LCD_BLACK); + lcd_clear_text(); } ``` -Clears the LCD screen to the specified color. +Clears all text strings on the LCD screen. + +#### Clearing the images on the LCD screen +```c +void lcd_clear_images(void); +``` + +```c +#include "lcd_api.h" + +void main(void) { + ... + lcd_init(true); + lcd_draw_img_from_fs("st.bmp", 300, 100); + ... + lcd_clear_images(); +} +``` + +Clears all text strings on the LCD screen. diff --git a/project/Core/Inc/lcd_api.h b/project/Core/Inc/lcd_api.h index 292515b..c3ee770 100644 --- a/project/Core/Inc/lcd_api.h +++ b/project/Core/Inc/lcd_api.h @@ -100,10 +100,9 @@ void lcd_task(void); * @param[in] x_pos X-position * @param[in] y_pos Y-position * @param[in] color Color in which the text will be displayed, see preset colors in defines above - * @param[in] bg_color Background color for the text * @param[in] font Font size, see defines above in file */ -void lcd_display_text(uint8_t* text, uint16_t x_pos, uint16_t y_pos, uint32_t color, uint32_t bg_color, sFONT *font); +void lcd_display_text(const char* text, uint16_t x_pos, uint16_t y_pos, uint32_t color, sFONT *font); /** * @brief Draw BMP image on screen @@ -144,13 +143,25 @@ void lcd_draw_bmp_img(uint8_t* bmp_buff, uint32_t x_pos, uint32_t y_pos); void lcd_draw_img_from_fs(const char* name, uint32_t x_pos, uint32_t y_pos); /** - * @brief Clear LCD screen - * Clears the whole LCD screen to the desired color + * @brief Clear LCD text + * Clears the text drawn on the LCD screen * - *@param[in] color Color to which the LCD should be cleared */ +void lcd_clear_text(void); -void lcd_clear(uint32_t color); +/** + * @brief Clear images + * Clears the images drawn on the LCD screen + * + */ +void lcd_clear_images(void); + +/** + * @brief LCD stop all GIFs + * Stops all playing GIFs on lcd screen + * + */ +void lcd_stop_all_gifs(void); /** * @brief Draw GIF image on screen from memory diff --git a/project/Core/Src/lcd_api.c b/project/Core/Src/lcd_api.c index 16232e5..2c0738e 100644 --- a/project/Core/Src/lcd_api.c +++ b/project/Core/Src/lcd_api.c @@ -22,18 +22,22 @@ void lcd_init(bool bl_on) { BSP_LCD_Init(); BSP_LCD_LayerDefaultInit(1, LCD_FB_START_ADDRESS); - BSP_LCD_LayerDefaultInit(0, LCD_FB_START_ADDRESS + (BSP_LCD_GetXSize() * BSP_LCD_GetYSize() * 4)); + BSP_LCD_LayerDefaultInit(0, LCD_FB_START_ADDRESS + (BSP_LCD_GetXSize() * BSP_LCD_GetYSize()) * 4); BSP_LCD_SelectLayer(0); - BSP_LCD_Clear(LCD_COLOR_BLACK); + BSP_LCD_Clear(0); BSP_LCD_SelectLayer(1); - BSP_LCD_Clear(LCD_COLOR_BLACK); + BSP_LCD_Clear(0); + BSP_LCD_SetLayerVisible(0, ENABLE); + BSP_LCD_SetLayerVisible(1, ENABLE); if (bl_on) { HAL_GPIO_WritePin(GPIOK, GPIO_PIN_3, GPIO_PIN_SET); HAL_GPIO_WritePin(GPIOI, GPIO_PIN_12, GPIO_PIN_SET); + LOG_INFO(TAG, "LCD initialise with backlight"); return; } HAL_GPIO_WritePin(GPIOK, GPIO_PIN_3, GPIO_PIN_RESET); HAL_GPIO_WritePin(GPIOI, GPIO_PIN_12, GPIO_PIN_RESET); + LOG_INFO(TAG, "LCD initialise without backlight"); } void lcd_task(void) { @@ -80,39 +84,42 @@ void lcd_task(void) { } } -void lcd_display_text(uint8_t* text, uint16_t x_pos, uint16_t y_pos, uint32_t color, uint32_t bg_color, sFONT* font) { +void lcd_display_text(const char* text, uint16_t x_pos, uint16_t y_pos, uint32_t color, sFONT* font) { + BSP_LCD_SelectLayer(1); LOG_INFO(TAG, "Display text: %s @x=%d,y=%d", text, x_pos, y_pos); - uint16_t tot_length = x_pos + (strlen(text) * font->Width); + uint16_t tot_length = x_pos + ((uint16_t)strlen(text) * font->Width); if ((x_pos % font->Width) != 0) { x_pos -= (x_pos % font->Width); } BSP_LCD_SetTextColor(color); - BSP_LCD_SetBackColor(bg_color); + BSP_LCD_SetBackColor(0); BSP_LCD_SetFont(font); if (tot_length > BSP_LCD_GetXSize()) { - for (int i = 0; i < strlen(text); i++) { + for (unsigned int i = 0; i < (unsigned int)strlen(text); i++) { if ((x_pos) > BSP_LCD_GetXSize() - (font->Width) * 2) { if (isalpha(text[i - 1]) && isalpha(text[i])) { - BSP_LCD_DisplayChar(x_pos, y_pos, '-'); + BSP_LCD_DisplayChar(x_pos, y_pos, (uint8_t)'-'); } else { - BSP_LCD_DisplayChar(x_pos, y_pos, text[i]); + BSP_LCD_DisplayChar(x_pos, y_pos, (uint8_t)text[i]); } x_pos = 0; y_pos += font->Height; continue; } - BSP_LCD_DisplayChar(x_pos, y_pos, text[i]); + BSP_LCD_DisplayChar(x_pos, y_pos, (uint8_t)text[i]); x_pos += font->Width; } return; } - BSP_LCD_DisplayStringAt(x_pos, y_pos, text, LEFT_MODE); + BSP_LCD_DisplayStringAt(x_pos, y_pos, (uint8_t*)text, LEFT_MODE); } void lcd_draw_raw_img(const void* p_src, uint32_t x_pos, uint32_t y_pos, uint32_t x_size, uint32_t y_size, uint32_t color_mode) { + LOG_INFO(TAG, "Displaying raw image: @x=%d, @y=%d, width=%d, height=%d", x_pos, y_pos, x_size, y_size); + BSP_LCD_SelectLayer(0); uint32_t address = hLtdcHandler.LayerCfg[1].FBStartAdress + (((BSP_LCD_GetXSize() * y_pos) + x_pos) * (4)); void* p_dst = (void*)address; @@ -146,23 +153,49 @@ void lcd_draw_raw_img(const void* p_src, uint32_t x_pos, uint32_t y_pos, uint32_ } void lcd_draw_bmp_img(uint8_t* bmp_buff, uint32_t x_pos, uint32_t y_pos) { + LOG_INFO(TAG, "Displaying BMP image: @x=%d, @y=%d", x_pos, y_pos); + BSP_LCD_SelectLayer(0); BSP_LCD_DrawBitmap(x_pos, y_pos, bmp_buff); } void lcd_draw_img_from_fs(const char* name, uint32_t x_pos, uint32_t y_pos) { + LOG_INFO(TAG, "Displaying BMP image %s: @x=%d, @y=%d", name, x_pos, y_pos); + BSP_LCD_SelectLayer(0); llfs_file_t* file = llfs_file_open(name); if (file != NULL) { BSP_LCD_DrawBitmap(x_pos, y_pos, (uint8_t*)file->data); return; } - LOG_WARN(TAG, "File \"%s\" not found", file->name); + LOG_WARN(TAG, "File \"%s\" not found", name); } -void lcd_clear(uint32_t color) { - BSP_LCD_Clear(color); +void lcd_clear_text(void) { + LOG_INFO(TAG, "Clear text"); + BSP_LCD_SelectLayer(1); + BSP_LCD_Clear(0); +} + +void lcd_clear_images(void) { + LOG_INFO(TAG, "Clear images"); + BSP_LCD_SelectLayer(0); + for (uint8_t i = 0; i < LCD_MAX_GIFS; i++) { + if (gifs[i].src != NULL) { + lcd_stop_gif(&gifs[i]); + } + } + BSP_LCD_Clear(0); +} + +void lcd_stop_all_gifs(void) { + for (uint8_t i = 0; i < LCD_MAX_GIFS; i++) { + if (gifs[i].src != NULL) { + lcd_stop_gif(&gifs[i]); + } + } } lcd_gif_t* lcd_draw_gif(uint8_t* src, size_t size, uint32_t x_pos, uint32_t y_pos) { + BSP_LCD_SelectLayer(0); lcd_gif_t* gif; // Get a free GIF slot @@ -174,6 +207,7 @@ lcd_gif_t* lcd_draw_gif(uint8_t* src, size_t size, uint32_t x_pos, uint32_t y_po // Open the GIF and reset slot values GIF_begin(&(gif->gif), GIF_PALETTE_RGB888); if (GIF_openRAM(&(gif->gif), src, (int)size, gif_draw_cb)) { + LOG_INFO(TAG, "Draw GIF: @x=%d, @y=%d with size: %d", x_pos, y_pos, size); gif->src = src; gif->x_pos = x_pos; gif->y_pos = y_pos; @@ -193,6 +227,7 @@ lcd_gif_t* lcd_draw_gif(uint8_t* src, size_t size, uint32_t x_pos, uint32_t y_po } lcd_gif_t* lcd_draw_gif_from_fs(const char* name, uint32_t x_pos, uint32_t y_pos) { + BSP_LCD_SelectLayer(0); lcd_gif_t* gif; llfs_file_t* file; @@ -202,7 +237,7 @@ lcd_gif_t* lcd_draw_gif_from_fs(const char* name, uint32_t x_pos, uint32_t y_pos LOG_WARN(TAG, "File \"%s\" not found", name); return NULL; } - + LOG_INFO(TAG, "Draw GIF %s", name); // Draw the GIF using the file data gif = lcd_draw_gif((uint8_t*)file->data, file->len, x_pos, y_pos); return gif; @@ -250,13 +285,14 @@ static inline void free_gif_slot(lcd_gif_t* gif) { * @param pDraw Pointer to the GIFDRAW struct */ static void gif_draw_cb(GIFDRAW* pDraw) { + BSP_LCD_SelectLayer(0); lcd_gif_t* gif = (lcd_gif_t*)pDraw->pUser; uint8_t* palette = pDraw->pPalette24; // The RGB888 color palette uint8_t* p_src = pDraw->pPixels; // Source pixel pointer int y = pDraw->iY + pDraw->y; // Current line being drawn // Calculate the destination address of the first pixel in the line - uint32_t address = hLtdcHandler.LayerCfg[1].FBStartAdress + (((BSP_LCD_GetXSize() * gif->y_pos) + gif->x_pos) * 4) + uint32_t address = hLtdcHandler.LayerCfg[0].FBStartAdress + (((BSP_LCD_GetXSize() * gif->y_pos) + gif->x_pos) * 4) + (y * (BSP_LCD_GetXSize() * 4)); // Restore the background @@ -285,4 +321,4 @@ static void gif_draw_cb(GIFDRAW* pDraw) { // Draw the pixel ((uint32_t *)address)[x] = color; } -} \ No newline at end of file +}