I am trying to run LVGL V9.2 on STM32H7 with a monochrome display from Newhaven - 128x128 ST7528. As per the documentation, rendering for monochrome displays seems to be supported. I just cannot find the proper documentation to implement the flush callback for this display.
Can any one give me a direction here?
Thanks.
By the way I am able to run the simulator with the monochrome setting correctly. So it seems the graphics library is all setup to work with monochrome displays. Just the flush_cb() needs to be implemented for which I need to know what will be the contents of the draw buffer which I can modify and send to the display over SPI.
What MCU/Processor/Board and compiler are you using?
STM32H7, Custom board, ARM GCC Compiler.
What LVGL version are you using?
V9.2
What do you want to achieve?
Know how the draw buffer will be rendered for monochrome displays so that I can implement the flush callback.
What have you tried so far?
Reading similar topics on this forum.
Scanning trough the latest documentation.
Went through multiple stale articles, forum posts and github issues regarding this issue but due to LVGLs major version changes many things have become obsolete and are not applicable. Hence I am seeking clear information here.
Was able to display text on the ubuntu+sdl simulator selecting monochrome theme and other settings hence trying to make it work on hardware.
#include "lv_disp_st7528.h"
#include "app_middleware/lvgl/lvgl.h"
#include "config/appconfig.h"
#include <stdbool.h>
#include <string.h>
#define BYTE_PER_PIXEL (LV_COLOR_FORMAT_GET_SIZE(LV_COLOR_FORMAT_I1))
/* The buffer should be 8 bytes larger as per the documentation. */
#define BUFF_SIZE ((ST7528_HOR_RES * ST7528_VER_RES * BYTE_PER_PIXEL)/8 + 8)
static void disp_flush(lv_display_t * disp_drv, const lv_area_t * area, uint8_t * px_map);
static uint8_t frameBuff[BUFF_SIZE];
volatile bool disp_flush_enabled = true;
/* Buffer for one page of data */
static uint8_t pageBuff[ST7528_HOR_RES * 4];
void lv_disp_st7528_init(void)
{
/*-------------------------
* Initialize your display
* -----------------------*/
ST7528Init();
/*------------------------------------
* Create a display and set a flush_cb
* -----------------------------------*/
lv_display_t * disp = lv_display_create(ST7528_HOR_RES, ST7528_VER_RES);
//lv_display_set_color_format(disp, LV_COLOR_FORMAT_I1);
lv_display_set_flush_cb(disp, disp_flush);
//lv_draw_sw_i1_convert_to_vtiled();
lv_display_set_buffers(disp, frameBuff, NULL,
sizeof(frameBuff), LV_DISPLAY_RENDER_MODE_FULL);
}
/* Enable updating the screen (the flushing process) when disp_flush() is called by LVGL
*/
void lv_disp_st7528_en_update(void)
{
disp_flush_enabled = true;
}
/* Disable updating the screen (the flushing process) when disp_flush() is called by LVGL
*/
void lv_disp_st7528_dis_update(void)
{
disp_flush_enabled = false;
}
/*Flush the content of the internal buffer the specific area on the display.
*`px_map` contains the rendered image as raw pixel map and it should be copied to `area` on the display.
*You can use DMA or any hardware acceleration to do this operation in the background but
*'lv_display_flush_ready()' has to be called when it's finished.*/
static void disp_flush(lv_display_t * disp_drv, const lv_area_t * area, uint8_t * px_map)
{
if(disp_flush_enabled)
{
/* Skip palette */
px_map += 8;
int32_t pageBuffIndex;
int32_t pxBuffBitId;
for(int32_t pgId = 0; pgId < 16; pgId++)
{
pageBuffIndex = 0;
for(int32_t colId = 0; colId < 128; colId++)
{
/* Which byte in the row */
int32_t byteCol = colId / 8;
/* Reverse bit order (7-0 instead of 0-7) */
pxBuffBitId = 7 - (colId % 8);
for(int32_t bitId = 0; bitId < 8; bitId++)
{
/* Calculate the byte index in the framebuffer */
int32_t row = pgId * 8 + bitId;
/* Calculate the byte index in the framebuffer */
int32_t calcIdx = (row * 16) + byteCol;
if((px_map[calcIdx]) & (1 << pxBuffBitId))
{
SBI(pageBuff[pageBuffIndex], bitId);
}
else
{
CBI(pageBuff[pageBuffIndex], bitId);
}
}
/* Copy for gray levels */
pageBuff[pageBuffIndex + 1] = pageBuff[pageBuffIndex];
pageBuff[pageBuffIndex + 2] = pageBuff[pageBuffIndex];
pageBuff[pageBuffIndex + 3] = pageBuff[pageBuffIndex];
pageBuffIndex += 4;
}
ST7528SetPageAddr(pgId);
ST7528SetColumnAddr(0);
ST7528WriteData(pageBuff, sizeof(pageBuff));
}
}
lv_display_flush_ready(disp_drv);
}