4 Handles the just one mode of the 8 bit AVR timer.
5 Still need to handle all the others!
7 Copyright 2008, 2009 Michel Pollet <buserror@gmail.com>
9 This file is part of simavr.
11 simavr is free software: you can redistribute it and/or modify
12 it under the terms of the GNU General Public License as published by
13 the Free Software Foundation, either version 3 of the License, or
14 (at your option) any later version.
16 simavr is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 GNU General Public License for more details.
21 You should have received a copy of the GNU General Public License
22 along with simavr. If not, see <http://www.gnu.org/licenses/>.
26 #include "avr_timer8.h"
28 static avr_cycle_count_t avr_timer8_compa(struct avr_t * avr, avr_cycle_count_t when, void * param)
30 avr_timer8_t * p = (avr_timer8_t *)param;
31 avr_raise_interrupt(avr, &p->compa);
32 return p->compa_cycles ? when + p->compa_cycles : 0;
35 static avr_cycle_count_t avr_timer8_compb(struct avr_t * avr, avr_cycle_count_t when, void * param)
37 avr_timer8_t * p = (avr_timer8_t *)param;
38 avr_raise_interrupt(avr, &p->compb);
39 return p->compb_cycles ? when + p->compb_cycles : 0;
42 static uint8_t avr_timer8_tcnt_read(struct avr_t * avr, uint8_t addr, void * param)
44 //avr_timer8_t * p = (avr_timer8_t *)param;
45 // made to trigger potential watchpoints
46 return avr_core_watch_read(avr, addr);
49 static void avr_timer8_write(struct avr_t * avr, uint8_t addr, uint8_t v, void * param)
51 avr_timer8_t * p = (avr_timer8_t *)param;
56 avr_core_watch_write(avr, addr, v);
57 long clock = avr->frequency;
58 if (avr_regbit_get(avr, p->as2))
60 uint8_t cs = avr_regbit_get_array(avr, p->cs, ARRAY_SIZE(p->cs));
62 printf("%s-%c clock turned off\n", __FUNCTION__, p->name);
63 avr_cycle_timer_cancel(avr, avr_timer8_compa, p);
64 avr_cycle_timer_cancel(avr, avr_timer8_compb, p);
67 uint8_t mode = avr_regbit_get_array(avr, p->wgm, ARRAY_SIZE(p->wgm));
68 uint8_t cs_div = p->cs_div[cs];
69 uint16_t ocra = avr->data[p->r_ocra];
70 uint16_t ocrb = avr->data[p->r_ocrb];
71 long f = clock >> cs_div;
72 long fa = f / (ocra+1), fb = f / (ocrb+1);
74 // printf("%s-%c clock f=%ld cs=%02x (div %d) = %ldhz\n", __FUNCTION__, p->name, clock, cs, 1 << cs_div, f);
75 if (ocra) printf("%s-%c wgm %d OCRA=%3d = %ldhz\n", __FUNCTION__, p->name, mode, ocra, fa);
76 if (ocrb) printf("%s-%c wgm %d OCRB=%3d = %ldhz\n", __FUNCTION__, p->name, mode, ocrb, fb);
78 p->compa_cycles = avr_hz_to_cycles(avr, fa);
79 p->compb_cycles = avr_hz_to_cycles(avr, fb);
81 avr_cycle_timer_register(avr, p->compa_cycles, avr_timer8_compa, p);
83 avr_cycle_timer_register(avr, p->compb_cycles, avr_timer8_compb, p);
84 // printf("%s-%c A %ld/%ld = cycles = %d\n", __FUNCTION__, p->name, (long)avr->frequency, fa, (int)p->compa_cycles);
85 // printf("%s-%c B %ld/%ld = cycles = %d\n", __FUNCTION__, p->name, (long)avr->frequency, fb, (int)p->compb_cycles);
88 static void avr_timer8_reset(avr_io_t * port)
90 avr_timer8_t * p = (avr_timer8_t *)port;
91 avr_cycle_timer_cancel(p->io.avr, avr_timer8_compa, p);
92 avr_cycle_timer_cancel(p->io.avr, avr_timer8_compb, p);
97 static avr_io_t _io = {
99 .reset = avr_timer8_reset,
102 void avr_timer8_init(avr_t * avr, avr_timer8_t * p)
105 // printf("%s timer%c created\n", __FUNCTION__, p->name);
107 avr_register_io(avr, &p->io);
108 avr_register_vector(avr, &p->compa);
110 avr_register_io_write(avr, p->cs[0].reg, avr_timer8_write, p);
111 avr_register_io_write(avr, p->r_ocra, avr_timer8_write, p);
112 avr_register_io_write(avr, p->r_ocrb, avr_timer8_write, p);
114 avr_register_io_read(avr, p->r_tcnt, avr_timer8_tcnt_read, p);