4 Handles the 8 bits and 16 bits AVR timer.
9 Copyright 2008, 2009 Michel Pollet <buserror@gmail.com>
11 This file is part of simavr.
13 simavr is free software: you can redistribute it and/or modify
14 it under the terms of the GNU General Public License as published by
15 the Free Software Foundation, either version 3 of the License, or
16 (at your option) any later version.
18 simavr is distributed in the hope that it will be useful,
19 but WITHOUT ANY WARRANTY; without even the implied warranty of
20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 GNU General Public License for more details.
23 You should have received a copy of the GNU General Public License
24 along with simavr. If not, see <http://www.gnu.org/licenses/>.
28 #include "avr_timer.h"
32 * The timers are /always/ 16 bits here, if the higher byte register
33 * is specified it's just added.
35 static uint16_t _timer_get_ocra(avr_timer_t * p)
37 return p->io.avr->data[p->r_ocra] |
38 (p->r_ocrah ? (p->io.avr->data[p->r_ocrah] << 8) : 0);
40 static uint16_t _timer_get_ocrb(avr_timer_t * p)
42 return p->io.avr->data[p->r_ocrb] |
43 (p->r_ocrbh ? (p->io.avr->data[p->r_ocrbh] << 8) : 0);
45 static uint16_t _timer_get_tcnt(avr_timer_t * p)
47 return p->io.avr->data[p->r_tcnt] |
48 (p->r_tcnth ? (p->io.avr->data[p->r_tcnth] << 8) : 0);
50 static uint16_t _timer_get_icr(avr_timer_t * p)
52 return p->io.avr->data[p->r_icr] |
53 (p->r_tcnth ? (p->io.avr->data[p->r_icrh] << 8) : 0);
56 static avr_cycle_count_t avr_timer_compa(struct avr_t * avr, avr_cycle_count_t when, void * param)
58 avr_timer_t * p = (avr_timer_t *)param;
59 avr_raise_interrupt(avr, &p->compa);
60 return p->tov_cycles ? 0 : p->compa_cycles ? when + p->compa_cycles : 0;
63 static avr_cycle_count_t avr_timer_compb(struct avr_t * avr, avr_cycle_count_t when, void * param)
65 avr_timer_t * p = (avr_timer_t *)param;
66 avr_raise_interrupt(avr, &p->compb);
67 return p->tov_cycles ? 0 : p->compb_cycles ? when + p->compb_cycles : 0;
70 static avr_cycle_count_t avr_timer_tov(struct avr_t * avr, avr_cycle_count_t when, void * param)
72 avr_timer_t * p = (avr_timer_t *)param;
73 int start = p->tov_base == 0;
76 avr_raise_interrupt(avr, &p->overflow);
79 if (p->compa_cycles) {
80 if (p->compa_cycles < p->tov_cycles)
81 avr_cycle_timer_register(avr,
82 p->compa_cycles - (avr->cycle - p->tov_base),
84 else if (p->tov_cycles == p->compa_cycles && !start)
85 avr_timer_compa(avr, when, param);
88 if (p->compb_cycles) {
89 if (p->compb_cycles < p->tov_cycles)
90 avr_cycle_timer_register(avr,
91 p->compb_cycles - (avr->cycle - p->tov_base),
93 else if (p->tov_cycles == p->compb_cycles && !start)
94 avr_timer_compb(avr, when, param);
97 return when + p->tov_cycles;
101 static uint8_t avr_timer_tcnt_read(struct avr_t * avr, avr_io_addr_t addr, void * param)
103 avr_timer_t * p = (avr_timer_t *)param;
104 // made to trigger potential watchpoints
107 uint64_t when = avr->cycle - p->tov_base;
109 uint16_t tcnt = (when * p->tov_top) / p->tov_cycles;
110 // printf("%s-%c when = %d tcnt = %d/%d\n", __FUNCTION__, p->name, (uint32_t)when, tcnt, p->tov_top);
112 avr->data[p->r_tcnt] = tcnt;
114 avr->data[p->r_tcnth] = tcnt >> 8;
117 return avr_core_watch_read(avr, addr);
120 static void avr_timer_tcnt_write(struct avr_t * avr, avr_io_addr_t addr, uint8_t v, void * param)
122 avr_timer_t * p = (avr_timer_t *)param;
123 avr_core_watch_write(avr, addr, v);
124 uint16_t tcnt = _timer_get_tcnt(p);
129 if (tcnt >= p->tov_top)
132 // this involves some magicking
133 // cancel the current timers, recalculate the "base" we should be at, reset the
134 // timer base as it should, and re-shedule the timers using that base.
136 avr_cycle_timer_cancel(avr, avr_timer_tov, p);
137 avr_cycle_timer_cancel(avr, avr_timer_compa, p);
138 avr_cycle_timer_cancel(avr, avr_timer_compb, p);
140 uint64_t cycles = (tcnt * p->tov_cycles) / p->tov_top;
142 // printf("%s-%c %d/%d -- cycles %d/%d\n", __FUNCTION__, p->name, tcnt, p->tov_top, (uint32_t)cycles, (uint32_t)p->tov_cycles);
144 // this reset the timers bases to the new base
146 avr_cycle_timer_register(avr, p->tov_cycles - cycles, avr_timer_tov, p);
147 avr_timer_tov(avr, avr->cycle - cycles, p);
149 // tcnt = ((avr->cycle - p->tov_base) * p->tov_top) / p->tov_cycles;
150 // printf("%s-%c new tnt derive to %d\n", __FUNCTION__, p->name, tcnt);
153 static void avr_timer_configure(avr_timer_t * p, uint32_t clock, uint32_t top)
155 uint32_t ocra = _timer_get_ocra(p);
156 uint32_t ocrb = _timer_get_ocrb(p);
157 float fa = clock / (float)(ocra+1), fb = clock / (float)(ocrb+1);
158 float t = clock / (float)(top+1);
159 float frequency = p->io.avr->frequency;
161 p->compa_cycles = p->compb_cycles = p->tov_cycles = 0;
164 printf("%s-%c clock %d top %d a %d b %d\n", __FUNCTION__, p->name, clock, top, ocra, ocrb);
165 p->tov_cycles = frequency / t; // avr_hz_to_cycles(frequency, t);
166 printf("%s-%c TOP %.2fHz = %d cycles\n", __FUNCTION__, p->name, t, (int)p->tov_cycles);
168 if (ocra && ocra <= top) {
169 p->compa_cycles = frequency / fa; // avr_hz_to_cycles(p->io.avr, fa);
170 printf("%s-%c A %.2fHz = %d cycles\n", __FUNCTION__, p->name, fa, (int)p->compa_cycles);
172 if (ocrb && ocrb <= top) {
173 p->compb_cycles = frequency / fb; // avr_hz_to_cycles(p->io.avr, fb);
174 printf("%s-%c B %.2fHz = %d cycles\n", __FUNCTION__, p->name, fb, (int)p->compb_cycles);
177 if (p->tov_cycles > 1) {
178 avr_cycle_timer_register(p->io.avr, p->tov_cycles, avr_timer_tov, p);
179 // calling it once, with when == 0 tells it to arm the A/B timers if needed
181 avr_timer_tov(p->io.avr, p->io.avr->cycle, p);
185 static void avr_timer_reconfigure(avr_timer_t * p)
187 avr_t * avr = p->io.avr;
189 avr_timer_wgm_t zero={0};
196 avr_cycle_timer_cancel(avr, avr_timer_tov, p);
197 avr_cycle_timer_cancel(avr, avr_timer_compa, p);
198 avr_cycle_timer_cancel(avr, avr_timer_compb, p);
200 long clock = avr->frequency;
202 // only can exists on "asynchronous" 8 bits timers
203 if (avr_regbit_get(avr, p->as2))
206 uint8_t cs = avr_regbit_get_array(avr, p->cs, ARRAY_SIZE(p->cs));
208 printf("%s-%c clock turned off\n", __FUNCTION__, p->name);
212 uint8_t mode = avr_regbit_get_array(avr, p->wgm, ARRAY_SIZE(p->wgm));
213 uint8_t cs_div = p->cs_div[cs];
214 uint32_t f = clock >> cs_div;
216 p->mode = p->wgm_op[mode];
217 //printf("%s-%c clock %d, div %d(/%d) = %d ; mode %d\n", __FUNCTION__, p->name, clock, cs, 1 << cs_div, f, mode);
218 switch (p->mode.kind) {
219 case avr_timer_wgm_normal:
220 avr_timer_configure(p, f, (1 << p->mode.size) - 1);
222 case avr_timer_wgm_ctc: {
223 avr_timer_configure(p, f, _timer_get_ocra(p));
225 case avr_timer_wgm_pwm: {
226 uint16_t top = p->mode.top == avr_timer_wgm_reg_ocra ? _timer_get_ocra(p) : _timer_get_icr(p);
227 avr_timer_configure(p, f, top);
229 case avr_timer_wgm_fast_pwm:
230 // avr_timer_configure(p, f, (1 << p->mode.size) - 1);
233 printf("%s-%c unsupported timer mode wgm=%d (%d)\n", __FUNCTION__, p->name, mode, p->mode.kind);
237 static void avr_timer_write_ocr(struct avr_t * avr, avr_io_addr_t addr, uint8_t v, void * param)
239 avr_timer_t * p = (avr_timer_t *)param;
240 avr_core_watch_write(avr, addr, v);
241 switch (p->mode.kind) {
242 case avr_timer_wgm_pwm:
243 if (p->mode.top != avr_timer_wgm_reg_ocra) {
244 avr_raise_irq(p->io.irq + TIMER_IRQ_OUT_PWM0, _timer_get_ocra(p));
245 avr_raise_irq(p->io.irq + TIMER_IRQ_OUT_PWM1, _timer_get_ocrb(p));
248 case avr_timer_wgm_fast_pwm:
249 avr_raise_irq(p->io.irq + TIMER_IRQ_OUT_PWM0, _timer_get_ocra(p));
250 avr_raise_irq(p->io.irq + TIMER_IRQ_OUT_PWM1, _timer_get_ocrb(p));
253 printf("%s-%c mode %d\n", __FUNCTION__, p->name, p->mode.kind);
254 avr_timer_reconfigure(p);
259 static void avr_timer_write(struct avr_t * avr, avr_io_addr_t addr, uint8_t v, void * param)
261 avr_timer_t * p = (avr_timer_t *)param;
262 avr_core_watch_write(avr, addr, v);
263 avr_timer_reconfigure(p);
266 static void avr_timer_reset(avr_io_t * port)
268 avr_timer_t * p = (avr_timer_t *)port;
269 avr_cycle_timer_cancel(p->io.avr, avr_timer_tov, p);
270 avr_cycle_timer_cancel(p->io.avr, avr_timer_compa, p);
271 avr_cycle_timer_cancel(p->io.avr, avr_timer_compb, p);
276 static avr_io_t _io = {
278 .reset = avr_timer_reset,
281 void avr_timer_init(avr_t * avr, avr_timer_t * p)
284 //printf("%s timer%c created\n", __FUNCTION__, p->name);
286 // allocate this module's IRQ
287 p->io.irq_count = TIMER_IRQ_COUNT;
288 p->io.irq = avr_alloc_irq(0, p->io.irq_count);
289 p->io.irq_ioctl_get = AVR_IOCTL_TIMER_GETIRQ(p->name);
290 p->io.irq[TIMER_IRQ_OUT_PWM0].flags |= IRQ_FLAG_FILTERED;
291 p->io.irq[TIMER_IRQ_OUT_PWM1].flags |= IRQ_FLAG_FILTERED;
293 avr_register_io(avr, &p->io);
294 avr_register_vector(avr, &p->compa);
295 avr_register_vector(avr, &p->compb);
296 avr_register_vector(avr, &p->overflow);
297 avr_register_vector(avr, &p->icr);
299 avr_register_io_write(avr, p->cs[0].reg, avr_timer_write, p);
302 * Even if the timer is 16 bits, we don't care to have watches on the
303 * high bytes because the datasheet says that the low address is always
306 avr_register_io_write(avr, p->r_ocra, avr_timer_write_ocr, p);
307 if (p->r_ocrb) // not all timers have B register
308 avr_register_io_write(avr, p->r_ocrb, avr_timer_write, p);
309 if(p->r_ocrc) // but some have a C one
310 avr_register_io_write(avr, p->r_ocrc, avr_timer_write, p);
311 avr_register_io_write(avr, p->r_tcnt, avr_timer_tcnt_write, p);
313 avr_register_io_read(avr, p->r_tcnt, avr_timer_tcnt_read, p);