Compare commits
6 Commits
01221fa28f
...
master
Author | SHA1 | Date |
---|---|---|
imi415 | 1af5bf82f2 | |
imi415 | 66c4b9b064 | |
imi415 | 228883c700 | |
imi415 | 38b517ca1b | |
imi415 | f531b89c4d | |
imi415 | 85ce092f39 |
|
@ -4,13 +4,16 @@ idf_component_register(SRCS
|
|||
"assets/fonts/bebas_neue/bebas_neue_120.c"
|
||||
"assets/fonts/material_webfont/material_webfont_32.c"
|
||||
"main.c"
|
||||
"helper/helper_wifi.c"
|
||||
"impl/impl_btn.c"
|
||||
"impl/impl_dht.c"
|
||||
"impl/impl_epd.c"
|
||||
"impl/impl_lvgl.c"
|
||||
"impl/impl_sdfs.c"
|
||||
"interface/if_standby.c"
|
||||
"interface/if_wifi.c"
|
||||
"lib/epd-spi/src/epd_common.c"
|
||||
"lib/epd-spi/src/epd_panel_gdew042t2.c"
|
||||
"lib/htu21d/htu21d.c"
|
||||
"lib/lvgl/src/core/lv_disp.c"
|
||||
"lib/lvgl/src/core/lv_event.c"
|
||||
"lib/lvgl/src/core/lv_group.c"
|
||||
|
@ -163,11 +166,18 @@ idf_component_register(SRCS
|
|||
"lib/lvgl/src/widgets/lv_switch.c"
|
||||
"lib/lvgl/src/widgets/lv_table.c"
|
||||
"lib/lvgl/src/widgets/lv_textarea.c"
|
||||
"service/service_battery.c"
|
||||
"service/service_clock.c"
|
||||
"service/service_dht.c"
|
||||
"service/service_wifi.c"
|
||||
|
||||
INCLUDE_DIRS
|
||||
"lib"
|
||||
"lib/epd-spi/include"
|
||||
"lib/htu21d"
|
||||
"lib/lvgl"
|
||||
"impl"
|
||||
"include"
|
||||
"interface"
|
||||
"service"
|
||||
)
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
menu "Application Specific Configuration"
|
||||
|
||||
config ESP_WIFI_SSID
|
||||
string "WiFi SSID"
|
||||
default "myssid"
|
||||
help
|
||||
SSID (network name) for the example to connect to.
|
||||
|
||||
config ESP_WIFI_PASSWORD
|
||||
string "WiFi Password"
|
||||
default "mypassword"
|
||||
help
|
||||
WiFi password (WPA or WPA2) for the example to use.
|
||||
|
||||
config ESP_WIFI_MAXIMUM_RETRY
|
||||
int "Maximum retry"
|
||||
default 5
|
||||
help
|
||||
Set the Maximum retry to avoid station reconnecting to the AP unlimited when the AP is really inexistent.
|
||||
endmenu
|
|
@ -0,0 +1,18 @@
|
|||
#ifndef FONT_HELPER_H
|
||||
#define FONT_HELPER_H
|
||||
|
||||
#define MDI_WIFI_STRENGTH_OFF "\U000F092D"
|
||||
#define MDI_WIFI_STRENGTH_4 "\U000F0928"
|
||||
#define MDI_WIFI_STRENGTH_3 "\U000F0925"
|
||||
#define MDI_WIFI_STRENGTH_2 "\U000F0922"
|
||||
#define MDI_WIFI_STRENGTH_1 "\U000F091F"
|
||||
#define MDI_WIFI_STRENGTH_1_ALERT "\U000F0920"
|
||||
|
||||
#define MDI_BATTERY "\U000F0079"
|
||||
#define MDI_BATTERY_10 "\U000F007A"
|
||||
|
||||
#define MDI_WEATHER_SUNNY "\U000F0599"
|
||||
#define MDI_WATER "\U000F058C"
|
||||
#define MDI_WATER_CHECK "\U000F1504"
|
||||
|
||||
#endif
|
|
@ -0,0 +1 @@
|
|||
0xF0079, 0xF007A, 0xF0504, 0xF058C, 0xF0599, 0xF05AD, 0xF0928, 0xF092D, 0xF1504
|
|
@ -62,6 +62,29 @@ static LV_ATTRIBUTE_LARGE_CONST const uint8_t glyph_bitmap[] = {
|
|||
0x66, 0x0, 0x0, 0x3c, 0x0, 0x0, 0x18, 0x0,
|
||||
0x0, 0x18, 0x0, 0x0, 0x0, 0x0,
|
||||
|
||||
/* U+F05AD "" */
|
||||
0xe0, 0x0, 0xfe, 0x0, 0x3d, 0xe0, 0xf, 0x1e,
|
||||
0x3, 0xc1, 0xe0, 0xf0, 0x1e, 0x3c, 0x1, 0xef,
|
||||
0x0, 0x1f, 0xc0, 0x1, 0xf0, 0x0, 0x3e, 0x0,
|
||||
0xf, 0xe0, 0x3, 0xde, 0x0, 0xf1, 0xe0, 0x3c,
|
||||
0x1e, 0xf, 0x1, 0xe3, 0xc0, 0x1e, 0xf0, 0x1,
|
||||
0xfc, 0x0, 0x1c,
|
||||
|
||||
/* U+F0928 "" */
|
||||
0x0, 0x1f, 0xf8, 0x0, 0x1, 0xff, 0xff, 0x80,
|
||||
0x7, 0xff, 0xff, 0xe0, 0x1f, 0xff, 0xff, 0xf8,
|
||||
0x3f, 0xff, 0xff, 0xfc, 0x7f, 0xff, 0xff, 0xfe,
|
||||
0x7f, 0xff, 0xff, 0xfe, 0x3f, 0xff, 0xff, 0xfc,
|
||||
0x1f, 0xff, 0xff, 0xf8, 0xf, 0xff, 0xff, 0xf0,
|
||||
0x7, 0xff, 0xff, 0xe0, 0x7, 0xff, 0xff, 0xe0,
|
||||
0x3, 0xff, 0xff, 0xc0, 0x1, 0xff, 0xff, 0x80,
|
||||
0x0, 0xff, 0xff, 0x0, 0x0, 0x7f, 0xfe, 0x0,
|
||||
0x0, 0x7f, 0xfe, 0x0, 0x0, 0x3f, 0xfc, 0x0,
|
||||
0x0, 0x1f, 0xf8, 0x0, 0x0, 0xf, 0xf0, 0x0,
|
||||
0x0, 0x7, 0xe0, 0x0, 0x0, 0x7, 0xe0, 0x0,
|
||||
0x0, 0x3, 0xc0, 0x0, 0x0, 0x1, 0x80, 0x0,
|
||||
0x0, 0x0, 0x0, 0x0,
|
||||
|
||||
/* U+F092D "" */
|
||||
0x8, 0x0, 0x0, 0x0, 0x1c, 0x0, 0x0, 0x0,
|
||||
0xe, 0x1f, 0xf8, 0x0, 0x7, 0x1f, 0xff, 0x80,
|
||||
|
@ -90,7 +113,9 @@ static const lv_font_fmt_txt_glyph_dsc_t glyph_dsc[] = {
|
|||
{.bitmap_index = 52, .adv_w = 512, .box_w = 24, .box_h = 23, .ofs_x = 4, .ofs_y = 1},
|
||||
{.bitmap_index = 121, .adv_w = 512, .box_w = 16, .box_h = 23, .ofs_x = 8, .ofs_y = 1},
|
||||
{.bitmap_index = 167, .adv_w = 512, .box_w = 24, .box_h = 26, .ofs_x = 4, .ofs_y = -1},
|
||||
{.bitmap_index = 245, .adv_w = 512, .box_w = 32, .box_h = 27, .ofs_x = 0, .ofs_y = -1}
|
||||
{.bitmap_index = 245, .adv_w = 512, .box_w = 19, .box_h = 18, .ofs_x = 6, .ofs_y = 3},
|
||||
{.bitmap_index = 288, .adv_w = 512, .box_w = 32, .box_h = 25, .ofs_x = 0, .ofs_y = -1},
|
||||
{.bitmap_index = 388, .adv_w = 512, .box_w = 32, .box_h = 27, .ofs_x = 0, .ofs_y = -1}
|
||||
};
|
||||
|
||||
/*---------------------
|
||||
|
@ -98,7 +123,7 @@ static const lv_font_fmt_txt_glyph_dsc_t glyph_dsc[] = {
|
|||
*--------------------*/
|
||||
|
||||
static const uint16_t unicode_list_0[] = {
|
||||
0x0, 0x48a, 0x512, 0x51f, 0x8b3
|
||||
0x0, 0x48a, 0x512, 0x51f, 0x533, 0x8ae, 0x8b3
|
||||
};
|
||||
|
||||
/*Collect the unicode lists and glyph_id offsets*/
|
||||
|
@ -106,7 +131,7 @@ static const lv_font_fmt_txt_cmap_t cmaps[] =
|
|||
{
|
||||
{
|
||||
.range_start = 983162, .range_length = 2228, .glyph_id_start = 1,
|
||||
.unicode_list = unicode_list_0, .glyph_id_ofs_list = NULL, .list_length = 5, .type = LV_FONT_FMT_TXT_CMAP_SPARSE_TINY
|
||||
.unicode_list = unicode_list_0, .glyph_id_ofs_list = NULL, .list_length = 7, .type = LV_FONT_FMT_TXT_CMAP_SPARSE_TINY
|
||||
}
|
||||
};
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,17 +0,0 @@
|
|||
#include "esp_log.h"
|
||||
#include "esp_spi_flash.h"
|
||||
#include "esp_system.h"
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "sdkconfig.h"
|
||||
|
||||
esp_err_t helper_wifi_init(void) {
|
||||
// Check stored credentials from NVS,
|
||||
// if no credentials stored or button pressed, force initiate easy connect
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
void helper_wifi_task(void *pvParameters) {
|
||||
//
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
#include "esp_system.h"
|
||||
#include "driver/i2c.h"
|
||||
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
|
||||
#include "impl_dht.h"
|
||||
|
||||
#define IMPL_DHT_I2C_NUM 0
|
||||
#define IMPL_DHT_I2C_TIMEOUT 1000
|
||||
|
||||
htu21d_ret_t impl_dht_i2c_read(void *handle, uint8_t* data, uint8_t len) {
|
||||
if(i2c_master_read_from_device(IMPL_DHT_I2C_NUM, 0x40, data, len, pdMS_TO_TICKS(IMPL_DHT_I2C_TIMEOUT)) != ESP_OK) {
|
||||
return HTU21D_ERROR;
|
||||
}
|
||||
|
||||
return HTU21D_OK;
|
||||
}
|
||||
|
||||
htu21d_ret_t impl_dht_i2c_write(void *handle, uint8_t* data, uint8_t len) {
|
||||
if(i2c_master_write_to_device(IMPL_DHT_I2C_NUM, 0x40, data, len, pdMS_TO_TICKS(IMPL_DHT_I2C_TIMEOUT)) != ESP_OK) {
|
||||
return HTU21D_ERROR;
|
||||
}
|
||||
|
||||
return HTU21D_OK;
|
||||
}
|
||||
|
||||
htu21d_ret_t impl_dht_delay(void *handle, uint32_t msec) {
|
||||
vTaskDelay(pdMS_TO_TICKS(msec));
|
||||
|
||||
return HTU21D_OK;
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
#ifndef IMPL_DHT_H
|
||||
#define IMPL_DHT_H
|
||||
|
||||
#include "htu21d.h"
|
||||
|
||||
htu21d_ret_t impl_dht_i2c_read(void *handle, uint8_t* data, uint8_t len);
|
||||
htu21d_ret_t impl_dht_i2c_write(void *handle, uint8_t* data, uint8_t len);
|
||||
htu21d_ret_t impl_dht_delay(void *handle, uint32_t msec);
|
||||
|
||||
#endif
|
|
@ -8,7 +8,7 @@
|
|||
#define EPD_GPIO_RES GPIO_NUM_10
|
||||
#define EPD_GPIO_DC GPIO_NUM_12
|
||||
|
||||
#define EPD_SPI_HOST SPI2_HOST
|
||||
#define EPD_SPI_HOST SPI3_HOST
|
||||
#define EPD_SPI_SPEED (16 * 1000 * 1000) /* 16MHz */
|
||||
#define EPD_SPI_MAX_XFER_SIZE (1024)
|
||||
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
#include "esp_log.h"
|
||||
#include "impl_btn.h"
|
||||
#include "impl_epd.h"
|
||||
#include "task_config.h"
|
||||
|
||||
#define LOG_TAG "IMPL_LVGL"
|
||||
|
||||
|
@ -10,7 +11,7 @@
|
|||
#define EPD_DISPLAY_FRAME_SIZE (EPD_DISPLAY_PIXEL_COUNT * 2 / 8)
|
||||
|
||||
#define EPD_DISPLAY_GS 0
|
||||
#define EPD_DISPLAY_MAX_PARTIAL 12
|
||||
#define EPD_DISPLAY_MAX_PARTIAL 64 /* !! Must be even !! */
|
||||
|
||||
static impl_epd_handle_t s_epd_impl;
|
||||
|
||||
|
@ -38,7 +39,7 @@ static uint8_t s_epd_partial_counter = 0;
|
|||
static uint32_t s_last_key = 0;
|
||||
|
||||
static lv_disp_draw_buf_t s_disp_buf;
|
||||
static lv_color_t s_disp_store[EPD_DISPLAY_FRAME_SIZE];
|
||||
static lv_color_t *s_disp_store;
|
||||
static lv_disp_drv_t s_disp_drv;
|
||||
static lv_indev_drv_t s_indev_drv;
|
||||
|
||||
|
@ -144,9 +145,9 @@ static void impl_lvgl_button_read(lv_indev_drv_t *drv, lv_indev_data_t *data) {
|
|||
}
|
||||
|
||||
else {
|
||||
data->key = s_last_key;
|
||||
data->state = LV_INDEV_STATE_RELEASED;
|
||||
s_last_key = 0U;
|
||||
data->key = s_last_key;
|
||||
data->state = LV_INDEV_STATE_RELEASED;
|
||||
s_last_key = 0U;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -194,6 +195,9 @@ esp_err_t impl_lvgl_init(void) {
|
|||
|
||||
lv_log_register_print_cb(impl_lvgl_log_cb);
|
||||
|
||||
s_disp_store = malloc(EPD_DISPLAY_FRAME_SIZE);
|
||||
if (s_disp_store == NULL) return ESP_FAIL;
|
||||
|
||||
lv_disp_draw_buf_init(&s_disp_buf, s_disp_store, NULL, EPD_DISPLAY_PIXEL_COUNT);
|
||||
lv_disp_drv_init(&s_disp_drv);
|
||||
|
||||
|
@ -214,11 +218,11 @@ esp_err_t impl_lvgl_init(void) {
|
|||
impl_btn_init();
|
||||
|
||||
lv_indev_drv_init(&s_indev_drv);
|
||||
s_indev_drv.type = LV_INDEV_TYPE_KEYPAD;
|
||||
s_indev_drv.type = LV_INDEV_TYPE_KEYPAD;
|
||||
s_indev_drv.read_cb = impl_lvgl_button_read;
|
||||
|
||||
lv_indev_t *indev = lv_indev_drv_register(&s_indev_drv);
|
||||
if(indev == NULL) {
|
||||
lv_indev_t *indev = lv_indev_drv_register(&s_indev_drv);
|
||||
if (indev == NULL) {
|
||||
ESP_LOGE(LOG_TAG, "LVGL indev register failed.");
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
@ -230,7 +234,7 @@ esp_err_t impl_lvgl_init(void) {
|
|||
lv_theme_t *default_theme = lv_theme_mono_init(disp, false, &lv_font_unscii_16);
|
||||
lv_disp_set_theme(disp, default_theme);
|
||||
|
||||
s_lv_semphr_handle = xSemaphoreCreateBinary();
|
||||
s_lv_semphr_handle = xSemaphoreCreateMutex();
|
||||
if (s_lv_semphr_handle == NULL) {
|
||||
ESP_LOGE(LOG_TAG, "LVGL semaphore creation failed.");
|
||||
return ESP_FAIL;
|
||||
|
@ -238,11 +242,13 @@ esp_err_t impl_lvgl_init(void) {
|
|||
|
||||
xSemaphoreGive(s_lv_semphr_handle);
|
||||
|
||||
if (xTaskCreate(impl_lvgl_tick_task, "LV_TICK", 4096, NULL, 5, &s_lv_tick_handle) != pdPASS) {
|
||||
if (xTaskCreate(impl_lvgl_tick_task, "IMPL_LVT", TASK_IMPL_LVT_STACK_SIZE, NULL, TASK_IMPL_LVT_PRIORITY,
|
||||
&s_lv_tick_handle) != pdPASS) {
|
||||
ESP_LOGE(LOG_TAG, "LVGL tick task creation failed.");
|
||||
return ESP_FAIL;
|
||||
}
|
||||
if (xTaskCreate(impl_lvgl_timer_task, "LV_TMR", 4096, NULL, 4, &s_lv_task_handle) != pdPASS) {
|
||||
if (xTaskCreate(impl_lvgl_timer_task, "IMPL_LVE", TASK_IMPL_LVE_STACK_SIZE, NULL, TASK_IMPL_LVE_PRIORITY,
|
||||
&s_lv_task_handle) != pdPASS) {
|
||||
ESP_LOGE(LOG_TAG, "LVGL timer handler task creation failed.");
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,18 @@
|
|||
#include "impl_sdfs.h"
|
||||
|
||||
#include "lvgl.h"
|
||||
|
||||
lv_fs_res_t impl_sdfs_open(lv_fs_drv_t *drv, void *file_p, const char *path, lv_fs_mode_t mode) {
|
||||
//
|
||||
return LV_FS_RES_OK;
|
||||
}
|
||||
|
||||
lv_fs_res_t impl_sdfs_close(lv_fs_drv_t *drv, void *file_p) {
|
||||
//
|
||||
return LV_FS_RES_OK;
|
||||
}
|
||||
|
||||
esp_err_t impl_sdfs_init(void) {
|
||||
//
|
||||
return ESP_OK;
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
#ifndef IMPL_SDFS_H
|
||||
#define IMPL_SDFS_H
|
||||
|
||||
#include "esp_system.h"
|
||||
|
||||
#endif
|
|
@ -0,0 +1,19 @@
|
|||
#ifndef TASK_CONFIG_H
|
||||
#define TASK_CONFIG_H
|
||||
|
||||
#define TASK_IMPL_LVE_STACK_SIZE 4096
|
||||
#define TASK_IMPL_LVE_PRIORITY 4
|
||||
|
||||
#define TASK_IMPL_LVT_STACK_SIZE 4096
|
||||
#define TASK_IMPL_LVT_PRIORITY 5
|
||||
|
||||
#define TASK_SVC_CLK_STACK_SIZE 2048
|
||||
#define TASK_SVC_CLK_PRIORITY 6
|
||||
|
||||
#define TASK_SVC_DHT_STACK_SIZE 2048
|
||||
#define TASK_SVC_DHT_PRIORITY 6
|
||||
|
||||
#define TASK_SVC_WIFI_STACK_SIZE 2048
|
||||
#define TASK_SVC_WIFI_PRIORITY 6
|
||||
|
||||
#endif
|
|
@ -3,16 +3,42 @@
|
|||
#include <sys/time.h>
|
||||
|
||||
#include "esp_log.h"
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "if_wifi.h"
|
||||
#include "impl_lvgl.h"
|
||||
|
||||
#define LOG_TAG "IF_STANDBY"
|
||||
#define LOG_TAG "IF_STANDBY"
|
||||
|
||||
static TaskHandle_t s_if_standby_handle;
|
||||
#define IF_EVENT_WIFI_BUTTON 0
|
||||
#define IF_EVENT_BAT_BUTTON 1
|
||||
|
||||
typedef struct {
|
||||
if_standby_component_t component;
|
||||
char payload[IF_STANDBY_PAYLOAD_LENGTH];
|
||||
} if_standby_request_t;
|
||||
|
||||
static TaskHandle_t s_if_standby_handle;
|
||||
static QueueHandle_t s_standby_screen_queue;
|
||||
|
||||
lv_obj_t *g_standby_screen;
|
||||
|
||||
void if_standby_event_handler(lv_event_t *ev) {
|
||||
int button_event = (int)ev->user_data;
|
||||
|
||||
switch (button_event) {
|
||||
case IF_EVENT_WIFI_BUTTON:
|
||||
if_wifi_init(g_standby_screen);
|
||||
break;
|
||||
case IF_EVENT_BAT_BUTTON:
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* @brief Standby screen task, handles GUI element updates through a queue.
|
||||
*
|
||||
* @param pvParameters
|
||||
*/
|
||||
void if_standby_task(void *pvParameters) {
|
||||
impl_lvgl_lock();
|
||||
|
||||
|
@ -38,6 +64,9 @@ void if_standby_task(void *pvParameters) {
|
|||
lv_obj_t *date_obj = lv_obj_create(top_container);
|
||||
lv_obj_t *battery_obj = lv_btn_create(top_container);
|
||||
|
||||
lv_obj_add_event_cb(network_status_obj, if_standby_event_handler, LV_EVENT_CLICKED, (void *)IF_EVENT_WIFI_BUTTON);
|
||||
lv_obj_add_event_cb(battery_obj, if_standby_event_handler, LV_EVENT_CLICKED, (void *)IF_EVENT_BAT_BUTTON);
|
||||
|
||||
lv_obj_set_size(network_status_obj, 50, 50);
|
||||
lv_obj_set_size(battery_obj, 50, 50);
|
||||
|
||||
|
@ -105,9 +134,9 @@ void if_standby_task(void *pvParameters) {
|
|||
lv_label_set_text(date_label, "1970/01/01");
|
||||
lv_label_set_text(time_label, "23:59");
|
||||
lv_label_set_text(temp_icon_label, "\U000F0599");
|
||||
lv_label_set_text(temp_label, "30.00C");
|
||||
lv_label_set_text(temp_label, "30.00");
|
||||
lv_label_set_text(humid_icon_label, "\U000F058C");
|
||||
lv_label_set_text(humid_label, "100.00%");
|
||||
lv_label_set_text(humid_label, "100.00");
|
||||
|
||||
lv_obj_set_align(network_status_label, LV_ALIGN_CENTER);
|
||||
lv_obj_set_align(battery_label, LV_ALIGN_CENTER);
|
||||
|
@ -123,9 +152,49 @@ void if_standby_task(void *pvParameters) {
|
|||
|
||||
ESP_LOGI(LOG_TAG, "Standby screen created.");
|
||||
|
||||
if_standby_request_t update_request;
|
||||
|
||||
for (;;) {
|
||||
// Wait for notifications.
|
||||
vTaskSuspend(NULL);
|
||||
// Read from queue for UI element updates.
|
||||
xQueueReceive(s_standby_screen_queue, &update_request, portMAX_DELAY);
|
||||
impl_lvgl_lock();
|
||||
switch (update_request.component) {
|
||||
case IF_STANDBY_COMPONENT_DATE:
|
||||
lv_label_set_text(date_label, update_request.payload);
|
||||
lv_obj_set_align(date_label, LV_ALIGN_CENTER);
|
||||
break;
|
||||
case IF_STANDBY_COMPONENT_HUMID:
|
||||
lv_label_set_text(humid_label, update_request.payload);
|
||||
lv_obj_align(humid_label, LV_ALIGN_CENTER, 0, 16);
|
||||
break;
|
||||
case IF_STANDBY_COMPONENT_HUMID_ICON:
|
||||
lv_label_set_text(humid_icon_label, update_request.payload);
|
||||
lv_obj_align(humid_icon_label, LV_ALIGN_CENTER, 0, -16);
|
||||
break;
|
||||
case IF_STANDBY_COMPONENT_TEMP:
|
||||
lv_label_set_text(temp_label, update_request.payload);
|
||||
lv_obj_align(temp_label, LV_ALIGN_CENTER, 0, 16);
|
||||
break;
|
||||
case IF_STANDBY_COMPONENT_TEMP_ICON:
|
||||
lv_label_set_text(temp_icon_label, update_request.payload);
|
||||
lv_obj_align(temp_icon_label, LV_ALIGN_CENTER, 0, -16);
|
||||
break;
|
||||
case IF_STANDBY_COMPONENT_TIME:
|
||||
lv_label_set_text(time_label, update_request.payload);
|
||||
lv_obj_set_align(time_label, LV_ALIGN_CENTER);
|
||||
break;
|
||||
case IF_STANDBY_COMPONENT_WEEKDAY:
|
||||
lv_label_set_text(weekday_label, update_request.payload);
|
||||
lv_obj_set_align(weekday_label, LV_ALIGN_CENTER);
|
||||
break;
|
||||
case IF_STANDBY_COMPONENT_WIFI:
|
||||
lv_label_set_text(network_status_label, update_request.payload);
|
||||
lv_obj_set_align(network_status_label, LV_ALIGN_CENTER);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
impl_lvgl_unlock();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -135,9 +204,40 @@ esp_err_t if_standby_init(void) {
|
|||
lv_disp_load_scr(g_standby_screen);
|
||||
impl_lvgl_unlock();
|
||||
|
||||
if (xTaskCreate(if_standby_task, "STBY_TASK", 4096, NULL, 6, &s_if_standby_handle) != pdPASS) {
|
||||
s_standby_screen_queue = xQueueCreate(8, sizeof(if_standby_request_t));
|
||||
if (s_standby_screen_queue == NULL) {
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
if (xTaskCreate(if_standby_task, "IF_STBY", 4096, NULL, 6, &s_if_standby_handle) != pdPASS) {
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Update component content on standby screen.
|
||||
*
|
||||
* @param component if_standby_component_t
|
||||
* @param fmt printf-style format
|
||||
* @param ...
|
||||
* @return esp_err_t
|
||||
*/
|
||||
esp_err_t if_standby_component_update(if_standby_component_t component, const char *fmt, ...) {
|
||||
if_standby_request_t req;
|
||||
va_list ap;
|
||||
|
||||
req.component = component;
|
||||
|
||||
va_start(ap, fmt);
|
||||
vsnprintf(req.payload, IF_STANDBY_PAYLOAD_LENGTH, fmt, ap);
|
||||
va_end(ap);
|
||||
|
||||
// Queue update command.
|
||||
if (xQueueSendToBack(s_standby_screen_queue, &req, 0) != pdPASS) {
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
|
|
@ -2,6 +2,28 @@
|
|||
#define IF_STANDBY_H
|
||||
|
||||
#include "esp_system.h"
|
||||
esp_err_t if_standby_init(void);
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/queue.h"
|
||||
#include "freertos/task.h"
|
||||
#include "lvgl.h"
|
||||
|
||||
#endif
|
||||
#define IF_STANDBY_PAYLOAD_LENGTH 16
|
||||
|
||||
typedef enum {
|
||||
IF_STANDBY_COMPONENT_BAT,
|
||||
IF_STANDBY_COMPONENT_DATE,
|
||||
IF_STANDBY_COMPONENT_HUMID,
|
||||
IF_STANDBY_COMPONENT_HUMID_ICON,
|
||||
IF_STANDBY_COMPONENT_TIME,
|
||||
IF_STANDBY_COMPONENT_TEMP,
|
||||
IF_STANDBY_COMPONENT_TEMP_ICON,
|
||||
IF_STANDBY_COMPONENT_WEEKDAY,
|
||||
IF_STANDBY_COMPONENT_WIFI,
|
||||
} if_standby_component_t;
|
||||
|
||||
extern lv_obj_t *g_standby_screen;
|
||||
|
||||
esp_err_t if_standby_init(void);
|
||||
esp_err_t if_standby_component_update(if_standby_component_t component, const char *fmt, ...);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -0,0 +1,88 @@
|
|||
#include "esp_system.h"
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/queue.h"
|
||||
#include "freertos/task.h"
|
||||
#include "impl_lvgl.h"
|
||||
|
||||
#define IF_EVENT_QUEUE_LEN 2
|
||||
#define IF_EVENT_QUEUE_SIZE() (sizeof(int))
|
||||
#define IF_EVENT_QUEUE_TIMEOUT 100
|
||||
|
||||
#define IF_EVENT_EXIT_BUTTON 0
|
||||
|
||||
static TaskHandle_t s_if_wifi_task_handle;
|
||||
static QueueHandle_t s_if_wifi_event_queue;
|
||||
|
||||
static void if_wifi_event_handler(lv_event_t *ev) {
|
||||
int button_event = (int)ev->user_data;
|
||||
xQueueSend(s_if_wifi_event_queue, &button_event, pdMS_TO_TICKS(100));
|
||||
}
|
||||
|
||||
void if_wifi_task(void *pvParameters) {
|
||||
lv_obj_t *parent = pvParameters;
|
||||
|
||||
impl_lvgl_lock();
|
||||
|
||||
lv_obj_t *wifi_main = lv_obj_create(parent);
|
||||
lv_obj_set_size(wifi_main, 360, 280);
|
||||
lv_obj_set_align(wifi_main, LV_ALIGN_CENTER);
|
||||
|
||||
lv_obj_t *exit_obj = lv_btn_create(wifi_main);
|
||||
|
||||
lv_obj_set_size(exit_obj, 36, 36);
|
||||
|
||||
lv_obj_align(exit_obj, LV_ALIGN_TOP_RIGHT, 0, 0);
|
||||
|
||||
lv_obj_add_event_cb(exit_obj, if_wifi_event_handler, LV_EVENT_CLICKED, (void *)IF_EVENT_EXIT_BUTTON);
|
||||
|
||||
lv_obj_t *exit_label = lv_label_create(exit_obj);
|
||||
|
||||
lv_obj_set_style_text_font(exit_label, &material_webfont_32, 0);
|
||||
|
||||
lv_label_set_text(exit_label, "\U000F05AD");
|
||||
|
||||
lv_obj_set_align(exit_label, LV_ALIGN_CENTER);
|
||||
|
||||
impl_lvgl_unlock();
|
||||
|
||||
int button_event = 0;
|
||||
uint8_t terminate_flag = 0;
|
||||
|
||||
for (;;) {
|
||||
if (xQueueReceive(s_if_wifi_event_queue, &button_event, portMAX_DELAY) == pdPASS) {
|
||||
switch (button_event) {
|
||||
case IF_EVENT_EXIT_BUTTON:
|
||||
terminate_flag = 1;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (terminate_flag) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// When we are done, delete UI elements and task
|
||||
lv_obj_del_async(wifi_main);
|
||||
|
||||
vQueueDelete(s_if_wifi_event_queue);
|
||||
s_if_wifi_event_queue = NULL;
|
||||
vTaskDelete(NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Initialize WiFi status/configuration component
|
||||
*
|
||||
* @param parent_obj
|
||||
* @return esp_err_t
|
||||
*/
|
||||
esp_err_t if_wifi_init(lv_obj_t *parent_obj) {
|
||||
s_if_wifi_event_queue = xQueueCreate(IF_EVENT_QUEUE_LEN, IF_EVENT_QUEUE_SIZE());
|
||||
|
||||
if (xTaskCreate(if_wifi_task, "STBY_TASK", 4096, parent_obj, 6, &s_if_wifi_task_handle) != pdPASS) {
|
||||
return ESP_FAIL;
|
||||
}
|
||||
return ESP_OK;
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
#ifndef IF_WIFI_H
|
||||
#define IF_WIFI_H
|
||||
|
||||
esp_err_t if_wifi_init(lv_obj_t *parent_obj);
|
||||
|
||||
#endif
|
|
@ -0,0 +1,44 @@
|
|||
#include "htu21d.h"
|
||||
|
||||
#define HTU21D_REG_MEASURE_TEMP_HOLD 0xE3
|
||||
#define HTU21D_REG_MEASURE_TEMP_NOHOLD 0xF3
|
||||
|
||||
#define HTU21D_REG_MEASURE_HUMID_HOLD 0xE5
|
||||
#define HTU21D_REG_MEASURE_HUMID_NOHOLD 0xF5
|
||||
|
||||
#define HTU21D_REG_READ_USER_REG 0xE7
|
||||
#define HTU21D_REG_WRITE_USER_REG 0xE6
|
||||
|
||||
#define HTU21D_REG_SOFT_RESET 0xFE
|
||||
|
||||
#define HTU21D_ERROR_CHECK(x) \
|
||||
if (x != HTU21D_OK) return HTU21D_ERROR
|
||||
|
||||
htu21d_ret_t htu21d_init(htu21d_t *htu) {
|
||||
uint8_t tx_buf = HTU21D_REG_SOFT_RESET;
|
||||
HTU21D_ERROR_CHECK(htu->cb.write_cb(htu->user_data, &tx_buf, 0x01));
|
||||
return HTU21D_OK;
|
||||
}
|
||||
|
||||
htu21d_ret_t htu21d_measure(htu21d_t *htu, htu21d_result_t *result) {
|
||||
uint8_t tx_buf = HTU21D_REG_MEASURE_TEMP_NOHOLD;
|
||||
uint8_t rx_data[3];
|
||||
|
||||
HTU21D_ERROR_CHECK(htu->cb.write_cb(htu->user_data, &tx_buf, 0x01));
|
||||
HTU21D_ERROR_CHECK(htu->cb.delay_cb(htu->user_data, 50));
|
||||
HTU21D_ERROR_CHECK(htu->cb.read_cb(htu->user_data, rx_data, 0x03));
|
||||
|
||||
uint16_t raw_data = (rx_data[0] << 8U) | (rx_data[1] & 0xFC);
|
||||
result->temperature = (float)raw_data / 65536.0 * 175.72 - 46.85;
|
||||
|
||||
tx_buf = HTU21D_REG_MEASURE_HUMID_NOHOLD;
|
||||
|
||||
HTU21D_ERROR_CHECK(htu->cb.write_cb(htu->user_data, &tx_buf, 0x01));
|
||||
HTU21D_ERROR_CHECK(htu->cb.delay_cb(htu->user_data, 50));
|
||||
HTU21D_ERROR_CHECK(htu->cb.read_cb(htu->user_data, rx_data, 0x03));
|
||||
|
||||
raw_data = (rx_data[0] << 8U) | (rx_data[1] & 0xFC);
|
||||
result->humidity = (float)raw_data / 65536.0 * 125.0 - 6.0;
|
||||
|
||||
return HTU21D_OK;
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
#ifndef HTU21D_H
|
||||
#define HTU21D_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
typedef enum {
|
||||
HTU21D_OK,
|
||||
HTU21D_ERROR
|
||||
} htu21d_ret_t;
|
||||
|
||||
typedef struct {
|
||||
htu21d_ret_t (*write_cb)(void * handle, uint8_t* data, uint8_t len);
|
||||
htu21d_ret_t (*read_cb)(void *handle, uint8_t* data, uint8_t len);
|
||||
htu21d_ret_t (*delay_cb)(void *handle, uint32_t msec);
|
||||
} htu21d_cb_t;
|
||||
|
||||
typedef struct {
|
||||
float temperature;
|
||||
float humidity;
|
||||
} htu21d_result_t;
|
||||
|
||||
typedef struct {
|
||||
htu21d_cb_t cb;
|
||||
void *user_data;
|
||||
} htu21d_t;
|
||||
|
||||
htu21d_ret_t htu21d_init(htu21d_t *htu);
|
||||
htu21d_ret_t htu21d_measure(htu21d_t *htu, htu21d_result_t *result);
|
||||
|
||||
#endif
|
|
@ -0,0 +1,42 @@
|
|||
#include "ltc2941.h"
|
||||
|
||||
#define LTC2941_REG_STATUS 0x00
|
||||
#define LTC2941_REG_CONTROL 0x01
|
||||
#define LTC2941_REG_CHARGE_MSB 0x02
|
||||
#define LTC2941_REG_CHARGE_LSB 0x03
|
||||
|
||||
ltc2941_ret_t ltc2941_init(ltc2941_t *bat) {
|
||||
|
||||
uint8_t control_reg =
|
||||
((bat->config.alert_mode & 0x03U) << 0x01U) |
|
||||
((bat->config.prescaler & 0x07U) << 0x03U) |
|
||||
((bat->config.alert_level & 0x03U) << 0x06U);
|
||||
|
||||
bat->cb.write_register_cb(bat->user_data, LTC2941_REG_CONTROL, control_reg);
|
||||
return LTC2941_OK;
|
||||
}
|
||||
|
||||
ltc2941_ret_t ltc2941_read_status(ltc2941_t *bat, uint8_t *status) {
|
||||
return bat->cb.read_register_cb(bat->user_data, LTC2941_REG_STATUS, status);
|
||||
}
|
||||
|
||||
ltc2941_ret_t ltc2941_read_charge(ltc2941_t *bat, uint16_t *charge) {
|
||||
uint8_t reg = 0x00;
|
||||
bat->cb.read_register_cb(bat->user_data, LTC2941_REG_CHARGE_MSB, ®);
|
||||
*charge = reg << 0x08U;
|
||||
|
||||
bat->cb.read_register_cb(bat->user_data, LTC2941_REG_CHARGE_LSB, ®);
|
||||
*charge |= reg;
|
||||
|
||||
return LTC2941_OK;
|
||||
}
|
||||
|
||||
ltc2941_ret_t ltc2941_write_charge(ltc2941_t *bat, uint16_t charge) {
|
||||
uint8_t reg = (charge >> 0x08U); // MSB
|
||||
bat->cb.write_register_cb(bat->user_data, LTC2941_REG_CHARGE_MSB, reg);
|
||||
|
||||
reg = (charge & 0xFFU); // LSB
|
||||
bat->cb.write_register_cb(bat->user_data, LTC2941_REG_CHARGE_LSB, reg);
|
||||
|
||||
return LTC2941_OK;
|
||||
}
|
|
@ -0,0 +1,64 @@
|
|||
#ifndef __LTC2941_BATTERY_H
|
||||
#define __LTC2941_BATTERY_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
typedef enum {
|
||||
LTC2941_OK,
|
||||
LTC2941_ERROR
|
||||
} ltc2941_ret_t;
|
||||
|
||||
typedef enum {
|
||||
LTC2941_ALERT_3_0V = 0x03,
|
||||
LTC2941_ALERT_2_9V = 0x02,
|
||||
LTC2941_ALERT_2_8V = 0x01,
|
||||
LTC2941_ALERT_OFF = 0x00
|
||||
} ltc2941_battery_alert_t;
|
||||
|
||||
typedef enum {
|
||||
LTC2941_PRE_1 = 0x00,
|
||||
LTC2941_PRE_2 = 0x01,
|
||||
LTC2941_PRE_4 = 0x02,
|
||||
LTC2941_PRE_8 = 0x03,
|
||||
LTC2941_PRE_16 = 0x04,
|
||||
LTC2941_PRE_32 = 0x05,
|
||||
LTC2941_PRE_64 = 0x06,
|
||||
LTC2941_PRE_128 = 0x07
|
||||
} ltc2941_prescale_t;
|
||||
|
||||
typedef enum {
|
||||
LTC2941_ALERT_DISABLED = 0x00,
|
||||
LTC2941_ALERT_CC = 0x01,
|
||||
LTC2941_ALERT_AL = 0x02
|
||||
} ltc2941_alert_mode_t;
|
||||
|
||||
typedef struct {
|
||||
ltc2941_ret_t (*write_register_cb)(void * handle, uint8_t reg, uint8_t value);
|
||||
ltc2941_ret_t (*read_register_cb)(void *handle, uint8_t reg, uint8_t *value);
|
||||
} ltc2941_cb_t;
|
||||
|
||||
typedef struct {
|
||||
ltc2941_prescale_t prescaler;
|
||||
ltc2941_alert_mode_t alert_mode;
|
||||
ltc2941_battery_alert_t alert_level;
|
||||
} ltc2941_config_t;
|
||||
|
||||
typedef struct {
|
||||
ltc2941_cb_t cb;
|
||||
ltc2941_config_t config;
|
||||
void *user_data;
|
||||
} ltc2941_t;
|
||||
|
||||
#define LTC2941_STATUS_CHIPID (1 << 7U)
|
||||
#define LTC2941_STATUS_OVERFLOW (1 << 5U)
|
||||
#define LTC2941_STATUS_ALRT_HIGH (1 << 3U)
|
||||
#define LTC2941_STATUS_ALRT_LOW (1 << 2U)
|
||||
#define LTC2941_STATUS_ALRT_VBAT (1 << 1U)
|
||||
#define LTC2941_STATUS_ALRT_UVLO 1U
|
||||
|
||||
ltc2941_ret_t ltc2941_init(ltc2941_t *bat);
|
||||
ltc2941_ret_t ltc2941_read_status(ltc2941_t *bat, uint8_t *status);
|
||||
ltc2941_ret_t ltc2941_read_charge(ltc2941_t *bat, uint16_t *charge);
|
||||
ltc2941_ret_t ltc2941_write_charge(ltc2941_t *bat, uint16_t charge);
|
||||
|
||||
#endif
|
|
@ -78,10 +78,10 @@
|
|||
*====================*/
|
||||
|
||||
/*Default display refresh period. LVG will redraw changed areas with this period time*/
|
||||
#define LV_DISP_DEF_REFR_PERIOD 30 /*[ms]*/
|
||||
#define LV_DISP_DEF_REFR_PERIOD 100 /*[ms]*/
|
||||
|
||||
/*Input device read period in milliseconds*/
|
||||
#define LV_INDEV_DEF_READ_PERIOD 30 /*[ms]*/
|
||||
#define LV_INDEV_DEF_READ_PERIOD 50 /*[ms]*/
|
||||
|
||||
/*Use a custom tick source that tells the elapsed time in milliseconds.
|
||||
*It removes the need to manually update the tick with `lv_tick_inc()`)*/
|
||||
|
@ -181,7 +181,7 @@ e.g. "stm32f769xx.h" or "stm32f429xx.h"*/
|
|||
*LV_LOG_LEVEL_ERROR Only critical issue, when the system may fail
|
||||
*LV_LOG_LEVEL_USER Only logs added by the user
|
||||
*LV_LOG_LEVEL_NONE Do not log anything*/
|
||||
# define LV_LOG_LEVEL LV_LOG_LEVEL_INFO
|
||||
# define LV_LOG_LEVEL LV_LOG_LEVEL_WARN
|
||||
|
||||
/*1: Print the log with 'printf';
|
||||
*0: User need to register a callback with `lv_log_register_print_cb()`*/
|
||||
|
@ -343,7 +343,7 @@ e.g. "stm32f769xx.h" or "stm32f429xx.h"*/
|
|||
LV_FONT_DECLARE(material_webfont_32)
|
||||
|
||||
/*Always set a default font*/
|
||||
#define LV_FONT_DEFAULT &lv_font_unscii_16
|
||||
#define LV_FONT_DEFAULT &bebas_neue_32
|
||||
|
||||
/*Enable handling large font and/or fonts with a lot of characters.
|
||||
*The limit depends on the font size, font face and bpp.
|
||||
|
|
46
main/main.c
46
main/main.c
|
@ -1,6 +1,8 @@
|
|||
#include <stdio.h>
|
||||
|
||||
#include "driver/gpio.h"
|
||||
#include "driver/i2c.h"
|
||||
#include "esp_sntp.h"
|
||||
#include "esp_spi_flash.h"
|
||||
#include "esp_system.h"
|
||||
#include "nvs_flash.h"
|
||||
|
@ -9,8 +11,16 @@
|
|||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
//
|
||||
#include "impl_lvgl.h"
|
||||
#include "if_standby.h"
|
||||
#include "impl_lvgl.h"
|
||||
#include "service_clock.h"
|
||||
#include "service_dht.h"
|
||||
#include "service_wifi.h"
|
||||
|
||||
#define APP_I2C_MASTER_NUM 0
|
||||
#define APP_I2C_SDA_NUM GPIO_NUM_39
|
||||
#define APP_I2C_SCL_NUM GPIO_NUM_40
|
||||
#define APP_I2C_HZ 400000
|
||||
|
||||
static esp_err_t app_init_nvs(void) {
|
||||
esp_err_t ret = nvs_flash_init();
|
||||
|
@ -22,18 +32,48 @@ static esp_err_t app_init_nvs(void) {
|
|||
return ret;
|
||||
}
|
||||
|
||||
static esp_err_t app_init_gpio(void) { return gpio_install_isr_service(0); }
|
||||
static esp_err_t app_init_gpio(void) {
|
||||
//
|
||||
return gpio_install_isr_service(0);
|
||||
}
|
||||
|
||||
esp_err_t impl_lvgl_init(void);
|
||||
static esp_err_t app_init_i2c(void) {
|
||||
i2c_config_t cfg = {
|
||||
.mode = I2C_MODE_MASTER,
|
||||
.sda_io_num = APP_I2C_SDA_NUM,
|
||||
.scl_io_num = APP_I2C_SCL_NUM,
|
||||
.sda_pullup_en = GPIO_PULLUP_ENABLE,
|
||||
.scl_pullup_en = GPIO_PULLUP_ENABLE,
|
||||
.master.clk_speed = APP_I2C_HZ,
|
||||
};
|
||||
|
||||
i2c_param_config(APP_I2C_MASTER_NUM, &cfg);
|
||||
|
||||
return i2c_driver_install(APP_I2C_MASTER_NUM, cfg.mode, 0, 0, 0);
|
||||
}
|
||||
|
||||
static esp_err_t app_init_sntp(void) {
|
||||
sntp_setoperatingmode(SNTP_OPMODE_POLL);
|
||||
sntp_setservername(0, "pool.ntp.org");
|
||||
sntp_init();
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
void app_main(void) {
|
||||
ESP_ERROR_CHECK(app_init_nvs());
|
||||
ESP_ERROR_CHECK(app_init_gpio());
|
||||
ESP_ERROR_CHECK(app_init_i2c());
|
||||
ESP_ERROR_CHECK(app_init_sntp());
|
||||
|
||||
ESP_ERROR_CHECK(impl_lvgl_init());
|
||||
|
||||
ESP_ERROR_CHECK(if_standby_init());
|
||||
|
||||
ESP_ERROR_CHECK(service_dht_init());
|
||||
ESP_ERROR_CHECK(service_clock_init());
|
||||
ESP_ERROR_CHECK(service_wifi_init());
|
||||
|
||||
/* Dead loop */
|
||||
for (;;) {
|
||||
vTaskSuspend(NULL);
|
||||
|
|
|
@ -0,0 +1,58 @@
|
|||
#include "service_clock.h"
|
||||
|
||||
#include <time.h>
|
||||
|
||||
#include "esp_log.h"
|
||||
#include "if_standby.h"
|
||||
#include "task_config.h"
|
||||
|
||||
#define LOG_TAG "SERVICE_CLOCK"
|
||||
|
||||
static TaskHandle_t s_clock_task_handle;
|
||||
|
||||
static const char *s_wday_array[] = {"SUN", "MON", "TUE", "WED", "THU", "FRI", "SAT"};
|
||||
|
||||
void clock_task(void *pvParameters) {
|
||||
struct tm timeinfo;
|
||||
time_t now;
|
||||
|
||||
uint8_t prev_min = 0xFF;
|
||||
uint8_t prev_mday = 0xFF;
|
||||
uint8_t prev_wday = 0xFF;
|
||||
|
||||
setenv("TZ", "CST-8", 1);
|
||||
tzset();
|
||||
|
||||
for (;;) {
|
||||
time(&now);
|
||||
localtime_r(&now, &timeinfo);
|
||||
|
||||
if ((timeinfo.tm_min != prev_min) || (prev_min == 0xFF)) {
|
||||
if_standby_component_update(IF_STANDBY_COMPONENT_TIME, "%02u:%02u", timeinfo.tm_hour, timeinfo.tm_min);
|
||||
|
||||
prev_min = timeinfo.tm_min;
|
||||
}
|
||||
if ((timeinfo.tm_mday != prev_mday) || (prev_mday == 0xFF)) {
|
||||
if_standby_component_update(IF_STANDBY_COMPONENT_DATE, "%04u/%02d/%02d", timeinfo.tm_year + 1900,
|
||||
timeinfo.tm_mon + 1, timeinfo.tm_mday);
|
||||
|
||||
prev_mday = timeinfo.tm_mday;
|
||||
}
|
||||
if ((timeinfo.tm_wday != prev_wday) || (prev_wday == 0xFF)) {
|
||||
if_standby_component_update(IF_STANDBY_COMPONENT_WEEKDAY, s_wday_array[timeinfo.tm_wday]);
|
||||
prev_wday = timeinfo.tm_wday;
|
||||
}
|
||||
|
||||
// TODO: Set an alarm at 0sec every 1 minute.
|
||||
vTaskDelay(pdMS_TO_TICKS(200));
|
||||
}
|
||||
}
|
||||
|
||||
esp_err_t service_clock_init(void) {
|
||||
if (xTaskCreate(clock_task, "SVC_CLK", TASK_SVC_CLK_STACK_SIZE, NULL, TASK_SVC_CLK_PRIORITY,
|
||||
&s_clock_task_handle) != pdTRUE) {
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
return ESP_OK;
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
#ifndef SERVICE_CLOCK_H
|
||||
#define SERVICE_CLOCK_H
|
||||
|
||||
#include "esp_system.h"
|
||||
|
||||
esp_err_t service_clock_init(void);
|
||||
|
||||
#endif
|
|
@ -0,0 +1,46 @@
|
|||
#include "service_dht.h"
|
||||
|
||||
#include "esp_log.h"
|
||||
#include "if_standby.h"
|
||||
#include "impl_dht.h"
|
||||
#include "task_config.h"
|
||||
|
||||
#define LOG_TAG "SERVICE_DHT"
|
||||
|
||||
static htu21d_t s_htu = {
|
||||
.cb =
|
||||
{
|
||||
.read_cb = impl_dht_i2c_read,
|
||||
.write_cb = impl_dht_i2c_write,
|
||||
.delay_cb = impl_dht_delay,
|
||||
},
|
||||
.user_data = NULL,
|
||||
};
|
||||
|
||||
static TaskHandle_t s_dht_task_handle;
|
||||
|
||||
void dht_task(void *pvParameters) {
|
||||
htu21d_result_t result;
|
||||
|
||||
for (;;) {
|
||||
while (htu21d_measure(&s_htu, &result) != HTU21D_OK) {
|
||||
vTaskDelay(pdMS_TO_TICKS(100));
|
||||
}
|
||||
|
||||
if_standby_component_update(IF_STANDBY_COMPONENT_TEMP, "%.2f", result.temperature);
|
||||
if_standby_component_update(IF_STANDBY_COMPONENT_HUMID, "%.2f", result.humidity);
|
||||
|
||||
vTaskDelay(pdMS_TO_TICKS(30000));
|
||||
}
|
||||
}
|
||||
|
||||
esp_err_t service_dht_init(void) {
|
||||
htu21d_init(&s_htu);
|
||||
|
||||
if (xTaskCreate(dht_task, "SVC_DHT", TASK_SVC_DHT_STACK_SIZE, NULL, TASK_SVC_DHT_PRIORITY, &s_dht_task_handle) !=
|
||||
pdTRUE) {
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
return ESP_OK;
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
#ifndef SERVICE_DHT_H
|
||||
#define SERVICE_DHT_H
|
||||
|
||||
#include "esp_system.h"
|
||||
|
||||
esp_err_t service_dht_init(void);
|
||||
|
||||
#endif
|
|
@ -0,0 +1,156 @@
|
|||
#include "esp_event.h"
|
||||
#include "esp_log.h"
|
||||
#include "esp_spi_flash.h"
|
||||
#include "esp_system.h"
|
||||
#include "esp_wifi.h"
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/queue.h"
|
||||
#include "freertos/task.h"
|
||||
#include "if_standby.h"
|
||||
#include "if_wifi.h"
|
||||
#include "nvs_flash.h"
|
||||
#include "sdkconfig.h"
|
||||
#include "task_config.h"
|
||||
|
||||
#define LOG_TAG "SVC_WIFI"
|
||||
|
||||
#define WIFI_SERVICE_SSID CONFIG_ESP_WIFI_SSID
|
||||
#define WIFI_SERVICE_PASS CONFIG_ESP_WIFI_PASSWORD
|
||||
#define WIFI_SERVICE_MAXIMUM_RETRY CONFIG_ESP_WIFI_MAXIMUM_RETRY
|
||||
|
||||
static TaskHandle_t s_service_wifi_task_handle;
|
||||
static QueueHandle_t s_service_wifi_event_queue;
|
||||
|
||||
static uint8_t s_retry_count = 0;
|
||||
|
||||
typedef enum {
|
||||
SERVICE_WIFI_EV_STATE_CHANGE,
|
||||
} service_wifi_event_t;
|
||||
|
||||
typedef enum {
|
||||
SERVICE_WIFI_STATE_DISABLED,
|
||||
SERVICE_WIFI_STATE_DPP,
|
||||
SERVICE_WIFI_STATE_CONNECTING,
|
||||
SERVICE_WIFI_STATE_CONNECTED,
|
||||
SERVICE_WIFI_STATE_IP_READY,
|
||||
} service_wifi_state_t;
|
||||
|
||||
typedef struct {
|
||||
service_wifi_event_t ev;
|
||||
void *payload;
|
||||
} service_wifi_request_t;
|
||||
|
||||
static esp_err_t service_wifi_update_state(service_wifi_state_t new_state) {
|
||||
service_wifi_request_t req = {
|
||||
.ev = SERVICE_WIFI_EV_STATE_CHANGE,
|
||||
.payload = (void *)new_state,
|
||||
};
|
||||
|
||||
if(xQueueSend(s_service_wifi_event_queue, &req, 0) != pdPASS) {
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
static void service_wifi_event_handler(void *arg, esp_event_base_t event_base, int32_t event_id, void *event_data) {
|
||||
if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_START) {
|
||||
esp_wifi_connect();
|
||||
} else if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_DISCONNECTED) {
|
||||
if (s_retry_count < WIFI_SERVICE_MAXIMUM_RETRY) {
|
||||
esp_wifi_connect();
|
||||
s_retry_count++;
|
||||
}
|
||||
} else if (event_base == IP_EVENT && event_id == IP_EVENT_STA_GOT_IP) {
|
||||
s_retry_count = 0;
|
||||
service_wifi_update_state(SERVICE_WIFI_STATE_IP_READY);
|
||||
}
|
||||
}
|
||||
|
||||
void service_wifi_task(void *pvParameters) {
|
||||
char wifi_ssid[32];
|
||||
char wifi_pass[32];
|
||||
|
||||
size_t wifi_length = 32;
|
||||
|
||||
uint8_t wifi_config_valid = 0;
|
||||
|
||||
nvs_handle_t n_handle;
|
||||
if (nvs_open("storage", NVS_READWRITE, &n_handle) != ESP_OK) {
|
||||
ESP_LOGE(LOG_TAG, "Failed to create NVS handle.");
|
||||
vTaskSuspend(NULL);
|
||||
}
|
||||
|
||||
// TODO: check WiFi storage length.
|
||||
if (nvs_get_str(n_handle, "u_wifi_ssid", wifi_ssid, &wifi_length) == ESP_OK) {
|
||||
if (nvs_get_str(n_handle, "u_wifi_pass", wifi_pass, &wifi_length) == ESP_OK) {
|
||||
wifi_config_valid = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (!wifi_config_valid) {
|
||||
if_standby_component_update(IF_STANDBY_COMPONENT_WIFI, "\U000F092D");
|
||||
}
|
||||
|
||||
wifi_config_t wifi_config = {
|
||||
.sta =
|
||||
{
|
||||
.ssid = WIFI_SERVICE_SSID,
|
||||
.password = WIFI_SERVICE_PASS,
|
||||
.threshold.authmode = WIFI_AUTH_WPA2_WPA3_PSK,
|
||||
.pmf_cfg =
|
||||
{
|
||||
.capable = true,
|
||||
.required = false,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA));
|
||||
ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_STA, &wifi_config));
|
||||
ESP_ERROR_CHECK(esp_wifi_start());
|
||||
|
||||
service_wifi_request_t request;
|
||||
for (;;) {
|
||||
if (xQueueReceive(s_service_wifi_event_queue, &request, portMAX_DELAY) == pdPASS) {
|
||||
if (request.ev == SERVICE_WIFI_EV_STATE_CHANGE) {
|
||||
service_wifi_state_t state = (service_wifi_state_t)request.payload;
|
||||
switch (state) {
|
||||
case SERVICE_WIFI_STATE_IP_READY:
|
||||
if_standby_component_update(IF_STANDBY_COMPONENT_WIFI, "\U000F0928");
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
esp_err_t service_wifi_init(void) {
|
||||
ESP_ERROR_CHECK(esp_netif_init());
|
||||
ESP_ERROR_CHECK(esp_event_loop_create_default());
|
||||
esp_netif_create_default_wifi_sta();
|
||||
|
||||
wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
|
||||
ESP_ERROR_CHECK(esp_wifi_init(&cfg));
|
||||
|
||||
ESP_ERROR_CHECK(esp_event_handler_register(WIFI_EVENT, ESP_EVENT_ANY_ID, service_wifi_event_handler, NULL));
|
||||
ESP_ERROR_CHECK(esp_event_handler_register(IP_EVENT, IP_EVENT_STA_GOT_IP, service_wifi_event_handler, NULL));
|
||||
|
||||
s_service_wifi_event_queue = xQueueCreate(2, sizeof(service_wifi_request_t));
|
||||
if (s_service_wifi_event_queue == NULL) {
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
if (xTaskCreate(service_wifi_task, "SVC_WIFI", TASK_SVC_WIFI_STACK_SIZE, NULL, TASK_SVC_WIFI_PRIORITY,
|
||||
&s_service_wifi_task_handle) != pdPASS) {
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t service_wifi_notify() {
|
||||
return ESP_OK;
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
#ifndef SERVICE_WIFI_H
|
||||
#define SERVICE_WIFI_H
|
||||
|
||||
#include "esp_system.h"
|
||||
|
||||
typedef enum {
|
||||
SERVICE_WIFI_NOTIFY_STANDBY_REFRESH,
|
||||
SERVICE_WIFI_NOTIFY_SETTINGS_REFRESH,
|
||||
} service_wifi_notify_t;
|
||||
|
||||
esp_err_t service_wifi_init(void);
|
||||
esp_err_t service_wifi_notify();
|
||||
|
||||
|
||||
#endif
|
|
@ -0,0 +1,12 @@
|
|||
# This file format is not compatible with CSV,
|
||||
# as comments are supported, whitespaces are trimmed.
|
||||
#
|
||||
# Name, Type, SubType, Offset, Size, Flags
|
||||
nvs, data, nvs, 0x9000, 0x4000,
|
||||
otadata, data, ota, 0xd000, 0x2000,
|
||||
phy_init, data, phy, 0xf000, 0x1000,
|
||||
factory, app, factory, 0x10000, 2M,
|
||||
ota_0, app, ota_0, 0x210000, 2M,
|
||||
ota_1, app, ota_1, 0x410000, 2M,
|
||||
nvs_keys, data, nvs_keys, 0x610000, 0x1000,
|
||||
spiffs, data, spiffs, 0x620000, 8M,
|
|
Loading…
Reference in New Issue