~arcachofo/simulide/1.1.0

« back to all changes in this revision

Viewing changes to src/simavr/sim/avr_timer.h

  • Committer: arcachofo
  • Date: 2021-01-01 14:23:42 UTC
  • Revision ID: arcachofo@simulide.com-20210101142342-ozfljnll44g5lbl3
Initial Commit 0.5.15-RC3

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
    avr_timer.h
 
3
 
 
4
    Copyright 2008, 2009 Michel Pollet <buserror@gmail.com>
 
5
 
 
6
     This file is part of simavr.
 
7
 
 
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.
 
12
 
 
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.
 
17
 
 
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/>.
 
20
 */
 
21
 
 
22
#ifndef __AVR_TIMER_H__
 
23
#define __AVR_TIMER_H__
 
24
 
 
25
#ifdef __cplusplus
 
26
extern "C" {
 
27
#endif
 
28
 
 
29
#include "sim_avr.h"
 
30
 
 
31
enum {
 
32
    AVR_TIMER_COMPA = 0,
 
33
    AVR_TIMER_COMPB,
 
34
    AVR_TIMER_COMPC,
 
35
 
 
36
    AVR_TIMER_COMP_COUNT
 
37
};
 
38
 
 
39
enum {
 
40
    TIMER_IRQ_OUT_PWM0 = 0,
 
41
    TIMER_IRQ_OUT_PWM1,
 
42
    TIMER_IRQ_OUT_PWM2,
 
43
    TIMER_IRQ_IN_ICP,    // input capture
 
44
    TIMER_IRQ_OUT_COMP,  // comparator pins output IRQ
 
45
 
 
46
    TIMER_IRQ_COUNT = TIMER_IRQ_OUT_COMP + AVR_TIMER_COMP_COUNT
 
47
};
 
48
 
 
49
// Get the internal IRQ corresponding to the INT
 
50
#define AVR_IOCTL_TIMER_GETIRQ(_name) AVR_IOCTL_DEF('t','m','r',(_name))
 
51
 
 
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))
 
58
 
 
59
// Waveform generation modes
 
60
enum {
 
61
    wgm_none = 0,    // invalid mode
 
62
    wgm_normal,
 
63
    wgm_ctc,
 
64
    //avr_timer_wgm_pwm,
 
65
    wgm_fast_pwm,
 
66
    wgm_fc_pwm,
 
67
};
 
68
 
 
69
// Compare output modes
 
70
enum {
 
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
 
75
};
 
76
 
 
77
enum {
 
78
    wgm_reg_constant = 0,
 
79
    wgm_reg_ocra,
 
80
    wgm_reg_icr,
 
81
};
 
82
 
 
83
typedef struct avr_timer_wgm_t {
 
84
    uint32_t top: 8, bottom: 8, size : 8, kind : 8;
 
85
} avr_timer_wgm_t;
 
86
 
 
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
 
94
 
 
95
#define WGM_NORMAL8()    { .kind = wgm_normal, .size=8 }
 
96
#define WGM_NORMAL16()   { .kind = wgm_normal, .size=16 }
 
97
 
 
98
#define WGM_CTC_OC()     { .kind = wgm_ctc, .top = wgm_reg_ocra }
 
99
#define WGM_CTC_IC()     { .kind = wgm_ctc, .top = wgm_reg_icr }
 
100
 
 
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 }
 
106
 
 
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 }
 
112
 
 
113
 
 
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)
 
123
        uint8_t             number;
 
124
} avr_timer_comp_t, *avr_timer_comp_p;
 
125
 
 
126
enum {
 
127
    avr_timer_trace_ocr        = (1 << 0),
 
128
    avr_timer_trace_tcnt    = (1 << 1),
 
129
 
 
130
    avr_timer_trace_compa     = (1 << 8),
 
131
    avr_timer_trace_compb     = (1 << 9),
 
132
    avr_timer_trace_compc     = (1 << 10),
 
133
};
 
134
 
 
135
typedef struct avr_timer_t {
 
136
    avr_io_t        io;
 
137
    char             name;
 
138
    uint32_t        trace;        // debug trace
 
139
 
 
140
    avr_regbit_t    disabled;    // bit in the PRR
 
141
 
 
142
    avr_io_addr_t    r_tcnt, r_icr;
 
143
    avr_io_addr_t    r_tcnth, r_icrh;
 
144
 
 
145
    avr_regbit_t    wgm[4];
 
146
    avr_timer_wgm_t    wgm_op[16];
 
147
    avr_timer_wgm_t    Wgm_mode;
 
148
    int                wgm_kind;
 
149
    uint32_t        wgm_size;
 
150
 
 
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
 
155
 
 
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
 
159
 
 
160
    avr_regbit_t    icp;        // input capture pin, to link IRQs
 
161
    avr_regbit_t    ices;        // input capture edge select
 
162
 
 
163
    avr_timer_comp_t comp[AVR_TIMER_COMP_COUNT];
 
164
 
 
165
    avr_int_vector_t overflow;    // overflow
 
166
    avr_int_vector_t icr;        // input capture
 
167
 
 
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
 
173
    uint8_t         countUp;
 
174
} avr_timer_t;
 
175
 
 
176
void avr_timer_init( avr_t* avr, avr_timer_t* port );
 
177
 
 
178
#ifdef __cplusplus
 
179
};
 
180
#endif
 
181
 
 
182
#endif /*__AVR_TIMER_H__*/