Pulled interrupts into an optional module.

This commit is contained in:
Brad Nelson
2023-07-08 11:57:20 -07:00
parent fc7175d488
commit 564a8fc68b
17 changed files with 414 additions and 341 deletions

View File

@ -167,7 +167,7 @@ clean-esp32:
vet: vet:
$(MAKE) clean $(MAKE) clean
$(MAKE) all $(MAKE)
$(MAKE) esp32-build $(MAKE) esp32-build
$(MAKE) esp32s2-build $(MAKE) esp32s2-build
$(MAKE) esp32c3-build $(MAKE) esp32c3-build
@ -175,7 +175,7 @@ vet:
$(MAKE) add-optional $(MAKE) add-optional
$(MAKE) esp32-build $(MAKE) esp32-build
$(MAKE) clean $(MAKE) clean
$(MAKE) all $(MAKE)
clean: clean:
rm -rf $(OUT) rm -rf $(OUT)
@ -292,7 +292,7 @@ ESP32_BOOT = $(COMMON_PHASE1) \
$(COMMON_PHASE2) $(COMMON_FILETOOLS) \ $(COMMON_PHASE2) $(COMMON_FILETOOLS) \
esp32/platform.fs \ esp32/platform.fs \
posix/httpd.fs posix/web_interface.fs esp32/web_interface.fs \ posix/httpd.fs posix/web_interface.fs esp32/web_interface.fs \
esp32/registers.fs esp32/timers.fs \ esp32/registers.fs \
posix/telnetd.fs \ posix/telnetd.fs \
esp32/optionals.fs \ esp32/optionals.fs \
esp32/autoboot.fs common/fini.fs esp32/autoboot.fs common/fini.fs
@ -325,6 +325,14 @@ $(GEN)/esp32_camera.h: \
esp32/optional/camera/camera.fs \ esp32/optional/camera/camera.fs \
esp32/optional/camera/camera_server.fs >$@ esp32/optional/camera/camera_server.fs >$@
$(GEN)/esp32_interrupts.h: \
tools/source_to_string.js \
esp32/optional/interrupts/interrupts.fs \
esp32/optional/interrupts/timers.fs | $(GEN)
$< interrupts_source $(VERSION) $(REVISION) \
esp32/optional/interrupts/interrupts.fs \
esp32/optional/interrupts/timers.fs >$@
$(GEN)/esp32_oled.h: \ $(GEN)/esp32_oled.h: \
tools/source_to_string.js esp32/optional/oled/oled.fs | $(GEN) tools/source_to_string.js esp32/optional/oled/oled.fs | $(GEN)
$< oled_source $(VERSION) $(REVISION) \ $< oled_source $(VERSION) $(REVISION) \
@ -347,6 +355,7 @@ OPTIONAL_MODULES = \
$(ESP32)/ESP32forth/assemblers.h \ $(ESP32)/ESP32forth/assemblers.h \
$(ESP32)/ESP32forth/camera.h \ $(ESP32)/ESP32forth/camera.h \
$(ESP32)/ESP32forth/oled.h \ $(ESP32)/ESP32forth/oled.h \
$(ESP32)/ESP32forth/interrupts.h \
$(ESP32)/ESP32forth/rmt.h \ $(ESP32)/ESP32forth/rmt.h \
$(ESP32)/ESP32forth/serial-bluetooth.h \ $(ESP32)/ESP32forth/serial-bluetooth.h \
$(ESP32)/ESP32forth/spi-flash.h $(ESP32)/ESP32forth/spi-flash.h
@ -650,6 +659,15 @@ $(ESP32)/ESP32forth/optional/camera.h: \
camera=@$(GEN)/esp32_camera.h \ camera=@$(GEN)/esp32_camera.h \
>$@ >$@
$(ESP32)/ESP32forth/optional/interrupts.h: \
esp32/optional/interrupts/interrupts.h \
$(GEN)/esp32_interrupts.h | $(ESP32)/ESP32forth/optional
cat esp32/optional/interrupts/interrupts.h | tools/replace.js \
VERSION=$(VERSION) \
REVISION=$(REVISION) \
interrupts=@$(GEN)/esp32_interrupts.h \
>$@
$(ESP32)/ESP32forth/optional/oled.h: \ $(ESP32)/ESP32forth/optional/oled.h: \
esp32/optional/oled/oled.h \ esp32/optional/oled/oled.h \
$(GEN)/esp32_oled.h | $(ESP32)/ESP32forth/optional $(GEN)/esp32_oled.h | $(ESP32)/ESP32forth/optional
@ -784,6 +802,7 @@ $(ESP32)/ESP32forth.zip: \
$(ESP32)/ESP32forth/optional/assemblers.h \ $(ESP32)/ESP32forth/optional/assemblers.h \
$(ESP32)/ESP32forth/optional/camera.h \ $(ESP32)/ESP32forth/optional/camera.h \
$(ESP32)/ESP32forth/optional/oled.h \ $(ESP32)/ESP32forth/optional/oled.h \
$(ESP32)/ESP32forth/optional/interrupts.h \
$(ESP32)/ESP32forth/optional/rmt.h \ $(ESP32)/ESP32forth/optional/rmt.h \
$(ESP32)/ESP32forth/optional/serial-bluetooth.h \ $(ESP32)/ESP32forth/optional/serial-bluetooth.h \
$(ESP32)/ESP32forth/optional/spi-flash.h $(ESP32)/ESP32forth/optional/spi-flash.h

View File

@ -37,3 +37,6 @@ typedef struct {
void *DOCREATE_OP; void *DOCREATE_OP;
const BUILTIN_WORD *builtins; const BUILTIN_WORD *builtins;
} G_SYS; } G_SYS;
static G_SYS *g_sys = 0;
static cell_t *forth_run(cell_t *init_rp);

View File

@ -43,8 +43,6 @@ enum {
#undef V #undef V
}; };
static G_SYS *g_sys = 0;
static cell_t convert(const char *pos, cell_t n, cell_t base, cell_t *ret) { static cell_t convert(const char *pos, cell_t n, cell_t base, cell_t *ret) {
*ret = 0; *ret = 0;
cell_t negate = 0; cell_t negate = 0;

View File

@ -623,7 +623,6 @@ e: test-esp32-forth-voclist
out: streams out: streams
out: tasks out: tasks
out: rtos out: rtos
out: interrupts
out: sockets out: sockets
out: Serial out: Serial
out: ledc out: ledc
@ -682,7 +681,6 @@ e: check-esp32-builtins
e: check-esp32-bindings e: check-esp32-bindings
out: rtos out: rtos
out: interrupts
out: sockets out: sockets
out: Serial out: Serial
out: ledc out: ledc
@ -699,7 +697,6 @@ e: test-esp32-forth-namespace
' forth list-from ' forth list-from
out: FORTH out: FORTH
out: telnetd out: telnetd
out: timers
out: registers out: registers
out: webui out: webui
out: login out: login

View File

@ -26,6 +26,7 @@
{{tier2_opcodes}} {{tier2_opcodes}}
{{floats}} {{floats}}
{{calls}} {{calls}}
{{bits}}
{{builtins.h}} {{builtins.h}}
{{builtins.cpp}} {{builtins.cpp}}
{{main.cpp}} {{main.cpp}}

View File

@ -79,30 +79,6 @@ transfer sockets-builtins
: ip. ( n -- ) ip# ip# ip# 255 and n. ; : ip. ( n -- ) ip# ip# ip# 255 and n. ;
forth definitions forth definitions
vocabulary interrupts interrupts definitions
transfer interrupts-builtins
DEFINED? gpio_config [IF]
0 constant ESP_INTR_FLAG_DEFAULT
: ESP_INTR_FLAG_LEVELn ( n=1-6 -- n ) 1 swap lshift ;
1 7 lshift constant ESP_INTR_FLAG_NMI
1 8 lshift constant ESP_INTR_FLAG_SHARED
1 9 lshift constant ESP_INTR_FLAG_EDGE
1 10 lshift constant ESP_INTR_FLAG_IRAM
1 11 lshift constant ESP_INTR_FLAG_INTRDISABLED
( Prefix these with # because GPIO_INTR_DISABLE conflicts with a function. )
0 constant #GPIO_INTR_DISABLE
1 constant #GPIO_INTR_POSEDGE
2 constant #GPIO_INTR_NEGEDGE
3 constant #GPIO_INTR_ANYEDGE
4 constant #GPIO_INTR_LOW_LEVEL
5 constant #GPIO_INTR_HIGH_LEVEL
( Easy word to trigger on any change to a pin )
ESP_INTR_FLAG_DEFAULT gpio_install_isr_service drop
: pinchange ( xt pin ) dup #GPIO_INTR_ANYEDGE gpio_set_intr_type throw
swap 0 gpio_isr_handler_add throw ;
[THEN]
forth definitions
vocabulary rtos rtos definitions vocabulary rtos rtos definitions
transfer rtos-builtins transfer rtos-builtins
forth definitions forth definitions

View File

@ -15,7 +15,6 @@
static char filename[PATH_MAX]; static char filename[PATH_MAX];
static char filename2[PATH_MAX]; static char filename2[PATH_MAX];
{{bits}}
{{core}} {{core}}
{{faults}} {{faults}}
{{calling}} {{calling}}
@ -52,63 +51,3 @@ static cell_t ResizeFile(cell_t fd, cell_t size) {
if (t < 0) { return errno; } if (t < 0) { return errno; }
return 0; return 0;
} }
#ifdef ENABLE_INTERRUPTS_SUPPORT
struct handle_interrupt_args {
cell_t xt;
cell_t arg;
};
static void IRAM_ATTR HandleInterrupt(void *arg) {
struct handle_interrupt_args *args = (struct handle_interrupt_args *) arg;
cell_t code[2];
code[0] = args->xt;
code[1] = g_sys->YIELD_XT;
cell_t fstack[INTERRUPT_STACK_CELLS];
cell_t rstack[INTERRUPT_STACK_CELLS];
cell_t stack[INTERRUPT_STACK_CELLS];
stack[0] = args->arg;
cell_t *rp = rstack;
*++rp = (cell_t) code;
*++rp = (cell_t) (fstack + 1);
*++rp = (cell_t) (stack + 1);
forth_run(rp);
}
static bool IRAM_ATTR HandleInterruptAndRet(void *arg) {
HandleInterrupt(arg);
return true;
}
static cell_t EspIntrAlloc(cell_t source, cell_t flags, cell_t xt, cell_t arg, void *ret) {
// NOTE: Leaks memory.
struct handle_interrupt_args *args = (struct handle_interrupt_args *) malloc(sizeof(struct handle_interrupt_args));
args->xt = xt;
args->arg = arg;
return esp_intr_alloc(source, flags, HandleInterrupt, args, (intr_handle_t *) ret);
}
static cell_t GpioIsrHandlerAdd(cell_t pin, cell_t xt, cell_t arg) {
// NOTE: Leaks memory.
struct handle_interrupt_args *args = (struct handle_interrupt_args *) malloc(sizeof(struct handle_interrupt_args));
args->xt = xt;
args->arg = arg;
return gpio_isr_handler_add((gpio_num_t) pin, HandleInterrupt, args);
}
static void TimerInitNull(cell_t group, cell_t timer) {
// Seems to be required starting in the 2.0 IDE.
timer_config_t config;
memset(&config, 0, sizeof(config));
config.divider = 2;
timer_init((timer_group_t) group, (timer_idx_t) timer, &config);
}
static cell_t TimerIsrCallbackAdd(cell_t group, cell_t timer, cell_t xt, cell_t arg, cell_t flags) {
// NOTE: Leaks memory.
struct handle_interrupt_args *args = (struct handle_interrupt_args *) malloc(sizeof(struct handle_interrupt_args));
args->xt = xt;
args->arg = arg;
return timer_isr_callback_add((timer_group_t) group, (timer_idx_t) timer, HandleInterruptAndRet, args, flags);
}
#endif

View File

@ -36,6 +36,14 @@
# define OPTIONAL_ASSEMBLERS_SUPPORT # define OPTIONAL_ASSEMBLERS_SUPPORT
# endif # endif
// Hook to pull in optional interrupts and timers support.
# if __has_include("interrupts.h")
# include "interrupts.h"
# else
# define OPTIONAL_INTERRUPTS_VOCABULARIES
# define OPTIONAL_INTERRUPTS_SUPPORT
# endif
// Hook to pull in optional Oled support. // Hook to pull in optional Oled support.
# if __has_include("oled.h") # if __has_include("oled.h")
# include "oled.h" # include "oled.h"
@ -101,13 +109,13 @@ static cell_t ResizeFile(cell_t fd, cell_t size);
OPTIONAL_I2C_SUPPORT \ OPTIONAL_I2C_SUPPORT \
OPTIONAL_SOCKETS_SUPPORT \ OPTIONAL_SOCKETS_SUPPORT \
OPTIONAL_FREERTOS_SUPPORT \ OPTIONAL_FREERTOS_SUPPORT \
OPTIONAL_INTERRUPTS_SUPPORT \
CALLING_OPCODE_LIST \ CALLING_OPCODE_LIST \
FLOATING_POINT_LIST FLOATING_POINT_LIST
#define EXTERNAL_OPTIONAL_MODULE_SUPPORT \ #define EXTERNAL_OPTIONAL_MODULE_SUPPORT \
OPTIONAL_ASSEMBLERS_SUPPORT \ OPTIONAL_ASSEMBLERS_SUPPORT \
OPTIONAL_CAMERA_SUPPORT \ OPTIONAL_CAMERA_SUPPORT \
OPTIONAL_INTERRUPTS_SUPPORT \
OPTIONAL_OLED_SUPPORT \ OPTIONAL_OLED_SUPPORT \
OPTIONAL_RMT_SUPPORT \ OPTIONAL_RMT_SUPPORT \
OPTIONAL_SERIAL_BLUETOOTH_SUPPORT \ OPTIONAL_SERIAL_BLUETOOTH_SUPPORT \
@ -278,85 +286,6 @@ static cell_t ResizeFile(cell_t fd, cell_t size);
YV(rtos, xPortGetCoreID, PUSH xPortGetCoreID()) YV(rtos, xPortGetCoreID, PUSH xPortGetCoreID())
#endif #endif
#ifndef ENABLE_INTERRUPTS_SUPPORT
# define OPTIONAL_INTERRUPTS_SUPPORT
#else
# ifndef SIM_PRINT_ONLY
# include "esp_intr_alloc.h"
# include "driver/timer.h"
# include "driver/gpio.h"
static cell_t EspIntrAlloc(cell_t source, cell_t flags, cell_t xt, cell_t arg, void *ret);
static cell_t GpioIsrHandlerAdd(cell_t pin, cell_t xt, cell_t arg);
static cell_t TimerIsrCallbackAdd(cell_t group, cell_t timer, cell_t xt, cell_t arg, cell_t flags);
static void TimerInitNull(cell_t group, cell_t timer);
# endif
# define OPTIONAL_INTERRUPTS_SUPPORT \
YV(interrupts, gpio_config, n0 = gpio_config((const gpio_config_t *) a0)) \
YV(interrupts, gpio_reset_pin, n0 = gpio_reset_pin((gpio_num_t) n0)) \
YV(interrupts, gpio_set_intr_type, n0 = gpio_set_intr_type((gpio_num_t) n1, (gpio_int_type_t) n0); NIP) \
YV(interrupts, gpio_intr_enable, n0 = gpio_intr_enable((gpio_num_t) n0)) \
YV(interrupts, gpio_intr_disable, n0 = gpio_intr_disable((gpio_num_t) n0)) \
YV(interrupts, gpio_set_level, n0 = gpio_set_level((gpio_num_t) n1, n0); NIP) \
YV(interrupts, gpio_get_level, n0 = gpio_get_level((gpio_num_t) n0)) \
YV(interrupts, gpio_set_direction, n0 = gpio_set_direction((gpio_num_t) n1, (gpio_mode_t) n0); NIP) \
YV(interrupts, gpio_set_pull_mode, n0 = gpio_set_pull_mode((gpio_num_t) n1, (gpio_pull_mode_t) n0); NIP) \
YV(interrupts, gpio_wakeup_enable, n0 = gpio_wakeup_enable((gpio_num_t) n1, (gpio_int_type_t) n0); NIP) \
YV(interrupts, gpio_wakeup_disable, n0 = gpio_wakeup_disable((gpio_num_t) n0)) \
YV(interrupts, gpio_pullup_en, n0 = gpio_pullup_en((gpio_num_t) n0)) \
YV(interrupts, gpio_pullup_dis, n0 = gpio_pullup_dis((gpio_num_t) n0)) \
YV(interrupts, gpio_pulldown_en, n0 = gpio_pulldown_en((gpio_num_t) n0)) \
YV(interrupts, gpio_pulldown_dis, n0 = gpio_pulldown_dis((gpio_num_t) n0)) \
YV(interrupts, gpio_hold_en, n0 = gpio_hold_en((gpio_num_t) n0)) \
YV(interrupts, gpio_hold_dis, n0 = gpio_hold_dis((gpio_num_t) n0)) \
YV(interrupts, gpio_deep_sleep_hold_en, gpio_deep_sleep_hold_en()) \
YV(interrupts, gpio_deep_sleep_hold_dis, gpio_deep_sleep_hold_dis()) \
YV(interrupts, gpio_install_isr_service, n0 = gpio_install_isr_service(n0)) \
YV(interrupts, gpio_uninstall_isr_service, gpio_uninstall_isr_service()) \
YV(interrupts, gpio_isr_handler_add, n0 = GpioIsrHandlerAdd(n2, n1, n0); NIPn(2)) \
YV(interrupts, gpio_isr_handler_remove, n0 = gpio_isr_handler_remove((gpio_num_t) n0)) \
YV(interrupts, gpio_set_drive_capability, n0 = gpio_set_drive_capability((gpio_num_t) n1, (gpio_drive_cap_t) n0); NIP) \
YV(interrupts, gpio_get_drive_capability, n0 = gpio_get_drive_capability((gpio_num_t) n1, (gpio_drive_cap_t *) a0); NIP) \
YV(interrupts, esp_intr_alloc, n0 = EspIntrAlloc(n4, n3, n2, n1, a0); NIPn(4)) \
YV(interrupts, esp_intr_free, n0 = esp_intr_free((intr_handle_t) n0)) \
YV(timers, timer_isr_callback_add, n0 = TimerIsrCallbackAdd(n4, n3, n2, n1, n0); NIPn(4)) \
YV(timers, timer_init_null, TimerInitNull(n1, n0); DROPn(2)) \
YV(timers, timer_get_counter_value, \
n0 = timer_get_counter_value((timer_group_t) n2, (timer_idx_t) n1, \
(uint64_t *) a0); NIPn(2)) \
YV(timers, timer_set_counter_value, \
uint64_t val = *(uint64_t *) a0; \
n0 = timer_set_counter_value((timer_group_t) n2, (timer_idx_t) n1, val); NIPn(2)) \
YV(timers, timer_start, \
n0 = timer_start((timer_group_t) n1, (timer_idx_t) n0); NIP) \
YV(timers, timer_pause, \
n0 = timer_pause((timer_group_t) n1, (timer_idx_t) n0); NIP) \
YV(timers, timer_set_counter_mode, \
n0 = timer_set_counter_mode((timer_group_t) n2, (timer_idx_t) n1, \
(timer_count_dir_t) n0); NIPn(2)) \
YV(timers, timer_set_auto_reload, \
n0 = timer_set_auto_reload((timer_group_t) n2, (timer_idx_t) n1, \
(timer_autoreload_t) n0); NIPn(2)) \
YV(timers, timer_set_divider, \
n0 = timer_set_divider((timer_group_t) n2, (timer_idx_t) n1, n0); NIPn(2)) \
YV(timers, timer_set_alarm_value, uint64_t val = *(uint64_t *) a0; \
n0 = timer_set_alarm_value((timer_group_t) n2, (timer_idx_t) n1, val); NIPn(2)) \
YV(timers, timer_get_alarm_value, \
n0 = timer_get_alarm_value((timer_group_t) n2, (timer_idx_t) n1, \
(uint64_t *) a0); NIPn(2)) \
YV(timers, timer_set_alarm, \
n0 = timer_set_alarm((timer_group_t) n2, (timer_idx_t) n1, \
(timer_alarm_t) n0); NIPn(2)) \
YV(timers, timer_group_intr_enable, \
n0 = timer_group_intr_enable((timer_group_t) n1, (timer_intr_t) n0); NIP) \
YV(timers, timer_group_intr_disable, \
n0 = timer_group_intr_disable((timer_group_t) n1, (timer_intr_t) n0); NIP) \
YV(timers, timer_enable_intr, \
n0 = timer_enable_intr((timer_group_t) n1, (timer_idx_t) n0); NIP) \
YV(timers, timer_disable_intr, \
n0 = timer_disable_intr((timer_group_t) n1, (timer_idx_t) n0); NIP)
#endif
#ifndef ENABLE_SOCKETS_SUPPORT #ifndef ENABLE_SOCKETS_SUPPORT
# define OPTIONAL_SOCKETS_SUPPORT # define OPTIONAL_SOCKETS_SUPPORT
#else #else

View File

@ -0,0 +1,37 @@
\ Copyright 2023 Bradley D. Nelson
\
\ Licensed under the Apache License, Version 2.0 (the "License");
\ you may not use this file except in compliance with the License.
\ You may obtain a copy of the License at
\
\ http://www.apache.org/licenses/LICENSE-2.0
\
\ Unless required by applicable law or agreed to in writing, software
\ distributed under the License is distributed on an "AS IS" BASIS,
\ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
\ See the License for the specific language governing permissions and
\ limitations under the License.
vocabulary interrupts interrupts definitions
transfer interrupts-builtins
DEFINED? gpio_config [IF]
0 constant ESP_INTR_FLAG_DEFAULT
: ESP_INTR_FLAG_LEVELn ( n=1-6 -- n ) 1 swap lshift ;
1 7 lshift constant ESP_INTR_FLAG_NMI
1 8 lshift constant ESP_INTR_FLAG_SHARED
1 9 lshift constant ESP_INTR_FLAG_EDGE
1 10 lshift constant ESP_INTR_FLAG_IRAM
1 11 lshift constant ESP_INTR_FLAG_INTRDISABLED
( Prefix these with # because GPIO_INTR_DISABLE conflicts with a function. )
0 constant #GPIO_INTR_DISABLE
1 constant #GPIO_INTR_POSEDGE
2 constant #GPIO_INTR_NEGEDGE
3 constant #GPIO_INTR_ANYEDGE
4 constant #GPIO_INTR_LOW_LEVEL
5 constant #GPIO_INTR_HIGH_LEVEL
( Easy word to trigger on any change to a pin )
ESP_INTR_FLAG_DEFAULT gpio_install_isr_service drop
: pinchange ( xt pin ) dup #GPIO_INTR_ANYEDGE gpio_set_intr_type throw
swap 0 gpio_isr_handler_add throw ;
[THEN]
forth definitions

View File

@ -0,0 +1,152 @@
// Copyright 2023 Bradley D. Nelson
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#define INTERRUPT_STACK_CELLS 64
#include "esp_intr_alloc.h"
#include "driver/timer.h"
#include "driver/gpio.h"
static cell_t EspIntrAlloc(cell_t source, cell_t flags, cell_t xt, cell_t arg, void *ret);
static cell_t GpioIsrHandlerAdd(cell_t pin, cell_t xt, cell_t arg);
static cell_t TimerIsrCallbackAdd(cell_t group, cell_t timer, cell_t xt, cell_t arg, cell_t flags);
static void TimerInitNull(cell_t group, cell_t timer);
#define OPTIONAL_INTERRUPTS_VOCABULARIES V(interrupts) V(timers)
#define OPTIONAL_INTERRUPTS_SUPPORT \
XV(internals, "interrupts-source", INTERRUPTS_SOURCE, \
PUSH interrupts_source; PUSH sizeof(interrupts_source) - 1) \
YV(interrupts, gpio_config, n0 = gpio_config((const gpio_config_t *) a0)) \
YV(interrupts, gpio_reset_pin, n0 = gpio_reset_pin((gpio_num_t) n0)) \
YV(interrupts, gpio_set_intr_type, n0 = gpio_set_intr_type((gpio_num_t) n1, (gpio_int_type_t) n0); NIP) \
YV(interrupts, gpio_intr_enable, n0 = gpio_intr_enable((gpio_num_t) n0)) \
YV(interrupts, gpio_intr_disable, n0 = gpio_intr_disable((gpio_num_t) n0)) \
YV(interrupts, gpio_set_level, n0 = gpio_set_level((gpio_num_t) n1, n0); NIP) \
YV(interrupts, gpio_get_level, n0 = gpio_get_level((gpio_num_t) n0)) \
YV(interrupts, gpio_set_direction, n0 = gpio_set_direction((gpio_num_t) n1, (gpio_mode_t) n0); NIP) \
YV(interrupts, gpio_set_pull_mode, n0 = gpio_set_pull_mode((gpio_num_t) n1, (gpio_pull_mode_t) n0); NIP) \
YV(interrupts, gpio_wakeup_enable, n0 = gpio_wakeup_enable((gpio_num_t) n1, (gpio_int_type_t) n0); NIP) \
YV(interrupts, gpio_wakeup_disable, n0 = gpio_wakeup_disable((gpio_num_t) n0)) \
YV(interrupts, gpio_pullup_en, n0 = gpio_pullup_en((gpio_num_t) n0)) \
YV(interrupts, gpio_pullup_dis, n0 = gpio_pullup_dis((gpio_num_t) n0)) \
YV(interrupts, gpio_pulldown_en, n0 = gpio_pulldown_en((gpio_num_t) n0)) \
YV(interrupts, gpio_pulldown_dis, n0 = gpio_pulldown_dis((gpio_num_t) n0)) \
YV(interrupts, gpio_hold_en, n0 = gpio_hold_en((gpio_num_t) n0)) \
YV(interrupts, gpio_hold_dis, n0 = gpio_hold_dis((gpio_num_t) n0)) \
YV(interrupts, gpio_deep_sleep_hold_en, gpio_deep_sleep_hold_en()) \
YV(interrupts, gpio_deep_sleep_hold_dis, gpio_deep_sleep_hold_dis()) \
YV(interrupts, gpio_install_isr_service, n0 = gpio_install_isr_service(n0)) \
YV(interrupts, gpio_uninstall_isr_service, gpio_uninstall_isr_service()) \
YV(interrupts, gpio_isr_handler_add, n0 = GpioIsrHandlerAdd(n2, n1, n0); NIPn(2)) \
YV(interrupts, gpio_isr_handler_remove, n0 = gpio_isr_handler_remove((gpio_num_t) n0)) \
YV(interrupts, gpio_set_drive_capability, n0 = gpio_set_drive_capability((gpio_num_t) n1, (gpio_drive_cap_t) n0); NIP) \
YV(interrupts, gpio_get_drive_capability, n0 = gpio_get_drive_capability((gpio_num_t) n1, (gpio_drive_cap_t *) a0); NIP) \
YV(interrupts, esp_intr_alloc, n0 = EspIntrAlloc(n4, n3, n2, n1, a0); NIPn(4)) \
YV(interrupts, esp_intr_free, n0 = esp_intr_free((intr_handle_t) n0)) \
YV(timers, timer_isr_callback_add, n0 = TimerIsrCallbackAdd(n4, n3, n2, n1, n0); NIPn(4)) \
YV(timers, timer_init_null, TimerInitNull(n1, n0); DROPn(2)) \
YV(timers, timer_get_counter_value, \
n0 = timer_get_counter_value((timer_group_t) n2, (timer_idx_t) n1, \
(uint64_t *) a0); NIPn(2)) \
YV(timers, timer_set_counter_value, \
uint64_t val = *(uint64_t *) a0; \
n0 = timer_set_counter_value((timer_group_t) n2, (timer_idx_t) n1, val); NIPn(2)) \
YV(timers, timer_start, \
n0 = timer_start((timer_group_t) n1, (timer_idx_t) n0); NIP) \
YV(timers, timer_pause, \
n0 = timer_pause((timer_group_t) n1, (timer_idx_t) n0); NIP) \
YV(timers, timer_set_counter_mode, \
n0 = timer_set_counter_mode((timer_group_t) n2, (timer_idx_t) n1, \
(timer_count_dir_t) n0); NIPn(2)) \
YV(timers, timer_set_auto_reload, \
n0 = timer_set_auto_reload((timer_group_t) n2, (timer_idx_t) n1, \
(timer_autoreload_t) n0); NIPn(2)) \
YV(timers, timer_set_divider, \
n0 = timer_set_divider((timer_group_t) n2, (timer_idx_t) n1, n0); NIPn(2)) \
YV(timers, timer_set_alarm_value, uint64_t val = *(uint64_t *) a0; \
n0 = timer_set_alarm_value((timer_group_t) n2, (timer_idx_t) n1, val); NIPn(2)) \
YV(timers, timer_get_alarm_value, \
n0 = timer_get_alarm_value((timer_group_t) n2, (timer_idx_t) n1, \
(uint64_t *) a0); NIPn(2)) \
YV(timers, timer_set_alarm, \
n0 = timer_set_alarm((timer_group_t) n2, (timer_idx_t) n1, \
(timer_alarm_t) n0); NIPn(2)) \
YV(timers, timer_group_intr_enable, \
n0 = timer_group_intr_enable((timer_group_t) n1, (timer_intr_t) n0); NIP) \
YV(timers, timer_group_intr_disable, \
n0 = timer_group_intr_disable((timer_group_t) n1, (timer_intr_t) n0); NIP) \
YV(timers, timer_enable_intr, \
n0 = timer_enable_intr((timer_group_t) n1, (timer_idx_t) n0); NIP) \
YV(timers, timer_disable_intr, \
n0 = timer_disable_intr((timer_group_t) n1, (timer_idx_t) n0); NIP)
struct handle_interrupt_args {
cell_t xt;
cell_t arg;
};
static void IRAM_ATTR HandleInterrupt(void *arg) {
struct handle_interrupt_args *args = (struct handle_interrupt_args *) arg;
cell_t code[2];
code[0] = args->xt;
code[1] = g_sys->YIELD_XT;
cell_t fstack[INTERRUPT_STACK_CELLS];
cell_t rstack[INTERRUPT_STACK_CELLS];
cell_t stack[INTERRUPT_STACK_CELLS];
stack[0] = args->arg;
cell_t *rp = rstack;
*++rp = (cell_t) code;
*++rp = (cell_t) (fstack + 1);
*++rp = (cell_t) (stack + 1);
forth_run(rp);
}
static bool IRAM_ATTR HandleInterruptAndRet(void *arg) {
HandleInterrupt(arg);
return true;
}
static cell_t EspIntrAlloc(cell_t source, cell_t flags, cell_t xt, cell_t arg, void *ret) {
// NOTE: Leaks memory.
struct handle_interrupt_args *args = (struct handle_interrupt_args *) malloc(sizeof(struct handle_interrupt_args));
args->xt = xt;
args->arg = arg;
return esp_intr_alloc(source, flags, HandleInterrupt, args, (intr_handle_t *) ret);
}
static cell_t GpioIsrHandlerAdd(cell_t pin, cell_t xt, cell_t arg) {
// NOTE: Leaks memory.
struct handle_interrupt_args *args = (struct handle_interrupt_args *) malloc(sizeof(struct handle_interrupt_args));
args->xt = xt;
args->arg = arg;
return gpio_isr_handler_add((gpio_num_t) pin, HandleInterrupt, args);
}
static void TimerInitNull(cell_t group, cell_t timer) {
// Seems to be required starting in the 2.0 IDE.
timer_config_t config;
memset(&config, 0, sizeof(config));
config.divider = 2;
timer_init((timer_group_t) group, (timer_idx_t) timer, &config);
}
static cell_t TimerIsrCallbackAdd(cell_t group, cell_t timer, cell_t xt, cell_t arg, cell_t flags) {
// NOTE: Leaks memory.
struct handle_interrupt_args *args = (struct handle_interrupt_args *) malloc(sizeof(struct handle_interrupt_args));
args->xt = xt;
args->arg = arg;
return timer_isr_callback_add((timer_group_t) group, (timer_idx_t) timer, HandleInterruptAndRet, args, flags);
}
{{interrupts}}

View File

@ -26,6 +26,10 @@ internals DEFINED? camera-source [IF]
camera-source evaluate camera-source evaluate
[THEN] forth [THEN] forth
internals DEFINED? interrupts-source [IF]
interrupts-source evaluate
[THEN] forth
internals DEFINED? oled-source [IF] internals DEFINED? oled-source [IF]
oled-source evaluate oled-source evaluate
[THEN] forth [THEN] forth

View File

@ -13,7 +13,6 @@
// limitations under the License. // limitations under the License.
#define STACK_CELLS 512 #define STACK_CELLS 512
#define INTERRUPT_STACK_CELLS 64
#define MINIMUM_FREE_SYSTEM_HEAP (64 * 1024) #define MINIMUM_FREE_SYSTEM_HEAP (64 * 1024)
// Default on several options. // Default on several options.
@ -23,7 +22,6 @@
#define ENABLE_I2C_SUPPORT #define ENABLE_I2C_SUPPORT
#define ENABLE_SOCKETS_SUPPORT #define ENABLE_SOCKETS_SUPPORT
#define ENABLE_FREERTOS_SUPPORT #define ENABLE_FREERTOS_SUPPORT
#define ENABLE_INTERRUPTS_SUPPORT
#define ENABLE_LEDC_SUPPORT #define ENABLE_LEDC_SUPPORT
#define ENABLE_SD_SUPPORT #define ENABLE_SD_SUPPORT
#define ENABLE_ESP32_FORTH_FAULT_HANDLING #define ENABLE_ESP32_FORTH_FAULT_HANDLING
@ -91,9 +89,9 @@
V(forth) V(internals) \ V(forth) V(internals) \
V(rtos) V(SPIFFS) V(serial) V(SD) V(SD_MMC) V(ESP) \ V(rtos) V(SPIFFS) V(serial) V(SD) V(SD_MMC) V(ESP) \
V(ledc) V(Wire) V(WiFi) V(sockets) \ V(ledc) V(Wire) V(WiFi) V(sockets) \
V(interrupts) V(timers) \
OPTIONAL_CAMERA_VOCABULARY \ OPTIONAL_CAMERA_VOCABULARY \
OPTIONAL_BLUETOOTH_VOCABULARY \ OPTIONAL_BLUETOOTH_VOCABULARY \
OPTIONAL_INTERRUPTS_VOCABULARIES \
OPTIONAL_OLED_VOCABULARY \ OPTIONAL_OLED_VOCABULARY \
OPTIONAL_RMT_VOCABULARY \ OPTIONAL_RMT_VOCABULARY \
OPTIONAL_SPI_FLASH_VOCABULARY \ OPTIONAL_SPI_FLASH_VOCABULARY \

View File

@ -25,15 +25,17 @@
#define USER_WORDS #define USER_WORDS
#define OPTIONAL_ASSEMBLERS_SUPPORT #define OPTIONAL_ASSEMBLERS_SUPPORT
#define OPTIONAL_OLED_SUPPORT
#define OPTIONAL_CAMERA_SUPPORT #define OPTIONAL_CAMERA_SUPPORT
#define OPTIONAL_INTERRUPTS_SUPPORT
#define OPTIONAL_OLED_SUPPORT
#define OPTIONAL_RMT_SUPPORT #define OPTIONAL_RMT_SUPPORT
#define OPTIONAL_SERIAL_BLUETOOTH_SUPPORT #define OPTIONAL_SERIAL_BLUETOOTH_SUPPORT
#define OPTIONAL_SPI_FLASH_SUPPORT #define OPTIONAL_SPI_FLASH_SUPPORT
#define OPTIONAL_OLED_VOCABULARY
#define OPTIONAL_CAMERA_VOCABULARY
#define OPTIONAL_BLUETOOTH_VOCABULARY #define OPTIONAL_BLUETOOTH_VOCABULARY
#define OPTIONAL_CAMERA_VOCABULARY
#define OPTIONAL_INTERRUPTS_VOCABULARIES
#define OPTIONAL_OLED_VOCABULARY
#define OPTIONAL_RMT_VOCABULARY #define OPTIONAL_RMT_VOCABULARY
#define OPTIONAL_SPI_FLASH_VOCABULARY #define OPTIONAL_SPI_FLASH_VOCABULARY

View File

@ -22,9 +22,10 @@
#define SIM_HEAP_SIZE (100 * 1024 + 1024 * 1024) #define SIM_HEAP_SIZE (100 * 1024 + 1024 * 1024)
#define OPTIONAL_OLED_VOCABULARY
#define OPTIONAL_CAMERA_VOCABULARY
#define OPTIONAL_BLUETOOTH_VOCABULARY #define OPTIONAL_BLUETOOTH_VOCABULARY
#define OPTIONAL_CAMERA_VOCABULARY
#define OPTIONAL_INTERRUPTS_VOCABULARIES
#define OPTIONAL_OLED_VOCABULARY
#define OPTIONAL_RMT_VOCABULARY #define OPTIONAL_RMT_VOCABULARY
#define OPTIONAL_SPI_FLASH_VOCABULARY #define OPTIONAL_SPI_FLASH_VOCABULARY
@ -104,9 +105,6 @@ static cell_t *simulated(cell_t *sp, const char *op) {
} else if (op == STR_digitalWrite) { } else if (op == STR_digitalWrite) {
sp -= 2; sp -= 2;
return sp; return sp;
} else if (op == STR_gpio_install_isr_service) {
*sp = 0;
return sp;
} else if (op == STR_SERIAL_AVAILABLE) { } else if (op == STR_SERIAL_AVAILABLE) {
*++sp = 1; *++sp = 1;
return sp; return sp;

View File

@ -474,45 +474,6 @@ WiFi.softAPgetStationNum ( -- num )
MDNS.begin ( name-z -- ) Start multicast dns MDNS.begin ( name-z -- ) Start multicast dns
</pre> </pre>
<h5>SPI Flash</h5>
These words are inside the <code>spi_flash</code> vocabulary.
<p><b>
NOTE: Starting in v7.0.7.13 the optional module spi-flash.h must be
placed next to ESP32forth.ino to include this capability.
</b></p>
<pre>
spi_flash_init ( -- ) Init driver access.
spi_flash_get_chip_size ( -- n ) Get flash size.
spi_flash_erase_sector ( sector -- err ) Erase a sector.
spi_flash_erase_range ( addr size -- err ) Erase a range.
spi_flash_write ( destaddr src size -- err ) Write to flash.
spi_flash_write_encrypted ( destaddr src size -- err ) Write encrypted.
spi_flash_read ( srcaddr dst size -- err ) Read from flash.
spi_flash_read_encrypted ( srcaddr dst size -- err ) Read encrypted.
spi_flash_mmap ( srcaddr size memtype out outhandle -- err ) Map region.
spi_flash_mmap_pages ( pages pages# memtype out outhandle -- err ) Map pages.
spi_flash_munmap ( handle -- ) Unmap region.
spi_flash_mmap_dump ( -- ) Dump memory map.
spi_flash_mmap_get_free_pages ( memtype -- n ) Get free pages.
spi_flash_cache2phys ( a -- addr ) Get flash addr.
spi_flash_phys2cache ( addr memtype -- a ) Get mapped flash addr.
spi_flash_cache_enabled ( -- f ) Is flash enabled.
esp_partition_t_size ( -- n ) sizeof(esp_parition_t).
esp_partition_find ( type subtype szlabel -- it ) Get partition iterator.
esp_partition_find_first ( type subtype szlabel -- part ) Get first partition.
esp_partition_get ( it -- part ) Get current partition.
esp_partition_next ( it -- it' ) Get next partition.
esp_partition_iterator_release ( it -- ) Free iterator.
esp_partition_verify ( part -- part' ) Verify partition.
esp_partition_read ( part srcoff dst size -- err ) Read from partition.
esp_partition_write ( part dstoff src size -- err ) Write to partition.
esp_partition_erase_range ( part start size -- err ) Erase range.
esp_partition_mmap ( part off size memtype out outhandle -- err ) Map memory.
esp_partition_get_sha256 ( part a -- err ) Get sha256 digest.
esp_partition_check_identity ( part part -- f ) Check partitions for equality.
</pre>
<h5>SPIFFS</h5> <h5>SPIFFS</h5>
These words are inside the <code>SPIFFS</code> vocabulary. These words are inside the <code>SPIFFS</code> vocabulary.
<pre> <pre>
@ -614,6 +575,169 @@ Wire.writeTransmission ( addr a n sendstop -- err )
Wire.readTransmission ( addr a n sendstop acount -- err ) Wire.readTransmission ( addr a n sendstop acount -- err )
</pre> </pre>
<h5>SD</h5>
These words are inside the <code>SD</code> vocabulary.
They allow use of an SDcard over SPI.
<pre>
SD.begin ( -- ok ) uses all the defaults "/sd" etc.
SD.beginDefaults ( -- sspin SPIClass frequency mountpointsz maxfiles format_if_empty )
( SS SPI 4000000 "/sd" 5 false )
SD.beginFull ( sspin SPIClass frequency mountpoint maxfiles format_if_empty -- ok )
SD.end ( -- )
SD.cardType ( -- n )
SD.totalBytes ( -- n )
SD.usedBytes ( -- n )
</pre>
<h5>SD_MMC</h5>
These words are inside the <code>SD_MMC</code> vocabulary.
They allow use of an SDcard over MMC internal interface.
<br/>
Note, SD_MMC is unavailable on ESP32-S2 and ESP32-C3.
<pre>
SD_MMC.begin ( -- ok ) uses all the defaults "/sdcard" etc.
SD_MMC.beginDefaults ( -- mountsz mode1bit format_if_fail )
( "/sdcard" false false )
( sdmmc_freq not supported for generality )
SD_MMC.beginFull ( mountsz mode1bit format_if_fail -- ok )
SD_MMC.end ( -- )
SD_MMC.cardType ( -- n )
SD_MMC.totalBytes ( -- n )
SD_MMC.usedBytes ( -- n )
</pre>
<h5 id="tasks">Tasks</h5>
These words are inside the <code>TASKS</code> vocabulary.
<pre>
PAUSE ( -- ) Yield to other tasks.
MS ( n -- ) Pause for some number of milliseconds (yields to other tasks).
TASK ( xt dsz rsz "name" -- ) Create a new task with dsz size data stack
and rsz size return stack running xt.
START-TASK ( task -- ) Activate a task.
.TASKS ( -- ) List running tasks.
Example:
tasks
: hi begin ." Time is: " ms-ticks . cr 1000 ms again ;
' hi 100 100 task my-counter
my-counter start-task
</pre>
<h5>RTOS</h5>
These words are inside the <code>RTOS</code> vocabulary.
<pre>
xPortGetCoreID ( -- n )
xTaskCreatePinnedToCore ( fn name stack-depth params priority taskout coreid -- )
vTaskDelete ( task ) -- )
</pre>
<h3 id="webui">ESP32 WebUI</h3>
<p>
A terminal over the web can be activated.
Contact at port printed or via mDNS <a href="http://forth/">http://forth/</a>.
</p>
<pre>
webui ( network-z password-z -- ) login and start webui
login ( network-z password-z -- ) login to wifi only
</pre>
<p>Usage:</p>
<pre>
z" NETWORK-NAME" z" PASSWORD" webui
</pre>
<p>
See <a href="https://github.com/flagxor/ueforth/blob/main/esp32/web_interface.fs">web_interface.fs</a>.
</p>
<h3 id="autoexec">Autoexec.fs</h3>
<p>
NOTE: This section describes one mechanism for running code at startup.
See <a href="#dictimages">this</a> for an alternate option.
</p>
<p>
The system will automatically attempt to mount SPIFFS filesystem at <code>/spiffs</code>.
It will then at start attempt to load <code>/spiffs/autoexec.fs</code>
</p>
<p>
One way this feature can be used to configure the Web UI to start by default.
When doing this, be sure to test your Web UI settings work well first.
</p>
<pre>
r| z" NETWORK-NAME" z" PASSWORD" webui | s" /spiffs/autoexec.fs" dump-file
</pre>
<p>
To remove a previously configured <code>autoexec.fs</code> you will need
to be able to reboot in a mode with Forth. One way to do this is to search
for the line in the .ino file that refers to <code>autoexec.fs</code>
and replace it with a different name. Then run the following:
</p>
<pre>
s" /spiffs/autoexec.fs" delete-file
</pre>
<p>
See <a href="https://github.com/flagxor/ueforth/blob/main/esp32/autoboot.fs">autoboot.fs</a>.
</p>
<h3>ESP32forth Optional Modules</h3>
<p>
Several optional modules are now available in the <code>optional/</code>
directory next to ESP32forth.ino. To use these modules,
move them up a directory to be adjacent to ESP32forth.ino.
</p>
<h5>SPI Flash</h5>
These words are inside the <code>spi_flash</code> vocabulary.
<p><b>
NOTE: Starting in v7.0.7.13 the optional module spi-flash.h must be
placed next to ESP32forth.ino to include this capability.
</b></p>
<pre>
spi_flash_init ( -- ) Init driver access.
spi_flash_get_chip_size ( -- n ) Get flash size.
spi_flash_erase_sector ( sector -- err ) Erase a sector.
spi_flash_erase_range ( addr size -- err ) Erase a range.
spi_flash_write ( destaddr src size -- err ) Write to flash.
spi_flash_write_encrypted ( destaddr src size -- err ) Write encrypted.
spi_flash_read ( srcaddr dst size -- err ) Read from flash.
spi_flash_read_encrypted ( srcaddr dst size -- err ) Read encrypted.
spi_flash_mmap ( srcaddr size memtype out outhandle -- err ) Map region.
spi_flash_mmap_pages ( pages pages# memtype out outhandle -- err ) Map pages.
spi_flash_munmap ( handle -- ) Unmap region.
spi_flash_mmap_dump ( -- ) Dump memory map.
spi_flash_mmap_get_free_pages ( memtype -- n ) Get free pages.
spi_flash_cache2phys ( a -- addr ) Get flash addr.
spi_flash_phys2cache ( addr memtype -- a ) Get mapped flash addr.
spi_flash_cache_enabled ( -- f ) Is flash enabled.
esp_partition_t_size ( -- n ) sizeof(esp_parition_t).
esp_partition_find ( type subtype szlabel -- it ) Get partition iterator.
esp_partition_find_first ( type subtype szlabel -- part ) Get first partition.
esp_partition_get ( it -- part ) Get current partition.
esp_partition_next ( it -- it' ) Get next partition.
esp_partition_iterator_release ( it -- ) Free iterator.
esp_partition_verify ( part -- part' ) Verify partition.
esp_partition_read ( part srcoff dst size -- err ) Read from partition.
esp_partition_write ( part dstoff src size -- err ) Write to partition.
esp_partition_erase_range ( part start size -- err ) Erase range.
esp_partition_mmap ( part off size memtype out outhandle -- err ) Map memory.
esp_partition_get_sha256 ( part a -- err ) Get sha256 digest.
esp_partition_check_identity ( part part -- f ) Check partitions for equality.
</pre>
<h5>Camera</h5> <h5>Camera</h5>
These words are inside the <code>camera</code> vocabulary. These words are inside the <code>camera</code> vocabulary.
<p><b> <p><b>
@ -718,39 +842,12 @@ server ( port -- ) Start an image server at port,
e.g. http://IP/image will produce an image e.g. http://IP/image will produce an image
</pre> </pre>
<h5>SD</h5>
These words are inside the <code>SD</code> vocabulary.
They allow use of an SDcard over SPI.
<pre>
SD.begin ( -- ok ) uses all the defaults "/sd" etc.
SD.beginDefaults ( -- sspin SPIClass frequency mountpointsz maxfiles format_if_empty )
( SS SPI 4000000 "/sd" 5 false )
SD.beginFull ( sspin SPIClass frequency mountpoint maxfiles format_if_empty -- ok )
SD.end ( -- )
SD.cardType ( -- n )
SD.totalBytes ( -- n )
SD.usedBytes ( -- n )
</pre>
<h5>SD_MMC</h5>
These words are inside the <code>SD_MMC</code> vocabulary.
They allow use of an SDcard over MMC internal interface.
<br/>
Note, SD_MMC is unavailable on ESP32-S2 and ESP32-C3.
<pre>
SD_MMC.begin ( -- ok ) uses all the defaults "/sdcard" etc.
SD_MMC.beginDefaults ( -- mountsz mode1bit format_if_fail )
( "/sdcard" false false )
( sdmmc_freq not supported for generality )
SD_MMC.beginFull ( mountsz mode1bit format_if_fail -- ok )
SD_MMC.end ( -- )
SD_MMC.cardType ( -- n )
SD_MMC.totalBytes ( -- n )
SD_MMC.usedBytes ( -- n )
</pre>
<h5 id="interrupts">Interrupts</h5> <h5 id="interrupts">Interrupts</h5>
These words are inside the <code>INTERRUPTS</code> vocabulary. These words are inside the <code>INTERRUPTS</code> vocabulary.
<p><b>
NOTE: Starting in v7.0.7.15 the optional module interrupts.h must be
placed next to ESP32forth.ino to include this capability.
</b></p>
<p>High Level words:</p> <p>High Level words:</p>
<pre> <pre>
@ -758,15 +855,13 @@ pinchange ( xt pin -- ) Call xt when pin changes.
</pre> </pre>
<p>Example:</p> <p>Example:</p>
<pre> <pre>
17 input pinMode 17 input pinMode
: test ." pinvalue: " 17 digitalRead . cr ; : test ." pinvalue: " 17 digitalRead . cr ;
' test 17 pinchange ' test 17 pinchange
</pre> </pre>
<h5 id="interrupts">Interrupts</h5> <p>Low Level words:</p>
These words are inside the <code>interrupts</code> vocabulary.
<pre> <pre>
ESP_INTR_FLAG_DEFAULT -- Default handler allows per pin routing ESP_INTR_FLAG_DEFAULT -- Default handler allows per pin routing
@ -887,26 +982,12 @@ rmt_clr_intr_enable_mask --- DEPRECATED interrupt handled by driver
rmt_set_pin --- DEPRECATED use rmt_set_gpio instead rmt_set_pin --- DEPRECATED use rmt_set_gpio instead
</pre> </pre>
<h5 id="tasks">Tasks</h5>
These words are inside the <code>TASKS</code> vocabulary.
<pre>
PAUSE ( -- ) Yield to other tasks.
MS ( n -- ) Pause for some number of milliseconds (yields to other tasks).
TASK ( xt dsz rsz "name" -- ) Create a new task with dsz size data stack
and rsz size return stack running xt.
START-TASK ( task -- ) Activate a task.
.TASKS ( -- ) List running tasks.
Example:
tasks
: hi begin ." Time is: " ms-ticks . cr 1000 ms again ;
' hi 100 100 task my-counter
my-counter start-task
</pre>
<h5 id="timers">Timers</h5> <h5 id="timers">Timers</h5>
These words are inside the <code>TIMERS</code> vocabulary. These words are inside the <code>TIMERS</code> vocabulary.
<p><b>
NOTE: Starting in v7.0.7.15 the optional module interrupts.h must be
placed next to ESP32forth.ino to include this capability.
</b></p>
<br/><b>NOTE: These are low level ESP32 timers. For a periodic background <br/><b>NOTE: These are low level ESP32 timers. For a periodic background
operation, you'll probably want to use <a href="#tasks">TASKS</a>.</b> operation, you'll probably want to use <a href="#tasks">TASKS</a>.</b>
@ -974,72 +1055,6 @@ TIMGn_Tx_INT_ST_REG ( n -- a )
TIMGn_Tx_INT_CLR_REG ( n -- a ) TIMGn_Tx_INT_CLR_REG ( n -- a )
</pre> </pre>
<h5>RTOS</h5>
These words are inside the <code>RTOS</code> vocabulary.
<pre>
xPortGetCoreID ( -- n )
xTaskCreatePinnedToCore ( fn name stack-depth params priority taskout coreid -- )
vTaskDelete ( task ) -- )
</pre>
<h3 id="webui">ESP32 WebUI</h3>
<p>
A terminal over the web can be activated.
Contact at port printed or via mDNS <a href="http://forth/">http://forth/</a>.
</p>
<pre>
webui ( network-z password-z -- ) login and start webui
login ( network-z password-z -- ) login to wifi only
</pre>
<p>Usage:</p>
<pre>
z" NETWORK-NAME" z" PASSWORD" webui
</pre>
<p>
See <a href="https://github.com/flagxor/ueforth/blob/main/esp32/web_interface.fs">web_interface.fs</a>.
</p>
<h3 id="autoexec">Autoexec.fs</h3>
<p>
NOTE: This section describes one mechanism for running code at startup.
See <a href="#dictimages">this</a> for an alternate option.
</p>
<p>
The system will automatically attempt to mount SPIFFS filesystem at <code>/spiffs</code>.
It will then at start attempt to load <code>/spiffs/autoexec.fs</code>
</p>
<p>
One way this feature can be used to configure the Web UI to start by default.
When doing this, be sure to test your Web UI settings work well first.
</p>
<pre>
r| z" NETWORK-NAME" z" PASSWORD" webui | s" /spiffs/autoexec.fs" dump-file
</pre>
<p>
To remove a previously configured <code>autoexec.fs</code> you will need
to be able to reboot in a mode with Forth. One way to do this is to search
for the line in the .ino file that refers to <code>autoexec.fs</code>
and replace it with a different name. Then run the following:
</p>
<pre>
s" /spiffs/autoexec.fs" delete-file
</pre>
<p>
See <a href="https://github.com/flagxor/ueforth/blob/main/esp32/autoboot.fs">autoboot.fs</a>.
</p>
<h3 id="adding_words">Adding Words</h3> <h3 id="adding_words">Adding Words</h3>
<p> <p>

View File

@ -51,6 +51,9 @@ enum {
#undef V #undef V
}; };
static cell_t *forth_run(cell_t *init_rp) {
return 0;
}
int main(int argc, char *argv[]) { int main(int argc, char *argv[]) {
if (argc == 2 && strcmp(argv[1], "cases") == 0) { if (argc == 2 && strcmp(argv[1], "cases") == 0) {
@ -75,6 +78,8 @@ int main(int argc, char *argv[]) {
TIER0_OPCODE_LIST TIER0_OPCODE_LIST
#undef Z #undef Z
} else if (argc == 2 && strcmp(argv[1], "sys") == 0) { } else if (argc == 2 && strcmp(argv[1], "sys") == 0) {
(void) g_sys;
(void) forth_run;
G_SYS *g_sys = 0; G_SYS *g_sys = 0;
#define G_SYS 256 #define G_SYS 256
printf(" const g_sys = %d;\n", G_SYS); printf(" const g_sys = %d;\n", G_SYS);