1d5790d78880d4bd60be277ee20e53a851aa8c11Mike J. Chen/*
2d5790d78880d4bd60be277ee20e53a851aa8c11Mike J. Chen  wiring_analog.c - analog input and output
3d5790d78880d4bd60be277ee20e53a851aa8c11Mike J. Chen  Part of Arduino - http://www.arduino.cc/
4d5790d78880d4bd60be277ee20e53a851aa8c11Mike J. Chen
5d5790d78880d4bd60be277ee20e53a851aa8c11Mike J. Chen  Copyright (c) 2005-2006 David A. Mellis
6d5790d78880d4bd60be277ee20e53a851aa8c11Mike J. Chen
7d5790d78880d4bd60be277ee20e53a851aa8c11Mike J. Chen  This library is free software; you can redistribute it and/or
8d5790d78880d4bd60be277ee20e53a851aa8c11Mike J. Chen  modify it under the terms of the GNU Lesser General Public
9d5790d78880d4bd60be277ee20e53a851aa8c11Mike J. Chen  License as published by the Free Software Foundation; either
10d5790d78880d4bd60be277ee20e53a851aa8c11Mike J. Chen  version 2.1 of the License, or (at your option) any later version.
11d5790d78880d4bd60be277ee20e53a851aa8c11Mike J. Chen
12d5790d78880d4bd60be277ee20e53a851aa8c11Mike J. Chen  This library is distributed in the hope that it will be useful,
13d5790d78880d4bd60be277ee20e53a851aa8c11Mike J. Chen  but WITHOUT ANY WARRANTY; without even the implied warranty of
14d5790d78880d4bd60be277ee20e53a851aa8c11Mike J. Chen  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15d5790d78880d4bd60be277ee20e53a851aa8c11Mike J. Chen  Lesser General Public License for more details.
16d5790d78880d4bd60be277ee20e53a851aa8c11Mike J. Chen
17d5790d78880d4bd60be277ee20e53a851aa8c11Mike J. Chen  You should have received a copy of the GNU Lesser General
18d5790d78880d4bd60be277ee20e53a851aa8c11Mike J. Chen  Public License along with this library; if not, write to the
19d5790d78880d4bd60be277ee20e53a851aa8c11Mike J. Chen  Free Software Foundation, Inc., 59 Temple Place, Suite 330,
20d5790d78880d4bd60be277ee20e53a851aa8c11Mike J. Chen  Boston, MA  02111-1307  USA
21d5790d78880d4bd60be277ee20e53a851aa8c11Mike J. Chen
22d5790d78880d4bd60be277ee20e53a851aa8c11Mike J. Chen  Modified 28 September 2010 by Mark Sproul
23d5790d78880d4bd60be277ee20e53a851aa8c11Mike J. Chen
24d5790d78880d4bd60be277ee20e53a851aa8c11Mike J. Chen  $Id: wiring.c 248 2007-02-03 15:36:30Z mellis $
25d5790d78880d4bd60be277ee20e53a851aa8c11Mike J. Chen*/
26d5790d78880d4bd60be277ee20e53a851aa8c11Mike J. Chen
27d5790d78880d4bd60be277ee20e53a851aa8c11Mike J. Chen#include "wiring_private.h"
28d5790d78880d4bd60be277ee20e53a851aa8c11Mike J. Chen#include "pins_arduino.h"
29d5790d78880d4bd60be277ee20e53a851aa8c11Mike J. Chen
30d5790d78880d4bd60be277ee20e53a851aa8c11Mike J. Chenuint8_t analog_reference = DEFAULT;
31d5790d78880d4bd60be277ee20e53a851aa8c11Mike J. Chen
32d5790d78880d4bd60be277ee20e53a851aa8c11Mike J. Chenvoid analogReference(uint8_t mode)
33d5790d78880d4bd60be277ee20e53a851aa8c11Mike J. Chen{
34d5790d78880d4bd60be277ee20e53a851aa8c11Mike J. Chen	// can't actually set the register here because the default setting
35d5790d78880d4bd60be277ee20e53a851aa8c11Mike J. Chen	// will connect AVCC and the AREF pin, which would cause a short if
36d5790d78880d4bd60be277ee20e53a851aa8c11Mike J. Chen	// there's something connected to AREF.
37d5790d78880d4bd60be277ee20e53a851aa8c11Mike J. Chen	analog_reference = mode;
38d5790d78880d4bd60be277ee20e53a851aa8c11Mike J. Chen}
39d5790d78880d4bd60be277ee20e53a851aa8c11Mike J. Chen
40d5790d78880d4bd60be277ee20e53a851aa8c11Mike J. Chenint analogRead(uint8_t pin)
41d5790d78880d4bd60be277ee20e53a851aa8c11Mike J. Chen{
42d5790d78880d4bd60be277ee20e53a851aa8c11Mike J. Chen	uint8_t low, high;
43d5790d78880d4bd60be277ee20e53a851aa8c11Mike J. Chen
44d5790d78880d4bd60be277ee20e53a851aa8c11Mike J. Chen#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
45d5790d78880d4bd60be277ee20e53a851aa8c11Mike J. Chen	if (pin >= 54) pin -= 54; // allow for channel or pin numbers
46d5790d78880d4bd60be277ee20e53a851aa8c11Mike J. Chen#else
47d5790d78880d4bd60be277ee20e53a851aa8c11Mike J. Chen	if (pin >= 14) pin -= 14; // allow for channel or pin numbers
48d5790d78880d4bd60be277ee20e53a851aa8c11Mike J. Chen#endif
49d5790d78880d4bd60be277ee20e53a851aa8c11Mike J. Chen
50d5790d78880d4bd60be277ee20e53a851aa8c11Mike J. Chen#if defined(ADCSRB) && defined(MUX5)
51d5790d78880d4bd60be277ee20e53a851aa8c11Mike J. Chen	// the MUX5 bit of ADCSRB selects whether we're reading from channels
52d5790d78880d4bd60be277ee20e53a851aa8c11Mike J. Chen	// 0 to 7 (MUX5 low) or 8 to 15 (MUX5 high).
53d5790d78880d4bd60be277ee20e53a851aa8c11Mike J. Chen	ADCSRB = (ADCSRB & ~(1 << MUX5)) | (((pin >> 3) & 0x01) << MUX5);
54d5790d78880d4bd60be277ee20e53a851aa8c11Mike J. Chen#endif
55d5790d78880d4bd60be277ee20e53a851aa8c11Mike J. Chen
56d5790d78880d4bd60be277ee20e53a851aa8c11Mike J. Chen	// set the analog reference (high two bits of ADMUX) and select the
57d5790d78880d4bd60be277ee20e53a851aa8c11Mike J. Chen	// channel (low 4 bits).  this also sets ADLAR (left-adjust result)
58d5790d78880d4bd60be277ee20e53a851aa8c11Mike J. Chen	// to 0 (the default).
59d5790d78880d4bd60be277ee20e53a851aa8c11Mike J. Chen#if defined(ADMUX)
60d5790d78880d4bd60be277ee20e53a851aa8c11Mike J. Chen	ADMUX = (analog_reference << 6) | (pin & 0x07);
61d5790d78880d4bd60be277ee20e53a851aa8c11Mike J. Chen#endif
62d5790d78880d4bd60be277ee20e53a851aa8c11Mike J. Chen
63d5790d78880d4bd60be277ee20e53a851aa8c11Mike J. Chen	// without a delay, we seem to read from the wrong channel
64d5790d78880d4bd60be277ee20e53a851aa8c11Mike J. Chen	//delay(1);
65d5790d78880d4bd60be277ee20e53a851aa8c11Mike J. Chen
66d5790d78880d4bd60be277ee20e53a851aa8c11Mike J. Chen#if defined(ADCSRA) && defined(ADCL)
67d5790d78880d4bd60be277ee20e53a851aa8c11Mike J. Chen	// start the conversion
68d5790d78880d4bd60be277ee20e53a851aa8c11Mike J. Chen	sbi(ADCSRA, ADSC);
69d5790d78880d4bd60be277ee20e53a851aa8c11Mike J. Chen
70d5790d78880d4bd60be277ee20e53a851aa8c11Mike J. Chen	// ADSC is cleared when the conversion finishes
71d5790d78880d4bd60be277ee20e53a851aa8c11Mike J. Chen	while (bit_is_set(ADCSRA, ADSC));
72d5790d78880d4bd60be277ee20e53a851aa8c11Mike J. Chen
73d5790d78880d4bd60be277ee20e53a851aa8c11Mike J. Chen	// we have to read ADCL first; doing so locks both ADCL
74d5790d78880d4bd60be277ee20e53a851aa8c11Mike J. Chen	// and ADCH until ADCH is read.  reading ADCL second would
75d5790d78880d4bd60be277ee20e53a851aa8c11Mike J. Chen	// cause the results of each conversion to be discarded,
76d5790d78880d4bd60be277ee20e53a851aa8c11Mike J. Chen	// as ADCL and ADCH would be locked when it completed.
77d5790d78880d4bd60be277ee20e53a851aa8c11Mike J. Chen	low  = ADCL;
78d5790d78880d4bd60be277ee20e53a851aa8c11Mike J. Chen	high = ADCH;
79d5790d78880d4bd60be277ee20e53a851aa8c11Mike J. Chen#else
80d5790d78880d4bd60be277ee20e53a851aa8c11Mike J. Chen	// we dont have an ADC, return 0
81d5790d78880d4bd60be277ee20e53a851aa8c11Mike J. Chen	low  = 0;
82d5790d78880d4bd60be277ee20e53a851aa8c11Mike J. Chen	high = 0;
83d5790d78880d4bd60be277ee20e53a851aa8c11Mike J. Chen#endif
84d5790d78880d4bd60be277ee20e53a851aa8c11Mike J. Chen
85d5790d78880d4bd60be277ee20e53a851aa8c11Mike J. Chen	// combine the two bytes
86d5790d78880d4bd60be277ee20e53a851aa8c11Mike J. Chen	return (high << 8) | low;
87d5790d78880d4bd60be277ee20e53a851aa8c11Mike J. Chen}
88d5790d78880d4bd60be277ee20e53a851aa8c11Mike J. Chen
89d5790d78880d4bd60be277ee20e53a851aa8c11Mike J. Chen// Right now, PWM output only works on the pins with
90d5790d78880d4bd60be277ee20e53a851aa8c11Mike J. Chen// hardware support.  These are defined in the appropriate
91d5790d78880d4bd60be277ee20e53a851aa8c11Mike J. Chen// pins_*.c file.  For the rest of the pins, we default
92d5790d78880d4bd60be277ee20e53a851aa8c11Mike J. Chen// to digital output.
93d5790d78880d4bd60be277ee20e53a851aa8c11Mike J. Chenvoid analogWrite(uint8_t pin, int val)
94d5790d78880d4bd60be277ee20e53a851aa8c11Mike J. Chen{
95d5790d78880d4bd60be277ee20e53a851aa8c11Mike J. Chen	// We need to make sure the PWM output is enabled for those pins
96d5790d78880d4bd60be277ee20e53a851aa8c11Mike J. Chen	// that support it, as we turn it off when digitally reading or
97d5790d78880d4bd60be277ee20e53a851aa8c11Mike J. Chen	// writing with them.  Also, make sure the pin is in output mode
98d5790d78880d4bd60be277ee20e53a851aa8c11Mike J. Chen	// for consistenty with Wiring, which doesn't require a pinMode
99d5790d78880d4bd60be277ee20e53a851aa8c11Mike J. Chen	// call for the analog output pins.
100d5790d78880d4bd60be277ee20e53a851aa8c11Mike J. Chen	pinMode(pin, OUTPUT);
101d5790d78880d4bd60be277ee20e53a851aa8c11Mike J. Chen	if (val == 0)
102d5790d78880d4bd60be277ee20e53a851aa8c11Mike J. Chen	{
103d5790d78880d4bd60be277ee20e53a851aa8c11Mike J. Chen		digitalWrite(pin, LOW);
104d5790d78880d4bd60be277ee20e53a851aa8c11Mike J. Chen	}
105d5790d78880d4bd60be277ee20e53a851aa8c11Mike J. Chen	else if (val == 255)
106d5790d78880d4bd60be277ee20e53a851aa8c11Mike J. Chen	{
107d5790d78880d4bd60be277ee20e53a851aa8c11Mike J. Chen		digitalWrite(pin, HIGH);
108d5790d78880d4bd60be277ee20e53a851aa8c11Mike J. Chen	}
109d5790d78880d4bd60be277ee20e53a851aa8c11Mike J. Chen	else
110d5790d78880d4bd60be277ee20e53a851aa8c11Mike J. Chen	{
111d5790d78880d4bd60be277ee20e53a851aa8c11Mike J. Chen		switch(digitalPinToTimer(pin))
112d5790d78880d4bd60be277ee20e53a851aa8c11Mike J. Chen		{
113d5790d78880d4bd60be277ee20e53a851aa8c11Mike J. Chen			// XXX fix needed for atmega8
114d5790d78880d4bd60be277ee20e53a851aa8c11Mike J. Chen			#if defined(TCCR0) && defined(COM00) && !defined(__AVR_ATmega8__)
115d5790d78880d4bd60be277ee20e53a851aa8c11Mike J. Chen			case TIMER0A:
116d5790d78880d4bd60be277ee20e53a851aa8c11Mike J. Chen				// connect pwm to pin on timer 0
117d5790d78880d4bd60be277ee20e53a851aa8c11Mike J. Chen				sbi(TCCR0, COM00);
118d5790d78880d4bd60be277ee20e53a851aa8c11Mike J. Chen				OCR0 = val; // set pwm duty
119d5790d78880d4bd60be277ee20e53a851aa8c11Mike J. Chen				break;
120d5790d78880d4bd60be277ee20e53a851aa8c11Mike J. Chen			#endif
121d5790d78880d4bd60be277ee20e53a851aa8c11Mike J. Chen
122d5790d78880d4bd60be277ee20e53a851aa8c11Mike J. Chen			#if defined(TCCR0A) && defined(COM0A1)
123d5790d78880d4bd60be277ee20e53a851aa8c11Mike J. Chen			case TIMER0A:
124d5790d78880d4bd60be277ee20e53a851aa8c11Mike J. Chen				// connect pwm to pin on timer 0, channel A
125d5790d78880d4bd60be277ee20e53a851aa8c11Mike J. Chen				sbi(TCCR0A, COM0A1);
126d5790d78880d4bd60be277ee20e53a851aa8c11Mike J. Chen				OCR0A = val; // set pwm duty
127d5790d78880d4bd60be277ee20e53a851aa8c11Mike J. Chen				break;
128d5790d78880d4bd60be277ee20e53a851aa8c11Mike J. Chen			#endif
129d5790d78880d4bd60be277ee20e53a851aa8c11Mike J. Chen
130d5790d78880d4bd60be277ee20e53a851aa8c11Mike J. Chen			#if defined(TCCR0A) && defined(COM0B1)
131d5790d78880d4bd60be277ee20e53a851aa8c11Mike J. Chen			case TIMER0B:
132d5790d78880d4bd60be277ee20e53a851aa8c11Mike J. Chen				// connect pwm to pin on timer 0, channel B
133d5790d78880d4bd60be277ee20e53a851aa8c11Mike J. Chen				sbi(TCCR0A, COM0B1);
134d5790d78880d4bd60be277ee20e53a851aa8c11Mike J. Chen				OCR0B = val; // set pwm duty
135d5790d78880d4bd60be277ee20e53a851aa8c11Mike J. Chen				break;
136d5790d78880d4bd60be277ee20e53a851aa8c11Mike J. Chen			#endif
137d5790d78880d4bd60be277ee20e53a851aa8c11Mike J. Chen
138d5790d78880d4bd60be277ee20e53a851aa8c11Mike J. Chen			#if defined(TCCR1A) && defined(COM1A1)
139d5790d78880d4bd60be277ee20e53a851aa8c11Mike J. Chen			case TIMER1A:
140d5790d78880d4bd60be277ee20e53a851aa8c11Mike J. Chen				// connect pwm to pin on timer 1, channel A
141d5790d78880d4bd60be277ee20e53a851aa8c11Mike J. Chen				sbi(TCCR1A, COM1A1);
142d5790d78880d4bd60be277ee20e53a851aa8c11Mike J. Chen				OCR1A = val; // set pwm duty
143d5790d78880d4bd60be277ee20e53a851aa8c11Mike J. Chen				break;
144d5790d78880d4bd60be277ee20e53a851aa8c11Mike J. Chen			#endif
145d5790d78880d4bd60be277ee20e53a851aa8c11Mike J. Chen
146d5790d78880d4bd60be277ee20e53a851aa8c11Mike J. Chen			#if defined(TCCR1A) && defined(COM1B1)
147d5790d78880d4bd60be277ee20e53a851aa8c11Mike J. Chen			case TIMER1B:
148d5790d78880d4bd60be277ee20e53a851aa8c11Mike J. Chen				// connect pwm to pin on timer 1, channel B
149d5790d78880d4bd60be277ee20e53a851aa8c11Mike J. Chen				sbi(TCCR1A, COM1B1);
150d5790d78880d4bd60be277ee20e53a851aa8c11Mike J. Chen				OCR1B = val; // set pwm duty
151d5790d78880d4bd60be277ee20e53a851aa8c11Mike J. Chen				break;
152d5790d78880d4bd60be277ee20e53a851aa8c11Mike J. Chen			#endif
153d5790d78880d4bd60be277ee20e53a851aa8c11Mike J. Chen
154d5790d78880d4bd60be277ee20e53a851aa8c11Mike J. Chen			#if defined(TCCR2) && defined(COM21)
155d5790d78880d4bd60be277ee20e53a851aa8c11Mike J. Chen			case TIMER2:
156d5790d78880d4bd60be277ee20e53a851aa8c11Mike J. Chen				// connect pwm to pin on timer 2
157d5790d78880d4bd60be277ee20e53a851aa8c11Mike J. Chen				sbi(TCCR2, COM21);
158d5790d78880d4bd60be277ee20e53a851aa8c11Mike J. Chen				OCR2 = val; // set pwm duty
159d5790d78880d4bd60be277ee20e53a851aa8c11Mike J. Chen				break;
160d5790d78880d4bd60be277ee20e53a851aa8c11Mike J. Chen			#endif
161d5790d78880d4bd60be277ee20e53a851aa8c11Mike J. Chen
162d5790d78880d4bd60be277ee20e53a851aa8c11Mike J. Chen			#if defined(TCCR2A) && defined(COM2A1)
163d5790d78880d4bd60be277ee20e53a851aa8c11Mike J. Chen			case TIMER2A:
164d5790d78880d4bd60be277ee20e53a851aa8c11Mike J. Chen				// connect pwm to pin on timer 2, channel A
165d5790d78880d4bd60be277ee20e53a851aa8c11Mike J. Chen				sbi(TCCR2A, COM2A1);
166d5790d78880d4bd60be277ee20e53a851aa8c11Mike J. Chen				OCR2A = val; // set pwm duty
167d5790d78880d4bd60be277ee20e53a851aa8c11Mike J. Chen				break;
168d5790d78880d4bd60be277ee20e53a851aa8c11Mike J. Chen			#endif
169d5790d78880d4bd60be277ee20e53a851aa8c11Mike J. Chen
170d5790d78880d4bd60be277ee20e53a851aa8c11Mike J. Chen			#if defined(TCCR2A) && defined(COM2B1)
171d5790d78880d4bd60be277ee20e53a851aa8c11Mike J. Chen			case TIMER2B:
172d5790d78880d4bd60be277ee20e53a851aa8c11Mike J. Chen				// connect pwm to pin on timer 2, channel B
173d5790d78880d4bd60be277ee20e53a851aa8c11Mike J. Chen				sbi(TCCR2A, COM2B1);
174d5790d78880d4bd60be277ee20e53a851aa8c11Mike J. Chen				OCR2B = val; // set pwm duty
175d5790d78880d4bd60be277ee20e53a851aa8c11Mike J. Chen				break;
176d5790d78880d4bd60be277ee20e53a851aa8c11Mike J. Chen			#endif
177d5790d78880d4bd60be277ee20e53a851aa8c11Mike J. Chen
178d5790d78880d4bd60be277ee20e53a851aa8c11Mike J. Chen			#if defined(TCCR3A) && defined(COM3A1)
179d5790d78880d4bd60be277ee20e53a851aa8c11Mike J. Chen			case TIMER3A:
180d5790d78880d4bd60be277ee20e53a851aa8c11Mike J. Chen				// connect pwm to pin on timer 3, channel A
181d5790d78880d4bd60be277ee20e53a851aa8c11Mike J. Chen				sbi(TCCR3A, COM3A1);
182d5790d78880d4bd60be277ee20e53a851aa8c11Mike J. Chen				OCR3A = val; // set pwm duty
183d5790d78880d4bd60be277ee20e53a851aa8c11Mike J. Chen				break;
184d5790d78880d4bd60be277ee20e53a851aa8c11Mike J. Chen			#endif
185d5790d78880d4bd60be277ee20e53a851aa8c11Mike J. Chen
186d5790d78880d4bd60be277ee20e53a851aa8c11Mike J. Chen			#if defined(TCCR3A) && defined(COM3B1)
187d5790d78880d4bd60be277ee20e53a851aa8c11Mike J. Chen			case TIMER3B:
188d5790d78880d4bd60be277ee20e53a851aa8c11Mike J. Chen				// connect pwm to pin on timer 3, channel B
189d5790d78880d4bd60be277ee20e53a851aa8c11Mike J. Chen				sbi(TCCR3A, COM3B1);
190d5790d78880d4bd60be277ee20e53a851aa8c11Mike J. Chen				OCR3B = val; // set pwm duty
191d5790d78880d4bd60be277ee20e53a851aa8c11Mike J. Chen				break;
192d5790d78880d4bd60be277ee20e53a851aa8c11Mike J. Chen			#endif
193d5790d78880d4bd60be277ee20e53a851aa8c11Mike J. Chen
194d5790d78880d4bd60be277ee20e53a851aa8c11Mike J. Chen			#if defined(TCCR3A) && defined(COM3C1)
195d5790d78880d4bd60be277ee20e53a851aa8c11Mike J. Chen			case TIMER3C:
196d5790d78880d4bd60be277ee20e53a851aa8c11Mike J. Chen				// connect pwm to pin on timer 3, channel C
197d5790d78880d4bd60be277ee20e53a851aa8c11Mike J. Chen				sbi(TCCR3A, COM3C1);
198d5790d78880d4bd60be277ee20e53a851aa8c11Mike J. Chen				OCR3C = val; // set pwm duty
199d5790d78880d4bd60be277ee20e53a851aa8c11Mike J. Chen				break;
200d5790d78880d4bd60be277ee20e53a851aa8c11Mike J. Chen			#endif
201d5790d78880d4bd60be277ee20e53a851aa8c11Mike J. Chen
202d5790d78880d4bd60be277ee20e53a851aa8c11Mike J. Chen			#if defined(TCCR4A) && defined(COM4A1)
203d5790d78880d4bd60be277ee20e53a851aa8c11Mike J. Chen			case TIMER4A:
204d5790d78880d4bd60be277ee20e53a851aa8c11Mike J. Chen				// connect pwm to pin on timer 4, channel A
205d5790d78880d4bd60be277ee20e53a851aa8c11Mike J. Chen				sbi(TCCR4A, COM4A1);
206d5790d78880d4bd60be277ee20e53a851aa8c11Mike J. Chen				OCR4A = val; // set pwm duty
207d5790d78880d4bd60be277ee20e53a851aa8c11Mike J. Chen				break;
208d5790d78880d4bd60be277ee20e53a851aa8c11Mike J. Chen			#endif
209d5790d78880d4bd60be277ee20e53a851aa8c11Mike J. Chen
210d5790d78880d4bd60be277ee20e53a851aa8c11Mike J. Chen			#if defined(TCCR4A) && defined(COM4B1)
211d5790d78880d4bd60be277ee20e53a851aa8c11Mike J. Chen			case TIMER4B:
212d5790d78880d4bd60be277ee20e53a851aa8c11Mike J. Chen				// connect pwm to pin on timer 4, channel B
213d5790d78880d4bd60be277ee20e53a851aa8c11Mike J. Chen				sbi(TCCR4A, COM4B1);
214d5790d78880d4bd60be277ee20e53a851aa8c11Mike J. Chen				OCR4B = val; // set pwm duty
215d5790d78880d4bd60be277ee20e53a851aa8c11Mike J. Chen				break;
216d5790d78880d4bd60be277ee20e53a851aa8c11Mike J. Chen			#endif
217d5790d78880d4bd60be277ee20e53a851aa8c11Mike J. Chen
218d5790d78880d4bd60be277ee20e53a851aa8c11Mike J. Chen			#if defined(TCCR4A) && defined(COM4C1)
219d5790d78880d4bd60be277ee20e53a851aa8c11Mike J. Chen			case TIMER4C:
220d5790d78880d4bd60be277ee20e53a851aa8c11Mike J. Chen				// connect pwm to pin on timer 4, channel C
221d5790d78880d4bd60be277ee20e53a851aa8c11Mike J. Chen				sbi(TCCR4A, COM4C1);
222d5790d78880d4bd60be277ee20e53a851aa8c11Mike J. Chen				OCR4C = val; // set pwm duty
223d5790d78880d4bd60be277ee20e53a851aa8c11Mike J. Chen				break;
224d5790d78880d4bd60be277ee20e53a851aa8c11Mike J. Chen			#endif
225d5790d78880d4bd60be277ee20e53a851aa8c11Mike J. Chen
226d5790d78880d4bd60be277ee20e53a851aa8c11Mike J. Chen			#if defined(TCCR5A) && defined(COM5A1)
227d5790d78880d4bd60be277ee20e53a851aa8c11Mike J. Chen			case TIMER5A:
228d5790d78880d4bd60be277ee20e53a851aa8c11Mike J. Chen				// connect pwm to pin on timer 5, channel A
229d5790d78880d4bd60be277ee20e53a851aa8c11Mike J. Chen				sbi(TCCR5A, COM5A1);
230d5790d78880d4bd60be277ee20e53a851aa8c11Mike J. Chen				OCR5A = val; // set pwm duty
231d5790d78880d4bd60be277ee20e53a851aa8c11Mike J. Chen				break;
232d5790d78880d4bd60be277ee20e53a851aa8c11Mike J. Chen			#endif
233d5790d78880d4bd60be277ee20e53a851aa8c11Mike J. Chen
234d5790d78880d4bd60be277ee20e53a851aa8c11Mike J. Chen			#if defined(TCCR5A) && defined(COM5B1)
235d5790d78880d4bd60be277ee20e53a851aa8c11Mike J. Chen			case TIMER5B:
236d5790d78880d4bd60be277ee20e53a851aa8c11Mike J. Chen				// connect pwm to pin on timer 5, channel B
237d5790d78880d4bd60be277ee20e53a851aa8c11Mike J. Chen				sbi(TCCR5A, COM5B1);
238d5790d78880d4bd60be277ee20e53a851aa8c11Mike J. Chen				OCR5B = val; // set pwm duty
239d5790d78880d4bd60be277ee20e53a851aa8c11Mike J. Chen				break;
240d5790d78880d4bd60be277ee20e53a851aa8c11Mike J. Chen			#endif
241d5790d78880d4bd60be277ee20e53a851aa8c11Mike J. Chen
242d5790d78880d4bd60be277ee20e53a851aa8c11Mike J. Chen			#if defined(TCCR5A) && defined(COM5C1)
243d5790d78880d4bd60be277ee20e53a851aa8c11Mike J. Chen			case TIMER5C:
244d5790d78880d4bd60be277ee20e53a851aa8c11Mike J. Chen				// connect pwm to pin on timer 5, channel C
245d5790d78880d4bd60be277ee20e53a851aa8c11Mike J. Chen				sbi(TCCR5A, COM5C1);
246d5790d78880d4bd60be277ee20e53a851aa8c11Mike J. Chen				OCR5C = val; // set pwm duty
247d5790d78880d4bd60be277ee20e53a851aa8c11Mike J. Chen				break;
248d5790d78880d4bd60be277ee20e53a851aa8c11Mike J. Chen			#endif
249d5790d78880d4bd60be277ee20e53a851aa8c11Mike J. Chen
250d5790d78880d4bd60be277ee20e53a851aa8c11Mike J. Chen			case NOT_ON_TIMER:
251d5790d78880d4bd60be277ee20e53a851aa8c11Mike J. Chen			default:
252d5790d78880d4bd60be277ee20e53a851aa8c11Mike J. Chen				if (val < 128) {
253d5790d78880d4bd60be277ee20e53a851aa8c11Mike J. Chen					digitalWrite(pin, LOW);
254d5790d78880d4bd60be277ee20e53a851aa8c11Mike J. Chen				} else {
255d5790d78880d4bd60be277ee20e53a851aa8c11Mike J. Chen					digitalWrite(pin, HIGH);
256d5790d78880d4bd60be277ee20e53a851aa8c11Mike J. Chen				}
257d5790d78880d4bd60be277ee20e53a851aa8c11Mike J. Chen		}
258d5790d78880d4bd60be277ee20e53a851aa8c11Mike J. Chen	}
259d5790d78880d4bd60be277ee20e53a851aa8c11Mike J. Chen}
260