\ ------------------------------------------------------------- \ 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 ;