1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
|
.include "m16def.inc"
#ifndef F_CPU
# error The LEDs are timing sensitive. F_CPU required.
#elif F_CPU < 4000000
# error The LEDs are timing sensitive. CPU Frequency must be at least 4MHz
#elif F_CPU == 4000000
// 4MHz
#define nop_short
#define nop_long nop $ nop
#elif F_CPU == 8000000
// 8MHz
#define nop_short nop
#define nop_long nop $ nop $ nop $ nop $ nop
#elif F_CPU == 16000000
// 16MHz
#define nop_short nop $ nop $ nop
#define nop_long nop $ nop $ nop $ nop $ nop $ nop $ nop $ nop $ nop $ nop $ nop
#else
# error Missing nop definitions for your CPU frequency.
#endif
.global led_write_rgb
.type led_write_rgb, @function
; void (uint16_t port, char pins, char r, char g, char b);
;
; Args:
; port: r25, r24
; pins: r22
; b: r20
; g: r19
; r: r18
;
; destroys: r19
;
; The leds expect the data in G-R-B order
led_write_rgb:
clr r0
dec r0
call L_led_write_byte
mov r19, r18
call L_led_write_byte
mov r19, r20
call L_led_write_byte
ret
; Args:
; port: X -- curently ignored, hadcoded to PORTD
; pins: r22 -- currently ignored, hardcoded to 0xFF
; byte: r19 (!)
;
; Prerequisites:
; r0 must be 0xFF
;
; destroys: r21 -- will be 0 afterwards
; destroys: r19 -- call rol on it once to restore
L_led_write_byte:
ldi r21, 8
L_led_write_byte__loop_head:
rol r19
brcc L_led_write_byte__zero
L_led_write_byte__one:
out PORTD, r0
nop_long
out PORTD, r1
nop_short
rjmp L_led_write_byte__loop_ctrl
L_led_write_byte__zero:
out PORTD, r0
nop_short
out PORTD, r1
nop_long
L_led_write_byte__loop_ctrl:
; loop ctrl
dec r21
brne L_led_write_byte__loop_head
L_led_write_byte__out:
ret
|