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