Files
ueforth/site/ESP32forth.html
2023-12-22 20:46:23 -08:00

1179 lines
36 KiB
HTML

<!DOCTYPE html>
<!--
Copyright 2021 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.
-->
<head>
#include "head.html"
<title>ESP32forth</title>
</head>
<body>
<h1>ESP32forth</h1>
#include "menu.html"
<div class="wrapper">
<h2>Download</h2>
<h3>STABLE RELEASE</h3>
<p>
<a href="https://eforth.storage.googleapis.com/releases/ESP32forth-{{STABLE_VERSION}}.zip">ESP32forth-{{STABLE_VERSION}}.zip</a>
- Single .ino file ready for installation<br/>
<i>Version: {{STABLE_VERSION}} (Stable)</i>
</p>
<h3>LONG TERM STABLE RELEASE</h3>
<p>
<a href="https://eforth.storage.googleapis.com/releases/ESP32forth-{{OLD_STABLE_VERSION}}.zip">ESP32forth-{{OLD_STABLE_VERSION}}.zip</a>
- Single .ino file ready for installation<br/>
<i>Version: {{OLD_STABLE_VERSION}} (Long-term Stable)</i>
</p>
<h3>Beta Release</h3>
<p>
<a href="https://eforth.storage.googleapis.com/releases/ESP32forth-{{VERSION}}.zip">ESP32forth-{{VERSION}}.zip</a>
- Single .ino file ready for installation<br/>
<i>Version: {{VERSION}} (Beta)</i>
</p>
<hr/>
<p>
<a href="https://eforth.storage.googleapis.com/releases/archive.html" target="_blank">Release Archive</a>
- Prior Releases
</p>
<p>
<a href="https://github.com/flagxor/ueforth" target="_blank">http://github.com/flagxor/ueforth</a>
- Complete Unprocessed Source Code
</p>
<h2>License</h2>
<p>
<b>
NOTE: Although Esp32forth is licensed under Apache 2.0,
please be aware that binaries built with the Arduino IDE (such as ESP32forth) include
components and libraries under
<a target="_blank" href="https://github.com/arduino/Arduino/blob/master/license.txt">other additional licenses</a>.<br/>
The ESP32 plugin for Arduino is also under a
<a target="_blank" href="https://github.com/espressif/arduino-esp32/blob/master/LICENSE.md">different license</a>.<br/>
Additionally, the ESP32 toolchain used by Arduino, contains further components under
<a target="_blank" href="https://docs.espressif.com/projects/esp-idf/en/latest/esp32/COPYRIGHT.html">other licenses</a>.<br/>
<u>Be sure to consult a lawyer before using for comercial purposes.</u>
</b>
</p>
<hr/>
<pre>
Copyright 2021 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
<a target="_blank" href="http://www.apache.org/licenses/LICENSE-2.0">http://www.apache.org/licenses/LICENSE-2.0</a>
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.
</pre>
<h2>Install</h2>
<p>
Download the <a href="https://www.arduino.cc/en/software">Arduino IDE</a> for your platform.
</p>
<p>
Go to <b>File &gt; Preferences</b>.<br/>
Under <b>Additional Board Manager URLs</b> add:
<ul>
<li>For ESP32 - <code>https://dl.espressif.com/dl/package_esp32_index.json</code></li>
<li>For ESP32-S2 or ESP32-C3 - <code>https://raw.githubusercontent.com/espressif/arduino-esp32/gh-pages/package_esp32_dev_index.json</code></li>
</ul>
</p>
<p>
Select your serial port under <b>Tools &gt; Port</b>.
</p>
<p>
Under <b>Tools</b> choose board and settings as below under <b>Tools</b>.
</p>
<table>
<tr>
<th>BOARD</th>
<th>ESP32 Version</th>
<th>Tools Settings</th>
</tr>
<tr>
<td>
<b>OTHER ESP32-XXX BOARDS</b><br/>
Use a more exact board selection or consult documentation to choose equivalent Dev Module settings.
Your mileage may vary.
<br/>
<b style="color: red">NOTE: Not all ESP-32 boards are compatible with Arduino.</b>
</td>
<td>2.0.1</td>
<td>
<small>
<b>Board:</b> <span class="hilit">Your board type OR closest Dev Module</span><br/>
<b>Partition Scheme:</b> <span class="hilit">Favor more App storage if option available</span><br/>
</small>
</td>
</tr>
<tr>
<td>
<b>ESP32-WROOM</b><br/>
<a href="static/esp32-wroom.jpg" style="border: 0"><img src="static/esp32-wroom.jpg" width="100"></a>
</td>
<td>1.0.6</td>
<td>
<small>
<b>Board:</b> <span class="hilit">ESP32 Dev Module</span><br/>
<b>Partition Scheme:</b> <span class="hilit">No OTA (2M APP, 2M SPIFFS) <b>&larr; Non-default</b></span><br/>
<b>Upload Speed:</b> 921600<br/>
<b>CPU Frequency:</b> 240MHz<br/>
<b>Flash Frequency:</b> 80MHz<br/>
<b>Flash Mode:</b> QIO<br/>
<b>Flash Size:</b> 4MB (32Mb)<br/>
<b>Core Debug Level:</b> None<br/>
<b>PSRAM:</b> Disable<br/>
<hr/>
<i>
<b>Arduino Runs On:</b> Core 1<br/>
<b>Events Run On:</b> Core 1<br/>
</i>
</small>
</td>
</tr>
<tr>
<td>
<b>ESP32-WROVER</b><br/>
</td>
<td>1.0.6</td>
<td>
<small>
<b>Board:</b> <span class="hilit">ESP32 Dev Module</span><br/>
<b>Partition Scheme:</b> <span class="hilit">No OTA (2M APP, 2M SPIFFS) <b>&larr; Non-default</b></span><br/>
<b>Upload Speed:</b> 921600<br/>
<b>CPU Frequency:</b> 240MHz<br/>
<b>Flash Frequency:</b> 80MHz<br/>
<b>Flash Mode:</b> QIO<br/>
<b>Flash Size:</b> 4MB (32Mb)<br/>
<b>Core Debug Level:</b> None<br/>
<b>PSRAM:</b> <span class="hilit">Enabled</span><br/>
<hr/>
<i>
<b>Arduino Runs On:</b> Core 1<br/>
<b>Events Run On:</b> Core 1<br/>
</i>
</small>
</td>
</tr>
<tr>
<td>
<b>ESP32-CAM</b><br/>
<a href="static/esp-cam-front.jpg" style="border: 0"><img src="static/esp-cam-front.jpg" width="100"></a>
<a href="static/esp-cam-back.jpg" style="border: 0"><img src="static/esp-cam-back.jpg" width="100"></a>
<a href="static/esp-cam-wiring.jpg" style="border: 0"><img src="static/esp-cam-wiring.jpg" width="100"></a>
</td>
<td>1.0.6</td>
<td>
<small>
<b>Board:</b> <span class="hilit">AI Thinker ESP32-CAM</span><br/>
</small>
</td>
</tr>
<tr>
<td>
<b>ESP32-MINI-1</b><br/>
<b>ESP32-SOLO-1</b><br/>
<a href="static/esp32-mini-1.jpg" style="border: 0"><img src="static/esp32-mini-1.jpg" width="100"></a>
<b style="color: red">NOT CURRENTLY SUPPORTED</b>
</td>
<td>N/A</td>
<td style="background-color: red; color: yellow">
<b>NOT CURRENTLY SUPPORTED</b><br/>
Arduino builds ESP32 assuming dual core, but the SOLO and MINI have only one core.
</td>
</tr>
<tr>
<td>
<b>ESP32-S2-WROOM</b><br/>
<a href="static/esp32-s2-wroom.jpg" style="border: 0"><img src="static/esp32-s2-wroom.jpg" width="100"></a>
</td>
<td>2.0.1</td>
<td>
<small>
<b>Board:</b> <span class="hilit">ESP32S2 Dev Module</span><br/>
<b>Partition Scheme:</b> <span class="hilit">No OTA (2M APP, 2M SPIFFS) <b>&larr; Non-default</b></span><br/>
<b>Upload Speed:</b> 921600<br/>
<b>USB CDC On Boot:</b> Disabled<br/>
<b>USB Firmware MSC On Boot:</b> Disabled<br/>
<b>USB DFU On Boot:</b> Disabled<br/>
<b>Upload Mode:</b> UART0<br/>
<b>CPU Frequency:</b> 240MHz<br/>
<b>Flash Frequency:</b> 80MHz<br/>
<b>Flash Mode:</b> QIO<br/>
<b>Flash Size:</b> 4MB (32Mb)<br/>
<b>Core Debug Level:</b> None<br/>
<b>PSRAM:</b> Disabled<br/>
</small>
</td>
</tr>
<tr>
<td>
<b>ESP32-S2-WROVER</b><br/>
<a href="static/esp32-s2-wrover.jpg" style="border: 0"><img src="static/esp32-s2-wrover.jpg" width="100"></a>
</td>
<td>2.0.1</td>
<td>
<small>
<b>Board:</b> <span class="hilit">ESP32S2 Dev Module</span><br/>
<b>Partition Scheme:</b> <span class="hilit">No OTA (2M APP, 2M SPIFFS) <b>&larr; Non-default</b></span><br/>
<b>Upload Speed:</b> 921600<br/>
<b>USB CDC On Boot:</b> Disabled<br/>
<b>USB Firmware MSC On Boot:</b> Disabled<br/>
<b>USB DFU On Boot:</b> Disabled<br/>
<b>Upload Mode:</b> UART0<br/>
<b>CPU Frequency:</b> 240MHz<br/>
<b>Flash Frequency:</b> 80MHz<br/>
<b>Flash Mode:</b> QIO<br/>
<b>Flash Size:</b> 4MB (32Mb)<br/>
<b>Core Debug Level:</b> None<br/>
<b>PSRAM:</b> <span class="hilit">Enabled</span><br/>
</small>
</td>
</tr>
<tr>
<td>
<table style="border: 0">
<tr>
<td style="border: 0">
<b>ESP32-C3-MINI-1</b><br/>
<b>(ESP32-C3-DevKitM-1)</b><br/>
<a href="static/esp32-c3-mini-1.jpg" style="border: 0"><img src="static/esp32-c3-mini-1.jpg" width="100"></a>
</td>
<td style="border: 0">
<b>ESP32-C3-WROOM-02</b><br/>
<b>(ESP32-C3-DevKitC-02)</b><br/>
<a href="static/esp32-c3-wroom-02.jpg" style="border: 0"><img src="static/esp32-c3-wroom-02.jpg" width="100"></a>
</td>
</tr>
</table>
</td>
</td>
<td>2.0.1</td>
<td>
<small>
<b>Board:</b> <span class="hilit">ESP32C3 Dev Module</span><br/>
<b>Partition Scheme:</b> <span class="hilit">No OTA (2M APP, 2M SPIFFS) <b>&larr; Non-default</b></span><br/>
<b>Upload Speed:</b> 921600<br/>
<b>USB CDC On Boot:</b> Disabled<br/>
<b>CPU Frequency:</b> 160MHz<br/>
<b>Flash Frequency:</b> 80MHz<br/>
<b>Flash Mode:</b> QIO<br/>
<b>Flash Size:</b> 4MB (32Mb)<br/>
<b>Core Debug Level:</b> None<br/>
<b>PSRAM:</b> Disabled<br/>
</small>
</td>
</tr>
</table>
<h2>Use</h2>
<p>
Initially ESP32forth can be interacted with over a serial port (over USB).
You can do this from the Arduino IDE's Serial Monitor option.
Be sure to config the serial port to: <code>baud rate = 115200, data bits = 8, stop bits = 1, and parity = N</code>.
</p>
<p>
On boot, ESP32forth configures PIN 2 (typically an LED) to be an output and brings it HIGH (lighting the LED after boot).
</p>
<h2>ESP32forth Features</h2>
<h3>ESP32forth Specific Words</h3>
#include "common.html"
#include "files_common.html"
#include "posix_common.html"
<h3>ESP32forth Bindings</h3>
<p>
Because Arduino builds a statically linked image for flashing into ESP32 devices,
all C function bindings need to be explicitly added.
This is the current collection.
Typically to reduce confusion, function names have be preserved even through verbose.
In popular cases a shorted higher level name is provided.
</p>
<p>
See <a href="https://github.com/flagxor/ueforth/blob/main/esp32/template.ino">template.ino</a>.
</p>
<h5>Allocation</h5>
These words are inside the <code>internals</code> vocabulary.
<pre>
MALLOC ( n -- a | 0 ) System malloc
SYSFREE ( a -- ) System free
REALLOC ( a n -- a | 0 ) System realloc
</pre>
<h5>Serial</h5>
These words are inside the <code>Serial</code> vocabulary.
<pre>
Serial.begin ( baud -- ) Start serial port
Serial.end ( -- ) End serial port
Serial.available ( -- f ) Is serial data available
Serial.readBytes ( a n -- n ) Read serial bytes, return number gotten
Serial.write ( a n -- n ) Write serial bytes
Serial.flush ( -- ) Flush serial buffer
</pre>
<h5>Serial Bluetooth</h5>
These words are inside the <code>bluetooth</code> vocabulary.
<p><b>
NOTE: Starting in v7.0.7.13 the optional module serial-bluetooth.h must be
placed next to ESP32forth.ino to include this capability.
</b></p>
<pre>
SerialBT.new ( -- bt ) Allocate new BT object
SerialBT.delete ( bt -- ) Free BT object
SerialBT.begin ( localname ismaster bt -- f )
SerialBT.end ( bt -- )
SerialBT.available ( bt -- f )
SerialBT.readBytes ( a n bt -- n )
SerialBT.write ( a n bt -- n )
SerialBT.flush ( bt -- )
SerialBT.hasClient ( bt -- f )
SerialBT.enableSSP ( bt -- )
SerialBT.setPin ( z bt -- f )
SerialBT.unpairDevice ( addr bt -- f )
SerialBT.connect ( remotename bt -- f )
SerialBT.connectAddr ( addr bt -- f )
SerialBT.disconnect ( bt -- f )
SerialBT.connected ( timeout bt -- f )
SerialBT.isReady ( checkMaster timeout -- f ) Default checkMaster=false, timeout=0
</pre>
<h5>Bluetooth</h5>
These words are inside the <code>bluetooth</code> vocabulary.
<pre>
esp_bt_dev_get_address ( -- a ) addr of 6 byte mac address
</pre>
<h5>GPIO</h5>
<pre>
pinMode ( pin mode -- ) Set GPIO pin mode
digitalWrite ( pin value -- ) Set GPIO pin state
analogRead ( pin -- n ) Analog read from 0-4095
pulseIn ( pin value usec -- usec/0 ) Wait for a pulse
</pre>
Available on devices other than ESP32-C3:
<pre>
dacWrite ( pin 0-255 -- ) Write to DAC (pin 25, 26)
</pre>
<h5>ledc</h5>
These words are inside the <code>ledc</code> vocabulary.
<pre>
ledcSetup ( channel freq resolution -- freq )
ledcAttachPin ( pin channel -- )
ledcDetachPin ( pin -- )
ledcRead ( channel -- n )
ledcReadFreq ( channel -- freq ) Get frequency (x 1,000,000)
ledcWrite ( channel duty -- )
ledcWriteTone ( channel freq ) Write tone frequency (x 1000)
ledcWriteNote ( channel note octave -- freq )
</pre>
<h5>Short GPIO Names</h5>
<pre>
pin ( value pin# -- ) Set GPIO pin value
adc ( pin# -- n ) Analog read pin, result 0-1023
</pre>
<h5>System</h5>
<pre>
MS ( n -- ) Pause for some number of milliseconds.
MS-TICKS ( -- n ) Time since start in milliseconds.
TERMINATE ( n -- ) Call system exit.
</pre>
<h5>Files</h5>
<pre>
R/O ( -- mode )
R/W ( -- mode )
W/O ( -- mode )
BIN ( mode -- mode )
CLOSE-FILE ( fh -- ior )
OPEN-FILE ( a n mode -- fh ior )
CREATE-FILE ( a n mode -- fh ior )
DELETE-FILE ( a n -- ior )
WRITE-FILE ( a n fh -- ior )
READ-FILE ( a n fh -- n ior )
FILE-POSITION ( fh -- n ior )
REPOSITION-FILE ( n fh -- ior )
FILE-SIZE ( fh -- n ior )
</pre>
<h5>WiFi</h5>
These words are inside the <code>WiFi</code> vocabulary.
<pre>
WiFi.config ( ip dns gateway subnet -- ) Packaged a.b.c.d little-endian
Wifi.begin ( ssid-z password-z -- )
Wifi.disconnect ( -- )
WiFi.status ( -- n )
WiFi.macAddress ( a -- )
WiFi.localIP ( -- ip )
WiFi.mode ( mode -- ) WIFI_MODE_NULL WIFI_MODE_STA WIFI_MODE_AP WIFI_MODE_APSTA
WiFi.setTxPower ( powerx4 -- ) Set power x4
WiFi.getTxPower ( -- powerx4 ) Get power x4
( In 7.0.6.17 and up )
WiFi.softAP ( ssid password/0 -- success )
WiFi.softAPIP ( -- ip )
WiFi.softAPBroadcastIP ( -- ip )
WiFi.softAPNetworkID ( -- ip )
WiFi.softAPConfig ( localip gateway subnet -- success )
WiFi.softAPdisconnect ( wifioff -- success )
WiFi.softAPgetStationNum ( -- num )
</pre>
<h5>mDNS</h5>
<pre>
MDNS.begin ( name-z -- ) Start multicast dns
</pre>
<h5>SPIFFS</h5>
These words are inside the <code>SPIFFS</code> vocabulary.
<pre>
SPIFFS.begin ( format-on-fail path-z max-files -- f )
SPIFFS.end ( -- )
SPIFFS.format ( -- f )
SPIFFS.totalBytes ( -- n )
SPIFFS.usedBytes ( -- n )
</pre>
<h5>WebServer (DEPRECATED)</h5>
These words are inside the <code>WebServer</code> vocabulary.
<p><b>Removed in 7.0.6.14</b>, use httpd instead.</p>
<pre>
WebServer.new ( port -- ws ) Allocate new webserver object
WebServer.delete ( ws -- ) Delete webserver object
WebServer.begin ( port ws -- )
WebServer.stop ( ws -- )
WebServer.on ( path-z xt ws -- ) Set up a web path handle callback
WebServer.handleClient ( ws -- ) Handle one client request
WebServer.hasArg ( z ws -- f ) By name
WebServer.arg ( z ws -- z ) By name
WebServer.argi ( n ws -- z ) By index
WebServer.argName ( n ws -- z) By index
WebServer.args ( ws -- n ) Number of args
WebServer.setContentLength ( n ws -- )
WebServer.sendHeader ( name-z value-z fist ws -- )
WebServer.send ( code mimetype data ws -- )
WebServer.sendContent ( z ws -- )
WebServer.method ( ws -- n ) GET / POST etc.
</pre>
<h5>httpd</h5>
These words are inside the <code>httpd</code> vocabulary.
<pre>
server ( port -- ) Run a webserver on a port (in background, returns immediately).
handleClient ( -- f ) Wait for a client to connect, true if connected.
path ( -- a n ) Get request path.
method ( -- a n ) Get request method (GET/POST).
header ( a n -- a n ) Get header value or empty string.
body ( -- a n ) Get request body.
response ( mime mime# result result# status -- ) Respond with a particular mime type result and status.
ok-response ( mime mime# ) Response with a HTTP 200.
bad-response ( -- ) Response with HTTP 400 Bad request.
notfound-response ( -- ) Response with HTTP 404 Not found.
send ( a n -- ) Send response bytes.
NOTE: You may want to use this feature in tandem with tasks / streams.
Example:
also httpd
: handle-index
s" text/html" ok-response r|
<html>
<body>Hi!</body>
</html>
| send ;
: handle1
." Got a request for: " path type cr
path s" /" str= if handle-index exit then
notfound-response
;
: run 8080 server
begin handleClient if handle1 then pause again ;
run
</pre>
<h5>Wire</h5>
These words are inside the <code>Wire</code> vocabulary.
<pre>
Wire.begin ( -- f )
Wire.setPins ( sda scl -- f )
Wire.setClock ( frequency -- )
Wire.getClock ( -- frequency )
Wire.setTimeout ( ms -- ) Default is 50ms
Wire.getTimeout ( -- ms )
Wire.beginTransmission ( n -- )
Wire.endTransmission ( sendstop -- f ) Default is true
Wire.requestFrom ( address quantity sendstop -- n )
Wire.write ( a n -- n )
Wire.available ( -- f )
Wire.read ( -- ch )
Wire.peek ( -- ch )
Wire.flush ( -- )
</pre>
These words were available in v7.0.6.5 and before,
but are now deprecated as the underlying Arduino functions
have gone away in the v2.0.1 ESP32 Arduino library.
<pre>
Wire.lastError ( -- n )
Wire.getErrorText ( n -- z )
Wire.busy ( -- f )
Wire.writeTransmission ( addr a n sendstop -- err )
Wire.readTransmission ( addr a n sendstop acount -- err )
</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>
These words are inside the <code>camera</code> vocabulary.
<p><b>
NOTE: Starting in v7.0.7.13 the optional module camera.h must be
placed next to ESP32forth.ino to include this capability.
</b></p>
<pre>
esp_camera_init ( config -- f )
esp_camera_deinit ( -- f )
esp_camera_fb_get ( -- fb )
esp_camera_fb_return ( fb -- )
esp_camera_sensor_get ( -- sensor )
esp_camera_save_to_nvs ( key -- n )
esp_camera_load_from_nvs ( key -- n )
( formats )
PIXFORMAT_RGB565
PIXFORMAT_YUV422
PIXFORMAT_GRAYSCALE
PIXFORMAT_JPEG
PIXFORMAT_RGB888
PIXFORMAT_RAW
PIXFORMAT_RGB444
PIXFORMAT_RGB555
( frame sizes )
FRAMESIZE_96x96 ( 96x96)
FRAMESIZE_QQVGA ( 160x120 )
FRAMESIZE_QCIF ( 176x144 )
FRAMESIZE_HQVGA ( 240x176 )
FRAMESIZE_240x240 ( 176x144 )
FRAMESIZE_QVGA ( 320x240 )
FRAMESIZE_CIF ( 400x296 )
FRAMESIZE_HVGA ( 480x320 )
FRAMESIZE_VGA ( 640x480 )
FRAMESIZE_SVGA ( 800x600 )
FRAMESIZE_XGA ( 1024x768 )
FRAMESIZE_HD ( 1280x720 )
FRAMESIZE_SXGA ( 1280x1024 )
FRAMESIZE_UXGA ( 1600x1200 )
( access to config )
camera-fb-count ( -- a )
camera-jpeg-quality ( -- a )
camera-frame-size ( -- a )
camera-format ( -- a )
( Access a frame returned by esp_camera_fb_get )
fb->buf ( -- a )
fb->len ( -- n )
fb->width ( -- n )
fb->height ( -- n )
fb->format ( -- n )
fb->sec ( -- n )
fb->usec ( -- n )
( Access methods in struct returned by esp_camera_sensor_get )
s->xclk_freq_hz ( a )
s->init_status ( s )
s->reset ( s )
s->set_pixformat ( s pixformat )
s->set_framesize ( s framesize )
s->set_contrast ( s level )
s->set_brightness ( s level )
s->set_saturation ( s level )
s->set_sharpness ( s level )
s->set_denoise ( s level )
s->set_gainceiling ( s gainceil )
s->set_quality ( s quality )
s->set_colorbar ( s enable )
s->set_whitebal ( s enable )
s->set_gain_ctrl ( s enable )
s->set_exposure_ctrl ( s enable )
s->set_hmirror ( s enable )
s->set_vflip ( s enable )
( --- )
s->set_aec2 ( s enable )
s->set_awb_gain ( s enable )
s->set_agc_gain ( s gain )
s->set_aec_value ( s gain )
( --- )
s->set_special_effect ( s effect )
s->set_wb_mode ( s mode )
s->set_ae_level ( s level )
( --- )
s->set_raw_gma ( s enable )
s->set_lenc ( s enable )
( --- )
s->get_reg ( s reg mask )
s->set_reg ( s reg mask value )
s->set_res_raw ( s startX startY endX endY offsetX offsetY totalX totalY outputX outputY scale binning )
s->set_pll ( s bypass mul sys root pre seld5 pclken pclk )
s->set_xclk ( s time xclk )
</pre>
<h5>Camera Server</h5>
<p><b>Requires v7.0.6+</b></p>
<b>WIP Prototype - Not yet stable</b><br/>
These words are inside the <code>camera-server</code> vocabulary.
<pre>
server ( port -- ) Start an image server at port,
e.g. http://IP/image will produce an image
</pre>
<h5 id="interrupts">Interrupts</h5>
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>
<pre>
pinchange ( xt pin -- ) Call xt when pin changes.
</pre>
<p>Example:</p>
<pre>
17 input pinMode
: test ." pinvalue: " 17 digitalRead . cr ;
' test 17 pinchange
</pre>
<p>Low Level words:</p>
<pre>
ESP_INTR_FLAG_DEFAULT -- Default handler allows per pin routing
Various triggers:
#GPIO_INTR_DISABLE
#GPIO_INTR_POSEDGE
#GPIO_INTR_NEGEDGE
#GPIO_INTR_ANYEDGE
#GPIO_INTR_LOW_LEVEL
#GPIO_INTR_HIGH_LEVEL
gpio_config ( gpio_config_t* -- 0/err )
gpio_reset_pin ( pin -- 0/err )
gpio_set_intr_type ( pin type -- 0/err )
gpio_intr_enable ( pin -- 0/err )
gpio_intr_disable ( pin -- 0/err )
gpio_set_level ( pin level -- 0/err )
gpio_get_level ( pin -- level )
gpio_set_direction ( pin mode -- 0/err )
gpio_set_pull_mode ( pin mode -- 0/err )
gpio_wakeup_enable ( pin type -- 0/err )
gpio_wakeup_disable ( pin -- 0/err )
gpio_pullup_en ( pin -- 0/err )
gpio_pullup_dis ( pin -- 0/err )
gpio_pulldown_en ( pin -- 0/err )
gpio_pulldown_dis ( pin -- 0/err )
gpio_hold_en ( pin -- 0/err )
gpio_hold_dis ( pin -- 0/err )
gpio_deep_sleep_hold_en ( -- )
gpio_deep_sleep_hold_dis ( -- )
gpio_install_isr_service ( a -- ) Typically ESP_INTR_FLAG_DEFAULT
gpio_uninstall_isr_service
gpio_isr_handler_add ( pin xt arg -- 0/err )
gpio_isr_handler_remove ( pin -- 0/err )
gpio_set_drive_capability ( pin cap -- 0/err )
gpio_get_drive_capability ( pin cap* -- 0/err )
esp_intr_alloc ( source flags xt args handle* -- 0/err )
esp_intr_free ( handle -- 0/err )
</pre>
<h5 id="timers">Timers</h5>
These words are inside the <code>timers</code> vocabulary.
<pre>
timer_isr_callback_add ( group timer xt arg -- 0/err ) Register a raw timer ISR callback.
timer_isr_register ( group timer xt arg ret -- 0/err ) REMOVED
</pre>
<h5 id="rmt">RMT</h5>
These words are inside the <code>RMT</code> vocabulary.
<p><b>
NOTE: Starting in v7.0.7.15 the optional module rmt.h must be
placed next to ESP32forth.ino to include this capability.
</b></p>
<pre>
rmt_set_clk_div ( channel div8 -- err )
rmt_get_clk_div ( channel @div8 -- err )
rmt_set_rx_idle_thresh ( channel thresh16 -- err )
rmt_get_rx_idle_thresh ( channel @thresh16 -- err )
rmt_set_mem_block_num ( channel memnum8 -- err )
rmt_get_mem_block_num ( channel @memnum8 -- err )
rmt_set_tx_carrier ( channel enable highlev lowlev carrierlev -- err )
rmt_set_mem_pd ( channel f -- err )
rmt_get_mem_pd ( channel @f -- err )
rmt_tx_start ( channel f -- err )
rmt_tx_stop ( channel -- err )
rmt_rx_start ( channel f -- err )
rmt_rx_stop ( channel -- err )
rmt_tx_memory_reset ( channel -- err )
rmt_rx_memory_reset ( channel -- err )
rmt_set_memory_owner ( channel owner -- err )
rmt_get_memory_owner ( channel @owner -- err )
rmt_set_tx_loop_mode ( channel f -- err )
rmt_get_tx_loop_mode ( channel @f -- err )
rmt_set_rx_filter ( channel enable thresh8 -- err )
rmt_set_source_clk ( channel baseclk -- err )
rmt_get_source_clk ( channel @baseclk -- err )
rmt_set_idle_level ( channel enable level -- err )
rmt_get_idle_level ( channel @enable @level -- err )
rmt_get_status ( channel @status -- err )
rmt_set_rx_intr_en ( channel enable -- err )
rmt_set_err_intr_en ( channel enable -- err )
rmt_set_tx_intr_en ( channel enable -- err )
rmt_set_tx_thr_intr_en (channel enable thresh -- err )
rmt_set_gpio ( channel mode gpio# invertsig -- err )
rmt_config ( rmt_config_t* )
rmt_isr_register ( fn arg allocflags handle -- err )
rmt_isr_deregister ( handle -- err )
rmt_fill_tx_items ( channel @items items# offset -- err )
rmt_driver_install ( channel rxbufsize allocflags -- err )
rmt_driver_uinstall ( channel -- err )
rmt_get_channel_status ( channel @status -- err )
rmt_get_counter_clock ( channel @clockhz -- err )
rmt_write_items ( channel @items items# wait -- err )
rmt_wait_tx_done ( channel time -- err )
rmt_get_ringbuf_handle ( channel @handle -- err )
rmt_translator_init ( channel fn -- err )
rmt_translator_set_context ( channel @context -- err )
rmt_translator_get_context ( channel @@context -- err )
rmt_write_sample ( channel src src# wait -- err )
rmt_register_tx_end_callback --- NOT SUPPORTED
rmt_memory_rw_rst --- DEPRECATED USE rmt_tx_memory_reset or rmt_rx_memory_reset
rmt_set_intr_enable_mask --- DEPRECATED interrupt handled by driver
rmt_clr_intr_enable_mask --- DEPRECATED interrupt handled by driver
rmt_set_pin --- DEPRECATED use rmt_set_gpio instead
</pre>
<h5 id="timers">Timers</h5>
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
operation, you'll probably want to use <a href="#tasks">TASKS</a>.</b>
<p>High Level words:</p>
<pre>
( timer t = 0-3 )
interval ( xt usec t -- ) Setup timer t to call xt each after usec
rerun ( t -- ) REMOVED - rerun no longer required as autoreload used
</pre>
<br/><b>NOTE: The Interrupt Watchdog timer doesn't work well with
use of serial output during an interrupt routine.
Operations durring the handler should be kept to a minimum.</b>
<pre>
Example:
timers
variable x
: hi 1 x +! ;
' hi 1000000 0 interval ( run hi every second )
x @ . ( See value of x goes up )
</pre>
<p>Medium Level words:</p>
<pre>
timer@ ( t -- lo hi ) Get timer counter current value
timer! ( lo hi t -- ) Set timer counter current value
alarm@ ( t -- lo hi ) Get alarm value
alarm! ( lo hi t -- ) Set alarm value
enable! ( f t -- ) Timer enable/disable
increase! ( f t -- ) Timer increasing/decreasing
divider! ( n t -- ) Timer divider 2 - 65535
alarm-enable! ( f t -- ) Enable/disable alarm.
int-enable! ( f t -- ) Enable/disble interrupt.
onalarm ( xt t -- ) Set callback
alarm ( t -- a ) REMOVED
alarm-enable@ ( t -- f ) REMOVED
</pre>
<p>Low Level words:</p>
<pre>
( 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 )
</pre>
<h3 id="adding_words">Adding Words</h3>
<p>
Words can be added based on C functions by placing a file named <code>userwords.h</code>
alongside the .ino file for ESP32forth.<br/>
<b>Requires v7.0.6.4+</b><br/>
<i>Before v7.0.6.4, user words required editing the .ino file.</i>
</p>
<p>
Because of the use of <a href="https://en.wikipedia.org/wiki/X_Macro">X-Macros</a> words can be
added in as little as one line. Locate the macro called <code>PLATFORM_OPCODE_LIST</code>
and add your words there.
</p>
<p>NOTE: Be careful to end each line with a \ so the macros will chain correctly.</p>
<p>
To add a word containing only letters, numbers, and underscore you can use <code>Y</code>.
</p>
<pre>
<b>---- userwords.h ----</b>
#define USER_WORDS \
Y(MY_WORD123, c_function_to_call()) \
</pre>
<p>
If your word name contains other characters, instead use <code>X</code>.
You will need to make up an alternate name for the middle parameter.
It must contain only letters, numbers, and underscore.
The name is not used anywhere else, but must be unique.
</p>
<pre>
<b>---- userwords.h ----</b>
#define USER_WORDS \
X("myword!", MY_WORD_BANG, c_function_to_call()) \
</pre>
<p>
Values from the data stack can be accessed via
the variables <code>tos</code> (Top of Stack) and
<code>sp</code> (Pointer to the rest of the stack).
The stack has the data type <code>cell_t</code>.
</p>
<p>
You can push a value of any type to the stack with the macro <code>PUSH</code>:
</p>
<pre>
<b>---- userwords.h ----</b>
#define USER_WORDS \
Y(MY_WORD, PUSH calculate_magic_value()) \
</pre>
<p>
To simplify calling C functions, you can also refer to elements on the stack
with the types positional names:
</p>
<pre>
n10 n9 n8 n7 n6 n5 n4 n3 n2 n1 n0 - Access stack as cell_t integer values
c4 c3 c2 c1 c0 - Access stack as char* values
b4 b3 b2 b1 b0 - Access stack as uint8_t* byte values
a6 a5 a4 a3 a2 a1 a0 - Access stack as void* values
Examples:
<b>---- userwords.h ----</b>
void send_message(const char *message, int code);
...
#define USER_WORDS \
X("send-message", SEND_MESSAGE, send_message(c1, n0)) \
</pre>
<p>
You can always replace the top item on the stack with <code>SET</code>:
</p>
<pre>
<b>---- userwords.h ----</b>
#define USER_WORDS \
Y(DECODE, SET decode_func(n0)) \
</pre>
<p>
You can drop elements from the stack with <code>DROP</code>
or <code>DROPn(number)</code>.
You can nip elements from below top of the stack with <code>NIP</code>
or <code>NIPn(number)</code>.
Be aware that like <code>PUSH</code> this will cause stack indices to change.
</p>
<pre>
<b>---- userwords.h ----</b>
int my_cool_function(char *foo, int bar, uint8_t *baz);
...
#define USER_WORDS \
Y(MY_FUNC, n0 = my_cool_function(c2, n1, b0); NIPn(2)) \
</pre>
<p>
Multiple C statements can be included in the code area of a word,
but care must be taken to generally avoid {}s.
If you find you need nesting, a separate function is recommended.
</p>
<p>
New variables can be declared in each word and are scoped to that word.
</p>
<pre>
<b>---- userwords.h ----</b>
#define USER_WORDS \
Y(MY_WORD, cell_t foo = n0; DROP; char *x = c0; DROP; \
PUSH my_func(foo, x)) \
</pre>