Compare commits
11 Commits
41e589db5e
...
main
Author | SHA1 | Date | |
---|---|---|---|
![]() |
d8baf5370c | ||
![]() |
c2aabfd227 | ||
![]() |
224a354394 | ||
![]() |
f005fcf1c7 | ||
![]() |
936b27116e | ||
![]() |
de8b0d663b | ||
![]() |
77d2aa09ec | ||
![]() |
e1aa89982d | ||
![]() |
75ca356f1c | ||
![]() |
b93cf777a5 | ||
![]() |
4e1502357c |
@@ -1,13 +0,0 @@
|
|||||||
ARG DOCKER_TAG=latest
|
|
||||||
FROM espressif/idf:${DOCKER_TAG}
|
|
||||||
|
|
||||||
ENV LC_ALL=C.UTF-8
|
|
||||||
ENV LANG=C.UTF-8
|
|
||||||
|
|
||||||
RUN apt-get update -y && apt-get install udev -y
|
|
||||||
|
|
||||||
RUN echo "source /opt/esp/idf/export.sh > /dev/null 2>&1" >> ~/.bashrc
|
|
||||||
|
|
||||||
ENTRYPOINT [ "/opt/esp/entrypoint.sh" ]
|
|
||||||
|
|
||||||
CMD ["/bin/bash", "-c"]
|
|
@@ -1,21 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "ESP-IDF QEMU",
|
|
||||||
"build": {
|
|
||||||
"dockerfile": "Dockerfile"
|
|
||||||
},
|
|
||||||
"customizations": {
|
|
||||||
"vscode": {
|
|
||||||
"settings": {
|
|
||||||
"terminal.integrated.defaultProfile.linux": "bash",
|
|
||||||
"idf.espIdfPath": "/opt/esp/idf",
|
|
||||||
"idf.toolsPath": "/opt/esp",
|
|
||||||
"idf.gitPath": "/usr/bin/git"
|
|
||||||
},
|
|
||||||
"extensions": [
|
|
||||||
"espressif.esp-idf-extension",
|
|
||||||
"espressif.esp-idf-web"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"runArgs": ["--privileged"]
|
|
||||||
}
|
|
12
.gitignore
vendored
12
.gitignore
vendored
@@ -1,3 +1,9 @@
|
|||||||
build/
|
*
|
||||||
sdkconfig
|
!*/
|
||||||
sdkconfig.old
|
!components/**
|
||||||
|
!main/**
|
||||||
|
!.gitignore
|
||||||
|
!.gitmodules
|
||||||
|
!CMakeLists.txt
|
||||||
|
!dependencies.lock
|
||||||
|
!README.md
|
||||||
|
23
.vscode/c_cpp_properties.json
vendored
23
.vscode/c_cpp_properties.json
vendored
@@ -1,23 +0,0 @@
|
|||||||
{
|
|
||||||
"configurations": [
|
|
||||||
{
|
|
||||||
"name": "ESP-IDF",
|
|
||||||
"compilerPath": "${config:idf.toolsPath}/tools/xtensa-esp-elf/esp-14.2.0_20241119/xtensa-esp-elf/bin/xtensa-esp32-elf-gcc",
|
|
||||||
"compileCommands": "${config:idf.buildPath}/compile_commands.json",
|
|
||||||
"includePath": [
|
|
||||||
"${config:idf.espIdfPath}/components/**",
|
|
||||||
"${config:idf.espIdfPathWin}/components/**",
|
|
||||||
"${workspaceFolder}/**"
|
|
||||||
],
|
|
||||||
"browse": {
|
|
||||||
"path": [
|
|
||||||
"${config:idf.espIdfPath}/components",
|
|
||||||
"${config:idf.espIdfPathWin}/components",
|
|
||||||
"${workspaceFolder}"
|
|
||||||
],
|
|
||||||
"limitSymbolsToIncludedHeaders": true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"version": 4
|
|
||||||
}
|
|
15
.vscode/launch.json
vendored
15
.vscode/launch.json
vendored
@@ -1,15 +0,0 @@
|
|||||||
{
|
|
||||||
"version": "0.2.0",
|
|
||||||
"configurations": [
|
|
||||||
{
|
|
||||||
"type": "gdbtarget",
|
|
||||||
"request": "attach",
|
|
||||||
"name": "Eclipse CDT GDB Adapter"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "espidf",
|
|
||||||
"name": "Launch",
|
|
||||||
"request": "launch"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
14
.vscode/settings.json
vendored
14
.vscode/settings.json
vendored
@@ -1,14 +0,0 @@
|
|||||||
{
|
|
||||||
"C_Cpp.intelliSenseEngine": "default",
|
|
||||||
"idf.espIdfPath": "/home/sirian/esp/esp-idf",
|
|
||||||
"idf.pythonInstallPath": "/usr/bin/python3",
|
|
||||||
"idf.openOcdConfigs": [
|
|
||||||
"board/esp32-wrover-kit-3.3v.cfg"
|
|
||||||
],
|
|
||||||
"idf.port": "/dev/ttyS1",
|
|
||||||
"idf.toolsPath": "/home/sirian/.espressif",
|
|
||||||
"idf.customExtraVars": {
|
|
||||||
"IDF_TARGET": "esp32"
|
|
||||||
},
|
|
||||||
"idf.flashType": "UART"
|
|
||||||
}
|
|
35
README.md
35
README.md
@@ -1,32 +1,11 @@
|
|||||||
# _Sample project_
|
# OLED display counter
|
||||||
|
|
||||||
(See the README.md file in the upper level 'examples' directory for more information about examples.)
|
A simple counter on an oled display.
|
||||||
|
|
||||||
This is the simplest buildable example. The example is used by command `idf.py create-project`
|
## References
|
||||||
that copies the project to user specified path and set it's name. For more information follow the [docs page](https://docs.espressif.com/projects/esp-idf/en/latest/api-guides/build-system.html#start-a-new-project)
|
|
||||||
|
|
||||||
|
- [Esp32 programming guide](https://docs.espressif.com/projects/esp-idf/en/stable/esp32/get-started/index.html)
|
||||||
|
- [Esp32 datasheet](https://www.espressif.com/sites/default/files/documentation/esp32-wroom-32d_esp32-wroom-32u_datasheet_en.pdf)
|
||||||
|
- [SSD1306 datasheet](https://cdn-shop.adafruit.com/datasheets/SSD1306.pdf)
|
||||||
|
- [lvgl programming guide](https://docs.lvgl.io/master/intro/introduction/index.html)
|
||||||
|
|
||||||
|
|
||||||
## How to use example
|
|
||||||
We encourage the users to use the example as a template for the new projects.
|
|
||||||
A recommended way is to follow the instructions on a [docs page](https://docs.espressif.com/projects/esp-idf/en/latest/api-guides/build-system.html#start-a-new-project).
|
|
||||||
|
|
||||||
## Example folder contents
|
|
||||||
|
|
||||||
The project **sample_project** contains one source file in C language [main.c](main/main.c). The file is located in folder [main](main).
|
|
||||||
|
|
||||||
ESP-IDF projects are built using CMake. The project build configuration is contained in `CMakeLists.txt`
|
|
||||||
files that provide set of directives and instructions describing the project's source files and targets
|
|
||||||
(executable, library, or both).
|
|
||||||
|
|
||||||
Below is short explanation of remaining files in the project folder.
|
|
||||||
|
|
||||||
```
|
|
||||||
├── CMakeLists.txt
|
|
||||||
├── main
|
|
||||||
│ ├── CMakeLists.txt
|
|
||||||
│ └── main.c
|
|
||||||
└── README.md This is the file you are currently reading
|
|
||||||
```
|
|
||||||
Additionally, the sample project contains Makefile and component.mk files, used for the legacy Make based build system.
|
|
||||||
They are not used or needed when building with CMake and idf.py.
|
|
||||||
|
@@ -28,8 +28,6 @@
|
|||||||
|
|
||||||
/** Color depth: 1 (I1), 8 (L8), 16 (RGB565), 24 (RGB888), 32 (XRGB8888) */
|
/** Color depth: 1 (I1), 8 (L8), 16 (RGB565), 24 (RGB888), 32 (XRGB8888) */
|
||||||
#define LV_COLOR_DEPTH 1
|
#define LV_COLOR_DEPTH 1
|
||||||
#define LV_COLOR_1_BYTE 1
|
|
||||||
#define LV_USE_THEME_MONO 1
|
|
||||||
|
|
||||||
/*=========================
|
/*=========================
|
||||||
STDLIB WRAPPER SETTINGS
|
STDLIB WRAPPER SETTINGS
|
||||||
@@ -45,7 +43,7 @@
|
|||||||
#define LV_USE_STDLIB_MALLOC LV_STDLIB_BUILTIN
|
#define LV_USE_STDLIB_MALLOC LV_STDLIB_BUILTIN
|
||||||
|
|
||||||
/** Possible values
|
/** Possible values
|
||||||
* - LV_STDLIB_BUILTIN: LVGL's built in implementation
|
* - LV_STDLIB_BUlILTIN: LVGL's built in implementation
|
||||||
* - LV_STDLIB_CLIB: Standard C functions, like malloc, strlen, etc
|
* - LV_STDLIB_CLIB: Standard C functions, like malloc, strlen, etc
|
||||||
* - LV_STDLIB_MICROPYTHON: MicroPython implementation
|
* - LV_STDLIB_MICROPYTHON: MicroPython implementation
|
||||||
* - LV_STDLIB_RTTHREAD: RT-Thread implementation
|
* - LV_STDLIB_RTTHREAD: RT-Thread implementation
|
||||||
@@ -611,7 +609,7 @@
|
|||||||
#define LV_FONT_MONTSERRAT_18 0
|
#define LV_FONT_MONTSERRAT_18 0
|
||||||
#define LV_FONT_MONTSERRAT_20 0
|
#define LV_FONT_MONTSERRAT_20 0
|
||||||
#define LV_FONT_MONTSERRAT_22 0
|
#define LV_FONT_MONTSERRAT_22 0
|
||||||
#define LV_FONT_MONTSERRAT_24 0
|
#define LV_FONT_MONTSERRAT_24 1
|
||||||
#define LV_FONT_MONTSERRAT_26 0
|
#define LV_FONT_MONTSERRAT_26 0
|
||||||
#define LV_FONT_MONTSERRAT_28 0
|
#define LV_FONT_MONTSERRAT_28 0
|
||||||
#define LV_FONT_MONTSERRAT_30 0
|
#define LV_FONT_MONTSERRAT_30 0
|
||||||
@@ -621,7 +619,7 @@
|
|||||||
#define LV_FONT_MONTSERRAT_38 0
|
#define LV_FONT_MONTSERRAT_38 0
|
||||||
#define LV_FONT_MONTSERRAT_40 0
|
#define LV_FONT_MONTSERRAT_40 0
|
||||||
#define LV_FONT_MONTSERRAT_42 0
|
#define LV_FONT_MONTSERRAT_42 0
|
||||||
#define LV_FONT_MONTSERRAT_44 0
|
#define LV_FONT_MONTSERRAT_44 1
|
||||||
#define LV_FONT_MONTSERRAT_46 0
|
#define LV_FONT_MONTSERRAT_46 0
|
||||||
#define LV_FONT_MONTSERRAT_48 0
|
#define LV_FONT_MONTSERRAT_48 0
|
||||||
|
|
||||||
|
313
main/main.c
313
main/main.c
@@ -5,30 +5,31 @@
|
|||||||
#include "freertos/task.h"
|
#include "freertos/task.h"
|
||||||
|
|
||||||
#define LV_CONF_INCLUDE_SIMPLE 1
|
#define LV_CONF_INCLUDE_SIMPLE 1
|
||||||
#include "lv_conf.h"
|
|
||||||
|
|
||||||
|
#include "lv_conf.h"
|
||||||
#include "lvgl.h"
|
#include "lvgl.h"
|
||||||
|
|
||||||
|
#define I2C_SCL 19
|
||||||
|
#define I2C_SDA 21
|
||||||
|
|
||||||
#define I2C_SCL 19
|
#define DISP_ADDRESS 0X3c
|
||||||
#define I2C_SDA 21
|
#define I2C_FREQ 400000
|
||||||
|
|
||||||
/* Docs: https://cdn-shop.adafruit.com/datasheets/SSD1306.pdf */
|
typedef struct {
|
||||||
#define DISP_ADDRESS 0X3c
|
uint8_t page_num;
|
||||||
#define I2C_FREQ 100000
|
uint8_t data[128];
|
||||||
|
} page_data_t;
|
||||||
|
|
||||||
static i2c_master_dev_handle_t disp_handle;
|
static i2c_master_dev_handle_t disp_handle;
|
||||||
|
static lv_obj_t *counter_label;
|
||||||
static lv_obj_t *counter_label;
|
static SemaphoreHandle_t flush_sem = NULL;
|
||||||
|
static QueueHandle_t page_queue = NULL;
|
||||||
static SemaphoreHandle_t flush_sem = NULL;
|
static uint8_t lv_buf[(128 * 64/8)+8];
|
||||||
|
|
||||||
static lv_color_t lv_buf[128 * 64];
|
|
||||||
|
|
||||||
void init_i2c(void){
|
void init_i2c(void){
|
||||||
i2c_master_bus_config_t i2c_mst_config = {
|
i2c_master_bus_config_t i2c_mst_config = {
|
||||||
.clk_source = I2C_CLK_SRC_DEFAULT,
|
.clk_source = I2C_CLK_SRC_DEFAULT,
|
||||||
.i2c_port = I2C_NUM_0,
|
.i2c_port = I2C_NUM_0,
|
||||||
.scl_io_num = I2C_SCL,
|
.scl_io_num = I2C_SCL,
|
||||||
.sda_io_num = I2C_SDA,
|
.sda_io_num = I2C_SDA,
|
||||||
.glitch_ignore_cnt = 7,
|
.glitch_ignore_cnt = 7,
|
||||||
@@ -44,135 +45,139 @@ void init_i2c(void){
|
|||||||
.scl_speed_hz = I2C_FREQ,
|
.scl_speed_hz = I2C_FREQ,
|
||||||
};
|
};
|
||||||
|
|
||||||
ESP_ERROR_CHECK(i2c_master_bus_add_device(bus_handle, &dev_cfg, &disp_handle));
|
i2c_master_bus_add_device(bus_handle, &dev_cfg, &disp_handle);
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void i2c_disp_send_cmd(uint8_t cmd){
|
void disp_send_cmd(uint8_t cmd){
|
||||||
uint8_t data[2] = {0x00, cmd}; /*command mode*/
|
uint8_t data[2] = {0x00, cmd}; /*command mode*/
|
||||||
|
|
||||||
i2c_master_transmit(disp_handle, data, sizeof(data), pdMS_TO_TICKS(1000));
|
i2c_master_transmit(disp_handle, data, sizeof(data), pdMS_TO_TICKS(1000));
|
||||||
|
|
||||||
|
|
||||||
vTaskDelay(pdMS_TO_TICKS(1));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*void i2c_disp_send_data(uint8_t *data, size_t len){
|
void disp_send_data(uint8_t *data, size_t len){
|
||||||
uint8_t *buf = malloc(len + 1);
|
|
||||||
buf[0] = 0x40; data mode
|
|
||||||
memcpy(&buf[1], data, len);
|
|
||||||
ESP_ERROR_CHECK(
|
|
||||||
i2c_master_transmit(disp_handle, buf, len + 1, pdMS_TO_TICKS(100)));
|
|
||||||
free(buf);
|
|
||||||
}*/
|
|
||||||
void i2c_disp_send_data(uint8_t *data, size_t len){
|
|
||||||
|
|
||||||
uint8_t *buf = malloc(len+1);
|
uint8_t *buf = malloc(len+1);
|
||||||
buf[0] = 0x40;
|
buf[0] = 0x40; /*data mode*/
|
||||||
memcpy(&buf[1], data, len);
|
memcpy(&buf[1], data, len);
|
||||||
esp_err_t ret = i2c_master_transmit(disp_handle, buf, len+1, pdMS_TO_TICKS(2000));
|
|
||||||
free(buf);
|
|
||||||
return;
|
|
||||||
|
|
||||||
|
i2c_master_transmit(disp_handle, buf, len+1, pdMS_TO_TICKS(2000));
|
||||||
|
free(buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
void send_page_task(void *arg){
|
||||||
|
page_data_t page;
|
||||||
|
|
||||||
|
while(1){
|
||||||
|
if(xQueueReceive(page_queue, &page, portMAX_DELAY)){
|
||||||
|
disp_send_cmd(0x21);
|
||||||
|
disp_send_cmd(0);
|
||||||
|
disp_send_cmd(127);
|
||||||
|
disp_send_cmd(0x22);
|
||||||
|
disp_send_cmd(page.page_num);
|
||||||
|
disp_send_cmd(page.page_num);
|
||||||
|
disp_send_data(page.data, 128);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void init_display(void){
|
void init_display(void){
|
||||||
|
|
||||||
i2c_disp_send_cmd(0xAE); // Display OFF
|
disp_send_cmd(0xAE); // Display OFF
|
||||||
|
|
||||||
i2c_disp_send_cmd(0xD5); // Set display clock divide ratio/oscillator frequency
|
disp_send_cmd(0xD5); // Set display clock divide ratio/oscillator frequency
|
||||||
i2c_disp_send_cmd(0x80); // Default value
|
disp_send_cmd(0x80); // Default value
|
||||||
|
|
||||||
i2c_disp_send_cmd(0xA8); // Set multiplex ratio
|
disp_send_cmd(0xA8); // Set multiplex ratio
|
||||||
i2c_disp_send_cmd(0x3F); // 1/64 duty (64 COM lines)
|
disp_send_cmd(0x3F); // 1/64 duty (64 COM lines)
|
||||||
|
|
||||||
i2c_disp_send_cmd(0xD3); // Set display offset
|
disp_send_cmd(0xD3); // Set display offset
|
||||||
i2c_disp_send_cmd(0x00); // No offset
|
disp_send_cmd(0x00); // No offset
|
||||||
|
|
||||||
i2c_disp_send_cmd(0x40); // Set display start line to 0
|
disp_send_cmd(0x40); // Set display start line to 0
|
||||||
|
|
||||||
i2c_disp_send_cmd(0x8D); // Charge pump setting
|
disp_send_cmd(0x8D); // Charge pump setting
|
||||||
i2c_disp_send_cmd(0x14); // Enable charge pump
|
disp_send_cmd(0x14); // Enable charge pump
|
||||||
|
|
||||||
i2c_disp_send_cmd(0x20); // Set Memory Addressing Mode
|
disp_send_cmd(0x20); // Set Memory Addressing Mode
|
||||||
i2c_disp_send_cmd(0x00); // Horizontal addressing mode
|
disp_send_cmd(0x00); // Horizontal addressing mode
|
||||||
|
|
||||||
i2c_disp_send_cmd(0xA0); // Set segment re-map (A0h/A1h)
|
disp_send_cmd(0xA1); // Set segment re-map (A0h/A1h)
|
||||||
i2c_disp_send_cmd(0xC0); // Set COM output scan direction
|
disp_send_cmd(0xC8); // Set COM output scan direction
|
||||||
|
|
||||||
i2c_disp_send_cmd(0xDA); // Set COM pins hardware configuration
|
disp_send_cmd(0xDA); // Set COM pins hardware configuration
|
||||||
i2c_disp_send_cmd(0x12); // Alternative COM pin config
|
disp_send_cmd(0x12); // Alternative COM pin config
|
||||||
|
|
||||||
i2c_disp_send_cmd(0x81); // Set contrast control
|
disp_send_cmd(0x81); // Set contrast control
|
||||||
i2c_disp_send_cmd(0xCF); // Max contrast
|
disp_send_cmd(0xCF); // Max contrast
|
||||||
|
|
||||||
i2c_disp_send_cmd(0xD9); // Set pre-charge period
|
disp_send_cmd(0xD9); // Set pre-charge period
|
||||||
i2c_disp_send_cmd(0xF1); // Phase 1: 15 DCLK, Phase 2: 15 DCLK
|
disp_send_cmd(0xF1); // Phase 1: 15 DCLK, Phase 2: 15 DCLK
|
||||||
|
|
||||||
i2c_disp_send_cmd(0xDB); // Set VCOMH deselect level
|
disp_send_cmd(0xDB); // Set VCOMH deselect level
|
||||||
i2c_disp_send_cmd(0x40); // ~0.77 x VCC
|
disp_send_cmd(0x40); // ~0.77 x VCC
|
||||||
|
|
||||||
i2c_disp_send_cmd(0xA4); // Entire display ON (resume to RAM content)
|
disp_send_cmd(0xA4); // Entire display ON (resume to RAM content)
|
||||||
i2c_disp_send_cmd(0xA6); // Set normal display (not inverted)
|
disp_send_cmd(0xA6); // Set normal display (not inverted)
|
||||||
|
|
||||||
i2c_disp_send_cmd(0x2E); // Deactivate scroll
|
disp_send_cmd(0x2E); // Deactivate scroll
|
||||||
|
|
||||||
i2c_disp_send_cmd(0xAF); // Display ON
|
disp_send_cmd(0xAF); // Display ON
|
||||||
}
|
}
|
||||||
|
|
||||||
void lvgl_flush_callback(lv_display_t *disp, const lv_area_t *area, uint8_t *px_map)
|
void lvgl_flush_callback(lv_display_t *disp, const lv_area_t *area, uint8_t *px_map){
|
||||||
{
|
|
||||||
printf("FLUSH CALLED! area: (%ld,%ld)-(%ld,%ld)\n", (long)area->x1, (long)area->y1, (long)area->x2, (long)area->y2);
|
|
||||||
|
|
||||||
if (flush_sem == NULL)
|
if (flush_sem == NULL){
|
||||||
{
|
|
||||||
lv_display_flush_ready(disp);
|
lv_display_flush_ready(disp);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
xSemaphoreTake(flush_sem, portMAX_DELAY);
|
xSemaphoreTake(flush_sem, portMAX_DELAY);
|
||||||
|
|
||||||
|
|
||||||
uint16_t width = 128;
|
uint16_t width = 128;
|
||||||
uint16_t height = 64;
|
uint16_t height = 64;
|
||||||
uint16_t pages = height/8;
|
|
||||||
|
|
||||||
static uint8_t buf[128*8];
|
uint8_t buf[128];
|
||||||
memset(buf, 0, sizeof(buf));
|
memset(buf, 0, sizeof(buf));
|
||||||
|
|
||||||
uint8_t *pixels = px_map;
|
uint16_t bytes = (width * height + 7) / 8;
|
||||||
|
uint16_t bytes_per_row = width / 8;
|
||||||
|
uint16_t bytes_per_page = bytes_per_row*8;
|
||||||
|
uint8_t page = 0;
|
||||||
|
uint8_t page_x = 0;
|
||||||
|
uint8_t page_y = 0;
|
||||||
|
uint8_t byte;
|
||||||
|
|
||||||
printf("Center pixels (64,32): %d %d %d %d\n",
|
px_map += 8;
|
||||||
pixels[32 * 128 + 62], pixels[32 * 128 + 63],
|
|
||||||
pixels[32 * 128 + 64], pixels[32 * 128 + 65]);
|
|
||||||
|
|
||||||
for(uint8_t page = 0; page < pages; page++){
|
/*converted pixels to page format*/
|
||||||
for(uint16_t x = 0; x < width; x++){
|
for (uint16_t i = 0; i <= bytes; i++){
|
||||||
|
byte = px_map[i];
|
||||||
|
|
||||||
uint8_t byte = 0;
|
for (int bit = 7; bit >= 0; bit--){
|
||||||
for(uint8_t bit = 0; bit < 8; bit++){
|
if (byte & (1 << bit)){
|
||||||
uint16_t y = page*8 + bit;
|
buf[page_x] |= (1 << page_y);
|
||||||
if(pixels[y*width+x] != 0){
|
|
||||||
byte |= (1<<bit);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
buf[page*width+x] = byte;
|
++page_x;
|
||||||
|
}
|
||||||
|
if ((i+1) % bytes_per_row == 0 && i+1 != 0){
|
||||||
|
page_y++;
|
||||||
|
page_x = 0;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
if((i+1)% bytes_per_page == 0 && i+1 != 0){
|
||||||
|
/*page finished => send to display*/
|
||||||
|
page_data_t page_data;
|
||||||
|
page_data.page_num = page;
|
||||||
|
memcpy(page_data.data, buf, 128);
|
||||||
|
xQueueSend(page_queue, &page_data, portMAX_DELAY);
|
||||||
|
memset(buf, 0, sizeof(buf));
|
||||||
|
page++;
|
||||||
|
page_y = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
i2c_disp_send_cmd(0x21);
|
|
||||||
i2c_disp_send_cmd(0);
|
|
||||||
i2c_disp_send_cmd(width-1);
|
|
||||||
|
|
||||||
i2c_disp_send_cmd(0x22);
|
|
||||||
i2c_disp_send_cmd(0);
|
|
||||||
i2c_disp_send_cmd(pages-1);
|
|
||||||
|
|
||||||
|
|
||||||
i2c_disp_send_data(buf, sizeof(buf));
|
|
||||||
|
|
||||||
lv_display_flush_ready(disp);
|
lv_display_flush_ready(disp);
|
||||||
xSemaphoreGive(flush_sem);
|
xSemaphoreGive(flush_sem);
|
||||||
}
|
}
|
||||||
@@ -183,17 +188,21 @@ void init_graphics(void){
|
|||||||
xSemaphoreGive(flush_sem);
|
xSemaphoreGive(flush_sem);
|
||||||
}
|
}
|
||||||
|
|
||||||
lv_init();
|
page_queue = xQueueCreate(8, sizeof(page_data_t));
|
||||||
printf("LVGL initialized\n");
|
|
||||||
|
|
||||||
printf("LV_COLOR_DEPTH = %d\n", LV_COLOR_DEPTH);
|
memset(lv_buf, 0, sizeof(lv_buf));
|
||||||
|
|
||||||
|
lv_init();
|
||||||
|
|
||||||
lv_display_t *display = lv_display_create(128, 64);
|
lv_display_t *display = lv_display_create(128, 64);
|
||||||
printf("Display created\n");
|
lv_display_set_color_format(display, LV_COLOR_FORMAT_I1);
|
||||||
lv_display_set_flush_cb(display, lvgl_flush_callback);
|
lv_display_set_flush_cb(display, lvgl_flush_callback);
|
||||||
printf("Flush callback set\n");
|
|
||||||
lv_display_set_buffers(display, lv_buf, NULL, sizeof(lv_buf), LV_DISPLAY_RENDER_MODE_FULL);
|
lv_display_set_buffers(display, lv_buf, NULL, sizeof(lv_buf), LV_DISPLAY_RENDER_MODE_FULL);
|
||||||
printf("lvgl buffers set");
|
|
||||||
|
lv_obj_t *scr = lv_screen_active();
|
||||||
|
|
||||||
|
lv_obj_set_style_bg_color(scr, lv_color_black(), 0);
|
||||||
|
lv_obj_set_style_bg_opa(scr, LV_OPA_COVER, 0);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -207,7 +216,7 @@ void lv_tick_task(void *arg){
|
|||||||
void lv_task(void *arg){
|
void lv_task(void *arg){
|
||||||
while(1){
|
while(1){
|
||||||
lv_task_handler();
|
lv_task_handler();
|
||||||
vTaskDelay(pdMS_TO_TICKS(10));
|
vTaskDelay(pdMS_TO_TICKS(50));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -226,115 +235,45 @@ void counter_task(void *arg){
|
|||||||
counter++;
|
counter++;
|
||||||
}
|
}
|
||||||
|
|
||||||
vTaskDelay(pdMS_TO_TICKS(1000));
|
vTaskDelay(pdMS_TO_TICKS(100));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void create_counter(void){
|
void create_counter(void){
|
||||||
lv_obj_t *scr = lv_scr_act();
|
lv_obj_t *scr = lv_scr_act();
|
||||||
lv_obj_set_style_bg_color(scr, lv_color_black(), 0);
|
|
||||||
lv_obj_set_style_bg_opa(scr, LV_OPA_COVER, 0);
|
|
||||||
|
|
||||||
counter_label = lv_label_create(lv_scr_act());
|
|
||||||
|
counter_label = lv_label_create(scr);
|
||||||
printf("Label created");
|
printf("Label created");
|
||||||
lv_obj_set_style_text_color(counter_label, lv_color_white(), 0);
|
|
||||||
//lv_obj_set_style_text_font(counter_label, &lv_font_montserrat_12, 0);
|
|
||||||
lv_label_set_text(counter_label, "00");
|
lv_label_set_text(counter_label, "00");
|
||||||
|
lv_obj_set_style_text_color(counter_label, lv_color_white(), 0);
|
||||||
|
lv_obj_set_style_text_font(counter_label, &lv_font_montserrat_44, 0);
|
||||||
|
lv_obj_set_style_pad_all(counter_label, 0, 0);
|
||||||
|
lv_obj_set_style_margin_all(counter_label, 0, 0);
|
||||||
|
lv_obj_set_width(counter_label, LV_SIZE_CONTENT);
|
||||||
|
lv_obj_set_style_text_align(counter_label, LV_TEXT_ALIGN_LEFT, 0);
|
||||||
lv_obj_align(counter_label, LV_ALIGN_CENTER, 0, 0);
|
lv_obj_align(counter_label, LV_ALIGN_CENTER, 0, 0);
|
||||||
|
|
||||||
xTaskCreate(counter_task, "counter_task", 2048, NULL, 5, NULL);
|
xTaskCreate(counter_task, "counter_task", 2048, NULL, 1, NULL);
|
||||||
printf("Counter task created");
|
printf("Counter task created");
|
||||||
}
|
}
|
||||||
|
|
||||||
void clear_display(void)
|
|
||||||
{
|
|
||||||
printf("Clearing display...\n");
|
|
||||||
|
|
||||||
i2c_disp_send_cmd(0x21);
|
|
||||||
i2c_disp_send_cmd(0);
|
|
||||||
i2c_disp_send_cmd(127);
|
|
||||||
i2c_disp_send_cmd(0x22);
|
|
||||||
i2c_disp_send_cmd(0);
|
|
||||||
i2c_disp_send_cmd(7);
|
|
||||||
|
|
||||||
uint8_t zeros[128];
|
|
||||||
memset(zeros, 0x00, 128);
|
|
||||||
|
|
||||||
for (int page = 0; page < 8; page++)
|
|
||||||
{
|
|
||||||
i2c_disp_send_data(zeros, 128);
|
|
||||||
}
|
|
||||||
|
|
||||||
printf("Cleared!\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
void draw_text_ok(void)
|
|
||||||
{
|
|
||||||
printf("Drawing 'OK'...\n");
|
|
||||||
|
|
||||||
uint8_t letter_O[8] = {
|
|
||||||
0b00000000, // column 0 (tyhjä)
|
|
||||||
0b01111110, // column 1 (vasen reuna)
|
|
||||||
0b10000001, // column 2
|
|
||||||
0b10000001, // column 3
|
|
||||||
0b10000001, // column 4
|
|
||||||
0b01111110, // column 5 (oikea reuna)
|
|
||||||
0b00000000, // column 6 (tyhjä)
|
|
||||||
0b00000000 // column 7 (väli)
|
|
||||||
};
|
|
||||||
|
|
||||||
// Kirjain K
|
|
||||||
uint8_t letter_K[8] = {
|
|
||||||
0b00000000, // column 0 (tyhjä)
|
|
||||||
0b11111111, // column 1 (pystyviiva)
|
|
||||||
0b00011000, // column 2
|
|
||||||
0b00100100, // column 3
|
|
||||||
0b01000010, // column 4
|
|
||||||
0b10000001, // column 5
|
|
||||||
0b00000000, // column 6 (tyhjä)
|
|
||||||
0b00000000 // column 7
|
|
||||||
};
|
|
||||||
|
|
||||||
// Aseta page 3 (keskellä näyttöä), column 50
|
|
||||||
i2c_disp_send_cmd(0x21);
|
|
||||||
i2c_disp_send_cmd(50);
|
|
||||||
i2c_disp_send_cmd(127);
|
|
||||||
i2c_disp_send_cmd(0x22);
|
|
||||||
i2c_disp_send_cmd(3);
|
|
||||||
i2c_disp_send_cmd(3);
|
|
||||||
|
|
||||||
// Lähetä "OK"
|
|
||||||
i2c_disp_send_data(letter_O, 8);
|
|
||||||
i2c_disp_send_data(letter_K, 8);
|
|
||||||
|
|
||||||
printf("'OK' drawn!\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
void app_main(void){
|
void app_main(void){
|
||||||
init_i2c();
|
init_i2c();
|
||||||
vTaskDelay(pdMS_TO_TICKS(100));
|
vTaskDelay(pdMS_TO_TICKS(50));
|
||||||
init_display();
|
|
||||||
|
|
||||||
|
init_display();
|
||||||
|
vTaskDelay(pdMS_TO_TICKS(50));
|
||||||
|
|
||||||
|
init_graphics();
|
||||||
|
vTaskDelay(pdMS_TO_TICKS(50));
|
||||||
|
|
||||||
|
xTaskCreate(send_page_task, "page_send", 4096, NULL, 2, NULL);
|
||||||
|
xTaskCreate(lv_tick_task, "lv_tick", 4096, NULL, 1, NULL);
|
||||||
|
xTaskCreate(lv_task, "lv_task", 8192, NULL, 3, NULL);
|
||||||
|
|
||||||
vTaskDelay(pdMS_TO_TICKS(200));
|
vTaskDelay(pdMS_TO_TICKS(200));
|
||||||
|
|
||||||
init_graphics();
|
|
||||||
vTaskDelay(pdMS_TO_TICKS(500));
|
|
||||||
|
|
||||||
|
|
||||||
create_counter();
|
create_counter();
|
||||||
|
|
||||||
vTaskDelay(pdMS_TO_TICKS(500));
|
|
||||||
|
|
||||||
xTaskCreate(lv_tick_task, "lv_tick", 4096, NULL, 1, NULL);
|
|
||||||
xTaskCreate(lv_task, "lv_task", 8192, NULL, 5, NULL);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*while(1){
|
|
||||||
clear_display();
|
|
||||||
vTaskDelay(pdMS_TO_TICKS(1000));
|
|
||||||
draw_text_ok();
|
|
||||||
vTaskDelay(pdMS_TO_TICKS(1000));
|
|
||||||
}*/
|
|
||||||
}
|
}
|
Reference in New Issue
Block a user