Added automatic light sleep.
This commit is contained in:
parent
322fc1d9c6
commit
a7bacfd671
|
@ -8,6 +8,7 @@ idf_component_register(SRCS
|
|||
"app_lib_epd_impl.c"
|
||||
"app_lib_wifi_impl.c"
|
||||
"app_lib_fs_impl.c"
|
||||
"app_lib_pm_impl.c"
|
||||
"lib/gdew042t2_epd.c"
|
||||
"lib/ltc2941_battery.c"
|
||||
"lib/sht35_dht.c"
|
||||
|
|
|
@ -17,4 +17,89 @@ menu "Application Specific Configuration"
|
|||
default 5
|
||||
help
|
||||
Set the Maximum retry to avoid station reconnecting to the AP unlimited when the AP is really inexistent.
|
||||
|
||||
config APP_WIFI_LISTEN_INTERVAL
|
||||
int "WiFi listen interval"
|
||||
default 3
|
||||
help
|
||||
Interval for station to listen to beacon from AP. The unit of listen interval is one beacon interval.
|
||||
For example, if beacon interval is 100 ms and listen interval is 3, the interval for station to listen
|
||||
to beacon is 300 ms.
|
||||
|
||||
choice APP_POWER_SAVE_MODE
|
||||
prompt "power save mode"
|
||||
default APP_POWER_SAVE_MIN_MODEM
|
||||
help
|
||||
Power save mode for the esp32 to use. Modem sleep mode includes minimum and maximum power save modes.
|
||||
In minimum power save mode, station wakes up every DTIM to receive beacon. Broadcast data will not be
|
||||
lost because it is transmitted after DTIM. However, it can not save much more power if DTIM is short
|
||||
for DTIM is determined by AP.
|
||||
In maximum power save mode, station wakes up every listen interval to receive beacon. Broadcast data
|
||||
may be lost because station may be in sleep state at DTIM time. If listen interval is longer, more power
|
||||
is saved but broadcast data is more easy to lose.
|
||||
|
||||
config APP_POWER_SAVE_NONE
|
||||
bool "none"
|
||||
config APP_POWER_SAVE_MIN_MODEM
|
||||
bool "minimum modem"
|
||||
config APP_POWER_SAVE_MAX_MODEM
|
||||
bool "maximum modem"
|
||||
endchoice
|
||||
|
||||
|
||||
choice APP_MAX_CPU_FREQ
|
||||
prompt "Maximum CPU frequency"
|
||||
default APP_MAX_CPU_FREQ_80
|
||||
depends on PM_ENABLE
|
||||
help
|
||||
Maximum CPU frequency to use for dynamic frequency scaling.
|
||||
|
||||
config APP_MAX_CPU_FREQ_80
|
||||
bool "80 MHz"
|
||||
config APP_MAX_CPU_FREQ_160
|
||||
bool "160 MHz"
|
||||
config APP_MAX_CPU_FREQ_240
|
||||
bool "240 MHz"
|
||||
depends on IDF_TARGET_ESP32 || IDF_TARGET_ESP32S2 || IDF_TARGET_ESP32S3
|
||||
endchoice
|
||||
|
||||
config APP_MAX_CPU_FREQ_MHZ
|
||||
int
|
||||
default 80 if APP_MAX_CPU_FREQ_80
|
||||
default 160 if APP_MAX_CPU_FREQ_160
|
||||
default 240 if APP_MAX_CPU_FREQ_240
|
||||
|
||||
|
||||
choice APP_MIN_CPU_FREQ
|
||||
prompt "Minimum CPU frequency"
|
||||
default APP_MIN_CPU_FREQ_10M
|
||||
depends on PM_ENABLE
|
||||
help
|
||||
Minimum CPU frequency to use for dynamic frequency scaling.
|
||||
Should be set to XTAL frequency or XTAL frequency divided by integer.
|
||||
|
||||
config APP_MIN_CPU_FREQ_40M
|
||||
bool "40 MHz (use with 40MHz XTAL)"
|
||||
depends on IDF_TARGET_ESP32S2 || IDF_TARGET_ESP32C3 || ESP32_XTAL_FREQ_40 || ESP32_XTAL_FREQ_AUTO
|
||||
config APP_MIN_CPU_FREQ_20M
|
||||
bool "20 MHz (use with 40MHz XTAL)"
|
||||
depends on IDF_TARGET_ESP32S2 || IDF_TARGET_ESP32C3 || ESP32_XTAL_FREQ_40 || ESP32_XTAL_FREQ_AUTO
|
||||
config APP_MIN_CPU_FREQ_10M
|
||||
bool "10 MHz (use with 40MHz XTAL)"
|
||||
depends on IDF_TARGET_ESP32S2 || IDF_TARGET_ESP32C3 || ESP32_XTAL_FREQ_40 || ESP32_XTAL_FREQ_AUTO
|
||||
config APP_MIN_CPU_FREQ_26M
|
||||
bool "26 MHz (use with 26MHz XTAL)"
|
||||
depends on ESP32_XTAL_FREQ_26 || ESP32_XTAL_FREQ_AUTO
|
||||
config APP_MIN_CPU_FREQ_13M
|
||||
bool "13 MHz (use with 26MHz XTAL)"
|
||||
depends on ESP32_XTAL_FREQ_26 || ESP32_XTAL_FREQ_AUTO
|
||||
endchoice
|
||||
|
||||
config APP_MIN_CPU_FREQ_MHZ
|
||||
int
|
||||
default 40 if APP_MIN_CPU_FREQ_40M
|
||||
default 20 if APP_MIN_CPU_FREQ_20M
|
||||
default 10 if APP_MIN_CPU_FREQ_10M
|
||||
default 26 if APP_MIN_CPU_FREQ_26M
|
||||
default 13 if APP_MIN_CPU_FREQ_13M
|
||||
endmenu
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
#include <string.h>
|
||||
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
|
||||
|
@ -5,7 +7,7 @@
|
|||
|
||||
#include "app_lib_epd_impl.h"
|
||||
|
||||
#define MAXIMUM_XFER_SIZE 400 * 300 / 8 // FULL fb.
|
||||
#define MAXIMUM_XFER_SIZE 4000
|
||||
#define MAX_BUSY_POLL_COUNT 10
|
||||
|
||||
static void _spi_pre_transfere_callback(spi_transaction_t *txn) {
|
||||
|
@ -46,6 +48,7 @@ void app_lib_epd_impl_init(app_lib_epd_impl_t *impl) {
|
|||
.spics_io_num = BOARD_EPD_SPI_CS_PIN,
|
||||
.queue_size = 7,
|
||||
.pre_cb = _spi_pre_transfere_callback,
|
||||
.flags = SPI_DEVICE_HALFDUPLEX,
|
||||
};
|
||||
|
||||
ESP_ERROR_CHECK(spi_bus_initialize(SPI2_HOST, &bus_cfg, SPI_DMA_CH_AUTO));
|
||||
|
@ -102,15 +105,36 @@ gd_epd_042_ret_t app_lib_epd_impl_write_cmd(app_lib_epd_impl_t *impl, uint8_t *c
|
|||
|
||||
gd_epd_042_ret_t app_lib_epd_impl_write_data(app_lib_epd_impl_t *impl, uint8_t *data, uint32_t len) {
|
||||
esp_err_t ret;
|
||||
|
||||
uint8_t *dma_buffer = heap_caps_malloc(MAXIMUM_XFER_SIZE, MALLOC_CAP_DMA);
|
||||
if(dma_buffer == NULL) return EPD_ERR;
|
||||
|
||||
uint8_t has_partial = (len % MAXIMUM_XFER_SIZE ? 1 : 0);
|
||||
uint32_t txn_count = len / MAXIMUM_XFER_SIZE + has_partial;
|
||||
|
||||
spi_transaction_t txn = {
|
||||
.length = 8 * len,
|
||||
.tx_buffer = data,
|
||||
.user = (void *)1
|
||||
};
|
||||
|
||||
ret = spi_device_polling_transmit(impl->spi_handle, &txn);
|
||||
for(uint32_t i = 0; i < txn_count; i++) {
|
||||
uint16_t txn_bytes = MAXIMUM_XFER_SIZE;
|
||||
if(i == (txn_count - 1) && has_partial) {
|
||||
txn_bytes = len % MAXIMUM_XFER_SIZE;
|
||||
}
|
||||
|
||||
memcpy(dma_buffer, &data[i * MAXIMUM_XFER_SIZE], txn_bytes);
|
||||
|
||||
txn.length = 8 * txn_bytes;
|
||||
txn.tx_buffer = dma_buffer;
|
||||
|
||||
ret = spi_device_polling_transmit(impl->spi_handle, &txn);
|
||||
if(ret != ESP_OK) return EPD_ERR;
|
||||
}
|
||||
|
||||
free(dma_buffer);
|
||||
|
||||
return EPD_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,14 @@
|
|||
#include "esp_pm.h"
|
||||
|
||||
#define DVFS_MAXIMUM_FREQ CONFIG_APP_MAX_CPU_FREQ_MHZ
|
||||
#define DVFS_MINIMUM_FREQ CONFIG_APP_MIN_CPU_FREQ_MHZ
|
||||
|
||||
void app_lib_pm_init(void) {
|
||||
esp_pm_config_esp32s2_t pm_config = {
|
||||
.max_freq_mhz = DVFS_MAXIMUM_FREQ,
|
||||
.min_freq_mhz = DVFS_MINIMUM_FREQ,
|
||||
.light_sleep_enable = true
|
||||
};
|
||||
|
||||
ESP_ERROR_CHECK(esp_pm_configure(&pm_config));
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
#ifndef __APP_LIB_PM_IMPL_H
|
||||
#define __APP_LIB_PM_IMPL_H
|
||||
|
||||
void app_lib_pm_init(void);
|
||||
|
||||
#endif
|
|
@ -17,6 +17,21 @@ static const char *TAG = "APP_WIFI";
|
|||
#define APP_WIFI_SSID CONFIG_APP_WIFI_SSID
|
||||
#define APP_WIFI_PASS CONFIG_APP_WIFI_PASSWORD
|
||||
#define APP_WIFI_RETR CONFIG_APP_WIFI_MAXIMUM_RETRY
|
||||
#define APP_WIFI_INTV CONFIG_APP_WIFI_LISTEN_INTERVAL
|
||||
|
||||
#if CONFIG_APP_POWER_SAVE_MIN_MODEM
|
||||
#define DEFAULT_PS_MODE WIFI_PS_MIN_MODEM
|
||||
|
||||
#elif CONFIG_APP_POWER_SAVE_MAX_MODEM
|
||||
#define DEFAULT_PS_MODE WIFI_PS_MAX_MODEM
|
||||
|
||||
#elif CONFIG_APP_POWER_SAVE_NONE
|
||||
#define DEFAULT_PS_MODE WIFI_PS_NONE
|
||||
|
||||
#else
|
||||
#define DEFAULT_PS_MODE WIFI_PS_NONE
|
||||
|
||||
#endif
|
||||
|
||||
static void 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) {
|
||||
|
@ -38,7 +53,7 @@ static void event_handler(void *arg, esp_event_base_t event_base, int32_t event_
|
|||
}
|
||||
}
|
||||
|
||||
void app_lib_start_wifi(void) {
|
||||
void app_lib_init_wifi(void) {
|
||||
esp_err_t ret = nvs_flash_init();
|
||||
if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND) {
|
||||
ESP_ERROR_CHECK(nvs_flash_erase());
|
||||
|
@ -65,6 +80,7 @@ void app_lib_start_wifi(void) {
|
|||
.ssid = APP_WIFI_SSID,
|
||||
.password = APP_WIFI_PASS,
|
||||
.threshold.authmode = WIFI_AUTH_WPA2_PSK,
|
||||
.listen_interval = APP_WIFI_INTV,
|
||||
|
||||
.pmf_cfg = {
|
||||
.capable = true,
|
||||
|
@ -75,5 +91,12 @@ void app_lib_start_wifi(void) {
|
|||
|
||||
ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA));
|
||||
ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_STA, &wifi_config));
|
||||
}
|
||||
|
||||
void app_lib_start_wifi(void) {
|
||||
ESP_ERROR_CHECK(esp_wifi_start());
|
||||
}
|
||||
|
||||
void app_lib_stop_wifi(void) {
|
||||
ESP_ERROR_CHECK(esp_wifi_stop());
|
||||
}
|
|
@ -10,6 +10,8 @@ extern EventGroupHandle_t g_wifi_event_group;
|
|||
#define WIFI_CONNECTED_BIT BIT0
|
||||
#define WIFI_ERROR_BIT BIT1
|
||||
|
||||
void app_lib_init_wifi(void);
|
||||
void app_lib_start_wifi(void);
|
||||
void app_lib_stop_wifi(void);
|
||||
|
||||
#endif
|
|
@ -0,0 +1,20 @@
|
|||
#ifndef __APP_TASK_H
|
||||
#define __APP_TASK_H
|
||||
|
||||
#include "esp_sleep.h"
|
||||
|
||||
typedef struct {
|
||||
esp_sleep_source_t wakeup_source;
|
||||
void *user_params;
|
||||
} app_task_params_t;
|
||||
|
||||
void vTaskLEDs(void *pvParameters);
|
||||
extern TaskHandle_t xTaskLEDsHandle;
|
||||
|
||||
void vTasBatteryExample(void *pvParameters);
|
||||
extern TaskHandle_t xTaskBatteryExampleHandle;
|
||||
|
||||
extern TaskHandle_t xTaskEPDExampleHandle;
|
||||
void vTaskEPDExample(void *pvParameters);
|
||||
|
||||
#endif
|
|
@ -44,6 +44,6 @@ void vTasBatteryExample(void *pvParameters) {
|
|||
|
||||
ESP_LOGI(TAG, "Capacity: %04.2fmAh, Charge: %03.2f%%", mah, percentage);
|
||||
|
||||
vTaskDelay(pdMS_TO_TICKS(5000));
|
||||
vTaskDelay(pdMS_TO_TICKS(30000));
|
||||
}
|
||||
}
|
|
@ -4,9 +4,13 @@
|
|||
#include "freertos/task.h"
|
||||
#include "freertos/queue.h"
|
||||
|
||||
#include "esp_log.h"
|
||||
|
||||
#include "app_lib_epd_impl.h"
|
||||
|
||||
static uint8_t frame_data[2][15000];
|
||||
static uint8_t *frame_data[2];
|
||||
|
||||
static const char *TAG = "TASK_EPD";
|
||||
|
||||
extern const unsigned char pixiv_82311703_p0_4indexed[];
|
||||
extern const unsigned char pixiv_57852730_p0_4indexed[];
|
||||
|
@ -19,6 +23,16 @@ extern const unsigned char pixiv_57852730_p0_4indexed[];
|
|||
|
||||
TaskHandle_t xTaskEPDExampleHandle = NULL;
|
||||
void vTaskEPDExample(void *pvParameters) {
|
||||
|
||||
ESP_LOGI(TAG, "EPD task started.");
|
||||
|
||||
frame_data[0] = malloc(15000);
|
||||
frame_data[1] = malloc(15000);
|
||||
if(frame_data[0] == NULL || frame_data[1] == NULL) {
|
||||
ESP_LOGE(TAG, "Failed to allocate memory on heap.");
|
||||
vTaskSuspend(NULL);
|
||||
}
|
||||
|
||||
app_lib_epd_impl_t epd_impl = {0};
|
||||
|
||||
gd_epd_042_t epd = {
|
||||
|
@ -40,11 +54,15 @@ void vTaskEPDExample(void *pvParameters) {
|
|||
frame_data[1][i] = ARRAY_EVEN_BYTES(pixiv_57852730_p0_4indexed, i);
|
||||
}
|
||||
|
||||
ESP_LOGI(TAG, "EPD frame constructed.");
|
||||
|
||||
gd_epd_042_load(&epd, frame_data[0], frame_data[1]);
|
||||
gd_epd_042_update(&epd);
|
||||
gd_epd_042_deepsleep(&epd);
|
||||
|
||||
ESP_LOGI(TAG, "EPD task finished.");
|
||||
|
||||
for(;;) {
|
||||
vTaskDelay(pdMS_TO_TICKS(10000));
|
||||
vTaskSuspend(NULL);
|
||||
}
|
||||
}
|
|
@ -105,7 +105,13 @@ void vTaskLEDs(void *pvParameters) {
|
|||
ledc_channels[i].channel, LEDC_FADE_NO_WAIT);
|
||||
}
|
||||
current_phase++;
|
||||
if(current_phase == 8) current_phase = 0;
|
||||
if(current_phase == 8) {
|
||||
for(uint8_t i = 0; i < 4; i++) {
|
||||
ledc_set_duty(ledc_channels[i].speed_mode, ledc_channels[i].channel, 0);
|
||||
}
|
||||
|
||||
vTaskSuspend(NULL);
|
||||
}
|
||||
vTaskDelay(pdMS_TO_TICKS(BREATHE_LED_CYCLE));
|
||||
}
|
||||
}
|
36
main/main.c
36
main/main.c
|
@ -8,17 +8,11 @@
|
|||
|
||||
#include "app_lib_wifi_impl.h"
|
||||
#include "app_lib_fs_impl.h"
|
||||
#include "app_lib_pm_impl.h"
|
||||
|
||||
#include "user_board.h"
|
||||
|
||||
void vTaskLEDs(void *pvParameters);
|
||||
extern TaskHandle_t xTaskLEDsHandle;
|
||||
|
||||
void vTasBatteryExample(void *pvParameters);
|
||||
extern TaskHandle_t xTaskBatteryExampleHandle;
|
||||
|
||||
extern TaskHandle_t xTaskEPDExampleHandle;
|
||||
void vTaskEPDExample(void *pvParameters);
|
||||
#include "app_task.h"
|
||||
|
||||
void app_lib_i2c_system_init(void);
|
||||
|
||||
|
@ -27,15 +21,35 @@ static const char *TAG = "APP_MAIN";
|
|||
void app_main(void) {
|
||||
// Init system peripherals.
|
||||
app_lib_i2c_system_init();
|
||||
|
||||
//app_lib_pm_init();
|
||||
|
||||
app_lib_init_wifi();
|
||||
app_lib_start_wifi();
|
||||
|
||||
app_lib_fs_init();
|
||||
|
||||
ESP_LOGI(TAG, "System initialized, starting tasks.");
|
||||
|
||||
// Init tasks
|
||||
xTaskCreate(vTaskLEDs, "TASK_LEDs", 1024, NULL, 4, &xTaskLEDsHandle);
|
||||
xTaskCreate(vTasBatteryExample, "TASK_BAT", 2048, NULL, 4, &xTaskBatteryExampleHandle);
|
||||
xTaskCreate(vTaskEPDExample, "TASK_EPD", 2048, NULL, 4, &xTaskEPDExampleHandle);
|
||||
if(xTaskCreate(vTaskLEDs, "TASK_LEDs", 1024, NULL, 4, &xTaskLEDsHandle) != pdPASS) {
|
||||
ESP_LOGE(TAG, "Task LED creation failed.");
|
||||
for(;;) {
|
||||
vTaskSuspend(NULL);
|
||||
}
|
||||
}
|
||||
if(xTaskCreate(vTasBatteryExample, "TASK_BAT", 2048, NULL, 4, &xTaskBatteryExampleHandle) != pdPASS) {
|
||||
ESP_LOGE(TAG, "Task BAT creation failed.");
|
||||
for(;;) {
|
||||
vTaskSuspend(NULL);
|
||||
}
|
||||
}
|
||||
if(xTaskCreate(vTaskEPDExample, "TASK_EPD", 2048, NULL, 4, &xTaskEPDExampleHandle) != pdPASS) {
|
||||
ESP_LOGE(TAG, "Task EPD creation failed.");
|
||||
for(;;) {
|
||||
vTaskSuspend(NULL);
|
||||
}
|
||||
}
|
||||
|
||||
ESP_LOGI(TAG, "Task created, suspending current task.");
|
||||
|
||||
|
|
Loading…
Reference in New Issue