initial version of firmware
Stefan Schuermans authored 5 years ago
|
1) ; Chaosknoten - animated logo board
2) ; Copyright (C) 2019 Stefan Schuermans <stefan@blinkenarea.org>
3) ; Copyleft: GNU public license - http://www.gnu.org/copyleft/gpl.html
4)
5) ; ATtiny2313A, clock frequency: 8 MHz (internal oscillator)
6)
7) ; PA0: unused
8) ; PA1: unused
9) ; PA2: reset
10) ; PB0: column 0 output (output, low)
11) ; PB1: column 1 output (output, low)
12) ; PB2: column 2 output (output, low)
13) ; PB3: column 3 output (output, low)
14) ; PB4: column 4 output (output, low)
15) ; PB5: column 5 output (output, low)
16) ; PB6: column 6 output (output, low)
17) ; PB7: unused (input, pull-up enabled)
18) ; PD0: row 0 output (output, high)
19) ; PD1: row 1 output (output, high)
20) ; PD2: row 2 output (output, high)
21) ; PD3: row 3 output (output, high)
22) ; PD4: row 4 output (output, high)
23) ; PD5: row 5 output (output, high)
24) ; PD6: mode switch (input, pull-up enabled)
25)
26)
27)
28) .INCLUDE "tn2313def.inc"
29)
30)
31)
32) ; IO pins
33) .equ COL_PORT = PORTB ; column outputs
34) .equ ROW_PORT = PORTD ; row outputs
35) .equ MODE_SW_PIN = PIND
36) .equ MODE_SW_BIT = 6
37)
38)
39)
40) ; general purpose registers
41) .def TMP = r16
42) .def TMP2 = r17
43) .def CNT = r18
44) .def DATA = r19
45) .def GRAY = r20
46)
47) ; current mode
48) .def MODE = r21
49) .equ MODE_ALL = 0 ; play all animations
50) .equ MODE_SINGLE = 1 ; play single animation only
51) .equ MODE_UNKNOWN = 0xFF ; unknown mode
52)
53) ; current animation number and iterations
54) .def ANI_NO = r22
55) .def ANI_IT = r23
56)
57)
58)
59) .DSEG
60) .ORG 0x060
61)
62)
63)
64) ; current frame
65) FRAME: .BYTE 42
66)
67)
68)
69) .CSEG
70) .ORG 0x000
71) rjmp ENTRY ; RESET
72) reti ; INT0
73) reti ; INT1
74) reti ; TIMER1_CAPT
75) reti ; TIMER1_COMPA
76) reti ; TIMER1_OVF
77) reti ; TIMER0_OVF
78) reti ; USART0_RX
79) reti ; USART0_UDRE
80) reti ; USART0_TX
81) reti ; ANALOG_COMP
82) reti ; PC_INT0
83) reti ; TIMER1_COMPB
84) reti ; TIMER0_COMPA
85) reti ; TIMER0_COMPB
86) reti ; USI_START
87) reti ; USI_OVERFLOW
88) reti ; EE_READY
89) reti ; WDT
90) reti ; PC_INT1
91) reti ; PC_INT2
92)
93)
94)
95) ; code entry point
96) ENTRY:
97) ; set system clock prescaler to 1:1
98) ldi TMP,1<<CLKPCE
99) out CLKPR,TMP
100) ldi TMP,0
101) out CLKPR,TMP
102) ; initialize output ports
103) ldi TMP,0x00 ; PA[01] to output, low
104) out PORTA,TMP
105) ldi TMP,0x03
106) out DDRA,TMP
107) ldi TMP,0x80 ; PB[0-6] to output, low - PB7 to input, pull-up enabled
108) out PORTB,TMP
109) ldi TMP,0x7F
110) out DDRB,TMP
111) ldi TMP,0x7F ; PD[0-5] to output, high - PD6 to input, pull-up enabled
112) out PORTD,TMP
113) ldi TMP,0x3F
114) out DDRD,TMP
115) ; initialize stack pointer
116) ldi TMP,RAMEND
117) out SPL,TMP
118) ; enable watchdog (64ms)
119) wdr
120) ldi TMP,1<<WDCE|1<<WDE
121) out WDTCR,TMP
122) ldi TMP,1<<WDE|1<<WDP1
123) out WDTCR,TMP
124) wdr
125) ; disable analog comparator
126) ldi TMP,1<<ACD
127) out ACSR,TMP
128) ; jump to main program
129) rjmp MAIN
130)
131)
132)
133) ; wait 61 cycles
134) ; input: -
135) ; output: -
136) ; changes: TMP
137) ; cycles: 61 (including rcall and ret)
138) WAIT61:
139) ldi TMP,18
140) WAIT61_LOOP:
141) dec TMP
142) brne WAIT61_LOOP
143) ; done
144) ret
145)
146)
147)
148) ; output row for grayscale (black/white) and wait
149) ; input: X = ptr to pixel data (0..15)
150) ; GRAY = grayscale value (1..15)
151) ; output: -
152) ; changes: TMP, TMP2, DATA
153) ; cycles: GRAY * 64 + 1 (including rcall and ret)
154) ROW_BW_WAIT:
155) ; get data for LEDs
156) ldi TMP2,7 ; 7 pixels
157) ROW_BW_WAIT_PIXEL:
158) ld TMP,X+ ; get pixel value
159) cp TMP,GRAY ; compare with grayscale value
160) ror DATA ; store result as output bit
161) dec TMP2 ; next pixel
162) brne ROW_BW_WAIT_PIXEL
163) ; restore data pointer
164) subi XL,7 ; XH not there on ATtiny2313
165) ; output
166) lsr DATA ; ensure remaining bit stays high
167) ; (pull-up for unused pin)
168) com DATA
169) out COL_PORT,DATA
170) ; wait 5 + (GRAY - 1) * 64
171) mov TMP2,GRAY
172) rjmp ROW_BW_WAIT_LOOP_ENTRY
173) ROW_BW_WAIT_LOOP:
174) rcall WAIT61
175) ROW_BW_WAIT_LOOP_ENTRY:
176) dec TMP2
177) brne ROW_BW_WAIT_LOOP
178) ret
179)
180)
181)
182) ; turn off row (with same timing as ROW_BW_WAIT)
183) ; input: -
184) ; output: -
185) ; changes: TMP
186) ; cycles: 60 (including rcall and ret)
187) ROW_OFF:
188) ldi TMP,17
189) ROW_OFF_LOOP:
190) dec TMP
191) brne ROW_OFF_LOOP
192) ldi TMP,0x80 ; ensure remaining bit stays high
193) ; (pull-up for unused pin)
194) out COL_PORT,TMP
195) ret
196)
197)
198)
199) ; output row (grayscales)
200) ; input: X = ptr to pixel data (0..15)
201) ; output: -
202) ; changes: TMP, TMP2, DATA
203) ; cycles: 7822 (including rcall and ret)
204) ; time: 1ms
205) ROW_GRAY:
206) ldi GRAY,1
207) ROW_GRAY_LOOP:
208) rcall ROW_BW_WAIT
209) inc GRAY
210) cpi GRAY,16
211) brlo ROW_GRAY_LOOP
212) rcall ROW_OFF
213) ; done
214) ret
215)
216)
217)
218) ; output a frame
219) ; input: FRAME = pixel data (0..15)
220) ; output: -
221) ; changes: TMP, TMP2, CNT, DATA, X
222) ; time: 6ms
223) OUT_FRAME:
224) wdr
225) ldi XL,low(FRAME) ; ptr to pixel data
226) ; XH not there on ATtiny2313
227) ldi CNT,0x01 ; bitmask loop over rows
228) OUT_FRAME_LOOP:
229) mov TMP,CNT ; select row
230) com TMP
231) andi TMP,0x3F
232) ori TMP,0x40 ; ensure bit 6 stays high
233) ; (pull-up for switch input)
234) out ROW_PORT,TMP
235) rcall ROW_GRAY ; display row
236) subi XL,-7 ; ptr to next row
237) ; XH not there on ATtiny2313
238) lsl CNT ; bitmask loop over rows
239) cpi CNT,0x40
240) brne OUT_FRAME_LOOP
241) ; done
242) ret
243)
244)
245)
246) ; output a frame for some time
247) ; input: FRAME = pixel data (0..15)
248) ; TMP = time to show frame (1..255, in 6 ms steps)
249) ; output: -
250) ; changes: X, TMP, TMP2
251) ; time: TMP * 6 ms
252) OUT_FRAME_TIME:
253) ; output frame
254) push TMP
255) push CNT
256) push DATA
257) rcall OUT_FRAME ; 6 ms
258) pop DATA
259) pop CNT
260) pop TMP
261) ; loop
262) dec TMP
263) brne OUT_FRAME_TIME
264) ; done
265) ret
266)
267)
268)
269) ; clear frame
270) ; input: -
271) ; output: -
272) ; changes: X, FRAME, TMP
273) ; time: short
274) CLEAR:
275) ldi XL,low(FRAME) ; ptr to pixel data
276) ; XH not there on ATtiny2313
277) clr TMP
278) CLEAR_LOOP:
279) st X+,TMP ; clear pixel
280) cpi XL,low(FRAME)+42 ; bottom of loop
281) ; XH not there on ATtiny2313
282) brne CLEAR_LOOP
283) ; done
284) ret
285)
286)
287)
288) ; set frame to solid color
289) ; input: DATA = value (0..15)
290) ; output: -
291) ; changes: X, FRAME
292) ; time: short
293) SET_COLOR:
294) ldi XL,low(FRAME) ; ptr to pixel data
295) ; XH not there on ATtiny2313
296) SET_COLOR_LOOP:
297) st X+,DATA ; set pixel value
298) cpi XL,low(FRAME)+42 ; bottom of loop
299) ; XH not there on ATtiny2313
300) brne SET_COLOR_LOOP
301) ; done
302) ret
303)
304)
305)
306) ; set pixel
307) ; input: CNT = pixel number (0..41, nothing is done for 42..255)
308) ; DATA = value (0..15)
309) ; output: -
310) ; changes: X, FRAME, TMP
311) ; time: short
312) SET_PIXEL:
313) cpi CNT,42 ; invalid pixel number -> done
314) brsh SET_PIXEL_END
315) ldi XL,low(FRAME) ; ptr to pixel (base + offset)
316) add XL,CNT ; XH not there on ATtiny2313
317) st X,DATA ; set pixel
318) SET_PIXEL_END:
319) ; done
320) ret
321)
322)
323)
324) ; blink animation
325) ; input: -
326) ; output: -
327) ; changes: X, FRAME, CNT, DATA, TMP, TMP2
328) ANIM_BLINK:
329) ; off
330) ldi DATA,0 ; minimum color
331) rcall SET_COLOR ; paint
332) ldi TMP,100 ; show frame 600 ms
333) rcall OUT_FRAME_TIME
334) ; on
335) ldi DATA,15 ; maximum color
336) rcall SET_COLOR ; paint
337) ldi TMP,100 ; show frame 600 ms
338) rcall OUT_FRAME_TIME
339) ; done
340) ret
341)
342)
343)
344) ; fade up and down animation
345) ; input: -
346) ; output: -
347) ; changes: X, FRAME, CNT, DATA, TMP, TMP2
348) ANIM_FADE:
349) ; fade up
350) ldi DATA,0 ; start dark
351) ANIM_FADE_UP:
352) rcall SET_COLOR ; paint
353) ldi TMP,10 ; show frame 60 ms
354) rcall OUT_FRAME_TIME
355) inc DATA ; fade up
356) cpi DATA,15 ; loop until almost full on
357) brne ANIM_FADE_UP
358) ; fade down
359) ANIM_FADE_DOWN:
360) rcall SET_COLOR ; paint
361) ldi TMP,10 ; show frame 60 ms
362) rcall OUT_FRAME_TIME
363) dec DATA ; fade up
364) cpi DATA,255 ; loop until full off
365) brne ANIM_FADE_DOWN
366) ; done
367) ret
368)
369)
370)
|
movie compression, add anot...
Stefan Schuermans authored 5 years ago
|
439) rjmp ANIM_MOVIE_CODE_SHOW
440)
441) ; rle frame
442) ANIM_MOVIE_CODE_1:
443) ; save 12 bit value
444) push DATA
445) push CNT
446) ; extract frame to frame buffer
447) ldi XL,low(FRAME) ; ptr to pixel data
448) ; XH not there on ATtiny2313
449) ldi CNT,0 ; no pixel data yet
450) ANIM_MOVIE_CODE_FRAME_RLE_LOOP:
451) ; load new pixel data if none available
452) cpi CNT,0
453) brne ANIM_MOVIE_CODE_FRAME_RLE_DATA_OK
454) lpm DATA,Z+ ; get repeat count and pixel value
455) mov CNT,DATA
456) andi DATA,0x0F ; pixel value in DATA
457) swap CNT
458) andi CNT,0x0F ; repeat count in CNT
459) inc CNT ; use for repeat count + 1 pixels
460) ANIM_MOVIE_CODE_FRAME_RLE_DATA_OK:
461) ; write pixel data to frame
462) st X+,DATA
463) ; count down available pixel data
464) dec CNT
465) ; bottom of loop
466) cpi XL,low(FRAME)+42 ; XH not there on ATtiny2313
467) brlo ANIM_MOVIE_CODE_FRAME_RLE_LOOP
468) ; restore 12 bit value
469) pop CNT
470) pop DATA
471) ; show frame
472) rjmp ANIM_MOVIE_CODE_SHOW
473)
474) ; back reference
475) ANIM_MOVIE_CODE_2:
476) ; check if in nested call
477) cpi TMP2,0
478) brne ANIM_MOVIE_CODE_2_NESTED
479) ; save pointer to frame data
480) push ZL
481) push ZH
482) ; go back by 12 bit value in DATA:CNT
483) sub ZL,CNT
484) sbc ZH,DATA
485) ; recursive call
486) ldi TMP2,1 ; nested call
487) rcall ANIM_MOVIE_CODE
488) ; restore pointer to frame data
489) pop ZH
490) pop ZL
491) ; done
492) ldi TMP,0 ; continue
493) ret
494)
495) ; back reference - nested call
496) ANIM_MOVIE_CODE_2_NESTED:
497) ; go back by 12 bit value in DATA:CNT
498) sub ZL,CNT
499) sbc ZH,DATA
500) ; recursive tail call (no need to save Z on nested call)
501) ldi TMP2,1 ; nested call
502) rjmp ANIM_MOVIE_CODE
503)
504) ; show frame
505) ANIM_MOVIE_CODE_SHOW:
506) ; high part of frame time
507) cpi DATA,0
508) breq ANIM_MOVIE_CODE_SHOW_HIGH_DONE
509) ldi TMP,0 ; means 256 frames times
510) rcall OUT_FRAME_TIME
511) dec DATA
512) rjmp ANIM_MOVIE_CODE_SHOW
513) ANIM_MOVIE_CODE_SHOW_HIGH_DONE:
514) ; low part of frame time
515) cpi CNT,0
516) breq ANIM_MOVIE_CODE_SHOW_LOW_DONE
517) mov TMP,CNT
518) rcall OUT_FRAME_TIME
519) ANIM_MOVIE_CODE_SHOW_LOW_DONE:
520) ; done
521) ldi TMP,0 ; continue
522) ret
523)
524)
525)
526) ; play animation
527) ; input: Z = pointer to movie data
528) ; output: -
529) ; changes: X, Z, FRAME, CNT, DATA, TMP, TMP2
530) ANIM_MOVIE:
531) ; process code block
532) ldi TMP2,0 ; initial call
533) rcall ANIM_MOVIE_CODE
534) ; continue if not yet end
535) cpi TMP,0
536) breq ANIM_MOVIE
537) ; done
|
initial version of firmware
Stefan Schuermans authored 5 years ago
|
546) ; read mode from switch and (store animation number)
547) ; input: MODE = old mode, CNT = animation number
548) ; output: MODE = new mode
549) ; changes: TMP, DATA
550) MODE_READ:
551) ; read new mode (into DATA)
552) ldi DATA,MODE_ALL
553) sbic MODE_SW_PIN,MODE_SW_BIT
554) ldi DATA,MODE_SINGLE
555) ; mode was changed from all to single -> save animation number
556) cpi MODE,MODE_ALL ; old mode not all -> do nothing
557) brne MODE_READ_NOT_0_TO_1
558) cpi DATA,MODE_SINGLE ; new mode not single -> do nothing
559) brne MODE_READ_NOT_0_TO_1
560) sbic EECR,EEPE ; EEPROM write ongoing -> do nothing
561) rjmp MODE_READ_NOT_0_TO_1
562) ldi TMP,0<<EEPM1|0<<EEPM0 ; set EEPROM programming mode
563) out EECR,TMP
564) ldi TMP,0 ; set EEPROM address
565) out EEARL,TMP
566) mov TMP,CNT ; set EEPROM data to animation number
567) com TMP ; with NOTed number in upper nibble
568) swap TMP
569) andi TMP,0xF0
570) or TMP,CNT
571) out EEDR,TMP
572) sbi EECR,EEMPE ; begin writing EEPROM
573) sbi EECR,EEPE
574) MODE_READ_NOT_0_TO_1:
575) ; remember new mode (in MODE)
576) mov MODE,DATA
577) ; done
578) ret
579)
580)
581)
582) ; animation table: animation function, iteration count (<= 255)
583) ANIM_TAB:
|