timer: Fixed an off by one
[simavr] / simavr / sim / avr_timer.c
1 /*
2         avr_timer.c
3
4         Handles the 8 bits and 16 bits AVR timer.
5         Handles
6         + CDC
7         + Fast PWM
8
9         Copyright 2008, 2009 Michel Pollet <buserror@gmail.com>
10
11         This file is part of simavr.
12
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.
17
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.
22
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/>.
25  */
26
27 #include <stdio.h>
28 #include "avr_timer.h"
29 #include "avr_ioport.h"
30
31 /*
32  * The timers are /always/ 16 bits here, if the higher byte register
33  * is specified it's just added.
34  */
35 static uint16_t _timer_get_ocr(avr_timer_t * p, int compi)
36 {
37         return p->io.avr->data[p->comp[compi].r_ocr] |
38                       (p->comp[compi].r_ocrh ? (p->io.avr->data[p->comp[compi].r_ocrh] << 8) : 0);
39 }
40 static uint16_t _timer_get_tcnt(avr_timer_t * p)
41 {
42         return p->io.avr->data[p->r_tcnt] |
43                                 (p->r_tcnth ? (p->io.avr->data[p->r_tcnth] << 8) : 0);
44 }
45 static uint16_t _timer_get_icr(avr_timer_t * p)
46 {
47         return p->io.avr->data[p->r_icr] |
48                                 (p->r_tcnth ? (p->io.avr->data[p->r_icrh] << 8) : 0);
49 }
50 static avr_cycle_count_t avr_timer_comp(avr_timer_t *p, avr_cycle_count_t when, uint8_t comp)
51 {
52         avr_t * avr = p->io.avr;
53         avr_raise_interrupt(avr, &p->comp[comp].interrupt);
54
55         // check output compare mode and set/clear pins
56         uint8_t mode = avr_regbit_get(avr, p->comp[comp].com);
57         avr_irq_t * irq = &p->io.irq[TIMER_IRQ_OUT_COMP + comp];
58
59         switch (mode) {
60                 case avr_timer_com_normal: // Normal mode OCnA disconnected
61                         break;
62                 case avr_timer_com_toggle: // Toggle OCnA on compare match
63                         if (p->comp[comp].com_pin.reg)  // we got a physical pin
64                                 avr_raise_irq(irq,
65                                                 0x100 + (avr_regbit_get(avr, p->comp[comp].com_pin) ? 0 : 1));
66                         else // no pin, toggle the IRQ anyway
67                                 avr_raise_irq(irq,
68                                                 p->io.irq[TIMER_IRQ_OUT_COMP + comp].value ? 0 : 1);
69                         break;
70                 case avr_timer_com_clear:
71                         avr_raise_irq(irq, 0);
72                         break;
73                 case avr_timer_com_set:
74                         avr_raise_irq(irq, 1);
75                         break;
76         }
77
78         return p->tov_cycles ? 0 : p->comp[comp].comp_cycles ? when
79                 + p->comp[comp].comp_cycles : 0;
80 }
81
82 static avr_cycle_count_t avr_timer_compa(struct avr_t * avr, avr_cycle_count_t when, void * param)
83 {
84         return avr_timer_comp((avr_timer_t*)param, when, AVR_TIMER_COMPA);
85 }
86
87 static avr_cycle_count_t avr_timer_compb(struct avr_t * avr, avr_cycle_count_t when, void * param)
88 {
89         return avr_timer_comp((avr_timer_t*)param, when, AVR_TIMER_COMPB);
90 }
91
92 static avr_cycle_count_t avr_timer_compc(struct avr_t * avr, avr_cycle_count_t when, void * param)
93 {
94         return avr_timer_comp((avr_timer_t*)param, when, AVR_TIMER_COMPC);
95 }
96
97 static avr_cycle_count_t avr_timer_tov(struct avr_t * avr, avr_cycle_count_t when, void * param)
98 {
99         avr_timer_t * p = (avr_timer_t *)param;
100         int start = p->tov_base == 0;
101
102         if (!start)
103                 avr_raise_interrupt(avr, &p->overflow);
104         p->tov_base = when;
105
106         static const avr_cycle_timer_t dispatch[AVR_TIMER_COMP_COUNT] =
107                 { avr_timer_compa, avr_timer_compb, avr_timer_compc };
108
109         for (int compi = 0; compi < AVR_TIMER_COMP_COUNT; compi++) {
110                 if (p->comp[compi].comp_cycles) {
111                         if (p->comp[compi].comp_cycles < p->tov_cycles)
112                                 avr_cycle_timer_register(avr,
113                                         p->comp[compi].comp_cycles,
114                                         dispatch[compi], p);
115                         else if (p->tov_cycles == p->comp[compi].comp_cycles && !start)
116                                 dispatch[compi](avr, when, param);
117                 }
118         }
119
120         return when + p->tov_cycles;
121 }
122
123
124 static uint8_t avr_timer_tcnt_read(struct avr_t * avr, avr_io_addr_t addr, void * param)
125 {
126         avr_timer_t * p = (avr_timer_t *)param;
127         // made to trigger potential watchpoints
128
129         if (p->tov_cycles) {
130                 uint64_t when = avr->cycle - p->tov_base;
131
132                 uint16_t tcnt = (when * p->tov_top) / p->tov_cycles;
133         //      printf("%s-%c when = %d tcnt = %d/%d\n", __FUNCTION__, p->name, (uint32_t)when, tcnt, p->tov_top);
134
135                 avr->data[p->r_tcnt] = tcnt;
136                 if (p->r_tcnth)
137                         avr->data[p->r_tcnth] = tcnt >> 8;
138         }
139         
140         return avr_core_watch_read(avr, addr);
141 }
142
143 static void avr_timer_tcnt_write(struct avr_t * avr, avr_io_addr_t addr, uint8_t v, void * param)
144 {
145         avr_timer_t * p = (avr_timer_t *)param;
146         avr_core_watch_write(avr, addr, v);
147         uint16_t tcnt = _timer_get_tcnt(p);
148
149         if (!p->tov_top)
150                 return;
151                 
152         if (tcnt >= p->tov_top)
153                 tcnt = 0;
154         
155         // this involves some magicking
156         // cancel the current timers, recalculate the "base" we should be at, reset the
157         // timer base as it should, and re-shedule the timers using that base.
158         
159         avr_cycle_timer_cancel(avr, avr_timer_tov, p);
160         avr_cycle_timer_cancel(avr, avr_timer_compa, p);
161         avr_cycle_timer_cancel(avr, avr_timer_compb, p);
162         avr_cycle_timer_cancel(avr, avr_timer_compc, p);
163
164         uint64_t cycles = (tcnt * p->tov_cycles) / p->tov_top;
165
166 //      printf("%s-%c %d/%d -- cycles %d/%d\n", __FUNCTION__, p->name, tcnt, p->tov_top, (uint32_t)cycles, (uint32_t)p->tov_cycles);
167
168         // this reset the timers bases to the new base
169         p->tov_base = 0;
170         avr_cycle_timer_register(avr, p->tov_cycles - cycles, avr_timer_tov, p);
171         avr_timer_tov(avr, avr->cycle - cycles, p);
172
173 //      tcnt = ((avr->cycle - p->tov_base) * p->tov_top) / p->tov_cycles;
174 //      printf("%s-%c new tnt derive to %d\n", __FUNCTION__, p->name, tcnt);    
175 }
176
177 static void avr_timer_configure(avr_timer_t * p, uint32_t clock, uint32_t top)
178 {
179         float t = clock / (float)(top+1);
180         float frequency = p->io.avr->frequency;
181
182         p->tov_cycles = 0;
183         p->tov_top = top;
184
185         p->tov_cycles = frequency / t; // avr_hz_to_cycles(frequency, t);
186         printf("%s-%c TOP %.2fHz = %d cycles\n", __FUNCTION__, p->name, t, (int)p->tov_cycles);
187
188         for (int compi = 0; compi < AVR_TIMER_COMP_COUNT; compi++) {
189                 uint32_t ocr = _timer_get_ocr(p, compi);
190                 float fc = clock / (float)(ocr+1);
191
192                 p->comp[compi].comp_cycles = 0;
193 //              printf("%s-%c clock %d top %d OCR%c %d\n", __FUNCTION__, p->name, clock, top, 'A'+compi, ocr);
194
195                 if (ocr && ocr <= top) {
196                         p->comp[compi].comp_cycles = frequency / fc; // avr_hz_to_cycles(p->io.avr, fa);
197                         printf("%s-%c %c %.2fHz = %d cycles\n", __FUNCTION__, p->name,
198                                         'A'+compi, fc, (int)p->comp[compi].comp_cycles);
199                 }
200         }
201
202         if (p->tov_cycles > 1) {
203                 avr_cycle_timer_register(p->io.avr, p->tov_cycles, avr_timer_tov, p);
204                 // calling it once, with when == 0 tells it to arm the A/B/C timers if needed
205                 p->tov_base = 0;
206                 avr_timer_tov(p->io.avr, p->io.avr->cycle, p);
207         }
208 }
209
210 static void avr_timer_reconfigure(avr_timer_t * p)
211 {
212         avr_t * avr = p->io.avr;
213
214         avr_timer_wgm_t zero={0};
215         p->mode = zero;
216         // cancel everything
217         p->comp[AVR_TIMER_COMPA].comp_cycles = 0;
218         p->comp[AVR_TIMER_COMPB].comp_cycles = 0;
219         p->comp[AVR_TIMER_COMPC].comp_cycles = 0;
220         p->tov_cycles = 0;
221         
222         avr_cycle_timer_cancel(avr, avr_timer_tov, p);
223         avr_cycle_timer_cancel(avr, avr_timer_compa, p);
224         avr_cycle_timer_cancel(avr, avr_timer_compb, p);
225         avr_cycle_timer_cancel(avr, avr_timer_compc, p);
226
227         long clock = avr->frequency;
228
229         // only can exists on "asynchronous" 8 bits timers
230         if (avr_regbit_get(avr, p->as2))
231                 clock = 32768;
232
233         uint8_t cs = avr_regbit_get_array(avr, p->cs, ARRAY_SIZE(p->cs));
234         if (cs == 0) {
235                 printf("%s-%c clock turned off\n", __FUNCTION__, p->name);              
236                 return;
237         }
238
239         uint8_t mode = avr_regbit_get_array(avr, p->wgm, ARRAY_SIZE(p->wgm));
240         uint8_t cs_div = p->cs_div[cs];
241         uint32_t f = clock >> cs_div;
242
243         p->mode = p->wgm_op[mode];
244         //printf("%s-%c clock %d, div %d(/%d) = %d ; mode %d\n", __FUNCTION__, p->name, clock, cs, 1 << cs_div, f, mode);
245         switch (p->mode.kind) {
246                 case avr_timer_wgm_normal:
247                         avr_timer_configure(p, f, (1 << p->mode.size) - 1);
248                         break;
249                 case avr_timer_wgm_ctc: {
250                         avr_timer_configure(p, f, _timer_get_ocr(p, AVR_TIMER_COMPA));
251                 }       break;
252                 case avr_timer_wgm_pwm: {
253                         uint16_t top = p->mode.top == avr_timer_wgm_reg_ocra ? _timer_get_ocr(p, AVR_TIMER_COMPA) : _timer_get_icr(p);
254                         avr_timer_configure(p, f, top);
255                 }       break;
256                 case avr_timer_wgm_fast_pwm:
257                 //      avr_timer_configure(p, f, (1 << p->mode.size) - 1);
258                         break;
259                 default:
260                         printf("%s-%c unsupported timer mode wgm=%d (%d)\n", __FUNCTION__, p->name, mode, p->mode.kind);
261         }       
262 }
263
264 static void avr_timer_write_ocr(struct avr_t * avr, avr_io_addr_t addr, uint8_t v, void * param)
265 {
266         avr_timer_t * p = (avr_timer_t *)param;
267         avr_core_watch_write(avr, addr, v);
268
269         switch (p->mode.kind) {
270                 case avr_timer_wgm_pwm:
271                         if (p->mode.top != avr_timer_wgm_reg_ocra) {
272                                 avr_raise_irq(p->io.irq + TIMER_IRQ_OUT_PWM0, _timer_get_ocr(p, AVR_TIMER_COMPA));
273                                 avr_raise_irq(p->io.irq + TIMER_IRQ_OUT_PWM1, _timer_get_ocr(p, AVR_TIMER_COMPB));
274                         }
275                         break;
276                 case avr_timer_wgm_fast_pwm:
277                         avr_raise_irq(p->io.irq + TIMER_IRQ_OUT_PWM0, _timer_get_ocr(p, AVR_TIMER_COMPA));
278                         avr_raise_irq(p->io.irq + TIMER_IRQ_OUT_PWM1, _timer_get_ocr(p, AVR_TIMER_COMPB));
279                         break;
280                 default:
281                         printf("%s-%c mode %d\n", __FUNCTION__, p->name, p->mode.kind);
282                         avr_timer_reconfigure(p);
283                         break;
284         }
285 }
286
287 static void avr_timer_write(struct avr_t * avr, avr_io_addr_t addr, uint8_t v, void * param)
288 {
289         avr_timer_t * p = (avr_timer_t *)param;
290         avr_core_watch_write(avr, addr, v);
291         avr_timer_reconfigure(p);
292 }
293
294 static void avr_timer_reset(avr_io_t * port)
295 {
296         avr_timer_t * p = (avr_timer_t *)port;
297         avr_cycle_timer_cancel(p->io.avr, avr_timer_tov, p);
298         avr_cycle_timer_cancel(p->io.avr, avr_timer_compa, p);
299         avr_cycle_timer_cancel(p->io.avr, avr_timer_compb, p);
300         avr_cycle_timer_cancel(p->io.avr, avr_timer_compc, p);
301
302         // check to see if the comparators have a pin output. If they do,
303         // (try) to get the ioport corresponding IRQ and connect them
304         // they will automagically be triggered when the comparator raises
305         // it's own IRQ
306         for (int compi = 0; compi < AVR_TIMER_COMP_COUNT; compi++) {
307                 p->comp[compi].comp_cycles = 0;
308
309                 avr_ioport_getirq_t req = {
310                         .bit = p->comp[compi].com_pin
311                 };
312                 if (avr_ioctl(port->avr, AVR_IOCTL_IOPORT_GETIRQ_REGBIT, &req) > 0) {
313                         // cool, got an IRQ
314 //                      printf("%s-%c COMP%c Connecting PIN IRQ %d\n", __FUNCTION__, p->name, 'A'+compi, req.irq[0]->irq);
315                         avr_connect_irq(&port->irq[TIMER_IRQ_OUT_COMP + compi], req.irq[0]);
316                 }
317         }
318 }
319
320 static  avr_io_t        _io = {
321         .kind = "timer",
322         .reset = avr_timer_reset,
323 };
324
325 void avr_timer_init(avr_t * avr, avr_timer_t * p)
326 {
327         p->io = _io;
328
329         // allocate this module's IRQ
330         p->io.irq_count = TIMER_IRQ_COUNT;
331         p->io.irq = avr_alloc_irq(0, p->io.irq_count);
332         p->io.irq_ioctl_get = AVR_IOCTL_TIMER_GETIRQ(p->name);
333         p->io.irq[TIMER_IRQ_OUT_PWM0].flags |= IRQ_FLAG_FILTERED;
334         p->io.irq[TIMER_IRQ_OUT_PWM1].flags |= IRQ_FLAG_FILTERED;
335
336         avr_register_io(avr, &p->io);
337         avr_register_vector(avr, &p->overflow);
338         avr_register_vector(avr, &p->icr);
339
340         avr_register_io_write(avr, p->cs[0].reg, avr_timer_write, p);
341
342         /*
343          * Even if the timer is 16 bits, we don't care to have watches on the
344          * high bytes because the datasheet says that the low address is always
345          * the trigger.
346          */
347         for (int compi = 0; compi < AVR_TIMER_COMP_COUNT; compi++) {
348                 avr_register_vector(avr, &p->comp[compi].interrupt);
349
350                 if (p->comp[compi].r_ocr) // not all timers have all comparators
351                         avr_register_io_write(avr, p->comp[compi].r_ocr, avr_timer_write_ocr, p);
352         }
353         avr_register_io_write(avr, p->r_tcnt, avr_timer_tcnt_write, p);
354         avr_register_io_read(avr, p->r_tcnt, avr_timer_tcnt_read, p);
355 }