matrix.inc
changeset 33 0d0309787be3
child 34 4646abd073fb
equal deleted inserted replaced
32:7ceb76b5a104 33:0d0309787be3
       
     1 ;; LED Matrix driver
       
     2 ;;
       
     3 
       
     4 .set MATRIX_DDR = DDRB
       
     5 .set MATRIX_PORT = PORTB
       
     6 .set MATRIX_OE = PORTB1		; Output Enable, active low, externally pulled high
       
     7 
       
     8 .dseg
       
     9 .set MATRIX_COLS = 8		; number of columns
       
    10 
       
    11 matrix_colbit:	.byte 1					; column bit
       
    12 matrix_rowbuf:	.byte MATRIX_COLS		; row bitmask by column
       
    13 
       
    14 .cseg
       
    15 
       
    16 ;; Normalize the outputs, enable the matrix, an set up buffers
       
    17 Matrix_Init:
       
    18     ; Setup ENable port
       
    19         sbi         MATRIX_PORT, MATRIX_OE	; high -> disabled
       
    20         sbi         MATRIX_DDR, MATRIX_OE	; out
       
    21  
       
    22 	; blank hardware
       
    23 		ldi			r16, 0
       
    24 
       
    25 		sts			spi_outbuf + 0, r16		; column sinks
       
    26 		sts			spi_outbuf + 1, r16		; row drivers
       
    27 
       
    28 	; write out
       
    29 		rcall		SPI_SendRecv
       
    30 
       
    31 	; enable
       
    32 		cbi			MATRIX_PORT, MATRIX_OE	; low -> enabled
       
    33 
       
    34 	; init buffers
       
    35 		ldi			r16, 0b1
       
    36 		sts			matrix_colbit, r16
       
    37 
       
    38 		ldi			r16, 0
       
    39 		ldi			r17, MATRIX_COLS
       
    40 		ldi			YL, low(matrix_rowbuf)
       
    41 		ldi			YH, high(matrix_rowbuf)
       
    42 
       
    43 m_init_mzero:
       
    44 		st			Y+, r16
       
    45 		
       
    46 		; loop until zero
       
    47 		dec			r17
       
    48 		brne		m_init_mzero
       
    49 
       
    50 	; Use Timer0, 32k cycles -> 500Hz scan rate
       
    51 		ldi			r16, 32
       
    52 		rcall		Timer0_Start
       
    53 
       
    54 	; done
       
    55 		ret
       
    56 
       
    57 ;; Scan the next column
       
    58 ;;  Interrupt-driven
       
    59 Matrix_ScanCol:
       
    60 	; Column bit
       
    61 		; load
       
    62 		lds			r16, matrix_colbit
       
    63 	
       
    64 		; start packet
       
    65         cbi         SPI_PORT, SPI_SS
       
    66 
       
    67 		; output
       
    68 		out			SPDR, r16
       
    69 
       
    70 	; Compute col index
       
    71 		ldi			r17, 0
       
    72 
       
    73 m_sc_colidx:
       
    74 		; shift
       
    75 		lsr			r16
       
    76 
       
    77 		; done if we shifted the bit out
       
    78 		brcs		m_sc_row
       
    79 
       
    80 		; count shifts
       
    81 		inc			r17
       
    82 		rjmp		m_sc_colidx
       
    83 
       
    84 m_sc_row:
       
    85 	; Row mask
       
    86 		; base
       
    87 		ldi			XL, low(matrix_rowbuf)
       
    88 		ldi			XH, high(matrix_rowbuf)
       
    89 
       
    90 		; offset
       
    91 		ldi			r18, 0
       
    92 
       
    93 		add			XL, r17
       
    94 		adc			XH, r18
       
    95 
       
    96 		; load
       
    97 		ld			r16, X
       
    98 
       
    99 		; output
       
   100 		rcall		SPI_Wait
       
   101 		out			SPDR, r16
       
   102 
       
   103 	; Update col bit
       
   104 		lds			r16, matrix_colbit
       
   105 	
       
   106 		; shift left
       
   107 		lsl			r16
       
   108 		brcc		m_sc_colout
       
   109 
       
   110 		; overflow, take bit from C
       
   111 		rol			r16
       
   112 
       
   113 m_sc_colout:
       
   114 		; store
       
   115 		sts			matrix_colbit, r16
       
   116 
       
   117 	; End of packet
       
   118 		rcall		SPI_Wait
       
   119         sbi         SPI_PORT, SPI_SS
       
   120 
       
   121 	; Done
       
   122 		ret
       
   123 
       
   124 ;; Scan the matrix once in one go
       
   125 Matrix_ScanFull:
       
   126 	; Row index
       
   127 		ldi			ZL, low(matrix_rowbuf)
       
   128 		ldi			ZH, high(matrix_rowbuf)
       
   129 
       
   130 	; Column bit
       
   131 		ldi			r25, 0
       
   132 		sec								; set C
       
   133 		
       
   134 m_pulse_col:
       
   135 		; rotate bit left from C
       
   136 		rol			r25
       
   137 		
       
   138 		; overflow
       
   139 		brcs		m_pulse_end
       
   140 		
       
   141 		; store in output buffer
       
   142 		sts			spi_outbuf + 1, r25
       
   143 
       
   144 	; Row mask
       
   145 		ld			r16, Z+
       
   146 
       
   147 		sts			spi_outbuf + 0, r16
       
   148 
       
   149 	; Display
       
   150 		rcall		SPI_SendRecv
       
   151 
       
   152 	; Next column
       
   153 		rjmp		m_pulse_col
       
   154 
       
   155 m_pulse_end:
       
   156 	; Done
       
   157 		ret
       
   158