1 ;; vim: filetype=avr |
1 ;; vim: filetype=avr |
2 ;; |
2 ;; |
3 ;; Timer unit control and use |
3 ;; Timer unit control and use |
4 ;; |
4 ;; |
5 |
5 |
6 ; Waveform Generation Mode (nibble low/high) |
6 .equ TIMER_FLAGS = GPIOR0 |
7 .set TIMER_WGML = 0b00 |
7 |
8 .set TIMER_WGMH = 0b01 |
8 ;; Timer0 |
|
9 ; Compare output mode |
|
10 .set TIMER0_COMA = 0b00 ; null |
|
11 .set TIMER0_COMB = 0b00 ; null |
|
12 |
|
13 ; Waveform Generation Mode (triplet low/high) |
|
14 .set TIMER0_WGML = 0b10 ; CTC |
|
15 .set TIMER0_WGMH = 0b0 ; CTC |
9 |
16 |
10 ; Clock Source |
17 ; Clock Source |
11 .set TIMER_CS = 0b101 |
18 .set TIMER0_CS = 0b101 ; 1/1024 |
12 |
19 |
13 .equ TIMER_FLAGS = GPIOR0 |
20 ;; Timer1 |
14 .equ TIMER_BUSY = 1 |
21 ; Waveform Generation Mode (nibble low/high) |
|
22 .set TIMER1_WGML = 0b00 ; CTC |
|
23 .set TIMER1_WGMH = 0b01 ; CTC |
|
24 |
|
25 ; Clock Source |
|
26 .set TIMER1_CS = 0b101 ; 1/1024 |
|
27 |
|
28 ; Flags |
|
29 .equ TIMER1_BUSY = 1 |
15 |
30 |
16 .set SLEEP_MODE = 0b000 ; Idle |
31 .set SLEEP_MODE = 0b000 ; Idle |
17 |
32 |
18 Timer_Init: |
33 Timer_Init: |
|
34 Timer0_Init: |
|
35 ; OC0A/B disconnected from output |
|
36 ; No PWM mode |
|
37 ldi r16, (TIMER0_COMA << COM0A0) | (TIMER0_COMB << COM0B0) | (TIMER0_WGML << WGM00) |
|
38 out TCCR0A, r16 |
|
39 |
|
40 ; Clear |
|
41 ldi r16, 0 |
|
42 out OCR0A, r16 |
|
43 out OCR0B, r16 |
|
44 out TCCR0B, r16 |
|
45 |
|
46 ; Enable compare interrupt |
|
47 ldi r16, (1 << OCIE0A) |
|
48 sts TIMSK0, r16 |
|
49 |
|
50 Timer1_Init: |
19 ; OC1A/B disconnected from output |
51 ; OC1A/B disconnected from output |
20 ; No PWM mode |
52 ; No PWM mode |
21 poke [TCCR1A, r16, (0b00 << COM1A0) | (0b00 << COM1B0) | (TIMER_WGML << WGM10)] |
53 poke [TCCR1A, r16, (0b00 << COM1A0) | (0b00 << COM1B0) | (TIMER1_WGML << WGM10)] |
22 |
54 |
23 ; Clear |
55 ; Clear |
24 poke [TCCR1B, r16, 0] |
56 poke [TCCR1B, r16, 0] |
25 poke [TCCR1C, r16, 0] |
57 poke [TCCR1C, r16, 0] |
26 |
58 |
27 ; Enable timer overflow interrupt |
59 ; Enable compare interrupt |
28 poke [TIMSK1, r16, (1 << OCIE1A)] |
60 poke [TIMSK1, r16, (1 << OCIE1A)] |
29 |
61 |
30 Sleep_init: |
62 Sleep_init: |
31 ; Select sleep mode |
63 ; Select sleep mode |
32 ; Enable `sleep` |
64 ; Enable `sleep` |
35 ; Disable ADC |
67 ; Disable ADC |
36 poke [SMCR, r16, (1 << PRTWI) | (1 << PRUSART0) | (1 << PRADC)] |
68 poke [SMCR, r16, (1 << PRTWI) | (1 << PRUSART0) | (1 << PRADC)] |
37 |
69 |
38 ret |
70 ret |
39 |
71 |
40 Timer_Start: |
72 ;; Timer0 is recurring; this starts it running, and it keeps hitting OC0A periodically |
|
73 ;; Input: r16 (period, in 1k-cycles) |
|
74 Timer0_Start: |
|
75 ; Initialize timer |
|
76 ; set CTC trigger from r16 |
|
77 out OCR0A, r16 |
|
78 |
|
79 ; clear counter |
|
80 ldi r16, 0 |
|
81 out TCNT0, r16 |
|
82 |
|
83 ; Start |
|
84 ; WGM |
|
85 ; Clock Source |
|
86 ldi r16, (TIMER0_WGMH << WGM02) | (TIMER0_CS << CS00) |
|
87 out TCCR0B, r16 |
|
88 |
|
89 ret |
|
90 |
|
91 Timer0_Read8: |
|
92 in r16, TCNT0 |
|
93 |
|
94 ret |
|
95 |
|
96 ;; Timer0 Compare A interrupt handler |
|
97 Timer_OC0A: |
|
98 in r0, SREG |
|
99 |
|
100 ; Run callback |
|
101 rcall TIMER0_CB_A |
|
102 |
|
103 out SREG, r0 |
|
104 reti |
|
105 |
|
106 ;; Timer1 is one-shot; this starts it running, and it is then stopped once it hits OC1A |
|
107 Timer1_Start: |
41 ; Initialize timer |
108 ; Initialize timer |
42 poke [TCNT1H, r16, high(0)] |
109 poke [TCNT1H, r16, high(0)] |
43 poke [TCNT1L, r16, low(0)] |
110 poke [TCNT1L, r16, low(0)] |
44 |
111 |
45 ; Set flag |
112 ; Set flag |
46 sbi TIMER_FLAGS, TIMER_BUSY |
113 sbi TIMER_FLAGS, TIMER1_BUSY |
47 |
114 |
|
115 ; Start |
48 ; WGM |
116 ; WGM |
49 ; Clock Source |
117 ; Clock Source |
50 poke [TCCR1B, r16, (TIMER_WGMH << WGM12) | (TIMER_CS << CS10)] |
118 poke [TCCR1B, r16, (TIMER1_WGMH << WGM12) | (TIMER1_CS << CS10)] |
51 |
119 |
52 ret |
120 ret |
53 |
121 |
54 Timer_Stop: |
122 Timer1_Stop: |
55 ; WGM |
123 ; WGM |
56 ; Clock off |
124 ; Clock off |
57 poke [TCCR1B, r16, (TIMER_WGMH << WGM12) | (0b00 << CS10)] |
125 poke [TCCR1B, r16, (TIMER1_WGMH << WGM12) | (0b00 << CS10)] |
58 |
126 |
59 ; Clear flag |
127 ; Clear flag |
60 cbi TIMER_FLAGS, TIMER_BUSY |
128 cbi TIMER_FLAGS, TIMER1_BUSY |
61 |
129 |
62 ret |
130 ret |
63 |
131 |
64 ;; Timer Compare 1A interrupt handler |
132 ;; Timer1 Compare A interrupt handler |
65 Timer_OC1A: |
133 Timer_OC1A: |
66 in r0, SREG |
134 in r0, SREG |
67 |
135 |
68 ; Stop timer |
136 ; Stop timer |
69 rcall Timer_Stop |
137 rcall Timer1_Stop |
70 |
138 |
71 out SREG, r0 |
139 out SREG, r0 |
72 reti |
140 reti |
73 |
141 |
74 ;; Count to X |
142 ;; Count to X |