Fri, 17 Nov 2017 10:13:31 +0100
proper configuration, homing and planner optimization
2 | 1 | /* |
2 | wiring_analog.c - analog input and output | |
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 | Modified 28 September 2010 by Mark Sproul | |
23 | ||
24 | $Id: wiring.c 248 2007-02-03 15:36:30Z mellis $ | |
25 | */ | |
26 | ||
27 | #include "wiring_private.h" | |
28 | #include "pins_arduino.h" | |
29 | ||
30 | uint8_t analog_reference = DEFAULT; | |
31 | ||
32 | void analogReference(uint8_t mode) | |
33 | { | |
34 | // can't actually set the register here because the default setting | |
35 | // will connect AVCC and the AREF pin, which would cause a short if | |
36 | // there's something connected to AREF. | |
37 | analog_reference = mode; | |
38 | } | |
39 | ||
40 | int analogRead(uint8_t pin) | |
41 | { | |
42 | uint8_t low, high; | |
43 | ||
44 | #if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) | |
45 | if (pin >= 54) pin -= 54; // allow for channel or pin numbers | |
46 | #elif defined(__AVR_ATmega32U4__) | |
47 | if (pin >= 18) pin -= 18; // allow for channel or pin numbers | |
48 | #elif defined(__AVR_ATmega1284__) || defined(__AVR_ATmega644p__) | |
49 | if (pin >= 24) pin -= 24; // allow for channel or pin numbers | |
50 | #else | |
51 | if (pin >= 14) pin -= 14; // allow for channel or pin numbers | |
52 | #endif | |
53 | ||
54 | #if defined(__AVR_ATmega32U4__) | |
55 | pin = analogPinToChannel(pin); | |
56 | ADCSRB = (ADCSRB & ~(1 << MUX5)) | (((pin >> 3) & 0x01) << MUX5); | |
57 | #elif defined(ADCSRB) && defined(MUX5) | |
58 | // the MUX5 bit of ADCSRB selects whether we're reading from channels | |
59 | // 0 to 7 (MUX5 low) or 8 to 15 (MUX5 high). | |
60 | ADCSRB = (ADCSRB & ~(1 << MUX5)) | (((pin >> 3) & 0x01) << MUX5); | |
61 | #endif | |
62 | ||
63 | // set the analog reference (high two bits of ADMUX) and select the | |
64 | // channel (low 4 bits). this also sets ADLAR (left-adjust result) | |
65 | // to 0 (the default). | |
66 | #if defined(ADMUX) | |
67 | ADMUX = (analog_reference << 6) | (pin & 0x07); | |
68 | #endif | |
69 | ||
70 | // without a delay, we seem to read from the wrong channel | |
71 | //delay(1); | |
72 | ||
73 | #if defined(ADCSRA) && defined(ADCL) | |
74 | // start the conversion | |
75 | sbi(ADCSRA, ADSC); | |
76 | ||
77 | // ADSC is cleared when the conversion finishes | |
78 | while (bit_is_set(ADCSRA, ADSC)); | |
79 | ||
80 | // we have to read ADCL first; doing so locks both ADCL | |
81 | // and ADCH until ADCH is read. reading ADCL second would | |
82 | // cause the results of each conversion to be discarded, | |
83 | // as ADCL and ADCH would be locked when it completed. | |
84 | low = ADCL; | |
85 | high = ADCH; | |
86 | #else | |
87 | // we dont have an ADC, return 0 | |
88 | low = 0; | |
89 | high = 0; | |
90 | #endif | |
91 | ||
92 | // combine the two bytes | |
93 | return (high << 8) | low; | |
94 | } | |
95 | ||
96 | // Right now, PWM output only works on the pins with | |
97 | // hardware support. These are defined in the appropriate | |
98 | // pins_*.c file. For the rest of the pins, we default | |
99 | // to digital output. | |
100 | void analogWrite(uint8_t pin, int val) | |
101 | { | |
102 | // We need to make sure the PWM output is enabled for those pins | |
103 | // that support it, as we turn it off when digitally reading or | |
104 | // writing with them. Also, make sure the pin is in output mode | |
105 | // for consistenty with Wiring, which doesn't require a pinMode | |
106 | // call for the analog output pins. | |
107 | pinMode(pin, OUTPUT); | |
108 | if (val == 0) | |
109 | { | |
110 | digitalWrite(pin, LOW); | |
111 | } | |
112 | else if (val == 255) | |
113 | { | |
114 | digitalWrite(pin, HIGH); | |
115 | } | |
116 | else | |
117 | { | |
118 | switch(digitalPinToTimer(pin)) | |
119 | { | |
120 | // XXX fix needed for atmega8 | |
121 | #if defined(TCCR0) && defined(COM00) && !defined(__AVR_ATmega8__) | |
122 | case TIMER0A: | |
123 | // connect pwm to pin on timer 0 | |
124 | sbi(TCCR0, COM00); | |
125 | OCR0 = val; // set pwm duty | |
126 | break; | |
127 | #endif | |
128 | ||
129 | #if defined(TCCR0A) && defined(COM0A1) | |
130 | case TIMER0A: | |
131 | // connect pwm to pin on timer 0, channel A | |
132 | sbi(TCCR0A, COM0A1); | |
133 | OCR0A = val; // set pwm duty | |
134 | break; | |
135 | #endif | |
136 | ||
137 | #if defined(TCCR0A) && defined(COM0B1) | |
138 | case TIMER0B: | |
139 | // connect pwm to pin on timer 0, channel B | |
140 | sbi(TCCR0A, COM0B1); | |
141 | OCR0B = val; // set pwm duty | |
142 | break; | |
143 | #endif | |
144 | ||
145 | #if defined(TCCR1A) && defined(COM1A1) | |
146 | case TIMER1A: | |
147 | // connect pwm to pin on timer 1, channel A | |
148 | sbi(TCCR1A, COM1A1); | |
149 | OCR1A = val; // set pwm duty | |
150 | break; | |
151 | #endif | |
152 | ||
153 | #if defined(TCCR1A) && defined(COM1B1) | |
154 | case TIMER1B: | |
155 | // connect pwm to pin on timer 1, channel B | |
156 | sbi(TCCR1A, COM1B1); | |
157 | OCR1B = val; // set pwm duty | |
158 | break; | |
159 | #endif | |
160 | ||
161 | #if defined(TCCR2) && defined(COM21) | |
162 | case TIMER2: | |
163 | // connect pwm to pin on timer 2 | |
164 | sbi(TCCR2, COM21); | |
165 | OCR2 = val; // set pwm duty | |
166 | break; | |
167 | #endif | |
168 | ||
169 | #if defined(TCCR2A) && defined(COM2A1) | |
170 | case TIMER2A: | |
171 | // connect pwm to pin on timer 2, channel A | |
172 | sbi(TCCR2A, COM2A1); | |
173 | OCR2A = val; // set pwm duty | |
174 | break; | |
175 | #endif | |
176 | ||
177 | #if defined(TCCR2A) && defined(COM2B1) | |
178 | case TIMER2B: | |
179 | // connect pwm to pin on timer 2, channel B | |
180 | sbi(TCCR2A, COM2B1); | |
181 | OCR2B = val; // set pwm duty | |
182 | break; | |
183 | #endif | |
184 | ||
185 | #if defined(TCCR3A) && defined(COM3A1) | |
186 | case TIMER3A: | |
187 | // connect pwm to pin on timer 3, channel A | |
188 | sbi(TCCR3A, COM3A1); | |
189 | OCR3A = val; // set pwm duty | |
190 | break; | |
191 | #endif | |
192 | ||
193 | #if defined(TCCR3A) && defined(COM3B1) | |
194 | case TIMER3B: | |
195 | // connect pwm to pin on timer 3, channel B | |
196 | sbi(TCCR3A, COM3B1); | |
197 | OCR3B = val; // set pwm duty | |
198 | break; | |
199 | #endif | |
200 | ||
201 | #if defined(TCCR3A) && defined(COM3C1) | |
202 | case TIMER3C: | |
203 | // connect pwm to pin on timer 3, channel C | |
204 | sbi(TCCR3A, COM3C1); | |
205 | OCR3C = val; // set pwm duty | |
206 | break; | |
207 | #endif | |
208 | ||
209 | #if defined(TCCR4A) | |
210 | case TIMER4A: | |
211 | //connect pwm to pin on timer 4, channel A | |
212 | sbi(TCCR4A, COM4A1); | |
213 | #if defined(COM4A0) // only used on 32U4 | |
214 | cbi(TCCR4A, COM4A0); | |
215 | #endif | |
216 | OCR4A = val; // set pwm duty | |
217 | break; | |
218 | #endif | |
219 | ||
220 | #if defined(TCCR4A) && defined(COM4B1) | |
221 | case TIMER4B: | |
222 | // connect pwm to pin on timer 4, channel B | |
223 | sbi(TCCR4A, COM4B1); | |
224 | OCR4B = val; // set pwm duty | |
225 | break; | |
226 | #endif | |
227 | ||
228 | #if defined(TCCR4A) && defined(COM4C1) | |
229 | case TIMER4C: | |
230 | // connect pwm to pin on timer 4, channel C | |
231 | sbi(TCCR4A, COM4C1); | |
232 | OCR4C = val; // set pwm duty | |
233 | break; | |
234 | #endif | |
235 | ||
236 | #if defined(TCCR4C) && defined(COM4D1) | |
237 | case TIMER4D: | |
238 | // connect pwm to pin on timer 4, channel D | |
239 | sbi(TCCR4C, COM4D1); | |
240 | #if defined(COM4D0) // only used on 32U4 | |
241 | cbi(TCCR4C, COM4D0); | |
242 | #endif | |
243 | OCR4D = val; // set pwm duty | |
244 | break; | |
245 | #endif | |
246 | ||
247 | ||
248 | #if defined(TCCR5A) && defined(COM5A1) | |
249 | case TIMER5A: | |
250 | // connect pwm to pin on timer 5, channel A | |
251 | sbi(TCCR5A, COM5A1); | |
252 | OCR5A = val; // set pwm duty | |
253 | break; | |
254 | #endif | |
255 | ||
256 | #if defined(TCCR5A) && defined(COM5B1) | |
257 | case TIMER5B: | |
258 | // connect pwm to pin on timer 5, channel B | |
259 | sbi(TCCR5A, COM5B1); | |
260 | OCR5B = val; // set pwm duty | |
261 | break; | |
262 | #endif | |
263 | ||
264 | #if defined(TCCR5A) && defined(COM5C1) | |
265 | case TIMER5C: | |
266 | // connect pwm to pin on timer 5, channel C | |
267 | sbi(TCCR5A, COM5C1); | |
268 | OCR5C = val; // set pwm duty | |
269 | break; | |
270 | #endif | |
271 | ||
272 | case NOT_ON_TIMER: | |
273 | default: | |
274 | if (val < 128) { | |
275 | digitalWrite(pin, LOW); | |
276 | } else { | |
277 | digitalWrite(pin, HIGH); | |
278 | } | |
279 | } | |
280 | } | |
281 | } | |
282 |