Giter Club home page Giter Club logo

punyforth's Introduction

Build Status

Punyforth

Punyforth is a simple, stack-based, Forth inspired programming language that primarily targets Internet of Things (IOT) devices, like the ESP8266. The ESP8266 is a low-cost Wi-Fi capable chip with a 80 MHz Xtensa LX3 32 bit CPU, TCP/IP stack, GPIO pins and 512 KiB to 4 MiB flash memory. It is widely used in IoT applications and home automation projects.

Punyforth also runs on x86 (Linux), ARM (Raspberry PI) but these are not the primary supported targets.

Design goals

  • Simple
  • Highly interactive
  • Extensible
  • Small memory footprint and resource efficiency

Quick start

The easiest way to try out Punyforth is to use a ESP8266 based development board that has USB to serial interface on board (Geekcreit/Doit, Amica, WeMos, LoLin). Connect the development board to your computer via USB. Let's assume the serial port is COM4.

$ cd arch/esp8266/bin
$ python flash.py COM4

The flash.py utility will store the Punyforth binary and modules source code on the flash memory of the esp8266.

Open a serial terminal1 on port COM4 then type:

println: "Hello world!"

1: Baud rate: 115200 bps. Local echo: on, line mode: enabled. You can find some free terminal emulators here.

Note that flash.py flashes with Quad I/O speed (qio) by default. This is the fastest mode but not all devices support this. If you have trouble while flashing try adding a --flashmode dio parameter.

Now let's do some simple arithmetics.
4
dup
+
.

This should give you the following output.

(stack)
(stack 4)
(stack 4 4)
(stack 8)
(stack)
8

Congratulation, you've just doubled a number and printed out the result in the REPL.

For a detailed getting started guide see Developing and deploying Punyforth applications.

About the language

Punyforth is a simple, imperative, stack-based, concatenative programming language and interactive environment with good metaprogramming support and extensibility.

The Forth environment combines the compiler with an interactive shell (REPL), where the user can define functions called words.

Punyforth does not have local variables, instead values are kept on a stack. This stack is used only for storing data. There is a separate return stack that stores information about nested subroutine calls. Both stacks are first-class in the language.

As a consequence of the stack, Punyforth uses a form of syntax known as Reverse Polish or Postfix Notation.

If you type the following code in the REPL:

1 2 +

The interpreter pushes the number 1 then the number 2 onto the data stack. It executes the word +, which pops the two top level items off the stack, calculates their sum, and pushes the result back to the stack.

The following code calculates a * a + b * b.

2 3                  \ let's say a is 2, b is 3
dup * swap dup * + . \ prints out 13

The word dup duplicates the top level item of the stack. The word swap exchanges the two top level items of the stack.

Stack visualization:

2 3  3  9  2   2 4 13
  2  3  2  9   2 9
     2         9

dup and swap are stack shuffle words. Excessive use of words like them makes the code hard to follow, so it is advisable to use them sparingly. There are many ways to reduce the number of stack shuffles, one of them is to use quotations and combinators.

For example the above code could have been expressed the following way:

2 3 { square } bi@ +

Where square is defined as dup *.

See the chapter about quotations and combinators for more information.

Differences between Punyforth and other Forth systems

Punyforth is heavily inspired by the Forth programming language. It uses the same compilation model (outer interpreter, compiler, modes, dictionary, immediate words, etc.) as other Forth systems. Punyforth is bootstrapped from a small set of primitives written in assembly language. The compiler targets these primitives and compiles indirect-threaded code. Higher level abstractions are built on top of the primitives therefore most of the system is written in itself (in Forth).

Some of the differences

  • Punyforth is case sensitive
  • Strings are null-terminated
  • String literals ("Hello World") and character literals ($A) are supported
  • Strings can be printed out differently (print: "foobar" instead of ." foobar")
  • Parsing words are ended with a colon character by convention (including variable:, constant:, create: does>)
  • Defining a word in terms of itself results recursion by default (use the override word to alter this behaviour)
  • Curly brackets denote quotations instead of locals

Punyforth supports exception handling, multitasking, socket and GPIO APIs and comes with a UART and a TCP REPL.

Programming

During programming, the user uses the REPL to write and test small piece of codes or to extend the languge with new words (which are called subroutines or functions in other languages).

The REPL (also known as the Forth Outer/Text Interpreter) operates in 2 modes. In interpretation mode, it immediately executes the words that the user typed in. In compilation mode (when you start a new word definition), its action depends on the compilation semantic of the current word. In most cases it compiles the execution token (pointer to the word) into the word to be defined. However, if the current word is flagged as immediate, the compiler executes the word at compile time so the word can define its own compilation semantic. This is a bit similar to Lisp macros. Control structures are implemented as immediate words in Forth.

The syntax

Forth has almost no syntax. It grabs tokens separated by whitespace, looks them up in a dictionary then executes either their compilation or interpretation semantic. If the token is not found in the dictionary, it tries to convert it to a number. Eeverything in Forth is either a word or a number. Because of the postfix notation there are no precedence rules and parentheses.

 This is an example of
 valid   Forth syntax 123  *&^%$#@2

Extending the dictionary

Words are stored in a dictionary. The dictionary maps words to executable code or data structures.

You can use defining words to extend the dictionary with new definitions. The most basic defining words is the : (colon). This adds a new word to the dictionary with the behavior defined in terms of existing words. A colon definition begins with a colon and ends with a semicolon.

: square ( n -- n^2 ) dup * ;

4 square .      \ prints 16

In the above example we created a new word called square that takes a number off the stack, multiplies it with itself, then leaves the result on the stack. The ( n -- n^2 ) is the optional stack effect comment indicating the input and output parameters.

Other common defining words are variable: and constant:.

variable: var1                \ create a variable 'var1' without initializing
54 init-variable: var2        \ create a variable 'var2' and initialize it to 54
42 constant: answer           \ create a constant 'answer' with the value 42

var2 @ var1 !   \ assigns the value of var2 to var1
var1 ?          \ prints out 54
answer .        \ prints out 42

Control structures

Punyforth supports the regular Forth conditional and loop words.

Conditionals

General form of if else then.

<bool> if <consequent> else <alternative> then

For example:

: max ( a b -- max )
  2dup < if nip else drop then ;

10 100 max . \ prints 100

The else part can be omitted.

: abs ( n -- absn )
  dup 0< if -1 * then ;

-10 abs . \ prints 10

Case statement

Punyforth also supports switch-case like flow control logic as shown in the following example.

: day ( n -- )
  case
    1 of print: "Monday" endof
    2 of print: "Tuesday" endof
    3 of print: "Wednesday" endof
    4 of print: "Thursday" endof
    5 of print: "Friday" endof
    6 of print: "Saturday" endof
    7 of print: "Sunday" endof
    print: "Unknown day: " .
  endcase ;

Count-controlled loops

The limit and start before the word do defines the number of times the loop will run.

<limit> <start> do <loop-body> loop

Do loops iterate through integers by starting at start and incrementing until you reach the limit. The word i pushes the loop index onto the stack. In a nested loop, the inner loop may access the loop variable of the outer loop by using the word j.

For example:

5 0 do i . loop \ prints 01234

There is an other version of the do loop where you can define the increment (which can be negative as well).

<limit> <start> do <loop-body> <increment> +loop

For example:

10 0 do i . 2 +loop \ prints 02468

If the increment is negative then limit is inclusive.

0 8 do i . -2 +loop \ prints 86420

It is important to know that Do loops store the loop index on the return stack. You can break the semantics of i and j if you use the return stack to store temporary data. Also you can't simply exit a word from inside a do loop without clearing the return stack first. See unloop for more information.

Condition-controlled loops

until loop
begin <loop-body> <bool> until

The begin...until loop repeats until a condition is true. This loop always executes at least one time.

For example:

: countdown ( n -- )
  begin
    dup .
    1- dup
  0 < until
  drop ;

5 countdown \ prints 543210

If you replace until with again and omit the condition then the loop will run indefinitely.

begin <loop-body> again
while loop
begin .. <bool> while <loop-body> repeat

For example:

: countdown ( n -- )
  begin
    dup 0 >=
  while
    dup . 1-
  repeat
  drop ;

5 countdown \ prints 543210

You can use the exit word to exit from the current word as well from the loop.

But this won't work with do loops. The reason for this is because do loops store the loop index on the return stack. You can use the unloop word to clear the return stack before exiting a do loop.

: some-word ( -- )
  10 0 do
    i 5 = if unloop exit then
  loop ;

An unloop is required for each nesting level before the definition may be exited.

: nested-exit ( -- )
  5 0 do
    5 i 1+ do
      j i + 7 = if
        i . space j . cr
        unloop unloop               \ clear the return stack before exiting
        exit
      then
    loop
  loop ;

Control structres are compile time words with no interpretation semantics. They can be used only in compilation mode, that is inside a word definition.

Exception handling

If a word faces an error condition it can throw an exception. Your can provide exception handlers to catch exceptions.

For example:

exception: EZERODIV

: div ( q d -- r | throws:EZERODIV ) \ this word throws an exception in case of division by zero
  dup 0= if
    EZERODIV throw
  else
    /
  then ;
: test-div ( q d -- r )
  ['] div catch
    case
      EZERODIV of
        println: '/ by zero'                 \ print exception in case of zero division
        2drop                                \ drop q d
      endof
      throw                                  \ rethrow if it wasn't EZERODIV, or there was no exception (code=0)
    endcase ;

The word catch expects an execution token of a word that potentially throws an exception.

The exeption mechanism in Punyforth follows the "catch everything and re-throw if needed" semantics. The instruction 0 throw is essentially a no-op and indicates no error.

Uncaught exception handler

An uncaught exception causes the program to print out the error and the stack trace to the standard output and terminate.

You can modify this behaviour by overriding the unhandled deferred word.

: my-uncaught-exception-handler ( code -- )
  cr print: "Uncaught exception: " ex-type
  abort ;

' unhandled is: my-uncaught-exception-handler

The implementation of exceptions is based on the idea of William Bradley.

Immediate words

Immediate words are executed at compile time. Loops and control structures are implemented with immediate words that compile the required semantics.

: begin
  here                   \ saves the absolute address of the beginning of the loop to the stack
; immediate

: until
  ['] branch0 ,          \ compiles a conditional branch
  here - cell - ,        \ calculate then compile the relative address
; immediate

Parsing words

Parsing words can parse the input stream. One example of a parsing word is the comment. There are 2 types of comments.

( this is a comment )
\ this is an other comment
: (                                \ comments start with ( character
  begin                            \ consume the stream until ) character is found
    key ')' =
  until
; immediate
: \                                \ single line comments start with \ character
  begin
    key dup
    'cr' = swap
    'lf' = or
  until                            \ consume the stream until cr or lf character is found
; immediate

The word hex: is an other example of a parsing word.

hex: FF \ pushes 255 onto the stack

This word interprets the input as a hexadecimal number then pushes it to the stack. Parsing words are similar to reader macros in Lisp.

Deferred words

Punyforth relies on a Hyper Static Global Environment. This means redefining a word will create a new definition, but the words continue to refer to the definition that existed when they were defined. You can alter this behaviour by using deferred words.

For example

: myword1 ( -- )
  print: 'foo' ;

: myword2 ( -- )
  myword1
  print: 'bar' ;

: myword1 ( -- ) \ redefining myword1 to print out baz instead of foo
  print: 'baz' ;

myword2 \ myword2 will print out foobar, not bazbar

Redefinition has no effect on myword2. Let's try it again. This time using the defer:/is: words.

defer: myword1

: myword2 ( -- )
  myword1                       \ I can define myword2 in terms of the (yet undefined) myword1
  print: 'bar' ;

: printfoo ( -- ) print: 'foo' ;
: printbaz ( -- ) print: 'baz' ;

' myword1 is: printfoo          \ redefine the deferred word to print out foo
myword2                         \ this prints out foobar

' myword1 is: printbaz          \ redefine the deferred word to print out baz
myword2                         \ this prints out bazbar

Override

You might want to redefine a word in terms of it's older definition.

For example:

: myword ( -- )
  print: 'foo' ;

: myword ( -- )
  myword
  print: 'bar' ;

myword \ infinite recursion

Unfortunately this won't work because the myword inside the second defintion will refer to the new word, resulting infinite recursion. You can avoid this by marking the word with override.

: myword ( -- )
  print: 'foo' ;

: myword ( -- ) override
  myword
  print: 'bar' ;

myword \ prints out foobar

Because the usage of override, the myword in the second defintion will refer to the old myword. Therefore the execution of myword will print out foobar.

Quotations

A quotation is an anonymous word inside an other word, similar than a lambda expression in other languages. Quotations don't act as lexical closures, because there are no locals in Forth to close over. The word { starts compiling the quotation body into the current word definition. The word } ends the quotation by compiling an exit word into the quotation.

: a-word-definition ( -- )
  ( .. )
  { ( ..quotation body.. ) }
  ( .. ) ;

At runtime the quotation pushes its execution token onto the stack, therefore it can be used with execute, catch or combinators.

: demo ( -- n )
  3 { 1+ 5 * } execute ;

% demo
(stack 20)

Quotations and exception handling

  { "AF01z" hex>int } catch
  if
    println: 'invalid hex number'
    abort
  then

Quotations and Factor style combinators

Punyforth supports a few Factor style combinators.

dip ( x quot -- x )

Calls a quotation while temporarily hiding the top item on the stack.

  1 2 4 { + } dip    \ Same as: 1 2 4 >r + r>
  (stack 3 4)
keep ( x quot -- x )

Calls a quotation with an item on the stack, restoring that item after the quotation returns.

  1 2 4 { + } keep    \ Same as: 1 2 4 dup >r + r>
  (stack 1 6 4)
bi ( x p q -- )

Applies quotation p to x, then applies quotation q to x.

  \ given a rectangle(width=3, height=4)
  rectangle { .width @ } { .height @ } bi *    \ Same as: rectangle dup .width @ swap .height @ *
  (stack 12)
bi* ( x y p q -- )

Applies quotation p to x, then applies quotation q to y.

  "john" ".doe" { 1+ c@ } { 2 + c@ } bi* =    \ Same as: "john" ".doe" swap 1+ c@ swap 2 + c@ =
  (stack -1)
bi@ ( x y quot -- )

Applies the quotation to x, then to y.

 "john" ".doe" { strlen } bi@ =    \ Same as: "john" ".doe" swap strlen swap strlen =
 (stack -1)

The word create: does>

The word create: and does> lets you combine a data structure with an action. You can create multiple instances with different data content and with the same action.

create: is a defining word like the : (colon). It creates a new dictionary entry with the header but without the body. The name of the newly created definition comes from the input stream. Then you can lay out some data using the , (comma) word. The action which will operate on this data is the sequence of words that comes after the does> part. The pointer to the data is pushed to the stack before invoking the action.

Examples

One of the simplest application of create: does> is the definition of a constant.

: constant:
  create: ,
  does> @ ;

80 constant: COLUMNS

COLUMNS . \ prints out 80
  • First we push the value 80 to the data stack
  • Then we invoke the constant: word
  • The word create: reads the name of the constant (COLUMNS) from the input stream and creates a new dictionary header
  • The word , stores the value on the stack (80) in the body of the newly created dictionary entry
  • The does> sets the action to be the @ (fetch) word which will read the constant value from the body

Other examples of create: does>

Indexed array
: array: ( size "name" -- ) ( index -- addr )
  create: cells allot
  does> swap cells + ;

10 array: numbers \ create an array with 10 elements

12 3 numbers !      \ store 12 in the 3rd element
3 numbers @         \ fetch the 3rd element
Structs
: struct 0 ;

: field:
  create: over , +
  does> @ + ;

struct
  cell field: .width
  cell field: .height
constant Rect

: new-rect: ( "name" -- )
  Rect create: allot ;

: area ( rect -- area )
  dup .width @ swap .height @ * ;

new-rect: r1
3 r1 .width !
5 r1 .height !
r1 area .

Unit testing

Words with name starting with the test: prefix are treated as unit tests. Unit testing words typically use assert or =assert to validate the correctness of an other word.

: test:add 1 2 + 3 =assert ;
: test:sub 8 3 - 5 =assert ;

test

The =assert word asserts that two top-most items on the stack are equal. The assert words asserts that the top-most item of the stack is true.

The test word runs all unit tests and gives back a simple report.

2 tests, 2 passed, 0 failed, 0 errors
All passed

A unit test can either pass/fail or raise an error. Failure means an assertion wasn't met. Error occurs in case of an unhandled exception.

: test:add 1 2 + 4 =assert ;
: test:sub some-exception throw ;

test
2 tests, 0 passed, 1 failed, 1 errors
test:add(3 4 <>) FAIL
test:sub ERROR: some-exception
There were failures

ESP8266 specific things

WIFI

The ESP8266 has a built in Wi-Fi chip that can be used both in access point and station mode (wireless client).

In station mode, the ESP8266 connects to an existing Wi-Fi access point.

"password" "existing-ssid" wifi-connect

The station mode Wi-Fi settings are persistently stored by the ESP8266, there is no need to setup the Wi-Fi at every startup.

In AP mode, the ESP8266 acts as an central connection point, which wireless clients (smartphones, laptops) can connect to. In this mode you have to choose an IP address for the ESP and an IP range for the clients. Client IP addresses are assigned by the DHCP server.

172 16 0 1 >ipv4 wifi-set-ip                                      \ AP ip is 172.16.0.1
4 3 0 AUTH_WPA2_PSK "1234567890" "my-ssid" wifi-softap            \ max connections = 4
8 172 16 0 2 >ipv4 dhcpd-start                                    \ dhcp max_leases = 8, first client ip is 172.16.0.2

The dhcp max_leases parameter should not be smaller than the maximum allowed connections.

GPIO

Examples

2 constant: PIN
PIN GPIO_OUT gpio-mode
PIN GPIO_HIGH gpio-write
250 ms
PIN GPIO_LOW gpio-write

See Philips Hue lightswitch example for more information.

Netconn

Netconn is a sequential API on top of the lightweight TCP/IP stack of FreeRTOS. Punyforth provides a wrapper around the Netconn API.

Simple HTTP request

512 buffer: line

: fetch ( netcon -- )
  begin
    dup 512 line netcon-readln -1 <>
  while
    line type cr
  repeat
  drop ;

80 "google.com" TCP netcon-connect constant: socket
socket "GET / HTTP/1.1\r\n\r\n" netcon-write
socket fetch
socket netcon-dispose

UDP client

"Lorem ipsum" constant: data
"192.168.0.3" constant: SERVER_IP
8005 constant: SERVER_PORT
SERVER_PORT SERVER_IP UDP netcon-connect
dup data 11 netcon-send-buf
netcon-dispose
Python test server
import select, socket

s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.bind(('0.0.0.0', 8005))
s.setblocking(0)

while True:
    result = select.select([s],[],[])
    msg = result[0][0].recv(1024)
    print(msg.strip())

UDP server

"192.168.0.15" constant: HOST
8000 constant: PORT
128 buffer: data

PORT HOST netcon-udp-server
dup 128 data netcon-readln
print: 'received bytes: ' . cr
data type
netcon-dispose
Python test client
import socket
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.sendto(b'hello\r\n', ('192.168.0.15',8000))

See Simple HTTP Server for more information.

Tasks

Punyforth supports cooperative multitasking which enables users to run more than one task simultaneously. For example one task may wait for input on a socket, while another one receives commands through the serial port. Punyforth never initiates a context switch by its own. Instead, tasks voluntarily yield control periodically using the word pause. Tasks are executed in a round robin fashion.

In order to run some code in the background, one must create a new task first, using the task: parsing word. A tasks can be activated inside a word. This word usually does something in a loop and calls pause periodically to yield controll to other tasks.

0 task: mytask

: my-word
  mytask activate
  [...] pause [...]
  deactivate

To start the task, first you have to switch to multi tasking mode first by executing the word multi. Then simply call the word that was associated to the task.

multi
my-word

Mailboxes

Often tasks need to communicate with each other. A mailbox is a fixed size blocking queue where messages can be left for a task. Receiving from an empty mailbox or sending to a full mailbox blocks the current task.

\ create a mailbox with size 5
5 mailbox: mailbox1

\ create a task for the consumer
0 task: task-consumer

\ this word is executed by the task
: consumer ( task -- )
  activate                            \ activate task
  begin
    mailbox1 mailbox-receive .        \ receive and print one item from the mailbox
    println: "received by consumer"
    pause                             \ allow other tasks to run
  again
  deactivate ;                        \ deactivate task

multi                                 \ switch to multitask mode
task-consumer consumer                \ run the consumer
123 mailbox1 mailbox-send             \ send some numbers to the consumer
456 mailbox1 mailbox-send

Examples

\ create a task for the counter
task: task-counter

\ this word is executed by the task
: counter ( task -- )
    activate                              \ activate task
    100 0 do
        i . cr
        500 ms
    loop
    deactivate ;                          \ deactivate task

multi                                     \ switch to multitask mode
task-counter counter                      \ run the consumer

Misc

\ Returns the available free dictionary space.
freemem ( -- bytes )

\ Returns the available free memory.
osfreemem ( -- bytes )

\ Blocks all running tasks for the specified number of millisecond.
ms ( msec -- )

\ Blocks for the specified number of microsecond. This is implemented as busy loop. Use it if you need high precision delay.
us ( usec -- )

\ Sets the baud rate of the specied uart.
uart-set-bps ( bps uart-number -- )

\ print out available words
help ( -- )

You can see some example code under the examples directory.

Build instructions and further information is available at punyforth wiki.

Contact

Attila Magyar

Twitter Follow Gitter chat

punyforth's People

Contributors

dfoderick avatar gerardsontag avatar gpummer avatar hartzell avatar joseluis avatar larsks avatar luisarrisan avatar zeroflag avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

punyforth's Issues

unloop problem in nested do loops

Unless I'm missing something it seems like there is a bug in unloop when used in nested do loops. The code below illustrates the problem.

: test 20 0 do i . cr 10 0 do i . i 4 = if unloop exit then loop loop ;

Esplorer works also well with Punyforth

I only wanted to share my experience with Punyforth and Esplorer, I can edit side by side,
send 1 line of code, a selection of code or a complete file , very easy !
It would be useful to find a way to edit the buttons of esplorer, to have shortcuts snippets etc at hand....
like it does for lua and mphyton, something I could not find how to modify.
I am enjoying very much Punyforth, thanks Attila !

traceback seems to have problems printing stack trace

Hello,

"traceback" seems to have problems to print the names of the word in the stack trace.

Example:
exception: EXC : test-trace EXC traceback ; test-trace
prints:

Exeption: exc rdepth: 3
at ??? (1075948848)
Restarting ESP ..

If I do
: testrp rp@ @ heap-end - . ; testrp
it shows that the address on top is about 2MB above the heap-end.
I do not understand whats going on here. The addresses on the return stack seem to be not inside the dictionary.

Can you explain, what I'm doing wrong here?
Many thanks,

Dietmar

Complete word list with usage

Hi to your team. I enjoy using Forth as a hobby on my Wemos D1. But PunyForth is giving me a hard time because I cannot find a complete list of all words and their usage. The word help is the only way I found to see all defined words, but without a description of the usage. Could you please tell me where I could find documentation describing all PunyForth words and their usage. I appreciate your collaboration.

Need way to print integers in hex

Since Punyforth doesn't have words like: base and hex how does one print out numbers in hexidecimal? I am working with hardware where I need to display values during debugging in hex. Is there an easy way to do this or do I have to write my own decimal to hex string conversion?

License

What is the license? I would suggest CC0/Unlicense as Forths are traditionally public domain if it is not decided yet, but for now I have not found any information about license at all.

Unexplained crash on ESP8266

It looks like I have the same problem as what was demonstrated in the issue of 10 May 2018.

As it is closed, I reopen here (the code is also not the same : here I take it from Readme.md)

I use the punyforth version taken from github (ESP8266 : nodemcu v0.9 is my device) and then also a version that I compiled by myself. Both presented the same stange behavior (driving to crash).

then:
(stack) 5 0 do i . loop

Word has no interpretation semantics
0
Word has no interpretation semantics

(stack 5 0)

then:

(stack 5 0) 10 0 do i . 2 +loop

Word has no interpretation semantics
0
Word has no interpretation semantics
Fatal exception (29):
epc1=0x4023da00
epc2=0x00000000
epc3=0x4020ff20
excvaddr=0x00000000
depc=0x00000000
excsave1=0x40215a90
Registers:
a0 40215a90 a1 3fffbfd0 a2 00000000 a3 3fff7870
a4 00000001 a5 00000000 a6 4021ddc6 a7 00000000
a8 00000000 a9 3ffea9b0 a10 60000000 a11 0000000a
a12 00000000 a13 3ffeec48 SAR 0000001e

Stack: SP=0x3fffbfd0
0x3fffbfd0: 00000000 00000000 00000000 00000000
0x3fffbfe0: 00000000 00000000 00000000 a5a5a5a5
0x3fffbff0: fab22c8a 0000014c 3fffbf80 79fa9aaa

Free Heap: 18228
_heap_start 0x3fff7a68 brk 0x3fffc85c supervisor sp 0x40000000 sp-brk 14244 bytes
arena (total_size) 19956 fordblks (free_size) 3984 uordblocks (used_size) 15972

ets Jan 8 2013,rst cause:2, boot mode:(1,6)

ets Jan 8 2013,rst cause:4, boot mode:(1,6)

wdt reset

I had to remove power and to connect again to see the prompt again!
Any idea is welcome but I think there is something wrong in the code or in my ESP8266.

Contributions

Hi, Not sure if you still like additions
After poking around in GIT it seems that can be done through a fork.
Not sure if it is right and what to do next for:
c998b6a
if it is acceptable.
Jos

highbit

Hi,
At I am still quite happy with your Punyforth. Great work!
There is just 1 question for a primitive floating-point pack.

When highbit is defined as:
-1 1 rshift invert constant: highbit
than highbit returns 214748364
Other 32 bits systems return 2147483648
How should highbit be defined?
Thanks in advance.

Despite that problem the pack seem to work as you can see:

(stack) 10 s>f 3 s>f f/ f.
333333333e-8(stack)
10 s>f 6 s>f f/ f.
1666666666e-9(stack)

Kind regards, Jos

Need "words" word

It would be nice if you could add a "words" word so that we could see all of the words currently defined in the dictionary.

A new fast flash utility

Hi,
I just released flash_web.zip
flash_web.zip contains a flash utility that is able to flash ASCII files
to an ESP8266F through a WiFi connection from a Rpi, Windows PC or Linux-PC.
The speed is far better than the program flash.py
After optimizing the program I am able to get a transfer speed of 581.954 kbit/s
That is about 6* faster than flash.py
It uses punyforth on the ESP8266F side and Gforth or Win32Forth on the server side.
Read for the installation and details the start of _FlashWeb.f
See the included CircuitEsp8266F.jpg for the used circuit.

You can download it from: https://sites.google.com/site/win324th/smart-home
It also needs domotica_v41.zip from that page.
Kind regards, Jos

An interesting bug in the example dht22-data-loger or in netcon?

I changed the example a little:

exception: EGAVEUP
variable: data
variable: server
variable: ecnt
 : measure ( -- temperature humidity | throws:EGAVEUP )
    10 0 do
        ['] dht-measure catch ?dup if ex-type cr 5000 ms else unloop exit then
    loop
    EGAVEUP throw ;
 : data! ( temperature humidity -- ) 16 lshift swap or data ! ;
 : connect ( -- ) 8005 "192.168.1.6" TCP netcon-connect server ! ; 
 : dispose ( -- ) server @ netcon-dispose ;
 : send ( -- ) server @ data 4 netcon-write-buf ;
 : log ( temperature humidity -- ) data! connect ['] send catch dispose throw ;
 : log-measurement ( -- ) { measure log } catch ?dup if  ex-type  1 ecnt +! ecnt @ space . cr then ; 
\ : main ( -- ) log-measurement 50 ms 120000000 deep-sleep ;
: main begin log-measurement 2000 ms again ;    

As long as the "server" receiving the information is working, everything seems fine.
But if you stop the server and wait for> 70 attempts to connect to the server and start the server again, then (esp8266) can no longer connect. Up to 70 attempts a connection is restored.
Failed to connect to 192.168.1.6:8005. Error: -14 NETCON error: -14 ENETCON 67 Failed to connect to 192.168.1.6:8005. Error: -14 NETCON error: -14 ENETCON 68 Failed to connect to 192.168.1.6:8005. Error: -14 NETCON error: -14 ENETCON 69 Failed to connect to 192.168.1.6:8005. Error: -14 NETCON error: -14 ENETCON 70 Failed to connect to 192.168.1.6:8005. Error: -14 NETCON error: -14 ENETCON 71 ENETCON 72 ENETCON 73 ENETCON 74 ENETCON 75 ENETCON 76 ENETCON 77

request for Memory map of Punyforth

Dear Attila,

Sory if this is explained elsewhere I did not found it

I am very confused without a memory map of Punyforth, I need to understand
what is happening with my reboot problems I am experimenting with
different programs. It is also almost impossible to advance with Forth
without having a memory map of the full system, I feel like shooting
with a machinegun blindfolded ! It is tough.

I am copying below an example of a memory Map of MicroPhyton for ESP8266
please if you can edit it and correct it for Punyforth to help
everybody visualize better how is Flash and Ram used in Punyforth, and
were is our free space going after loading dependencies.
The example of the internal of Micropython on ESP8266
helped me understand a bit further how the Rtos and Wifi will
consume memory etc...

I have many questions left : 1) is Uber.forth at $51000
copyed from flash to RAM before execution ? because it does not make
sense if we have 1 MB Flash , that 96 K or 64 K ram of ESP get so fast
gone ! In my application 1 LCD with i2cbus and 1 wifi Repl , it consumes
all my memory, I have left only 2K ! After that I can almost not add
anything more without falling into constant reboots.
2) how can this 1MB or 4MB of internal flash been better used ? Is it now
a wasted space ?
3) I suppose there is no way to add an external SD card, this would not
help in any sense. What else can be done ?

Mphyton Memory MAP :


----------------------- 0X4030_0000

MEMORY MAPPED FLASH ROM (1M)

----------------------- 0X4020_0000 ]
]
FLASH MEMORY MAPPING CACHE #1 ] 6
16 K INSTARAM ] 4
-------------------------0X4010_C000 ]
] K
FLASH MEMORY MAPPING CACHE #0 ]
16 K INSTARAM ]
]
------------------------ 0X4011_0000 ]

FAST CODE INSTARAM (32K)

------------------------ 0X4010_0000

------------------------ 0X4001_0000

 BOOT ROM  (64)

------------------------ 0X4000_0000 ]
] 9
]
SYSTEM DATA RAM (16K) ] 6
]
------------------------ 0X4001_0000 ]
] K
]
USER DATA RAM (80 K) ]
]
------------------------ 0X3FFE_8000 ]


Kind regards
Enrique

No interactive with punyforth

Hey Dear!

I flashing and flashing, search and search tonight but still no idea what's wrong and need some help please.

I installed driver of CH340G for mac
$ python modules.py test
or
$ python modules.py core
and then
$ ./flash.sh /dev/tty.wchusbserial1a20 #flashing my esp8266
and then
$ screen /dev/tty.wchusbserial1a20 115200
or
$ picocom -b 115200 -f h /dev/tty.wchusbserial1a20 (for dupble check)

punyforth said:
$ screen /dev/tty.wchusbserial1a20 115200

test:core-str-escape
test:core-multi-line-str
test:eval-whitespace
test:core-str
test:core-alloc
test:core-rdepth
test:core-catch
test:core-defer
test:core-case
test:core-hex
test:core-factorial
test:core-between
test:core-logic
test:core-unloop
test:core-doloop
test:core-?dup
test:core-bounds
test:core-branch
test:core-arithmetic
32 tests, 32 passed, 0 failed, 0 errors
All passed

(stack) Punyforth ready.
(stack)

but I can got any interactive with her :(
nothing hapen when press any key. and sometime someone joined this AP XD
Orz

Thank you!

Different speeds for multiple motors

Hi,
How can the speed of 1 motor be changed while 2 motors are running?
Switching off one motor is not very nice.
pwm-duty changes all motors instead of one only (pity!).
The code I use is based on the example of
~\punyforth-master\arch\esp8266\forth\examples\example-geekcreit-rctank.forth
Thanks in advance, Jos

Enhancement Request - Escape " in strings

The application I am writing uses a lot of strings. In this app I need to embed double quotes in other strings. I need to do things like: ""Hello World""

To this end I made the following change to core.frt

: eschr ( char -- char ) \ read next char from stdin
    dup [ char: \ ] literal = if
        drop key case
            [ char: r ] literal of 13 endof
            [ char: n ] literal of 10 endof
            [ char: t ] literal of 9  endof
            [ char: \ ] literal of 92 endof
            [ char: " ] literal of 34 endof  \ CAL
            EESCAPE throw
        endcase
    then ;

Unexplained Crash

I am currently doing some graphics programming on the esp8266 and have run into a crash that I cannot explain. When I execute the following code and let it run for a while, it always crashes.

128 constant: displayWidth
160 constant: displayHeight

displayHeight 2 / constant: MIDY
displayWidth 2 / constant: MIDX

\ Manhattan distance from middle of screen
: dist
MIDY - abs swap MIDX - abs +
;

: test

displayWidth 0
do
displayHeight 0
do
j i dist . cr
loop
loop
;

Can anyone see anything wrong?

tcp-rpl "library" , is hanging punyforth , what can be wrong

Dear Attila,

I am triying to make REPL (tcp-rpl library ) function work.

Punyforth is finally comunicating fine trough the usb and I was able to test some GP-IO tasks without problems.

Now I am following your example of "Running punyforth from a power outlet" to redirect all in-out from the net , and be able to download new words from a wifi link.
(please note I am doing all this from Windows, I only needed Linux to create the first "core.forth" , from them on I coninued flashing the ESP8266 from the windows flashing utility)

For this example( Sonoff "smart socket") , we need

  1. gpio.forth \ ok, it did work then
  2. tcp-repl.forth which apparently requires to install first "netcon.forth" and "mailbox.forth"

My problems seem to be with "netcon.forth" :

we have this problem that will not compile see (**)

: netcon-new
( type -- netcon | throws:ENETCON ) override netcon-new \ <--- ** this is an autoreference ?
dup 0= if ENETCON throw then RECV_TIMEOUT_MSEC over netcon-set-recvtimeout ;

I really do not know were the problem is in netcon.forth
but, when I try to install those needed files to get tcp-repl working ,
it allways hangs the system. I get into infinte resets and reboots.

I am thanking in advance for your help.

Regards Enrique

** can I comment out "override netcon-new" ?

Build instructions seem incomplete

Following wiki at the end I get:

user@machine ~/projects/esp8266/esp-open-rtos/examples/punyforth/arch/esp8266/rtos/user $ make CC /home/user/projects/esp8266/esp-open-rtos/open_esplibs/libmain/user_interface.c /home/user/projects/esp8266/esp-open-rtos/open_esplibs/libmain/user_interface.c:14:23: fatal error: lwip/dhcp.h: No such file or directory #include "lwip/dhcp.h" ^ compilation terminated. make: *** [../../../../../../open_esplibs/component.mk:17: build/open_esplibs_libmain//user_interface.o] Error 1

Do I need to set other environment variables?

request to flush out getting started docs.

On your page that describes setup you should also point out,(sorry if I missed it) you need to run modules.py and select a program to install as uber.forth.

serial connection requires local echo and crlf and delbs swap.

(trusty)mmh@localhost:~/esp/forth/esp-open-rtos/examples/punyforth/arch/esp8266/bin$ picocom /dev/ttyUSB4 -b 115200 --omap crlf --echo --imap delbs
picocom v1.7

port is        : /dev/ttyUSB4
flowcontrol    : none
baudrate is    : 115200
parity is      : none
databits are   : 8
escape is      : C-a
local echo is  : yes
noinit is      : no
noreset is     : no
nolock is      : no
send_cmd is    : sz -vv
receive_cmd is : rz -vv
imap is        : delbs,
omap is        : crlf,
emap is        : crcrlf,delbs,

Terminal ready

(stack 0 10) 

BTW this is a really cool program very light weight.

ADC command

I am not seeing an ADC example. Is this command implemented?

Just for fun

marker: LedsStrip \ Testing an APA201 ledstrip connected through SPI

\ SPI connections:
\ Name ESP8266 APA102 ledstrip
\ MISO = GPIO 12 \ NOT USED
\ MOSI = GPIO 13 --> DAT
\ CLK = GPIO 14 --> CLK

\ Note for the ESP8266 ESP-12-F:
\ Do not use the SPI connections
\ at GPIO22 GPIO25 and GPIO24 !

4 constant: #Leds \ Number of used leds
0 constant: false -1 constant: true
1 constant: spi_word_size_8bit 1 constant: bus
8 constant: buffer_size 224 constant: PrefixCmd

: .s ( - ) stack-print ;
: tp ( - ) cr .s cr ;
: off ( addr -- ) false swap ! ;
: on ( addr -- ) true swap ! ;
: 4dup ( n1 n2 n3 n4 - n1 n2 n3 n4 n1 n2 n3 n4 ) 2over 2over ;
: freq ( divider count -- freq ) 16 lshift swap 65535 and or ;

: .c ( n - )
dup 10 <
if space space .
else dup 100 <
if space .
else .
then
then space ;

: .c@ ( adr - ) c@ .c ;

1 10 freq constant: spi_freq_div_4m

: init-spi ( - flag )
TRUE 0 ( little endian ) TRUE spi_freq_div_4m 0 ( SPI_MODE0 ) bus
spi-init dup 0= if print: " init-spi FAILED " then ;

struct
1 field: LedCmd \ For 0xE0 and 31 levels of brightness
1 field: LedBlue
1 field: LedGreen
1 field: LedRed
constant: /ledframe

#Leds 2 + /ledframe * constant: /ledstrip

create: &ledstrip /ledstrip allot

: initApa201 ( - flag ) cr print: " Start>" init-spi ;
: >led ( led# - adr ) 1+ /ledframe * &ledstrip + ;

: >led! ( Red Green Blue Cmdlevel led# - )
>led dup >r c!
r@ 1+ c!
r@ 2 + c!
r> 3 + c! ;

: DumpStrip ( - )
cr print: " # Level red green blue"
#Leds 0
do cr i .c space i >led
dup c@ 15 and .c
dup 3 + .c@
dup 2 + .c@
1+ .c@
loop ;

: SetCmd ( Brightness - LedCmd ) PrefixCmd or ;
: ResetStartFrame ( - ) &ledstrip off ;
: SetEndFrame ( - ) #Leds 1+ /ledframe * &ledstrip + 240 over c! 255 swap 1+ c! ;

: .Strip ( - ) \ Writes to the ledstrip over the SPI connection
spi_word_size_8bit
/ledstrip 0 ( ignore output )
&ledstrip bus spi-send drop ;

: FillLeds ( red green blue brightness #Leds FirstLed# - )
ResetStartFrame >r >r SetCmd r> r>
do 4dup i >led!
loop 2drop 2drop
SetEndFrame ;

: StripRed ( - ) 1 0 0 10 #Leds 0 FillLeds ;
: StripBlue ( - ) 0 0 1 10 #Leds 0 FillLeds ;

: .BlueRed ( - )
initApa201
if 10 0
do StripBlue .Strip 500 ms
StripRed .Strip 500 ms
loop
then ;

.BlueRed

\ End, I leave the fancy show to you.

Flashing error in SSD1

quickstart using flash.py

Flashing fails at;
Erasing flash...
Took 0.08s to erase flash block
Writing at 0x00060000... (16 %)
Writing at 0x00060400... (33 %)

A fatal error occurred: Invalid head of packet

bad bin image?

Memory troubles solved

Hi,
I had some trouble to flash punyforth. When using:
python flash.py /dev/ttyUSB0 --main blinker.forth

I got:
Writing at 0x0005f000... (100 %)
Wrote 1024 bytes at 0x0005f000 in 0.1 seconds (84.5 kbit/s)...
Erasing flash...

A fatal error occurred: Invalid head of packet.

Then after reading some more stuff I entered:
python esptool.py erase_flash
Reset the ESP8266
python flash.py /dev/ttyUSB0 --flashmode dio --main blinker.forth --modules gpio.forth
Ran it. And then:
python flash.py /dev/ttyUSB0 --flashmode dio --main blinker.forth --binary false

Now I got:
Writing at 0x0006b400... (100 %)
Wrote 2048 bytes at 0x0006b000 in 0.2 seconds (82.8 kbit/s)...

Leaving...

Finally, no memory error anymore. I think something was blocking access to the memory.

What is the highest possible address to which I can write to on my ESP8266 ESP-12F ?

Jos

In AP mode, ESP resets causing restart of punyforth

Thanks to @zeroflag, who gave me support via esp8266.com
I set up a dev board (ESP12E devkit by doit.com). It uses just the USB to supply power to the ESP module. For this test, I just let it boot into punyforth. Note that the punyforth has everything available from the release, not just the core. The setup is just the same as for that project to drive stepper (on hackaday.io). Even though the ESP does remember its IP information, I still load the three lines each time just to be consistent.
192 168 8 88 >ipv4 wifi-set-ip
1 3 0 AUTH_WPA2_PSK str: "1234567890" str: "avago" wifi-softap
4 192 168 8 100 >ipv4 dhcpd-start

Of course, I wait for the prompt '(stack)' before loading the next line, but he line sent is not echoed to the logfile. I've attached a sample log from about 10 minutes connection. Many thanks for looking at this, @zeroflag.
The file has 8 fatal exceptions: 1 code (9) and 7 code (28).
ESP12Edevkit6c27log.txt
freemem . osfreemem .
results in

8036(stack) 13456(stack)

PS in station mode, all works just fine. stable and all

Need SPI documentation

I'm trying to code up an spi-read function. I guess it needs to be implemented using the spi-send function but there is no documentation on how the function works. Also I would like to know how to set the spi speed correctly for the spi-init function.

If you can either provide me with an spi-read function or point me at some documentation so I can code one myself I would appreciate it.

Undefined word: wifi-connect

I loaded Punyforth into my ESP8266 according to instructions. When I use the wifi-connect word (from instructions) I get Undefined word: wifi-connect

Serial UART Terminal misconfiguration creates apparent hang at (stack)

May have spoken too soon in closing #40

After replacing with the latest esptool.py I thought the flashing process had completed but there still seems to be something wrong with the punyforth session which comes up after the flashing reports success. I tried resorting to a NodeMCUv2 device which has a CP2102 and ESP8266 with 4MB but this behaves identically.

I connected via screen /dev/ttyUSB0 115200 and it shows (stack) but the terminal session is non-responsive - none of the keys you press appear as echoed characters and typing the example test command println: "hello" does nothing.

On closer inspection of the example terminal session you show on the main page, I should probably be seeing the phrase "Punyforth ready" which never arrives, and not just (stack).

If I stay connected to /dev/ttyUSB0 and press reset it shows the following after the boot messages...

pp_task_hdl : 3fff5c20, prio:14, stack:512
pm_task_hdl : 3fff5680, prio:1, stack:176
frc2_timer_task_hdl:0x3fff4950, prio:12, stack:200

ESP-Open-SDK ver: 0.0.1 compiled @ Jan 10 2018 17:21:17
phy ver: 273, pp ver: 8.3


Loading Punyforth
mode : softAP(5e:cf:7f:1e:13:e0)
add if1
bcn 100
.......
(stack)

Below is a log of the upload process in case there's anything which might help...

$ python2 flash.py /dev/ttyUSB1
Selected modules: ALL
Flashing binaries..
Flashing 0x0: rboot.bin, 0x1000: blank_config.bin, 0x2000: punyforth.bin
WARNING: Flash size arguments in megabits like '32m' are deprecated.
Please use the equivalent size '4MB'.
Megabit arguments may be removed in a future release.
esptool.py v2.4.0-dev
Connecting....
Detecting chip type... ESP8266
Chip is ESP8266EX
Features: WiFi
Uploading stub...
Running stub...
Stub running...
Configuring flash size...
Flash params set to 0x0040
Compressed 3104 bytes to 2169...
Wrote 3104 bytes (2169 compressed) at 0x00000000 in 0.2 seconds (effective 126.7 kbit/s)...
Hash of data verified.
Compressed 2048 bytes to 23...
Wrote 2048 bytes (23 compressed) at 0x00001000 in 0.0 seconds (effective 2326.9 kbit/s)...
Hash of data verified.
Compressed 310800 bytes to 203795...
Wrote 310800 bytes (203795 compressed) at 0x00002000 in 18.0 seconds (effective 137.9 kbit/s)...
Hash of data verified.

Leaving...
Hard resetting via RTS pin...
Flashing LAYOUT.tmp
esptool.py v2.4.0-dev
Connecting....
Detecting chip type... ESP8266
Chip is ESP8266EX
Features: WiFi
Uploading stub...
Running stub...
Stub running...
Configuring flash size...
Auto-detected Flash size: 4MB
Compressed 392 bytes to 184...
Wrote 392 bytes (184 compressed) at 0x00051000 in 0.0 seconds (effective 149.4 kbit/s)...
Hash of data verified.

Leaving...
Hard resetting via RTS pin...
Flashing 0x52000: APP.tmp, 0x53000: CORE.tmp, 0x56000: DHT22.tmp, 0x57000: FLASH.tmp, 0x58000: FONT57.tmp, 0x59000: GPIO.tmp, 0x5a000: MAILBOX.tmp, 0x5b000: NETCON.tmp, 0x5d000: NTP.tmp, 0x5e000: PING.tmp, 0x5f000: SONOFF.tmp, 0x60000: SSD1306I2C.tmp, 0x62000: SSD1306SPI.tmp, 0x64000: TASKS.tmp, 0x65000: TCPREPL.tmp, 0x66000: TURNKEY.tmp, 0x67000: WIFI.tmp, 0x68000: EVENT.tmp, 0x69000: RINGBUF.tmp, 0x6a000: DECOMP.tmp, 0x6b000: PUNIT.tmp
WARNING: Flash size arguments in megabits like '32m' are deprecated.
Please use the equivalent size '4MB'.
Megabit arguments may be removed in a future release.
esptool.py v2.4.0-dev
Connecting....
Detecting chip type... ESP8266
Chip is ESP8266EX
Features: WiFi
Uploading stub...
Running stub...
Stub running...
Configuring flash size...
Compressed 40 bytes to 39...
Wrote 40 bytes (39 compressed) at 0x00052000 in 0.0 seconds (effective 39.8 kbit/s)...
Hash of data verified.
Compressed 11044 bytes to 3502...
Wrote 11044 bytes (3502 compressed) at 0x00053000 in 0.3 seconds (effective 282.2 kbit/s)...
Hash of data verified.
Compressed 1768 bytes to 722...
Wrote 1768 bytes (722 compressed) at 0x00056000 in 0.1 seconds (effective 208.0 kbit/s)...
Hash of data verified.
Compressed 1528 bytes to 714...
Wrote 1528 bytes (714 compressed) at 0x00057000 in 0.1 seconds (effective 179.7 kbit/s)...
Hash of data verified.
Compressed 3864 bytes to 1720...
Wrote 3864 bytes (1720 compressed) at 0x00058000 in 0.2 seconds (effective 198.2 kbit/s)...
Hash of data verified.
Compressed 800 bytes to 361...
Wrote 800 bytes (361 compressed) at 0x00059000 in 0.0 seconds (effective 177.6 kbit/s)...
Hash of data verified.
Compressed 340 bytes to 172...
Wrote 340 bytes (172 compressed) at 0x0005a000 in 0.0 seconds (effective 136.1 kbit/s)...
Hash of data verified.
Compressed 4252 bytes to 1329...
Wrote 4252 bytes (1329 compressed) at 0x0005b000 in 0.1 seconds (effective 278.7 kbit/s)...
Hash of data verified.
Compressed 1080 bytes to 542...
Wrote 1080 bytes (542 compressed) at 0x0005d000 in 0.1 seconds (effective 163.1 kbit/s)...
Hash of data verified.
Compressed 1096 bytes to 579...
Wrote 1096 bytes (579 compressed) at 0x0005e000 in 0.1 seconds (effective 156.8 kbit/s)...
Hash of data verified.
Compressed 616 bytes to 307...
Wrote 616 bytes (307 compressed) at 0x0005f000 in 0.0 seconds (effective 153.6 kbit/s)...
Hash of data verified.
Compressed 5224 bytes to 1861...
Wrote 5224 bytes (1861 compressed) at 0x00060000 in 0.2 seconds (effective 248.7 kbit/s)...
Hash of data verified.
Compressed 5276 bytes to 1751...
Wrote 5276 bytes (1751 compressed) at 0x00062000 in 0.2 seconds (effective 263.9 kbit/s)...
Hash of data verified.
Compressed 3260 bytes to 1083...
Wrote 3260 bytes (1083 compressed) at 0x00064000 in 0.1 seconds (effective 258.1 kbit/s)...
Hash of data verified.
Compressed 1760 bytes to 714...
Wrote 1760 bytes (714 compressed) at 0x00065000 in 0.1 seconds (effective 206.6 kbit/s)...
Hash of data verified.
Compressed 804 bytes to 416...
Wrote 804 bytes (416 compressed) at 0x00066000 in 0.0 seconds (effective 156.9 kbit/s)...
Hash of data verified.
Compressed 1444 bytes to 600...
Wrote 1444 bytes (600 compressed) at 0x00067000 in 0.1 seconds (effective 199.6 kbit/s)...
Hash of data verified.
Compressed 328 bytes to 193...
Wrote 328 bytes (193 compressed) at 0x00068000 in 0.0 seconds (effective 119.6 kbit/s)...
Hash of data verified.
Compressed 1392 bytes to 446...
Wrote 1392 bytes (446 compressed) at 0x00069000 in 0.0 seconds (effective 252.9 kbit/s)...
Hash of data verified.
Compressed 3312 bytes to 1257...
Wrote 3312 bytes (1257 compressed) at 0x0006a000 in 0.1 seconds (effective 230.1 kbit/s)...
Hash of data verified.
Compressed 1972 bytes to 750...
Wrote 1972 bytes (750 compressed) at 0x0006b000 in 0.1 seconds (effective 221.8 kbit/s)...
Hash of data verified.

Leaving...
Hard resetting via RTS pin...

example of i2c words

Hi Atila !

I am having troubles finding an example of i2c use, I am triying a PCF8574 lcd
and saw yours
i2c-write-slave
i2c-read-slave
i2c-write
i2c-read
i2c-init
i2c-stop
i2c-start

my questions are how to adress the chip , stack notation for each word, etc.

is it Ok to use D1 SCL and D2 SDA, must those Pins be defined beforehand to the
ESP8266 or are they fixeded pins ? lots of doubts....

Can you help me ?

Best regards,
Enrique.

Flash starts but doesn't finish properly

Hi,
I'm trying to flash punyforth into my ESP-01 from my Ubuntu 18.04.
It seems to start fine but it suddenly ends without an error:

takeshi@takeshi-Prime-Series:~/extra/src/git/punyforth/arch/esp8266/bin$ python flash.py --flashmode dio /dev/ttyUSB0
Selected modules: ALL
Flashing binaries..
Flashing 0x0: rboot.bin, 0x1000: blank_config.bin, 0x2000: punyforth.bin
Connecting...
Erasing flash...
Took 0.16s to erase flash block
Writing at 0x00000000... (25 %)
Writing at 0x00000400... (50 %)
Writing at 0x00000800... (75 %)
Writing at 0x00000c00... (100 %)
Wrote 4096 bytes at 0x00000000 in 0.4 seconds (82.1 kbit/s)...
Erasing flash...
Took 0.16s to erase flash block
Writing at 0x00001000... (50 %)
Writing at 0x00001400... (100 %)
Wrote 2048 bytes at 0x00001000 in 0.2 seconds (82.8 kbit/s)...
Erasing flash...
Took 2.32s to erase flash block
Writing at 0x00002000... (0 %)
Writing at 0x00002400... (0 %)
Writing at 0x00002800... (0 %)
Writing at 0x00002c00... (1 %)
Writing at 0x00003000... (1 %)
Writing at 0x00003400... (1 %)
Writing at 0x00003800... (2 %)
Writing at 0x00003c00... (2 %)
Writing at 0x00004000... (2 %)
Writing at 0x00004400... (3 %)
Writing at 0x00004800... (3 %)
Writing at 0x00004c00... (3 %)
Writing at 0x00005000... (4 %)
Writing at 0x00005400... (4 %)
Writing at 0x00005800... (4 %)
Writing at 0x00005c00... (5 %)
Writing at 0x00006000... (5 %)
Writing at 0x00006400... (5 %)
Writing at 0x00006800... (6 %)
Writing at 0x00006c00... (6 %)
Writing at 0x00007000... (6 %)
Writing at 0x00007400... (7 %)
Writing at 0x00007800... (7 %)
Writing at 0x00007c00... (7 %)
Writing at 0x00008000... (8 %)
Writing at 0x00008400... (8 %)
Writing at 0x00008800... (8 %)
Writing at 0x00008c00... (9 %)
Writing at 0x00009000... (9 %)
Writing at 0x00009400... (9 %)
Writing at 0x00009800... (10 %)
Writing at 0x00009c00... (10 %)
Writing at 0x0000a000... (10 %)
Writing at 0x0000a400... (11 %)
Writing at 0x0000a800... (11 %)
Writing at 0x0000ac00... (11 %)
Writing at 0x0000b000... (12 %)
Writing at 0x0000b400... (12 %)
Writing at 0x0000b800... (12 %)
Writing at 0x0000bc00... (13 %)
Writing at 0x0000c000... (13 %)
Writing at 0x0000c400... (13 %)
Writing at 0x0000c800... (14 %)
Writing at 0x0000cc00... (14 %)
Writing at 0x0000d000... (14 %)
Writing at 0x0000d400... (15 %)
Writing at 0x0000d800... (15 %)
Writing at 0x0000dc00... (15 %)
Writing at 0x0000e000... (16 %)
Writing at 0x0000e400... (16 %)
Writing at 0x0000e800... (16 %)
Writing at 0x0000ec00... (17 %)
Writing at 0x0000f000... (17 %)
Writing at 0x0000f400... (17 %)
Writing at 0x0000f800... (18 %)
Writing at 0x0000fc00... (18 %)
Writing at 0x00010000... (18 %)
Writing at 0x00010400... (19 %)
Writing at 0x00010800... (19 %)
Writing at 0x00010c00... (19 %)
Writing at 0x00011000... (20 %)
Writing at 0x00011400... (20 %)
Writing at 0x00011800... (20 %)
Writing at 0x00011c00... (21 %)
Writing at 0x00012000... (21 %)
Writing at 0x00012400... (21 %)
Writing at 0x00012800... (22 %)
Writing at 0x00012c00... (22 %)
Writing at 0x00013000... (22 %)
Writing at 0x00013400... (23 %)
Writing at 0x00013800... (23 %)
Writing at 0x00013c00... (23 %)
Writing at 0x00014000... (24 %)
Writing at 0x00014400... (24 %)
Writing at 0x00014800... (24 %)
Writing at 0x00014c00... (25 %)
Writing at 0x00015000... (25 %)
Writing at 0x00015400... (25 %)
Writing at 0x00015800... (25 %)
Writing at 0x00015c00... (26 %)
Writing at 0x00016000... (26 %)
Writing at 0x00016400... (26 %)
Writing at 0x00016800... (27 %)
Writing at 0x00016c00... (27 %)
Writing at 0x00017000... (27 %)
Writing at 0x00017400... (28 %)
Writing at 0x00017800... (28 %)
Writing at 0x00017c00... (28 %)
Writing at 0x00018000... (29 %)
Writing at 0x00018400... (29 %)
Writing at 0x00018800... (29 %)
Writing at 0x00018c00... (30 %)
Writing at 0x00019000... (30 %)
Writing at 0x00019400... (30 %)
Writing at 0x00019800... (31 %)
Writing at 0x00019c00... (31 %)
Writing at 0x0001a000... (31 %)
Writing at 0x0001a400... (32 %)
Writing at 0x0001a800... (32 %)
Writing at 0x0001ac00... (32 %)
Writing at 0x0001b000... (33 %)
Writing at 0x0001b400... (33 %)
Writing at 0x0001b800... (33 %)
Writing at 0x0001bc00... (34 %)
Writing at 0x0001c000... (34 %)
Writing at 0x0001c400... (34 %)
Writing at 0x0001c800... (35 %)
Writing at 0x0001cc00... (35 %)
Writing at 0x0001d000... (35 %)
Writing at 0x0001d400... (36 %)
Writing at 0x0001d800... (36 %)
Writing at 0x0001dc00... (36 %)
Writing at 0x0001e000... (37 %)
Writing at 0x0001e400... (37 %)
Writing at 0x0001e800... (37 %)
Writing at 0x0001ec00... (38 %)
Writing at 0x0001f000... (38 %)
Writing at 0x0001f400... (38 %)
Writing at 0x0001f800... (39 %)
Writing at 0x0001fc00... (39 %)
Writing at 0x00020000... (39 %)
Writing at 0x00020400... (40 %)
Writing at 0x00020800... (40 %)
Writing at 0x00020c00... (40 %)
Writing at 0x00021000... (41 %)
Writing at 0x00021400... (41 %)
Writing at 0x00021800... (41 %)
Writing at 0x00021c00... (42 %)
Writing at 0x00022000... (42 %)
Writing at 0x00022400... (42 %)
Writing at 0x00022800... (43 %)
Writing at 0x00022c00... (43 %)
Writing at 0x00023000... (43 %)
Writing at 0x00023400... (44 %)
Writing at 0x00023800... (44 %)
Writing at 0x00023c00... (44 %)
Writing at 0x00024000... (45 %)
Writing at 0x00024400... (45 %)
Writing at 0x00024800... (45 %)
Writing at 0x00024c00... (46 %)
Writing at 0x00025000... (46 %)
Writing at 0x00025400... (46 %)
Writing at 0x00025800... (47 %)
Writing at 0x00025c00... (47 %)
Writing at 0x00026000... (47 %)
Writing at 0x00026400... (48 %)
Writing at 0x00026800... (48 %)
Writing at 0x00026c00... (48 %)
Writing at 0x00027000... (49 %)
Writing at 0x00027400... (49 %)
Writing at 0x00027800... (49 %)
Writing at 0x00027c00... (50 %)
Writing at 0x00028000... (50 %)
Writing at 0x00028400... (50 %)
Writing at 0x00028800... (50 %)
Writing at 0x00028c00... (51 %)
Writing at 0x00029000... (51 %)
Writing at 0x00029400... (51 %)
Writing at 0x00029800... (52 %)
Writing at 0x00029c00... (52 %)
Writing at 0x0002a000... (52 %)
Writing at 0x0002a400... (53 %)
Writing at 0x0002a800... (53 %)
Writing at 0x0002ac00... (53 %)
Writing at 0x0002b000... (54 %)
Writing at 0x0002b400... (54 %)
Writing at 0x0002b800... (54 %)
Writing at 0x0002bc00... (55 %)
Writing at 0x0002c000... (55 %)
Writing at 0x0002c400... (55 %)
Writing at 0x0002c800... (56 %)
Writing at 0x0002cc00... (56 %)
Writing at 0x0002d000... (56 %)
Writing at 0x0002d400... (57 %)
Writing at 0x0002d800... (57 %)
Writing at 0x0002dc00... (57 %)
Writing at 0x0002e000... (58 %)
Writing at 0x0002e400... (58 %)
Writing at 0x0002e800... (58 %)
Writing at 0x0002ec00... (59 %)
Writing at 0x0002f000... (59 %)
Writing at 0x0002f400... (59 %)
Writing at 0x0002f800... (60 %)
Writing at 0x0002fc00... (60 %)
Writing at 0x00030000... (60 %)
Writing at 0x00030400... (61 %)
Writing at 0x00030800... (61 %)
Writing at 0x00030c00... (61 %)
Writing at 0x00031000... (62 %)
Writing at 0x00031400... (62 %)
Writing at 0x00031800... (62 %)
Writing at 0x00031c00... (63 %)
Writing at 0x00032000... (63 %)
Writing at 0x00032400... (63 %)
Writing at 0x00032800... (64 %)
Writing at 0x00032c00... (64 %)
Writing at 0x00033000... (64 %)
Writing at 0x00033400... (65 %)
Writing at 0x00033800... (65 %)
Writing at 0x00033c00... (65 %)
Writing at 0x00034000... (66 %)
Writing at 0x00034400... (66 %)
Writing at 0x00034800... (66 %)
Writing at 0x00034c00... (67 %)
Writing at 0x00035000... (67 %)
Writing at 0x00035400... (67 %)
Writing at 0x00035800... (68 %)
Writing at 0x00035c00... (68 %)
Writing at 0x00036000... (68 %)
Writing at 0x00036400... (69 %)
Writing at 0x00036800... (69 %)
Writing at 0x00036c00... (69 %)
Writing at 0x00037000... (70 %)
Writing at 0x00037400... (70 %)
Writing at 0x00037800... (70 %)
Writing at 0x00037c00... (71 %)
Writing at 0x00038000... (71 %)
Writing at 0x00038400... (71 %)
Writing at 0x00038800... (72 %)
Writing at 0x00038c00... (72 %)
Writing at 0x00039000... (72 %)
Writing at 0x00039400... (73 %)
Writing at 0x00039800... (73 %)
Writing at 0x00039c00... (73 %)
Writing at 0x0003a000... (74 %)
Writing at 0x0003a400... (74 %)
Writing at 0x0003a800... (74 %)
Writing at 0x0003ac00... (75 %)
Writing at 0x0003b000... (75 %)
Writing at 0x0003b400... (75 %)
Writing at 0x0003b800... (75 %)
Writing at 0x0003bc00... (76 %)
Writing at 0x0003c000... (76 %)
Writing at 0x0003c400... (76 %)
Writing at 0x0003c800... (77 %)
Writing at 0x0003cc00... (77 %)
Writing at 0x0003d000... (77 %)
Writing at 0x0003d400... (78 %)
Writing at 0x0003d800... (78 %)
Writing at 0x0003dc00... (78 %)
Writing at 0x0003e000... (79 %)
Writing at 0x0003e400... (79 %)
Writing at 0x0003e800... (79 %)
Writing at 0x0003ec00... (80 %)
Writing at 0x0003f000... (80 %)
Writing at 0x0003f400... (80 %)
Writing at 0x0003f800... (81 %)
Writing at 0x0003fc00... (81 %)
Writing at 0x00040000... (81 %)
Writing at 0x00040400... (82 %)
Writing at 0x00040800... (82 %)
Writing at 0x00040c00... (82 %)
Writing at 0x00041000... (83 %)
Writing at 0x00041400... (83 %)
Writing at 0x00041800... (83 %)
Writing at 0x00041c00... (84 %)
Writing at 0x00042000... (84 %)
Writing at 0x00042400... (84 %)
Writing at 0x00042800... (85 %)
Writing at 0x00042c00... (85 %)
Writing at 0x00043000... (85 %)
Writing at 0x00043400... (86 %)
Writing at 0x00043800... (86 %)
Writing at 0x00043c00... (86 %)
Writing at 0x00044000... (87 %)
Writing at 0x00044400... (87 %)
Writing at 0x00044800... (87 %)
Writing at 0x00044c00... (88 %)
Writing at 0x00045000... (88 %)
Writing at 0x00045400... (88 %)
Writing at 0x00045800... (89 %)
Writing at 0x00045c00... (89 %)
Writing at 0x00046000... (89 %)
Writing at 0x00046400... (90 %)
Writing at 0x00046800... (90 %)
Writing at 0x00046c00... (90 %)
Writing at 0x00047000... (91 %)
Writing at 0x00047400... (91 %)
Writing at 0x00047800... (91 %)
Writing at 0x00047c00... (92 %)
Writing at 0x00048000... (92 %)
Writing at 0x00048400... (92 %)
Writing at 0x00048800... (93 %)
Writing at 0x00048c00... (93 %)
Writing at 0x00049000... (93 %)
Writing at 0x00049400... (94 %)
Writing at 0x00049800... (94 %)
Writing at 0x00049c00... (94 %)
Writing at 0x0004a000... (95 %)
Writing at 0x0004a400... (95 %)
Writing at 0x0004a800... (95 %)
Writing at 0x0004ac00... (96 %)
Writing at 0x0004b000... (96 %)
Writing at 0x0004b400... (96 %)
Writing at 0x0004b800... (97 %)
Writing at 0x0004bc00... (97 %)
Writing at 0x0004c000... (97 %)
Writing at 0x0004c400... (98 %)
Writing at 0x0004c800... (98 %)
Writing at 0x0004cc00... (98 %)
Writing at 0x0004d000... (99 %)
Writing at 0x0004d400... (99 %)
Writing at 0x0004d800... (99 %)
Writing at 0x0004dc00... (100 %)
Wrote 311296 bytes at 0x00002000 in 30.6 seconds (81.3 kbit/s)...

Leaving...
Flashing LAYOUT.tmp
Connecting...
Erasing flash...
Took 0.16s to erase flash block
Writing at 0x00051000... (100 %)
Wrote 1024 bytes at 0x00051000 in 0.1 seconds (83.7 kbit/s)...

Leaving...
Flashing 0x52000: APP.tmp, 0x53000: CORE.tmp, 0x56000: DHT22.tmp, 0x57000: FLASH.tmp, 0x58000: FONT57.tmp, 0x59000: GPIO.tmp, 0x5a000: MAILBOX.tmp, 0x5b000: NETCON.tmp, 0x5d000: NTP.tmp, 0x5e000: PING.tmp, 0x5f000: SONOFF.tmp, 0x60000: SSD1306I2C.tmp, 0x62000: SSD1306SPI.tmp, 0x64000: TASKS.tmp, 0x65000: TCPREPL.tmp, 0x66000: TURNKEY.tmp, 0x67000: WIFI.tmp, 0x68000: EVENT.tmp, 0x69000: RINGBUF.tmp, 0x6a000: DECOMP.tmp, 0x6b000: PUNIT.tmp
Connecting...
Erasing flash...
Took 0.13s to erase flash block
Writing at 0x00052000... (100 %)
Wrote 1024 bytes at 0x00052000 in 0.1 seconds (83.7 kbit/s)...
Erasing flash...
Took 0.30s to erase flash block
Writing at 0x00053000... (9 %)
Writing at 0x00053400... (18 %)
Writing at 0x00053800... (27 %)
Writing at 0x00053c00... (36 %)
Writing at 0x00054000... (45 %)
Writing at 0x00054400... (54 %)
Writing at 0x00054800... (63 %)
Writing at 0x00054c00... (72 %)
Writing at 0x00055000... (81 %)
Writing at 0x00055400... (90 %)
Writing at 0x00055800... (100 %)
Wrote 11264 bytes at 0x00053000 in 1.1 seconds (82.8 kbit/s)...
Erasing flash...
Took 0.16s to erase flash block
Writing at 0x00056000... (50 %)
Writing at 0x00056400... (100 %)
Wrote 2048 bytes at 0x00056000 in 0.2 seconds (83.2 kbit/s)...
Erasing flash...
Took 0.13s to erase flash block
Writing at 0x00057000... (50 %)
Writing at 0x00057400... (100 %)
Wrote 2048 bytes at 0x00057000 in 0.2 seconds (83.2 kbit/s)...
Erasing flash...
Took 0.14s to erase flash block
Writing at 0x00058000... (25 %)
Writing at 0x00058400... (50 %)
Writing at 0x00058800... (75 %)
Writing at 0x00058c00... (100 %)
Wrote 4096 bytes at 0x00058000 in 0.4 seconds (82.8 kbit/s)...
Erasing flash...
Took 0.16s to erase flash block
Writing at 0x00059000... (100 %)
Wrote 1024 bytes at 0x00059000 in 0.1 seconds (83.7 kbit/s)...
Erasing flash...
Took 0.16s to erase flash block
Writing at 0x0005a000... (100 %)
Wrote 1024 bytes at 0x0005a000 in 0.1 seconds (83.7 kbit/s)...
Erasing flash...
Took 0.13s to erase flash block
Writing at 0x0005b000... (20 %)
Writing at 0x0005b400... (40 %)
Writing at 0x0005b800... (60 %)
Writing at 0x0005bc00... (80 %)
Writing at 0x0005c000... (100 %)
Wrote 5120 bytes at 0x0005b000 in 0.5 seconds (82.9 kbit/s)...
Erasing flash...
Took 0.13s to erase flash block
Writing at 0x0005d000... (50 %)
Writing at 0x0005d400... (100 %)
Wrote 2048 bytes at 0x0005d000 in 0.2 seconds (83.2 kbit/s)...
Erasing flash...
Took 0.16s to erase flash block
Writing at 0x0005e000... (50 %)
Writing at 0x0005e400... (100 %)
Wrote 2048 bytes at 0x0005e000 in 0.2 seconds (83.2 kbit/s)...
Erasing flash...
Took 0.16s to erase flash block
Writing at 0x0005f000... (100 %)
Wrote 1024 bytes at 0x0005f000 in 0.1 seconds (83.7 kbit/s)...
Erasing flash...
Took 0.13s to erase flash block
Writing at 0x00060000... (16 %)
Writing at 0x00060400... (33 %)
Writing at 0x00060800... (50 %)
Writing at 0x00060c00... (66 %)
Writing at 0x00061000... (83 %)
Writing at 0x00061400... (100 %)
Wrote 6144 bytes at 0x00060000 in 0.6 seconds (82.9 kbit/s)...
Erasing flash...
Took 0.13s to erase flash block
Writing at 0x00062000... (20 %)
Writing at 0x00062400... (40 %)
Writing at 0x00062800... (60 %)
Writing at 0x00062c00... (80 %)
Writing at 0x00063000... (100 %)
Wrote 5120 bytes at 0x00062000 in 0.5 seconds (82.8 kbit/s)...
Erasing flash...
Took 0.16s to erase flash block
Writing at 0x00064000... (25 %)
Writing at 0x00064400... (50 %)
Writing at 0x00064800... (75 %)
Writing at 0x00064c00... (100 %)
Wrote 4096 bytes at 0x00064000 in 0.4 seconds (83.0 kbit/s)...
Erasing flash...
Took 0.16s to erase flash block
Writing at 0x00065000... (50 %)
Writing at 0x00065400... (100 %)
Wrote 2048 bytes at 0x00065000 in 0.2 seconds (83.2 kbit/s)...
Erasing flash...
Took 0.13s to erase flash block
Writing at 0x00066000... (100 %)
Wrote 1024 bytes at 0x00066000 in 0.1 seconds (82.9 kbit/s)...
Erasing flash...
Took 0.14s to erase flash block
Writing at 0x00067000... (50 %)
Writing at 0x00067400... (100 %)
Wrote 2048 bytes at 0x00067000 in 0.2 seconds (83.2 kbit/s)...
Erasing flash...
Took 0.16s to erase flash block
Writing at 0x00068000... (100 %)
Wrote 1024 bytes at 0x00068000 in 0.1 seconds (83.7 kbit/s)...
Erasing flash...
Took 0.16s to erase flash block
Writing at 0x00069000... (50 %)
Writing at 0x00069400... (100 %)
Wrote 2048 bytes at 0x00069000 in 0.2 seconds (83.2 kbit/s)...
Erasing flash...
Took 0.13s to erase flash block
Writing at 0x0006a000... (25 %)
Writing at 0x0006a400... (50 %)
Writing at 0x0006a800... (75 %)
Writing at 0x0006ac00... (100 %)
Wrote 4096 bytes at 0x0006a000 in 0.4 seconds (83.0 kbit/s)...
Erasing flash...
Took 0.13s to erase flash block
Writing at 0x0006b000... (50 %)
Writing at 0x0006b400... (100 %)
Wrote 2048 bytes at 0x0006b000 in 0.2 seconds (82.8 kbit/s)...

Leaving...
takeshi@takeshi-Prime-Series:~/extra/src/git/punyforth/arch/esp8266/bin$ echo $?
0

Based on output shown in other issues, i believe I should see:

Leaving...
Hard resetting via RTS pin...

But this didn't happen.
Anyway, after the above, when I reset the board, I can connect to it using a terminal emulator (tio) but nothing shows up, and nothing that I input gets echoed back.

Does anybody have any tips for me?

Problem with flashing modules

I followed the documentation in the readme file and successfully flashed a esp8266 using the following commands on my mac:
python flash.py /dev/tty.SLAB_USBtoUART

My understanding is that without specifying which modules to program, all modules would be programmed including the GPIO module. Unfortunately when I type help to see all defined words, words like GPIO_HIGH or GPIO_IN, etc. are not found. Further more when I try to examine the value of GPIO_HIGH it is undefined.

Then I attempted to specify the GPIO module directly using the following command line it still doesn't work.
python flash.py /dev/tty.SLAB_USBtoUART --modules core gpio flash

What am I doing wrong?

I should also say that the docs still shows the use of modules.py file to control which forth modules to be included in uber.forth. It now seems uber.forth is no longer used and the modules.py functionality is now included in the flash.py file. Please update the docs to match the code when you get a chance.

Mistype in README.md

Note that flash.py flashes with Quad I/O speed (qio) by default. This is the fastest mode but not all devices support this. If you have trouble while flashing try adding a --flashmode qio parameter.

But if I specify qio, it will not change anything, right?

How know that dhcp client is running, so can use netcon words?

As part of startup code on an ESP12 I connect to a server (actually an ESP14) with:
str: "1234567890" str: "AVAGO" wifi-connect
and also start up a couple of tasks. One of the tasks needs to
PORT HOST TCP netcon-connect
but the wifi-connect has not completed setting up the route so the netcon-connect aborts (usually -10).
One way around this is just to catch the error from netcon-connect and loop until it is successful, but it just does not look tidy. Is there a way to check the status of the dhcp client before attempting the netcon-connect?

missing further examples of turnkey and save

Dear Attila,
This is the only example we have of turnkey from the dt data logger
and there is a flash forth with another turnkey definition and save-loader
***********from data-logger *************
: main ( -- ) log-measurement 600000000 deep-sleep ;
' boot is: main turnkey abort


from falsh.forth
: save-loader ( -- ) 0 block drop c 0 row dup heap-size >str dup strlen +
str: ' heap-start ' over 12 cmove 12 + dup dst >str dup strlen +
str: ' read-flash drop boot' swap 22 cmove update flush ;


I triyed to save a forth incrementally (without using any external flash memory) bare bone
esp8266 chip. And I failed, it will all the way fall in reboot. It happend the same with
turnkey....
I am requesting kindly more examples or explanations of both words
and also if there is a way to interact with punyforth test and compile some words incrementally
and then make a "SAVE" so the system will preserve the actual dictionary for the next boot
cycle for future use and interaction.... do you understand what I mean ?
save would make the same as turnkey except for executing the ' word stored at boot, it will
coolstart from the interpreter prompt.

(I am enyoing very much your work, long life to Punyforth ! :)

Cannot flash Punyforth to ESP8285 with dout

Hi there,

I have flashing routines working routinely with the hardware under test, flashing Micropython, Circuitpython Lua(NodeMCU) and Espruino. It is a NodeMCU-M with an ESP8285 (an ESP8266 with 1MB flash) and a CH340 UART.

However, I can't seem to get the punyforth flash.py routine to function properly. Is there anything I can try?

I have overridden the mode to 'dout' as normally required when flashing this module, but I still get...

$ python2 flash.py --flashmode dout /dev/ttyUSB0
Selected modules: ALL
Flashing binaries..
Flashing 0x0: rboot.bin, 0x1000: blank_config.bin, 0x2000: punyforth.bin
Connecting...

A fatal error occurred: Failed to connect to ESP8266
Flashing LAYOUT.tmp
Connecting...

A fatal error occurred: Failed to connect to ESP8266
Flashing 0x52000: APP.tmp, 0x53000: CORE.tmp, 0x56000: DHT22.tmp, 0x57000: FLASH.tmp, 0x58000: FONT57.tmp, 0x59000: GPIO.tmp, 0x5a000: MAILBOX.tmp, 0x5b000: NETCON.tmp, 0x5d000: NTP.tmp, 0x5e000: PING.tmp, 0x5f000: SONOFF.tmp, 0x60000: SSD1306I2C.tmp, 0x62000: SSD1306SPI.tmp, 0x64000: TASKS.tmp, 0x65000: TCPREPL.tmp, 0x66000: TURNKEY.tmp, 0x67000: WIFI.tmp, 0x68000: EVENT.tmp, 0x69000: RINGBUF.tmp, 0x6a000: DECOMP.tmp, 0x6b000: PUNIT.tmp
Connecting...

A fatal error occurred: Failed to connect to ESP8266

What is IP when using AP

Just after booting I run the following 4 commands:
172 16 0 10 >ipv4 wifi-set-ip 4 3 0 AUTH_WPA2_PSK str: "1234567890" str: "AVAGO" wifi-softap 1 172 16 0 1 >ipv4 dhcpd-start wifi-ip type
and the result is

0.0.0.0(stack)

Now the netcon-... commands depend on wifi-ip being correct, so I am having trouble connecting to this server from other machines. I've followed the code back to an RTOS call and all looks ok at the punyforth end. Is this another RTOS problem?

OSX .jar files

The contribution by Craig A. Lindley lists the prerequisite files:

  1. ESP8266PunyForthLoader.jar
  2. jssc.jar (version 2.6.0 or newer)

He does supply jssc.jar, but not ESP8266PunyForthLoader.jar - only: ESP8266PunyForthLoader.java
Is ESP8266PunyForthLoader.jar or can it be generated from the ESP8266PunyForthLoader.java?

when i flash puny forth i get the same error , see file

kendo@kdewey:~/Downloads/punyforth-master/arch/esp8266/bin > python flash.py /dev/ttyUSB0
Selected modules: ALL
Flashing binaries..
Flashing 0x0: rboot.bin, 0x1000: blank_config.bin, 0x2000: punyforth.bin
Connecting...
Erasing flash...
Took 0.16s to erase flash block
Writing at 0x00000000... (25 %)
Writing at 0x00000400... (50 %)
Writing at 0x00000800... (75 %)
Writing at 0x00000c00... (100 %)
Wrote 4096 bytes at 0x00000000 in 0.4 seconds (83.2 kbit/s)...
Erasing flash...
Took 0.17s to erase flash block
Writing at 0x00001000... (50 %)
Writing at 0x00001400... (100 %)
Wrote 2048 bytes at 0x00001000 in 0.2 seconds (83.7 kbit/s)...
Erasing flash...
Took 2.22s to erase flash block
Writing at 0x00002000... (0 %)
Writing at 0x00002400... (0 %)
Writing at 0x00002800... (0 %)
Writing at 0x00002c00... (1 %)
Writing at 0x00003000... (1 %)
Writing at 0x00003400... (1 %)
Writing at 0x00003800... (2 %)
Writing at 0x00003c00... (2 %)
Writing at 0x00004000... (2 %)
Writing at 0x00004400... (3 %)
Writing at 0x00004800... (3 %)
Writing at 0x00004c00... (3 %)
Writing at 0x00005000... (4 %)
Writing at 0x00005400... (4 %)
Writing at 0x00005800... (4 %)
Writing at 0x00005c00... (5 %)
Writing at 0x00006000... (5 %)
Writing at 0x00006400... (5 %)
Writing at 0x00006800... (6 %)
Writing at 0x00006c00... (6 %)
Writing at 0x00007000... (6 %)
Writing at 0x00007400... (7 %)
Writing at 0x00007800... (7 %)
Writing at 0x00007c00... (7 %)
Writing at 0x00008000... (8 %)
Writing at 0x00008400... (8 %)
Writing at 0x00008800... (8 %)
Writing at 0x00008c00... (9 %)
Writing at 0x00009000... (9 %)
Writing at 0x00009400... (9 %)
Writing at 0x00009800... (10 %)
Writing at 0x00009c00... (10 %)
Writing at 0x0000a000... (10 %)
Writing at 0x0000a400... (11 %)
Writing at 0x0000a800... (11 %)
Writing at 0x0000ac00... (11 %)
Writing at 0x0000b000... (12 %)
Writing at 0x0000b400... (12 %)
Writing at 0x0000b800... (12 %)
Writing at 0x0000bc00... (13 %)
Writing at 0x0000c000... (13 %)
Writing at 0x0000c400... (13 %)
Writing at 0x0000c800... (14 %)
Writing at 0x0000cc00... (14 %)
Writing at 0x0000d000... (14 %)
Writing at 0x0000d400... (15 %)
Writing at 0x0000d800... (15 %)
Writing at 0x0000dc00... (15 %)
Writing at 0x0000e000... (16 %)
Writing at 0x0000e400... (16 %)
Writing at 0x0000e800... (16 %)
Writing at 0x0000ec00... (17 %)
Writing at 0x0000f000... (17 %)
Writing at 0x0000f400... (17 %)
Writing at 0x0000f800... (18 %)
Writing at 0x0000fc00... (18 %)
Writing at 0x00010000... (18 %)
Writing at 0x00010400... (19 %)
Writing at 0x00010800... (19 %)
Writing at 0x00010c00... (19 %)
Writing at 0x00011000... (20 %)
Writing at 0x00011400... (20 %)
Writing at 0x00011800... (20 %)
Writing at 0x00011c00... (21 %)
Writing at 0x00012000... (21 %)
Writing at 0x00012400... (21 %)
Writing at 0x00012800... (22 %)
Writing at 0x00012c00... (22 %)
Writing at 0x00013000... (22 %)
Writing at 0x00013400... (23 %)
Writing at 0x00013800... (23 %)
Writing at 0x00013c00... (23 %)
Writing at 0x00014000... (24 %)
Writing at 0x00014400... (24 %)
Writing at 0x00014800... (24 %)
Writing at 0x00014c00... (25 %)
Writing at 0x00015000... (25 %)
Writing at 0x00015400... (25 %)
Writing at 0x00015800... (25 %)
Writing at 0x00015c00... (26 %)
Writing at 0x00016000... (26 %)
Writing at 0x00016400... (26 %)
Writing at 0x00016800... (27 %)
Writing at 0x00016c00... (27 %)
Writing at 0x00017000... (27 %)
Writing at 0x00017400... (28 %)
Writing at 0x00017800... (28 %)
Writing at 0x00017c00... (28 %)
Writing at 0x00018000... (29 %)
Writing at 0x00018400... (29 %)
Writing at 0x00018800... (29 %)
Writing at 0x00018c00... (30 %)
Writing at 0x00019000... (30 %)
Writing at 0x00019400... (30 %)
Writing at 0x00019800... (31 %)
Writing at 0x00019c00... (31 %)
Writing at 0x0001a000... (31 %)
Writing at 0x0001a400... (32 %)
Writing at 0x0001a800... (32 %)
Writing at 0x0001ac00... (32 %)
Writing at 0x0001b000... (33 %)
Writing at 0x0001b400... (33 %)
Writing at 0x0001b800... (33 %)
Writing at 0x0001bc00... (34 %)
Writing at 0x0001c000... (34 %)
Writing at 0x0001c400... (34 %)
Writing at 0x0001c800... (35 %)
Writing at 0x0001cc00... (35 %)
Writing at 0x0001d000... (35 %)
Writing at 0x0001d400... (36 %)
Writing at 0x0001d800... (36 %)
Writing at 0x0001dc00... (36 %)
Writing at 0x0001e000... (37 %)
Writing at 0x0001e400... (37 %)
Writing at 0x0001e800... (37 %)
Writing at 0x0001ec00... (38 %)
Writing at 0x0001f000... (38 %)
Writing at 0x0001f400... (38 %)
Writing at 0x0001f800... (39 %)
Writing at 0x0001fc00... (39 %)
Writing at 0x00020000... (39 %)
Writing at 0x00020400... (40 %)
Writing at 0x00020800... (40 %)
Writing at 0x00020c00... (40 %)
Writing at 0x00021000... (41 %)
Writing at 0x00021400... (41 %)
Writing at 0x00021800... (41 %)
Writing at 0x00021c00... (42 %)
Writing at 0x00022000... (42 %)
Writing at 0x00022400... (42 %)
Writing at 0x00022800... (43 %)
Writing at 0x00022c00... (43 %)
Writing at 0x00023000... (43 %)
Writing at 0x00023400... (44 %)
Writing at 0x00023800... (44 %)
Writing at 0x00023c00... (44 %)
Writing at 0x00024000... (45 %)
Writing at 0x00024400... (45 %)
Writing at 0x00024800... (45 %)
Writing at 0x00024c00... (46 %)
Writing at 0x00025000... (46 %)
Writing at 0x00025400... (46 %)
Writing at 0x00025800... (47 %)
Writing at 0x00025c00... (47 %)
Writing at 0x00026000... (47 %)
Writing at 0x00026400... (48 %)
Writing at 0x00026800... (48 %)
Writing at 0x00026c00... (48 %)
Writing at 0x00027000... (49 %)
Writing at 0x00027400... (49 %)
Writing at 0x00027800... (49 %)
Writing at 0x00027c00... (50 %)
Writing at 0x00028000... (50 %)
Writing at 0x00028400... (50 %)
Writing at 0x00028800... (50 %)
Writing at 0x00028c00... (51 %)
Writing at 0x00029000... (51 %)
Writing at 0x00029400... (51 %)
Writing at 0x00029800... (52 %)
Writing at 0x00029c00... (52 %)
Writing at 0x0002a000... (52 %)
Writing at 0x0002a400... (53 %)
Writing at 0x0002a800... (53 %)
Writing at 0x0002ac00... (53 %)
Writing at 0x0002b000... (54 %)
Writing at 0x0002b400... (54 %)
Writing at 0x0002b800... (54 %)
Writing at 0x0002bc00... (55 %)
Writing at 0x0002c000... (55 %)
Writing at 0x0002c400... (55 %)
Writing at 0x0002c800... (56 %)
Writing at 0x0002cc00... (56 %)
Writing at 0x0002d000... (56 %)
Writing at 0x0002d400... (57 %)
Writing at 0x0002d800... (57 %)
Writing at 0x0002dc00... (57 %)
Writing at 0x0002e000... (58 %)
Writing at 0x0002e400... (58 %)
Writing at 0x0002e800... (58 %)
Writing at 0x0002ec00... (59 %)
Writing at 0x0002f000... (59 %)
Writing at 0x0002f400... (59 %)
Writing at 0x0002f800... (60 %)
Writing at 0x0002fc00... (60 %)
Writing at 0x00030000... (60 %)
Writing at 0x00030400... (61 %)
Writing at 0x00030800... (61 %)
Writing at 0x00030c00... (61 %)
Writing at 0x00031000... (62 %)
Writing at 0x00031400... (62 %)
Writing at 0x00031800... (62 %)
Writing at 0x00031c00... (63 %)
Writing at 0x00032000... (63 %)
Writing at 0x00032400... (63 %)
Writing at 0x00032800... (64 %)
Writing at 0x00032c00... (64 %)
Writing at 0x00033000... (64 %)
Writing at 0x00033400... (65 %)
Writing at 0x00033800... (65 %)
Writing at 0x00033c00... (65 %)
Writing at 0x00034000... (66 %)
Writing at 0x00034400... (66 %)
Writing at 0x00034800... (66 %)
Writing at 0x00034c00... (67 %)
Writing at 0x00035000... (67 %)
Writing at 0x00035400... (67 %)
Writing at 0x00035800... (68 %)
Writing at 0x00035c00... (68 %)
Writing at 0x00036000... (68 %)
Writing at 0x00036400... (69 %)
Writing at 0x00036800... (69 %)
Writing at 0x00036c00... (69 %)
Writing at 0x00037000... (70 %)
Writing at 0x00037400... (70 %)
Writing at 0x00037800... (70 %)
Writing at 0x00037c00... (71 %)
Writing at 0x00038000... (71 %)
Writing at 0x00038400... (71 %)
Writing at 0x00038800... (72 %)
Writing at 0x00038c00... (72 %)
Writing at 0x00039000... (72 %)
Writing at 0x00039400... (73 %)
Writing at 0x00039800... (73 %)
Writing at 0x00039c00... (73 %)
Writing at 0x0003a000... (74 %)
Writing at 0x0003a400... (74 %)
Writing at 0x0003a800... (74 %)
Writing at 0x0003ac00... (75 %)
Writing at 0x0003b000... (75 %)
Writing at 0x0003b400... (75 %)
Writing at 0x0003b800... (75 %)
Writing at 0x0003bc00... (76 %)
Writing at 0x0003c000... (76 %)
Writing at 0x0003c400... (76 %)
Writing at 0x0003c800... (77 %)
Writing at 0x0003cc00... (77 %)
Writing at 0x0003d000... (77 %)
Writing at 0x0003d400... (78 %)
Writing at 0x0003d800... (78 %)
Writing at 0x0003dc00... (78 %)
Writing at 0x0003e000... (79 %)
Writing at 0x0003e400... (79 %)
Writing at 0x0003e800... (79 %)
Writing at 0x0003ec00... (80 %)
Writing at 0x0003f000... (80 %)
Writing at 0x0003f400... (80 %)
Writing at 0x0003f800... (81 %)
Writing at 0x0003fc00... (81 %)
Writing at 0x00040000... (81 %)
Writing at 0x00040400... (82 %)
Writing at 0x00040800... (82 %)
Writing at 0x00040c00... (82 %)
Writing at 0x00041000... (83 %)
Writing at 0x00041400... (83 %)
Writing at 0x00041800... (83 %)
Writing at 0x00041c00... (84 %)
Writing at 0x00042000... (84 %)
Writing at 0x00042400... (84 %)
Writing at 0x00042800... (85 %)
Writing at 0x00042c00... (85 %)
Writing at 0x00043000... (85 %)
Writing at 0x00043400... (86 %)
Writing at 0x00043800... (86 %)
Writing at 0x00043c00... (86 %)
Writing at 0x00044000... (87 %)
Writing at 0x00044400... (87 %)
Writing at 0x00044800... (87 %)
Writing at 0x00044c00... (88 %)
Writing at 0x00045000... (88 %)
Writing at 0x00045400... (88 %)
Writing at 0x00045800... (89 %)
Writing at 0x00045c00... (89 %)
Writing at 0x00046000... (89 %)
Writing at 0x00046400... (90 %)
Writing at 0x00046800... (90 %)
Writing at 0x00046c00... (90 %)
Writing at 0x00047000... (91 %)
Writing at 0x00047400... (91 %)
Writing at 0x00047800... (91 %)
Writing at 0x00047c00... (92 %)
Writing at 0x00048000... (92 %)
Writing at 0x00048400... (92 %)
Writing at 0x00048800... (93 %)
Writing at 0x00048c00... (93 %)
Writing at 0x00049000... (93 %)
Writing at 0x00049400... (94 %)
Writing at 0x00049800... (94 %)
Writing at 0x00049c00... (94 %)
Writing at 0x0004a000... (95 %)
Writing at 0x0004a400... (95 %)
Writing at 0x0004a800... (95 %)
Writing at 0x0004ac00... (96 %)
Writing at 0x0004b000... (96 %)
Writing at 0x0004b400... (96 %)
Writing at 0x0004b800... (97 %)
Writing at 0x0004bc00... (97 %)
Writing at 0x0004c000... (97 %)
Writing at 0x0004c400... (98 %)
Writing at 0x0004c800... (98 %)
Writing at 0x0004cc00... (98 %)
Writing at 0x0004d000... (99 %)
Writing at 0x0004d400... (99 %)
Writing at 0x0004d800... (99 %)
Writing at 0x0004dc00... (100 %)
Wrote 311296 bytes at 0x00002000 in 30.2 seconds (82.4 kbit/s)...

Leaving...
Flashing LAYOUT.tmp
Connecting...
Erasing flash...
Took 0.15s to erase flash block
Writing at 0x00051000... (100 %)
Wrote 1024 bytes at 0x00051000 in 0.1 seconds (85.4 kbit/s)...

Leaving...
Flashing 0x52000: APP.tmp, 0x53000: CORE.tmp, 0x56000: DHT22.tmp, 0x57000: FLASH.tmp, 0x58000: FONT57.tmp, 0x59000: GPIO.tmp, 0x5a000: MAILBOX.tmp, 0x5b000: NETCON.tmp, 0x5d000: NTP.tmp, 0x5e000: PING.tmp, 0x5f000: SONOFF.tmp, 0x60000: SSD1306I2C.tmp, 0x62000: SSD1306SPI.tmp, 0x64000: TASKS.tmp, 0x65000: TCPREPL.tmp, 0x66000: TURNKEY.tmp, 0x67000: WIFI.tmp, 0x68000: EVENT.tmp, 0x69000: RINGBUF.tmp, 0x6a000: DECOMP.tmp, 0x6b000: PUNIT.tmp
Connecting...
Erasing flash...
Took 0.10s to erase flash block
Writing at 0x00052000... (100 %)
Wrote 1024 bytes at 0x00052000 in 0.1 seconds (86.3 kbit/s)...
Erasing flash...
Took 0.22s to erase flash block
Writing at 0x00053000... (9 %)
Writing at 0x00053400... (18 %)
Writing at 0x00053800... (27 %)
Writing at 0x00053c00... (36 %)
Writing at 0x00054000... (45 %)
Writing at 0x00054400... (54 %)
Writing at 0x00054800... (63 %)
Writing at 0x00054c00... (72 %)
Writing at 0x00055000... (81 %)
Writing at 0x00055400... (90 %)
Writing at 0x00055800... (100 %)
Wrote 11264 bytes at 0x00053000 in 1.1 seconds (84.5 kbit/s)...
Erasing flash...
Took 0.13s to erase flash block
Writing at 0x00056000... (50 %)
Writing at 0x00056400... (100 %)
Wrote 2048 bytes at 0x00056000 in 0.2 seconds (84.6 kbit/s)...
Erasing flash...
Took 0.09s to erase flash block
Writing at 0x00057000... (50 %)
Writing at 0x00057400... (100 %)
Wrote 2048 bytes at 0x00057000 in 0.2 seconds (85.0 kbit/s)...
Erasing flash...
Took 0.13s to erase flash block
Writing at 0x00058000... (25 %)
Writing at 0x00058400... (50 %)
Writing at 0x00058800... (75 %)
Writing at 0x00058c00... (100 %)
Wrote 4096 bytes at 0x00058000 in 0.4 seconds (84.5 kbit/s)...
Erasing flash...
Took 0.09s to erase flash block
Writing at 0x00059000... (100 %)
Wrote 1024 bytes at 0x00059000 in 0.1 seconds (84.6 kbit/s)...
Erasing flash...
Took 0.13s to erase flash block
Writing at 0x0005a000... (100 %)
Wrote 1024 bytes at 0x0005a000 in 0.1 seconds (85.4 kbit/s)...
Erasing flash...
Took 0.09s to erase flash block
Writing at 0x0005b000... (20 %)
Writing at 0x0005b400... (40 %)
Writing at 0x0005b800... (60 %)
Writing at 0x0005bc00... (80 %)
Writing at 0x0005c000... (100 %)
Wrote 5120 bytes at 0x0005b000 in 0.5 seconds (84.9 kbit/s)...
Erasing flash...
Took 0.13s to erase flash block
Writing at 0x0005d000... (50 %)
Writing at 0x0005d400... (100 %)
Wrote 2048 bytes at 0x0005d000 in 0.2 seconds (85.4 kbit/s)...
Erasing flash...
Took 0.09s to erase flash block
Writing at 0x0005e000... (50 %)
Writing at 0x0005e400... (100 %)
Wrote 2048 bytes at 0x0005e000 in 0.2 seconds (85.4 kbit/s)...
Erasing flash...
Took 0.12s to erase flash block
Writing at 0x0005f000... (100 %)
Wrote 1024 bytes at 0x0005f000 in 0.1 seconds (85.4 kbit/s)...
Erasing flash...
Took 0.09s to erase flash block
Writing at 0x00060000... (16 %)

A fatal error occurred: Invalid head of packet
ken

Convert flash.py to python3

I did a simple conversion to python3

  1. I ran 2to3 on flash.py. (this changes mostly print statements, I think)
  2. That left two remaining issues:

line 188. -- had to convert address into an int
def write_flash_many(self, tupl):
if not tupl: return
print('Flashing %s' % ', '.join('0x%x: %s' % (int(address), os.path.basename(path)) for (address, path) in tupl))

line 190 -- same thing
os.system("python esptool.py -p %s write_flash -fs 32m -fm %s -ff 40m %s" % (self.port, self.flashmode, ' '.join("0x%x %s" % (int(a),p) for a,p in tupl)))

flash.py seems to run OK now.
Surprisingly I did not seem to have to change esptool.py
A python3 version of esptool.py has been installed by pip, so it seems to use this one.

The changed file is attached.

(Sorry I am not used to this - I had to change to txt extension to get it to upload)

flash.py.txt

Also:-
This is for esp8266. I am running a macbook on catalina.

Want to understand, how it works

Hallo,
great that there is a forth for ESP8266 :-)
I want to use it for personal development and will try to add mutt-support.
Browsing through the source I wonder how/when uber.forth is read from flash during startup.
Can you give me some hints, so I can better understand how it woks?

mny tnx in advance,

Dietmar

punyforth integration into tasmota?

Dear Attila,

I am looking for a scripting language for expanding the configurability of the tasmota framework
https://github.com/arendst/Sonoff-Tasmota
As punyforth, tasmota runs on ESP8266 platform and started on sonoff devices.
It implemets a web surface, MQTT client, serial and http command, remote syslog feature...

Forth is a natural choice, and punyforth runs on the target platform - great :-)

However, tasmota is not based on RTOS, but on arduino-esp8266 and implements a simple arduino type architcture

init() { 
     do some stuff; 
}

loop() {
    repeat stuff all the time;
}

Do you think it is possible to get punyforth built and running?
A first glance on https://github.com/zeroflag/punyforth/blob/master/arch/esp8266/rtos/user/user_main.c made me optimistic.

This reads like it can be called from arduino framework as well.
It's just the xTaskCreate that worries me a little bit.
Does this belong to RTOS?
How deeply are punyforth and RTOS woven together ?

I think I willl need

  • hooks to create tasks
  • hooks to initiate the whole thing
  • hooks for the arduino yield() which resembles the scheduler
  • or may be it suffices just to call it once in every loop turn?
  • hooks to redirect tasmota command processing stream to forth
  • information on the memory and flash management to keep it coexistent
  • some hints on the details of the multitasking implementatin
  • maybe some extra hardware function wrappers

I'll try to understand the code myself, but of course, any pointer to assist me in my endeavour will be appreciated :-)

I2C

I am trying to port the SPI example of oled SSD1306 to use i2c instead. I haven't succeeded yet. I am suspicious that this call:
defprimitive "i2c-write-slave"
at line 550 in ext.S of punyforth
is missing one of the 4 parameters of the corresponding C call
int i2c_slave_write()
at line 120 in i2c.h at https://github.com/SuperHouse/esp-open-rtos/blob/master/extras/i2c/i2c.h

Am I missing something?
I do hope I don't have to set up to recompile punyforth, just for a 1-line change to ext.S

Brian

Need netcon-available function

In trying to do streaming with Punyforth I am using the netcon-read function. This is a blocking function that won't return until at least some bytes have been received. The blocking nature of this function means I cannot do other meaningful work in my code while waiting for bytes to be received. What I need is a function that I can call (like netcon-available) that will tell me how many bytes are available and if none are, I can execute other code until some data arrives.

Then I could use tasks: one for receiving data and putting it into a FIFO and another that would remove the data from the FIFO and process it.

Port to ESP32

Not an issue, but are there any plans to port punyforth to ESP32 ?

char:

char: is not an immediate word and this prevent writing it, easily, in a column word on the opposite hex: can be used in interactive and compiling mode.
Is it possible to have char: written in the same manner as hex: like this
: char: immediate word drop c@ interpret? invert if ['], , then ;
Yes i can overwrite it, but do you think it has to be include in the core?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.