TACHYON
[~
FORGET WS2812.fth
pub WS2812.fth PRINT" WS2812 Intelligent RGB LED driver V1.0 1410131230.0000 " ;
IFNDEF [WS2812] --- use newer name for module in case this had the old name
ALIAS [TXRGB] [WS2812]
}
{ WS2812 timing
A zero is transmitted as 350ns high by 800ns low (+/-150ns)
A one is transmitted as 700ns high by 600ns low
RET is >50us
A zero is transmitted as 350ns high by 800ns low (+/-150ns)
A one is transmitted as 700ns high by 600ns low
RET is >50us
}
--- UPDATE - WS2812 RUNMOD added to current 2.4 kernel, this is all that is needed now to run it
( define I/O and an array )
#P14 == WSTXD --- define our transmit pin
#96 == rgbsz --- specify the size of the array as a constant
rgbsz BYTES rgbleds --- define our byte array
pub LEDS
WSTXD OUTCLR --- Start a RET to synch the chips
WSTXD 4 COGREG! --- setup the I/O pin for the RUNMOD to use
[WS2812] --- select the WS2812 module for RUNMOD (needs to be renamed yet to [WS2812] )
#10 us --- still need a bit of extra delay for a minimum RET op while txd is low
rgbleds rgbsz RUNMOD --- pass the address of the array and the byte count to the RUNMOD
;
{ executing LEDS will update a 96 byte display in 1 ms
The WS2812 LEDs can also be updated in the background of the main console cog this way:
KEYPOLL LEDS
or
' LEDS keypoll W!
Or called regularly from the timer cog this way:
TIMER ledtimer --- create a timer for the LEDs
#20 ledtimer TIMEOUT --- set it to trip in 20 ms (add this method to LEDS as well to reload)
' LEDS ledtimer ALARM --- what to do when the timer expires
}
--- some extra definitions for testing
pub CLEAR rgbleds rgbsz ERASE ;
pub COLOR ( value offset -- ) rgbleds + rgbsz ADO DUP I C! 3 +LOOP DROP ;
pub RED ( value -- ) 1 COLOR ;
pub GREEN ( value -- ) 0 COLOR ;
pub BLUE ( value -- ) 2 COLOR ;
pub CYAN ( value -- ) DUP GREEN BLUE ;
pub MAGENTA ( value -- ) DUP RED 2/ BLUE ;
pub WHITE ( value -- ) rgbleds rgbsz ROT FILL ;
--- color adjectives are fixed values
#32 == DARK
#255 == BRIGHT
{ usage:
20 % RED
DARK GREEN
BRIGHT BLUE
75 % CYAN
}
( Simple DEMO code to make RGB LEDs chase each other )
DECIMAL
TIMER ledtimer --- create a timer structure variable
WORD spd --- allow for the speed to be varied interactively
pub (CHASE) --- perform a single chase step
spd W@ ledtimer TIMEOUT --- reload timer with current speed
rgbleds rgbsz + 1- C@ --- save last byte in array
rgbleds rgbleds 1+ rgbsz 1- <CMOVE --- shift them all along (in reverse)
rgbleds C! --- write copy of last byte back into first
;
pub SPEED ( n -- ) 1 MAX 10000 MIN spd W! ;
pub FAST 50 SPEED ;
pub SLOW 500 SPEED ;
pub FASTER spd W@ 80 * 100 / SPEED ;
pub SLOWER spd W@ 120 * 100 / SPEED ;
pub CHASE
$FF rgbleds 1 + C! --- set 1st LED to red
$FF rgbleds 3 + C! --- set 2nd LED to green
$FF rgbleds 8 + C! --- set 3rd LED to blue
rgbleds DUP 9 + rgbsz 9 - CMOVE --- then replicate these three over the remainder of the array
' (CHASE) ledtimer ALARM --- set action for timer
10 ledtimer TIMEOUT --- kick off timer
100 SPEED --- set initial chase speed
;
{ *** Using CHASE to test the LEDs *** Type CHASE which will initialize the process and start running in the background every 100ms Type SLOW to make it go slow or FAST or FASTER or SLOWER etc You can enter a speed in milliseconds: 300 SPEED NOTE: normally Tachyon is case sensitive (that's a good thing) but in case (pun) it doesn't understand a word it will convert it all to uppercase and try again. So if you type slow instead of SLOW it will catch on. } |
]~
END