terom@38: ;; vim: set ft=avr: terom@38: terom@31: .nolist terom@31: .include "m168def.inc" ; Same family as 328P terom@31: .list terom@31: terom@31: terom@31: ;; Interrupt Vector terom@31: .org 0x00 terom@31: rjmp init terom@31: terom@33: .org OC1Aaddr terom@33: ; Timer/Counter1 Compare Output A terom@33: rjmp Timer_OC1A terom@33: terom@33: .org OC0Aaddr terom@33: ; Timer/Counter0 Compare Output A terom@33: rjmp Timer_OC0A terom@33: terom@33: .org SPIaddr terom@33: rjmp SPI_Interrupt terom@33: terom@34: terom@34: cseg0: .org 0x40 terom@33: terom@31: ;; Syntax terom@31: .include "macros.inc" terom@31: terom@31: ;; SPI terom@31: .include "spi.inc" terom@31: terom@33: ;; Matrix terom@33: .include "matrix.inc" terom@33: terom@33: ;; Timer terom@33: .set TIMER0_CB_A = Matrix_ScanCol terom@33: terom@33: .include "timer.inc" terom@33: terom@31: ;; Utils terom@31: .include "delay.inc" terom@31: terom@38: ;; Font rendering terom@38: .include "font.inc" terom@38: terom@31: ;; Scan through each pixel terom@33: Main_ScanRaw: terom@31: ; init terom@31: ldi r18, 1 terom@31: ldi r19, 1 terom@31: terom@31: scan_loop: terom@31: ; write out to SPI terom@31: sts spi_outbuf + 0, r18 ; rows terom@31: sts spi_outbuf + 1, r19 ; columns terom@31: terom@31: rcall SPI_SendRecv terom@31: terom@31: ; delay terom@31: ldi r20, 5 ; ~4M cycles terom@31: rcall VarDelay terom@31: terom@33: ; cols terom@33: lsl r19 ; next col terom@33: brcc scan_loop ; refresh if we didn't overflow terom@33: terom@33: rol r19 ; shift back from C into r21.0 terom@33: terom@31: ; rows terom@33: lsl r18 ; next row terom@31: brcc scan_loop ; refresh if we didn't overflow terom@31: terom@31: rol r18 ; shift back from C into r20.0 terom@31: terom@31: ; one scan completed terom@31: ret terom@31: terom@33: ;; Scan with test pattern terom@33: Main_ScanTest: terom@33: ; Generate pattern terom@33: ; end of buffer terom@34: ldi r17, MATRIX_BUF_COLS terom@34: ldi XL, low(matrix_colbuf + MATRIX_BUF_COLS) terom@34: ldi XH, high(matrix_colbuf + MATRIX_BUF_COLS) terom@33: terom@33: ; bit pattern terom@33: ldi r16, 0b11 terom@33: terom@33: st_loop: terom@34: ; put, pre-decrement terom@33: st -X, r16 terom@33: terom@33: ; flip terom@33: rol r16 terom@33: terom@33: ; loop until zero terom@33: dec r17 terom@33: brne st_loop terom@33: terom@34: st_animate: terom@34: ; Animate terom@34: ; shift right terom@36: rcall Matrix_ShiftLeft terom@34: terom@34: ; wait for X/16th of a second terom@35: ldi XH, high(8 * 1024) terom@35: ldi XL, low(8 * 1024) terom@34: terom@34: rcall Timer_Sleep terom@34: terom@34: ; loop terom@34: rjmp st_animate terom@34: terom@34: terom@34: ;; Display device code memory terom@34: Main_ScanCode: terom@34: ; Code start terom@34: ldi ZL, low(cseg0 * 2) ; word addr terom@34: ldi ZH, high(cseg0 * 2) ; word addr terom@34: terom@35: ; Pause refresh terom@35: cli terom@35: terom@34: ; Load initial frame terom@34: ; to first frame, starting from right edge terom@34: ldi r17, 8 terom@34: ldi XL, low(matrix_colbuf + 16) terom@34: ldi XH, high(matrix_colbuf + 16) terom@34: terom@34: sc_load_initial: terom@34: ; one byte terom@34: lpm r16, Z+ terom@34: st -X, r16 terom@34: terom@34: ; loop until zero terom@34: dec r17 terom@34: brne sc_load_initial terom@34: terom@36: ; the first ShiftLeft below will jump to the end of the framebuffer terom@36: terom@34: sc_next: terom@34: ; Show this frame terom@36: rcall Matrix_ShiftLeft terom@34: terom@34: ; Load next frame terom@34: ldi r17, 8 terom@34: ldi XL, low(matrix_colbuf + 8) terom@34: ldi XH, high(matrix_colbuf + 8) terom@34: terom@34: sc_load_next: terom@34: ; one byte terom@34: lpm r16, Z+ terom@34: st -X, r16 terom@34: terom@34: ; loop until zero terom@34: dec r17 terom@34: brne sc_load_next terom@34: terom@35: ; Enable refresh terom@35: sei terom@35: terom@34: ; Animate from this -> next frame terom@34: ldi r17, 8 ; 8 columns terom@34: terom@34: sc_anim: terom@34: ; wait for X/16th of a second terom@34: ldi XH, high(2 * 1024) terom@34: ldi XL, low(2 * 1024) terom@34: terom@34: rcall Timer_Sleep terom@34: terom@34: ; shift terom@36: rcall Matrix_ShiftLeft terom@34: terom@34: ; loop until zero terom@34: dec r17 terom@34: brne sc_anim terom@34: terom@35: ; Pause refresh terom@35: cli terom@35: terom@34: ; Move next -> this terom@34: ldi r17, 8 terom@34: ldi XL, low(matrix_colbuf + 16) terom@34: ldi XH, high(matrix_colbuf + 16) terom@34: ldi YL, low(matrix_colbuf + 8) terom@34: ldi YH, high(matrix_colbuf + 8) terom@34: terom@34: sc_move_this: terom@34: ; one byte terom@34: ld r16, -Y terom@34: st -X, r16 terom@34: terom@34: ; loop until zero terom@34: dec r17 terom@34: brne sc_move_this terom@34: terom@34: sbi PIND, PIND7 terom@34: terom@34: ; Load next frame, and animate terom@34: rjmp sc_next terom@33: terom@38: Main_ScanText: terom@38: terom@39: ; Constants terom@39: stxt_message: ; text to render terom@39: .db 0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x20, 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x21, 0x0 ; 'hello world!' terom@38: terom@39: ; Load into buffer terom@39: ldi ZL, low(stxt_message * 2) terom@39: ldi ZH, high(stxt_message * 2) terom@38: terom@39: rcall Text_LoadString terom@38: terom@39: sbi PORTD, PIND7 terom@38: terom@39: ; Display terom@39: rcall Text_ShowString terom@39: terom@39: ; Done terom@39: ret terom@38: terom@31: Main: terom@31: init: terom@31: ; Stack terom@31: ldi r16, high(RAMEND) terom@31: ldi r17, low(RAMEND) terom@31: out SPH, r16 terom@31: out SPL, r17 terom@31: terom@31: ; Enable interrupts terom@31: sei terom@31: terom@33: ; DEBUG terom@33: sbi DDRD, PORTD7 terom@33: cbi PORTD, PORTD7 terom@33: terom@33: ; Timer terom@33: rcall Timer_Init terom@33: terom@31: ; SPI terom@31: rcall SPI_Init terom@33: terom@33: ; Matrix terom@33: rcall Matrix_Init terom@31: terom@31: ; Run terom@33: ; rcall Main_ScanRaw terom@34: ; rcall Main_ScanTest terom@38: ; rcall Main_ScanCode terom@38: rcall Main_ScanText terom@31: terom@31: end: terom@31: rjmp end terom@31: