Index

auto-plow / 1ca92fc

A wheelchair motor-propelled battery-powered ESP32-driven remote control snow plow.

Latest Commit

{#}TimeHashSubjectAuthor#(+)(-)GPG?
630 Nov 2018 18:364a63c8cInclude Arduino core filesJoshua13920N

Blob @ auto-plow / include / arduino / wiring.c

text/plain11963 bytesdownload raw
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
38volatile unsigned long timer0_overflow_count = 0;
39volatile unsigned long timer0_millis = 0;
40static unsigned char timer0_fract = 0;
41
42#if defined(TIM0_OVF_vect)
43ISR(TIM0_OVF_vect)
44#else
45ISR(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;
62 timer0_overflow_count++;
63}
64
65unsigned 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
79unsigned long micros() {
80 unsigned long m;
81 uint8_t oldSREG = SREG, t;
82
83 cli();
84 m = timer0_overflow_count;
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
106void 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. */
120void 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
241void 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}
393