If you're following this little project you may have noticed that I take pride in adjusting the code for supporting almost any type of cheap STM8S Value Line device.
Here is a number of constraints:
- in most cases UART pins are not broken out
- in some cases UART pins are used for communication
- in most cases there is no accessible "unused" GPIO
- in some cases there is no ICP connector, PD1 is used, and NRST isn't accessible
I did the following to meet constraints 1. and 2.:
- there is a simple "half-duplex" single GPIO configuration for the console
- the serial line simulation for interactive console can be configured for any GPIO (assumption: port change interrupt requirements of other GPIOs on the used port can be met with "falling-edge")
- two instances of serial com "devices" can be used in Forth code, one for the application, one for the console
However, I'm still working on some edge cases constraint 3:
- Sharing a GPIO for the console with the application requires priority for communication (e.g. the DP segment of an 7S-LED doesn't work while the console is being used)
- the "interactive" state has to be detected, stored, and maintained for a convenient period of time
I'm working on a solution that doesn't lead to much entanglement between communication and board support code. I'd like to restrict it to cases where the "background task" option is enabled.
Constraint 4 is a bit more complicated to meet as I learned yesterday:
- When the NRST pin is not accessible PD1/SWIM must be in input mode at least for some time
I've got it working in cases where PD1/SWIM is used for digits or segments of the 7S/LED display even if it's not used for the serial communication code (where the constraint is implicitly met).
Anther thing I've been working on is the code density of Forth user code: having literals (constants, addresses) in STC (subroutine threaded code) is quite expensive: a call to DOLIT followed by a 16 bit constant, that's 5 bytes. In the core code I got that down to 4, 3, 2, or even 1 bytes in many cases (CALLR DOLIT for 16 bit, CALLR DOLITC for 8bit constants, and LDW Y,#W and LD A,#C, or CLRW Y and CLR A with TOS in a register). This method contributes to quite some binary size reduction in the core, but it can't be used easily in user code (one work around is to use words like "0" for frequently used constants).
I now experimented with the STM8 TRAP instruction to build a native DOLIT which is just TRAP MSB LSB. It works nicely, but it takes 3 µs to execute. An 80's programmer would have been happy with that, but today it's a "size over speed" decision.