Thu, 07 Jul 2016 12:23:34 +0200
added missing sanguino files
2 | 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 | $Id$ | |
23 | */ | |
24 | ||
25 | #include "wiring_private.h" | |
26 | ||
27 | // the prescaler is set so that timer0 ticks every 64 clock cycles, and the | |
28 | // the overflow handler is called every 256 ticks. | |
29 | #define MICROSECONDS_PER_TIMER0_OVERFLOW (clockCyclesToMicroseconds(64 * 256)) | |
30 | ||
31 | // the whole number of milliseconds per timer0 overflow | |
32 | #define MILLIS_INC (MICROSECONDS_PER_TIMER0_OVERFLOW / 1000) | |
33 | ||
34 | // the fractional number of milliseconds per timer0 overflow. we shift right | |
35 | // by three to fit these numbers into a byte. (for the clock speeds we care | |
36 | // about - 8 and 16 MHz - this doesn't lose precision.) | |
37 | #define FRACT_INC ((MICROSECONDS_PER_TIMER0_OVERFLOW % 1000) >> 3) | |
38 | #define FRACT_MAX (1000 >> 3) | |
39 | ||
40 | volatile unsigned long timer0_overflow_count = 0; | |
41 | volatile unsigned long timer0_millis = 0; | |
42 | static unsigned char timer0_fract = 0; | |
43 | ||
44 | #if defined(__AVR_ATtiny24__) || defined(__AVR_ATtiny44__) || defined(__AVR_ATtiny84__) | |
45 | SIGNAL(TIM0_OVF_vect) | |
46 | #else | |
47 | SIGNAL(TIMER0_OVF_vect) | |
48 | #endif | |
49 | { | |
50 | // copy these to local variables so they can be stored in registers | |
51 | // (volatile variables must be read from memory on every access) | |
52 | unsigned long m = timer0_millis; | |
53 | unsigned char f = timer0_fract; | |
54 | ||
55 | m += MILLIS_INC; | |
56 | f += FRACT_INC; | |
57 | if (f >= FRACT_MAX) { | |
58 | f -= FRACT_MAX; | |
59 | m += 1; | |
60 | } | |
61 | ||
62 | timer0_fract = f; | |
63 | timer0_millis = m; | |
64 | timer0_overflow_count++; | |
65 | } | |
66 | ||
67 | unsigned long millis() | |
68 | { | |
69 | unsigned long m; | |
70 | uint8_t oldSREG = SREG; | |
71 | ||
72 | // disable interrupts while we read timer0_millis or we might get an | |
73 | // inconsistent value (e.g. in the middle of a write to timer0_millis) | |
74 | cli(); | |
75 | m = timer0_millis; | |
76 | SREG = oldSREG; | |
77 | ||
78 | return m; | |
79 | } | |
80 | ||
81 | unsigned long micros() { | |
82 | unsigned long m; | |
83 | uint8_t oldSREG = SREG, t; | |
84 | ||
85 | cli(); | |
86 | m = timer0_overflow_count; | |
87 | #if defined(TCNT0) | |
88 | t = TCNT0; | |
89 | #elif defined(TCNT0L) | |
90 | t = TCNT0L; | |
91 | #else | |
92 | #error TIMER 0 not defined | |
93 | #endif | |
94 | ||
95 | ||
96 | #ifdef TIFR0 | |
97 | if ((TIFR0 & _BV(TOV0)) && (t < 255)) | |
98 | m++; | |
99 | #else | |
100 | if ((TIFR & _BV(TOV0)) && (t < 255)) | |
101 | m++; | |
102 | #endif | |
103 | ||
104 | SREG = oldSREG; | |
105 | ||
106 | return ((m << 8) + t) * (64 / clockCyclesPerMicrosecond()); | |
107 | } | |
108 | ||
109 | void delay(unsigned long ms) | |
110 | { | |
111 | uint16_t start = (uint16_t)micros(); | |
112 | ||
113 | while (ms > 0) { | |
114 | if (((uint16_t)micros() - start) >= 1000) { | |
115 | ms--; | |
116 | start += 1000; | |
117 | } | |
118 | } | |
119 | } | |
120 | ||
121 | /* Delay for the given number of microseconds. Assumes a 8 or 16 MHz clock. */ | |
122 | void delayMicroseconds(unsigned int us) | |
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 >= 20000000L | |
128 | // for the 20 MHz clock on rare Arduino boards | |
129 | ||
130 | // for a one-microsecond delay, simply wait 2 cycle and return. The overhead | |
131 | // of the function call yields a delay of exactly a one microsecond. | |
132 | __asm__ __volatile__ ( | |
133 | "nop" "\n\t" | |
134 | "nop"); //just waiting 2 cycle | |
135 | if (--us == 0) | |
136 | return; | |
137 | ||
138 | // the following loop takes a 1/5 of a microsecond (4 cycles) | |
139 | // per iteration, so execute it five times for each microsecond of | |
140 | // delay requested. | |
141 | us = (us<<2) + us; // x5 us | |
142 | ||
143 | // account for the time taken in the preceeding commands. | |
144 | us -= 2; | |
145 | ||
146 | #elif F_CPU >= 16000000L | |
147 | // for the 16 MHz clock on most Arduino boards | |
148 | ||
149 | // for a one-microsecond delay, simply return. the overhead | |
150 | // of the function call yields a delay of approximately 1 1/8 us. | |
151 | if (--us == 0) | |
152 | return; | |
153 | ||
154 | // the following loop takes a quarter of a microsecond (4 cycles) | |
155 | // per iteration, so execute it four times for each microsecond of | |
156 | // delay requested. | |
157 | us <<= 2; | |
158 | ||
159 | // account for the time taken in the preceeding commands. | |
160 | us -= 2; | |
161 | #else | |
162 | // for the 8 MHz internal clock on the ATmega168 | |
163 | ||
164 | // for a one- or two-microsecond delay, simply return. the overhead of | |
165 | // the function calls takes more than two microseconds. can't just | |
166 | // subtract two, since us is unsigned; we'd overflow. | |
167 | if (--us == 0) | |
168 | return; | |
169 | if (--us == 0) | |
170 | return; | |
171 | ||
172 | // the following loop takes half of a microsecond (4 cycles) | |
173 | // per iteration, so execute it twice for each microsecond of | |
174 | // delay requested. | |
175 | us <<= 1; | |
176 | ||
177 | // partially compensate for the time taken by the preceeding commands. | |
178 | // we can't subtract any more than this or we'd overflow w/ small delays. | |
179 | us--; | |
180 | #endif | |
181 | ||
182 | // busy wait | |
183 | __asm__ __volatile__ ( | |
184 | "1: sbiw %0,1" "\n\t" // 2 cycles | |
185 | "brne 1b" : "=w" (us) : "0" (us) // 2 cycles | |
186 | ); | |
187 | } | |
188 | ||
189 | void init() | |
190 | { | |
191 | // this needs to be called before setup() or some functions won't | |
192 | // work there | |
193 | sei(); | |
194 | ||
195 | // on the ATmega168, timer 0 is also used for fast hardware pwm | |
196 | // (using phase-correct PWM would mean that timer 0 overflowed half as often | |
197 | // resulting in different millis() behavior on the ATmega8 and ATmega168) | |
198 | #if defined(TCCR0A) && defined(WGM01) | |
199 | sbi(TCCR0A, WGM01); | |
200 | sbi(TCCR0A, WGM00); | |
201 | #endif | |
202 | ||
203 | // set timer 0 prescale factor to 64 | |
204 | #if defined(__AVR_ATmega128__) | |
205 | // CPU specific: different values for the ATmega128 | |
206 | sbi(TCCR0, CS02); | |
207 | #elif defined(TCCR0) && defined(CS01) && defined(CS00) | |
208 | // this combination is for the standard atmega8 | |
209 | sbi(TCCR0, CS01); | |
210 | sbi(TCCR0, CS00); | |
211 | #elif defined(TCCR0B) && defined(CS01) && defined(CS00) | |
212 | // this combination is for the standard 168/328/1280/2560 | |
213 | sbi(TCCR0B, CS01); | |
214 | sbi(TCCR0B, CS00); | |
215 | #elif defined(TCCR0A) && defined(CS01) && defined(CS00) | |
216 | // this combination is for the __AVR_ATmega645__ series | |
217 | sbi(TCCR0A, CS01); | |
218 | sbi(TCCR0A, CS00); | |
219 | #else | |
220 | #error Timer 0 prescale factor 64 not set correctly | |
221 | #endif | |
222 | ||
223 | // enable timer 0 overflow interrupt | |
224 | #if defined(TIMSK) && defined(TOIE0) | |
225 | sbi(TIMSK, TOIE0); | |
226 | #elif defined(TIMSK0) && defined(TOIE0) | |
227 | sbi(TIMSK0, TOIE0); | |
228 | #else | |
229 | #error Timer 0 overflow interrupt not set correctly | |
230 | #endif | |
231 | ||
232 | // timers 1 and 2 are used for phase-correct hardware pwm | |
233 | // this is better for motors as it ensures an even waveform | |
234 | // note, however, that fast pwm mode can achieve a frequency of up | |
235 | // 8 MHz (with a 16 MHz clock) at 50% duty cycle | |
236 | ||
237 | #if defined(TCCR1B) && defined(CS11) && defined(CS10) | |
238 | TCCR1B = 0; | |
239 | ||
240 | // set timer 1 prescale factor to 64 | |
241 | sbi(TCCR1B, CS11); | |
242 | #if F_CPU >= 8000000L | |
243 | sbi(TCCR1B, CS10); | |
244 | #endif | |
245 | #elif defined(TCCR1) && defined(CS11) && defined(CS10) | |
246 | sbi(TCCR1, CS11); | |
247 | #if F_CPU >= 8000000L | |
248 | sbi(TCCR1, CS10); | |
249 | #endif | |
250 | #endif | |
251 | // put timer 1 in 8-bit phase correct pwm mode | |
252 | #if defined(TCCR1A) && defined(WGM10) | |
253 | sbi(TCCR1A, WGM10); | |
254 | #elif defined(TCCR1) | |
255 | #warning this needs to be finished | |
256 | #endif | |
257 | ||
258 | // set timer 2 prescale factor to 64 | |
259 | #if defined(TCCR2) && defined(CS22) | |
260 | sbi(TCCR2, CS22); | |
261 | #elif defined(TCCR2B) && defined(CS22) | |
262 | sbi(TCCR2B, CS22); | |
263 | #else | |
264 | #warning Timer 2 not finished (may not be present on this CPU) | |
265 | #endif | |
266 | ||
267 | // configure timer 2 for phase correct pwm (8-bit) | |
268 | #if defined(TCCR2) && defined(WGM20) | |
269 | sbi(TCCR2, WGM20); | |
270 | #elif defined(TCCR2A) && defined(WGM20) | |
271 | sbi(TCCR2A, WGM20); | |
272 | #else | |
273 | #warning Timer 2 not finished (may not be present on this CPU) | |
274 | #endif | |
275 | ||
276 | #if defined(TCCR3B) && defined(CS31) && defined(WGM30) | |
277 | sbi(TCCR3B, CS31); // set timer 3 prescale factor to 64 | |
278 | sbi(TCCR3B, CS30); | |
279 | sbi(TCCR3A, WGM30); // put timer 3 in 8-bit phase correct pwm mode | |
280 | #endif | |
281 | ||
282 | #if defined(TCCR4A) && defined(TCCR4B) && defined(TCCR4D) /* beginning of timer4 block for 32U4 and similar */ | |
283 | sbi(TCCR4B, CS42); // set timer4 prescale factor to 64 | |
284 | sbi(TCCR4B, CS41); | |
285 | sbi(TCCR4B, CS40); | |
286 | sbi(TCCR4D, WGM40); // put timer 4 in phase- and frequency-correct PWM mode | |
287 | sbi(TCCR4A, PWM4A); // enable PWM mode for comparator OCR4A | |
288 | sbi(TCCR4C, PWM4D); // enable PWM mode for comparator OCR4D | |
289 | #else /* beginning of timer4 block for ATMEGA1280 and ATMEGA2560 */ | |
290 | #if defined(TCCR4B) && defined(CS41) && defined(WGM40) | |
291 | sbi(TCCR4B, CS41); // set timer 4 prescale factor to 64 | |
292 | sbi(TCCR4B, CS40); | |
293 | sbi(TCCR4A, WGM40); // put timer 4 in 8-bit phase correct pwm mode | |
294 | #endif | |
295 | #endif /* end timer4 block for ATMEGA1280/2560 and similar */ | |
296 | ||
297 | #if defined(TCCR5B) && defined(CS51) && defined(WGM50) | |
298 | sbi(TCCR5B, CS51); // set timer 5 prescale factor to 64 | |
299 | sbi(TCCR5B, CS50); | |
300 | sbi(TCCR5A, WGM50); // put timer 5 in 8-bit phase correct pwm mode | |
301 | #endif | |
302 | ||
303 | #if defined(ADCSRA) | |
304 | // set a2d prescale factor to 128 | |
305 | // 16 MHz / 128 = 125 KHz, inside the desired 50-200 KHz range. | |
306 | // XXX: this will not work properly for other clock speeds, and | |
307 | // this code should use F_CPU to determine the prescale factor. | |
308 | sbi(ADCSRA, ADPS2); | |
309 | sbi(ADCSRA, ADPS1); | |
310 | sbi(ADCSRA, ADPS0); | |
311 | ||
312 | // enable a2d conversions | |
313 | sbi(ADCSRA, ADEN); | |
314 | #endif | |
315 | ||
316 | // the bootloader connects pins 0 and 1 to the USART; disconnect them | |
317 | // here so they can be used as normal digital i/o; they will be | |
318 | // reconnected in Serial.begin() | |
319 | #if defined(UCSRB) | |
320 | UCSRB = 0; | |
321 | #elif defined(UCSR0B) | |
322 | UCSR0B = 0; | |
323 | #endif | |
324 | } |