|
52 | 52 |
|
53 | 53 | Prescaler:
|
54 | 54 | Prescalers: GCLK_TC, GCLK_TC/2, GCLK_TC/4, GCLK_TC/8, GCLK_TC/16, GCLK_TC/64, GCLK_TC/256, GCLK_TC/1024
|
55 |
| - Base frequency: 84MHz |
| 55 | + Base frequency: 48MHz |
56 | 56 |
|
57 | 57 | We will use TCC2, as there're some models with only 3 timers (regular models have 5 TCs)
|
58 | 58 |
|
59 | 59 | REMEMBER! 16 bit counter!!!
|
60 | 60 |
|
61 | 61 |
|
62 | 62 | Name Prescaler Freq Base Delay Overflow delay
|
63 |
| - GCLK_TC 1 48MHz 0,020833333us 1365,333333333us; 1,365333333333ms |
64 |
| - GCLK_TC/2 2 24MHz 0,041666667us 2730,666666667us; 2,730666666667ms |
65 |
| - GCLK_TC/4 4 12MHz 0,083333333us 5461,333333333us; 5,461333333333ms |
66 |
| - GCLK_TC/8 8 6MHz 0,166666667us 10922,666666667us; 10,922666666667ms |
67 |
| - GCLK_TC/16 16 3MHz 0,333333333us 21845,333333333us; 21,845333333333ms |
68 |
| - GCLK_TC/64 64 750KHz 1,333333333us 87381,333311488us; 87,381333311488ms |
69 |
| - GCLK_TC/256 256 187,5KHz 5,333333333us 349525,333311488us; 349,525333311488ms |
70 |
| - GCLK_TC/1024 1024 46.875Hz 21,333333333us 1398101,333333333us; 1398,101333333333ms; 1,398101333333333s |
| 63 | + GCLK_TC 1 48MHz ~0,020833333us 1365,3125us; 1,3653125ms |
| 64 | + GCLK_TC/2 2 24MHz ~0,041666667us 2730,625us; 2,730625ms |
| 65 | + GCLK_TC/4 4 12MHz ~0,083333333us 5461,25us; 5,46125ms |
| 66 | + GCLK_TC/8 8 6MHz ~0,166666667us 10922,5us; 10,9225ms |
| 67 | + GCLK_TC/16 16 3MHz ~0,333333333us 21845us; 21,845ms |
| 68 | + GCLK_TC/64 64 750KHz ~1,333333333us 87380us; 87,380ms |
| 69 | + GCLK_TC/256 256 187,5KHz ~5,333333333us 349520us; 349,52ms |
| 70 | + GCLK_TC/1024 1024 46.875kHz ~21,333333333us 1398080us; 1398,08ms; 1,39808s |
| 71 | +
|
| 72 | + In general: |
| 73 | + freq = 48 MHz / prescaler |
| 74 | + base_delay = 1 / freq |
| 75 | + overflow_delay = UINT16_MAX * base_delay |
71 | 76 |
|
72 | 77 | Will be using:
|
73 | 78 | GCLK_TC/16 for us
|
74 | 79 | GCLK_TC/1024 for s
|
| 80 | +
|
| 81 | + GCLK_TC/16: |
| 82 | + freq = 48 MHz / prescaler = 48 MHz / 16 = 3 MHz |
| 83 | + base_delay = 1 / freq = 1 / 3e6 s = 1/3 us ~= 0.333333333 us |
| 84 | + overflow_delay = UINT16_MAX * base_delay = 65535 / 3 us = 21845 us |
| 85 | +
|
| 86 | + GCLK_TC/1024: |
| 87 | + freq = 48 MHz / prescaler = 48 MHz / 1024 = 46.875 kHz = 46875 Hz |
| 88 | + base_delay = 1 / freq = 1 / 46875 s = ~= 21.333333333us |
| 89 | + overflow_delay = UINT16_MAX * base_delay = 65535 / 46875 s = 1.39808 s |
75 | 90 | */
|
76 | 91 |
|
77 | 92 | // Enable clock for TC
|
|
82 | 97 | _TC->CTRLA.reg &= ~TC_CTRLA_ENABLE;
|
83 | 98 | while (_TC->STATUS.bit.SYNCBUSY == 1); // sync
|
84 | 99 |
|
85 |
| - // Set Timer counter Mode to 16 bits + Set TC as normal Normal Frq + Prescaler: GCLK_TC/16 |
86 |
| - _TC->CTRLA.reg |= (TC_CTRLA_MODE_COUNT16 + TC_CTRLA_WAVEGEN_NFRQ + TC_CTRLA_PRESCALER_DIV16); |
| 100 | + // Set Timer counter Mode to 16 bits + Set TC as normal Match Frq + Prescaler: GCLK_TC/16 |
| 101 | + _TC->CTRLA.reg |= (TC_CTRLA_MODE_COUNT16 + TC_CTRLA_WAVEGEN_MFRQ + TC_CTRLA_PRESCALER_DIV16); |
87 | 102 | while (_TC->STATUS.bit.SYNCBUSY == 1); // sync
|
88 | 103 |
|
89 | 104 | if (us > 21845) {
|
90 |
| - __overflows = _overflows = us / 21845.333333333; |
91 |
| - __remaining = _remaining = ((us - (21845.333333333 * _overflows)) / 0.333333333) + 0.5; // +0.5 is same as round |
| 105 | + __overflows = _overflows = us / 21845.0; |
| 106 | + __remaining = _remaining = (us - (21845 * _overflows)) * 3 - 1; |
92 | 107 | } else {
|
93 | 108 | __overflows = _overflows = 0;
|
94 |
| - __remaining = _remaining = (us / 0.333333333) + 0.5; // +0.5 is same as round |
| 109 | + __remaining = _remaining = us * 3 - 1; |
95 | 110 | }
|
96 | 111 |
|
97 | 112 | if (__overflows == 0) {
|
98 | 113 | _loadRemaining();
|
99 | 114 | _remaining = 0;
|
100 | 115 | } else {
|
101 |
| - _TC->CC[0].reg = 65535; |
| 116 | + _TC->CC[0].reg = UINT16_MAX; |
102 | 117 | _TC->INTENSET.reg = 0; // disable all interrupts
|
103 | 118 | _TC->INTENSET.bit.OVF = 1; // enable overfollow
|
104 | 119 | // Skip: while (_TC->STATUS.bit.SYNCBUSY == 1); // sync
|
|
126 | 141 | }
|
127 | 142 |
|
128 | 143 | /*
|
129 |
| - GCLK_TC/1024 1024 46.875Hz 21,333333333us 1398101,333333333us; 1398,101333333333ms; 1,398101333333333s |
| 144 | + GCLK_TC/1024 1024 46.875kHz ~21,333333333us 1398080us; 1398,08ms; 1,39808s |
130 | 145 | */
|
131 | 146 |
|
132 | 147 | // Enable clock for TC
|
|
137 | 152 | _TC->CTRLA.reg &= ~TC_CTRLA_ENABLE;
|
138 | 153 | while (_TC->STATUS.bit.SYNCBUSY == 1); // sync
|
139 | 154 |
|
140 |
| - // Set Timer counter Mode to 16 bits + Set TC as normal Normal Frq + Prescaler: GCLK_TC/1024 |
141 |
| - _TC->CTRLA.reg |= (TC_CTRLA_MODE_COUNT16 + TC_CTRLA_WAVEGEN_NFRQ + TC_CTRLA_PRESCALER_DIV1024); |
| 155 | + // Set Timer counter Mode to 16 bits + Set TC as normal Match Frq + Prescaler: GCLK_TC/1024 |
| 156 | + _TC->CTRLA.reg |= (TC_CTRLA_MODE_COUNT16 + TC_CTRLA_WAVEGEN_MFRQ + TC_CTRLA_PRESCALER_DIV1024); |
142 | 157 | while (_TC->STATUS.bit.SYNCBUSY == 1); // sync
|
143 | 158 |
|
144 | 159 | if (s > 1) {
|
145 |
| - __overflows = _overflows = s / 1.398101333333333; |
146 |
| - __remaining = _remaining = ((s - (1.398101333333333 * _overflows)) / 0.000021333333333) + 0.5; // +0.5 is same as round |
| 160 | + __overflows = _overflows = s / 1.39808; |
| 161 | + __remaining = _remaining = ((s * 100000) % 139808) * 480 / 1024 - 1; // for integer s this is always an integer |
147 | 162 | } else {
|
148 | 163 | __overflows = _overflows = 0;
|
149 |
| - __remaining = _remaining = (s / 0.000021333333333) + 0.5; // +0.5 is same as round |
| 164 | + __remaining = _remaining = s * 46875 - 1; |
150 | 165 | }
|
151 | 166 |
|
152 | 167 | if (__overflows == 0) {
|
153 | 168 | _loadRemaining();
|
154 | 169 | _remaining = 0;
|
155 | 170 | } else {
|
156 |
| - _TC->CC[0].reg = 65535; |
| 171 | + _TC->CC[0].reg = UINT16_MAX; |
157 | 172 | _TC->INTENSET.reg = 0; // disable all interrupts
|
158 | 173 | _TC->INTENSET.bit.OVF = 1; // enable overfollow
|
159 | 174 | // Skip: while (_TC->STATUS.bit.SYNCBUSY == 1); // sync
|
|
174 | 189 | * Note: This is device-dependant
|
175 | 190 | */
|
176 | 191 | void uTimerLib::_loadRemaining() {
|
177 |
| - _TC->COUNT.reg = 0; // Reset to 0 |
178 | 192 | _TC->CC[0].reg = _remaining;
|
179 | 193 | _TC->INTENSET.reg = 0; // disable all interrupts
|
180 | 194 | _TC->INTENSET.bit.MC0 = 1; // enable compare match to CC0
|
|
217 | 231 | if (_type == UTIMERLIB_TYPE_TIMEOUT) {
|
218 | 232 | clearTimer();
|
219 | 233 | } else if (_type == UTIMERLIB_TYPE_INTERVAL) {
|
220 |
| - if (__overflows == 0) { |
221 |
| - _remaining = __remaining; |
222 |
| - _loadRemaining(); |
223 |
| - _remaining = 0; |
224 |
| - } else { |
| 234 | + if (__overflows != 0) { |
225 | 235 | _overflows = __overflows;
|
226 | 236 | _remaining = __remaining;
|
227 | 237 |
|
228 |
| - _TC->COUNT.reg = 0; // Reset to 0 |
229 | 238 | _TC->INTENSET.reg = 0; // disable all interrupts
|
230 | 239 | _TC->INTENSET.bit.OVF = 0; // enable overfollow
|
231 | 240 | _TC->INTENSET.bit.MC0 = 1; // disable compare match to CC0
|
232 |
| - _TC->CC[0].reg = 65535; |
| 241 | + _TC->CC[0].reg = UINT16_MAX; |
233 | 242 | }
|
234 | 243 | }
|
235 | 244 | _cb();
|
236 | 245 | } else if (_overflows > 0) { // Reload for SAMD21
|
237 |
| - _TC->COUNT.reg = 0; // Reset to 0 |
238 | 246 | _TC->INTENSET.reg = 0; // disable all interrupts
|
239 | 247 | _TC->INTENSET.bit.OVF = 0; // enable overfollow
|
240 | 248 | _TC->INTENSET.bit.MC0 = 1; // disable compare match to CC0
|
241 |
| - _TC->CC[0].reg = 65535; |
| 249 | + _TC->CC[0].reg = UINT16_MAX; |
242 | 250 | }
|
243 | 251 | }
|
244 | 252 |
|
|
0 commit comments