Close

UART for application, serial console through SWIM

A project log for eForth for cheap STM8S gadgets

Turn cheap modules from AliExpress into interactive development kits!

thomasThomas 01/10/2017 at 06:350 Comments

With the following configuration the latest code on GitHub has the option to use the UART for other things than a Forth console:

         HALF_DUPLEX      = 1    ; Use EMIT/?KEY in half duplex mode
         HAS_TXUART       = 1    ; No UART TXD, word TX!
         HAS_RXUART       = 1    ; No UART RXD, word ?RX
         HAS_TXSIM        = 2    ; Enable TxD via GPIO/TIM4, word TXGP!
         PDTX             = 1    ; Port D GPIO for HAS_TXDSIM
         HAS_RXSIM        = 2    ; Enable RxD via GPIO/TIM4, word ?RXGP
         PDRX             = 1    ; Port D GPIO for HAS_RXDSIM
I used a higher flag value for HAS_TXSIM and TXRXSIM to indicate that it should be used for the console. In this configuration the UART can be used with TX! and ?RX while the EMIT and ?KEY vectors point to TXP! and ?RXP. It would also have been possible to keep the simulated serial interface free by not using a higher flag value.
Here is a test to copy chars from RX to TX in the background:
: bcopy ?RX IF TX! THEN ; ok
' bcopy BG ! ok

This works fine but for using it to automate an ESP8266 remote serial with background code we still need buffers for RX and TX. Next up: vectored I/O for the background and some kind of buffers. An input buffer is also necessary for using some of the interpreter code in the background.

Edit1: of course, I/O in the background is already vectored, but the vectors used are fixed. The vectors can be changed at the start of the background task, and maybe I keep it that way.

Edit2: I don't want to go for a multi-tasking/multi-user system, and changing the user context therefor isn't necessary (that would be interesting for a CPU with a vast amount of resources, e.g. an entry level Cortex M0 ;-) ). However, the eForth implementation of the words parse (single out words separated by a delimiter) and find (look up words in a linked-list or dictionary) use the temporary variable tmp, which is the only thing that binds the words to a user context (along with the compiler and the interpreter). I'm now removing the words from the implementation and use temporary storage on one of the stacks instead (the return stack). That's not much nicer than the tmp variable, but it provides a cheap multi-tasking context switch.

Edit3: I was wrong - using the return stack instead of the tmp variable is much nicer (and a bit more compact, too). Now I've got to figure out how to implement buffered I/O in a multi-tasking friendly way.

Discussions