diff --git a/ueforth/esp32/template.ino b/ueforth/esp32/template.ino index a603303..1332f66 100644 --- a/ueforth/esp32/template.ino +++ b/ueforth/esp32/template.ino @@ -54,6 +54,7 @@ # define HEAP_SIZE 2 * 1024 # define STACK_SIZE 32 #endif +#define INTERRUPT_STACK_CELLS 16 #define PLATFORM_OPCODE_LIST \ /* Memory Allocation */ \ @@ -162,6 +163,7 @@ # define OPTIONAL_INTERRUPTS_SUPPORT #else # include "esp_intr_alloc.h" +# include "driver/timer.h" # include "driver/gpio.h" # define OPTIONAL_INTERRUPTS_SUPPORT \ Y(gpio_config, n0 = gpio_config((const gpio_config_t *) a0)) \ @@ -185,12 +187,13 @@ Y(gpio_deep_sleep_hold_dis, gpio_deep_sleep_hold_dis()) \ Y(gpio_install_isr_service, n0 = gpio_install_isr_service(n0)) \ Y(gpio_uninstall_isr_service, gpio_uninstall_isr_service()) \ - Y(gpio_isr_handler_add, n0 = GpioIsrHandlerAdd((gpio_num_t) n2, n1, n0); NIPn(2)) \ + Y(gpio_isr_handler_add, n0 = GpioIsrHandlerAdd(n2, n1, n0); NIPn(2)) \ Y(gpio_isr_handler_remove, n0 = gpio_isr_handler_remove((gpio_num_t) n0)) \ Y(gpio_set_drive_capability, n0 = gpio_set_drive_capability((gpio_num_t) n1, (gpio_drive_cap_t) n0); NIP) \ Y(gpio_get_drive_capability, n0 = gpio_get_drive_capability((gpio_num_t) n1, (gpio_drive_cap_t *) a0); NIP) \ Y(esp_intr_alloc, n0 = EspIntrAlloc(n4, n3, n2, n1, a0); NIPn(4)) \ - Y(esp_intr_free, n0 = esp_intr_free((intr_handle_t) n0)) + Y(esp_intr_free, n0 = esp_intr_free((intr_handle_t) n0)) \ + Y(timer_isr_register, n0 = TimerIsrRegister(n5, n4, n3, n2, n1, a0); NIPn(5)) #endif #ifndef ENABLE_CAMERA_SUPPORT @@ -407,6 +410,7 @@ static String string_value; static cell_t EspIntrAlloc(cell_t source, cell_t flags, cell_t xt, cell_t arg, cell_t *ret); static cell_t GpioIsrHandlerAdd(cell_t pin, cell_t xt, cell_t arg); +static cell_t TimerIsrRegister(cell_t group, cell_t timer, cell_t xt, cell_t arg, void *ret); {{core}} {{interp}} @@ -449,8 +453,8 @@ static void InvokeWebServerOn(WebServer *ws, const char *url, cell_t xt) { cell_t code[2]; code[0] = xt; code[1] = g_sys.YIELD_XT; - cell_t stack[16]; - cell_t rstack[16]; + cell_t stack[INTERRUPT_STACK_CELLS]; + cell_t rstack[INTERRUPT_STACK_CELLS]; cell_t *rp = rstack; *++rp = (cell_t) (stack + 1); *++rp = (cell_t) code; @@ -469,8 +473,8 @@ static void IRAM_ATTR HandleInterrupt(void *arg) { cell_t code[2]; code[0] = args->xt; code[1] = g_sys.YIELD_XT; - cell_t stack[16]; - cell_t rstack[16]; + cell_t stack[INTERRUPT_STACK_CELLS]; + cell_t rstack[INTERRUPT_STACK_CELLS]; stack[0] = args->arg; cell_t *rp = rstack; *++rp = (cell_t) (stack + 1); @@ -494,6 +498,14 @@ static cell_t GpioIsrHandlerAdd(cell_t pin, cell_t xt, cell_t arg) { return gpio_isr_handler_add((gpio_num_t) pin, HandleInterrupt, args); } +static cell_t TimerIsrRegister(cell_t group, cell_t timer, cell_t xt, cell_t arg, cell_t flags, 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 timer_isr_register((timer_group_t) group, (timer_idx_t) timer, HandleInterrupt, args, flags, (timer_isr_handle_t *) ret); +} + void setup() { cell_t *heap = (cell_t *) malloc(HEAP_SIZE); forth_init(0, 0, heap, boot, sizeof(boot)); diff --git a/ueforth/esp32/timers.fs b/ueforth/esp32/timers.fs index 1ea3008..4f2b1d0 100644 --- a/ueforth/esp32/timers.fs +++ b/ueforth/esp32/timers.fs @@ -1,4 +1,4 @@ -vocabulary timers timers definitions also registers +vocabulary timers timers definitions also registers also interrupts $3ff5f000 constant TIMG_BASE ( group n = 0/1, timer x = 0/1, watchdog m = 0-5 ) @@ -42,4 +42,6 @@ $3ff5f000 constant TIMG_BASE : alarm-enable! ( v t ) >r 10 $400 r> t>nx TIMGn_TxCONFIG_REG m! ; : alarm-enable@ ( v t ) >r 10 $400 r> t>nx TIMGn_TxCONFIG_REG m@ ; +: onalarm ( xt t ) swap >r t>nx r> 0 0 0 timer_isr_register throw ; + only forth definitions diff --git a/ueforth/site/ESP32forth.html b/ueforth/site/ESP32forth.html index 06e5217..307c6ce 100644 --- a/ueforth/site/ESP32forth.html +++ b/ueforth/site/ESP32forth.html @@ -352,6 +352,51 @@ gpio_get_drive_capability ( pin cap* -- 0/err ) esp_intr_alloc ( source flags xt args handle* -- 0/err ) esp_intr_free ( handle -- 0/err ) + +timer_isr_register ( group timer xt arg ret -- 0/err ) + + +
Timers
+These words are inside the TIMERS vocabulary. + +

High Level words:

+
+( timer t = 0-3 )
+timer@ ( t -- lo hi )
+timer! ( lo hi t -- )
+alarm ( t -- a )
+enable! ( f t -- ) Timer enable/disable
+increase! ( f t -- ) Timer increasing/decreasing
+divider! ( n t -- ) Timer divider 2 - 65535
+edgeint! ( f t -- ) Edge trigger
+levelint! ( f t -- ) Level trigger
+alarm-enable! ( f t -- ) Alarm enable
+alarm-enable@ ( t -- f ) Alarm enabled?
+onalarm ( xt t -- ) Set callback
+
+ +

Low Level words:

+
+( group n = 0/1, timer x = 0/1, watchdog m = 0-5 )
+
+TIMGn_TxCONFIG_REG ( n x -- a )
+TIMGn_TxLOHI_REG ( n x -- a )
+TIMGn_TxUPDATE_REG ( n x -- a )
+TIMGn_TxALARMLOHI_REG ( n x -- a )
+TIMGn_TxLOADLOHI_REG ( n x -- a )
+TIMGn_TxLOAD_REG ( n x -- a )
+
+TIMGn_Tx_WDTCONFIGm_REG ( n m -- a )
+TIMGn_Tx_WDTFEED_REG ( n -- a )
+TIMGn_Tx_WDTWPROTECT_REG ( n -- a )
+
+TIMGn_RTCCALICFG_REG ( n -- a )
+TIMGn_RTCCALICFG1_REG ( n -- a )
+
+TIMGn_Tx_INT_ENA_REG ( n -- a )
+TIMGn_Tx_INT_RAW_REG ( n -- a )
+TIMGn_Tx_INT_ST_REG ( n -- a )
+TIMGn_Tx_INT_CLR_REG ( n -- a )
 
RTOS