Skip to content

Commit 9c06e6c

Browse files
frnktanksalkinium
authored andcommitted
[example] Add LGVL example on NUCLEO-L476RG
1 parent 4ad8f5d commit 9c06e6c

File tree

5 files changed

+321
-0
lines changed

5 files changed

+321
-0
lines changed
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
/*
2+
* Copyright (c) 2024, Frank Altheim
3+
*
4+
* This file is part of the modm project.
5+
*
6+
* This Source Code Form is subject to the terms of the Mozilla Public
7+
* License, v. 2.0. If a copy of the MPL was not distributed with this
8+
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
9+
*/
10+
// ----------------------------------------------------------------------------
11+
12+
#ifndef LV_CONF_H
13+
# error "Don't include this file directly, use 'lv_conf.h' instead!"
14+
#endif
15+
16+
// Maximal resolutions
17+
#define LV_HOR_RES_MAX 240
18+
#define LV_VER_RES_MAX 320
19+
#define LV_DPI 200
20+
21+
/* Color depth:
22+
* - 1: 1 byte per pixel
23+
* - 8: RGB332
24+
* - 16: RGB565
25+
* - 32: ARGB8888
26+
*/
27+
#define LV_COLOR_DEPTH 16
28+
29+
// Enable logging at INFO level
30+
#define LV_USE_LOG 1
31+
#define LV_LOG_LEVEL LV_LOG_LEVEL_INFO
32+
33+
// Fonts:
34+
#define LV_FONT_MONTSERRAT_36 1
35+
#define LV_FONT_MONTSERRAT_24 1
36+
#define LV_FONT_MONTSERRAT_16 1
37+
38+
// Disable anti-aliasing
39+
#define LV_ANTIALIAS 0
Lines changed: 164 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,164 @@
1+
/*
2+
* Copyright (c) 2024, Frank Altheim
3+
*
4+
* This file is part of the modm project.
5+
*
6+
* This Source Code Form is subject to the terms of the Mozilla Public
7+
* License, v. 2.0. If a copy of the MPL was not distributed with this
8+
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
9+
*/
10+
// ----------------------------------------------------------------------------
11+
12+
#include <modm/board.hpp>
13+
#include <modm/debug.hpp>
14+
#include <modm/processing.hpp>
15+
#include <modm/driver/display/ili9341_spi.hpp>
16+
#include <modm/driver/touch/touch2046.hpp>
17+
18+
#include <lvgl/lvgl.h>
19+
20+
// USER INCLUDES
21+
#include "test_screen.h"
22+
23+
24+
// Set the log level
25+
#undef MODM_LOG_LEVEL
26+
#define MODM_LOG_LEVEL modm::log::DEBUG
27+
28+
using namespace Board;
29+
using namespace modm::literals;
30+
31+
32+
namespace tft
33+
{
34+
using DmaRx = Dma1::Channel2;
35+
using DmaTx = Dma1::Channel3;
36+
using Spi = SpiMaster1_Dma<DmaRx, DmaTx>;
37+
//using Spi = SpiMaster1;
38+
using Cs = Board::D10;
39+
using Sck = Board::D13;
40+
using Miso = Board::D12;
41+
using Mosi = Board::D11;
42+
using DataCommands = Board::D9;
43+
using Reset = Board::D8;
44+
using Backlight = modm::platform::GpioC9;
45+
}
46+
47+
modm::Ili9341Spi<
48+
tft::Spi,
49+
tft::Cs,
50+
tft::DataCommands,
51+
tft::Reset,
52+
tft::Backlight
53+
> tftController;
54+
55+
namespace touch
56+
{
57+
using Spi = SpiMaster3;
58+
using Cs = modm::platform::GpioD2;
59+
using Sck = modm::platform::GpioC10;
60+
using Miso = modm::platform::GpioC11;
61+
using Mosi = modm::platform::GpioC12;
62+
using Interrupt = modm::platform::GpioC9;
63+
}
64+
65+
modm::Touch2046<touch::Spi, touch::Cs> touchController;
66+
67+
// Define display buffer 1
68+
static constexpr size_t buf_size = 240 * 320 / 8;
69+
static lv_color_t modm_aligned(4) buf[buf_size];
70+
71+
// Define display buffer 2
72+
static constexpr size_t buf2_size = 240 * 320 / 8;
73+
static lv_color_t modm_aligned(4) buf2[buf2_size];
74+
75+
void my_touchpad_read(lv_indev_t*, lv_indev_data_t* data)
76+
{
77+
data->state = touchController.isTouched() ? LV_INDEV_STATE_PRESSED : LV_INDEV_STATE_RELEASED;
78+
if(data->state == LV_INDEV_STATE_PRESSED) {
79+
std::tuple xy = touchController.getTouchPosition();
80+
data->point.x = std::get<0>(xy);
81+
data->point.y = std::get<1>(xy);
82+
83+
std::tuple xyRAW = touchController.getRawValues();
84+
int16_t rawX = std::get<0>(xyRAW);
85+
int16_t rawY = std::get<1>(xyRAW);
86+
// Display on test screen
87+
setTouchText(data->point.x, data->point.y, rawX, rawY);
88+
89+
}
90+
}
91+
92+
void disp_flush(lv_display_t* disp, const lv_area_t* area, uint8_t* px_map)
93+
{
94+
tftController.drawRaw(
95+
{uint16_t(area->x1), uint16_t(area->y1)},
96+
(area->x2 - area->x1 +1),
97+
(area->y2 - area->y1 + 1),
98+
(modm::color::Rgb565*)px_map);
99+
lv_display_flush_ready(disp);
100+
}
101+
102+
int
103+
main()
104+
{
105+
Board::initialize();
106+
Dma1::enable();
107+
108+
tft::Spi::connect<
109+
tft::Sck::Sck,
110+
tft::Miso::Miso,
111+
tft::Mosi::Mosi>();
112+
tft::Spi::initialize<Board::SystemClock, 24_MHz>();
113+
tftController.initialize();
114+
tftController.enableBacklight(true);
115+
116+
touch::Spi::connect<
117+
touch::Sck::Sck,
118+
touch::Miso::Miso,
119+
touch::Mosi::Mosi>();
120+
touch::Spi::initialize<Board::SystemClock, 1.5_MHz>();
121+
modm::touch2046::Calibration cal{
122+
.OffsetX = -11,
123+
.OffsetY = 335,
124+
.FactorX = 22018,
125+
.FactorY = -29358,
126+
.MaxX = 240,
127+
.MaxY = 320,
128+
.ThresholdZ = 100,
129+
};
130+
touchController.setCalibration(cal);
131+
132+
MODM_LOG_INFO << "reflow-display on nucleo-l476rg!\n\n";
133+
134+
lv_display_t *disp = lv_display_create(240, 320);
135+
lv_display_set_flush_cb(disp, disp_flush);
136+
lv_display_set_buffers(disp, buf, buf2, sizeof(buf), LV_DISPLAY_RENDER_MODE_PARTIAL);
137+
138+
// Initialize touchscreen driver:
139+
lv_indev_t* indev = lv_indev_create();
140+
// Assert touchscreen driver was created successfully:
141+
if (indev == NULL) {
142+
MODM_LOG_ERROR << "Failed to create input device\n";
143+
while (1) {}
144+
}
145+
146+
lv_indev_set_type(indev, LV_INDEV_TYPE_POINTER);
147+
lv_indev_set_read_cb(indev, my_touchpad_read);
148+
149+
drawTestScreen();
150+
151+
modm::ShortPeriodicTimer tmr{20ms};
152+
153+
while (true)
154+
{
155+
lv_timer_handler();
156+
157+
if (tmr.execute())
158+
{
159+
setLblText();
160+
}
161+
}
162+
163+
return 0;
164+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
<library>
2+
<extends>modm:nucleo-l476rg</extends>
3+
<options>
4+
<option name="modm:build:build.path">../../../build/nucleo_l476rg/lvgl</option>
5+
</options>
6+
<modules>
7+
<module>modm:build:scons</module>
8+
<module>modm:processing:timer</module>
9+
<module>modm:driver:ili9341</module>
10+
<module>modm:driver:touch2046</module>
11+
<module>modm:platform:spi:1</module>
12+
<module>modm:platform:spi:3</module>
13+
<module>modm:platform:dma</module>
14+
<module>modm:lvgl</module>
15+
</modules>
16+
</library>
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
/*
2+
* Copyright (c) 2024, Frank Altheim
3+
*
4+
* This file is part of the modm project.
5+
*
6+
* This Source Code Form is subject to the terms of the Mozilla Public
7+
* License, v. 2.0. If a copy of the MPL was not distributed with this
8+
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
9+
*/
10+
// ----------------------------------------------------------------------------
11+
12+
#include "test_screen.h"
13+
#include <lvgl/lvgl.h>
14+
15+
static lv_obj_t* screen;
16+
static uint16_t counter = 0;
17+
static lv_obj_t* labelA;
18+
static lv_obj_t* labelTouch;
19+
static lv_obj_t* labelRawTouch;
20+
21+
void btn_event_cb(lv_event_t *event)
22+
{
23+
static uint16_t btnCounter = 0;
24+
lv_label_set_text_fmt((lv_obj_t*) lv_event_get_user_data(event),
25+
"Button: %d", ++btnCounter);
26+
}
27+
28+
void drawTestScreen(void)
29+
{
30+
screen = lv_obj_create(NULL);
31+
32+
labelA = lv_label_create(screen);
33+
lv_label_set_text(labelA, "Hello world!");
34+
lv_obj_set_pos(labelA, 60, 10);
35+
lv_obj_set_size(labelA, 120, 50);
36+
37+
labelTouch = lv_label_create(screen);
38+
lv_label_set_text_fmt(labelTouch, "Pos Touch: x = %d, y = %d", 0, 0);
39+
lv_obj_set_pos(labelTouch, 60, 30);
40+
lv_obj_set_size(labelTouch, 120, 50);
41+
42+
labelRawTouch = lv_label_create(screen);
43+
lv_label_set_text_fmt(labelRawTouch, "Raw Touch: x = %d, y = %d", 0, 0);
44+
lv_obj_set_pos(labelRawTouch, 60, 80);
45+
lv_obj_set_size(labelRawTouch, 120, 50);
46+
47+
lv_obj_t* btn = lv_button_create(screen);
48+
lv_obj_set_pos(btn, 60, 135);
49+
lv_obj_set_size(btn, 120, 50);
50+
51+
lv_obj_t* btnLabel = lv_label_create(btn);
52+
lv_label_set_text(btnLabel, "Button");
53+
54+
static lv_style_t style_btn_pressed;
55+
lv_style_init(&style_btn_pressed);
56+
lv_style_set_bg_color(&style_btn_pressed, lv_palette_main(LV_PALETTE_ORANGE));
57+
58+
lv_obj_add_style(btn, &style_btn_pressed, LV_STATE_PRESSED);
59+
lv_obj_add_event_cb(btn, btn_event_cb, LV_EVENT_PRESSED, btnLabel);
60+
lv_obj_t* labelB = lv_label_create(screen);
61+
lv_label_set_text(labelB, "Big Font");
62+
lv_obj_set_pos(labelB, 40, 260);
63+
lv_obj_set_style_text_font(labelB, &lv_font_montserrat_36, LV_PART_MAIN);
64+
65+
// Load screen
66+
lv_scr_load(screen);
67+
}
68+
69+
void setLblText(void)
70+
{
71+
lv_label_set_text_fmt(labelA, "counter=%d", ++counter);
72+
}
73+
74+
void setTouchText(int16_t x, int16_t y, int16_t rawX, int16_t rawY)
75+
{
76+
lv_label_set_text_fmt(labelTouch, "Pos Touch: x = %d, y = %d", x, y);
77+
lv_label_set_text_fmt(labelRawTouch, "Raw Touch: x = %d, y = %d", rawX, rawY);
78+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
/*
2+
* Copyright (c) 2024, Frank Altheim
3+
*
4+
* This file is part of the modm project.
5+
*
6+
* This Source Code Form is subject to the terms of the Mozilla Public
7+
* License, v. 2.0. If a copy of the MPL was not distributed with this
8+
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
9+
*/
10+
// ----------------------------------------------------------------------------
11+
12+
#ifndef TEST_SCREEN_H
13+
#define TEST_SCREEN_H
14+
15+
#pragma once
16+
17+
#include <cstdint>
18+
19+
void drawTestScreen(void);
20+
void setLblText(void);
21+
void setTouchText(int16_t x, int16_t y, int16_t rawX, int16_t rawY);
22+
23+
24+
#endif //TEST_SCREEN_H

0 commit comments

Comments
 (0)