forked from adafruit/Adafruit_ZeroTimer
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Adafruit_ZeroTimer.h
144 lines (121 loc) · 4.13 KB
/
Adafruit_ZeroTimer.h
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
#include "Arduino.h"
enum tc_clock_prescaler {
/** Divide clock by 1 */
TC_CLOCK_PRESCALER_DIV1 = TC_CTRLA_PRESCALER(0),
/** Divide clock by 2 */
TC_CLOCK_PRESCALER_DIV2 = TC_CTRLA_PRESCALER(1),
/** Divide clock by 4 */
TC_CLOCK_PRESCALER_DIV4 = TC_CTRLA_PRESCALER(2),
/** Divide clock by 8 */
TC_CLOCK_PRESCALER_DIV8 = TC_CTRLA_PRESCALER(3),
/** Divide clock by 16 */
TC_CLOCK_PRESCALER_DIV16 = TC_CTRLA_PRESCALER(4),
/** Divide clock by 64 */
TC_CLOCK_PRESCALER_DIV64 = TC_CTRLA_PRESCALER(5),
/** Divide clock by 256 */
TC_CLOCK_PRESCALER_DIV256 = TC_CTRLA_PRESCALER(6),
/** Divide clock by 1024 */
TC_CLOCK_PRESCALER_DIV1024 = TC_CTRLA_PRESCALER(7),
};
enum tc_counter_size {
/** The counter's maximum value is 0xFF, the period register is
* available to be used as top value
*/
TC_COUNTER_SIZE_8BIT = TC_CTRLA_MODE_COUNT8,
/** The counter's maximum value is 0xFFFF. There is no separate
* period register, to modify top one of the capture compare
* registers has to be used. This limits the amount of
* available channels.
*/
TC_COUNTER_SIZE_16BIT = TC_CTRLA_MODE_COUNT16,
/** The counter's maximum value is 0xFFFFFFFF. There is no separate
* period register, to modify top one of the capture compare
* registers has to be used. This limits the amount of
* available channels.
*/
TC_COUNTER_SIZE_32BIT = TC_CTRLA_MODE_COUNT32,
};
#if defined(__SAMD51__)
enum tc_wave_generation {
TC_WAVE_GENERATION_NORMAL_FREQ = TC_WAVE_WAVEGEN_NFRQ,
TC_WAVE_GENERATION_MATCH_FREQ = TC_WAVE_WAVEGEN_MFRQ,
TC_WAVE_GENERATION_NORMAL_PWM = TC_WAVE_WAVEGEN_NPWM,
TC_WAVE_GENERATION_MATCH_PWM = TC_WAVE_WAVEGEN_MPWM,
};
#else
enum tc_wave_generation {
/** Top is maximum, except in 8-bit counter size where it is the PER
* register
*/
TC_WAVE_GENERATION_NORMAL_FREQ = TC_CTRLA_WAVEGEN_NFRQ,
/** Top is CC0, except in 8-bit counter size where it is the PER
* register
*/
TC_WAVE_GENERATION_MATCH_FREQ = TC_CTRLA_WAVEGEN_MFRQ,
/** Top is maximum, except in 8-bit counter size where it is the PER
* register
*/
TC_WAVE_GENERATION_NORMAL_PWM = TC_CTRLA_WAVEGEN_NPWM,
/** Top is CC0, except in 8-bit counter size where it is the PER
* register
*/
TC_WAVE_GENERATION_MATCH_PWM = TC_CTRLA_WAVEGEN_MPWM,
};
#endif
enum tc_count_direction {
TC_COUNT_DIRECTION_UP = 0,
TC_COUNT_DIRECTION_DOWN
};
enum tc_callback {
TC_CALLBACK_OVERFLOW = 0,
TC_CALLBACK_ERROR,
TC_CALLBACK_CC_CHANNEL0,
TC_CALLBACK_CC_CHANNEL1,
TC_CALLBACK_N
};
#define NUM_PWM_CHANNELS 2
#define NUM_CC_CHANNELS 2
class Adafruit_ZeroTimer {
public:
Adafruit_ZeroTimer(uint8_t tn);
boolean PWMout(boolean pwmout, uint8_t channum, uint8_t pin);
void setPeriodMatch(uint32_t period, uint32_t match, uint8_t channum = 1);
void enable(boolean en);
void configure(tc_clock_prescaler prescale, tc_counter_size countersize, tc_wave_generation wavegen, tc_count_direction countdir = TC_COUNT_DIRECTION_UP);
void setCompare(uint8_t channum, uint32_t compare);
void setTop(uint32_t top);
void invertWave(uint8_t invert);
void setCallback(boolean enable, tc_callback cb_type, void(* callback_func) (void) = NULL);
static void timerHandler(uint8_t timerNum);
protected:
uint8_t _timernum;
Tc *_hw;
tc_clock_prescaler _clock_prescaler;
tc_counter_size _counter_size;
tc_wave_generation _wave_generation;
uint8_t _waveform_invert_output;
tc_count_direction _count_direction;
struct counter_8_bit {
uint8_t compare_capture_channel[NUM_CC_CHANNELS];
uint8_t period;
uint8_t value;
};
counter_8_bit _counter_8_bit;
struct counter_16_bit {
uint16_t compare_capture_channel[NUM_CC_CHANNELS];
uint16_t value;
};
counter_16_bit _counter_16_bit;
struct counter_32_bit {
uint32_t compare_capture_channel[NUM_CC_CHANNELS];
uint32_t value;
};
counter_32_bit _counter_32_bit;
struct pwm_channel {
bool enabled;
uint32_t pin_mux;
uint32_t pin_out;
};
pwm_channel _pwm_channel[NUM_PWM_CHANNELS];
bool tc_init();
};