Some STM8S peripherals are equal, some are the same

A project log for eForth for cheap STM8S gadgets

Turn cheap modules from AliExpress into interactive development kits!

ThomasThomas 05/24/2020 at 19:580 Comments

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. The 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. A 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:

  1. provide a symbol file that contains a shared functional sub-set of peripheral register addresses
  2. provide identical symbols for peripheral registers with common functionality in different symbol files
  3. first define device independent symbols in low-level application code from device specific symbol files, first then load device independent code

Workaround 1 has now been implemented by STM8s.efr in the current master branch of STM8 eForth. It 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).

For UART addresses there is a partial 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. I'll now try to combine the first two options based on the use case (common peripheral addresses or peripheral register alias). Hopefully that works better.