diff options
author | Mitch Bradley <wmb@firmworks.com> | 2017-01-03 13:22:50 -1000 |
---|---|---|
committer | Mitch Bradley <wmb@firmworks.com> | 2017-01-03 13:34:40 -1000 |
commit | 1df190251fd04c9fa426f7ef69d3a8a084460b5e (patch) | |
tree | a32511a845ab3db5ec615209b773911426e5d8a2 | |
parent | e36b2ecec8cd07cacf59b6a49dc3e860d4e628b0 (diff) | |
download | cforth-1df190251fd04c9fa426f7ef69d3a8a084460b5e.tar.gz |
First try at ESP32 version
-rw-r--r-- | build/esp32/.gitignore | 3 | ||||
-rw-r--r-- | build/esp32/Makefile | 34 | ||||
-rw-r--r-- | build/esp32/sdk_build/.gitignore | 2 | ||||
-rw-r--r-- | build/esp32/sdk_build/Makefile | 2 | ||||
-rw-r--r-- | build/esp32/sdk_build/main/component.mk | 6 | ||||
-rw-r--r-- | build/esp32/sdk_build/sdkconfig | 187 | ||||
-rw-r--r-- | src/app/esp32/app.fth | 42 | ||||
-rw-r--r-- | src/app/esp32/consio.c | 113 | ||||
-rw-r--r-- | src/app/esp32/fileio.c | 221 | ||||
-rw-r--r-- | src/app/esp32/targets.mk | 85 | ||||
-rw-r--r-- | src/app/esp32/textend.c | 33 | ||||
-rw-r--r-- | src/app/esp32/tmain.c | 17 | ||||
-rw-r--r-- | src/cforth/targets.mk | 2 |
13 files changed, 746 insertions, 1 deletions
diff --git a/build/esp32/.gitignore b/build/esp32/.gitignore new file mode 100644 index 0000000..ece9a1a --- /dev/null +++ b/build/esp32/.gitignore @@ -0,0 +1,3 @@ +*.DSYM +tccalls.fth +tdate.c diff --git a/build/esp32/Makefile b/build/esp32/Makefile new file mode 100644 index 0000000..7a9b0ab --- /dev/null +++ b/build/esp32/Makefile @@ -0,0 +1,34 @@ +# Builds CForth for ESP8266 + +default: forth.elf + +TOPDIR=../.. + +# CONFIG += -DBITS32 -DT16 +CONFIG += -DBITS32 + +CFLAGS += -m32 + +CC := gcc + +# Change these to reflect the locations of external stuff on your system, +# either here or on the command line, e.g. COMPORT=COM27 make download +XTGCCPATH ?= /c/msys32/opt/xtensa-esp32-elf/bin/ +CROSS ?= $(XTGCCPATH)xtensa-esp32-elf- + +# ESP32 SDK +IDF_PATH ?= $(TOPDIR)/../esp-idf +IDF_TEMPLATE_PATH ?= $(TOPDIR)/../esp-idf-template + +COMPORT ?= COM27 + +include $(TOPDIR)/src/app/esp32/targets.mk + +forth.elf: app.o + @IDF_PATH=$(IDF_PATH) make --no-print-directory -C sdk_build + +flash: app.o + @IDF_PATH=$(IDF_PATH) make --no-print-directory -C sdk_build flash + +clean:: + @rm -rf sdk_build/build diff --git a/build/esp32/sdk_build/.gitignore b/build/esp32/sdk_build/.gitignore new file mode 100644 index 0000000..13fa9a7 --- /dev/null +++ b/build/esp32/sdk_build/.gitignore @@ -0,0 +1,2 @@ +build/ +sdkconfig.old diff --git a/build/esp32/sdk_build/Makefile b/build/esp32/sdk_build/Makefile new file mode 100644 index 0000000..f97e089 --- /dev/null +++ b/build/esp32/sdk_build/Makefile @@ -0,0 +1,2 @@ +PROJECT_NAME := forth +include $(IDF_PATH)/make/project.mk diff --git a/build/esp32/sdk_build/main/component.mk b/build/esp32/sdk_build/main/component.mk new file mode 100644 index 0000000..c96f957 --- /dev/null +++ b/build/esp32/sdk_build/main/component.mk @@ -0,0 +1,6 @@ +# +# Main component makefile. + +# COMPONENT_OBJS := ../../../app.o main.o + +COMPONENT_OBJS := ../../../app.o diff --git a/build/esp32/sdk_build/sdkconfig b/build/esp32/sdk_build/sdkconfig new file mode 100644 index 0000000..f1bb237 --- /dev/null +++ b/build/esp32/sdk_build/sdkconfig @@ -0,0 +1,187 @@ +# +# Automatically generated file; DO NOT EDIT. +# Espressif IoT Development Framework Configuration +# + +# +# SDK tool configuration +# +CONFIG_TOOLPREFIX="xtensa-esp32-elf-" +CONFIG_PYTHON="python" + +# +# Bootloader config +# +# CONFIG_LOG_BOOTLOADER_LEVEL_NONE is not set +# CONFIG_LOG_BOOTLOADER_LEVEL_ERROR is not set +CONFIG_LOG_BOOTLOADER_LEVEL_WARN=y +# CONFIG_LOG_BOOTLOADER_LEVEL_INFO is not set +# CONFIG_LOG_BOOTLOADER_LEVEL_DEBUG is not set +# CONFIG_LOG_BOOTLOADER_LEVEL_VERBOSE is not set +CONFIG_LOG_BOOTLOADER_LEVEL=2 + +# +# Security features +# +# CONFIG_SECURE_BOOT_ENABLED is not set +# CONFIG_FLASH_ENCRYPTION_ENABLED is not set + +# +# Serial flasher config +# +CONFIG_ESPTOOLPY_PORT="COM27" +CONFIG_ESPTOOLPY_BAUD_115200B=y +# CONFIG_ESPTOOLPY_BAUD_230400B is not set +# CONFIG_ESPTOOLPY_BAUD_921600B is not set +# CONFIG_ESPTOOLPY_BAUD_2MB is not set +# CONFIG_ESPTOOLPY_BAUD_OTHER is not set +CONFIG_ESPTOOLPY_BAUD_OTHER_VAL=115200 +CONFIG_ESPTOOLPY_BAUD=115200 +# CONFIG_ESPTOOLPY_COMPRESSED is not set +# CONFIG_ESPTOOLPY_FLASHMODE_QIO is not set +# CONFIG_ESPTOOLPY_FLASHMODE_QOUT is not set +CONFIG_ESPTOOLPY_FLASHMODE_DIO=y +# CONFIG_ESPTOOLPY_FLASHMODE_DOUT is not set +CONFIG_ESPTOOLPY_FLASHMODE="dio" +# CONFIG_ESPTOOLPY_FLASHFREQ_80M is not set +CONFIG_ESPTOOLPY_FLASHFREQ_40M=y +# CONFIG_ESPTOOLPY_FLASHFREQ_26M is not set +# CONFIG_ESPTOOLPY_FLASHFREQ_20M is not set +CONFIG_ESPTOOLPY_FLASHFREQ="40m" +# CONFIG_ESPTOOLPY_FLASHSIZE_1MB is not set +CONFIG_ESPTOOLPY_FLASHSIZE_2MB=y +# CONFIG_ESPTOOLPY_FLASHSIZE_4MB is not set +# CONFIG_ESPTOOLPY_FLASHSIZE_8MB is not set +# CONFIG_ESPTOOLPY_FLASHSIZE_16MB is not set +CONFIG_ESPTOOLPY_FLASHSIZE="2MB" + +# +# Partition Table +# +CONFIG_PARTITION_TABLE_SINGLE_APP=y +# CONFIG_PARTITION_TABLE_TWO_OTA is not set +# CONFIG_PARTITION_TABLE_CUSTOM is not set +CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions.csv" +CONFIG_PARTITION_TABLE_CUSTOM_APP_BIN_OFFSET=0x10000 +CONFIG_PARTITION_TABLE_FILENAME="partitions_singleapp.csv" +CONFIG_APP_OFFSET=0x10000 +CONFIG_PHY_DATA_OFFSET=0xf000 +CONFIG_OPTIMIZATION_LEVEL_DEBUG=y +# CONFIG_OPTIMIZATION_LEVEL_RELEASE is not set + +# +# Component config +# +CONFIG_BTC_TASK_STACK_SIZE=3072 +# CONFIG_BLUEDROID_MEM_DEBUG is not set +CONFIG_BT_RESERVE_DRAM=0 + +# +# ESP32-specific config +# +# CONFIG_ESP32_DEFAULT_CPU_FREQ_80 is not set +# CONFIG_ESP32_DEFAULT_CPU_FREQ_160 is not set +CONFIG_ESP32_DEFAULT_CPU_FREQ_240=y +CONFIG_ESP32_DEFAULT_CPU_FREQ_MHZ=240 +CONFIG_ESP32_ENABLE_STACK_WIFI=y +# CONFIG_ESP32_ENABLE_STACK_BT is not set +CONFIG_MEMMAP_SMP=y +# CONFIG_MEMMAP_TRACEMEM is not set +CONFIG_TRACEMEM_RESERVE_DRAM=0x0 +CONFIG_WIFI_ENABLED=y +CONFIG_SYSTEM_EVENT_QUEUE_SIZE=32 +CONFIG_SYSTEM_EVENT_TASK_STACK_SIZE=2048 +CONFIG_MAIN_TASK_STACK_SIZE=4096 +# CONFIG_NEWLIB_STDOUT_ADDCR is not set +# CONFIG_NEWLIB_NANO_FORMAT is not set +# CONFIG_CONSOLE_UART_DEFAULT is not set +CONFIG_CONSOLE_UART_CUSTOM=y +# CONFIG_CONSOLE_UART_NONE is not set +CONFIG_CONSOLE_UART_CUSTOM_NUM_0=y +# CONFIG_CONSOLE_UART_CUSTOM_NUM_1 is not set +CONFIG_CONSOLE_UART_NUM=0 +CONFIG_CONSOLE_UART_TX_GPIO=1 +CONFIG_CONSOLE_UART_RX_GPIO=3 +CONFIG_CONSOLE_UART_BAUDRATE=115200 +# CONFIG_ULP_COPROC_ENABLED is not set +CONFIG_ULP_COPROC_RESERVE_MEM=0 +# CONFIG_ESP32_PANIC_PRINT_HALT is not set +CONFIG_ESP32_PANIC_PRINT_REBOOT=y +# CONFIG_ESP32_PANIC_SILENT_REBOOT is not set +# CONFIG_ESP32_PANIC_GDBSTUB is not set +CONFIG_ESP32_DEBUG_OCDAWARE=y +CONFIG_INT_WDT=y +CONFIG_INT_WDT_TIMEOUT_MS=300 +# CONFIG_TASK_WDT is not set +# CONFIG_ESP32_TIME_SYSCALL_USE_RTC is not set +CONFIG_ESP32_TIME_SYSCALL_USE_RTC_FRC1=y +# CONFIG_ESP32_TIME_SYSCALL_USE_FRC1 is not set +# CONFIG_ESP32_TIME_SYSCALL_USE_NONE is not set +CONFIG_ESP32_RTC_CLOCK_SOURCE_INTERNAL_RC=y +CONFIG_ESP32_DEEP_SLEEP_WAKEUP_DELAY=0 +CONFIG_ESP32_PHY_AUTO_INIT=y +# CONFIG_ESP32_PHY_INIT_DATA_IN_PARTITION is not set +CONFIG_ESP32_PHY_MAX_TX_POWER=20 +# CONFIG_ETHERNET is not set + +# +# FreeRTOS +# +CONFIG_FREERTOS_UNICORE=y +CONFIG_FREERTOS_CORETIMER_0=y +# CONFIG_FREERTOS_CORETIMER_1 is not set +# CONFIG_FREERTOS_CORETIMER_2 is not set +CONFIG_FREERTOS_HZ=1000 +CONFIG_FREERTOS_ASSERT_ON_UNTESTED_FUNCTION=y +# CONFIG_FREERTOS_CHECK_STACKOVERFLOW_NONE is not set +CONFIG_FREERTOS_CHECK_STACKOVERFLOW_PTRVAL=y +# CONFIG_FREERTOS_CHECK_STACKOVERFLOW_CANARY is not set +CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=3 +CONFIG_FREERTOS_ASSERT_FAIL_ABORT=y +# CONFIG_FREERTOS_ASSERT_FAIL_PRINT_CONTINUE is not set +# CONFIG_FREERTOS_ASSERT_DISABLE is not set +CONFIG_FREERTOS_BREAK_ON_SCHEDULER_START_JTAG=y +# CONFIG_ENABLE_MEMORY_DEBUG is not set +CONFIG_FREERTOS_ISR_STACKSIZE=1536 +# CONFIG_FREERTOS_LEGACY_HOOKS is not set +# CONFIG_FREERTOS_DEBUG_INTERNALS is not set + +# +# Log output +# +# CONFIG_LOG_DEFAULT_LEVEL_NONE is not set +# CONFIG_LOG_DEFAULT_LEVEL_ERROR is not set +# CONFIG_LOG_DEFAULT_LEVEL_WARN is not set +CONFIG_LOG_DEFAULT_LEVEL_INFO=y +# CONFIG_LOG_DEFAULT_LEVEL_DEBUG is not set +# CONFIG_LOG_DEFAULT_LEVEL_VERBOSE is not set +CONFIG_LOG_DEFAULT_LEVEL=3 +CONFIG_LOG_COLORS=y + +# +# LWIP +# +# CONFIG_L2_TO_L3_COPY is not set +CONFIG_LWIP_MAX_SOCKETS=4 +CONFIG_LWIP_THREAD_LOCAL_STORAGE_INDEX=0 +# CONFIG_LWIP_SO_REUSE is not set +CONFIG_LWIP_DHCP_MAX_NTP_SERVERS=1 +# CONFIG_LWIP_IP_FRAG is not set +# CONFIG_LWIP_IP_REASSEMBLY is not set + +# +# mbedTLS +# +CONFIG_MBEDTLS_SSL_MAX_CONTENT_LEN=16384 +# CONFIG_MBEDTLS_DEBUG is not set +CONFIG_MBEDTLS_HARDWARE_AES=y +CONFIG_MBEDTLS_HARDWARE_MPI=y +CONFIG_MBEDTLS_MPI_USE_INTERRUPT=y +CONFIG_MBEDTLS_HARDWARE_SHA=y +CONFIG_MBEDTLS_HAVE_TIME=y +# CONFIG_MBEDTLS_HAVE_TIME_DATE is not set + +# +# SPI Flash driver +# +# CONFIG_SPI_FLASH_ENABLE_COUNTERS is not set diff --git a/src/app/esp32/app.fth b/src/app/esp32/app.fth new file mode 100644 index 0000000..fe9d1a3 --- /dev/null +++ b/src/app/esp32/app.fth @@ -0,0 +1,42 @@ +\ Load file for application-specific Forth extensions + +fl ../../lib/misc.fth +fl ../../lib/dl.fth +fl ../../lib/random.fth +fl ../../lib/ilog2.fth +fl ../../lib/tek.fth + +warning @ warning off +: bye standalone? if restart then bye ; +warning ! + +: .commit ( -- ) 'version cscount type ; + +: .built ( -- ) 'build-date cscount type ; + +: banner ( -- ) + cr ." CForth built " .built + ." from " .commit + cr +; + +0 [if] +\ Replace 'quit' to make CForth auto-run some application code +\ instead of just going interactive. +\ : app banner hex init-i2c showstack quit ; +: interrupt? ( -- flag ) + ." Type a key within 2 seconds to interact" cr + #20 0 do key? if key drop true unloop exit then #100 ms loop + false +; +: load-startup-file ( -- ) " start" included ; +[then] + +: app + banner hex + quit +; + +alias id: \ + +" app.dic" save diff --git a/src/app/esp32/consio.c b/src/app/esp32/consio.c new file mode 100644 index 0000000..7bb65a0 --- /dev/null +++ b/src/app/esp32/consio.c @@ -0,0 +1,113 @@ +/* + * Console I/O routines + */ + +#include "forth.h" +#include "compiler.h" +#include "stdlib.h" +#include "driver/uart.h" + +int isinteractive() { return (1); } +int isstandalone() { return (1); } + +void raw_emit(unsigned char c) +{ + uart_write_bytes(0, &c, 1); +} + +void emit(u_char c, cell *up) +{ + if (c == '\n') + raw_emit('\r'); + raw_emit(c); +} + +u_char key_is_avail = 0; +u_char the_key; + +int key_avail(cell *up) +{ + if (key_is_avail) { + return (cell)-1; + } + if(uart_read_bytes(0, &the_key, 1, 0)) { + key_is_avail = 1; + return (cell)-1; + } + return 0; +} + +int key(cell *up) +{ + cell this_key; + while (!key_avail(up)) {} + key_is_avail = 0; + return (cell)the_key; +} + +static const char *TAG = "forth"; +#define BUF_SIZE (1024) +void uart_on(void) +{ + int uart_num = UART_NUM_0; + uart_config_t uart_config = { + .baud_rate = 115200, + .data_bits = UART_DATA_8_BITS, + .parity = UART_PARITY_DISABLE, + .stop_bits = UART_STOP_BITS_1, + .flow_ctrl = UART_HW_FLOWCTRL_DISABLE, + .rx_flow_ctrl_thresh = 122, + }; + //Set UART parameters + uart_param_config(uart_num, &uart_config); + //Set UART log level +// esp_log_level_set(TAG, ESP_LOG_INFO); + //Set UART pins,(-1: default pin, no change.) + //For UART0, we can just use the default pins. + //uart_set_pin(uart_num, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE); + //Install UART driver( We don't need an event queue here) + //We don't even use a buffer for sending data. + uart_driver_install(uart_num, BUF_SIZE * 2, 0, 0, NULL, 0); +} + +void init_io(int argc, char **argv, cell *up) +{ + key_is_avail = 0; + uart_on(); +} + +int caccept(char *addr, cell count, cell *up) +{ + return lineedit(addr, count, up); +} + +// Defines the resolution of c_puts +void output_redirect(const char *str) { + puts(str); +} + +void alerror(char *str, int len, cell *up) +{ + while (len--) + emit((u_char)*str++, up); + + /* Sequences of calls to error() eventually end with a newline */ + V(NUM_OUT) = 0; +} + +// moreinput() returns 0 when the console input stream has been closed for good +int moreinput() { return (1); } + +char *getmem(u_cell nbytes, cell *up) +{ + return (char *)malloc(nbytes); +} + +void memfree(char *ptr, cell *up) +{ + free(ptr); +} +char * memresize(char *ptr, u_cell nbytes, cell *up) +{ + return (char *)realloc(ptr, nbytes); +} diff --git a/src/app/esp32/fileio.c b/src/app/esp32/fileio.c new file mode 100644 index 0000000..4d72ba3 --- /dev/null +++ b/src/app/esp32/fileio.c @@ -0,0 +1,221 @@ +// I/O subroutines for C Forth 93. +// This code mostly uses C standard I/O, so it should work on most systems. +// +// Exported definitions: +// +// init_io(argc,argv); Initialize io system +// emit(char, up); Output a character +// n = key_avail(); How many characters can be read? +// error(s, up); Print a string on the error stream +// n = caccept(addr, count); Collect a line of input +// char = key(); Get the next input character +// name_input(filename); + +// newlib configuration to match esp-idf/components/newlib/include/sys/config.h +// If we do not do this, we get linker errors about undefined _impure_ptr +#define __DYNAMIC_REENT__ +#define _REENT_SMALL_ + +#include <stdio.h> +#include <string.h> +#include <stdlib.h> +#include <unistd.h> + +#include "forth.h" +#include "compiler.h" + +int ansi_emit(int c, FILE *fd); +extern int key(); +extern void exit(); +extern FILE *fopen(); + +#define STRINGINPUT (FILE *) -1 + +cell +freadline(cell f, cell *sp, cell *up) // Returns IO result, actual and more? on stack +{ + printf("In freadline\n"); + // Stack: adr len -- actual more? + + u_char *adr = (u_char *)sp[1]; + register cell len = sp[0]; + + register cell actual; + register int c; + + sp[0] = -1; // Assume not end of file + + for (actual = 0; actual < len; ) { + if ((c = getc((FILE *)f)) == EOF) { + if (actual == 0) + sp[0] = 0; + + if (ferror((FILE *)f)) { + sp[1] = actual; + return(READFAIL); + } + break; + } + if (c == CNEWLINE) { // Last character of an end-of-line sequence + break; + } + + // Don't store the first half of a 2-character newline sequence + if (c == SNEWLINE[0]) + continue; + + *adr++ = c; +// printf("%c", c); + ++actual; + } +// printf("\n"); + + + sp[1] = actual; + return(0); +} + +cell +pfclose(cell f, cell *up) +{ + return( (cell)fclose((FILE *)f) ); +} + +cell +pfflush(cell f, cell *up) +{ + return( (cell)fflush((FILE *)f) ); +} + +cell +pfsize(cell f, u_cell *high, u_cell *low, cell *up) +{ + FILE *fd = (FILE *)f; + long old, end; + old = ftell(fd); + fseek(fd, 0L, SEEK_END); + end = ftell(fd); + fseek(fd, old, SEEK_SET); + *high = 0; + *low = end; + return((cell)(end==-1 ? SIZEFAIL : 0)); +} + +char * +expand_name(char *name) +{ + char envvar[64], *fnamep, *envp, paren, *fullp; + static char fullname[MAXPATHLEN]; + int ndx; + + fullp = fullname; + fullname[0] = '\0'; + + fnamep = name; + + while (*fnamep) { + if (*fnamep == '$') { + fnamep++; + ndx = 0; + if (*fnamep == '{' || *fnamep == '(') { // multi char env var + paren = (*fnamep++ == '{') ? '}' : ')'; + + while (*fnamep != paren && ndx < MAXPATHLEN && *fnamep != '\0') { + envvar[ndx++] = *(fnamep++); + } + if (*fnamep == paren) { + fnamep++; + } else { + ndx = 0; + fnamep = name; + } + } else /* single char env. var. */ + envvar[ndx++] = *(fnamep++); + envvar[ndx] = '\0'; + + if (ndx > 0 && (envp = getenv(envvar)) != NULL) { + strcpy(fullp, envp); + fullp += strlen(envp); + } else { + printf("Can't find environment variable %s in %s\n", envvar,name); + exit(1); + } + ndx = 0; + } else { + *fullp++ = *fnamep++; + } + } + *fullp = '\0'; + return (fullname); +} + +// r/o Open existing file for reading +// w/o Open or create file for appending +// r/w Open existing for reading and writing +// r/o create-flag or Open or create file for appending, read at beginning +// w/o create-flag or ??? + +// 0:r/o 1:w/o 2:r/w 3: undefined +static char *open_modes[] = { "rb", "ab", "r+b", "" }; +static char *popen_modes[] = { "r", "w", "rw", "" }; +cell pfopen(char *name, int len, int mode, cell *up) +{ + char cstrbuf[MAXPATHLEN]; + char *s = expand_name(altocstr(name, len, cstrbuf, MAXPATHLEN)); + + FILE *res = fopen(s, open_modes[mode&3]); + return (cell)res; +} + +static char *create_modes[] = { "a+b", "wb", "w+b", "" }; +cell pfcreate(char *name, int len, int mode, cell *up) +{ + char cstrbuf[512]; + + return( (cell)fopen(expand_name(altocstr(name, len, cstrbuf, 512)), create_modes[mode&3]) ); +} + +cell pfread(cell *sp, cell len, void *fid, cell *up) // Returns IO result, actual in *sp +{ + size_t ret; + *sp = (cell)fread((void *)*sp, 1, (size_t)len, (FILE *)fid); + + return (*sp == 0) ? ferror((FILE *)fid) : 0; +} + +cell pfwrite(void *adr, cell len, void *fid, cell *up) // Returns IO result, actual in *sp +{ + size_t ret; + ret = (cell)fwrite(adr, 1, (size_t)len, (FILE *)fid); + + return (ret == 0) ? ferror((FILE *)fid) : 0; +} + +cell pfseek(void *fid, u_cell high, u_cell low, cell *up) +{ + (void)fseek((FILE *)fid, low, 0); + return 0; +} + +cell pfposition(void *fid, u_cell *high, u_cell *low, cell *up) +{ + *low = ftell((FILE *)fid); + *high = 0; + return 0; +} + +void clear_log(cell *up) { } +void start_logging(cell *up) { } +void stop_logging(cell *up) { } +cell log_extent(cell *log_base, cell *up) { *log_base = 0; return 0; } + +void pfmarkinput(void *fp, cell *up) {} +void pfprint_input_stack(void) {} + +void read_dictionary(char *name, cell *up) { FTHERROR("read_dictionary unsupported\n"); } + +void write_dictionary(char *name, int len, char *dict, int dictsize, + cell *up, int usersize) +{ + FTHERROR("write_dictionary unsupported\n"); +} diff --git a/src/app/esp32/targets.mk b/src/app/esp32/targets.mk new file mode 100644 index 0000000..110178d --- /dev/null +++ b/src/app/esp32/targets.mk @@ -0,0 +1,85 @@ +# APPPATH is the path to the application code, i.e. this directory +APPPATH=$(TOPDIR)/src/app/esp32 + +# APPLOADFILE is the top-level "Forth load file" for the application code. +APPLOADFILE = app.fth + +# APPSRCS is a list of Forth source files that the application uses, +# i.e. the list of files that APPLOADFILE floads. It's for dependency checking. +APPSRCS = $(wildcard $(APPPATH)/*.fth) + +# Makefile fragment for the final target application + +SRC=$(TOPDIR)/src + +# Target compiler definitions +CROSS ?= /Volumes/case-sensitive/esp-open-sdk/xtensa-lx106-elf/bin/xtensa-lx106-elf- +TCC=$(CROSS)gcc +TLD=$(CROSS)ld +TOBJDUMP=$(CROSS)objdump +TOBJCOPY=$(CROSS)objcopy + +LIBDIRS=-L$(dir $(shell $(TCC) $(TCFLAGS) -print-libgcc-file-name)) + +VPATH += $(SRC)/cforth +VPATH += $(SRC)/lib +VPATH += $(APPPATH) +INCS += -I$(APPPATH) + +INCS += -I$(IDF_TEMPLATE_PATH)/build/include +INCS += -I$(IDF_PATH)/components/freertos/include +INCS += -I$(IDF_PATH)/components/esp32/include +INCS += -I$(IDF_PATH)/components/driver/include +INCS += -I$(IDF_PATH)/components/nvs_flash/include + +include $(SRC)/common.mk +include $(SRC)/cforth/targets.mk + +OPTIMIZE = -O2 + +TCFLAGS += \ + -g \ + -fno-inline-functions \ + -nostdlib \ + -mlongcalls \ + -mtext-section-literals \ + -DXTENSA + +DUMPFLAGS = --disassemble -z -x -s + +# Platform-specific object files for low-level startup and platform I/O + +ttmain.o: vars.h + +PLAT_OBJS += ttmain.o +PLAT_OBJS += tfileio.o + +# Object files for the Forth system and application-specific extensions + +FORTH_OBJS = tembed.o textend.o + +# Recipe for linking the final image + +DICTIONARY=ROM +DICTSIZE=0x4000 + +app.o: tdate.o + @echo Linking $@ ... + @$(TLD) -o $@ -r $(PLAT_OBJS) $(FORTH_OBJS) tdate.o + +# This rule builds a date stamp object that you can include in the image +# if you wish. + +tdate.o: $(PLAT_OBJS) $(FORTH_OBJS) + @(echo "`git rev-parse --verify --short HEAD``if git diff-index --exit-code --name-only HEAD >/dev/null; then echo '-dirty'; fi`" || echo UNKNOWN) >version + @echo 'const char version[] = "'`cat version`'";' >tdate.c + @echo 'const char build_date[] = "'`date --utc +%F\ %R`'";' >>tdate.c + @cat tdate.c + @echo TCC $@ + @$(TCC) -c tdate.c -o $@ + +EXTRA_CLEAN += *.elf *.dump *.nm *.img date.c $(FORTH_OBJS) $(PLAT_OBJS) tdate.c version + +PREFIX += CBP=$(realpath $(TOPDIR)/src) + +include $(SRC)/cforth/embed/targets.mk diff --git a/src/app/esp32/textend.c b/src/app/esp32/textend.c new file mode 100644 index 0000000..9f572f5 --- /dev/null +++ b/src/app/esp32/textend.c @@ -0,0 +1,33 @@ +// Forth interfaces to platform-specific C routines +// See "ccalls" below. + +#include "forth.h" +#include "freertos/FreeRTOS.h" + +extern cell *callback_up; + +cell version_adr(void) +{ + extern char version[]; + return (cell)version; +} + +cell build_date_adr(void) +{ + extern char build_date[]; + return (cell)build_date; +} + +void ms(cell msecs) +{ + vTaskDelay(msecs/ portTICK_PERIOD_MS); +} + +extern void software_reset(void); + +cell ((* const ccalls[])()) = { + C(build_date_adr) //c 'build-date { -- a.value } + C(version_adr) //c 'version { -- a.value } + C(ms) //c ms { i.ms -- } + C(software_reset) //c restart { -- } +}; diff --git a/src/app/esp32/tmain.c b/src/app/esp32/tmain.c new file mode 100644 index 0000000..a30b055 --- /dev/null +++ b/src/app/esp32/tmain.c @@ -0,0 +1,17 @@ +// Top-level routine for starting Forth + +#include "forth.h" +#include "esp_system.h" +#include "nvs_flash.h" + + +// Defines startup routine for nodemcu-firmware +void app_main(void) +{ + nvs_flash_init(); + + cell *up; + init_io(0, (char **)0, (cell *)up); // Perform platform-specific initialization + up = (void *)init_forth(); + execute_word("app", up); // Call the top-level application word +} diff --git a/src/cforth/targets.mk b/src/cforth/targets.mk index d979aaa..00faa69 100644 --- a/src/cforth/targets.mk +++ b/src/cforth/targets.mk @@ -180,7 +180,7 @@ makeccalls: makeccalls.c @echo CC $< @$(CC) -o makeccalls $< -clean: +clean:: @rm -f $(ARTIFACTS) forth forth.dic app.dic $(EXTRA_CLEAN) tidy: |