Has it really been a year?
New features
Target builds in downstream projects
Adding more boards to STM8 eForth is nice but creating new GitHub repositories for applications, while keeping the core lean, is better.
A new feature supports downstream projects with "target boards": a STM8 eForth release archive contains all source code required for a target build and the Makefile
was split in two parts, one with the overal configuration (Makefile
), the other for building a board folder (forth.mk
).
The release archives are still much smaller since the post-linker list file forth.rst
, formerly used by symload.sh
, has moved to the release archive stm8ef-rst.tgz
. It will only be needed if you'd like to know what exactly went into a binary condiguration.
Support for projects that separate generic from hardware dependent code comes from issue #298: by changing the search order for Forth code in simload.py
hardware target folders can used as the "configuration root" that provides initialization and abstractions for multiple targets ({BOARD}/board.fs
now comes first, main.fs
is second).
Here are some of the GitHub projects that use the new method:
GitHub Project | Notes |
---|---|
STM8 eForth Modular Build | template repository and cookbook in one |
stm8ef-modbus | the project targeting the C0135 that first required this feature |
W1209 Data-Logging Thermostat | a solution for the still growing number of W1209 variants |
XY-LPWM | timers and 7S-LED code |
stm8l051led | simulated serial interface and other things for STM8L |
Refer to #272 for details.
Move more out of the Core
#282, #285 and #289 make the STM8 eForth Core leaner: the idea is to move more potentially board specific code to include files so that it can be "overwritten" by adding a specific solution to a board folder.
An example is the specialized sser_fdx.inc
in stm8l051led which works around a one-sided inverter in a serial link.
Configurable Timer for Background Task
Since introduction of the background task almost 4 years ago it was limited to TIM2. The issues #304 and #305 changed that.
It's now possible to use BG_USE_TIM1 = 1
or BG_USE_TIM3 = 1
in globconf.inc
to select TIM1 or TIM3 instead of TIM2. So far the code only works on STM8S.
There is currently no support for STM8L (what's at least missing is configuration of the clock tree for TIM3 and support for TIM1).
Priority feature for EEALIAS using "un-link tags"
With #265 tagging un-linked dictionary entries was introduced. #263 cleaned up old feature selection options. Both contribute to building the aliaslist.fs
file in the target
folder so that they can be loaded into the EEPROM with the EEALIAS feature.
With this method (#266) up to half a KiB of Flash memory an be saved compared with a STM8 eForth binary that has the same feature set. This is particularly useful for tweaking memory usage in downstream projects.
Improved support for STM8S Low Density Devices with UART remapping
Certain STM8S Low Density Devices (i.e. STM8S001J3, STM8S903 and certain STM8AF devices) have a UART remapping feature: the UART can be mapped to PA3/PF4 instead of the usual PD5/PD6.
#288 and #290 makes sure that by setting HALF_DUPLEX = 2
in globconf.inc
the init code in COLD
check OPT2 for STM8S "Low Density Device UART remapping" to set either PA_CR1 or PD_CR1.
Improved Support for STM8S High Density Devices
High density devices had a number of feature gaps:
- #292 required a solution for using the 2nd UART - this is now possible by setting
USE_UART2 = 1
inglobconf.inc
. - #298 also adds Forth stack primitives (
rp@
,rp!
,sp!
andsp@
). - #293 fixes a bug that broke simulated console port with TIM4
Future releases will add more support for High Density devices, e.g. access of Far memory for data storage.
Better UART support
Work on STM8EF-MODBUS created some need for non-console use cases of the UART. #302, #303, core exports like OSCFREQ
or library words like UART_DIV.
#320 introduces a baud rate parameter for codeload.py
.
While the console works fine and feels snappy at 115200 baud, using background tasks can be a challenge (at 9600 baud the background task can take up to 1ms but). A spin-off was code for "buffered RX" (INTRX). This is surprisingly simple and it works very well. The code will be added to the library in the next release.
Better support for the simulated serial interface
The following changes address the simulated serial interface:
- #293 the simulated interface compatible with STM8S High Density devides, and
- #319 did the same for STM8L devices
- #305 adds support for Port E.
There are now configuration parameters for setting the baud rate of the simulated serial interface: TIM4_ARR
and TIM4_PSCR
.
The following table shows parameter values for a range of baud rates:
Rate | CTIM4ARR | CTIM4PSCR | sser-fdx | sser-hdx |
---|---|---|---|---|
600 | 7 | 0xCF | yes* | yes* |
1200 | 6 | 0xCF | yes* | yes* |
2400 | 5 | 0xCF | yes* | yes* |
4800 | 4 | 0xCF | yes | yes |
9600 | 3 | 0xCF | yes | yes |
19200 | 2 | 0xCF | yes | yes |
38400 | 1 | 0xCF | yes | yes |
57600 | 1 | 0x89 | (yes) | yes |
115200 | 0 | 0x89 | no | (yes) |
*) untested but very likely to work - due to a 4 bit pre-scaler index STM8L devices can also use 300, 150, 75 downto 2.34375 baud - maybe that's useful for communication using a flashlight ;-)
Full-duplex at 115200 baud was too much for the combined TIM4 Rx/Tx state machine, and it stopped working. 115200 with half-duplex worked fine (using the new "-r" option of codeload.py, see #320) but I didn't test it with e4thcom since the baud rate in version 0.8.0.64 appears to be limited to 57600.
To be on the safe side it's best to limit the simulated serial in full-duplex to 38400 baud and in half-duplex to 57600 baud. It might also be necessary to introduce tuning for the HSI or using a crystal.
More core information export in target
Some use-cases, e.g. writing code that extends the core, requires knowledge of internal constants, variables or CALL
targets. Certain improvements togenconst.awk
enable export of information from annotated RAM allocation, constant definitions and targets (e.g. #311, $316, #317, #323 and #326).
The following table shows names exported from STM8 eForth 2.2.24 on:
Word in target | type | notes |
---|---|---|
'?BGKEY | NVM xt-parameter | xt of ?KEY for BG task |
'BGEMIT | NVM xt-parameter | xt of EMIT for BG task |
PC_?UNIQUE | NVM patch target | patch target for CURRENT |
PC_BOARDINIT | NVM patch target | patch target for board initialization |
PC_LEDMPX | NVM patch target | patch target for 7S-LED multiplex |
PC_NAME? | NVM patch target | patch target for CURRENT |
PC_WORDS | NVM patch target | patch target for CURRENT |
BGPAD | NVM parameter | address of the empty PAD for BG task |
BGSPP | NVM parameter | address of the empty data stack for BG task |
BGTIMREL | NVM parameter | timer reload value for BG task |
ISPP | NVM parameter | address of the empty data stack for interrupt task |
SPP | NVM parameter | address of the main data stack |
TIB | NVM parameter | address of Terminal Input Buffer (TIB) |
UARTBRR | NVM parameter | UART baud rate generator value (see UART_DIV) |
C_BSPP | constant | address of the empty data stack for BG task |
C_ISPP | constant | address of the empty data stack for interrupt task |
C_RPP | constant | address of the return stack |
C_SPP | constant | address of the main data stack |
C_TIB | constant | address of Terminal Input Buffer (TIB) |
C_UPP | constant | offset of UPP user area |
OSCFREQ | constant | clock frequency in kHz as defined in target.inc |
KEYREPET | RamByte | key repetition counter for board keys |
LED7FIRST | RamBlck | buffer for 7S LED/LCD patterns |
OUT | RamWord | register for board output |
TIM4RXBUF | RamByte | RX buffer from simulated serial interface |
TIM4RXREG | RamByte | RX shift register of sim. serial interface |
TIM4TCNT | RamByte | sequence counter of simulated serial interface |
TIM4TXREG | RamByte | TX shift register of sim. serial interface |
TOKEN_$,n | ALIAS | patch target for CURRENT |
aborq | ALIAS | runtime word for ABORT" (renamed from abort" ) |
Note that "parameters" point to locations in NVM (Flash memory) that can be changed as needed. That's especially useful for changing I/O words for background tasks by writing to '?BGKEY
and 'BGEMIT
.
Abstraction of peripheral addresses in the core
Across the STM8S family, the reference manual RM0016 describes peripherals such as GPIOs, timers, UARTS, I2C, SSC, ADC, watchdog timers and control of interrupt or control. Variants of these peripherals are often described in great detail, and the variants are given names such as USART, UART1, UART2, UART3, UART4 or even USART and LINUART. Sometimes the same peripheral has a different name in the datasheet of commercial/industrial and automotive grades of the same chip.
It turns out that subsets of peripheral register addresses are almost always the same. Almost. Timers TIM2 and TIM4 have the same register names in LD (Low Density) as in MD (Medium Density) and HD (High Density) devices but the addresses differ a bit.
UART irregularities are of a different kind: there are two sets of address and interrupt vectors, let's call them 1st UART and 2nd UART. An "LD" device has a 1st UART, "MD" a 2nd UART and "HD" has both of them.
For writing device independent low-level code some workarounds can be used:
- provide a symbol file that contains a shared functional sub-set of peripheral register addresses
- provide identical symbols for peripheral registers with common functionality in different symbol files
- first define device independent symbols in low-level application code from device specific symbol files, first then load device independent code
For UART addresses there is an implementation of workaround 2 in STM8S103.efr, STM8S105.efr and STM8S207.efr: a default UART can be accessed using the alias UART (which is wither the 1st UART or the 2nd UART).
Code that implements workaround 3 turned out to be quite ugly and difficult to maintain but a combination of the first two options based on the use case (common peripheral addresses or peripheral register alias) appears to be manageable.
#302 implements the 1st workaround for the core include files. #307 introduces generic device type identifiers, e.g. for Low or Medium Density and #313 added STM8s.efr
. Using this file in \res MCU: STM8S
should work for most applications that use common peripherals (e.g, GPIOs, I2C or SSC) and for almost all peripherals of STM8S MD or HD devices (e.g. STM8S105K4 or STM8S207RB).
The release now also contains an mcu definition file STM8L.efr
which can be used for all kinds of STM8L devices except STM8L101 (with a caveat, of course).
Yet another W1209 Variant
#275 & #277 adds support for the W1209 CA V2. Please refer to the docs in the board folder.
Other changes
- #259, #260, #261, #262, #263 better understanding of ASxxxx macro string quirks improves HEADERs and genalias.awk
- #281 makes the behavior of
'IDLE
similar toBG
: setting it to 0 stops Idle Task execution - #299 adds
]BCPL
for direct bit complement (like]B!
etc.) - #309 adds automated tests for background and for IDLE tasks
Bug Fixes
- #270, #271 fixes the Rx GPIO CR1 settings if the simulated UART doesn't use PD1 (SWIM)
- #279 fixed GPIO settings for the STM8L-Discovery board
- #300 fixes a bug in genconst.awk which broke features like
'IDLE
and which was on master for about 5 weeks - fortunately release 2.2.24.pre1 was unaffected and 2.2.24.pre2 only lasted for hours.