--- a/matrix.inc Thu Jun 17 23:05:24 2010 +0300
+++ b/matrix.inc Mon Aug 23 01:07:26 2010 +0300
@@ -1,21 +1,47 @@
;; LED Matrix driver
;;
+.dseg
+;; I/O addresses
+; Control port
.set MATRIX_DDR = DDRB
.set MATRIX_PORT = PORTB
+
+; Pin for matrix driver Output Enable
.set MATRIX_OE = PORTB1 ; Output Enable, active low, externally pulled high
-.dseg
-.set MATRIX_COLS = 8 ; number of physical columns (XXX: fixed to 8)
-.set MATRIX_BUF_COLS = 16 ; number of columns in frame buffer
+;; Matrix properties
+; Matrix width in columns
+.set MATRIX_COLS = 8 ; physical columns
-matrix_colbit: .byte 1 ; scan column bit
-matrix_colbuf: .byte MATRIX_BUF_COLS ; row bits by column
-matrix_colshift: .byte 1 ; left column offset
+; Framebuffer width in columns
+.set MATRIX_BUF_COLS = 16 ; framebuffer columns
+
+;; SPI addresses
+; row drivers (8 bits)
+.set MATRIX_SPI_ROW = 0 ; row mask source
+
+; column sinks (8 bits)
+.set MATRIX_SPI_COL = 1 ; column scan sink
+
+;; Matrix state
+; Matrix framebuffer
+; this holds the columns data as a 1 byte bitmask of row data per column (8 bits -> 8 rows)
+matrix_colbuf: .byte MATRIX_BUF_COLS ; framebuffer (row data by column)
+
+; Column scan bit
+; in the matrix refresh loop, we push out each column's row data in turn
+; this bit tracks the currently refreshing column
+matrix_colbit: .byte 1 ; column scan bit
+
+; Matrix viewport offset
+; the visible matrix data is taken directly from the framebuffer, but it can be taken at an arbitrary offset
+; this determines the starting offset for the visible viewport's left edge from the start of the framebuffer in columns
+matrix_colshift: .byte 1 ; viewport left column offset
.cseg
-;; Normalize the outputs, enable the matrix, an set up buffers
+;; Normalize the outputs, enable the matrix, and set up buffers
Matrix_Init:
; Setup ENable port
sbi MATRIX_PORT, MATRIX_OE ; high -> disabled
@@ -59,7 +85,7 @@
; done
ret
-;; Scan the next column
+;; Scan the matrix's next column from the viewport
;; Interrupt-driven
Matrix_ScanCol:
; Save registers
@@ -73,7 +99,7 @@
; start packet
cbi SPI_PORT, SPI_SS
- ; output
+ ; output single column-enable bit
out SPDR, r16
; Compute col index
@@ -112,7 +138,7 @@
; load
ld r16, X
- ; output
+ ; output full row-enable bitmask
rcall SPI_Wait
out SPDR, r16
@@ -141,6 +167,7 @@
ret
;; Scan the matrix once in one go
+;; XXX: doesn't support colshift
Matrix_ScanFull:
; Row index
ldi ZL, low(matrix_colbuf)
@@ -175,8 +202,17 @@
; Done
ret
-;; Shift the matrix output one column to the right, looping around
-Matrix_ShiftRight:
+;; Reset the viewport to the start (left edge) of the framebuffer
+Matrix_ShiftZero:
+ ; Constant offset
+ ldi r16, 0
+
+ ; Set
+ rjmp Matrix_ShiftSet
+
+;; Shift the viewport one column to the left in the framebuffer, looping around to the end of the framebuffer
+; This moves the visible output one column to the right
+Matrix_ShiftLeft:
; Decrement-loop current value
; current value
lds r16, matrix_colshift
@@ -184,15 +220,36 @@
; shift window left
dec r16
- ; test for underflow -> MSB/N set
+ ; test for underflow (MSB/N set) -> don't skip reset
brpl Matrix_ShiftSet
; reset window to right edge
ldi r16, MATRIX_BUF_COLS - MATRIX_COLS
- ;; Continue
+ ; Set
+ rjmp Matrix_ShiftSet
-;; Set the matrix output left shift
+;; Shift the viewport one column to the right in the framebuffer, looping around to the start of the FB
+; This moves the visible output one column to the left
+Matrix_ShiftRight:
+ ; Increment-loop current value
+ ; current value
+ lds r16, matrix_colshift
+
+ ; shift window right
+ inc r16
+
+ ; test for overflow -> don't skip reset
+ cpi r16, MATRIX_BUF_COLS - MATRIX_COLS
+ brlt Matrix_ShiftSet
+
+ ; reset window to left edge
+ ldi r16, 0
+
+ ; Set
+ rjmp Matrix_ShiftSet
+
+;; Set the matrix viewport offset
;; Input: r16
Matrix_ShiftSet:
; store new value