@@ -21,8 +21,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
21
21
22
22
volatile clk_t system_clks ;
23
23
volatile uint64_t ms_clk ;
24
-
25
- volatile uint8_t us_delay_done ;
24
+ uint32_t usec_delay_mult ;
25
+ #define USEC_DELAY_LOOP_CYCLES 3 //Sum of instruction cycles in us delay loop
26
26
27
27
const uint32_t sercom_apbbase [] = {(uint32_t )SERCOM0 ,(uint32_t )SERCOM1 ,(uint32_t )SERCOM2 ,(uint32_t )SERCOM3 ,(uint32_t )SERCOM4 ,(uint32_t )SERCOM5 };
28
28
const uint8_t sercom_pchan [] = {7 , 8 , 23 , 24 , 34 , 35 };
@@ -73,6 +73,9 @@ void CLK_oscctrl_init(void)
73
73
74
74
system_clks .freq_gclk [0 ] = system_clks .freq_dpll [0 ];
75
75
76
+ usec_delay_mult = system_clks .freq_gclk [0 ] / (USEC_DELAY_LOOP_CYCLES * 1000000 );
77
+ if (usec_delay_mult < 1 ) usec_delay_mult = 1 ; //Never allow a multiplier of zero
78
+
76
79
DBGC (DC_CLK_OSC_INIT_COMPLETE );
77
80
}
78
81
@@ -158,23 +161,11 @@ void TC4_Handler()
158
161
}
159
162
}
160
163
161
- void TC5_Handler ()
162
- {
163
- if (TC5 -> COUNT16 .INTFLAG .bit .MC0 )
164
- {
165
- TC5 -> COUNT16 .INTFLAG .reg = TC_INTENCLR_MC0 ;
166
- us_delay_done = 1 ;
167
- TC5 -> COUNT16 .CTRLA .bit .ENABLE = 0 ;
168
- while (TC5 -> COUNT16 .SYNCBUSY .bit .ENABLE ) {}
169
- }
170
- }
171
-
172
164
uint32_t CLK_enable_timebase (void )
173
165
{
174
166
Gclk * pgclk = GCLK ;
175
167
Mclk * pmclk = MCLK ;
176
168
Tc * ptc4 = TC4 ;
177
- Tc * ptc5 = TC5 ;
178
169
Tc * ptc0 = TC0 ;
179
170
Evsys * pevsys = EVSYS ;
180
171
@@ -189,11 +180,6 @@ uint32_t CLK_enable_timebase(void)
189
180
pgclk -> PCHCTRL [TC4_GCLK_ID ].bit .GEN = GEN_TC45 ;
190
181
pgclk -> PCHCTRL [TC4_GCLK_ID ].bit .CHEN = 1 ;
191
182
192
- //unmask TC5 sourcegclk2 to TC5
193
- pmclk -> APBCMASK .bit .TC5_ = 1 ;
194
- pgclk -> PCHCTRL [TC5_GCLK_ID ].bit .GEN = GEN_TC45 ;
195
- pgclk -> PCHCTRL [TC5_GCLK_ID ].bit .CHEN = 1 ;
196
-
197
183
//configure TC4
198
184
DBGC (DC_CLK_ENABLE_TIMEBASE_TC4_BEGIN );
199
185
ptc4 -> COUNT16 .CTRLA .bit .ENABLE = 0 ;
@@ -220,30 +206,6 @@ uint32_t CLK_enable_timebase(void)
220
206
221
207
DBGC (DC_CLK_ENABLE_TIMEBASE_TC4_COMPLETE );
222
208
223
- //configure TC5
224
- DBGC (DC_CLK_ENABLE_TIMEBASE_TC5_BEGIN );
225
- ptc5 -> COUNT16 .CTRLA .bit .ENABLE = 0 ;
226
- while (ptc5 -> COUNT16 .SYNCBUSY .bit .ENABLE ) { DBGC (DC_CLK_ENABLE_TIMEBASE_TC5_SYNC_DISABLE ); }
227
- ptc5 -> COUNT16 .CTRLA .bit .SWRST = 1 ;
228
- while (ptc5 -> COUNT16 .SYNCBUSY .bit .SWRST ) { DBGC (DC_CLK_ENABLE_TIMEBASE_TC5_SYNC_SWRST_1 ); }
229
- while (ptc5 -> COUNT16 .CTRLA .bit .SWRST ) { DBGC (DC_CLK_ENABLE_TIMEBASE_TC5_SYNC_SWRST_2 ); }
230
-
231
- //CTRLA defaults
232
- //CTRLB as default, counting up
233
- ptc5 -> COUNT16 .CTRLBCLR .reg = 5 ;
234
- while (ptc5 -> COUNT16 .SYNCBUSY .bit .CTRLB ) { DBGC (DC_CLK_ENABLE_TIMEBASE_TC5_SYNC_CLTRB ); }
235
- //ptc5->COUNT16.DBGCTRL.bit.DBGRUN = 1;
236
-
237
- //wave mode
238
- ptc5 -> COUNT16 .WAVE .bit .WAVEGEN = 1 ; //MFRQ match frequency mode, toggle each CC match
239
- //generate event for next stage
240
- ptc5 -> COUNT16 .EVCTRL .bit .MCEO0 = 1 ;
241
-
242
- NVIC_EnableIRQ (TC5_IRQn );
243
- ptc5 -> COUNT16 .INTENSET .bit .MC0 = 1 ;
244
-
245
- DBGC (DC_CLK_ENABLE_TIMEBASE_TC5_COMPLETE );
246
-
247
209
//unmask TC0,1, sourcegclk2 to TC0,1
248
210
pmclk -> APBAMASK .bit .TC0_ = 1 ;
249
211
pgclk -> PCHCTRL [TC0_GCLK_ID ].bit .GEN = GEN_TC45 ;
@@ -289,37 +251,27 @@ uint32_t CLK_enable_timebase(void)
289
251
return 0 ;
290
252
}
291
253
292
- uint32_t CLK_get_ms ( void )
254
+ void CLK_delay_us ( uint32_t usec )
293
255
{
294
- return ms_clk ;
295
- }
296
-
297
- void CLK_delay_us (uint16_t usec )
298
- {
299
- us_delay_done = 0 ;
300
-
301
- if (TC5 -> COUNT16 .CTRLA .bit .ENABLE )
302
- {
303
- TC5 -> COUNT16 .CTRLA .bit .ENABLE = 0 ;
304
- while (TC5 -> COUNT16 .SYNCBUSY .bit .ENABLE ) {}
305
- }
306
-
307
- if (usec < 10 ) usec = 0 ;
308
- else usec -= 10 ;
309
-
310
- TC5 -> COUNT16 .CC [0 ].reg = usec ;
311
- while (TC5 -> COUNT16 .SYNCBUSY .bit .CC0 ) {}
312
-
313
- TC5 -> COUNT16 .CTRLA .bit .ENABLE = 1 ;
314
- while (TC5 -> COUNT16 .SYNCBUSY .bit .ENABLE ) {}
315
-
316
- while (!us_delay_done ) {}
256
+ asm (
257
+ "CBZ R0, return\n\t" //If usec == 0, branch to return label
258
+ );
259
+ asm (
260
+ "MULS R0, %0\n\t" //Multiply R0(usec) by usec_delay_mult and store in R0
261
+ ".balign 16\n\t" //Ensure loop is aligned for fastest performance
262
+ "loop: SUBS R0, #1\n\t" //Subtract 1 from R0 and update flags (1 cycle)
263
+ "BNE loop\n\t" //Branch if non-zero to loop label (2 cycles) NOTE: USEC_DELAY_LOOP_CYCLES is the sum of loop cycles
264
+ "return:\n\t" //Return label
265
+ : //No output registers
266
+ : "r" (usec_delay_mult ) //For %0
267
+ );
268
+ //Note: BX LR generated
317
269
}
318
270
319
271
void CLK_delay_ms (uint64_t msec )
320
272
{
321
- msec += CLK_get_ms ();
322
- while (msec > CLK_get_ms ()) {}
273
+ msec += timer_read64 ();
274
+ while (msec > timer_read64 ()) {}
323
275
}
324
276
325
277
void clk_enable_sercom_apbmask (int sercomn )
0 commit comments