timer: Masssive timer update. 8 & 16 bits
[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
30 static avr_cycle_count_t avr_timer_compa(struct avr_t * avr, avr_cycle_count_t when, void * param)
31 {
32         avr_timer_t * p = (avr_timer_t *)param;
33         avr_raise_interrupt(avr, &p->compa);
34         return p->tov_cycles ? 0 : p->compa_cycles ? when + p->compa_cycles : 0;
35 }
36
37 static avr_cycle_count_t avr_timer_compb(struct avr_t * avr, avr_cycle_count_t when, void * param)
38 {
39         avr_timer_t * p = (avr_timer_t *)param;
40         avr_raise_interrupt(avr, &p->compb);
41         return p->tov_cycles ? 0 : p->compb_cycles ? when + p->compb_cycles : 0;
42 }
43
44 static avr_cycle_count_t avr_timer_tov(struct avr_t * avr, avr_cycle_count_t when, void * param)
45 {
46         avr_timer_t * p = (avr_timer_t *)param;
47         avr_raise_interrupt(avr, &p->overflow);
48
49         if (p->compa_cycles && p->tov_cycles > p->compa_cycles)
50                 avr_cycle_timer_register(avr, p->compa_cycles, avr_timer_compa, p);
51         if (p->compb_cycles && p->tov_cycles > p->compb_cycles)
52                 avr_cycle_timer_register(avr, p->compb_cycles, avr_timer_compb, p);
53         return when + p->tov_cycles;
54 }
55
56 static uint8_t avr_timer_tcnt_read(struct avr_t * avr, avr_io_addr_t addr, void * param)
57 {
58         //avr_timer_t * p = (avr_timer_t *)param;
59         // made to trigger potential watchpoints
60         return avr_core_watch_read(avr, addr);
61 }
62
63 /*
64  * The timers are /always/ 16 bits here, if the higher byte register
65  * is specified it's just added.
66  */
67 static uint16_t _timer_get_ocra(avr_timer_t * p)
68 {
69         return p->io.avr->data[p->r_ocra] |
70                                 (p->r_ocrah ? (p->io.avr->data[p->r_ocrah] << 8) : 0);
71 }
72 static uint16_t _timer_get_ocrb(avr_timer_t * p)
73 {
74         return p->io.avr->data[p->r_ocrb] |
75                                 (p->r_ocrbh ? (p->io.avr->data[p->r_ocrbh] << 8) : 0);
76 }
77
78 static void avr_timer_configure(avr_timer_t * p, uint32_t clock, uint32_t top)
79 {
80         uint32_t ocra = _timer_get_ocra(p);
81         uint32_t ocrb = _timer_get_ocrb(p);
82         float fa = clock / (float)(ocra+1), fb = clock / (float)(ocrb+1);
83         float t = clock / (float)(top+1);
84         float frequency = p->io.avr->frequency;
85
86         p->compa_cycles = p->compb_cycles = p->tov_cycles = 0;
87
88         printf("%s-%c clock %d top %d a %d b %d\n", __FUNCTION__, p->name, clock, top, ocra, ocrb);
89         if (top != ocra) {
90                 p->tov_cycles = frequency / t; // avr_hz_to_cycles(frequency, t);
91                 printf("%s-%c TOP %.2fHz = cycles = %d\n", __FUNCTION__, p->name, t, (int)p->tov_cycles);
92         }
93         if (ocra && ocra <= top) {
94                 p->compa_cycles = frequency / fa; // avr_hz_to_cycles(p->io.avr, fa);
95                 printf("%s-%c A %.2fHz = cycles = %d\n", __FUNCTION__, p->name, fa, (int)p->compa_cycles);
96         }
97         if (ocrb && ocrb <= top) {
98                 p->compb_cycles = frequency / fb; // avr_hz_to_cycles(p->io.avr, fb);
99                 printf("%s-%c B %.2fHz = cycles = %d\n", __FUNCTION__, p->name, fb, (int)p->compb_cycles);
100         }
101
102         if (p->tov_cycles > 1)
103                 avr_cycle_timer_register(p->io.avr, p->tov_cycles, avr_timer_tov, p);
104         else {
105                 if (p->compa_cycles > 1)
106                         avr_cycle_timer_register(p->io.avr, p->compa_cycles, avr_timer_compa, p);
107                 if (p->compb_cycles > 1)
108                         avr_cycle_timer_register(p->io.avr, p->compb_cycles, avr_timer_compb, p);
109         }
110 }
111
112 static void avr_timer_write(struct avr_t * avr, avr_io_addr_t addr, uint8_t v, void * param)
113 {
114         avr_timer_t * p = (avr_timer_t *)param;
115
116         p->compa_cycles = 0;
117         p->compb_cycles = 0;
118
119         avr_core_watch_write(avr, addr, v);
120         long clock = avr->frequency;
121
122         // only can exists on "asynchronous" 8 bits timers
123         if (avr_regbit_get(avr, p->as2))
124                 clock = 32768;
125
126         uint8_t cs = avr_regbit_get_array(avr, p->cs, ARRAY_SIZE(p->cs));
127         if (cs == 0) {
128                 printf("%s-%c clock turned off\n", __FUNCTION__, p->name);              
129                 avr_cycle_timer_cancel(avr, avr_timer_tov, p);
130                 avr_cycle_timer_cancel(avr, avr_timer_compa, p);
131                 avr_cycle_timer_cancel(avr, avr_timer_compb, p);
132                 return;
133         }
134
135         uint8_t mode = avr_regbit_get_array(avr, p->wgm, ARRAY_SIZE(p->wgm));
136         uint8_t cs_div = p->cs_div[cs];
137         uint32_t f = clock >> cs_div;
138
139         printf("%s-%c clock %d, div %d(/%d) = %d ; mode %d\n", __FUNCTION__, p->name, clock, cs, 1 << cs_div, f, mode);
140         switch (p->wgm_op[mode].kind) {
141                 case avr_timer_wgm_normal:
142                         avr_timer_configure(p, f, (1 << p->wgm_op[mode].size) - 1);
143                         break;
144                 case avr_timer_wgm_ctc: {
145                         avr_timer_configure(p, f, _timer_get_ocra(p));
146                 }       break;
147                 case avr_timer_wgm_fast_pwm: {
148                         avr_raise_irq(p->io.irq + TIMER_IRQ_OUT_PWM0, _timer_get_ocra(p));
149                         avr_raise_irq(p->io.irq + TIMER_IRQ_OUT_PWM1, _timer_get_ocra(p));
150                 }       break;
151                 default:
152                         printf("%s-%c unsupported timer mode wgm=%d (%d)\n", __FUNCTION__, p->name, mode, p->wgm_op[mode].kind);
153         }
154 }
155
156 static void avr_timer_reset(avr_io_t * port)
157 {
158         avr_timer_t * p = (avr_timer_t *)port;
159         avr_cycle_timer_cancel(p->io.avr, avr_timer_tov, p);
160         avr_cycle_timer_cancel(p->io.avr, avr_timer_compa, p);
161         avr_cycle_timer_cancel(p->io.avr, avr_timer_compb, p);
162         p->compa_cycles = 0;
163         p->compb_cycles = 0;
164 }
165
166 static  avr_io_t        _io = {
167         .kind = "timer",
168         .reset = avr_timer_reset,
169 };
170
171 void avr_timer_init(avr_t * avr, avr_timer_t * p)
172 {
173         p->io = _io;
174         printf("%s timer%c created OCRA %02x OCRAH %02x\n", __FUNCTION__, p->name, p->r_ocra,  p->r_ocrah);
175
176         // allocate this module's IRQ
177         p->io.irq_count = TIMER_IRQ_COUNT;
178         p->io.irq = avr_alloc_irq(0, p->io.irq_count);
179         p->io.irq_ioctl_get = AVR_IOCTL_TIMER_GETIRQ(p->name);
180         p->io.irq[TIMER_IRQ_OUT_PWM0].flags |= IRQ_FLAG_FILTERED;
181         p->io.irq[TIMER_IRQ_OUT_PWM1].flags |= IRQ_FLAG_FILTERED;
182
183         avr_register_io(avr, &p->io);
184         avr_register_vector(avr, &p->compa);
185         avr_register_vector(avr, &p->compb);
186
187         avr_register_io_write(avr, p->cs[0].reg, avr_timer_write, p);
188
189         /*
190          * Even if the timer is 16 bits, we don't care to have watches on the
191          * high bytes because the datasheet says that the low address is always
192          * the trigger.
193          */
194         avr_register_io_write(avr, p->r_ocra, avr_timer_write, p);
195         avr_register_io_write(avr, p->r_ocrb, avr_timer_write, p);
196
197         avr_register_io_read(avr, p->r_tcnt, avr_timer_tcnt_read, p);
198 }