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