Skip to content

Commit

Permalink
[examples] Add LVGL example for Nucleo-L452RE with Ili9341
Browse files Browse the repository at this point in the history
  • Loading branch information
rleh committed Apr 6, 2021
1 parent d2abea5 commit e0d1327
Show file tree
Hide file tree
Showing 3 changed files with 235 additions and 0 deletions.
36 changes: 36 additions & 0 deletions examples/nucleo_l452re/lvgl/lv_conf_local.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/*
* Copyright (c) 2021, Raphael Lehmann
*
* This file is part of the modm project.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/

#ifndef LV_CONF_H
# error "Don't include this file directly, use 'lv_conf.h' instead!"
#endif

// Maximal resolutions
#define LV_HOR_RES_MAX 240
#define LV_VER_RES_MAX 320
#define LV_DPI 200

/* Color depth:
* - 1: 1 byte per pixel
* - 8: RGB332
* - 16: RGB565
* - 32: ARGB8888
*/
#define LV_COLOR_DEPTH 16

// Enable logging at INFO level
#define LV_USE_LOG 1
#define LV_LOG_LEVEL LV_LOG_LEVEL_INFO

// Enable a bigger font
#define LV_FONT_MONTSERRAT_36 1

// Disable anti-aliasing
#define LV_ANTIALIAS 0
183 changes: 183 additions & 0 deletions examples/nucleo_l452re/lvgl/main.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,183 @@
/*
* Copyright (c) 2021, Raphael Lehmann
*
* This file is part of the modm project.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
// ----------------------------------------------------------------------------

#include <modm/board.hpp>
#include <modm/debug.hpp>
#include <modm/processing.hpp>
#include <modm/driver/display/ili9341_spi.hpp>
#include <modm/driver/touch/touch2046.hpp>

#include <lvgl/lvgl.h>


// Set the log level
#undef MODM_LOG_LEVEL
#define MODM_LOG_LEVEL modm::log::DEBUG

using namespace Board;
using namespace modm::literals;


namespace tft
{
using DmaRx = Dma1::Channel2;
using DmaTx = Dma1::Channel3;
using Spi = SpiMaster1_Dma<DmaRx, DmaTx>;
//using Spi = SpiMaster1;
using Cs = modm::platform::GpioC8;
using Sck = modm::platform::GpioA5;
using Miso = modm::platform::GpioA6;
using Mosi = modm::platform::GpioA7;
using DataCommands = modm::platform::GpioC5;
using Reset = modm::platform::GpioC6;
using Backlight = modm::platform::GpioC9;
}

modm::Ili9341Spi<
tft::Spi,
tft::Cs,
tft::DataCommands,
tft::Reset,
tft::Backlight
> tftController;

namespace touch
{
using Spi = SpiMaster2;
using Cs = modm::platform::GpioB3;
using Sck = modm::platform::GpioB13;
using Miso = modm::platform::GpioB14;
using Mosi = modm::platform::GpioB15;
//using Interrupt = modm::platform::GpioA10;
}

modm::Touch2046<touch::Spi, touch::Cs> touchController;


static lv_disp_buf_t disp_buf;
static constexpr size_t buf_size = LV_HOR_RES_MAX * LV_VER_RES_MAX / 8;
static lv_color_t buf[buf_size];

bool my_touchpad_read(lv_indev_drv_t*, lv_indev_data_t* data)
{
data->state = RF_CALL_BLOCKING(touchController.isTouched()) ? LV_INDEV_STATE_PR : LV_INDEV_STATE_REL;
if(data->state == LV_INDEV_STATE_PR) {
auto xy = RF_CALL_BLOCKING(touchController.getTouchPosition());
data->point.x = std::get<0>(xy);
data->point.y = std::get<1>(xy);
}
return false;
}

void my_flush_cb(lv_disp_drv_t * disp_drv, const lv_area_t * area, lv_color_t * color_p)
{
tftController.drawRaw(
{area->x1, area->y1},
(area->x2 - area->x1 +1),
(area->y2 - area->y1 + 1),
(modm::glcd::Color*)color_p);
lv_disp_flush_ready(disp_drv);
}

int
main()
{
Board::initialize();
Dma1::enable();

tft::Spi::connect<
tft::Sck::Sck,
tft::Miso::Miso,
tft::Mosi::Mosi>();
tft::Spi::initialize<SystemClock, 40_MHz>();
tftController.initialize();
tftController.enableBacklight(true);

touch::Spi::connect<
touch::Sck::Sck,
touch::Miso::Miso,
touch::Mosi::Mosi>();
touch::Spi::initialize<SystemClock, 2500_kHz>();
modm::touch2046::Calibration cal{
.OffsetX = -11,
.OffsetY = 335,
.FactorX = 22018,
.FactorY = -29358,
.MaxX = 240,
.MaxY = 320,
.ThresholdZ = 500,
};
touchController.setCalibration(cal);

MODM_LOG_INFO << "modm LVGL example on Nucleo-L452RE board!\n\n";

lv_init();

// Initialize the display buffer
lv_disp_buf_init(&disp_buf, buf, NULL, buf_size);

// Initialize the display:
lv_disp_drv_t disp_drv;
lv_disp_drv_init(&disp_drv);
disp_drv.buffer = &disp_buf;
disp_drv.flush_cb = my_flush_cb;
disp_drv.hor_res = LV_HOR_RES_MAX;
disp_drv.ver_res = LV_VER_RES_MAX;
lv_disp_t * disp;
disp = lv_disp_drv_register(&disp_drv);

// Initialize touchscreen driver:
lv_indev_drv_t indev_drv;
lv_indev_drv_init(&indev_drv);
indev_drv.type = LV_INDEV_TYPE_POINTER;
indev_drv.read_cb = my_touchpad_read;
lv_indev_drv_register(&indev_drv);

lv_obj_t* scr = lv_disp_get_scr_act(disp); // Get the current screen

lv_obj_t* labelA = lv_label_create(scr, NULL);
lv_label_set_text(labelA, "Hello world!");
lv_obj_set_pos(labelA, 60, 10);
lv_obj_set_size(labelA, 120, 50);

lv_obj_t* btn = lv_btn_create(lv_scr_act(), NULL);
lv_obj_set_pos(btn, 60, 135);
lv_obj_set_size(btn, 120, 50);
lv_obj_t* btnLabel = lv_label_create(btn, NULL);
lv_label_set_text(btnLabel, "Button");
lv_obj_set_event_cb(btn, [](struct _lv_obj_t * obj, lv_event_t event) {
static uint16_t btnCounter = 0;
if(event == LV_EVENT_PRESSED) {
lv_label_set_text_fmt(lv_obj_get_child(obj, NULL), "Button: %d", ++btnCounter);
}
});

lv_obj_t* labelB = lv_label_create(scr, NULL);
lv_label_set_text(labelB, "Big Font");
lv_obj_set_pos(labelB, 40, 260);
lv_obj_set_style_local_text_font(labelB, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, &lv_font_montserrat_36);

uint16_t counter = 0;

modm::ShortPeriodicTimer tmr{10ms};

while (true)
{
lv_task_handler();

if (tmr.execute())
{
lv_label_set_text_fmt(labelA, "counter=%d", ++counter);
}
}

return 0;
}
16 changes: 16 additions & 0 deletions examples/nucleo_l452re/lvgl/project.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<library>
<extends>modm:nucleo-l452re</extends>
<options>
<option name="modm:build:build.path">../../../build/nucleo_l452re/lvgl</option>
</options>
<modules>
<module>modm:build:scons</module>
<module>modm:processing:timer</module>
<module>modm:driver:ili9341</module>
<module>modm:driver:touch2046</module>
<module>modm:platform:spi:1</module>
<module>modm:platform:spi:2</module>
<module>modm:platform:dma</module>
<module>modm:lvgl</module>
</modules>
</library>

0 comments on commit e0d1327

Please sign in to comment.