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