matrix.inc
changeset 36 06e1e554acbb
parent 34 4646abd073fb
child 38 f430b507a885
equal deleted inserted replaced
35:f1ac13235304 36:06e1e554acbb
     1 ;; LED Matrix driver
     1 ;; LED Matrix driver
     2 ;;
     2 ;;
     3 
     3 
       
     4 .dseg
       
     5 ;; I/O addresses
       
     6 ; Control port
     4 .set MATRIX_DDR = DDRB
     7 .set MATRIX_DDR = DDRB
     5 .set MATRIX_PORT = PORTB
     8 .set MATRIX_PORT = PORTB
       
     9 
       
    10 ; Pin for matrix driver Output Enable
     6 .set MATRIX_OE = PORTB1		; Output Enable, active low, externally pulled high
    11 .set MATRIX_OE = PORTB1		; Output Enable, active low, externally pulled high
     7 
    12 
     8 .dseg
    13 ;; Matrix properties
     9 .set MATRIX_COLS = 8                        ; number of physical columns (XXX: fixed to 8)
    14 ; Matrix width in columns
    10 .set MATRIX_BUF_COLS = 16		            ; number of columns in frame buffer
    15 .set MATRIX_COLS = 8                        ; physical columns
    11 
    16 
    12 matrix_colbit:	    .byte 1					; scan column bit
    17 ; Framebuffer width in columns
    13 matrix_colbuf:	    .byte MATRIX_BUF_COLS	; row bits by column
    18 .set MATRIX_BUF_COLS = 16		            ; framebuffer columns
    14 matrix_colshift:    .byte 1                 ; left column offset
    19 
       
    20 ;; SPI addresses
       
    21 ; row drivers (8 bits)
       
    22 .set MATRIX_SPI_ROW = 0                     ; row mask source
       
    23 
       
    24 ; column sinks (8 bits)
       
    25 .set MATRIX_SPI_COL = 1                     ; column scan sink
       
    26 
       
    27 ;; Matrix state
       
    28 ; Matrix framebuffer
       
    29 ; this holds the columns data as a 1 byte bitmask of row data per column (8 bits -> 8 rows)
       
    30 matrix_colbuf:	    .byte MATRIX_BUF_COLS   ; framebuffer (row data by column)
       
    31 
       
    32 ; Column scan bit
       
    33 ; in the matrix refresh loop, we push out each column's row data in turn
       
    34 ; this bit tracks the currently refreshing column
       
    35 matrix_colbit:	    .byte 1                 ; column scan bit
       
    36 
       
    37 ; Matrix viewport offset
       
    38 ; the visible matrix data is taken directly from the framebuffer, but it can be taken at an arbitrary offset
       
    39 ; this determines the starting offset for the visible viewport's left edge from the start of the framebuffer in columns
       
    40 matrix_colshift:    .byte 1                 ; viewport left column offset
    15 
    41 
    16 .cseg
    42 .cseg
    17 
    43 
    18 ;; Normalize the outputs, enable the matrix, an set up buffers
    44 ;; Normalize the outputs, enable the matrix, and set up buffers
    19 Matrix_Init:
    45 Matrix_Init:
    20     ; Setup ENable port
    46     ; Setup ENable port
    21         sbi         MATRIX_PORT, MATRIX_OE	; high -> disabled
    47         sbi         MATRIX_PORT, MATRIX_OE	; high -> disabled
    22         sbi         MATRIX_DDR, MATRIX_OE	; out
    48         sbi         MATRIX_DDR, MATRIX_OE	; out
    23  
    49  
    57 		rcall		Timer0_Start
    83 		rcall		Timer0_Start
    58 
    84 
    59 	; done
    85 	; done
    60 		ret
    86 		ret
    61 
    87 
    62 ;; Scan the next column
    88 ;; Scan the matrix's next column from the viewport
    63 ;;  Interrupt-driven
    89 ;;  Interrupt-driven
    64 Matrix_ScanCol:
    90 Matrix_ScanCol:
    65     ; Save registers
    91     ; Save registers
    66         push        r16
    92         push        r16
    67         push        r17
    93         push        r17
    71 		lds			r16, matrix_colbit
    97 		lds			r16, matrix_colbit
    72 	
    98 	
    73 		; start packet
    99 		; start packet
    74         cbi         SPI_PORT, SPI_SS
   100         cbi         SPI_PORT, SPI_SS
    75 
   101 
    76 		; output
   102 		; output single column-enable bit
    77 		out			SPDR, r16
   103 		out			SPDR, r16
    78 
   104 
    79 	; Compute col index
   105 	; Compute col index
    80 		ldi			r17, 0
   106 		ldi			r17, 0
    81 
   107 
   110 		adc			XH, r16
   136 		adc			XH, r16
   111 
   137 
   112 		; load
   138 		; load
   113 		ld			r16, X
   139 		ld			r16, X
   114 
   140 
   115 		; output
   141 		; output full row-enable bitmask
   116 		rcall		SPI_Wait
   142 		rcall		SPI_Wait
   117 		out			SPDR, r16
   143 		out			SPDR, r16
   118 
   144 
   119 	; Update col bit
   145 	; Update col bit
   120 		lds			r16, matrix_colbit
   146 		lds			r16, matrix_colbit
   139         pop         r16
   165         pop         r16
   140 
   166 
   141 		ret
   167 		ret
   142 
   168 
   143 ;; Scan the matrix once in one go
   169 ;; Scan the matrix once in one go
       
   170 ;; XXX: doesn't support colshift
   144 Matrix_ScanFull:
   171 Matrix_ScanFull:
   145 	; Row index
   172 	; Row index
   146 		ldi			ZL, low(matrix_colbuf)
   173 		ldi			ZL, low(matrix_colbuf)
   147 		ldi			ZH, high(matrix_colbuf)
   174 		ldi			ZH, high(matrix_colbuf)
   148 
   175 
   173 
   200 
   174 m_pulse_end:
   201 m_pulse_end:
   175 	; Done
   202 	; Done
   176 		ret
   203 		ret
   177 
   204 
   178 ;; Shift the matrix output one column to the right, looping around
   205 ;; Reset the viewport to the start (left edge) of the framebuffer
   179 Matrix_ShiftRight:
   206 Matrix_ShiftZero:
       
   207     ; Constant offset
       
   208         ldi         r16, 0
       
   209 
       
   210     ; Set
       
   211         rjmp        Matrix_ShiftSet
       
   212 
       
   213 ;; Shift the viewport one column to the left in the framebuffer, looping around to the end of the framebuffer
       
   214 ; This moves the visible output one column to the right
       
   215 Matrix_ShiftLeft:
   180     ; Decrement-loop current value
   216     ; Decrement-loop current value
   181         ; current value
   217         ; current value
   182         lds         r16, matrix_colshift
   218         lds         r16, matrix_colshift
   183 
   219 
   184         ; shift window left
   220         ; shift window left
   185         dec         r16
   221         dec         r16
   186 
   222 
   187         ; test for underflow -> MSB/N set
   223         ; test for underflow (MSB/N set) -> don't skip reset
   188         brpl        Matrix_ShiftSet
   224         brpl        Matrix_ShiftSet
   189 
   225 
   190         ; reset window to right edge
   226         ; reset window to right edge
   191         ldi         r16, MATRIX_BUF_COLS - MATRIX_COLS
   227         ldi         r16, MATRIX_BUF_COLS - MATRIX_COLS
   192 
   228 
   193     ;; Continue
   229     ; Set
   194 
   230         rjmp        Matrix_ShiftSet
   195 ;; Set the matrix output left shift
   231 
       
   232 ;; Shift the viewport one column to the right in the framebuffer, looping around to the start of the FB
       
   233 ; This moves the visible output one column to the left
       
   234 Matrix_ShiftRight:
       
   235     ; Increment-loop current value
       
   236         ; current value
       
   237         lds         r16, matrix_colshift
       
   238 
       
   239         ; shift window right
       
   240         inc         r16
       
   241 
       
   242         ; test for overflow -> don't skip reset
       
   243         cpi         r16, MATRIX_BUF_COLS - MATRIX_COLS
       
   244         brlt        Matrix_ShiftSet
       
   245 
       
   246         ; reset window to left edge
       
   247         ldi         r16, 0
       
   248 
       
   249     ; Set
       
   250         rjmp        Matrix_ShiftSet
       
   251 
       
   252 ;; Set the matrix viewport offset
   196 ;; Input: r16
   253 ;; Input: r16
   197 Matrix_ShiftSet:
   254 Matrix_ShiftSet:
   198         ; store new value
   255         ; store new value
   199         sts         matrix_colshift, r16
   256         sts         matrix_colshift, r16
   200 
   257