@@ -123,118 +123,114 @@ void delay(unsigned long ms)
123123void delayMicroseconds (unsigned int us )
124124{
125125 // call = 4 cycles + 2 to 4 cycles to init us(2 for constant delay, 4 for variable)
126+
126127 // calling avrlib's delay_us() function with low values (e.g. 1 or
127128 // 2 microseconds) gives delays longer than desired.
128129 //delay_us(us);
129130#if F_CPU >= 24000000L
130131 // for the 24 MHz clock for the aventurous ones, trying to overclock
131132
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)
143135
144136 // the following loop takes a 1/6 of a microsecond (4 cycles)
145137 // per iteration, so execute it six times for each microsecond of
146138 // delay requested.
147- us *= 6 ; // x6 us
139+ us *= 6 ; // x6 us, = 7 cycles
148140
149141 // 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
151145
152146#elif F_CPU >= 20000000L
153147 // for the 20 MHz clock on rare Arduino boards
154148
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
157151 __asm__ __volatile__ (
158152 "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)
162157
163158 // the following loop takes a 1/5 of a microsecond (4 cycles)
164159 // per iteration, so execute it five times for each microsecond of
165160 // delay requested.
166- us = (us << 2 ) + us ; // x5 us
161+ us = (us << 2 ) + us ; // x5 us, = 7 cycles
167162
168163 // 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
170167
171168#elif F_CPU >= 16000000L
172169 // for the 16 MHz clock on most Arduino boards
173170
174171 // 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)
178174
179175 // the following loop takes 1/4 of a microsecond (4 cycles)
180176 // per iteration, so execute it four times for each microsecond of
181177 // delay requested.
182- us <<= 2 ; // x4 us
178+ us <<= 2 ; // x4 us, = 4 cycles
183179
184180 // 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,
186184
187185#elif F_CPU >= 12000000L
188186 // for the 12 MHz clock if somebody is working with USB
189187
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)
194191
195192 // the following loop takes 1/3 of a microsecond (4 cycles)
196193 // per iteration, so execute it three times for each microsecond of
197194 // delay requested.
198- us = (us << 1 ) + us ; // x3 us
195+ us = (us << 1 ) + us ; // x3 us, = 5 cycles
199196
200197 // 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+
202202#elif F_CPU >= 8000000L
203203 // for the 8 MHz internal clock
204204
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)
212208
213209 // the following loop takes 1/2 of a microsecond (4 cycles)
214210 // per iteration, so execute it twice for each microsecond of
215211 // 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
221218
222219#else
223220 // for the 1 MHz internal clock (default settings for common Atmega microcontrollers)
224221
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)
234225
226+ // compensate for the time taken by the preceeding and next commands (about 22 cycles)
227+ us -= 22 ; // = 2 cycles
235228 // the following loop takes 4 microseconds (4 cycles)
236229 // 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+
238234#endif
239235
240236 // busy wait
@@ -360,14 +356,32 @@ void init()
360356#endif
361357
362358#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
371385 // enable a2d conversions
372386 sbi (ADCSRA , ADEN );
373387#endif
0 commit comments