2023-07-02 13:18:44 +08:00
|
|
|
/*
|
2023-09-08 19:09:15 +08:00
|
|
|
* Copyright (c) 2023-2023, lihongquan
|
2023-07-02 13:18:44 +08:00
|
|
|
*
|
2023-09-08 19:09:15 +08:00
|
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
|
|
|
*
|
|
|
|
|
* Change Logs:
|
|
|
|
|
* Date Author Notes
|
|
|
|
|
* 2023-9-8 lihongquan add license declaration
|
2023-07-02 13:18:44 +08:00
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
#include <stdint.h>
|
|
|
|
|
#include "esp_log.h"
|
|
|
|
|
#include <errno.h>
|
2023-08-30 10:19:39 +08:00
|
|
|
#include <dirent.h>
|
2023-09-06 15:08:17 +08:00
|
|
|
#include <esp_wifi.h>
|
|
|
|
|
#include <esp_event.h>
|
|
|
|
|
#include <nvs_flash.h>
|
2023-07-02 13:18:44 +08:00
|
|
|
#include "freertos/FreeRTOS.h"
|
|
|
|
|
#include "freertos/task.h"
|
|
|
|
|
#include "sdkconfig.h"
|
2023-07-22 17:52:32 +08:00
|
|
|
#include "DAP_config.h"
|
|
|
|
|
#include "DAP.h"
|
2023-09-06 15:08:17 +08:00
|
|
|
#include "esp_netif.h"
|
2023-09-08 19:09:15 +08:00
|
|
|
#include "web_handler.h"
|
2023-09-06 15:08:17 +08:00
|
|
|
#include "esp_http_server.h"
|
2023-09-08 19:09:15 +08:00
|
|
|
#include "web_server.h"
|
2023-09-11 14:55:26 +08:00
|
|
|
#include "programmer.h"
|
2023-09-06 15:08:17 +08:00
|
|
|
#include "protocol_examples_common.h"
|
2023-10-14 16:08:01 +08:00
|
|
|
#include "driver/gpio.h"
|
2023-10-21 21:44:06 +08:00
|
|
|
#include "power_measure.h"
|
|
|
|
|
#include "buzz.h"
|
2023-09-06 15:08:17 +08:00
|
|
|
|
2024-12-24 10:45:27 +08:00
|
|
|
#include "M5Unified.h"
|
|
|
|
|
#include "M5GFX.h"
|
|
|
|
|
#include "lv_port_disp.h"
|
|
|
|
|
#include "lv_port_indev.h"
|
|
|
|
|
#include "lvgl.h"
|
|
|
|
|
#include "gui_guider.h"
|
2024-12-30 14:55:01 +08:00
|
|
|
#include "app_display_c_api.h"
|
2024-12-24 10:45:27 +08:00
|
|
|
|
2024-12-25 15:31:02 +08:00
|
|
|
#include <stdlib.h>
|
|
|
|
|
#include <stdio.h>
|
|
|
|
|
#include <string.h>
|
|
|
|
|
#include "esp_vfs.h"
|
|
|
|
|
#include "esp_vfs_fat.h"
|
|
|
|
|
#include "esp_system.h"
|
|
|
|
|
|
2024-12-30 14:55:01 +08:00
|
|
|
#include <sys/unistd.h>
|
|
|
|
|
#include <sys/stat.h>
|
|
|
|
|
#include "sdmmc_cmd.h"
|
|
|
|
|
#include "driver/sdmmc_host.h"
|
|
|
|
|
|
2024-12-31 17:28:18 +08:00
|
|
|
#include "main.h"
|
|
|
|
|
|
2024-12-13 01:26:39 +08:00
|
|
|
#define EXAMPLE_ESP_WIFI_SSID "ATOMS3R-DAP"
|
|
|
|
|
#define EXAMPLE_ESP_WIFI_PASS "12345678"
|
|
|
|
|
#define EXAMPLE_ESP_WIFI_CHANNEL 1
|
|
|
|
|
#define EXAMPLE_MAX_STA_CONN 1
|
|
|
|
|
|
2024-12-24 10:45:27 +08:00
|
|
|
#define EXAMPLE_LVGL_TICK_PERIOD_MS 2 /*!< LVGL tick period in ms */
|
|
|
|
|
#define EXAMPLE_LVGL_TASK_MAX_DELAY_MS 500
|
|
|
|
|
#define EXAMPLE_LVGL_TASK_MIN_DELAY_MS 1
|
|
|
|
|
#define EXAMPLE_LVGL_TASK_STACK_SIZE (8 * 1024)
|
|
|
|
|
#define EXAMPLE_LVGL_TASK_PRIORITY 2
|
|
|
|
|
|
|
|
|
|
#define LV_TICK_PERIOD_MS 2
|
|
|
|
|
|
2024-12-30 14:55:01 +08:00
|
|
|
#define SDSPI_CS GPIO_NUM_4
|
|
|
|
|
#define SDSPI_SCK GPIO_NUM_18
|
|
|
|
|
#define SDSPI_MOSI GPIO_NUM_23
|
|
|
|
|
#define SDSPI_MISO GPIO_NUM_38
|
|
|
|
|
|
|
|
|
|
#define EXAMPLE_MAX_CHAR_SIZE 64
|
|
|
|
|
|
2023-09-23 22:58:38 +08:00
|
|
|
static const char *TAG = "main";
|
|
|
|
|
static httpd_handle_t http_server = NULL;
|
|
|
|
|
TaskHandle_t kDAPTaskHandle = NULL;
|
2024-12-24 10:45:27 +08:00
|
|
|
SemaphoreHandle_t xGuiSemaphore;
|
|
|
|
|
TaskHandle_t task_lvgl_handle = NULL;
|
2024-12-25 15:31:02 +08:00
|
|
|
// Mount path for the partition
|
|
|
|
|
const char *base_path = "/data";
|
|
|
|
|
// Handle of the wear levelling library instance
|
|
|
|
|
static wl_handle_t s_wl_handle = WL_INVALID_HANDLE;
|
2024-12-31 17:28:18 +08:00
|
|
|
static storage_status_t storage_mount_status = STORAGE_SD;
|
|
|
|
|
static sdmmc_card_t *card;
|
2023-09-23 22:58:38 +08:00
|
|
|
|
2023-09-24 21:45:46 +08:00
|
|
|
extern "C" void tcp_server_task(void *pvParameters);
|
|
|
|
|
extern "C" void DAP_Thread(void *pvParameters);
|
|
|
|
|
|
2023-10-14 18:51:19 +08:00
|
|
|
extern "C" void ui_main(void);
|
|
|
|
|
|
2023-09-06 15:08:17 +08:00
|
|
|
static void disconnect_handler(void *arg, esp_event_base_t event_base, int32_t event_id, void *event_data)
|
|
|
|
|
{
|
2023-09-08 19:09:15 +08:00
|
|
|
web_server_stop((httpd_handle_t *)arg);
|
2023-09-06 15:08:17 +08:00
|
|
|
}
|
|
|
|
|
|
2023-09-08 19:09:15 +08:00
|
|
|
static void connect_handler(void *arg, esp_event_base_t event_base, int32_t event_id, void *event_data)
|
2023-09-06 15:08:17 +08:00
|
|
|
{
|
2023-09-08 19:09:15 +08:00
|
|
|
web_server_init((httpd_handle_t *)arg);
|
|
|
|
|
}
|
2023-09-06 15:08:17 +08:00
|
|
|
|
2024-12-31 17:28:18 +08:00
|
|
|
storage_status_t get_storage_status(void)
|
|
|
|
|
{
|
|
|
|
|
return storage_mount_status;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
sdmmc_card_t* get_sdcard_status(void)
|
|
|
|
|
{
|
|
|
|
|
return card;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const char* get_base_path(void)
|
|
|
|
|
{
|
|
|
|
|
return base_path;
|
|
|
|
|
}
|
|
|
|
|
|
2024-12-30 14:55:01 +08:00
|
|
|
static esp_err_t mount_flash_as_fat(void)
|
|
|
|
|
{
|
|
|
|
|
// To mount device we need name of device partition, define base_path
|
|
|
|
|
// and allow format partition in case if it is new one and was not formatted before
|
|
|
|
|
esp_vfs_fat_mount_config_t mount_config = {0};
|
|
|
|
|
mount_config.max_files = 4;
|
|
|
|
|
mount_config.format_if_mount_failed = false;
|
|
|
|
|
mount_config.allocation_unit_size = CONFIG_WL_SECTOR_SIZE;
|
|
|
|
|
|
|
|
|
|
esp_err_t err = esp_vfs_fat_spiflash_mount_rw_wl(base_path, "storage", &mount_config, &s_wl_handle);
|
|
|
|
|
if (err != ESP_OK) {
|
|
|
|
|
ESP_LOGE(TAG, "Failed to mount FATFS (%s)", esp_err_to_name(err));
|
|
|
|
|
return err;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Print FAT FS size information
|
|
|
|
|
uint64_t bytes_total, bytes_free;
|
|
|
|
|
esp_vfs_fat_info(base_path, &bytes_total, &bytes_free);
|
|
|
|
|
ESP_LOGI(TAG, "FAT FS: %" PRIu64 " kB total, %" PRIu64 " kB free", bytes_total / 1024, bytes_free / 1024);
|
|
|
|
|
|
|
|
|
|
return err;
|
|
|
|
|
}
|
|
|
|
|
|
2024-12-13 01:26:39 +08:00
|
|
|
extern "C" void wifi_init_softap(void)
|
|
|
|
|
{
|
|
|
|
|
ESP_ERROR_CHECK(esp_netif_init());
|
|
|
|
|
ESP_ERROR_CHECK(esp_event_loop_create_default());
|
|
|
|
|
esp_netif_create_default_wifi_ap();
|
|
|
|
|
|
|
|
|
|
wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
|
|
|
|
|
ESP_ERROR_CHECK(esp_wifi_init(&cfg));
|
|
|
|
|
|
2024-12-24 17:42:22 +08:00
|
|
|
ESP_ERROR_CHECK(esp_event_handler_register(WIFI_EVENT, WIFI_EVENT_AP_START, connect_handler, &http_server));
|
|
|
|
|
ESP_ERROR_CHECK(esp_event_handler_register(WIFI_EVENT, WIFI_EVENT_AP_STOP, disconnect_handler, &http_server));
|
2024-12-13 01:26:39 +08:00
|
|
|
|
|
|
|
|
wifi_config_t wifi_config;
|
|
|
|
|
esp_wifi_get_config(WIFI_IF_AP, &wifi_config);
|
|
|
|
|
// wifi_config.ap.ssid = EXAMPLE_ESP_WIFI_SSID;
|
|
|
|
|
memcpy(wifi_config.ap.ssid, EXAMPLE_ESP_WIFI_SSID, strlen(EXAMPLE_ESP_WIFI_SSID));
|
|
|
|
|
wifi_config.ap.ssid_len = strlen(EXAMPLE_ESP_WIFI_SSID);
|
|
|
|
|
wifi_config.ap.channel = EXAMPLE_ESP_WIFI_CHANNEL;
|
|
|
|
|
// wifi_config.ap.password = EXAMPLE_ESP_WIFI_PASS;
|
|
|
|
|
memcpy(wifi_config.ap.password, EXAMPLE_ESP_WIFI_PASS, strlen(EXAMPLE_ESP_WIFI_PASS));
|
|
|
|
|
wifi_config.ap.max_connection = EXAMPLE_MAX_STA_CONN;
|
|
|
|
|
wifi_config.ap.pmf_cfg.required = true;
|
|
|
|
|
|
|
|
|
|
ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_AP));
|
|
|
|
|
ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_AP, &wifi_config));
|
|
|
|
|
ESP_ERROR_CHECK(esp_wifi_start());
|
|
|
|
|
|
|
|
|
|
ESP_LOGI(TAG, "wifi_init_softap finished. SSID:%s password:%s channel:%d",
|
|
|
|
|
EXAMPLE_ESP_WIFI_SSID, EXAMPLE_ESP_WIFI_PASS, EXAMPLE_ESP_WIFI_CHANNEL);
|
|
|
|
|
}
|
|
|
|
|
|
2024-12-24 10:45:27 +08:00
|
|
|
bool example_lvgl_lock(int timeout_ms)
|
|
|
|
|
{
|
|
|
|
|
const TickType_t timeout_ticks = (timeout_ms == -1) ? portMAX_DELAY : pdMS_TO_TICKS(timeout_ms);
|
|
|
|
|
return xSemaphoreTake(xGuiSemaphore, timeout_ticks) == pdTRUE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void example_lvgl_unlock(void)
|
|
|
|
|
{
|
|
|
|
|
xSemaphoreGive(xGuiSemaphore);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void example_lvgl_port_task(void *arg)
|
|
|
|
|
{
|
|
|
|
|
uint32_t task_delay_ms = EXAMPLE_LVGL_TASK_MAX_DELAY_MS;
|
|
|
|
|
setup_ui(&guider_ui);
|
|
|
|
|
while (1) {
|
|
|
|
|
/* Lock the mutex due to the LVGL APIs are not thread-safe */
|
|
|
|
|
if (example_lvgl_lock(-1)) {
|
2024-12-30 15:15:48 +08:00
|
|
|
M5.update();
|
2024-12-24 10:45:27 +08:00
|
|
|
task_delay_ms = lv_timer_handler();
|
|
|
|
|
/* Release the mutex */
|
|
|
|
|
example_lvgl_unlock();
|
|
|
|
|
}
|
|
|
|
|
if (task_delay_ms > EXAMPLE_LVGL_TASK_MAX_DELAY_MS) {
|
|
|
|
|
task_delay_ms = EXAMPLE_LVGL_TASK_MAX_DELAY_MS;
|
|
|
|
|
} else if (task_delay_ms < EXAMPLE_LVGL_TASK_MIN_DELAY_MS) {
|
|
|
|
|
task_delay_ms = EXAMPLE_LVGL_TASK_MIN_DELAY_MS;
|
|
|
|
|
}
|
|
|
|
|
vTaskDelay(pdMS_TO_TICKS(task_delay_ms));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void lv_tick_task(void *arg)
|
|
|
|
|
{
|
|
|
|
|
(void)arg;
|
|
|
|
|
|
|
|
|
|
lv_tick_inc(LV_TICK_PERIOD_MS);
|
|
|
|
|
}
|
|
|
|
|
|
2023-09-24 21:45:46 +08:00
|
|
|
extern "C" void app_main(void)
|
2023-07-02 13:18:44 +08:00
|
|
|
{
|
2024-12-30 14:55:01 +08:00
|
|
|
esp_err_t ret;
|
|
|
|
|
|
2024-12-30 15:15:48 +08:00
|
|
|
M5.begin();
|
|
|
|
|
M5.Display.begin();
|
|
|
|
|
M5.Power.begin();
|
2024-12-31 14:12:45 +08:00
|
|
|
M5.Speaker.begin();
|
|
|
|
|
M5.Speaker.setVolume(100);
|
2023-09-14 23:13:38 +08:00
|
|
|
|
2023-09-06 15:08:17 +08:00
|
|
|
ESP_ERROR_CHECK(nvs_flash_init());
|
2024-12-25 15:31:02 +08:00
|
|
|
ESP_LOGI(TAG, "Mounting FAT filesystem");
|
2024-12-30 14:55:01 +08:00
|
|
|
ESP_LOGI(TAG, "Using SPI peripheral");
|
|
|
|
|
|
|
|
|
|
sdmmc_host_t host = SDSPI_HOST_DEFAULT();
|
|
|
|
|
|
|
|
|
|
host.max_freq_khz = 80000;
|
|
|
|
|
host.command_timeout_ms = 10000;
|
|
|
|
|
|
|
|
|
|
spi_bus_config_t bus_cfg = {
|
|
|
|
|
.mosi_io_num = SDSPI_MOSI,
|
|
|
|
|
.miso_io_num = SDSPI_MISO,
|
|
|
|
|
.sclk_io_num = SDSPI_SCK,
|
|
|
|
|
.quadwp_io_num = -1,
|
|
|
|
|
.quadhd_io_num = -1,
|
|
|
|
|
.max_transfer_sz = 80000,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
host.slot = VSPI_HOST;
|
|
|
|
|
|
|
|
|
|
sdspi_device_config_t slot_config = SDSPI_DEVICE_CONFIG_DEFAULT();
|
|
|
|
|
slot_config.gpio_cs = SDSPI_CS;
|
|
|
|
|
slot_config.host_id = (spi_host_device_t)host.slot;
|
|
|
|
|
|
|
|
|
|
// Options for mounting the filesystem.
|
|
|
|
|
// If format_if_mount_failed is set to true, SD card will be partitioned and
|
|
|
|
|
// formatted in case when mounting fails.
|
|
|
|
|
esp_vfs_fat_sdmmc_mount_config_t mount_config = {0};
|
|
|
|
|
mount_config.max_files = 5;
|
2024-12-25 15:31:02 +08:00
|
|
|
mount_config.format_if_mount_failed = false;
|
2024-12-30 14:55:01 +08:00
|
|
|
mount_config.allocation_unit_size = 16 * 1024;
|
2024-12-25 15:31:02 +08:00
|
|
|
|
2024-12-30 14:55:01 +08:00
|
|
|
ESP_LOGI(TAG, "Mounting SDSPI");
|
|
|
|
|
ret = esp_vfs_fat_sdspi_mount(base_path, &host, &slot_config, &mount_config, &card);
|
|
|
|
|
|
|
|
|
|
if (ret != ESP_OK) {
|
|
|
|
|
if (ret == ESP_FAIL) {
|
|
|
|
|
ESP_LOGE(TAG, "Failed to mount filesystem. "
|
|
|
|
|
"If you want the card to be formatted, set the EXAMPLE_FORMAT_IF_MOUNT_FAILED menuconfig option.");
|
|
|
|
|
} else {
|
|
|
|
|
ESP_LOGE(TAG, "Failed to initialize the card (%s). "
|
|
|
|
|
"Make sure SD card lines have pull-up resistors in place.", esp_err_to_name(ret));
|
|
|
|
|
}
|
|
|
|
|
ESP_LOGI(TAG, "Mounting flash fat");
|
|
|
|
|
ret = mount_flash_as_fat();
|
|
|
|
|
|
|
|
|
|
if (ret != ESP_OK) {
|
2024-12-31 17:28:18 +08:00
|
|
|
storage_mount_status = STORAGE_ERROR;
|
2024-12-30 14:55:01 +08:00
|
|
|
ESP_LOGE(TAG, "Failed mount flash fat");
|
|
|
|
|
}
|
|
|
|
|
else {
|
2024-12-31 17:28:18 +08:00
|
|
|
storage_mount_status = STORAGE_FLASH;
|
2024-12-30 14:55:01 +08:00
|
|
|
ESP_LOGI(TAG, "Flash fat Filesystem mounted");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else {
|
2024-12-31 17:28:18 +08:00
|
|
|
storage_mount_status = STORAGE_SD;
|
2024-12-30 14:55:01 +08:00
|
|
|
ESP_LOGI(TAG, "SDSPI Filesystem mounted");
|
|
|
|
|
// Card has been initialized, print its properties
|
|
|
|
|
sdmmc_card_print_info(stdout, card);
|
|
|
|
|
}
|
|
|
|
|
|
2024-12-13 01:26:39 +08:00
|
|
|
wifi_init_softap();
|
2023-08-30 10:19:39 +08:00
|
|
|
|
2023-07-23 08:37:58 +08:00
|
|
|
DAP_Setup();
|
2023-09-08 19:09:15 +08:00
|
|
|
|
2023-09-11 14:55:26 +08:00
|
|
|
programmer_init();
|
2023-09-23 22:58:38 +08:00
|
|
|
|
|
|
|
|
// DAP handle task
|
|
|
|
|
xTaskCreate(DAP_Thread, "DAP_Task", 2048, NULL, 10, &kDAPTaskHandle);
|
2023-10-14 18:51:19 +08:00
|
|
|
|
|
|
|
|
//ui main
|
2024-12-24 10:45:27 +08:00
|
|
|
lv_init();
|
|
|
|
|
lv_port_disp_init();
|
|
|
|
|
lv_port_indev_init();
|
|
|
|
|
ESP_LOGI(TAG, "Install LVGL tick timer");
|
|
|
|
|
xGuiSemaphore = xSemaphoreCreateMutex();
|
|
|
|
|
const esp_timer_create_args_t periodic_timer_args = {
|
|
|
|
|
.callback = &lv_tick_task, .name = "periodic_gui"};
|
|
|
|
|
esp_timer_handle_t periodic_timer;
|
|
|
|
|
ESP_ERROR_CHECK(esp_timer_create(&periodic_timer_args, &periodic_timer));
|
|
|
|
|
ESP_ERROR_CHECK(
|
|
|
|
|
esp_timer_start_periodic(periodic_timer, LV_TICK_PERIOD_MS * 1000));
|
|
|
|
|
|
|
|
|
|
xTaskCreate(example_lvgl_port_task, "LVGL", EXAMPLE_LVGL_TASK_STACK_SIZE, NULL, EXAMPLE_LVGL_TASK_PRIORITY,
|
|
|
|
|
&task_lvgl_handle);
|
2023-07-02 13:18:44 +08:00
|
|
|
}
|