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.
Discussions
Become a Hackaday.io Member
Create an account to leave a comment. Already have an account? Log In.