mirror of
https://github.com/m5stack/ESP-Claw.git
synced 2026-05-20 11:51:49 -07:00
541 lines
14 KiB
C
541 lines
14 KiB
C
/*
|
|
* SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD
|
|
*
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
*/
|
|
#include "app_lua_modules.h"
|
|
|
|
#include <ctype.h>
|
|
#include <stdbool.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
|
|
#include "esp_err.h"
|
|
#include "esp_log.h"
|
|
|
|
#if CONFIG_APP_CLAW_LUA_MODULE_DELAY
|
|
#include "lua_module_delay.h"
|
|
#endif
|
|
#if CONFIG_APP_CLAW_LUA_MODULE_CAPABILITY
|
|
#include "lua_module_capability.h"
|
|
#endif
|
|
#if CONFIG_APP_CLAW_LUA_MODULE_ADC
|
|
#include "lua_module_adc.h"
|
|
#endif
|
|
#if CONFIG_APP_CLAW_LUA_MODULE_EVENT_PUBLISHER
|
|
#include "lua_module_event_publisher.h"
|
|
#endif
|
|
#if CONFIG_APP_CLAW_LUA_MODULE_GPIO
|
|
#include "lua_module_gpio.h"
|
|
#endif
|
|
#if CONFIG_APP_CLAW_LUA_MODULE_I2C
|
|
#include "lua_module_i2c.h"
|
|
#endif
|
|
#if CONFIG_APP_CLAW_LUA_MODULE_LED_STRIP
|
|
#include "lua_module_led_strip.h"
|
|
#endif
|
|
#if CONFIG_APP_CLAW_LUA_MODULE_STORAGE
|
|
#include "lua_module_storage.h"
|
|
#endif
|
|
#if CONFIG_APP_CLAW_LUA_MODULE_BUTTON
|
|
#include "lua_module_button.h"
|
|
#endif
|
|
#if CONFIG_APP_CLAW_LUA_MODULE_ESP_HEAP
|
|
#include "lua_module_esp_heap.h"
|
|
#endif
|
|
#if CONFIG_APP_CLAW_LUA_MODULE_SYSTEM
|
|
#include "lua_module_system.h"
|
|
#endif
|
|
#if CONFIG_APP_CLAW_LUA_MODULE_BOARD_MANAGER
|
|
#include "lua_module_board_manager.h"
|
|
#endif
|
|
#if CONFIG_APP_CLAW_LUA_MODULE_IMU
|
|
#include "lua_module_imu.h"
|
|
#endif
|
|
#if CONFIG_APP_CLAW_LUA_MODULE_TOUCH
|
|
#include "lua_module_touch.h"
|
|
#endif
|
|
#if CONFIG_APP_CLAW_LUA_MODULE_MCPWM
|
|
#include "lua_module_mcpwm.h"
|
|
#endif
|
|
#if CONFIG_APP_CLAW_LUA_MODULE_UART
|
|
#include "lua_module_uart.h"
|
|
#endif
|
|
|
|
#if CONFIG_APP_CLAW_LUA_MODULE_AUDIO && defined(CONFIG_ESP_BOARD_DEV_AUDIO_CODEC_SUPPORT)
|
|
#include "lua_module_audio.h"
|
|
#endif
|
|
#if CONFIG_APP_CLAW_LUA_MODULE_DISPLAY
|
|
#include "lua_module_display.h"
|
|
#endif
|
|
#if CONFIG_APP_CLAW_LUA_MODULE_LCD_TOUCH && defined(CONFIG_ESP_BOARD_DEV_LCD_TOUCH_I2C_SUPPORT)
|
|
#include "lua_module_lcd_touch.h"
|
|
#endif
|
|
#if CONFIG_APP_CLAW_LUA_MODULE_CAMERA && defined(CONFIG_ESP_BOARD_DEV_CAMERA_SUPPORT)
|
|
#include "lua_module_camera.h"
|
|
#endif
|
|
|
|
static const char *TAG = "app_lua_modules";
|
|
|
|
typedef esp_err_t (*app_lua_module_register_fn)(const char *fatfs_base_path);
|
|
|
|
typedef struct {
|
|
const char *module_id;
|
|
const char *display_name;
|
|
app_lua_module_register_fn reg;
|
|
} app_lua_module_entry_t;
|
|
|
|
static bool app_lua_modules_config_empty(const char *value)
|
|
{
|
|
size_t i;
|
|
|
|
if (!value) {
|
|
return true;
|
|
}
|
|
|
|
for (i = 0; value[i]; i++) {
|
|
if (!isspace((unsigned char)value[i])) {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
static char *app_lua_trim_token(char *token)
|
|
{
|
|
char *end;
|
|
|
|
if (!token) {
|
|
return NULL;
|
|
}
|
|
|
|
while (*token && isspace((unsigned char)*token)) {
|
|
token++;
|
|
}
|
|
|
|
end = token + strlen(token);
|
|
while (end > token && isspace((unsigned char)end[-1])) {
|
|
end--;
|
|
}
|
|
*end = '\0';
|
|
return token;
|
|
}
|
|
|
|
static int app_lua_find_entry(const app_lua_module_entry_t *entries,
|
|
size_t count,
|
|
const char *module_id)
|
|
{
|
|
size_t i;
|
|
|
|
if (!entries || !module_id || !module_id[0]) {
|
|
return -1;
|
|
}
|
|
|
|
for (i = 0; i < count; i++) {
|
|
if (entries[i].module_id && strcmp(entries[i].module_id, module_id) == 0) {
|
|
return (int)i;
|
|
}
|
|
}
|
|
|
|
return -1;
|
|
}
|
|
|
|
static esp_err_t app_lua_build_module_map(const char *configured_modules,
|
|
const app_lua_module_entry_t *entries,
|
|
size_t entry_count,
|
|
bool *selected_map)
|
|
{
|
|
char *modules_copy = NULL;
|
|
char *saveptr = NULL;
|
|
char *token = NULL;
|
|
size_t i;
|
|
|
|
if (!entries || !selected_map) {
|
|
return ESP_ERR_INVALID_ARG;
|
|
}
|
|
|
|
memset(selected_map, 0, entry_count * sizeof(selected_map[0]));
|
|
|
|
if (app_lua_modules_config_empty(configured_modules)) {
|
|
for (i = 0; i < entry_count; i++) {
|
|
selected_map[i] = true;
|
|
}
|
|
return ESP_OK;
|
|
}
|
|
|
|
modules_copy = malloc(strlen(configured_modules) + 1);
|
|
if (!modules_copy) {
|
|
return ESP_ERR_NO_MEM;
|
|
}
|
|
memcpy(modules_copy, configured_modules, strlen(configured_modules) + 1);
|
|
|
|
for (token = strtok_r(modules_copy, ",", &saveptr);
|
|
token;
|
|
token = strtok_r(NULL, ",", &saveptr)) {
|
|
char *trimmed = app_lua_trim_token(token);
|
|
int index;
|
|
|
|
if (!trimmed || !trimmed[0]) {
|
|
continue;
|
|
}
|
|
|
|
if (strcmp(trimmed, "__none__") == 0 || strcmp(trimmed, "none") == 0) {
|
|
continue;
|
|
}
|
|
|
|
index = app_lua_find_entry(entries, entry_count, trimmed);
|
|
if (index < 0) {
|
|
ESP_LOGW(TAG, "Ignoring unknown or unavailable Lua module: %s", trimmed);
|
|
continue;
|
|
}
|
|
|
|
selected_map[index] = true;
|
|
}
|
|
|
|
free(modules_copy);
|
|
return ESP_OK;
|
|
}
|
|
|
|
#if CONFIG_APP_CLAW_LUA_MODULE_DELAY
|
|
static esp_err_t app_lua_register_delay(const char *fatfs_base_path)
|
|
{
|
|
(void)fatfs_base_path;
|
|
return lua_module_delay_register();
|
|
}
|
|
#endif
|
|
|
|
#if CONFIG_APP_CLAW_LUA_MODULE_CAPABILITY
|
|
static esp_err_t app_lua_register_capability(const char *fatfs_base_path)
|
|
{
|
|
(void)fatfs_base_path;
|
|
return lua_module_capability_register();
|
|
}
|
|
#endif
|
|
|
|
#if CONFIG_APP_CLAW_LUA_MODULE_ADC
|
|
static esp_err_t app_lua_register_adc(const char *fatfs_base_path)
|
|
{
|
|
(void)fatfs_base_path;
|
|
return lua_module_adc_register();
|
|
}
|
|
#endif
|
|
|
|
#if CONFIG_APP_CLAW_LUA_MODULE_EVENT_PUBLISHER
|
|
static esp_err_t app_lua_register_event_publisher(const char *fatfs_base_path)
|
|
{
|
|
(void)fatfs_base_path;
|
|
return lua_module_event_publisher_register();
|
|
}
|
|
#endif
|
|
|
|
#if CONFIG_APP_CLAW_LUA_MODULE_GPIO
|
|
static esp_err_t app_lua_register_gpio(const char *fatfs_base_path)
|
|
{
|
|
(void)fatfs_base_path;
|
|
return lua_module_gpio_register();
|
|
}
|
|
#endif
|
|
|
|
#if CONFIG_APP_CLAW_LUA_MODULE_I2C
|
|
static esp_err_t app_lua_register_i2c(const char *fatfs_base_path)
|
|
{
|
|
(void)fatfs_base_path;
|
|
return lua_module_i2c_register();
|
|
}
|
|
#endif
|
|
|
|
#if CONFIG_APP_CLAW_LUA_MODULE_LED_STRIP
|
|
static esp_err_t app_lua_register_led_strip(const char *fatfs_base_path)
|
|
{
|
|
(void)fatfs_base_path;
|
|
return lua_module_led_strip_register();
|
|
}
|
|
#endif
|
|
|
|
#if CONFIG_APP_CLAW_LUA_MODULE_STORAGE
|
|
static esp_err_t app_lua_register_storage(const char *fatfs_base_path)
|
|
{
|
|
return lua_module_storage_register(fatfs_base_path);
|
|
}
|
|
#endif
|
|
|
|
#if CONFIG_APP_CLAW_LUA_MODULE_BUTTON
|
|
static esp_err_t app_lua_register_button(const char *fatfs_base_path)
|
|
{
|
|
(void)fatfs_base_path;
|
|
return lua_module_button_register();
|
|
}
|
|
#endif
|
|
|
|
#if CONFIG_APP_CLAW_LUA_MODULE_ESP_HEAP
|
|
static esp_err_t app_lua_register_esp_heap(const char *fatfs_base_path)
|
|
{
|
|
(void)fatfs_base_path;
|
|
return lua_module_esp_heap_register();
|
|
}
|
|
#endif
|
|
|
|
#if CONFIG_APP_CLAW_LUA_MODULE_SYSTEM
|
|
static esp_err_t app_lua_register_system(const char *fatfs_base_path)
|
|
{
|
|
(void)fatfs_base_path;
|
|
return lua_module_system_register();
|
|
}
|
|
#endif
|
|
|
|
#if CONFIG_APP_CLAW_LUA_MODULE_BOARD_MANAGER
|
|
static esp_err_t app_lua_register_board_manager(const char *fatfs_base_path)
|
|
{
|
|
(void)fatfs_base_path;
|
|
return lua_module_board_manager_register();
|
|
}
|
|
#endif
|
|
|
|
#if CONFIG_APP_CLAW_LUA_MODULE_IMU
|
|
static esp_err_t app_lua_register_imu(const char *fatfs_base_path)
|
|
{
|
|
(void)fatfs_base_path;
|
|
return lua_module_imu_register();
|
|
}
|
|
#endif
|
|
|
|
#if CONFIG_APP_CLAW_LUA_MODULE_TOUCH
|
|
static esp_err_t app_lua_register_touch(const char *fatfs_base_path)
|
|
{
|
|
(void)fatfs_base_path;
|
|
return lua_module_touch_register();
|
|
}
|
|
#endif
|
|
|
|
#if CONFIG_APP_CLAW_LUA_MODULE_MCPWM
|
|
static esp_err_t app_lua_register_mcpwm(const char *fatfs_base_path)
|
|
{
|
|
(void)fatfs_base_path;
|
|
return lua_module_mcpwm_register();
|
|
}
|
|
#endif
|
|
|
|
#if CONFIG_APP_CLAW_LUA_MODULE_UART
|
|
static esp_err_t app_lua_register_uart(const char *fatfs_base_path)
|
|
{
|
|
(void)fatfs_base_path;
|
|
return lua_module_uart_register();
|
|
}
|
|
#endif
|
|
|
|
#if CONFIG_APP_CLAW_LUA_MODULE_AUDIO && defined(CONFIG_ESP_BOARD_DEV_AUDIO_CODEC_SUPPORT)
|
|
static esp_err_t app_lua_register_audio(const char *fatfs_base_path)
|
|
{
|
|
(void)fatfs_base_path;
|
|
return lua_module_audio_register();
|
|
}
|
|
#endif
|
|
|
|
#if CONFIG_APP_CLAW_LUA_MODULE_DISPLAY
|
|
static esp_err_t app_lua_register_display(const char *fatfs_base_path)
|
|
{
|
|
(void)fatfs_base_path;
|
|
return lua_module_display_register();
|
|
}
|
|
#endif
|
|
|
|
#if CONFIG_APP_CLAW_LUA_MODULE_LCD_TOUCH && defined(CONFIG_ESP_BOARD_DEV_LCD_TOUCH_I2C_SUPPORT)
|
|
static esp_err_t app_lua_register_lcd_touch(const char *fatfs_base_path)
|
|
{
|
|
(void)fatfs_base_path;
|
|
return lua_module_lcd_touch_register();
|
|
}
|
|
#endif
|
|
|
|
#if CONFIG_APP_CLAW_LUA_MODULE_CAMERA && defined(CONFIG_ESP_BOARD_DEV_CAMERA_SUPPORT)
|
|
static esp_err_t app_lua_register_camera(const char *fatfs_base_path)
|
|
{
|
|
(void)fatfs_base_path;
|
|
return lua_module_camera_register();
|
|
}
|
|
#endif
|
|
|
|
static const app_lua_module_entry_t s_lua_module_entries[] = {
|
|
#if CONFIG_APP_CLAW_LUA_MODULE_ADC
|
|
{ "adc", "ADC", app_lua_register_adc },
|
|
#endif
|
|
#if CONFIG_APP_CLAW_LUA_MODULE_CAPABILITY
|
|
{ "capability", "Capability", app_lua_register_capability },
|
|
#endif
|
|
#if CONFIG_APP_CLAW_LUA_MODULE_DELAY
|
|
{ "delay", "Delay", app_lua_register_delay },
|
|
#endif
|
|
#if CONFIG_APP_CLAW_LUA_MODULE_STORAGE
|
|
{ "storage", "Storage", app_lua_register_storage },
|
|
#endif
|
|
#if CONFIG_APP_CLAW_LUA_MODULE_GPIO
|
|
{ "gpio", "GPIO", app_lua_register_gpio },
|
|
#endif
|
|
#if CONFIG_APP_CLAW_LUA_MODULE_I2C
|
|
{ "i2c", "I2C", app_lua_register_i2c },
|
|
#endif
|
|
#if CONFIG_APP_CLAW_LUA_MODULE_LED_STRIP
|
|
{ "led_strip", "LED Strip", app_lua_register_led_strip },
|
|
#endif
|
|
#if CONFIG_APP_CLAW_LUA_MODULE_AUDIO && defined(CONFIG_ESP_BOARD_DEV_AUDIO_CODEC_SUPPORT)
|
|
{ "audio", "Audio", app_lua_register_audio },
|
|
#endif
|
|
#if CONFIG_APP_CLAW_LUA_MODULE_BUTTON
|
|
{ "button", "Button", app_lua_register_button },
|
|
#endif
|
|
#if CONFIG_APP_CLAW_LUA_MODULE_DISPLAY
|
|
{ "display", "Display", app_lua_register_display },
|
|
#endif
|
|
#if CONFIG_APP_CLAW_LUA_MODULE_BOARD_MANAGER
|
|
{ "board_manager", "Board Manager", app_lua_register_board_manager },
|
|
#endif
|
|
#if CONFIG_APP_CLAW_LUA_MODULE_IMU
|
|
{ "imu", "IMU", app_lua_register_imu },
|
|
#endif
|
|
#if CONFIG_APP_CLAW_LUA_MODULE_TOUCH
|
|
{ "touch", "Touch", app_lua_register_touch },
|
|
#endif
|
|
#if CONFIG_APP_CLAW_LUA_MODULE_LCD_TOUCH && defined(CONFIG_ESP_BOARD_DEV_LCD_TOUCH_I2C_SUPPORT)
|
|
{ "lcd_touch", "LCD Touch", app_lua_register_lcd_touch },
|
|
#endif
|
|
#if CONFIG_APP_CLAW_LUA_MODULE_CAMERA && defined(CONFIG_ESP_BOARD_DEV_CAMERA_SUPPORT)
|
|
{ "camera", "Camera", app_lua_register_camera },
|
|
#endif
|
|
#if CONFIG_APP_CLAW_LUA_MODULE_ESP_HEAP
|
|
{ "esp_heap", "ESP Heap", app_lua_register_esp_heap },
|
|
#endif
|
|
#if CONFIG_APP_CLAW_LUA_MODULE_SYSTEM
|
|
{ "system", "System", app_lua_register_system },
|
|
#endif
|
|
#if CONFIG_APP_CLAW_LUA_MODULE_MCPWM
|
|
{ "mcpwm", "MCPWM", app_lua_register_mcpwm },
|
|
#endif
|
|
#if CONFIG_APP_CLAW_LUA_MODULE_UART
|
|
{ "uart", "UART", app_lua_register_uart },
|
|
#endif
|
|
#if CONFIG_APP_CLAW_LUA_MODULE_EVENT_PUBLISHER
|
|
{ "event_publisher", "Event Publisher", app_lua_register_event_publisher },
|
|
#endif
|
|
};
|
|
|
|
static const app_lua_module_info_t s_lua_module_infos[] = {
|
|
#if CONFIG_APP_CLAW_LUA_MODULE_ADC
|
|
{ "adc", "ADC" },
|
|
#endif
|
|
#if CONFIG_APP_CLAW_LUA_MODULE_CAPABILITY
|
|
{ "capability", "Capability" },
|
|
#endif
|
|
#if CONFIG_APP_CLAW_LUA_MODULE_DELAY
|
|
{ "delay", "Delay" },
|
|
#endif
|
|
#if CONFIG_APP_CLAW_LUA_MODULE_STORAGE
|
|
{ "storage", "Storage" },
|
|
#endif
|
|
#if CONFIG_APP_CLAW_LUA_MODULE_GPIO
|
|
{ "gpio", "GPIO" },
|
|
#endif
|
|
#if CONFIG_APP_CLAW_LUA_MODULE_I2C
|
|
{ "i2c", "I2C" },
|
|
#endif
|
|
#if CONFIG_APP_CLAW_LUA_MODULE_LED_STRIP
|
|
{ "led_strip", "LED Strip" },
|
|
#endif
|
|
#if CONFIG_APP_CLAW_LUA_MODULE_AUDIO && defined(CONFIG_ESP_BOARD_DEV_AUDIO_CODEC_SUPPORT)
|
|
{ "audio", "Audio" },
|
|
#endif
|
|
#if CONFIG_APP_CLAW_LUA_MODULE_BUTTON
|
|
{ "button", "Button" },
|
|
#endif
|
|
#if CONFIG_APP_CLAW_LUA_MODULE_DISPLAY
|
|
{ "display", "Display" },
|
|
#endif
|
|
#if CONFIG_APP_CLAW_LUA_MODULE_BOARD_MANAGER
|
|
{ "board_manager", "Board Manager" },
|
|
#endif
|
|
#if CONFIG_APP_CLAW_LUA_MODULE_IMU
|
|
{ "imu", "IMU" },
|
|
#endif
|
|
#if CONFIG_APP_CLAW_LUA_MODULE_TOUCH
|
|
{ "touch", "Touch" },
|
|
#endif
|
|
#if CONFIG_APP_CLAW_LUA_MODULE_LCD_TOUCH && defined(CONFIG_ESP_BOARD_DEV_LCD_TOUCH_I2C_SUPPORT)
|
|
{ "lcd_touch", "LCD Touch" },
|
|
#endif
|
|
#if CONFIG_APP_CLAW_LUA_MODULE_CAMERA && defined(CONFIG_ESP_BOARD_DEV_CAMERA_SUPPORT)
|
|
{ "camera", "Camera" },
|
|
#endif
|
|
#if CONFIG_APP_CLAW_LUA_MODULE_ESP_HEAP
|
|
{ "esp_heap", "ESP Heap" },
|
|
#endif
|
|
#if CONFIG_APP_CLAW_LUA_MODULE_SYSTEM
|
|
{ "system", "System" },
|
|
#endif
|
|
#if CONFIG_APP_CLAW_LUA_MODULE_MCPWM
|
|
{ "mcpwm", "MCPWM" },
|
|
#endif
|
|
#if CONFIG_APP_CLAW_LUA_MODULE_UART
|
|
{ "uart", "UART" },
|
|
#endif
|
|
#if CONFIG_APP_CLAW_LUA_MODULE_EVENT_PUBLISHER
|
|
{ "event_publisher", "Event Publisher" },
|
|
#endif
|
|
};
|
|
|
|
esp_err_t app_lua_modules_register(const app_claw_config_t *config, const char *fatfs_base_path)
|
|
{
|
|
const size_t entry_count = sizeof(s_lua_module_entries) / sizeof(s_lua_module_entries[0]);
|
|
bool *selected_map = NULL;
|
|
esp_err_t err = ESP_OK;
|
|
size_t i;
|
|
|
|
if (!config) {
|
|
return ESP_ERR_INVALID_ARG;
|
|
}
|
|
|
|
selected_map = calloc(entry_count > 0 ? entry_count : 1, sizeof(selected_map[0]));
|
|
if (!selected_map) {
|
|
return ESP_ERR_NO_MEM;
|
|
}
|
|
|
|
err = app_lua_build_module_map(config->enabled_lua_modules,
|
|
s_lua_module_entries,
|
|
entry_count,
|
|
selected_map);
|
|
if (err != ESP_OK) {
|
|
free(selected_map);
|
|
return err;
|
|
}
|
|
|
|
for (i = 0; i < entry_count; i++) {
|
|
if (!selected_map[i]) {
|
|
ESP_LOGI(TAG, "Skipping Lua module at init: %s", s_lua_module_entries[i].module_id);
|
|
continue;
|
|
}
|
|
|
|
err = s_lua_module_entries[i].reg(fatfs_base_path);
|
|
if (err != ESP_OK) {
|
|
ESP_LOGE(TAG, "Failed to register Lua module %s: %s",
|
|
s_lua_module_entries[i].module_id,
|
|
esp_err_to_name(err));
|
|
free(selected_map);
|
|
return err;
|
|
}
|
|
}
|
|
|
|
free(selected_map);
|
|
return ESP_OK;
|
|
}
|
|
|
|
esp_err_t app_lua_modules_get_compiled_modules(const app_lua_module_info_t **modules,
|
|
size_t *count)
|
|
{
|
|
if (!modules || !count) {
|
|
return ESP_ERR_INVALID_ARG;
|
|
}
|
|
|
|
*modules = s_lua_module_infos;
|
|
*count = sizeof(s_lua_module_infos) / sizeof(s_lua_module_infos[0]);
|
|
return ESP_OK;
|
|
}
|