summaryrefslogtreecommitdiff
path: root/lib/esp-idf-lua/examples
diff options
context:
space:
mode:
authorjacqueline <me@jacqueline.id.au>2023-11-12 19:14:09 +1100
committerjacqueline <me@jacqueline.id.au>2023-11-12 19:14:09 +1100
commit8a0a167adbf3d9b6f8b6f16aaf20ca39ad5549de (patch)
tree02b6cf23f591915747ec2994381854a79979c4a0 /lib/esp-idf-lua/examples
parent8471046a95ab9e00f7d42b56dbbc9ce3e5b424b9 (diff)
downloadtangara-fw-8a0a167adbf3d9b6f8b6f16aaf20ca39ad5549de.tar.gz
Convert the main menu screen to lua lol
Diffstat (limited to 'lib/esp-idf-lua/examples')
-rw-r--r--lib/esp-idf-lua/examples/alloc/CMakeLists.txt6
-rw-r--r--lib/esp-idf-lua/examples/alloc/Makefile5
-rw-r--r--lib/esp-idf-lua/examples/alloc/main/CMakeLists.txt2
-rw-r--r--lib/esp-idf-lua/examples/alloc/main/component.mk2
-rw-r--r--lib/esp-idf-lua/examples/alloc/main/main.c89
-rw-r--r--lib/esp-idf-lua/examples/custom_lib/CMakeLists.txt6
-rw-r--r--lib/esp-idf-lua/examples/custom_lib/Makefile5
-rw-r--r--lib/esp-idf-lua/examples/custom_lib/main/CMakeLists.txt2
-rw-r--r--lib/esp-idf-lua/examples/custom_lib/main/component.mk2
-rw-r--r--lib/esp-idf-lua/examples/custom_lib/main/gpiolib.c61
-rw-r--r--lib/esp-idf-lua/examples/custom_lib/main/gpiolib.h9
-rw-r--r--lib/esp-idf-lua/examples/custom_lib/main/main.c83
-rw-r--r--lib/esp-idf-lua/examples/custom_lib/main/rtoslib.c24
-rw-r--r--lib/esp-idf-lua/examples/custom_lib/main/rtoslib.h9
-rw-r--r--lib/esp-idf-lua/examples/simple/CMakeLists.txt6
-rw-r--r--lib/esp-idf-lua/examples/simple/Makefile5
-rw-r--r--lib/esp-idf-lua/examples/simple/main/CMakeLists.txt2
-rw-r--r--lib/esp-idf-lua/examples/simple/main/component.mk2
-rw-r--r--lib/esp-idf-lua/examples/simple/main/main.c77
-rw-r--r--lib/esp-idf-lua/examples/vfs/CMakeLists.txt8
-rw-r--r--lib/esp-idf-lua/examples/vfs/Makefile8
-rw-r--r--lib/esp-idf-lua/examples/vfs/main/CMakeLists.txt2
-rw-r--r--lib/esp-idf-lua/examples/vfs/main/component.mk2
-rw-r--r--lib/esp-idf-lua/examples/vfs/main/main.c95
-rw-r--r--lib/esp-idf-lua/examples/vfs/partitions.csv6
-rw-r--r--lib/esp-idf-lua/examples/vfs/sdkconfig.defaults3
-rw-r--r--lib/esp-idf-lua/examples/vfs/spiffs_image/hello.lua11
-rw-r--r--lib/esp-idf-lua/examples/vfs/spiffs_image/hex.lua13
-rw-r--r--lib/esp-idf-lua/examples/vfs/spiffs_image/main.lua6
29 files changed, 551 insertions, 0 deletions
diff --git a/lib/esp-idf-lua/examples/alloc/CMakeLists.txt b/lib/esp-idf-lua/examples/alloc/CMakeLists.txt
new file mode 100644
index 00000000..771bb5bb
--- /dev/null
+++ b/lib/esp-idf-lua/examples/alloc/CMakeLists.txt
@@ -0,0 +1,6 @@
+cmake_minimum_required(VERSION 3.5)
+
+set(EXTRA_COMPONENT_DIRS ${CMAKE_CURRENT_SOURCE_DIR}/../..)
+
+include($ENV{IDF_PATH}/tools/cmake/project.cmake)
+project(example-lua-alloc)
diff --git a/lib/esp-idf-lua/examples/alloc/Makefile b/lib/esp-idf-lua/examples/alloc/Makefile
new file mode 100644
index 00000000..2b16bdbf
--- /dev/null
+++ b/lib/esp-idf-lua/examples/alloc/Makefile
@@ -0,0 +1,5 @@
+PROJECT_NAME := example-lua-alloc
+
+EXTRA_COMPONENT_DIRS := $(CURDIR)/../..
+
+include $(IDF_PATH)/make/project.mk
diff --git a/lib/esp-idf-lua/examples/alloc/main/CMakeLists.txt b/lib/esp-idf-lua/examples/alloc/main/CMakeLists.txt
new file mode 100644
index 00000000..09a8616b
--- /dev/null
+++ b/lib/esp-idf-lua/examples/alloc/main/CMakeLists.txt
@@ -0,0 +1,2 @@
+idf_component_register(SRC_DIRS "."
+ INCLUDE_DIRS ".")
diff --git a/lib/esp-idf-lua/examples/alloc/main/component.mk b/lib/esp-idf-lua/examples/alloc/main/component.mk
new file mode 100644
index 00000000..037751c1
--- /dev/null
+++ b/lib/esp-idf-lua/examples/alloc/main/component.mk
@@ -0,0 +1,2 @@
+COMPONENT_ADD_INCLUDEDIRS = .
+COMPONENT_SRCDIRS = .
diff --git a/lib/esp-idf-lua/examples/alloc/main/main.c b/lib/esp-idf-lua/examples/alloc/main/main.c
new file mode 100644
index 00000000..38b374ef
--- /dev/null
+++ b/lib/esp-idf-lua/examples/alloc/main/main.c
@@ -0,0 +1,89 @@
+#include <stdio.h>
+#include <inttypes.h>
+#include <freertos/FreeRTOS.h>
+#include <freertos/task.h>
+#include <string.h>
+#include <lua/lua.h>
+#include <lua/lauxlib.h>
+#include <lua/lualib.h>
+
+#define LUA_MAX_MEMSIZE 0x10000 // 64k
+
+static const char *prg =
+ "local t = {}\n"
+ "for i = 1, 10000 do\n"
+ " print(string.format(\"Iteration %d...\", i))\n"
+ " t[i] = string.format(\"Lorem ipsum asklfhskldjf hskljfh slkjfd sdklfjh slkfjh sdkljfjh sdklfjh sdklf %d...\", i)\n"
+ "end\n";
+
+static void report(lua_State *L, int status)
+{
+ if (status == LUA_OK)
+ return;
+
+ const char *msg = lua_tostring(L, -1);
+ printf("%s\n", msg);
+ lua_pop(L, 1);
+}
+
+static int lua_mem_size = 0;
+
+static void* l_alloc(void *ud, void *ptr, size_t osize, size_t nsize)
+{
+ int new_size = lua_mem_size - osize + nsize;
+ if (new_size > LUA_MAX_MEMSIZE)
+ {
+ printf("Error! Lua wants more memory than we can allocate: %u > %u\n", new_size, LUA_MAX_MEMSIZE);
+ return NULL;
+ }
+ //printf("Reallocating: old = %u, new = %u\n", lua_mem_size, new_size);
+ lua_mem_size = new_size;
+
+ if (nsize == 0)
+ {
+ free(ptr);
+ return NULL;
+ }
+ else
+ return realloc(ptr, nsize);
+}
+
+void test(void *arg)
+{
+ printf("Program:\n%s\n", prg);
+
+ lua_State *L = lua_newstate(l_alloc, NULL);
+ if (!L)
+ {
+ printf("Could not create state\n");
+ while (1) { vTaskDelay(1000); }
+ }
+
+ luaL_openlibs(L);
+
+ int r = luaL_loadstring(L, prg);
+ if (r)
+ {
+ report(L, r);
+ while (1) { vTaskDelay(1000); }
+ }
+
+ r = lua_pcall(L, 0, 0, 0);
+ if (r)
+ report(L, r);
+
+ lua_close(L);
+
+ printf("State closed, heap: %" PRIu32 "\n", xPortGetFreeHeapSize());
+ while (1)
+ {
+ printf(".");
+ fflush(stdout);
+ vTaskDelay(pdMS_TO_TICKS(100));
+ }
+}
+
+void app_main()
+{
+ xTaskCreate(test, "test", 0x10000, NULL, 5, NULL);
+}
diff --git a/lib/esp-idf-lua/examples/custom_lib/CMakeLists.txt b/lib/esp-idf-lua/examples/custom_lib/CMakeLists.txt
new file mode 100644
index 00000000..1cca3176
--- /dev/null
+++ b/lib/esp-idf-lua/examples/custom_lib/CMakeLists.txt
@@ -0,0 +1,6 @@
+cmake_minimum_required(VERSION 3.5)
+
+set(EXTRA_COMPONENT_DIRS ${CMAKE_CURRENT_SOURCE_DIR}/../..)
+
+include($ENV{IDF_PATH}/tools/cmake/project.cmake)
+project(example-lua-custom-lib)
diff --git a/lib/esp-idf-lua/examples/custom_lib/Makefile b/lib/esp-idf-lua/examples/custom_lib/Makefile
new file mode 100644
index 00000000..ecdb9076
--- /dev/null
+++ b/lib/esp-idf-lua/examples/custom_lib/Makefile
@@ -0,0 +1,5 @@
+PROJECT_NAME := example-lua-custom-lib
+
+EXTRA_COMPONENT_DIRS := $(CURDIR)/../..
+
+include $(IDF_PATH)/make/project.mk
diff --git a/lib/esp-idf-lua/examples/custom_lib/main/CMakeLists.txt b/lib/esp-idf-lua/examples/custom_lib/main/CMakeLists.txt
new file mode 100644
index 00000000..09a8616b
--- /dev/null
+++ b/lib/esp-idf-lua/examples/custom_lib/main/CMakeLists.txt
@@ -0,0 +1,2 @@
+idf_component_register(SRC_DIRS "."
+ INCLUDE_DIRS ".")
diff --git a/lib/esp-idf-lua/examples/custom_lib/main/component.mk b/lib/esp-idf-lua/examples/custom_lib/main/component.mk
new file mode 100644
index 00000000..037751c1
--- /dev/null
+++ b/lib/esp-idf-lua/examples/custom_lib/main/component.mk
@@ -0,0 +1,2 @@
+COMPONENT_ADD_INCLUDEDIRS = .
+COMPONENT_SRCDIRS = .
diff --git a/lib/esp-idf-lua/examples/custom_lib/main/gpiolib.c b/lib/esp-idf-lua/examples/custom_lib/main/gpiolib.c
new file mode 100644
index 00000000..022b2ba2
--- /dev/null
+++ b/lib/esp-idf-lua/examples/custom_lib/main/gpiolib.c
@@ -0,0 +1,61 @@
+#include "gpiolib.h"
+#include <driver/gpio.h>
+
+static void lua_esp_check_err(lua_State *L, esp_err_t err)
+{
+ if (err != ESP_OK)
+ luaL_error(L, "Error: %s", esp_err_to_name(err));
+}
+
+static int lgpio_reset_pin(lua_State *L)
+{
+ gpio_num_t pin = luaL_checkinteger(L, 1);
+
+ lua_esp_check_err(L, gpio_reset_pin(pin));
+
+ return 0;
+}
+
+static int lgpio_set_level(lua_State *L)
+{
+ gpio_num_t pin = luaL_checkinteger(L, 1);
+ int level = luaL_checkinteger(L, 2);
+
+ lua_esp_check_err(L, gpio_set_level(pin, level));
+
+ return 0;
+}
+
+static int lgpio_get_level(lua_State *L)
+{
+ gpio_num_t pin = luaL_checkinteger(L, 1);
+ lua_pushinteger(L, gpio_get_level(pin));
+
+ return 1;
+}
+
+static int lgpio_set_direction(lua_State *L)
+{
+ gpio_num_t pin = luaL_checkinteger(L, 1);
+ int mode = luaL_checkinteger(L, 2);
+
+ lua_esp_check_err(L, gpio_set_direction(pin, mode));
+
+ return 0;
+}
+
+static const struct luaL_Reg lgpio_funcs[] = {
+ { "reset_pin", lgpio_reset_pin },
+ { "set_direction", lgpio_set_direction },
+ { "set_level", lgpio_set_level },
+ { "get_level", lgpio_get_level },
+ { NULL, NULL }
+};
+
+int luaopen_lgpio(lua_State *L)
+{
+ luaL_newlib(L, lgpio_funcs);
+
+ return 1;
+}
+
diff --git a/lib/esp-idf-lua/examples/custom_lib/main/gpiolib.h b/lib/esp-idf-lua/examples/custom_lib/main/gpiolib.h
new file mode 100644
index 00000000..f5d61651
--- /dev/null
+++ b/lib/esp-idf-lua/examples/custom_lib/main/gpiolib.h
@@ -0,0 +1,9 @@
+#ifndef MAIN_GPIOLIB_H_
+#define MAIN_GPIOLIB_H_
+
+#include <lua/lua.h>
+#include <lua/lauxlib.h>
+
+int luaopen_lgpio(lua_State *L);
+
+#endif /* MAIN_GPIOLIB_H_ */
diff --git a/lib/esp-idf-lua/examples/custom_lib/main/main.c b/lib/esp-idf-lua/examples/custom_lib/main/main.c
new file mode 100644
index 00000000..d5820b2d
--- /dev/null
+++ b/lib/esp-idf-lua/examples/custom_lib/main/main.c
@@ -0,0 +1,83 @@
+#include <stdio.h>
+#include <inttypes.h>
+#include <freertos/FreeRTOS.h>
+#include <freertos/task.h>
+#include <string.h>
+#include <lua/lua.h>
+#include <lua/lauxlib.h>
+#include <lua/lualib.h>
+
+#include "gpiolib.h"
+#include "rtoslib.h"
+
+#define GPIO_PIN "5"
+
+static void load_custom_libs(lua_State *L)
+{
+ luaL_requiref(L, "gpio", luaopen_lgpio, 1);
+ lua_pop(L, 1);
+
+ luaL_requiref(L, "rtos", luaopen_lrtos, 1);
+ lua_pop(L, 1);
+}
+
+static const char *prg =
+ "gpio.set_direction(" GPIO_PIN ", 2)\n"
+ "level = 1\n"
+ "for i = 1, 100 do\n"
+ " print(string.format(\"Iteration %d..., GPIO5=%d\", i, level))\n"
+ " gpio.set_level(" GPIO_PIN ", level)\n"
+ " level = 1 - level\n"
+ " rtos.delay(500)\n"
+ "end\n";
+
+static void report(lua_State *L, int status)
+{
+ if (status == LUA_OK)
+ return;
+
+ const char *msg = lua_tostring(L, -1);
+ printf("%s\n", msg);
+ lua_pop(L, 1);
+}
+
+void test(void *arg)
+{
+ printf("Program:\n%s\n", prg);
+
+ lua_State *L = luaL_newstate();
+ if (!L)
+ {
+ printf("Could not create state\n");
+ while (1) { vTaskDelay(1000); }
+ }
+
+ luaL_openlibs(L);
+ load_custom_libs(L);
+
+ int r = luaL_loadstring(L, prg);
+ if (r)
+ {
+ report(L, r);
+ while (1) { vTaskDelay(1000); }
+ }
+
+ r = lua_pcall(L, 0, 0, 0);
+ if (r)
+ report(L, r);
+
+ lua_close(L);
+
+ printf("State closed, heap: %" PRIu32 "\n", xPortGetFreeHeapSize());
+ while (1)
+ {
+ printf(".");
+ fflush(stdout);
+ vTaskDelay(pdMS_TO_TICKS(100));
+ }
+}
+
+void app_main()
+{
+ xTaskCreate(test, "test", 0x10000, NULL, 5, NULL);
+}
diff --git a/lib/esp-idf-lua/examples/custom_lib/main/rtoslib.c b/lib/esp-idf-lua/examples/custom_lib/main/rtoslib.c
new file mode 100644
index 00000000..6c5e219a
--- /dev/null
+++ b/lib/esp-idf-lua/examples/custom_lib/main/rtoslib.c
@@ -0,0 +1,24 @@
+#include "rtoslib.h"
+#include <freertos/FreeRTOS.h>
+#include <freertos/task.h>
+
+static int ldelay(lua_State *L)
+{
+ int ms = luaL_checkinteger(L, 1);
+
+ vTaskDelay(pdMS_TO_TICKS(ms));
+
+ return 0;
+}
+
+static const struct luaL_Reg lrtos_funcs[] = {
+ { "delay", ldelay },
+ { NULL, NULL }
+};
+
+int luaopen_lrtos(lua_State *L)
+{
+ luaL_newlib(L, lrtos_funcs);
+
+ return 1;
+}
diff --git a/lib/esp-idf-lua/examples/custom_lib/main/rtoslib.h b/lib/esp-idf-lua/examples/custom_lib/main/rtoslib.h
new file mode 100644
index 00000000..9f62f736
--- /dev/null
+++ b/lib/esp-idf-lua/examples/custom_lib/main/rtoslib.h
@@ -0,0 +1,9 @@
+#ifndef MAIN_RTOSLIB_H_
+#define MAIN_RTOSLIB_H_
+
+#include <lua/lua.h>
+#include <lua/lauxlib.h>
+
+int luaopen_lrtos(lua_State *L);
+
+#endif /* MAIN_RTOSLIB_H_ */
diff --git a/lib/esp-idf-lua/examples/simple/CMakeLists.txt b/lib/esp-idf-lua/examples/simple/CMakeLists.txt
new file mode 100644
index 00000000..ba61d4eb
--- /dev/null
+++ b/lib/esp-idf-lua/examples/simple/CMakeLists.txt
@@ -0,0 +1,6 @@
+cmake_minimum_required(VERSION 3.5)
+
+set(EXTRA_COMPONENT_DIRS ${CMAKE_CURRENT_SOURCE_DIR}/../..)
+
+include($ENV{IDF_PATH}/tools/cmake/project.cmake)
+project(example-lua-simple)
diff --git a/lib/esp-idf-lua/examples/simple/Makefile b/lib/esp-idf-lua/examples/simple/Makefile
new file mode 100644
index 00000000..ee373b18
--- /dev/null
+++ b/lib/esp-idf-lua/examples/simple/Makefile
@@ -0,0 +1,5 @@
+PROJECT_NAME := example-lua-simple
+
+EXTRA_COMPONENT_DIRS := $(CURDIR)/../..
+
+include $(IDF_PATH)/make/project.mk
diff --git a/lib/esp-idf-lua/examples/simple/main/CMakeLists.txt b/lib/esp-idf-lua/examples/simple/main/CMakeLists.txt
new file mode 100644
index 00000000..09a8616b
--- /dev/null
+++ b/lib/esp-idf-lua/examples/simple/main/CMakeLists.txt
@@ -0,0 +1,2 @@
+idf_component_register(SRC_DIRS "."
+ INCLUDE_DIRS ".")
diff --git a/lib/esp-idf-lua/examples/simple/main/component.mk b/lib/esp-idf-lua/examples/simple/main/component.mk
new file mode 100644
index 00000000..037751c1
--- /dev/null
+++ b/lib/esp-idf-lua/examples/simple/main/component.mk
@@ -0,0 +1,2 @@
+COMPONENT_ADD_INCLUDEDIRS = .
+COMPONENT_SRCDIRS = .
diff --git a/lib/esp-idf-lua/examples/simple/main/main.c b/lib/esp-idf-lua/examples/simple/main/main.c
new file mode 100644
index 00000000..ff671618
--- /dev/null
+++ b/lib/esp-idf-lua/examples/simple/main/main.c
@@ -0,0 +1,77 @@
+#include <stdio.h>
+#include <inttypes.h>
+#include <freertos/FreeRTOS.h>
+#include <freertos/task.h>
+#include <string.h>
+#include <lua/lua.h>
+#include <lua/lauxlib.h>
+#include <lua/lualib.h>
+
+static const char *prg =
+ "v = {'value1', 'value2', 1.21, 'gigawatts'}\n"
+ "for i = 1, #v do\n"
+ " print(v[i])\n"
+ "end\n";
+
+static int report(lua_State *L, int status)
+{
+ if (status != LUA_OK)
+ {
+ const char *msg = lua_tostring(L, -1);
+ lua_writestring(msg, strlen(msg));
+ lua_writeline();
+ lua_pop(L, 1); /* remove message */
+ }
+ return status;
+}
+
+void test(void *arg)
+{
+ printf("\n\n%s\n\n", prg);
+ printf("Start, heap: %" PRIu32 "\n", xPortGetFreeHeapSize());
+
+ lua_State *L = luaL_newstate();
+ if (!L)
+ {
+ printf("Could not create state....\n");
+ while (1) { vTaskDelay(1000); }
+ }
+
+ printf("State ready, heap: %" PRIu32 "\n", xPortGetFreeHeapSize());
+
+ luaL_openlibs(L);
+
+ printf("Libs ready, heap: %" PRIu32 "\n", xPortGetFreeHeapSize());
+
+ int r = luaL_loadstring(L, prg);
+ if (r)
+ {
+ report(L, r);
+ while (1) { vTaskDelay(1000); }
+ }
+
+ printf("Prg loaded, heap: %" PRIu32 "\n", xPortGetFreeHeapSize());
+
+ printf("-------------------------------------------\n");
+ r = lua_pcall(L, 0, 0, 0);
+ if (r)
+ report(L, r);
+ printf("-------------------------------------------\n");
+
+ printf("Prg done, heap: %" PRIu32 "\n", xPortGetFreeHeapSize());
+
+ lua_close(L);
+
+ printf("State closed, heap: %" PRIu32 "\n", xPortGetFreeHeapSize());
+ while (1)
+ {
+ printf(".");
+ fflush(NULL);
+ vTaskDelay(100);
+ }
+}
+
+void app_main()
+{
+ xTaskCreate(test, "test", 0x10000, NULL, 5, NULL);
+}
diff --git a/lib/esp-idf-lua/examples/vfs/CMakeLists.txt b/lib/esp-idf-lua/examples/vfs/CMakeLists.txt
new file mode 100644
index 00000000..1ab79407
--- /dev/null
+++ b/lib/esp-idf-lua/examples/vfs/CMakeLists.txt
@@ -0,0 +1,8 @@
+cmake_minimum_required(VERSION 3.5)
+
+set(EXTRA_COMPONENT_DIRS ${CMAKE_CURRENT_SOURCE_DIR}/../..)
+
+include($ENV{IDF_PATH}/tools/cmake/project.cmake)
+project(example-lua-vfs)
+
+spiffs_create_partition_image(storage spiffs_image FLASH_IN_PROJECT)
diff --git a/lib/esp-idf-lua/examples/vfs/Makefile b/lib/esp-idf-lua/examples/vfs/Makefile
new file mode 100644
index 00000000..b4e2554e
--- /dev/null
+++ b/lib/esp-idf-lua/examples/vfs/Makefile
@@ -0,0 +1,8 @@
+PROJECT_NAME := example-lua-vfs
+
+EXTRA_COMPONENT_DIRS := $(CURDIR)/../..
+
+include $(IDF_PATH)/make/project.mk
+
+SPIFFS_IMAGE_FLASH_IN_PROJECT := 1
+$(eval $(call spiffs_create_partition_image,storage,spiffs_image))
diff --git a/lib/esp-idf-lua/examples/vfs/main/CMakeLists.txt b/lib/esp-idf-lua/examples/vfs/main/CMakeLists.txt
new file mode 100644
index 00000000..09a8616b
--- /dev/null
+++ b/lib/esp-idf-lua/examples/vfs/main/CMakeLists.txt
@@ -0,0 +1,2 @@
+idf_component_register(SRC_DIRS "."
+ INCLUDE_DIRS ".")
diff --git a/lib/esp-idf-lua/examples/vfs/main/component.mk b/lib/esp-idf-lua/examples/vfs/main/component.mk
new file mode 100644
index 00000000..037751c1
--- /dev/null
+++ b/lib/esp-idf-lua/examples/vfs/main/component.mk
@@ -0,0 +1,2 @@
+COMPONENT_ADD_INCLUDEDIRS = .
+COMPONENT_SRCDIRS = .
diff --git a/lib/esp-idf-lua/examples/vfs/main/main.c b/lib/esp-idf-lua/examples/vfs/main/main.c
new file mode 100644
index 00000000..e9267ea5
--- /dev/null
+++ b/lib/esp-idf-lua/examples/vfs/main/main.c
@@ -0,0 +1,95 @@
+#include <stdio.h>
+#include <inttypes.h>
+#include <freertos/FreeRTOS.h>
+#include <freertos/task.h>
+#include <string.h>
+#include <stdbool.h>
+#include <lua/lua.h>
+#include <lua/lauxlib.h>
+#include <lua/lualib.h>
+#include <esp_spiffs.h>
+#include <esp_err.h>
+#include <esp_log.h>
+
+static const char *TAG = "LUA-VFS";
+
+static void report(lua_State *L, int status)
+{
+ if (status == LUA_OK) return;
+
+ const char *msg = lua_tostring(L, -1);
+ printf("%s\n", msg);
+ lua_pop(L, 1);
+}
+
+static void halt()
+{
+ ESP_LOGE(TAG, "System halted");
+ while (1)
+ vTaskDelay(1000);
+}
+
+static void mount_fs()
+{
+ esp_vfs_spiffs_conf_t conf = {
+ .base_path = "/lua",
+ .partition_label = NULL,
+ .max_files = 5,
+ .format_if_mount_failed = false
+ };
+
+ esp_err_t ret = esp_vfs_spiffs_register(&conf);
+ switch (ret)
+ {
+ case ESP_OK:
+ break;
+ case ESP_FAIL:
+ ESP_LOGE(TAG, "Failed to mount or format filesystem");
+ halt();
+ break;
+ case ESP_ERR_NOT_FOUND:
+ ESP_LOGE(TAG, "Failed to find SPIFFS partition");
+ halt();
+ break;
+ default:
+ ESP_LOGE(TAG, "Failed to initialize SPIFFS (%s)", esp_err_to_name(ret));
+ halt();
+ }
+ size_t total = 0, used = 0;
+ ESP_ERROR_CHECK(esp_spiffs_info(NULL, &total, &used));
+ ESP_LOGI(TAG, "Partition size: total: %d, used: %d", total, used);
+}
+
+
+void test(void *arg)
+{
+ mount_fs();
+
+ lua_State *L = luaL_newstate();
+ ESP_ERROR_CHECK(L ? ESP_OK : ESP_FAIL);
+
+ luaL_openlibs(L);
+
+ int r = luaL_loadfilex(L, "/lua/main.lua", NULL);
+ if (r != LUA_OK)
+ printf("Failed to execute /lua/main.lua\n");
+ else
+ r = lua_pcall(L, 0, LUA_MULTRET, 0);
+
+ report(L, r);
+ lua_close(L);
+
+ printf("State closed, heap: %" PRIu32 "\n", xPortGetFreeHeapSize());
+
+ while (1)
+ {
+ printf(".");
+ fflush(stdout);
+ vTaskDelay(100);
+ }
+}
+
+void app_main()
+{
+ xTaskCreate(test, "test", 0x10000, NULL, 5, NULL);
+}
diff --git a/lib/esp-idf-lua/examples/vfs/partitions.csv b/lib/esp-idf-lua/examples/vfs/partitions.csv
new file mode 100644
index 00000000..0eebc192
--- /dev/null
+++ b/lib/esp-idf-lua/examples/vfs/partitions.csv
@@ -0,0 +1,6 @@
+# Name, Type, SubType, Offset, Size, Flags
+# Note: if you have increased the bootloader size, make sure to update the offsets to avoid overlap
+nvs, data, nvs, 0x9000, 0x6000,
+phy_init, data, phy, 0xf000, 0x1000,
+factory, app, factory, 0x10000, 1M,
+storage, data, spiffs, , 0xF0000,
diff --git a/lib/esp-idf-lua/examples/vfs/sdkconfig.defaults b/lib/esp-idf-lua/examples/vfs/sdkconfig.defaults
new file mode 100644
index 00000000..8ff365b1
--- /dev/null
+++ b/lib/esp-idf-lua/examples/vfs/sdkconfig.defaults
@@ -0,0 +1,3 @@
+CONFIG_PARTITION_TABLE_CUSTOM=y
+CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions.csv"
+CONFIG_PARTITION_TABLE_FILENAME="partitions.csv"
diff --git a/lib/esp-idf-lua/examples/vfs/spiffs_image/hello.lua b/lib/esp-idf-lua/examples/vfs/spiffs_image/hello.lua
new file mode 100644
index 00000000..eda6f859
--- /dev/null
+++ b/lib/esp-idf-lua/examples/vfs/spiffs_image/hello.lua
@@ -0,0 +1,11 @@
+local hello = {}
+
+function hello.world()
+ return "Hello world!"
+end
+
+function hello.lorem_ipsum()
+ return "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum."
+end
+
+return hello
diff --git a/lib/esp-idf-lua/examples/vfs/spiffs_image/hex.lua b/lib/esp-idf-lua/examples/vfs/spiffs_image/hex.lua
new file mode 100644
index 00000000..c9e7634e
--- /dev/null
+++ b/lib/esp-idf-lua/examples/vfs/spiffs_image/hex.lua
@@ -0,0 +1,13 @@
+local hex = {}
+
+function hex.dump(buf)
+ for byte=1, #buf, 16 do
+ local chunk = buf:sub(byte, byte+15)
+ io.write(string.format('%08X ',byte-1))
+ chunk:gsub('.', function (c) io.write(string.format('%02X ',string.byte(c))) end)
+ io.write(string.rep(' ',3*(16-#chunk)))
+ io.write(' ',chunk:gsub('%c','.'),"\n")
+ end
+end
+
+return hex
diff --git a/lib/esp-idf-lua/examples/vfs/spiffs_image/main.lua b/lib/esp-idf-lua/examples/vfs/spiffs_image/main.lua
new file mode 100644
index 00000000..0873329c
--- /dev/null
+++ b/lib/esp-idf-lua/examples/vfs/spiffs_image/main.lua
@@ -0,0 +1,6 @@
+local hello = require "hello"
+local hex = require "hex"
+
+print(hello.world())
+
+hex.dump(hello.lorem_ipsum())