STM32H750VB_EPD/Core/Src/user_tasks.c

173 lines
4.6 KiB
C

#include <stdio.h>
#include "cmsis_os2.h"
#include "lvgl.h"
#include "user_epd_impl.h"
#include "user_lvgl_disp.h"
// Defined in main.c
extern SPI_HandleTypeDef hspi2;
// Private function prototypes
void user_task_flush_epd(void *arguments);
void user_task_lvgl_tick(void *arguments);
void user_task_hello(void *arguments);
uint8_t _user_tasks_init_epd(void);
uint8_t _user_tasks_init_lvgl(void);
#define FRAME_BUFFER_SIZE (212 * 10)
// Globals
depg0213_epd_t g_epd = {
.user_data = &hspi2,
.cb = {
.reset_cb = _epd_reset_cb,
.poll_busy_cb = _epd_poll_busy,
.write_cmd_cb = _epd_write_cmd_cb,
.write_data_cb = _epd_write_data_cb
}
};
lv_disp_buf_t g_disp_buf;
lv_color_t g_epd_frame[FRAME_BUFFER_SIZE];
lv_disp_t *g_epd_disp;
osSemaphoreId_t g_epd_busy_semphr;
osSemaphoreId_t g_spi2_semphr;
osSemaphoreId_t g_lvgl_semphr;
osThreadId_t g_flush_epd_task_handle;
const osThreadAttr_t g_flush_epd_task_attributes = {
.name = "flushEPD",
.priority = (osPriority_t) osPriorityBelowNormal,
.stack_size = 2048 * 4
};
osThreadId_t g_lvgl_tick_handle;
const osThreadAttr_t g_lvgl_tick_attributes = {
.name = "lvglTICK",
.priority = (osPriority_t) osPriorityBelowNormal,
.stack_size = 1024 * 4
};
osThreadId_t g_task_hello_handle;
const osThreadAttr_t g_task_hello_attributes = {
.name = "HELLO",
.priority = (osPriority_t) osPriorityNormal,
.stack_size = 1024 * 4
};
void user_tasks_initialize(void) {
HAL_NVIC_SetPriority(EXTI9_5_IRQn, 4, 0);
HAL_NVIC_SetPriority(SPI2_IRQn, 4, 0);
if(_user_tasks_init_epd()) return;
if(_user_tasks_init_lvgl()) return;
HAL_NVIC_SetPriority(EXTI9_5_IRQn, 5, 0);
HAL_NVIC_SetPriority(SPI2_IRQn, 6, 0);
g_flush_epd_task_handle = osThreadNew(user_task_flush_epd, NULL, &g_flush_epd_task_attributes);
g_lvgl_tick_handle = osThreadNew(user_task_lvgl_tick, NULL, &g_lvgl_tick_attributes);
g_task_hello_handle = osThreadNew(user_task_hello, NULL, &g_task_hello_attributes);
}
void user_task_hello(void *arguments) {
lv_obj_t *hello_label;
char buf[32];
osSemaphoreAcquire(g_lvgl_semphr, osWaitForever);
hello_label = lv_label_create(lv_scr_act(), NULL);
lv_label_set_align(hello_label, LV_LABEL_ALIGN_CENTER);
lv_label_set_text(hello_label, "Hello LVGL!!");
osSemaphoreRelease(g_lvgl_semphr);
for(;;) {
osDelay(10000);
snprintf(buf, 32, "LVGL@%ld", osKernelGetTickCount());
osSemaphoreAcquire(g_lvgl_semphr, osWaitForever);
lv_label_set_align(hello_label, LV_LABEL_ALIGN_CENTER);
lv_label_set_text(hello_label, buf);
osSemaphoreRelease(g_lvgl_semphr);
}
}
void user_task_flush_epd(void *arguments) {
for(;;) {
osSemaphoreAcquire(g_lvgl_semphr, osWaitForever);
lv_task_handler();
osSemaphoreRelease(g_lvgl_semphr);
osDelay(200);
}
}
void user_task_lvgl_tick(void *arguments) {
for(;;) {
osSemaphoreAcquire(g_lvgl_semphr, osWaitForever);
lv_tick_inc(50);
osSemaphoreRelease(g_lvgl_semphr);
osDelay(50);
}
}
uint8_t _user_tasks_init_epd(void) {
depg0213_ret_t ret;
g_epd_busy_semphr = osSemaphoreNew(1U, 0U, NULL); // Max: 1, initial 0, attr NULL
if(g_epd_busy_semphr == NULL) return -1;
g_spi2_semphr = osSemaphoreNew(1U, 0U, NULL);
if(g_spi2_semphr == NULL) return -1;
ret = depg0213_epd_init(&g_epd);
if(ret != DEPG0213_OK) return -2;
ret = depg0213_epd_window(&g_epd, DEPG0213_HORIZONTAL, 0, 211, 0, 103);
if(ret != DEPG0213_OK) return -3;
uint8_t buffer = 0x00;
for(uint16_t i = 0; i < 212; i++) {
for(uint16_t j = 0; j < 13; j++) {
depg0213_epd_load(&g_epd, NULL, &buffer, i, i, j * 8, j * 8 + 7);
}
}
buffer = 0xFF;
for(uint16_t i = 0; i < 212; i++) {
for(uint16_t j = 0; j < 13; j++) {
depg0213_epd_load(&g_epd, &buffer, NULL, i, i, j * 8, j * 8 + 7);
}
}
ret = depg0213_epd_deepsleep(&g_epd);
if(ret != DEPG0213_OK) return -6;
return 0;
}
uint8_t _user_tasks_init_lvgl(void) {
g_lvgl_semphr = osSemaphoreNew(1U, 1U, NULL); // Max: 1, initial 1, attr NULL
if(g_lvgl_semphr == NULL) return -1;
lv_init();
lv_disp_buf_init(&g_disp_buf, g_epd_frame, NULL, FRAME_BUFFER_SIZE);
lv_disp_drv_t disp_drv;
lv_disp_drv_init(&disp_drv);
disp_drv.buffer = &g_disp_buf;
disp_drv.set_px_cb = _epd_set_px_cb;
disp_drv.flush_cb = _epd_flush_cb;
disp_drv.rounder_cb = _epd_rounder_cb;
disp_drv.user_data = &g_epd;
g_epd_disp = lv_disp_drv_register(&disp_drv);
if(g_epd_disp == NULL) {
for(;;) {
//
}
}
return 0;
}