08/28/2019 at 19:44 •
It's been a while since I last worked with STM8S001J3 chips - ST's contested take on SO8 ATtiny85-like µCs.
The STM8S001J3 is a member of the "STM8S Low Density" family but it's based on the "STM8S Access Line" cross-breed STM8S903 that offers some (undocumented) goodies.
I ordered a 10pcs lot for $2.90 including shipping, and decided to make small RS485 nodes (e.g. for MODBUS RTU) with DS1621S thermometer chips that I happen to have lying around.
I made my last PCB with KiCad5.0 - updating to the latest version, especially the library handling, required some reading (I'm now using 5.1.4).
A µC with merrily 5 GPIO pins is a good shield against feature creep, but the following things "had" to be included:
- narrow PCB for a cylindrical sensor with less than 8mm diameter
- 5V supply, 3.3V internal power supply
- basic signalling LEDs
- most GPIOs, including I2C bus and an analog input available on a header
The design is really simple:
Components occupy both sides of the PCB of 34mm x 1/4" (minimal width supported by @oshpark ).
On the front side is the STM8S001J3M3, a LDO regulator and some caps:
The RS485 transceiver and the thermometer chip live on the backside:
The board has two intended applications: either a stand-alone bus coupled temperature sensor, or a minimal µC component, e.g. for a quick perfboard design.
I ordered from @oshpark - uploading my KiCad 5.1.4 file worked right away, and creating Gerber files wasn't necessary!
08/03/2019 at 09:54 •
When I started this project the STM8S003F3P6, an STM8S Value Line µC with 8K Flash and 1K RAM in a TSSOP20 package, was the cheapest device in its class. Cheap enough to enable an industry of low-cost electronics control devices, e.g. thermostats or voltmeters, with the left-overs of mass production runs. This market for low-mid-range µCs encouraged Nuvoton to market the mostly pin-compatible N76E003AT20, an 8051 family device.
For the initial goal of this project this was bad news: from then on the Nuvoton chip was the go-to device on the spot market, a chip with an architecture utterly unsuitable for a self-contained Forth system!
Right now, however, the STM8S003F3P6 is at a very low price point: I just received 10 pcs for $1.86, which is as low as it gets!
Don't get me wrong, the Nuvoton chip won't disappear and it's very likely to receive a thermostat like the W1209 with an "non-hackable" chip but at least the TSSOP20 package can be soldered with ease.
05/28/2019 at 19:00 •
Don't expect breaking changes - the STM8 eForth core is quite mature now.
The default build environment got an update to SDCC 3.8.6 (but it was tested with SDCC 3.9.0, too), and the binary export from uCsim got an upgrade (it's a nice Python script now instead of a lean-and-mean AWK scriptlet).
More internal constants can be exported with #require, STM8L chip got better support thanks to @Eelco. Coding with inline machine instructions is easier thanks to a number of bit copy and assembly interface words.
And of course, there is more docs.
More info is in the release notes: https://github.com/TG9541/stm8ef/releases/tag/2.2.23
02/10/2019 at 21:54 •
STM8EF-MODBUS deserved a GitHub project, of course with Travis-CI build automation, and docs.
Some of the properties are rather cool, e.g. the modular architecture and the clear separation of concerns between MODBUS protocol and other application logic :-)
Right now, on Aliexpress, the "MODBUS-RTU 4 way relay module STM8S103 MCU" is available at a good price: $6.65 incl. shipping.
01/20/2019 at 10:14 •
STM8 eForth is now a serious alternative to coding C coding for STM8 µCs, especially if Flash space is a premium or if interactive features or configuration in the field are required.
Recently, many other pages got updates. Especially a lot of graft was moved from the STM8 eForth Programming introduction page to improved topic pages in the Wiki.
The Forth VM makes context switching very efficient. In my opinion (I wrote many interrupt handlers for industrial and safety critical applications), implementing interrupts in Forth is easer than in C.
The STM8 eForth Interrupts in the STM8 eForth Wiki explains the bit that there is to know. The MODBUS server and the nRFL01 libraries implement low level code using STM8 interrupts.
As an example, here is the STM8S UART RX handler from the MODBUS library:
\ RX ISR handler :NVM SAVEC \ P1H UART1_DR C@ ( c ) rxp @ ( c a ) DUP rxbuf - ( c a len ) RXLEN < IF ( c a ) SWAP ( a c ) OVER ( a c a ) C! ( a ) 1+ rxp ! THEN TIM tstamp ! \ P1L IRET [ OVERT INT_UARTRX !
This example contains many stack comments (the stuff in round brackets) and just a bit of code for copying characters from the UART to a buffer, protecting against buffer overrun, and providing a time stamp for the MODBUS "end of transmission" detection.
The most striking point is that in this use case Forth is much more used as a macro assembler for a very simple virtual machine than as a programming language. The programmer builds the most simple "machine" that will do the job. No unnecessary abstractions.
Links to these libraries are on the examples page.
01/12/2019 at 09:15 •
I kept STM8 eForth stable for a long time but now there is a good reason for preparing a new release:
For the current work on a very lightweight MODBUS Server in STM8 eForth I needed some data from the target (e.g. clock frequency), and some other aides for low-level programming (e.g. an easy to use and stable interface between Forth and machine code).
The implementation of MODBUS in Forth is a pleasant experience: Moore's problem oriented language approach works quite well for embedded control and protocol implementations. I simply design the machine so that it implements layers of a protocol, and I do that in a language that describes the problem well. Thereby a language emerges, because my abstractions either describe the problem well, or I change it so that it describes the problem better.
It's safe to say that the implementation is very code efficient and highly functional at the same time (thanks to an interpreter-compiler on a MODBUS node).
Before the release of STM8 eForth 2.2.23, I'd like to improve the compilation of Forth code in the continuous integration environment.
01/02/2019 at 17:30 •
Edit: there is now a GitHub project: https://github.com/TG9541/stm8ef-modbus
One STM8 eForth needs something that I had planned to implement for a long time: a basic MODBUS server with RTU communication (serial binary protocol).
Implementing a MODBUS RTU server requires some of the following:
- understanding MODBUS vernacular,
- writing test code (with JAMOD and libmodbus.py),
- ISR timing validation, and
- fixing odd bugs
I wrote the UART ISR code in Forth: on a 8bit µC that's fast enough for 115200 baud full-duplex, or for 240400 baud half-duplex MODBUS RTU!
The diagram shows full-duplex mode at 115200 baud. The ISR do buffer bounds checking and media access control (including MODBUS timing requirements).
A Forth "idle task" builds the MODBUS response. The "background task" is free for local logic (i.e. following the input-process-output pattern).
Right now some simple MODBUS FCs are implemented (FC01 & FC05, some of FC02 & FC16). More FCs will be implemented when the need arises.
The code is very compact: the basic implementation is in 300 lines of Forth code (including debug code). Before optimizations 1.4K Flash are needed .
A (long) discussion around the development is here.
12/24/2018 at 12:45 •
Controlling the WS2812 with STM8 eForth was something I've had on my to-do list for a long time. The lore of W2812 timing is already long and twisted, and any new implementation, it seems, has to add a bit to it :-)
Mine is the following:
Do it the Aristotle way: Relax the timing but maintain the balance!
I coded the inner loop for a byte transfer and the bit timing in assembly (in a self balancing way). The outer loop is coded in Forth. The result is quite compact:
: WS2812 ( a1 a0 -- ) DO [ $1601 , \ LDW Y,(1,SP) $90F6 , \ LD A,(Y) $88 C, \ PUSH A $A608 , \ LD A,#8 ] [ 1 PB_ODR 4 ]B! [ $0901 , \ RLC (1,SP) $9D C, \ NOP $2504 , \ JRC 1$ ] [ 0 PB_ODR 4 ]B! [ $9D C, \ 1$: NOP $9D C, \ NOP $9D C, \ NOP $2404 , \ JRNC 2$ ] [ 0 PB_ODR 4 ]B! [ $9D C, \ 2$: NOP $4A C, \ DEC A $4D C, \ TNZ A $26E5 , \ JRNE 0$ $84 C, \ POP A ] LOOP ;
I tested the code by comparing the sensitivity of the reshaped bit timing at the output of the WS2812B.
The code and some findings are here.
12/09/2018 at 09:32 •
I reviewed the STM8 eForth Wiki under and tried to make it more readable for the casual visitor. Also removing some of the Forth evangelizing hyperbole doesn't hurt. Forth is still amazing, not only for philosophical reasons, but nobody likes Forth extremists, right?
Another activity is experimenting with interfacing STM8 eForth with SDCC C. Use-cases, approaches and the progress so far have been documented in Add/mix/graft STM8 eForth into a C project.
I found no documentation on parameter passing in the SDCC STM8 port, and after some experiments I have the following hypothesis:
- parameters are copied to the return stack in the relevant size, ready for access with "SP indirect addressing", and in the reverse order of the definition
- 8bit return values are in A
- 16bit return values are in X
- 32bit return values are in MSW X - LSW Y
SDCC passes most data on the (return) stack. The main difference to a stack oriented language is that this parameter passing behavior is not defined in the language, it's a mere implementation detail. The effect is that stack transfers have to be done over and over again, which creates a lot of waste.
From the software engineering point of view it becomes apparent that a minor change of paradigm (maintaining the stack is the responsibility of in the called function instead of the calling function) can be the defining feature of the architecture.
12/07/2018 at 06:49 •
There is a new wiki page that explains the STM8 eForth Compiler and Assembly.
A review from a 2nd side would be great :-)