Published using Google Docs
( WS2812.fth )
Updated automatically every 5 minutes

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

Screenshot from 2014-10-13 12:41:48.png

A zero is transmitted as 350ns high by 800ns low (+/-150ns)

A one is transmitted as 700ns high by 600ns low

RET is >50us

Screenshot from 2014-10-13 12:51:03.png

Screenshot from 2014-10-13 12:51:52.png

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