matrix.s
author Tero Marttila <terom@paivola.fi>
Sun, 20 Apr 2014 23:51:57 +0300
changeset 80 5254ba612630
parent 39 d7eac199d323
permissions -rw-r--r--
dmx-web: slightly better RGB colorpicker control..
;; vim: set ft=avr:

.nolist
.include "m168def.inc"      ; Same family as 328P
.list


;; Interrupt Vector
.org 0x00
        rjmp        init

.org OC1Aaddr
		; Timer/Counter1 Compare Output A
		rjmp		Timer_OC1A

.org OC0Aaddr
        ; Timer/Counter0 Compare Output A
        rjmp        Timer_OC0A

.org SPIaddr
        rjmp        SPI_Interrupt


cseg0:         .org 0x40

;; Syntax
.include "macros.inc"

;; SPI
.include "spi.inc"

;; Matrix
.include "matrix.inc"

;; Timer
.set TIMER0_CB_A = Matrix_ScanCol

.include "timer.inc"

;; Utils
.include "delay.inc"

;; Font rendering
.include "font.inc"

;; Scan through each pixel
Main_ScanRaw:
	; init
		ldi			r18, 1
		ldi			r19, 1

scan_loop:
	; write out to SPI
		sts			spi_outbuf + 0, r18		; rows
		sts			spi_outbuf + 1, r19		; columns

		rcall		SPI_SendRecv

	; delay
		ldi			r20, 5					; ~4M cycles
		rcall		VarDelay

	; cols
		lsl			r19						; next col
		brcc		scan_loop				; refresh if we didn't overflow
		
		rol			r19						; shift back from C into r21.0

	; rows
		lsl			r18						; next row
		brcc		scan_loop				; refresh if we didn't overflow
		
		rol			r18						; shift back from C into r20.0

	; one scan completed
		ret

;; Scan with test pattern
Main_ScanTest:
	; Generate pattern
		; end of buffer
		ldi			r17, MATRIX_BUF_COLS
		ldi			XL, low(matrix_colbuf + MATRIX_BUF_COLS)
		ldi			XH, high(matrix_colbuf + MATRIX_BUF_COLS)
		
		; bit pattern
		ldi			r16, 0b11

st_loop:
		; put, pre-decrement
		st			-X, r16

		; flip
		rol			r16
		
		; loop until zero	
		dec			r17
		brne		st_loop

st_animate:
	; Animate
        ; shift right
        rcall       Matrix_ShiftLeft

        ; wait for X/16th of a second
        ldi         XH, high(8 * 1024)
        ldi         XL, low(8 * 1024)

        rcall       Timer_Sleep

        ; loop
        rjmp        st_animate


;; Display device code memory
Main_ScanCode:
    ; Code start
        ldi         ZL, low(cseg0 * 2)      ; word addr
        ldi         ZH, high(cseg0 * 2)     ; word addr
    
    ; Pause refresh
        cli

    ; Load initial frame
        ; to first frame, starting from right edge
        ldi         r17, 8
		ldi			XL, low(matrix_colbuf + 16)
		ldi			XH, high(matrix_colbuf + 16)

sc_load_initial:
        ; one byte
        lpm         r16, Z+
        st          -X, r16

        ; loop until zero
        dec         r17
        brne        sc_load_initial

        ; the first ShiftLeft below will jump to the end of the framebuffer

sc_next:
    ; Show this frame
        rcall       Matrix_ShiftLeft

    ; Load next frame
        ldi         r17, 8
        ldi         XL, low(matrix_colbuf + 8)
        ldi         XH, high(matrix_colbuf + 8)

sc_load_next:
        ; one byte
        lpm         r16, Z+
        st          -X, r16

        ; loop until zero
        dec         r17
        brne        sc_load_next

    ; Enable refresh
        sei

    ; Animate from this -> next frame
        ldi         r17, 8      ; 8 columns

sc_anim:
        ; wait for X/16th of a second
        ldi         XH, high(2 * 1024)
        ldi         XL, low(2 * 1024)

        rcall       Timer_Sleep

        ; shift
        rcall       Matrix_ShiftLeft

        ; loop until zero
        dec         r17
        brne        sc_anim

    ; Pause refresh
        cli

    ; Move next -> this
        ldi         r17, 8
        ldi         XL, low(matrix_colbuf + 16)
        ldi         XH, high(matrix_colbuf + 16)
        ldi         YL, low(matrix_colbuf + 8)
        ldi         YH, high(matrix_colbuf + 8)

sc_move_this:
        ; one byte
        ld          r16, -Y
        st          -X, r16

        ; loop until zero
        dec         r17
        brne        sc_move_this

sbi         PIND, PIND7

    ; Load next frame, and animate
        rjmp        sc_next

Main_ScanText:

    ; Constants
stxt_message:       ; text to render
        .db         0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x20, 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x21, 0x0 ; 'hello world!'

    ; Load into buffer
        ldi         ZL, low(stxt_message * 2)
        ldi         ZH, high(stxt_message * 2)

        rcall       Text_LoadString

sbi         PORTD, PIND7

    ; Display
        rcall       Text_ShowString

    ; Done
        ret

Main:
init:
    ; Stack
        ldi         r16, high(RAMEND)
        ldi         r17, low(RAMEND)
        out         SPH, r16
        out         SPL, r17

    ; Enable interrupts
        sei

; DEBUG
sbi			DDRD, PORTD7
cbi			PORTD, PORTD7

	; Timer
		rcall		Timer_Init

    ; SPI
        rcall       SPI_Init

	; Matrix
		rcall		Matrix_Init	
	
    ; Run
		; rcall		Main_ScanRaw
		; rcall		Main_ScanTest
        ; rcall       Main_ScanCode
        rcall       Main_ScanText

end:
        rjmp        end