matrix.inc
changeset 89 1b3cea759eff
parent 88 c923295ee520
child 90 13c2deb919d1
--- a/matrix.inc	Mon Jun 02 18:27:08 2014 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,461 +0,0 @@
-;; LED Matrix driver
-;; vim: set ft=avr:
-
-.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
-
-;; Matrix properties
-; Matrix width in columns
-.set MATRIX_COLS = 8                        ; physical columns
-
-; 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
-
-;; Text
-; Maximum length of message
-.set TEXT_MAXLENGTH = 64
-
-; Scrolling speed (kiloticks per frame)
-.set TEXT_SPEED = 1
-
-text_buffer:        .byte TEXT_MAXLENGTH    ; display message buffer
-text_offset:        .byte 1                 ; current offset in text
-
-.cseg
-
-;; Normalize the outputs, enable the matrix, and set up buffers
-Matrix_Init:
-    ; Setup ENable port
-        sbi         MATRIX_PORT, MATRIX_OE	; high -> disabled
-        sbi         MATRIX_DDR, MATRIX_OE	; out
- 
-	; blank hardware
-		ldi			r16, 0
-
-		sts			spi_outbuf + 0, r16		; column sinks
-		sts			spi_outbuf + 1, r16		; row drivers
-
-	; write out
-		rcall		SPI_SendRecv
-
-	; enable
-		cbi			MATRIX_PORT, MATRIX_OE	; low -> enabled
-
-	; init buffers
-		ldi			r16, 0b1
-		sts			matrix_colbit, r16
-
-        ldi         r16, 0
-        sts         matrix_colshift, r16
-
-		ldi			r16, 0
-		ldi			r17, MATRIX_BUF_COLS
-		ldi			YL, low(matrix_colbuf)
-		ldi			YH, high(matrix_colbuf)
-
-m_init_mzero:
-		st			Y+, r16
-		
-		; loop until zero
-		dec			r17
-		brne		m_init_mzero
-
-	; Use Timer0, 32k cycles -> 500Hz scan rate
-		ldi			r16, 32
-		rcall		Timer0_Start
-
-	; done
-		ret
-
-;; Scan the matrix's next column from the viewport
-;;  Interrupt-driven
-Matrix_ScanCol:
-    ; Save registers
-        push        r16
-        push        r17
-
-	; Column bit
-		; load
-		lds			r16, matrix_colbit
-	
-		; start packet
-        cbi         SPI_PORT, SPI_SS
-
-		; output single column-enable bit
-		out			SPDR, r16
-
-	; Compute col index
-		ldi			r17, 0
-
-m_sc_colidx:
-		; shift
-		lsr			r16
-
-		; done if we shifted the bit out
-		brcs		m_sc_row
-
-		; count shifts
-		inc			r17
-		rjmp		m_sc_colidx
-
-m_sc_row:
-    ; Column shift
-        ; load
-        lds         r16, matrix_colshift
-
-        ; add to col index
-        add         r17, r16
-
-	; Row mask
-		; base
-		ldi			XL, low(matrix_colbuf)
-		ldi			XH, high(matrix_colbuf)
-
-		; offset
-		ldi			r16, 0
-
-		add			XL, r17
-		adc			XH, r16
-
-		; load
-		ld			r16, X
-
-		; output full row-enable bitmask
-		rcall		SPI_Wait
-		out			SPDR, r16
-
-	; Update col bit
-		lds			r16, matrix_colbit
-	
-		; shift left
-		lsl			r16
-		brcc		m_sc_colout
-
-		; overflow, take bit from C
-		rol			r16
-
-m_sc_colout:
-		; store
-		sts			matrix_colbit, r16
-
-	; End of packet
-		rcall		SPI_Wait
-        sbi         SPI_PORT, SPI_SS
-
-	; Done
-        pop         r17
-        pop         r16
-
-		ret
-
-;; Scan the matrix once in one go
-;; XXX: doesn't support colshift
-Matrix_ScanFull:
-	; Row index
-		ldi			ZL, low(matrix_colbuf)
-		ldi			ZH, high(matrix_colbuf)
-
-	; Column bit
-		ldi			r25, 0
-		sec								; set C
-		
-m_pulse_col:
-		; rotate bit left from C
-		rol			r25
-		
-		; overflow
-		brcs		m_pulse_end
-		
-		; store in output buffer
-		sts			spi_outbuf + 1, r25
-
-	; Row mask
-		ld			r16, Z+
-
-		sts			spi_outbuf + 0, r16
-
-	; Display
-		rcall		SPI_SendRecv
-
-	; Next column
-		rjmp		m_pulse_col
-
-m_pulse_end:
-	; Done
-		ret
-
-;; 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
-
-        ; shift window left
-        dec         r16
-
-        ; 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
-
-    ; Set
-        rjmp        Matrix_ShiftSet
-
-;; 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
-        sts         matrix_colshift, r16
-
-        ; done
-        ret
-
-;; Rewinds the currently visible viewport to the beginning of the framebuffer
-; This copies the currently visible viewport data to the beginning of the framebuffer and resets the offset
-Matrix_ShiftRewind:
-        ; current view offset
-        ldi         XL, low(matrix_colbuf)
-        ldi         XH, high(matrix_colbuf)
-
-        ; offset
-        lds         r16, matrix_colshift
-
-        ; add
-        ldi         r17, 0
-        add         XL, r16
-        adc         XH, r17
-
-        ; start of framebuffer
-        ldi         YL, low(matrix_colbuf + 0)
-        ldi         YH, high(matrix_colbuf + 0)
-
-        ; viewport width
-        ldi         r17, MATRIX_COLS
-
-matrix_shiftrew_loop:
-        ; copy
-        ld          r16, X+
-        st          Y+, r16
-
-        ; count
-        dec         r17
-        brne        matrix_shiftrew_loop
-
-        ; done, reset offset
-        rjmp        MAtrix_ShiftZero
-
-
-;; Load a NUL-terminated ASCII string from PGM into the text buffer
-; Input:    Z       - Address of NUL-terminated ASCII string in PGM        
-Text_LoadString:
-    ; Setup
-        ; storage buffer
-        ldi         YL, low(text_buffer)
-        ldi         YH, high(text_buffer)
-
-        ; max. length
-        ldi         r18, TEXT_MAXLENGTH
-
-text_loads_loop:
-    ; Test max length
-        ; count and check for overflow
-        dec         r18
-        brne        text_loads_char
-
-    ; Load char
-        ; force NUL
-        ldi         r16, 0x00
-
-text_loads_char:
-        ; load next char
-        lpm         r16, Z+
-
-text_loads_store:
-    ; Store and test NUL
-        ; store it
-        st          Y+, r16
-
-        ; test for NUL
-        tst         r16
-        brne        text_loads_loop
-
-    ; Update scroll offset
-        ; reset offset
-        ldi         r17, 0
-        sts         text_offset, r17
-
-        ; done
-        ret
-
-;; Shows the loaded string of ASCII text on the display, scrolling it horizontally
-; Uses font.inc for rendering
-; XXX: uses blocking timer sleeps and doesn't return until done
-Text_ShowString:
-    ; Load initial char
-        ldi         XL, low(text_buffer + 0)
-        ldi         XH, high(text_buffer + 0)
-
-        ; load char
-        ld          r16, X+
-        push        XL
-        push        XH
-
-        ; one column spacing
-        ldi         YL, low(matrix_colbuf + 1)
-        ldi         YH, high(matrix_colbuf + 1)
-
-        ; render to framebuffer
-        rcall       Font_Render
-
-        ; reset viewport
-        rcall       Matrix_ShiftZero
-       
-   ; Load next char
-text_shows_next:        
-        ; next char
-        pop         XH
-        pop         XL
-        ld          r16, X+
-        push        XL
-        push        XH
-
-        ; test NUL
-        tst         r16
-        breq        text_shows_end
-
-        ; offscreen
-        ldi         YL, low(matrix_colbuf + 1 + 6 + 1)
-        ldi         YH, high(matrix_colbuf + 1 + 6 + 1)
-
-        ; render
-        rcall       Font_Render
-
-    ; Animate to next char
-        ldi         r20, 7
-        
-text_shows_animloop:
-        ; sleep
-        ldi         XH, high(TEXT_SPEED * 1024)
-        ldi         XL, low(TEXT_SPEED * 1024)
-
-        rcall       Timer_Sleep
-
-        ; shift
-        rcall       Matrix_ShiftRight
-
-        ; count
-        dec         r20
-        brne        text_shows_animloop
-
-    ; Rewind to next char
-        rcall       Matrix_ShiftRewind
-
-        sbi         PIND, PIND7
-
-        ; load next char and animate it in
-        rjmp        text_shows_next
-
-text_shows_end:
-    ; Done
-        pop         XH
-        pop         XL
-
-
-    ; Clear second frame
-        ldi         YL, low(matrix_colbuf + 16)
-        ldi         YH, high(matrix_colbuf + 16)
-        ldi         r16, MATRIX_COLS
-        ldi         r17, 0
-
-text_shows_end2:        
-        st          -Y, r17
-
-        dec         r16
-        brne        text_shows_end2
-
-    ; Blink
-text_shows_end3:        
-        ; on
-        ldi         r16, 0
-        rcall       Matrix_ShiftSet
-
-        ; sleep
-        ldi         XH, high(TEXT_SPEED * 6 * 1024)
-        ldi         XL, low(TEXT_SPEED * 6 * 1024)
-
-        rcall       Timer_Sleep
-
-        ; off        
-        ldi         r16, 8
-        rcall       Matrix_ShiftSet
-
-        ; sleep
-        ldi         XH, high(TEXT_SPEED * 6 * 1024)
-        ldi         XL, low(TEXT_SPEED * 6 * 1024)
-
-        rcall       Timer_Sleep
-
-        ; loop
-        rjmp        text_shows_end3
-
-    ; XXX: end
-        ret
-