4
Copyright 2008, 2009 Michel Pollet <buserror@gmail.com>
6
This file is part of simavr.
8
simavr is free software: you can redistribute it and/or modify
9
it under the terms of the GNU General Public License as published by
10
the Free Software Foundation, either version 3 of the License, or
11
(at your option) any later version.
13
simavr is distributed in the hope that it will be useful,
14
but WITHOUT ANY WARRANTY; without even the implied warranty of
15
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16
GNU General Public License for more details.
18
You should have received a copy of the GNU General Public License
19
along with simavr. If not, see <http://www.gnu.org/licenses/>.
22
#ifndef __AVR_TIMER_H__
23
#define __AVR_TIMER_H__
40
TIMER_IRQ_OUT_PWM0 = 0,
43
TIMER_IRQ_IN_ICP, // input capture
44
TIMER_IRQ_OUT_COMP, // comparator pins output IRQ
46
TIMER_IRQ_COUNT = TIMER_IRQ_OUT_COMP + AVR_TIMER_COMP_COUNT
49
// Get the internal IRQ corresponding to the INT
50
#define AVR_IOCTL_TIMER_GETIRQ(_name) AVR_IOCTL_DEF('t','m','r',(_name))
52
// add timer number/name (character) to set tracing flags
53
#define AVR_IOCTL_TIMER_SET_TRACE(_number) AVR_IOCTL_DEF('t','m','t',(_number))
54
// enforce using virtual clock generator when external clock is chosen by firmware
55
#define AVR_IOCTL_TIMER_SET_VIRTCLK(_number) AVR_IOCTL_DEF('t','m','v',(_number))
56
// set frequency of the virtual clock generator
57
#define AVR_IOCTL_TIMER_SET_FREQCLK(_number) AVR_IOCTL_DEF('t','m','f',(_number))
59
// Waveform generation modes
61
wgm_none = 0, // invalid mode
69
// Compare output modes
71
avr_timer_com_normal = 0,// Normal mode, OCnx disconnected
72
avr_timer_com_toggle, // Toggle OCnx on compare match
73
avr_timer_com_clear, // clear OCnx on compare match
74
avr_timer_com_set, // set OCnx on compare match
83
typedef struct avr_timer_wgm_t {
84
uint32_t top: 8, bottom: 8, size : 8, kind : 8;
87
#define EXTCLK_CHOOSE 0x80 // marker value for cs_div specifying ext clock selection
88
#define EXTCLK_FLAG_TN 0x80 // Tn external clock chosen
89
#define EXTCLK_FLAG_STARTED 0x40 // peripheral started
90
#define EXTCLK_FLAG_REVDIR 0x20 // reverse counting (decrement)
91
#define EXTCLK_FLAG_AS2 0x10 // asynchronous external clock chosen
92
#define EXTCLK_FLAG_VIRT 0x08 // don't use the input pin, generate clock internally
93
#define EXTCLK_FLAG_EDGE 0x01 // use the rising edge
95
#define WGM_NORMAL8() { .kind = wgm_normal, .size=8 }
96
#define WGM_NORMAL16() { .kind = wgm_normal, .size=16 }
98
#define WGM_CTC_OC() { .kind = wgm_ctc, .top = wgm_reg_ocra }
99
#define WGM_CTC_IC() { .kind = wgm_ctc, .top = wgm_reg_icr }
101
#define WGM_FASTPWM_8() { .kind = wgm_fast_pwm, .size=8 }
102
#define WGM_FASTPWM_9() { .kind = wgm_fast_pwm, .size=9 }
103
#define WGM_FASTPWM_10() { .kind = wgm_fast_pwm, .size=10 }
104
#define WGM_FASTPWM_OC() { .kind = wgm_fast_pwm, .top = wgm_reg_ocra }
105
#define WGM_FASTPWM_IC() { .kind = wgm_fast_pwm, .top = wgm_reg_icr }
107
#define WGM_FCPWM_8() { .kind = wgm_fc_pwm, .size=8 }
108
#define WGM_FCPWM_9() { .kind = wgm_fc_pwm, .size=9 }
109
#define WGM_FCPWM_10() { .kind = wgm_fc_pwm, .size=10 }
110
#define WGM_FCPWM_OC() { .kind = wgm_fc_pwm, .top = wgm_reg_ocra }
111
#define WGM_FCPWM_IC() { .kind = wgm_fc_pwm, .top = wgm_reg_icr }
114
typedef struct avr_timer_comp_t {
115
avr_int_vector_t interrupt; // interrupt vector
116
struct avr_timer_t *timer; // parent timer
117
avr_io_addr_t r_ocr; // comparator register low byte
118
avr_io_addr_t r_ocrh; // comparator register hi byte
119
avr_regbit_t com; // comparator output mode registers
120
avr_regbit_t com_pin; // where comparator output is connected
121
uint64_t comp_cycles;
122
uint32_t ocr_cycles; // OCR value in cycles (prescaler*ocr)
124
} avr_timer_comp_t, *avr_timer_comp_p;
127
avr_timer_trace_ocr = (1 << 0),
128
avr_timer_trace_tcnt = (1 << 1),
130
avr_timer_trace_compa = (1 << 8),
131
avr_timer_trace_compb = (1 << 9),
132
avr_timer_trace_compc = (1 << 10),
135
typedef struct avr_timer_t {
138
uint32_t trace; // debug trace
140
avr_regbit_t disabled; // bit in the PRR
142
avr_io_addr_t r_tcnt, r_icr;
143
avr_io_addr_t r_tcnth, r_icrh;
146
avr_timer_wgm_t wgm_op[16];
147
avr_timer_wgm_t Wgm_mode;
151
avr_regbit_t as2; // asynchronous clock 32khz
152
avr_regbit_t cs[4]; // specify control register bits choosing clock sourcre
153
uint8_t cs_div[16]; // translate control register value to clock prescaler (orders of 2 exponent)
154
uint32_t cs_div_value; // Prescaler
156
avr_regbit_t ext_clock_pin; // external clock input pin, to link IRQs
157
uint8_t ext_clock_flags; // holds AVR_TIMER_EXTCLK_FLAG_ON, AVR_TIMER_EXTCLK_FLAG_EDGE and other ext. clock mode flags
158
float ext_clock; // external clock frequency, e.g. 32768Hz
160
avr_regbit_t icp; // input capture pin, to link IRQs
161
avr_regbit_t ices; // input capture edge select
163
avr_timer_comp_t comp[AVR_TIMER_COMP_COUNT];
165
avr_int_vector_t overflow; // overflow
166
avr_int_vector_t icr; // input capture
168
uint64_t tov_cycles; // number of cycles from zero to overflow
169
float tov_cycles_fract; // fractional part for external clock with non int ratio to F_CPU
170
float phase_accumulator;
171
uint64_t tov_base; // MCU cycle when the last overflow occured; when clocked externally holds external clock count
172
uint16_t tov_top; // current top value to calculate tnct
176
void avr_timer_init( avr_t* avr, avr_timer_t* port );
182
#endif /*__AVR_TIMER_H__*/