matrix.inc
changeset 36 06e1e554acbb
parent 34 4646abd073fb
child 38 f430b507a885
--- 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