Description
What MCU/Processor/Board and compiler are you using?
Custom Teensy Micromod with SDRAM (aka Dev board V4) - experimental
What LVGL version are you using?
8.3.3 / 8.3.11
What do you want to achieve?
Use two full screen sized frame buffers in SDRAM
What have you tried so far?
See code below
I have set my flush CB to simpley set the next buffer address for the eLCDIF.
I have added a callback to the eLCDIF frame done interrupt that calls lv_disp_flush_ready
and tells LVGL it can transmit the next frame.
I do see some rendering on the screen, but mostly garbage.
I know the library works as I have displayed a c array image copied into SDRAM and pointed to the LCDIF next buffer register (without LVGL)
Is there a better way to do this that is non-blocking?
Code to reproduce
my main.cpp code.
Im using an eLCDIF_t4 library that I put together earlier this week, alongside a SDRAM_t4 library that was written over the past 6 weeks by senior forum members on PJRC
#include "SDRAM_t4.h"
#include "eLCDIF_t4.h"
#include "wallpaper.c"
#include "lvgl.h"
SDRAM_t4 sdram;
eLCDIF_t4 lcd;
eLCDIF_t4_config lcd_config = {480, 8, 4, 4, 800, 8, 4, 4, 25, 24, 0, 0};
static lv_disp_drv_t disp_drv; /*A variable to hold the drivers. Must be static or global.*/
EXTMEM lv_color_t lcdBuffer1[800*480] __attribute__((aligned(64)));
EXTMEM lv_color_t lcdBuffer2[800*480] __attribute__((aligned(64)));
/*A static or global variable to store the buffers*/
static lv_disp_draw_buf_t disp_buf;
void my_flush_cb(lv_disp_drv_t * disp_drv, const lv_area_t * area, lv_color_t * color_p){
static bool runLCD = false;
if(!runLCD){
lcd.runLCD(); // Turn on the LCDIF when the 1st frame is ready to be displayed
runLCD = true;
}
lcd.setNextBufferAddress((uint32_t*)color_p);
}
void lcdCallback(){
lv_disp_flush_ready(&disp_drv);
}
static void anim_x_cb(void * var, int32_t v)
{
lv_obj_set_x(var, v);
}
static void anim_size_cb(void * var, int32_t v)
{
lv_obj_set_size(var, v, v);
}
/**
* Create a playback animation
*/
void lv_example_anim_2(void)
{
lv_obj_t * obj = lv_obj_create(lv_scr_act());
lv_obj_set_style_bg_color(obj, lv_palette_main(LV_PALETTE_RED), 0);
lv_obj_set_style_radius(obj, LV_RADIUS_CIRCLE, 0);
lv_obj_align(obj, LV_ALIGN_LEFT_MID, 10, 0);
lv_anim_t a;
lv_anim_init(&a);
lv_anim_set_var(&a, obj);
lv_anim_set_values(&a, 10, 50);
lv_anim_set_time(&a, 1000);
lv_anim_set_playback_delay(&a, 100);
lv_anim_set_playback_time(&a, 300);
lv_anim_set_repeat_delay(&a, 500);
lv_anim_set_repeat_count(&a, LV_ANIM_REPEAT_INFINITE);
lv_anim_set_path_cb(&a, lv_anim_path_ease_in_out);
lv_anim_set_exec_cb(&a, anim_size_cb);
lv_anim_start(&a);
lv_anim_set_exec_cb(&a, anim_x_cb);
lv_anim_set_values(&a, 10, 240);
lv_anim_start(&a);
}
IntervalTimer lv_tick;
#define LVGL_TICK_PERIOD 3
static void lv_tick_handler(void)
{
lv_tick_inc(LVGL_TICK_PERIOD);
}
void setup() {
Serial.begin(115200);
Serial.print(CrashReport);
//Start the SDRAM at 133Mhz
if (!sdram.begin(32, 133,0)){
Serial.println("SDRAM init fail :( ...");
}
else {
Serial.println("SDRAM init succcess ;)");
// Start the eLCFIF and set the current and next buffers (same source for this test)
lcd.begin(BUS_24BIT, WORD_24BIT, lcd_config);
lcd.onCompleteCallback(lcdCallback);
lcd.setCurrentBufferAddress(lcdBuffer1);
lcd.setNextBufferAddress(lcdBuffer1);
//Once everyhing is ready, set the run bit on the eLCDIF to start pushing data to the display
lv_init();
/*Initialize `disp_buf` with the buffer(s). With only one buffer use NULL instead buf_2 */
lv_disp_draw_buf_init(&disp_buf, lcdBuffer1, lcdBuffer2, 800*480);
lv_disp_drv_init(&disp_drv); /*Basic initialization*/
disp_drv.draw_buf = &disp_buf; /*Set an initialized buffer*/
disp_drv.flush_cb = my_flush_cb; /*Set a flush callback to draw to the display*/
disp_drv.hor_res = 800; /*Set the horizontal resolution in pixels*/
disp_drv.ver_res = 480; /*Set the vertical resolution in pixels*/
disp_drv.full_refresh = 1;
disp_drv.direct_mode = 0;
lv_disp_t * disp = lv_disp_drv_register(&disp_drv); /*Register the driver and save the created display objects*/
lv_tick.begin(lv_tick_handler, LVGL_TICK_PERIOD * 1000); // Start ticker
lv_example_anim_2();
}
}
unsigned long previousMillis = 0;
void loop() {
unsigned long currentMillis = millis();
if (currentMillis - previousMillis >= 5) {
// Save the last time lv_timer_handler was called
previousMillis = currentMillis;
// Call lv_timer_handler
lv_timer_handler();
}
//Serial.println("loop..");
}
Screenshot and/or video
If possible, add screenshots and/or videos about the current state.