Fun and games with STM8

I've been toying around with STM8 microcontrollers lately because they're a happy medium between low-end PIC/AVRs and full-blown 28-40 pin 8-bit devices. The fact that you can get breakout modules (8k flash, 1k ram, hardware uart, spi and i2c) for under 100 yen shipped from the usual suspects doesn't hurt either.

There's fairly good support for the devices under linux in sdcc, a C compiler for microcontrollers, but not much in the way of headers. There's a git repo with a few example programs at https://github.com/vdudouyt/sdcc-examples-stm8.git but the included header file there is for stm8l devices and not the stm8s ones that I'm using.

The blink example will compile, but ran into problems from the start trying to get the uart example running. Hooked up a logic analyser to the uart output pin and I was actually seeing the right data but was just getting mojibake when connecting it to a real serial. It turns out that one of the differences between stm8s and stm8l was that the registers used for addressing the clocking was at entirely different addresses. Had to go to the datasheets and check every line of the include file for discrepancies. Fortunately the uart section was ok and just had to fix the clock and timer sections.

Having that working my next thing to try was getting a WS2812B dot-addressable LED to blink in colors. https://wp.josh.com/2014/05/13/ws2812-neopixels-are-not-so-finicky-once-... gives some simplified timing requirements. I wrote some bitbanging code based on this info but unfortunately all I was getting was all-white. Digging out into the generated assembler it seems that sdcc is not sufficiently optimizing "PA_ODR |= (1<<3);" and "PA_ODR ^= ~(1<<3);" into the actual bitwise opcodes and generating 3-4 op code instead. This blew my T0H timing (the tightest requirement of the lot) over the limit by 62.5ns. Needed to remove 2 nop instructions to make it work (actually removed 3 to put it right at the typical time).