@@ -123,118 +123,114 @@ void delay(unsigned long ms)
123
123
void delayMicroseconds (unsigned int us )
124
124
{
125
125
// call = 4 cycles + 2 to 4 cycles to init us(2 for constant delay, 4 for variable)
126
+
126
127
// calling avrlib's delay_us() function with low values (e.g. 1 or
127
128
// 2 microseconds) gives delays longer than desired.
128
129
//delay_us(us);
129
130
#if F_CPU >= 24000000L
130
131
// for the 24 MHz clock for the aventurous ones, trying to overclock
131
132
132
- // for a one-microsecond delay, simply wait 6 cycles and return. The overhead
133
- // of the function call yields a delay of exactly one microsecond.
134
- __asm__ __volatile__ (
135
- "nop" "\n\t"
136
- "nop" "\n\t"
137
- "nop" "\n\t"
138
- "nop" "\n\t"
139
- "nop" "\n\t"
140
- "nop" ); //just waiting 6 cycles
141
- if (-- us == 0 )
142
- return ;
133
+ // zero delay fix
134
+ if (!us ) return ; // = 3 cycles, (4 when true)
143
135
144
136
// the following loop takes a 1/6 of a microsecond (4 cycles)
145
137
// per iteration, so execute it six times for each microsecond of
146
138
// delay requested.
147
- us *= 6 ; // x6 us
139
+ us *= 6 ; // x6 us, = 7 cycles
148
140
149
141
// account for the time taken in the preceeding commands.
150
- us -= 2 ;
142
+ // we just burned 22 (24) cycles above, remove 5, (5*4=20)
143
+ // us is at least 6 so we can substract 5
144
+ us -= 5 ; //=2 cycles
151
145
152
146
#elif F_CPU >= 20000000L
153
147
// for the 20 MHz clock on rare Arduino boards
154
148
155
- // for a one-microsecond delay, simply wait 2 cycles and return. The overhead
156
- // of the function call yields a delay of exactly one microsecond.
149
+ // for a one-microsecond delay, simply return. the overhead
150
+ // of the function call takes 18 (20) cycles, which is 1us
157
151
__asm__ __volatile__ (
158
152
"nop" "\n\t"
159
- "nop" ); //just waiting 2 cycle
160
- if (-- us == 0 )
161
- return ;
153
+ "nop" "\n\t"
154
+ "nop" "\n\t"
155
+ "nop" ); //just waiting 4 cycles
156
+ if (us <= 1 ) return ; // = 3 cycles, (4 when true)
162
157
163
158
// the following loop takes a 1/5 of a microsecond (4 cycles)
164
159
// per iteration, so execute it five times for each microsecond of
165
160
// delay requested.
166
- us = (us << 2 ) + us ; // x5 us
161
+ us = (us << 2 ) + us ; // x5 us, = 7 cycles
167
162
168
163
// account for the time taken in the preceeding commands.
169
- us -= 2 ;
164
+ // we just burned 26 (28) cycles above, remove 7, (7*4=28)
165
+ // us is at least 10 so we can substract 7
166
+ us -= 7 ; // 2 cycles
170
167
171
168
#elif F_CPU >= 16000000L
172
169
// for the 16 MHz clock on most Arduino boards
173
170
174
171
// for a one-microsecond delay, simply return. the overhead
175
- // of the function call yields a delay of approximately 1 1/8 us.
176
- if (-- us == 0 )
177
- return ;
172
+ // of the function call takes 14 (16) cycles, which is 1us
173
+ if (us <= 1 ) return ; // = 3 cycles, (4 when true)
178
174
179
175
// the following loop takes 1/4 of a microsecond (4 cycles)
180
176
// per iteration, so execute it four times for each microsecond of
181
177
// delay requested.
182
- us <<= 2 ; // x4 us
178
+ us <<= 2 ; // x4 us, = 4 cycles
183
179
184
180
// account for the time taken in the preceeding commands.
185
- us -= 2 ;
181
+ // we just burned 19 (21) cycles above, remove 5, (5*4=20)
182
+ // us is at least 8 so we can substract 5
183
+ us -= 5 ; // = 2 cycles,
186
184
187
185
#elif F_CPU >= 12000000L
188
186
// for the 12 MHz clock if somebody is working with USB
189
187
190
- // for a one-microsecond delay, simply return. the overhead
191
- // of the function call yields a delay of approximately 1.5 us.
192
- if (-- us == 0 )
193
- return ;
188
+ // for a 1 microsecond delay, simply return. the overhead
189
+ // of the function call takes 14 (16) cycles, which is 1.5us
190
+ if (us <= 1 ) return ; // = 3 cycles, (4 when true)
194
191
195
192
// the following loop takes 1/3 of a microsecond (4 cycles)
196
193
// per iteration, so execute it three times for each microsecond of
197
194
// delay requested.
198
- us = (us << 1 ) + us ; // x3 us
195
+ us = (us << 1 ) + us ; // x3 us, = 5 cycles
199
196
200
197
// account for the time taken in the preceeding commands.
201
- us -= 2 ;
198
+ // we just burned 20 (22) cycles above, remove 5, (5*4=20)
199
+ // us is at least 6 so we can substract 5
200
+ us -= 5 ; //2 cycles
201
+
202
202
#elif F_CPU >= 8000000L
203
203
// for the 8 MHz internal clock
204
204
205
- // for a one- or two-microsecond delay, simply return. the overhead of
206
- // the function calls takes more than two microseconds. can't just
207
- // subtract two, since us is unsigned; we'd overflow.
208
- if (-- us == 0 )
209
- return ;
210
- if (-- us == 0 )
211
- return ;
205
+ // for a 1 and 2 microsecond delay, simply return. the overhead
206
+ // of the function call takes 14 (16) cycles, which is 2us
207
+ if (us <= 2 ) return ; // = 3 cycles, (4 when true)
212
208
213
209
// the following loop takes 1/2 of a microsecond (4 cycles)
214
210
// per iteration, so execute it twice for each microsecond of
215
211
// delay requested.
216
- us <<= 1 ; //x2 us
217
-
218
- // partially compensate for the time taken by the preceeding commands.
219
- // we can't subtract any more than this or we'd overflow w/ small delays.
220
- us -- ;
212
+ us <<= 1 ; //x2 us, = 2 cycles
213
+
214
+ // account for the time taken in the preceeding commands.
215
+ // we just burned 17 (19) cycles above, remove 4, (4*4=16)
216
+ // us is at least 6 so we can substract 4
217
+ us -= 4 ; // = 2 cycles
221
218
222
219
#else
223
220
// for the 1 MHz internal clock (default settings for common Atmega microcontrollers)
224
221
225
- // the overhead of the function calls takes about 16 microseconds.
226
- if (us <= 16 ) //4 cycles spent here
227
- return ;
228
- if (us <= 22 ) { //4 cycles spent here
229
- return ;
230
- }
231
-
232
- // compensate for the time taken by the preceeding and next commands.
233
- us -= 22 ;
222
+ // the overhead of the function calls is 14 (16) cycles
223
+ if (us <= 16 ) return ; //= 3 cycles, (4 when true)
224
+ if (us <= 25 ) return ; //= 3 cycles, (4 when true), (must be at least 25 if we want to substract 22)
234
225
226
+ // compensate for the time taken by the preceeding and next commands (about 22 cycles)
227
+ us -= 22 ; // = 2 cycles
235
228
// the following loop takes 4 microseconds (4 cycles)
236
229
// per iteration, so execute it us/4 times
237
- us >>= 2 ; // us div 4
230
+ // us is at least 4, divided by 4 gives us 1 (no zero delay bug)
231
+ us >>= 2 ; // us div 4, = 4 cycles
232
+
233
+
238
234
#endif
239
235
240
236
// busy wait
@@ -360,14 +356,32 @@ void init()
360
356
#endif
361
357
362
358
#if defined(ADCSRA )
363
- // set a2d prescale factor to 128
364
- // 16 MHz / 128 = 125 KHz, inside the desired 50-200 KHz range.
365
- // XXX: this will not work properly for other clock speeds, and
366
- // this code should use F_CPU to determine the prescale factor.
367
- sbi (ADCSRA , ADPS2 );
368
- sbi (ADCSRA , ADPS1 );
369
- sbi (ADCSRA , ADPS0 );
370
-
359
+ // set a2d prescaler so we are inside the desired 50-200 KHz range.
360
+ #if F_CPU >= 16000000 // 16 MHz / 128 = 125 KHz
361
+ sbi (ADCSRA , ADPS2 );
362
+ sbi (ADCSRA , ADPS1 );
363
+ sbi (ADCSRA , ADPS0 );
364
+ #elif F_CPU >= 8000000 // 8 MHz / 64 = 125 KHz
365
+ sbi (ADCSRA , ADPS2 );
366
+ sbi (ADCSRA , ADPS1 );
367
+ cbi (ADCSRA , ADPS0 );
368
+ #elif F_CPU >= 4000000 // 4 MHz / 32 = 125 KHz
369
+ sbi (ADCSRA , ADPS2 );
370
+ cbi (ADCSRA , ADPS1 );
371
+ sbi (ADCSRA , ADPS0 );
372
+ #elif F_CPU >= 2000000 // 2 MHz / 16 = 125 KHz
373
+ sbi (ADCSRA , ADPS2 );
374
+ cbi (ADCSRA , ADPS1 );
375
+ cbi (ADCSRA , ADPS0 );
376
+ #elif F_CPU >= 1000000 // 1 MHz / 8 = 125 KHz
377
+ cbi (ADCSRA , ADPS2 );
378
+ sbi (ADCSRA , ADPS1 );
379
+ sbi (ADCSRA , ADPS0 );
380
+ #else // 128 kHz / 2 = 64 KHz -> This is the closest you can get, the prescaler is 2
381
+ cbi (ADCSRA , ADPS2 );
382
+ cbi (ADCSRA , ADPS1 );
383
+ sbi (ADCSRA , ADPS0 );
384
+ #endif
371
385
// enable a2d conversions
372
386
sbi (ADCSRA , ADEN );
373
387
#endif
0 commit comments