wiring.c
Go to the documentation of this file.
1 /*
2  wiring.c - Partial implementation of the Wiring API for the ATmega8.
3  Part of Arduino - http://www.arduino.cc/
4 
5  Copyright (c) 2005-2006 David A. Mellis
6 
7  This library is free software; you can redistribute it and/or
8  modify it under the terms of the GNU Lesser General Public
9  License as published by the Free Software Foundation; either
10  version 2.1 of the License, or (at your option) any later version.
11 
12  This library is distributed in the hope that it will be useful,
13  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15  Lesser General Public License for more details.
16 
17  You should have received a copy of the GNU Lesser General
18  Public License along with this library; if not, write to the
19  Free Software Foundation, Inc., 59 Temple Place, Suite 330,
20  Boston, MA 02111-1307 USA
21 */
22 
23 #include "wiring_private.h"
24 
25 // the prescaler is set so that timer0 ticks every 64 clock cycles, and the
26 // the overflow handler is called every 256 ticks.
27 #define MICROSECONDS_PER_TIMER0_OVERFLOW (clockCyclesToMicroseconds(64 * 256))
28 
29 // the whole number of milliseconds per timer0 overflow
30 #define MILLIS_INC (MICROSECONDS_PER_TIMER0_OVERFLOW / 1000)
31 
32 // the fractional number of milliseconds per timer0 overflow. we shift right
33 // by three to fit these numbers into a byte. (for the clock speeds we care
34 // about - 8 and 16 MHz - this doesn't lose precision.)
35 #define FRACT_INC ((MICROSECONDS_PER_TIMER0_OVERFLOW % 1000) >> 3)
36 #define FRACT_MAX (1000 >> 3)
37 
38 volatile unsigned long timer0_overflow_count = 0;
39 volatile unsigned long timer0_millis = 0;
40 static unsigned char timer0_fract = 0;
41 
42 #if defined(__AVR_ATtiny24__) || defined(__AVR_ATtiny44__) || defined(__AVR_ATtiny84__)
43 ISR(TIM0_OVF_vect)
44 #else
45 ISR(TIMER0_OVF_vect)
46 #endif
47 {
48  // copy these to local variables so they can be stored in registers
49  // (volatile variables must be read from memory on every access)
50  unsigned long m = timer0_millis;
51  unsigned char f = timer0_fract;
52 
53  m += MILLIS_INC;
54  f += FRACT_INC;
55  if (f >= FRACT_MAX) {
56  f -= FRACT_MAX;
57  m += 1;
58  }
59 
60  timer0_fract = f;
61  timer0_millis = m;
63 }
64 
65 unsigned long millis()
66 {
67  unsigned long m;
68  uint8_t oldSREG = SREG;
69 
70  // disable interrupts while we read timer0_millis or we might get an
71  // inconsistent value (e.g. in the middle of a write to timer0_millis)
72  cli();
73  m = timer0_millis;
74  SREG = oldSREG;
75 
76  return m;
77 }
78 
79 unsigned long micros() {
80  unsigned long m;
81  uint8_t oldSREG = SREG, t;
82 
83  cli();
85 #if defined(TCNT0)
86  t = TCNT0;
87 #elif defined(TCNT0L)
88  t = TCNT0L;
89 #else
90  #error TIMER 0 not defined
91 #endif
92 
93 #ifdef TIFR0
94  if ((TIFR0 & _BV(TOV0)) && (t < 255))
95  m++;
96 #else
97  if ((TIFR & _BV(TOV0)) && (t < 255))
98  m++;
99 #endif
100 
101  SREG = oldSREG;
102 
103  return ((m << 8) + t) * (64 / clockCyclesPerMicrosecond());
104 }
105 
106 void delay(unsigned long ms)
107 {
108  uint32_t start = micros();
109 
110  while (ms > 0) {
111  yield();
112  while ( ms > 0 && (micros() - start) >= 1000) {
113  ms--;
114  start += 1000;
115  }
116  }
117 }
118 
119 /* Delay for the given number of microseconds. Assumes a 1, 8, 12, 16, 20 or 24 MHz clock. */
120 void delayMicroseconds(unsigned int us)
121 {
122  // call = 4 cycles + 2 to 4 cycles to init us(2 for constant delay, 4 for variable)
123 
124  // calling avrlib's delay_us() function with low values (e.g. 1 or
125  // 2 microseconds) gives delays longer than desired.
126  //delay_us(us);
127 #if F_CPU >= 24000000L
128  // for the 24 MHz clock for the aventurous ones, trying to overclock
129 
130  // zero delay fix
131  if (!us) return; // = 3 cycles, (4 when true)
132 
133  // the following loop takes a 1/6 of a microsecond (4 cycles)
134  // per iteration, so execute it six times for each microsecond of
135  // delay requested.
136  us *= 6; // x6 us, = 7 cycles
137 
138  // account for the time taken in the preceeding commands.
139  // we just burned 22 (24) cycles above, remove 5, (5*4=20)
140  // us is at least 6 so we can substract 5
141  us -= 5; //=2 cycles
142 
143 #elif F_CPU >= 20000000L
144  // for the 20 MHz clock on rare Arduino boards
145 
146  // for a one-microsecond delay, simply return. the overhead
147  // of the function call takes 18 (20) cycles, which is 1us
148  __asm__ __volatile__ (
149  "nop" "\n\t"
150  "nop" "\n\t"
151  "nop" "\n\t"
152  "nop"); //just waiting 4 cycles
153  if (us <= 1) return; // = 3 cycles, (4 when true)
154 
155  // the following loop takes a 1/5 of a microsecond (4 cycles)
156  // per iteration, so execute it five times for each microsecond of
157  // delay requested.
158  us = (us << 2) + us; // x5 us, = 7 cycles
159 
160  // account for the time taken in the preceeding commands.
161  // we just burned 26 (28) cycles above, remove 7, (7*4=28)
162  // us is at least 10 so we can substract 7
163  us -= 7; // 2 cycles
164 
165 #elif F_CPU >= 16000000L
166  // for the 16 MHz clock on most Arduino boards
167 
168  // for a one-microsecond delay, simply return. the overhead
169  // of the function call takes 14 (16) cycles, which is 1us
170  if (us <= 1) return; // = 3 cycles, (4 when true)
171 
172  // the following loop takes 1/4 of a microsecond (4 cycles)
173  // per iteration, so execute it four times for each microsecond of
174  // delay requested.
175  us <<= 2; // x4 us, = 4 cycles
176 
177  // account for the time taken in the preceeding commands.
178  // we just burned 19 (21) cycles above, remove 5, (5*4=20)
179  // us is at least 8 so we can substract 5
180  us -= 5; // = 2 cycles,
181 
182 #elif F_CPU >= 12000000L
183  // for the 12 MHz clock if somebody is working with USB
184 
185  // for a 1 microsecond delay, simply return. the overhead
186  // of the function call takes 14 (16) cycles, which is 1.5us
187  if (us <= 1) return; // = 3 cycles, (4 when true)
188 
189  // the following loop takes 1/3 of a microsecond (4 cycles)
190  // per iteration, so execute it three times for each microsecond of
191  // delay requested.
192  us = (us << 1) + us; // x3 us, = 5 cycles
193 
194  // account for the time taken in the preceeding commands.
195  // we just burned 20 (22) cycles above, remove 5, (5*4=20)
196  // us is at least 6 so we can substract 5
197  us -= 5; //2 cycles
198 
199 #elif F_CPU >= 8000000L
200  // for the 8 MHz internal clock
201 
202  // for a 1 and 2 microsecond delay, simply return. the overhead
203  // of the function call takes 14 (16) cycles, which is 2us
204  if (us <= 2) return; // = 3 cycles, (4 when true)
205 
206  // the following loop takes 1/2 of a microsecond (4 cycles)
207  // per iteration, so execute it twice for each microsecond of
208  // delay requested.
209  us <<= 1; //x2 us, = 2 cycles
210 
211  // account for the time taken in the preceeding commands.
212  // we just burned 17 (19) cycles above, remove 4, (4*4=16)
213  // us is at least 6 so we can substract 4
214  us -= 4; // = 2 cycles
215 
216 #else
217  // for the 1 MHz internal clock (default settings for common Atmega microcontrollers)
218 
219  // the overhead of the function calls is 14 (16) cycles
220  if (us <= 16) return; //= 3 cycles, (4 when true)
221  if (us <= 25) return; //= 3 cycles, (4 when true), (must be at least 25 if we want to substract 22)
222 
223  // compensate for the time taken by the preceeding and next commands (about 22 cycles)
224  us -= 22; // = 2 cycles
225  // the following loop takes 4 microseconds (4 cycles)
226  // per iteration, so execute it us/4 times
227  // us is at least 4, divided by 4 gives us 1 (no zero delay bug)
228  us >>= 2; // us div 4, = 4 cycles
229 
230 
231 #endif
232 
233  // busy wait
234  __asm__ __volatile__ (
235  "1: sbiw %0,1" "\n\t" // 2 cycles
236  "brne 1b" : "=w" (us) : "0" (us) // 2 cycles
237  );
238  // return = 4 cycles
239 }
240 
241 void init()
242 {
243  // this needs to be called before setup() or some functions won't
244  // work there
245  sei();
246 
247  // on the ATmega168, timer 0 is also used for fast hardware pwm
248  // (using phase-correct PWM would mean that timer 0 overflowed half as often
249  // resulting in different millis() behavior on the ATmega8 and ATmega168)
250 #if defined(TCCR0A) && defined(WGM01)
251  sbi(TCCR0A, WGM01);
252  sbi(TCCR0A, WGM00);
253 #endif
254 
255  // set timer 0 prescale factor to 64
256 #if defined(__AVR_ATmega128__)
257  // CPU specific: different values for the ATmega128
258  sbi(TCCR0, CS02);
259 #elif defined(TCCR0) && defined(CS01) && defined(CS00)
260  // this combination is for the standard atmega8
261  sbi(TCCR0, CS01);
262  sbi(TCCR0, CS00);
263 #elif defined(TCCR0B) && defined(CS01) && defined(CS00)
264  // this combination is for the standard 168/328/1280/2560
265  sbi(TCCR0B, CS01);
266  sbi(TCCR0B, CS00);
267 #elif defined(TCCR0A) && defined(CS01) && defined(CS00)
268  // this combination is for the __AVR_ATmega645__ series
269  sbi(TCCR0A, CS01);
270  sbi(TCCR0A, CS00);
271 #else
272  #error Timer 0 prescale factor 64 not set correctly
273 #endif
274 
275  // enable timer 0 overflow interrupt
276 #if defined(TIMSK) && defined(TOIE0)
277  sbi(TIMSK, TOIE0);
278 #elif defined(TIMSK0) && defined(TOIE0)
279  sbi(TIMSK0, TOIE0);
280 #else
281  #error Timer 0 overflow interrupt not set correctly
282 #endif
283 
284  // timers 1 and 2 are used for phase-correct hardware pwm
285  // this is better for motors as it ensures an even waveform
286  // note, however, that fast pwm mode can achieve a frequency of up
287  // 8 MHz (with a 16 MHz clock) at 50% duty cycle
288 
289 #if defined(TCCR1B) && defined(CS11) && defined(CS10)
290  TCCR1B = 0;
291 
292  // set timer 1 prescale factor to 64
293  sbi(TCCR1B, CS11);
294 #if F_CPU >= 8000000L
295  sbi(TCCR1B, CS10);
296 #endif
297 #elif defined(TCCR1) && defined(CS11) && defined(CS10)
298  sbi(TCCR1, CS11);
299 #if F_CPU >= 8000000L
300  sbi(TCCR1, CS10);
301 #endif
302 #endif
303  // put timer 1 in 8-bit phase correct pwm mode
304 #if defined(TCCR1A) && defined(WGM10)
305  sbi(TCCR1A, WGM10);
306 #endif
307 
308  // set timer 2 prescale factor to 64
309 #if defined(TCCR2) && defined(CS22)
310  sbi(TCCR2, CS22);
311 #elif defined(TCCR2B) && defined(CS22)
312  sbi(TCCR2B, CS22);
313 //#else
314  // Timer 2 not finished (may not be present on this CPU)
315 #endif
316 
317  // configure timer 2 for phase correct pwm (8-bit)
318 #if defined(TCCR2) && defined(WGM20)
319  sbi(TCCR2, WGM20);
320 #elif defined(TCCR2A) && defined(WGM20)
321  sbi(TCCR2A, WGM20);
322 //#else
323  // Timer 2 not finished (may not be present on this CPU)
324 #endif
325 
326 #if defined(TCCR3B) && defined(CS31) && defined(WGM30)
327  sbi(TCCR3B, CS31); // set timer 3 prescale factor to 64
328  sbi(TCCR3B, CS30);
329  sbi(TCCR3A, WGM30); // put timer 3 in 8-bit phase correct pwm mode
330 #endif
331 
332 #if defined(TCCR4A) && defined(TCCR4B) && defined(TCCR4D) /* beginning of timer4 block for 32U4 and similar */
333  sbi(TCCR4B, CS42); // set timer4 prescale factor to 64
334  sbi(TCCR4B, CS41);
335  sbi(TCCR4B, CS40);
336  sbi(TCCR4D, WGM40); // put timer 4 in phase- and frequency-correct PWM mode
337  sbi(TCCR4A, PWM4A); // enable PWM mode for comparator OCR4A
338  sbi(TCCR4C, PWM4D); // enable PWM mode for comparator OCR4D
339 #else /* beginning of timer4 block for ATMEGA1280 and ATMEGA2560 */
340 #if defined(TCCR4B) && defined(CS41) && defined(WGM40)
341  sbi(TCCR4B, CS41); // set timer 4 prescale factor to 64
342  sbi(TCCR4B, CS40);
343  sbi(TCCR4A, WGM40); // put timer 4 in 8-bit phase correct pwm mode
344 #endif
345 #endif /* end timer4 block for ATMEGA1280/2560 and similar */
346 
347 #if defined(TCCR5B) && defined(CS51) && defined(WGM50)
348  sbi(TCCR5B, CS51); // set timer 5 prescale factor to 64
349  sbi(TCCR5B, CS50);
350  sbi(TCCR5A, WGM50); // put timer 5 in 8-bit phase correct pwm mode
351 #endif
352 
353 #if defined(ADCSRA)
354  // set a2d prescaler so we are inside the desired 50-200 KHz range.
355  #if F_CPU >= 16000000 // 16 MHz / 128 = 125 KHz
356  sbi(ADCSRA, ADPS2);
357  sbi(ADCSRA, ADPS1);
358  sbi(ADCSRA, ADPS0);
359  #elif F_CPU >= 8000000 // 8 MHz / 64 = 125 KHz
360  sbi(ADCSRA, ADPS2);
361  sbi(ADCSRA, ADPS1);
362  cbi(ADCSRA, ADPS0);
363  #elif F_CPU >= 4000000 // 4 MHz / 32 = 125 KHz
364  sbi(ADCSRA, ADPS2);
365  cbi(ADCSRA, ADPS1);
366  sbi(ADCSRA, ADPS0);
367  #elif F_CPU >= 2000000 // 2 MHz / 16 = 125 KHz
368  sbi(ADCSRA, ADPS2);
369  cbi(ADCSRA, ADPS1);
370  cbi(ADCSRA, ADPS0);
371  #elif F_CPU >= 1000000 // 1 MHz / 8 = 125 KHz
372  cbi(ADCSRA, ADPS2);
373  sbi(ADCSRA, ADPS1);
374  sbi(ADCSRA, ADPS0);
375  #else // 128 kHz / 2 = 64 KHz -> This is the closest you can get, the prescaler is 2
376  cbi(ADCSRA, ADPS2);
377  cbi(ADCSRA, ADPS1);
378  sbi(ADCSRA, ADPS0);
379  #endif
380  // enable a2d conversions
381  sbi(ADCSRA, ADEN);
382 #endif
383 
384  // the bootloader connects pins 0 and 1 to the USART; disconnect them
385  // here so they can be used as normal digital i/o; they will be
386  // reconnected in Serial.begin()
387 #if defined(UCSRB)
388  UCSRB = 0;
389 #elif defined(UCSR0B)
390  UCSR0B = 0;
391 #endif
392 }
void delay(unsigned long ms)
Definition: wiring.c:106
unsigned long millis()
Definition: wiring.c:65
#define MILLIS_INC
Definition: wiring.c:30
GLdouble GLdouble t
#define FRACT_MAX
Definition: wiring.c:36
GLuint start
volatile unsigned long timer0_overflow_count
Definition: wiring.c:38
unsigned int uint32_t
m
Definition: wiring.c:53
#define clockCyclesPerMicrosecond()
Definition: Arduino.h:104
void init()
Definition: wiring.c:241
ISR(TIMER2_COMPA_vect)
Definition: Tone.cpp:538
#define cbi(sfr, bit)
unsigned long micros()
Definition: wiring.c:79
volatile unsigned long timer0_millis
Definition: wiring.c:39
static unsigned char timer0_fract
Definition: wiring.c:40
void yield(void)
const GLdouble * m
void delayMicroseconds(unsigned int us)
Definition: wiring.c:120
#define FRACT_INC
Definition: wiring.c:35
unsigned char f
Definition: wiring.c:51
#define sbi(sfr, bit)
GLdouble GLdouble GLdouble GLdouble GLdouble GLdouble f


arduino_daq
Author(s):
autogenerated on Mon Jun 10 2019 12:46:03