\ -------------------------------------------------------------
\ A not-so-small "blinky" using the LED matrix on Calliope
\ -------------------------------------------------------------
$50000504 constant gpio_out \ Write GPIO port
$50000508 constant gpio_outset \ Set individual bits in GPIO port
$5000050C constant gpio_outclr \ Clear individual bits in GPIO port
$50000510 constant gpio_in \ Read GPIO port
$50000514 constant gpio_dir \ Direction of GPIO pins
$50000518 constant gpio_dirset \ Setting DIR register
$5000051c constant gpio_dirclr \ Clearing DIR register
$50000700 constant gpio_cnf \ Configuration of pin 0, add 4*n for other pins.
\ Pin config:
\ Bits 17 and 16: 0: No sense 1: Sense for high level 2: Sense for low level
\ Bits 10, 9, 8:
\ 0: Standard 0, standard 1
\ 1: High drive 0, standard 1
\ 2: Standard 0, high drive 1
\ 3: High drive 0, high drive 1
\ 4: Disconnect 0, standard 1
\ 5: Disconnect 0, high drive 1
\ 6: Standard 0, disconnect 1
\ 7: High drive 0, disconnect 1
\ Bits 3 and 2: 0: No pull 1: Pull down 2: Pull up
\ Bit 1: 0: Connect input buffer 1: Disconnect input buffer
\ Bit 0: 0: Input, 1: Output
\ -------------------------------------------------------------
\ Setup pins and wires
\ -------------------------------------------------------------
$FFF0 constant matrixmask
: init-matrix ( -- ) \ Prepare LEDs and Buttons
matrixmask gpio_outclr ! \ All matrix pins low
$301 gpio_cnf 4 cells + ! \ High drive in both directions, Input buffer active, Output
$301 gpio_cnf 5 cells + !
$301 gpio_cnf 6 cells + !
$301 gpio_cnf 7 cells + !
$301 gpio_cnf 8 cells + !
$301 gpio_cnf 9 cells + !
$301 gpio_cnf 10 cells + !
$301 gpio_cnf 11 cells + !
$301 gpio_cnf 12 cells + !
$301 gpio_cnf 13 cells + !
$301 gpio_cnf 14 cells + !
$301 gpio_cnf 15 cells + !
$008 gpio_cnf 17 cells + ! \ Button A Input with Pullup
$008 gpio_cnf 16 cells + ! \ Button B Input with Pullup
;
: buttona ( -- ? ) 1 17 lshift gpio_in bit@ not ;
: buttonb ( -- ? ) 1 16 lshift gpio_in bit@ not ;
\ -------------------------------------------------------------
\ Matrix is connected in a strange way
\ -------------------------------------------------------------
\ This is a really quite strange matrix.
\ Configuration:
\ $0010: Cathode 1
\ ...
\ $1000: Cathode 9
\ $2000: Common Anode 1 (a)
\ $4000: Common Anode 2 (b)
\ $8000: Common Anode 3 (c)
\ a1 b4 a2 b5 a3
\ c4 c5 c6 c7 c8
\ b2 a9 b3 c9 b1
\ a8 a7 a6 a5 a4
\ c3 b7 c1 b6 c2
0 0 0 3 nvariable matrixbuffer
: mpixel ( anode cathode -- )
8 swap lshift ( anode bitmask )
swap ( bitmask anode )
cells matrixbuffer + ( bitmask addr )
bic!
;
hex
: matrix ( image -- ) \ Turns 25 pixels into three rows of matrix data.
\ Prepare Anodes, with all Cathode lines high
$3FF0 matrixbuffer 0 + !
$5FF0 matrixbuffer 4 + !
$9FF0 matrixbuffer 8 + !
\ Prepare Cathodes by clearing singular bits. Chaotic wiring !
dup 1 and if 2 3 mpixel then \ c3
dup 2 and if 1 7 mpixel then \ b7
dup 4 and if 2 1 mpixel then \ c1
dup 8 and if 1 6 mpixel then \ b6
dup 10 and if 2 2 mpixel then \ c2
dup 20 and if 0 8 mpixel then \ a8
dup 40 and if 0 7 mpixel then \ a7
dup 80 and if 0 6 mpixel then \ a6
dup 100 and if 0 5 mpixel then \ a5
dup 200 and if 0 4 mpixel then \ a4
dup 400 and if 1 2 mpixel then \ b2
dup 800 and if 0 9 mpixel then \ a9
dup 1000 and if 1 3 mpixel then \ b3
dup 2000 and if 2 9 mpixel then \ c9
dup 4000 and if 1 1 mpixel then \ b1
dup 8000 and if 2 4 mpixel then \ c4
dup 10000 and if 2 5 mpixel then \ c5
dup 20000 and if 2 6 mpixel then \ c6
dup 40000 and if 2 7 mpixel then \ c7
dup 80000 and if 2 8 mpixel then \ c8
dup 100000 and if 0 1 mpixel then \ a1
dup 200000 and if 1 4 mpixel then \ b4
dup 400000 and if 0 2 mpixel then \ a2
dup 800000 and if 1 5 mpixel then \ b5
1000000 and if 0 3 mpixel then \ a3
;
decimal
\ -------------------------------------------------------------
\ A few example images
\ -------------------------------------------------------------
%11011.00000.00100.10001.01110 drop constant :-) \ Use drop to allow usage of . for clarity in image data.
%00011.00000.00100.10001.01110 drop constant ,-)
%11000.00000.00100.10001.01110 drop constant '-)
%11011.00000.00000.01110.10001 drop constant :-(
\ -------------------------------------------------------------
\ Display an image, as simple as possible...
\ -------------------------------------------------------------
: blinky ( -- )
init-matrix
:-) matrix
begin
matrixmask gpio_outclr ! \ All matrix pins low
matrixbuffer 0 + @ gpio_outset ! \ First row data
100 0 do loop
matrixmask gpio_outclr ! \ All matrix pins low
matrixbuffer 4 + @ gpio_outset ! \ Second row data
100 0 do loop
matrixmask gpio_outclr ! \ All matrix pins low
matrixbuffer 8 + @ gpio_outset ! \ Third row data
100 0 do loop
key? until
matrixmask gpio_outclr !
;
\ -------------------------------------------------------------
\ A matrix handler to care of shining in the background
\ -------------------------------------------------------------
0 variable currentanode
: matrix-handler ( -- ) \ Interrupt handler for matrix handling
matrixmask gpio_outclr ! \ All matrix pins low
matrixbuffer currentanode @ cells + @ gpio_outset ! \ Display current row
currentanode @ dup 2 u< if 1+ else drop 0 then currentanode ! \ Next row next time.
;
\ Hook the matrix handler into pause so that it continues to shine while typing.
: matrix-on ( -- )
init-matrix 0 matrix
['] matrix-handler hook-pause ! \ You can hook this into a timer interrupt if you wish !
;
: matrix-off ( -- )
['] nop hook-pause !
matrixmask gpio_outclr !
;
\ -------------------------------------------------------------
\ A small demo of everything.
\ -------------------------------------------------------------
: demo ( -- )
matrix-on
begin
:-)
buttona if drop '-) then
buttonb if drop ,-) then
buttona buttonb and if drop :-( then
matrix
key? until
matrix-off
;