summaryrefslogtreecommitdiff
path: root/vga-more/src/TimerHelpers.h
blob: d43698798772630f2aca11cfcea9141433830253 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
/*
 Timer Helpers library.

Devised and written by Nick Gammon.
Date: 21 March 2012
Version: 1.0

Licence: Released for public use.
 
See: http://www.gammon.com.au/forum/?id=11504
 
 Example:
 
 // set up Timer 1
 TCNT1 = 0;         // reset counter
 OCR1A =  999;       // compare A register value (1000 * clock speed)
 
 // Mode 4: CTC, top = OCR1A
 Timer1::setMode (4, Timer1::PRESCALE_1, Timer1::CLEAR_A_ON_COMPARE);
 
 TIFR1 |= _BV (OCF1A);    // clear interrupt flag
 TIMSK1 = _BV (OCIE1A);   // interrupt on Compare A Match  
 
*/

#ifndef _TimerHelpers_h
#define _TimerHelpers_h

#if defined(ARDUINO) && ARDUINO >= 100
  #include "Arduino.h"
#else
  #include "WProgram.h"
#endif

/* ---------------------------------------------------------------
 Timer 0 setup
 --------------------------------------------------------------- */

namespace Timer0 
{
  // TCCR0A, TCCR0B
  const byte Modes [8] [2] = 
  {
  
  { 0,                         0 },            // 0: Normal, top = 0xFF
  { _BV (WGM00),               0 },            // 1: PWM, Phase-correct, top = 0xFF
  {               _BV (WGM01), 0 },            // 2: CTC, top = OCR0A
  { _BV (WGM00) | _BV (WGM01), 0 },            // 3: Fast PWM, top = 0xFF
  { 0,                         _BV (WGM02) },  // 4: Reserved
  { _BV (WGM00),               _BV (WGM02) },  // 5: PWM, Phase-correct, top = OCR0A
  {               _BV (WGM01), _BV (WGM02) },  // 6: Reserved
  { _BV (WGM00) | _BV (WGM01), _BV (WGM02) },  // 7: Fast PWM, top = OCR0A
  
  };  // end of Timer0::Modes
  
  // Activation
  // Note: T0 is pin 6, Arduino port: D4
  enum { NO_CLOCK, PRESCALE_1, PRESCALE_8, PRESCALE_64, PRESCALE_256, PRESCALE_1024, T0_FALLING, T0_RISING };
  
  // what ports to toggle on timer fire
  enum { NO_PORT = 0, 
    
    // pin 12, Arduino port: D6
    TOGGLE_A_ON_COMPARE  = _BV (COM0A0), 
    CLEAR_A_ON_COMPARE   = _BV (COM0A1), 
    SET_A_ON_COMPARE     = _BV (COM0A0) | _BV (COM0A1),
    
    // pin 11, Arduino port: D5
    TOGGLE_B_ON_COMPARE  = _BV (COM0B0), 
    CLEAR_B_ON_COMPARE   = _BV (COM0B1), 
    SET_B_ON_COMPARE     = _BV (COM0B0) | _BV (COM0B1),
  };
  
  
  // choose a timer mode, set which clock speed, and which port to toggle
  void setMode (const byte mode, const byte clock, const byte port)
  {
  if (mode < 0 || mode > 7)  // sanity check
    return;
  
  // reset existing flags
  TCCR0A = 0;
  TCCR0B = 0;
  
  TCCR0A |= (Modes [mode] [0]) | port;  
  TCCR0B |= (Modes [mode] [1]) | clock;
  }  // end of Timer0::setMode
  
}  // end of namespace Timer0 

/* ---------------------------------------------------------------
 Timer 1 setup
 --------------------------------------------------------------- */

namespace Timer1 
{
  // TCCR1A, TCCR1B
  const byte Modes [16] [2] = 
  {
  
  { 0,                         0 },            // 0: Normal, top = 0xFFFF
  { _BV (WGM10),               0 },            // 1: PWM, Phase-correct, 8 bit, top = 0xFF
  {               _BV (WGM11), 0 },            // 2: PWM, Phase-correct, 9 bit, top = 0x1FF
  { _BV (WGM10) | _BV (WGM11), 0 },            // 3: PWM, Phase-correct, 10 bit, top = 0x3FF
  { 0,                         _BV (WGM12) },  // 4: CTC, top = OCR1A
  { _BV (WGM10),               _BV (WGM12) },  // 5: Fast PWM, 8 bit, top = 0xFF
  {               _BV (WGM11), _BV (WGM12) },  // 6: Fast PWM, 9 bit, top = 0x1FF
  { _BV (WGM10) | _BV (WGM11), _BV (WGM12) },  // 7: Fast PWM, 10 bit, top = 0x3FF
  { 0,                                       _BV (WGM13) },  // 8: PWM, phase and frequency correct, top = ICR1    
  { _BV (WGM10),                             _BV (WGM13) },  // 9: PWM, phase and frequency correct, top = OCR1A    
  {               _BV (WGM11),               _BV (WGM13) },  // 10: PWM, phase correct, top = ICR1A    
  { _BV (WGM10) | _BV (WGM11),               _BV (WGM13) },  // 11: PWM, phase correct, top = OCR1A
  { 0,                         _BV (WGM12) | _BV (WGM13) },  // 12: CTC, top = ICR1    
  { _BV (WGM10),               _BV (WGM12) | _BV (WGM13) },  // 13: reserved
  {               _BV (WGM11), _BV (WGM12) | _BV (WGM13) },  // 14: Fast PWM, TOP = ICR1
  { _BV (WGM10) | _BV (WGM11), _BV (WGM12) | _BV (WGM13) },  // 15: Fast PWM, TOP = OCR1A
  
  };  // end of Timer1::Modes
  
  // Activation
  // Note: T1 is pin 11, Arduino port: D5
  enum { NO_CLOCK, PRESCALE_1, PRESCALE_8, PRESCALE_64, PRESCALE_256, PRESCALE_1024, T1_FALLING, T1_RISING };
  
  // what ports to toggle on timer fire
  enum { NO_PORT = 0, 
    
    // pin 15, Arduino port: D9
    TOGGLE_A_ON_COMPARE  = _BV (COM1A0), 
    CLEAR_A_ON_COMPARE   = _BV (COM1A1), 
    SET_A_ON_COMPARE     = _BV (COM1A0) | _BV (COM1A1),
    
    // pin 16, Arduino port: D10
    TOGGLE_B_ON_COMPARE  = _BV (COM1B0), 
    CLEAR_B_ON_COMPARE   = _BV (COM1B1), 
    SET_B_ON_COMPARE     = _BV (COM1B0) | _BV (COM1B1),
  };
  
  // choose a timer mode, set which clock speed, and which port to toggle
  void setMode (const byte mode, const byte clock, const byte port)
  {
  if (mode < 0 || mode > 15)  // sanity check
    return;
  
  // reset existing flags
  TCCR1A = 0;
  TCCR1B = 0;
  
  TCCR1A |= (Modes [mode] [0]) | port;  
  TCCR1B |= (Modes [mode] [1]) | clock;
  }  // end of Timer1::setMode
  
}  // end of namespace Timer1 

/* ---------------------------------------------------------------
 Timer 2 setup
 --------------------------------------------------------------- */

namespace Timer2 
{
  // TCCR2A, TCCR2B
  const byte Modes [8] [2] = 
  {
  
  { 0,                         0 },            // 0: Normal, top = 0xFF
  { _BV (WGM20),               0 },            // 1: PWM, Phase-correct, top = 0xFF
  {               _BV (WGM21), 0 },            // 2: CTC, top = OCR2A
  { _BV (WGM20) | _BV (WGM21), 0 },            // 3: Fast PWM, top = 0xFF
  { 0,                         _BV (WGM22) },  // 4: Reserved
  { _BV (WGM20),               _BV (WGM22) },  // 5: PWM, Phase-correct, top = OCR2A
  {               _BV (WGM21), _BV (WGM22) },  // 6: Reserved
  { _BV (WGM20) | _BV (WGM21), _BV (WGM22) },  // 7: Fast PWM, top = OCR2A
  
  };  // end of Timer2::Modes
  
  // Activation
  enum { NO_CLOCK, PRESCALE_1, PRESCALE_8, PRESCALE_32, PRESCALE_64, PRESCALE_128, PRESCALE_256, PRESCALE_1024 };
  
  // what ports to toggle on timer fire
  enum { NO_PORT = 0, 
    
    // pin 17, Arduino port: D11
    TOGGLE_A_ON_COMPARE  = _BV (COM2A0), 
    CLEAR_A_ON_COMPARE   = _BV (COM2A1), 
    SET_A_ON_COMPARE     = _BV (COM2A0) | _BV (COM2A1),
    
    // pin 5, Arduino port: D3
    TOGGLE_B_ON_COMPARE  = _BV (COM2B0), 
    CLEAR_B_ON_COMPARE   = _BV (COM2B1), 
    SET_B_ON_COMPARE     = _BV (COM2B0) | _BV (COM2B1),
  };
  
  
  // choose a timer mode, set which clock speed, and which port to toggle
  void setMode (const byte mode, const byte clock, const byte port)
  {
  if (mode < 0 || mode > 7)  // sanity check
    return;
  
  // reset existing flags
  TCCR2A = 0;
  TCCR2B = 0;
  
  TCCR2A |= (Modes [mode] [0]) | port;  
  TCCR2B |= (Modes [mode] [1]) | clock;
  }  // end of Timer2::setMode
  
}  // end of namespace Timer2 

#endif