What MCU/Processor/Board and compiler are you using?
stm32f103 with arm-none-eabi-gcc from ac6’s systemworkbench
What do you want to achieve?
I want to achieve a minimal display (due to the limited flash and ram) just a bar that eventually will change
What have you tried so far?
I tried to follow the tutorials “Porting LittlevGL for monochrome display” and the blog post “LittlevGL on a Monochrome OLED” as well as reading the GetStarted articles
I am using the lv_port_disp_init() in the renamed lv_port_display.c. I am calling the filled-in disp_init() and using the one buffer sized #define BUFFERSIZE (LV_HOR_RES_MAX * LV_VER_RES_MAX / 8). The disp_flush() I filled in with a simple copy all the bytes out to the display.
When the lv_disp_drv_register( &disp_drv) runs at the end of lv_port_disp_init(), I am getting a null disp.
What pretty please did I forget to initialize?
Code to reproduce
Add the relevant code snippets here.
The code block(s) should be between ```c and ``` tags:
The first problem was what you diagnosed - a missing call to lv_init()
The picture is the output I’m getting. The 8 stripes are the chunks of 128 that my flush_cb() is pushing. I wonder if the stuff at the beginning is the “bar” that would have been in the middle if I had used the area info
I think I introduced the problem here, that the buffer pointed-to by disp_drv isn’t filled in yet. The code in there looks like I need to follow the color_p pointer for the display data. Is that a correct analysis?
static void disp_flush(lv_disp_drv_t * disp_drv, const lv_area_t * area, lv_color_t * color_p)
{
/The most simple case (but also the slowest) to put all pixels to the screen one-by-one/
ssd1306FlushToScreen( disp_drv->buffer );
#if 0
int32_t x;
int32_t y;
for(y = area->y1; y <= area->y2; y++) {
for(x = area->x1; x <= area->x2; x++) {
/* Put a pixel to the display. For example: /
/ put_px(x, y, color_p)/
color_p++;
}
} #endif
/* IMPORTANT!!!
* Inform the graphics library that you are ready with the flushing
* */
lv_disp_flush_ready( disp_drv );
Don’t be investigating the contents of the lv_disp_drv_t structure. That’s reserved for the implementation.
Yes. You can convert each of the values in color_p to an appropriate color format with the lv_color_to series of functions (e.g. lv_color_to1, lv_color_to8):
for(y = area->y1; y <= area->y2; y++) {
for(x = area->x1; x <= area->x2; x++) {
put_px(x, y, lv_color_to1(*color_p));
color_p++;
}
}
Thanks EmbeddedT, now I’m translating the lv_color_t union using the full member to test for my monochrome display. I’m puzzling over the x and y in terms of my display, do they map directly to offsets from (0,0)
Hi embeddedt,
Thanks for your help! I’m debugging my display and and it seems like I’m only getting the 1 level of color, I don’t ever get a 0 level. I do have the LV_COLOR_DEPTH set to 1 color level.
I get area (0,0) (127,7) and all the pixels are color 1, then the same for area(0,8)(127,15) and the successive areas through (0,56)(127,64) Do you have any idea what I may be doing wrong? I am expecting to see bar in the drawing color, and a dark background.
Thanks again,
Larry
tatic void disp_flush(lv_disp_drv_t * disp_drv, const lv_area_t * area, lv_color_t * color_p)
{
/The most simple case (but also the slowest) to put all pixels to the screen one-by-one/
int32_t x;
int32_t y;
SSD1306_COLOR color;
for(y = area->y1; y <= area->y2; y++) {
for(x = area->x1; x <= area->x2; x++) {
// Translate the passed in color value to our black or white
if ( color_p->full == 0 )
{
color = BLACK;
}
else // color is white
{
color = WHITE;
}
/* Put a pixel to the display. */
ssd1306_DrawPixel( x, y, color );
// Next pixel
color_p++;
}
}
ssd1306_UpdateScreen();
/* IMPORTANT!!!
* Inform the graphics library that you are ready with the flushing
* */
lv_disp_flush_ready( disp_drv );
Do you think I could be running out of memory: my stm32f103 has 128 KBytes of flash, 20KBytes RAM of which I am using about 87K right now, and I don’t see my code getting to the disp_flush() call back.
Can you step through it and find where it hangs? Also, for best results, you shouldn’t be calling lv_tick_inc in the same loop as lv_task_handler (use an interrupt or OS task).