Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/l476rg lvgl example #1240

Merged
merged 5 commits into from
Dec 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 1 addition & 6 deletions .github/workflows/macos.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,15 +25,10 @@ jobs:
brew link --force avr-gcc@13 arm-gcc-bin@13
# brew upgrade boost gcc git || true

- uses: actions/setup-python@v5
with:
python-version: '3.12'

- name: Setup environment - Python pip
run: |
pip3 install --user modm scons
pip3 install --upgrade --upgrade-strategy=eager --break-system-packages modm scons
echo "/usr/local/bin" >> $GITHUB_PATH
echo "/Users/runner/Library/Python/3.12/bin" >> $GITHUB_PATH

- name: Dump environment
run: |
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/windows.yml
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ jobs:
shell: bash
run: |
(cd examples && python ../tools/scripts/examples_compile.py nucleo_f031k6 nucleo_f103rb nucleo_f303re nucleo_f411re nucleo_f746zg)
(cd examples && python ../tools/scripts/examples_compile.py nucleo_g071rb nucleo_l031k6 nucleo_l152re nucleo_l476rg nucleo_g474re)
(cd examples && python ../tools/scripts/examples_compile.py nucleo_g071rb nucleo_l031k6 nucleo_l152re nucleo_l432kc nucleo_g474re)

- name: Compile AVR Examples
if: always()
Expand Down
39 changes: 39 additions & 0 deletions examples/nucleo_l476rg/lvgl/lv_conf_local.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/*
* Copyright (c) 2024, Frank Altheim
*
* 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

// Fonts:
#define LV_FONT_MONTSERRAT_36 1
#define LV_FONT_MONTSERRAT_24 1
#define LV_FONT_MONTSERRAT_16 1

// Disable anti-aliasing
#define LV_ANTIALIAS 0
164 changes: 164 additions & 0 deletions examples/nucleo_l476rg/lvgl/main.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,164 @@
/*
* Copyright (c) 2024, Frank Altheim
*
* 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>

// USER INCLUDES
#include "test_screen.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 = Board::D10;
using Sck = Board::D13;
using Miso = Board::D12;
using Mosi = Board::D11;
using DataCommands = Board::D9;
using Reset = Board::D8;
using Backlight = modm::platform::GpioC9;
}

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

namespace touch
{
using Spi = SpiMaster3;
using Cs = modm::platform::GpioD2;
using Sck = modm::platform::GpioC10;
using Miso = modm::platform::GpioC11;
using Mosi = modm::platform::GpioC12;
using Interrupt = modm::platform::GpioC9;
}

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

// Define display buffer 1
static constexpr size_t buf_size = 240 * 320 / 8;
static lv_color_t modm_aligned(4) buf[buf_size];

// Define display buffer 2
static constexpr size_t buf2_size = 240 * 320 / 8;
static lv_color_t modm_aligned(4) buf2[buf2_size];

void my_touchpad_read(lv_indev_t*, lv_indev_data_t* data)
{
data->state = touchController.isTouched() ? LV_INDEV_STATE_PRESSED : LV_INDEV_STATE_RELEASED;
if(data->state == LV_INDEV_STATE_PRESSED) {
std::tuple xy = touchController.getTouchPosition();
data->point.x = std::get<0>(xy);
data->point.y = std::get<1>(xy);

std::tuple xyRAW = touchController.getRawValues();
int16_t rawX = std::get<0>(xyRAW);
int16_t rawY = std::get<1>(xyRAW);
// Display on test screen
setTouchText(data->point.x, data->point.y, rawX, rawY);

}
}

void disp_flush(lv_display_t* disp, const lv_area_t* area, uint8_t* px_map)
{
tftController.drawRaw(
{uint16_t(area->x1), uint16_t(area->y1)},
(area->x2 - area->x1 +1),
(area->y2 - area->y1 + 1),
(modm::color::Rgb565*)px_map);
lv_display_flush_ready(disp);
}

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

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

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

MODM_LOG_INFO << "reflow-display on nucleo-l476rg!\n\n";

lv_display_t *disp = lv_display_create(240, 320);
lv_display_set_flush_cb(disp, disp_flush);
lv_display_set_buffers(disp, buf, buf2, sizeof(buf), LV_DISPLAY_RENDER_MODE_PARTIAL);

// Initialize touchscreen driver:
lv_indev_t* indev = lv_indev_create();
// Assert touchscreen driver was created successfully:
if (indev == NULL) {
MODM_LOG_ERROR << "Failed to create input device\n";
while (1) {}
}

lv_indev_set_type(indev, LV_INDEV_TYPE_POINTER);
lv_indev_set_read_cb(indev, my_touchpad_read);

drawTestScreen();

modm::ShortPeriodicTimer tmr{20ms};

while (true)
{
lv_timer_handler();

if (tmr.execute())
{
setLblText();
}
}

return 0;
}
16 changes: 16 additions & 0 deletions examples/nucleo_l476rg/lvgl/project.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<library>
<extends>modm:nucleo-l476rg</extends>
<options>
<option name="modm:build:build.path">../../../build/nucleo_l476rg/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:3</module>
<module>modm:platform:dma</module>
<module>modm:lvgl</module>
</modules>
</library>
78 changes: 78 additions & 0 deletions examples/nucleo_l476rg/lvgl/test_screen.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
/*
* Copyright (c) 2024, Frank Altheim
*
* 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 "test_screen.h"
#include <lvgl/lvgl.h>

static lv_obj_t* screen;
static uint16_t counter = 0;
static lv_obj_t* labelA;
static lv_obj_t* labelTouch;
static lv_obj_t* labelRawTouch;

void btn_event_cb(lv_event_t *event)
{
static uint16_t btnCounter = 0;
lv_label_set_text_fmt((lv_obj_t*) lv_event_get_user_data(event),
"Button: %d", ++btnCounter);
}

void drawTestScreen(void)
{
screen = lv_obj_create(NULL);

labelA = lv_label_create(screen);
lv_label_set_text(labelA, "Hello world!");
lv_obj_set_pos(labelA, 60, 10);
lv_obj_set_size(labelA, 120, 50);

labelTouch = lv_label_create(screen);
lv_label_set_text_fmt(labelTouch, "Pos Touch: x = %d, y = %d", 0, 0);
lv_obj_set_pos(labelTouch, 60, 30);
lv_obj_set_size(labelTouch, 120, 50);

labelRawTouch = lv_label_create(screen);
lv_label_set_text_fmt(labelRawTouch, "Raw Touch: x = %d, y = %d", 0, 0);
lv_obj_set_pos(labelRawTouch, 60, 80);
lv_obj_set_size(labelRawTouch, 120, 50);

lv_obj_t* btn = lv_button_create(screen);
lv_obj_set_pos(btn, 60, 135);
lv_obj_set_size(btn, 120, 50);

lv_obj_t* btnLabel = lv_label_create(btn);
lv_label_set_text(btnLabel, "Button");

static lv_style_t style_btn_pressed;
lv_style_init(&style_btn_pressed);
lv_style_set_bg_color(&style_btn_pressed, lv_palette_main(LV_PALETTE_ORANGE));

lv_obj_add_style(btn, &style_btn_pressed, LV_STATE_PRESSED);
lv_obj_add_event_cb(btn, btn_event_cb, LV_EVENT_PRESSED, btnLabel);
lv_obj_t* labelB = lv_label_create(screen);
lv_label_set_text(labelB, "Big Font");
lv_obj_set_pos(labelB, 40, 260);
lv_obj_set_style_text_font(labelB, &lv_font_montserrat_36, LV_PART_MAIN);

// Load screen
lv_scr_load(screen);
}

void setLblText(void)
{
lv_label_set_text_fmt(labelA, "counter=%d", ++counter);
}

void setTouchText(int16_t x, int16_t y, int16_t rawX, int16_t rawY)
{
lv_label_set_text_fmt(labelTouch, "Pos Touch: x = %d, y = %d", x, y);
lv_label_set_text_fmt(labelRawTouch, "Raw Touch: x = %d, y = %d", rawX, rawY);
}
24 changes: 24 additions & 0 deletions examples/nucleo_l476rg/lvgl/test_screen.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
/*
* Copyright (c) 2024, Frank Altheim
*
* 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 TEST_SCREEN_H
#define TEST_SCREEN_H

#pragma once

#include <cstdint>

void drawTestScreen(void);
void setLblText(void);
void setTouchText(int16_t x, int16_t y, int16_t rawX, int16_t rawY);


#endif //TEST_SCREEN_H
6 changes: 2 additions & 4 deletions src/modm/platform/uart/hosted/module.lb
Original file line number Diff line number Diff line change
Expand Up @@ -34,11 +34,9 @@ def build(env):
# FIXME: boost/type_traits/detail/config.hpp:85:69: warning: "__clang_major___WORKAROUND_GUARD" is not defined, evaluates to 0
env.collect(":build:cppdefines.release", "__clang_major___WORKAROUND_GUARD=4")

env.collect(":build:library", "boost_system")
env.collect(":build:library", "boost_system", "boost_thread")
if env[":target"].identifier.family == "linux":
env.collect(":build:library", "boost_thread", "pthread")
else:
env.collect(":build:library", "boost_thread-mt")
env.collect(":build:library", "pthread")

env.outbasepath = "modm/src/modm/platform/uart"
env.copy(".")
Loading
Loading