Skip to content

Commit c97be94

Browse files
authored
Merge pull request #3 from georgik/feature/update-lvgl-9
Update to LVGL 9 and conversion of images using CMake
2 parents 2f80d30 + fe68462 commit c97be94

23 files changed

+596
-471
lines changed

README.md

Lines changed: 24 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,17 +7,33 @@ The default configuration for ESP32-S3-BOX-3.
77
For M5Stack-CoreS3 - uncomment BSP in `idf_component.yml`
88

99

10+
## Quick start
11+
12+
```shell
13+
idf.py build flash
14+
pushd apps/tic_tac_toe
15+
idf.py build
16+
esptool.py --chip esp32s3 --baud 921600 --before default_reset --after hard_reset write_flash 0x220000 build/tic_tac_toe.bin
17+
popd
18+
pushd apps/wifi_list
19+
esptool.py --chip esp32s3 --baud 921600 --before default_reset --after hard_reset write_flash 0x4E0000 build/wifi_list.bin
20+
popd
21+
pushd apps/calculator
22+
esptool.py --chip esp32s3 --baud 921600 --before default_reset --after hard_reset write_flash 0x7A0000 build/calculator.bin
23+
popd
24+
```
25+
1026
## Build
1127

1228
Initial build and flash of the application and partition table.
1329

14-
```
30+
```shell
1531
idf.py build flash monitor
1632
```
1733

1834
After the initial flash, it's possible to use following command, just to update the factory application:
1935

20-
```
36+
```shell
2137
idf.py app-flash monitor
2238
```
2339

@@ -26,7 +42,7 @@ idf.py app-flash monitor
2642
Applications are stored in ota_0 - ota_4.
2743

2844
Build application (e.g. hello_world):
29-
```
45+
```shell
3046
idf.py build
3147
```
3248

@@ -53,7 +69,7 @@ The bootloader is using OTA mechanism. It's necessary to add following code to t
5369
in order to reboot to bootloader.
5470

5571
Put the following code to main, before starting the rest of the application:
56-
```
72+
```c
5773
#include "esp_ota_ops.h"
5874

5975
const esp_partition_t* factory_partition = esp_partition_find_first(ESP_PARTITION_TYPE_APP, ESP_PARTITION_SUBTYPE_APP_FACTORY, NULL);
@@ -64,7 +80,9 @@ if (factory_partition != NULL) {
6480

6581
Here's more elaborate version which can be put somwhere into application, like reaction on back button:
6682

67-
```
83+
```c
84+
#include "esp_ota_ops.h"
85+
6886
// Get the partition structure for the factory partition
6987
const esp_partition_t *factory_partition = esp_partition_find_first(ESP_PARTITION_TYPE_APP, ESP_PARTITION_SUBTYPE_APP_FACTORY, NULL);
7088
if (factory_partition != NULL) {
@@ -87,6 +105,6 @@ If the project is using explicit list of components, you need to add `app_update
87105
idf_component_register(
88106
SRCS "main.cpp"
89107
INCLUDE_DIRS "."
90-
REQUIRES esp-box-3 app_update
108+
REQUIRES app_update
91109
)
92110
```

apps/calculator/CMakeLists.txt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
# The following five lines of boilerplate have to be in your project's
2+
# CMakeLists in this exact order for cmake to work correctly
3+
cmake_minimum_required(VERSION 3.16)
4+
5+
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
6+
project(calculator)
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
idf_component_register(SRCS "calculator.c"
2+
INCLUDE_DIRS "."
3+
REQUIRES app_update)

apps/calculator/main/calculator.c

Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
1+
#include "freertos/FreeRTOS.h"
2+
#include "freertos/task.h"
3+
#include "esp_system.h"
4+
#include "esp_log.h"
5+
#include "lvgl.h"
6+
#include "bsp/esp-bsp.h"
7+
#include "esp_timer.h"
8+
#include "esp_ota_ops.h"
9+
10+
#define TAG "Calculator"
11+
12+
static lv_obj_t *display_label;
13+
static char current_input[64] = "";
14+
static double stored_value = 0;
15+
static char current_operator = 0;
16+
static bool clear_next = false;
17+
static int64_t last_press_time = 0;
18+
19+
static void update_display() {
20+
bsp_display_lock(0);
21+
lv_label_set_text(display_label, current_input);
22+
bsp_display_unlock();
23+
}
24+
25+
static void clear_input() {
26+
current_input[0] = '\0';
27+
update_display();
28+
}
29+
30+
static void append_input(const char *text) {
31+
if (clear_next) {
32+
clear_input();
33+
clear_next = false;
34+
}
35+
if (strlen(current_input) < sizeof(current_input) - 1) {
36+
strcat(current_input, text);
37+
}
38+
update_display();
39+
}
40+
41+
static void handle_operator(char operator) {
42+
if (current_operator != 0 && !clear_next) {
43+
double current_value = atof(current_input);
44+
switch (current_operator) {
45+
case '+': stored_value += current_value; break;
46+
case '-': stored_value -= current_value; break;
47+
case '*': stored_value *= current_value; break;
48+
case '/': if (current_value != 0) stored_value /= current_value; break;
49+
}
50+
snprintf(current_input, sizeof(current_input), "%g", stored_value);
51+
update_display();
52+
} else {
53+
stored_value = atof(current_input);
54+
}
55+
current_operator = operator;
56+
clear_next = true;
57+
}
58+
59+
static void btn_event_cb(lv_event_t *e) {
60+
int64_t now = esp_timer_get_time();
61+
if (now - last_press_time < 500000) { // 500 ms debounce time
62+
return;
63+
}
64+
last_press_time = now;
65+
66+
lv_obj_t *btn = lv_event_get_target(e);
67+
const char *txt = lv_btnmatrix_get_btn_text(btn, lv_btnmatrix_get_selected_btn(btn));
68+
69+
if (strcmp(txt, "C") == 0) {
70+
clear_input();
71+
stored_value = 0;
72+
current_operator = 0;
73+
} else if (strcmp(txt, "=") == 0) {
74+
handle_operator(0);
75+
current_operator = 0;
76+
clear_next = true;
77+
} else if (strchr("+-*/", txt[0]) != NULL) {
78+
handle_operator(txt[0]);
79+
} else {
80+
append_input(txt);
81+
}
82+
}
83+
84+
void reset_to_factory_app() {
85+
// Get the partition structure for the factory partition
86+
const esp_partition_t *factory_partition = esp_partition_find_first(ESP_PARTITION_TYPE_APP, ESP_PARTITION_SUBTYPE_APP_FACTORY, NULL);
87+
if (factory_partition != NULL) {
88+
if (esp_ota_set_boot_partition(factory_partition) == ESP_OK) {
89+
printf("Set boot partition to factory, restarting now.\n");
90+
} else {
91+
printf("Failed to set boot partition to factory.\n");
92+
}
93+
} else {
94+
printf("Factory partition not found.\n");
95+
}
96+
97+
fflush(stdout);
98+
}
99+
100+
void app_main(void) {
101+
// Reset to factory app for the next boot.
102+
// It should return to graphical bootloader.
103+
reset_to_factory_app();
104+
105+
// Initialize the BSP
106+
bsp_i2c_init();
107+
bsp_display_start();
108+
lv_init();
109+
110+
// Create a label for the display
111+
display_label = lv_label_create(lv_scr_act());
112+
lv_obj_set_size(display_label, 300, 30);
113+
lv_obj_align(display_label, LV_ALIGN_TOP_MID, 0, 10);
114+
lv_label_set_text(display_label, "0");
115+
116+
// Create a button matrix for the calculator
117+
static const char *btn_map[] = {
118+
"7", "8", "9", "C", "\n",
119+
"4", "5", "6", "*", "\n",
120+
"1", "2", "3", "-", "\n",
121+
"0", ".", "/", "+", "\n",
122+
"=", ""
123+
};
124+
125+
lv_obj_t *btnm = lv_btnmatrix_create(lv_scr_act());
126+
lv_btnmatrix_set_map(btnm, btn_map);
127+
lv_obj_set_size(btnm, 320, 180);
128+
lv_obj_align(btnm, LV_ALIGN_CENTER, 0, 30);
129+
lv_obj_add_event_cb(btnm, btn_event_cb, LV_EVENT_VALUE_CHANGED, NULL);
130+
131+
bsp_display_backlight_on();
132+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
## IDF Component Manager Manifest File
2+
dependencies:
3+
espressif/esp-box: "^3.1.0"
4+
#espressif/esp-box-3: "^1.2.0"
5+
# Workaround for i2c: CONFLICT! driver_ng is not allowed to be used with this old driver
6+
esp_codec_dev:
7+
public: true
8+
version: "==1.1.0"
9+
## Required IDF version
10+
idf:
11+
version: ">=5.0.0"

apps/tic_tac_toe/CMakeLists.txt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
# The following five lines of boilerplate have to be in your project's
2+
# CMakeLists in this exact order for cmake to work correctly
3+
cmake_minimum_required(VERSION 3.16)
4+
5+
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
6+
project(tic_tac_toe)
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
idf_component_register(SRCS "tic_tac_toe.c"
2+
INCLUDE_DIRS "."
3+
REQUIRES app_update)
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
## IDF Component Manager Manifest File
2+
dependencies:
3+
espressif/esp-box: "^3.1.0"
4+
#espressif/esp-box-3: "^1.2.0"
5+
# Workaround for i2c: CONFLICT! driver_ng is not allowed to be used with this old driver
6+
esp_codec_dev:
7+
public: true
8+
version: "==1.1.0"
9+
## Required IDF version
10+
idf:
11+
version: ">=5.0.0"

0 commit comments

Comments
 (0)