author | Tero Marttila <terom@paivola.fi> |
Thu, 01 May 2014 23:44:42 +0300 | |
changeset 84 | 9ebf1a2cee3a |
parent 32 | 7ceb76b5a104 |
permissions | -rw-r--r-- |
18 | 1 |
;; vim: filetype=avr |
2 |
;; |
|
3 |
;; Timer unit control and use |
|
4 |
;; |
|
5 |
||
29 | 6 |
.equ TIMER_FLAGS = GPIOR0 |
7 |
||
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 |
|
18 | 16 |
|
17 |
; Clock Source |
|
29 | 18 |
.set TIMER0_CS = 0b101 ; 1/1024 |
18 | 19 |
|
29 | 20 |
;; Timer1 |
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 |
|
21
95549ce0e3da
timer: try and actually sleep
Tero Marttila <terom@fixme.fi>
parents:
18
diff
changeset
|
30 |
|
95549ce0e3da
timer: try and actually sleep
Tero Marttila <terom@fixme.fi>
parents:
18
diff
changeset
|
31 |
.set SLEEP_MODE = 0b000 ; Idle |
18 | 32 |
|
33 |
Timer_Init: |
|
29 | 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: |
|
18 | 51 |
; OC1A/B disconnected from output |
52 |
; No PWM mode |
|
29 | 53 |
poke [TCCR1A, r16, (0b00 << COM1A0) | (0b00 << COM1B0) | (TIMER1_WGML << WGM10)] |
18 | 54 |
|
55 |
; Clear |
|
56 |
poke [TCCR1B, r16, 0] |
|
57 |
poke [TCCR1C, r16, 0] |
|
58 |
||
29 | 59 |
; Enable compare interrupt |
18 | 60 |
poke [TIMSK1, r16, (1 << OCIE1A)] |
21
95549ce0e3da
timer: try and actually sleep
Tero Marttila <terom@fixme.fi>
parents:
18
diff
changeset
|
61 |
|
95549ce0e3da
timer: try and actually sleep
Tero Marttila <terom@fixme.fi>
parents:
18
diff
changeset
|
62 |
Sleep_init: |
95549ce0e3da
timer: try and actually sleep
Tero Marttila <terom@fixme.fi>
parents:
18
diff
changeset
|
63 |
; Select sleep mode |
95549ce0e3da
timer: try and actually sleep
Tero Marttila <terom@fixme.fi>
parents:
18
diff
changeset
|
64 |
; Enable `sleep` |
95549ce0e3da
timer: try and actually sleep
Tero Marttila <terom@fixme.fi>
parents:
18
diff
changeset
|
65 |
poke [SMCR, r16, (SLEEP_MODE << SM0) | (1 << SE)] |
95549ce0e3da
timer: try and actually sleep
Tero Marttila <terom@fixme.fi>
parents:
18
diff
changeset
|
66 |
|
95549ce0e3da
timer: try and actually sleep
Tero Marttila <terom@fixme.fi>
parents:
18
diff
changeset
|
67 |
; Disable ADC |
95549ce0e3da
timer: try and actually sleep
Tero Marttila <terom@fixme.fi>
parents:
18
diff
changeset
|
68 |
poke [SMCR, r16, (1 << PRTWI) | (1 << PRUSART0) | (1 << PRADC)] |
95549ce0e3da
timer: try and actually sleep
Tero Marttila <terom@fixme.fi>
parents:
18
diff
changeset
|
69 |
|
18 | 70 |
ret |
71 |
||
29 | 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: |
|
18 | 108 |
; Initialize timer |
109 |
poke [TCNT1H, r16, high(0)] |
|
110 |
poke [TCNT1L, r16, low(0)] |
|
111 |
||
112 |
; Set flag |
|
29 | 113 |
sbi TIMER_FLAGS, TIMER1_BUSY |
114 |
||
115 |
; Start |
|
18 | 116 |
; WGM |
117 |
; Clock Source |
|
29 | 118 |
poke [TCCR1B, r16, (TIMER1_WGMH << WGM12) | (TIMER1_CS << CS10)] |
18 | 119 |
|
120 |
ret |
|
121 |
||
29 | 122 |
Timer1_Stop: |
18 | 123 |
; WGM |
124 |
; Clock off |
|
29 | 125 |
poke [TCCR1B, r16, (TIMER1_WGMH << WGM12) | (0b00 << CS10)] |
18 | 126 |
|
127 |
; Clear flag |
|
29 | 128 |
cbi TIMER_FLAGS, TIMER1_BUSY |
18 | 129 |
|
130 |
ret |
|
131 |
||
29 | 132 |
;; Timer1 Compare A interrupt handler |
18 | 133 |
Timer_OC1A: |
134 |
in r0, SREG |
|
135 |
||
136 |
; Stop timer |
|
29 | 137 |
rcall Timer1_Stop |
18 | 138 |
|
139 |
out SREG, r0 |
|
140 |
reti |
|
141 |
||
32
7ceb76b5a104
semi-broken Timer_Update mechanism
Tero Marttila <terom@fixme.fi>
parents:
29
diff
changeset
|
142 |
;; Prime the timer and sleep for 1s |
7ceb76b5a104
semi-broken Timer_Update mechanism
Tero Marttila <terom@fixme.fi>
parents:
29
diff
changeset
|
143 |
Timer_Sleep_1s: |
7ceb76b5a104
semi-broken Timer_Update mechanism
Tero Marttila <terom@fixme.fi>
parents:
29
diff
changeset
|
144 |
; Initialize counter to 16k cycles |
7ceb76b5a104
semi-broken Timer_Update mechanism
Tero Marttila <terom@fixme.fi>
parents:
29
diff
changeset
|
145 |
ldi XH, high(16 * 1024) |
7ceb76b5a104
semi-broken Timer_Update mechanism
Tero Marttila <terom@fixme.fi>
parents:
29
diff
changeset
|
146 |
ldi XL, low(16 * 1024) |
7ceb76b5a104
semi-broken Timer_Update mechanism
Tero Marttila <terom@fixme.fi>
parents:
29
diff
changeset
|
147 |
|
7ceb76b5a104
semi-broken Timer_Update mechanism
Tero Marttila <terom@fixme.fi>
parents:
29
diff
changeset
|
148 |
;; Continue |
7ceb76b5a104
semi-broken Timer_Update mechanism
Tero Marttila <terom@fixme.fi>
parents:
29
diff
changeset
|
149 |
|
18 | 150 |
;; Count to X |
151 |
Timer_Sleep: |
|
152 |
; Set TOP |
|
153 |
sts OCR1AH, XH |
|
154 |
sts OCR1AL, XL |
|
155 |
||
156 |
; Start timer |
|
29 | 157 |
rcall Timer1_Start |
18 | 158 |
|
159 |
; Wait for timer to complete |
|
29 | 160 |
_timer1_sleep: |
21
95549ce0e3da
timer: try and actually sleep
Tero Marttila <terom@fixme.fi>
parents:
18
diff
changeset
|
161 |
sleep |
95549ce0e3da
timer: try and actually sleep
Tero Marttila <terom@fixme.fi>
parents:
18
diff
changeset
|
162 |
|
29 | 163 |
sbic TIMER_FLAGS, TIMER1_BUSY |
164 |
rjmp _timer1_sleep |
|
21
95549ce0e3da
timer: try and actually sleep
Tero Marttila <terom@fixme.fi>
parents:
18
diff
changeset
|
165 |
|
18 | 166 |
; Done |
167 |
ret |
|
168 |
||
32
7ceb76b5a104
semi-broken Timer_Update mechanism
Tero Marttila <terom@fixme.fi>
parents:
29
diff
changeset
|
169 |
;; Update timer for given timeout |
7ceb76b5a104
semi-broken Timer_Update mechanism
Tero Marttila <terom@fixme.fi>
parents:
29
diff
changeset
|
170 |
Timer_Update: |
7ceb76b5a104
semi-broken Timer_Update mechanism
Tero Marttila <terom@fixme.fi>
parents:
29
diff
changeset
|
171 |
; Set TOP |
7ceb76b5a104
semi-broken Timer_Update mechanism
Tero Marttila <terom@fixme.fi>
parents:
29
diff
changeset
|
172 |
sts OCR1AH, XH |
7ceb76b5a104
semi-broken Timer_Update mechanism
Tero Marttila <terom@fixme.fi>
parents:
29
diff
changeset
|
173 |
sts OCR1AL, XL |
7ceb76b5a104
semi-broken Timer_Update mechanism
Tero Marttila <terom@fixme.fi>
parents:
29
diff
changeset
|
174 |
|
7ceb76b5a104
semi-broken Timer_Update mechanism
Tero Marttila <terom@fixme.fi>
parents:
29
diff
changeset
|
175 |
; Check timer |
7ceb76b5a104
semi-broken Timer_Update mechanism
Tero Marttila <terom@fixme.fi>
parents:
29
diff
changeset
|
176 |
lds YL, TCNT1L |
7ceb76b5a104
semi-broken Timer_Update mechanism
Tero Marttila <terom@fixme.fi>
parents:
29
diff
changeset
|
177 |
lds YH, TCNT1H |
7ceb76b5a104
semi-broken Timer_Update mechanism
Tero Marttila <terom@fixme.fi>
parents:
29
diff
changeset
|
178 |
|
7ceb76b5a104
semi-broken Timer_Update mechanism
Tero Marttila <terom@fixme.fi>
parents:
29
diff
changeset
|
179 |
cp YL, XL |
7ceb76b5a104
semi-broken Timer_Update mechanism
Tero Marttila <terom@fixme.fi>
parents:
29
diff
changeset
|
180 |
cpc YH, XH |
18 | 181 |
|
32
7ceb76b5a104
semi-broken Timer_Update mechanism
Tero Marttila <terom@fixme.fi>
parents:
29
diff
changeset
|
182 |
brlo timer_up_out |
18 | 183 |
|
32
7ceb76b5a104
semi-broken Timer_Update mechanism
Tero Marttila <terom@fixme.fi>
parents:
29
diff
changeset
|
184 |
; Update |
7ceb76b5a104
semi-broken Timer_Update mechanism
Tero Marttila <terom@fixme.fi>
parents:
29
diff
changeset
|
185 |
; XXX: figure out a better way to do this... |
7ceb76b5a104
semi-broken Timer_Update mechanism
Tero Marttila <terom@fixme.fi>
parents:
29
diff
changeset
|
186 |
ldi r16, 0 |
7ceb76b5a104
semi-broken Timer_Update mechanism
Tero Marttila <terom@fixme.fi>
parents:
29
diff
changeset
|
187 |
subi XL, 2 |
7ceb76b5a104
semi-broken Timer_Update mechanism
Tero Marttila <terom@fixme.fi>
parents:
29
diff
changeset
|
188 |
sbc XH, r16 |
7ceb76b5a104
semi-broken Timer_Update mechanism
Tero Marttila <terom@fixme.fi>
parents:
29
diff
changeset
|
189 |
|
7ceb76b5a104
semi-broken Timer_Update mechanism
Tero Marttila <terom@fixme.fi>
parents:
29
diff
changeset
|
190 |
sts TCNT1L, XL |
7ceb76b5a104
semi-broken Timer_Update mechanism
Tero Marttila <terom@fixme.fi>
parents:
29
diff
changeset
|
191 |
sts TCNT1H, XH |
7ceb76b5a104
semi-broken Timer_Update mechanism
Tero Marttila <terom@fixme.fi>
parents:
29
diff
changeset
|
192 |
|
7ceb76b5a104
semi-broken Timer_Update mechanism
Tero Marttila <terom@fixme.fi>
parents:
29
diff
changeset
|
193 |
timer_up_out: |
7ceb76b5a104
semi-broken Timer_Update mechanism
Tero Marttila <terom@fixme.fi>
parents:
29
diff
changeset
|
194 |
; Done |
7ceb76b5a104
semi-broken Timer_Update mechanism
Tero Marttila <terom@fixme.fi>
parents:
29
diff
changeset
|
195 |
ret |
7ceb76b5a104
semi-broken Timer_Update mechanism
Tero Marttila <terom@fixme.fi>
parents:
29
diff
changeset
|
196 |