diff --git a/hardware/arduino/cores/arduino/HardwareSerial.cpp b/hardware/arduino/cores/arduino/HardwareSerial.cpp old mode 100755 new mode 100644 index e7ac21f7cf2..c50aaff441d --- a/hardware/arduino/cores/arduino/HardwareSerial.cpp +++ b/hardware/arduino/cores/arduino/HardwareSerial.cpp @@ -17,6 +17,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Modified 23 November 2006 by David A. Mellis + Modified 28 September 2010 by Mark Sproul */ #include <stdlib.h> @@ -26,26 +27,40 @@ #include "wiring.h" #include "wiring_private.h" +// this next line disables the entire HardwareSerial.cpp, +// this is so I can support Attiny series and any other chip without a uart +#if defined(UBRRH) || defined(UBRR0H) || defined(UBRR1H) || defined(UBRR2H) || defined(UBRR3H) + #include "HardwareSerial.h" // Define constants and variables for buffering incoming serial data. We're // using a ring buffer (I think), in which rx_buffer_head is the index of the // location to which to write the next incoming character and rx_buffer_tail // is the index of the location from which to read. -#define RX_BUFFER_SIZE 128 +#if (RAMEND < 1500) + #define RX_BUFFER_SIZE 32 +#else + #define RX_BUFFER_SIZE 128 +#endif -struct ring_buffer { +struct ring_buffer +{ unsigned char buffer[RX_BUFFER_SIZE]; int head; int tail; }; -ring_buffer rx_buffer = { { 0 }, 0, 0 }; - -#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) -ring_buffer rx_buffer1 = { { 0 }, 0, 0 }; -ring_buffer rx_buffer2 = { { 0 }, 0, 0 }; -ring_buffer rx_buffer3 = { { 0 }, 0, 0 }; +#if defined(UBRRH) || defined(UBRR0H) + ring_buffer rx_buffer = { { 0 }, 0, 0 }; +#endif +#if defined(UBRR1H) + ring_buffer rx_buffer1 = { { 0 }, 0, 0 }; +#endif +#if defined(UBRR2H) + ring_buffer rx_buffer2 = { { 0 }, 0, 0 }; +#endif +#if defined(UBRR3H) + ring_buffer rx_buffer3 = { { 0 }, 0, 0 }; #endif inline void store_char(unsigned char c, ring_buffer *rx_buffer) @@ -62,50 +77,97 @@ inline void store_char(unsigned char c, ring_buffer *rx_buffer) } } -#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) - -SIGNAL(SIG_USART0_RECV) -{ - unsigned char c = UDR0; - store_char(c, &rx_buffer); -} - -SIGNAL(SIG_USART1_RECV) -{ - unsigned char c = UDR1; - store_char(c, &rx_buffer1); -} - -SIGNAL(SIG_USART2_RECV) -{ - unsigned char c = UDR2; - store_char(c, &rx_buffer2); -} - -SIGNAL(SIG_USART3_RECV) -{ - unsigned char c = UDR3; - store_char(c, &rx_buffer3); -} - +#if defined(USART_RX_vect) + SIGNAL(USART_RX_vect) + { + #if defined(UDR0) + unsigned char c = UDR0; + #elif defined(UDR) + unsigned char c = UDR; // atmega8535 + #else + #error UDR not defined + #endif + store_char(c, &rx_buffer); + } +#elif defined(SIG_USART0_RECV) && defined(UDR0) + SIGNAL(SIG_USART0_RECV) + { + unsigned char c = UDR0; + store_char(c, &rx_buffer); + } +#elif defined(SIG_UART0_RECV) && defined(UDR0) + SIGNAL(SIG_UART0_RECV) + { + unsigned char c = UDR0; + store_char(c, &rx_buffer); + } +//#elif defined(SIG_USART_RECV) +#elif defined(USART0_RX_vect) + // fixed by Mark Sproul this is on the 644/644p + //SIGNAL(SIG_USART_RECV) + SIGNAL(USART0_RX_vect) + { + #if defined(UDR0) + unsigned char c = UDR0; + #elif defined(UDR) + unsigned char c = UDR; // atmega8, atmega32 + #else + #error UDR not defined + #endif + store_char(c, &rx_buffer); + } +#elif defined(SIG_UART_RECV) + // this is for atmega8 + SIGNAL(SIG_UART_RECV) + { + #if defined(UDR0) + unsigned char c = UDR0; // atmega645 + #elif defined(UDR) + unsigned char c = UDR; // atmega8 + #endif + store_char(c, &rx_buffer); + } +#elif defined(USBCON) + #warning No interrupt handler for usart 0 + #warning Serial(0) is on USB interface #else + #error No interrupt handler for usart 0 +#endif -#if defined(__AVR_ATmega8__) -SIGNAL(SIG_UART_RECV) -#else -SIGNAL(USART_RX_vect) +//#if defined(SIG_USART1_RECV) +#if defined(USART1_RX_vect) + //SIGNAL(SIG_USART1_RECV) + SIGNAL(USART1_RX_vect) + { + unsigned char c = UDR1; + store_char(c, &rx_buffer1); + } +#elif defined(SIG_USART1_RECV) + #error SIG_USART1_RECV #endif -{ -#if defined(__AVR_ATmega8__) - unsigned char c = UDR; -#else - unsigned char c = UDR0; + +#if defined(USART2_RX_vect) && defined(UDR2) + SIGNAL(USART2_RX_vect) + { + unsigned char c = UDR2; + store_char(c, &rx_buffer2); + } +#elif defined(SIG_USART2_RECV) + #error SIG_USART2_RECV #endif - store_char(c, &rx_buffer); -} +#if defined(USART3_RX_vect) && defined(UDR3) + SIGNAL(USART3_RX_vect) + { + unsigned char c = UDR3; + store_char(c, &rx_buffer3); + } +#elif defined(SIG_USART3_RECV) + #error SIG_USART3_RECV #endif + + // Constructors //////////////////////////////////////////////////////////////// HardwareSerial::HardwareSerial(ring_buffer *rx_buffer, @@ -223,14 +285,25 @@ void HardwareSerial::write(uint8_t c) // Preinstantiate Objects ////////////////////////////////////////////////////// -#if defined(__AVR_ATmega8__) -HardwareSerial Serial(&rx_buffer, &UBRRH, &UBRRL, &UCSRA, &UCSRB, &UDR, RXEN, TXEN, RXCIE, UDRE, U2X); +#if defined(UBRRH) && defined(UBRRL) + HardwareSerial Serial(&rx_buffer, &UBRRH, &UBRRL, &UCSRA, &UCSRB, &UDR, RXEN, TXEN, RXCIE, UDRE, U2X); +#elif defined(UBRR0H) && defined(UBRR0L) + HardwareSerial Serial(&rx_buffer, &UBRR0H, &UBRR0L, &UCSR0A, &UCSR0B, &UDR0, RXEN0, TXEN0, RXCIE0, UDRE0, U2X0); +#elif defined(USBCON) + #warning no serial port defined (port 0) #else -HardwareSerial Serial(&rx_buffer, &UBRR0H, &UBRR0L, &UCSR0A, &UCSR0B, &UDR0, RXEN0, TXEN0, RXCIE0, UDRE0, U2X0); + #error no serial port defined (port 0) #endif -#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) -HardwareSerial Serial1(&rx_buffer1, &UBRR1H, &UBRR1L, &UCSR1A, &UCSR1B, &UDR1, RXEN1, TXEN1, RXCIE1, UDRE1, U2X1); -HardwareSerial Serial2(&rx_buffer2, &UBRR2H, &UBRR2L, &UCSR2A, &UCSR2B, &UDR2, RXEN2, TXEN2, RXCIE2, UDRE2, U2X2); -HardwareSerial Serial3(&rx_buffer3, &UBRR3H, &UBRR3L, &UCSR3A, &UCSR3B, &UDR3, RXEN3, TXEN3, RXCIE3, UDRE3, U2X3); +#if defined(UBRR1H) + HardwareSerial Serial1(&rx_buffer1, &UBRR1H, &UBRR1L, &UCSR1A, &UCSR1B, &UDR1, RXEN1, TXEN1, RXCIE1, UDRE1, U2X1); +#endif +#if defined(UBRR2H) + HardwareSerial Serial2(&rx_buffer2, &UBRR2H, &UBRR2L, &UCSR2A, &UCSR2B, &UDR2, RXEN2, TXEN2, RXCIE2, UDRE2, U2X2); +#endif +#if defined(UBRR3H) + HardwareSerial Serial3(&rx_buffer3, &UBRR3H, &UBRR3L, &UCSR3A, &UCSR3B, &UDR3, RXEN3, TXEN3, RXCIE3, UDRE3, U2X3); #endif + +#endif // whole file + diff --git a/hardware/arduino/cores/arduino/HardwareSerial.h b/hardware/arduino/cores/arduino/HardwareSerial.h old mode 100755 new mode 100644 index 29898b9535a..3efa775f843 --- a/hardware/arduino/cores/arduino/HardwareSerial.h +++ b/hardware/arduino/cores/arduino/HardwareSerial.h @@ -15,6 +15,8 @@ You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + Modified 28 September 2010 by Mark Sproul */ #ifndef HardwareSerial_h @@ -56,12 +58,19 @@ class HardwareSerial : public Stream using Print::write; // pull in write(str) and write(buf, size) from Print }; -extern HardwareSerial Serial; - -#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) -extern HardwareSerial Serial1; -extern HardwareSerial Serial2; -extern HardwareSerial Serial3; +#if defined(UBRRH) || defined(UBRR0H) + extern HardwareSerial Serial; +#elif defined(USBCON) + #include "usb_api.h" +#endif +#if defined(UBRR1H) + extern HardwareSerial Serial1; +#endif +#if defined(UBRR2H) + extern HardwareSerial Serial2; +#endif +#if defined(UBRR3H) + extern HardwareSerial Serial3; #endif #endif diff --git a/hardware/arduino/cores/arduino/Tone.cpp b/hardware/arduino/cores/arduino/Tone.cpp index 3ea034bf98b..8bdc5f7710e 100755 --- a/hardware/arduino/cores/arduino/Tone.cpp +++ b/hardware/arduino/cores/arduino/Tone.cpp @@ -28,7 +28,7 @@ Version Modified By Date Comments 09/11/25 Changed pin toggle method to XOR 09/11/25 Fixed timer0 from being excluded 0006 D Mellis 09/12/29 Replaced objects with functions - +0007 M Sproul 10/08/29 Changed #ifdefs from cpu to register *************************************************/ #include <avr/interrupt.h> @@ -36,7 +36,7 @@ Version Modified By Date Comments #include "wiring.h" #include "pins_arduino.h" -#if defined(__AVR_ATmega8__) +#if defined(__AVR_ATmega8__) || defined(__AVR_ATmega128__) #define TCCR2A TCCR2 #define TCCR2B TCCR2 #define COM2A1 COM21 @@ -66,19 +66,26 @@ volatile long timer2_toggle_count; volatile uint8_t *timer2_pin_port; volatile uint8_t timer2_pin_mask; -#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) +#if defined(TIMSK3) volatile long timer3_toggle_count; volatile uint8_t *timer3_pin_port; volatile uint8_t timer3_pin_mask; +#endif + +#if defined(TIMSK4) volatile long timer4_toggle_count; volatile uint8_t *timer4_pin_port; volatile uint8_t timer4_pin_mask; +#endif + +#if defined(TIMSK5) volatile long timer5_toggle_count; volatile uint8_t *timer5_pin_port; volatile uint8_t timer5_pin_mask; #endif +// MLS: This does not make sense, the 3 options are the same #if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) #define AVAILABLE_TONE_PINS 1 @@ -133,7 +140,7 @@ static int8_t toneBegin(uint8_t _pin) // whereas 16 bit timers are set to either ck/1 or ck/64 prescalar switch (_timer) { -#if !defined(__AVR_ATmega8__) + #if defined(TCCR0A) && defined(TCCR0B) case 0: // 8 bit timer TCCR0A = 0; @@ -143,8 +150,9 @@ static int8_t toneBegin(uint8_t _pin) timer0_pin_port = portOutputRegister(digitalPinToPort(_pin)); timer0_pin_mask = digitalPinToBitMask(_pin); break; -#endif + #endif + #if defined(TCCR1A) && defined(TCCR1B) && defined(WGM12) case 1: // 16 bit timer TCCR1A = 0; @@ -154,6 +162,9 @@ static int8_t toneBegin(uint8_t _pin) timer1_pin_port = portOutputRegister(digitalPinToPort(_pin)); timer1_pin_mask = digitalPinToBitMask(_pin); break; + #endif + + #if defined(TCCR2A) && defined(TCCR2B) case 2: // 8 bit timer TCCR2A = 0; @@ -163,8 +174,9 @@ static int8_t toneBegin(uint8_t _pin) timer2_pin_port = portOutputRegister(digitalPinToPort(_pin)); timer2_pin_mask = digitalPinToBitMask(_pin); break; + #endif -#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) + #if defined(TCCR3A) && defined(TCCR3B) && defined(TIMSK3) case 3: // 16 bit timer TCCR3A = 0; @@ -174,15 +186,27 @@ static int8_t toneBegin(uint8_t _pin) timer3_pin_port = portOutputRegister(digitalPinToPort(_pin)); timer3_pin_mask = digitalPinToBitMask(_pin); break; + #endif + + #if defined(TCCR4A) && defined(TCCR4B) && defined(TIMSK4) case 4: // 16 bit timer TCCR4A = 0; TCCR4B = 0; - bitWrite(TCCR4B, WGM42, 1); + #if defined(WGM42) + bitWrite(TCCR4B, WGM42, 1); + #elif defined(CS43) + #warning this may not be correct + // atmega32u4 + bitWrite(TCCR4B, CS43, 1); + #endif bitWrite(TCCR4B, CS40, 1); timer4_pin_port = portOutputRegister(digitalPinToPort(_pin)); timer4_pin_mask = digitalPinToBitMask(_pin); break; + #endif + + #if defined(TCCR5A) && defined(TCCR5B) && defined(TIMSK5) case 5: // 16 bit timer TCCR5A = 0; @@ -192,7 +216,7 @@ static int8_t toneBegin(uint8_t _pin) timer5_pin_port = portOutputRegister(digitalPinToPort(_pin)); timer5_pin_mask = digitalPinToBitMask(_pin); break; -#endif + #endif } } @@ -258,12 +282,22 @@ void tone(uint8_t _pin, unsigned int frequency, unsigned long duration) } } -#if !defined(__AVR_ATmega8__) +#if defined(TCCR0B) if (_timer == 0) + { TCCR0B = prescalarbits; + } else #endif +#if defined(TCCR2B) + { TCCR2B = prescalarbits; + } +#else + { + // dummy place holder to make the above ifdefs work + } +#endif } else { @@ -278,12 +312,20 @@ void tone(uint8_t _pin, unsigned int frequency, unsigned long duration) } if (_timer == 1) + { +#if defined(TCCR1B) TCCR1B = (TCCR1B & 0b11111000) | prescalarbits; -#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) +#endif + } +#if defined(TCCR3B) else if (_timer == 3) TCCR3B = (TCCR3B & 0b11111000) | prescalarbits; +#endif +#if defined(TCCR4B) else if (_timer == 4) TCCR4B = (TCCR4B & 0b11111000) | prescalarbits; +#endif +#if defined(TCCR5B) else if (_timer == 5) TCCR5B = (TCCR5B & 0b11111000) | prescalarbits; #endif @@ -307,7 +349,7 @@ void tone(uint8_t _pin, unsigned int frequency, unsigned long duration) switch (_timer) { -#if !defined(__AVR_ATmega8__) +#if defined(OCR0A) && defined(TIMSK0) && defined(OCIE0A) case 0: OCR0A = ocr; timer0_toggle_count = toggle_count; @@ -316,27 +358,43 @@ void tone(uint8_t _pin, unsigned int frequency, unsigned long duration) #endif case 1: +#if defined(OCR1A) && defined(TIMSK1) && defined(OCIE1A) OCR1A = ocr; timer1_toggle_count = toggle_count; bitWrite(TIMSK1, OCIE1A, 1); +#elif defined(OCR1A) && defined(TIMSK) && defined(OCIE1A) + // this combination is for at least the ATmega32 + OCR1A = ocr; + timer1_toggle_count = toggle_count; + bitWrite(TIMSK, OCIE1A, 1); +#endif break; + +#if defined(OCR2A) && defined(TIMSK2) && defined(OCIE2A) case 2: OCR2A = ocr; timer2_toggle_count = toggle_count; bitWrite(TIMSK2, OCIE2A, 1); break; +#endif -#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) +#if defined(TIMSK3) case 3: OCR3A = ocr; timer3_toggle_count = toggle_count; bitWrite(TIMSK3, OCIE3A, 1); break; +#endif + +#if defined(TIMSK4) case 4: OCR4A = ocr; timer4_toggle_count = toggle_count; bitWrite(TIMSK4, OCIE4A, 1); break; +#endif + +#if defined(OCR5A) && defined(TIMSK5) && defined(OCIE5A) case 5: OCR5A = ocr; timer5_toggle_count = toggle_count; @@ -356,27 +414,48 @@ void disableTimer(uint8_t _timer) { switch (_timer) { -#if !defined(__AVR_ATmega8__) case 0: - TIMSK0 = 0; + #if defined(TIMSK0) + TIMSK0 = 0; + #elif defined(TIMSK) + TIMSK = 0; // atmega32 + #endif break; -#endif + +#if defined(TIMSK1) && defined(OCIE1A) case 1: bitWrite(TIMSK1, OCIE1A, 0); break; +#endif + case 2: - bitWrite(TIMSK2, OCIE2A, 0); // disable interrupt - TCCR2A = (1 << WGM20); - TCCR2B = (TCCR2B & 0b11111000) | (1 << CS22); - OCR2A = 0; + #if defined(TIMSK2) && defined(OCIE2A) + bitWrite(TIMSK2, OCIE2A, 0); // disable interrupt + #endif + #if defined(TCCR2A) && defined(WGM20) + TCCR2A = (1 << WGM20); + #endif + #if defined(TCCR2B) && defined(CS22) + TCCR2B = (TCCR2B & 0b11111000) | (1 << CS22); + #endif + #if defined(OCR2A) + OCR2A = 0; + #endif break; -#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) + +#if defined(TIMSK3) case 3: TIMSK3 = 0; break; +#endif + +#if defined(TIMSK4) case 4: TIMSK4 = 0; break; +#endif + +#if defined(TIMSK5) case 5: TIMSK5 = 0; break; diff --git a/hardware/arduino/cores/arduino/WInterrupts.c b/hardware/arduino/cores/arduino/WInterrupts.c index 9c5741148ca..3b3e0c9ec43 100755 --- a/hardware/arduino/cores/arduino/WInterrupts.c +++ b/hardware/arduino/cores/arduino/WInterrupts.c @@ -21,6 +21,7 @@ Boston, MA 02111-1307 USA Modified 24 November 2006 by David A. Mellis + Modified 1 August 2010 by Mark Sproul */ #include <inttypes.h> @@ -35,11 +36,6 @@ volatile static voidFuncPtr intFunc[EXTERNAL_NUM_INTERRUPTS]; // volatile static voidFuncPtr twiIntFunc; -#if defined(__AVR_ATmega8__) -#define EICRA MCUCR -#define EIMSK GICR -#endif - void attachInterrupt(uint8_t interruptNum, void (*userFunc)(void), int mode) { if(interruptNum < EXTERNAL_NUM_INTERRUPTS) { intFunc[interruptNum] = userFunc; @@ -52,7 +48,7 @@ void attachInterrupt(uint8_t interruptNum, void (*userFunc)(void), int mode) { // Enable the interrupt. switch (interruptNum) { -#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) +#if defined(EICRA) && defined(EICRB) && defined(EIMSK) case 2: EICRA = (EICRA & ~((1 << ISC00) | (1 << ISC01))) | (mode << ISC00); EIMSK |= (1 << INT0); @@ -87,12 +83,33 @@ void attachInterrupt(uint8_t interruptNum, void (*userFunc)(void), int mode) { break; #else case 0: + #if defined(EICRA) && defined(ISC00) && defined(EIMSK) EICRA = (EICRA & ~((1 << ISC00) | (1 << ISC01))) | (mode << ISC00); EIMSK |= (1 << INT0); + #elif defined(MCUCR) && defined(ISC00) && defined(GICR) + MCUCR = (MCUCR & ~((1 << ISC00) | (1 << ISC01))) | (mode << ISC00); + GICR |= (1 << INT0); + #elif defined(MCUCR) && defined(ISC00) && defined(GIMSK) + MCUCR = (MCUCR & ~((1 << ISC00) | (1 << ISC01))) | (mode << ISC00); + GIMSK |= (1 << INT0); + #else + #error attachInterrupt not finished for this CPU (case 0) + #endif break; + case 1: + #if defined(EICRA) && defined(ISC10) && defined(ISC11) && defined(EIMSK) EICRA = (EICRA & ~((1 << ISC10) | (1 << ISC11))) | (mode << ISC10); EIMSK |= (1 << INT1); + #elif defined(MCUCR) && defined(ISC10) && defined(ISC11) && defined(GICR) + MCUCR = (MCUCR & ~((1 << ISC10) | (1 << ISC11))) | (mode << ISC10); + GICR |= (1 << INT1); + #elif defined(MCUCR) && defined(ISC10) && defined(GIMSK) && defined(GIMSK) + MCUCR = (MCUCR & ~((1 << ISC10) | (1 << ISC11))) | (mode << ISC10); + GIMSK |= (1 << INT1); + #else + #warning attachInterrupt may need some more work for this cpu (case 1) + #endif break; #endif } @@ -105,7 +122,7 @@ void detachInterrupt(uint8_t interruptNum) { // to the number of the EIMSK bit to clear, as this isn't true on the // ATmega8. There, INT0 is 6 and INT1 is 7.) switch (interruptNum) { -#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) +#if defined(EICRA) && defined(EICRB) && defined(EIMSK) case 2: EIMSK &= ~(1 << INT0); break; @@ -132,10 +149,27 @@ void detachInterrupt(uint8_t interruptNum) { break; #else case 0: + #if defined(EIMSK) && defined(INT0) EIMSK &= ~(1 << INT0); + #elif defined(GICR) && defined(ISC00) + GICR &= ~(1 << INT0); // atmega32 + #elif defined(GIMSK) && defined(INT0) + GIMSK &= ~(1 << INT0); + #else + #error detachInterrupt not finished for this cpu + #endif break; + case 1: + #if defined(EIMSK) && defined(INT1) EIMSK &= ~(1 << INT1); + #elif defined(GICR) && defined(INT1) + GICR &= ~(1 << INT1); // atmega32 + #elif defined(GIMSK) && defined(INT1) + GIMSK &= ~(1 << INT1); + #else + #warning detachInterrupt may need some more work for this cpu (case 1) + #endif break; #endif } @@ -150,7 +184,7 @@ void attachInterruptTwi(void (*userFunc)(void) ) { } */ -#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) +#if defined(EICRA) && defined(EICRB) SIGNAL(INT0_vect) { if(intFunc[EXTERNAL_INT_2]) diff --git a/hardware/arduino/cores/arduino/wiring.c b/hardware/arduino/cores/arduino/wiring.c index eb2d44001d4..ea54aee0308 100755 --- a/hardware/arduino/cores/arduino/wiring.c +++ b/hardware/arduino/cores/arduino/wiring.c @@ -80,7 +80,14 @@ unsigned long micros() { cli(); m = timer0_overflow_count; +#if defined(TCNT0) t = TCNT0; +#elif defined(TCNT0L) + t = TCNT0L; +#else + #error TIMER 0 not defined +#endif + #ifdef TIFR0 if ((TIFR0 & _BV(TOV0)) && (t < 255)) @@ -166,62 +173,99 @@ void init() // on the ATmega168, timer 0 is also used for fast hardware pwm // (using phase-correct PWM would mean that timer 0 overflowed half as often // resulting in different millis() behavior on the ATmega8 and ATmega168) -#if !defined(__AVR_ATmega8__) +#if defined(TCCR0A) && defined(WGM01) sbi(TCCR0A, WGM01); sbi(TCCR0A, WGM00); #endif + // set timer 0 prescale factor to 64 -#if defined(__AVR_ATmega8__) +#if defined(__AVR_ATmega128__) + // CPU specific: different values for the ATmega128 + sbi(TCCR0, CS02); +#elif defined(TCCR0) && defined(CS01) && defined(CS00) + // this combination is for the standard atmega8 sbi(TCCR0, CS01); sbi(TCCR0, CS00); -#else +#elif defined(TCCR0B) && defined(CS01) && defined(CS00) + // this combination is for the standard 168/328/1280/2560 sbi(TCCR0B, CS01); sbi(TCCR0B, CS00); +#elif defined(TCCR0A) && defined(CS01) && defined(CS00) + // this combination is for the __AVR_ATmega645__ series + sbi(TCCR0A, CS01); + sbi(TCCR0A, CS00); +#else + #error Timer 0 prescale factor 64 not set correctly #endif + // enable timer 0 overflow interrupt -#if defined(__AVR_ATmega8__) +#if defined(TIMSK) && defined(TOIE0) sbi(TIMSK, TOIE0); -#else +#elif defined(TIMSK0) && defined(TOIE0) sbi(TIMSK0, TOIE0); +#else + #error Timer 0 overflow interrupt not set correctly #endif // timers 1 and 2 are used for phase-correct hardware pwm // this is better for motors as it ensures an even waveform // note, however, that fast pwm mode can achieve a frequency of up // 8 MHz (with a 16 MHz clock) at 50% duty cycle - - TCCR1B = 0; + + TCCR1B = 0; // set timer 1 prescale factor to 64 +#if defined(TCCR1B) && defined(CS11) && defined(CS10) sbi(TCCR1B, CS11); sbi(TCCR1B, CS10); +#elif defined(TCCR1) && defined(CS11) && defined(CS10) + sbi(TCCR1, CS11); + sbi(TCCR1, CS10); +#endif // put timer 1 in 8-bit phase correct pwm mode +#if defined(TCCR1A) && defined(WGM10) sbi(TCCR1A, WGM10); +#elif defined(TCCR1) + #warning this needs to be finished +#endif // set timer 2 prescale factor to 64 -#if defined(__AVR_ATmega8__) +#if defined(TCCR2) && defined(CS22) sbi(TCCR2, CS22); -#else +#elif defined(TCCR2B) && defined(CS22) sbi(TCCR2B, CS22); +#else + #warning Timer 2 not finished (may not be present on this CPU) #endif + // configure timer 2 for phase correct pwm (8-bit) -#if defined(__AVR_ATmega8__) +#if defined(TCCR2) && defined(WGM20) sbi(TCCR2, WGM20); -#else +#elif defined(TCCR2A) && defined(WGM20) sbi(TCCR2A, WGM20); +#else + #warning Timer 2 not finished (may not be present on this CPU) +#endif + +#if defined(TCCR3B) && defined(CS31) && defined(WGM30) + sbi(TCCR3B, CS31); // set timer 3, 4, 5 prescale factor to 64 + sbi(TCCR3B, CS30); + sbi(TCCR3A, WGM30); // put timer 3, 4, 5 in 8-bit phase correct pwm mode +#endif + +#if defined(TCCR4B) && defined(CS41) && defined(WGM40) + sbi(TCCR4B, CS41); // set timer 3, 4, 5 prescale factor to 64 + sbi(TCCR4B, CS40); + sbi(TCCR4A, WGM40); // put timer 3, 4, 5 in 8-bit phase correct pwm mode #endif -#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) - // set timer 3, 4, 5 prescale factor to 64 - sbi(TCCR3B, CS31); sbi(TCCR3B, CS30); - sbi(TCCR4B, CS41); sbi(TCCR4B, CS40); - sbi(TCCR5B, CS51); sbi(TCCR5B, CS50); - // put timer 3, 4, 5 in 8-bit phase correct pwm mode - sbi(TCCR3A, WGM30); - sbi(TCCR4A, WGM40); - sbi(TCCR5A, WGM50); +#if defined(TCCR5B) && defined(CS51) && defined(WGM50) + sbi(TCCR5B, CS51); // set timer 3, 4, 5 prescale factor to 64 + sbi(TCCR5B, CS50); + sbi(TCCR5A, WGM50); // put timer 3, 4, 5 in 8-bit phase correct pwm mode #endif +#if defined(ADCSRA) // set a2d prescale factor to 128 // 16 MHz / 128 = 125 KHz, inside the desired 50-200 KHz range. // XXX: this will not work properly for other clock speeds, and @@ -232,13 +276,14 @@ void init() // enable a2d conversions sbi(ADCSRA, ADEN); +#endif // the bootloader connects pins 0 and 1 to the USART; disconnect them // here so they can be used as normal digital i/o; they will be // reconnected in Serial.begin() -#if defined(__AVR_ATmega8__) +#if defined(UCSRB) UCSRB = 0; -#else +#elif defined(UCSR0B) UCSR0B = 0; #endif -} \ No newline at end of file +} diff --git a/hardware/arduino/cores/arduino/wiring.h b/hardware/arduino/cores/arduino/wiring.h index 7245797e3af..eb4a7a2fdd4 100755 --- a/hardware/arduino/cores/arduino/wiring.h +++ b/hardware/arduino/cores/arduino/wiring.h @@ -84,9 +84,18 @@ extern "C"{ #define interrupts() sei() #define noInterrupts() cli() -#define clockCyclesPerMicrosecond() ( F_CPU / 1000000L ) -#define clockCyclesToMicroseconds(a) ( (a) / clockCyclesPerMicrosecond() ) -#define microsecondsToClockCycles(a) ( (a) * clockCyclesPerMicrosecond() ) +// Mark Sproul: +// if the clock is not an even multiple of 1000000 the following causes drift +// for example with F_CPU == 14745600L +#if (F_CPU == 16000000L) || (F_CPU == 8000000L) || (F_CPU == 20000000L) + #define clockCyclesPerMicrosecond() ( F_CPU / 1000000L ) + #define clockCyclesToMicroseconds(a) ( (a) / clockCyclesPerMicrosecond() ) + #define microsecondsToClockCycles(a) ( (a) * clockCyclesPerMicrosecond() ) +#else + #define clockCyclesPerMicrosecond() ( F_CPU / 1000000L ) + #define clockCyclesToMicroseconds(a) ( (a * 1000L) / (F_CPU / 1000L) ) + #define microsecondsToClockCycles(a) (( (a) * (F_CPU / 1000) ) / 1000) +#endif #define lowByte(w) ((uint8_t) ((w) & 0xff)) #define highByte(w) ((uint8_t) ((w) >> 8)) diff --git a/hardware/arduino/cores/arduino/wiring_analog.c b/hardware/arduino/cores/arduino/wiring_analog.c old mode 100755 new mode 100644 index da0cf0781ad..d2d72989b69 --- a/hardware/arduino/cores/arduino/wiring_analog.c +++ b/hardware/arduino/cores/arduino/wiring_analog.c @@ -19,6 +19,8 @@ Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Modified 28 September 2010 by Mark Sproul + $Id: wiring.c 248 2007-02-03 15:36:30Z mellis $ */ @@ -41,22 +43,27 @@ int analogRead(uint8_t pin) #if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) if (pin >= 54) pin -= 54; // allow for channel or pin numbers +#else + if (pin >= 14) pin -= 14; // allow for channel or pin numbers +#endif +#if defined(ADCSRB) && defined(MUX5) // the MUX5 bit of ADCSRB selects whether we're reading from channels // 0 to 7 (MUX5 low) or 8 to 15 (MUX5 high). ADCSRB = (ADCSRB & ~(1 << MUX5)) | (((pin >> 3) & 0x01) << MUX5); -#else - if (pin >= 14) pin -= 14; // allow for channel or pin numbers #endif // set the analog reference (high two bits of ADMUX) and select the // channel (low 4 bits). this also sets ADLAR (left-adjust result) // to 0 (the default). +#if defined(ADMUX) ADMUX = (analog_reference << 6) | (pin & 0x07); +#endif // without a delay, we seem to read from the wrong channel //delay(1); +#if defined(ADCSRA) && defined(ADCL) // start the conversion sbi(ADCSRA, ADSC); @@ -67,8 +74,13 @@ int analogRead(uint8_t pin) // and ADCH until ADCH is read. reading ADCL second would // cause the results of each conversion to be discarded, // as ADCL and ADCH would be locked when it completed. - low = ADCL; + low = ADCL; high = ADCH; +#else + // we dont have an ADC, return 0 + low = 0; + high = 0; +#endif // combine the two bytes return (high << 8) | low; @@ -86,98 +98,163 @@ void analogWrite(uint8_t pin, int val) // for consistenty with Wiring, which doesn't require a pinMode // call for the analog output pins. pinMode(pin, OUTPUT); - - if (digitalPinToTimer(pin) == TIMER1A) { - // connect pwm to pin on timer 1, channel A - sbi(TCCR1A, COM1A1); - // set pwm duty - OCR1A = val; - } else if (digitalPinToTimer(pin) == TIMER1B) { - // connect pwm to pin on timer 1, channel B - sbi(TCCR1A, COM1B1); - // set pwm duty - OCR1B = val; -#if defined(__AVR_ATmega8__) - } else if (digitalPinToTimer(pin) == TIMER2) { - // connect pwm to pin on timer 2, channel B - sbi(TCCR2, COM21); - // set pwm duty - OCR2 = val; -#else - } else if (digitalPinToTimer(pin) == TIMER0A) { - if (val == 0) { - digitalWrite(pin, LOW); - } else { - // connect pwm to pin on timer 0, channel A - sbi(TCCR0A, COM0A1); - // set pwm duty - OCR0A = val; - } - } else if (digitalPinToTimer(pin) == TIMER0B) { - if (val == 0) { - digitalWrite(pin, LOW); - } else { - // connect pwm to pin on timer 0, channel B - sbi(TCCR0A, COM0B1); - // set pwm duty - OCR0B = val; - } - } else if (digitalPinToTimer(pin) == TIMER2A) { - // connect pwm to pin on timer 2, channel A - sbi(TCCR2A, COM2A1); - // set pwm duty - OCR2A = val; - } else if (digitalPinToTimer(pin) == TIMER2B) { - // connect pwm to pin on timer 2, channel B - sbi(TCCR2A, COM2B1); - // set pwm duty - OCR2B = val; -#endif -#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) - // XXX: need to handle other timers here - } else if (digitalPinToTimer(pin) == TIMER3A) { - // connect pwm to pin on timer 3, channel A - sbi(TCCR3A, COM3A1); - // set pwm duty - OCR3A = val; - } else if (digitalPinToTimer(pin) == TIMER3B) { - // connect pwm to pin on timer 3, channel B - sbi(TCCR3A, COM3B1); - // set pwm duty - OCR3B = val; - } else if (digitalPinToTimer(pin) == TIMER3C) { - // connect pwm to pin on timer 3, channel C - sbi(TCCR3A, COM3C1); - // set pwm duty - OCR3C = val; - } else if (digitalPinToTimer(pin) == TIMER4A) { - // connect pwm to pin on timer 4, channel A - sbi(TCCR4A, COM4A1); - // set pwm duty - OCR4A = val; - } else if (digitalPinToTimer(pin) == TIMER4B) { - // connect pwm to pin on timer 4, channel B - sbi(TCCR4A, COM4B1); - // set pwm duty - OCR4B = val; - } else if (digitalPinToTimer(pin) == TIMER4C) { - // connect pwm to pin on timer 4, channel C - sbi(TCCR4A, COM4C1); - // set pwm duty - OCR4C = val; - } else if (digitalPinToTimer(pin) == TIMER5A) { - // connect pwm to pin on timer 5, channel A - sbi(TCCR5A, COM5A1); - // set pwm duty - OCR5A = val; - } else if (digitalPinToTimer(pin) == TIMER5B) { - // connect pwm to pin on timer 5, channel B - sbi(TCCR5A, COM5B1); - // set pwm duty - OCR5B = val; -#endif - } else if (val < 128) + if (val == 0) + { digitalWrite(pin, LOW); - else + } + else if (val == 255) + { digitalWrite(pin, HIGH); + } + else + { + switch(digitalPinToTimer(pin)) + { + // XXX fix needed for atmega8 + #if defined(TCCR0) && defined(COM00) && !defined(__AVR_ATmega8__) + case TIMER0A: + // connect pwm to pin on timer 0 + sbi(TCCR0, COM00); + OCR0 = val; // set pwm duty + break; + #endif + + #if defined(TCCR0A) && defined(COM0A1) + case TIMER0A: + // connect pwm to pin on timer 0, channel A + sbi(TCCR0A, COM0A1); + OCR0A = val; // set pwm duty + break; + #endif + + #if defined(TCCR0A) && defined(COM0B1) + case TIMER0B: + // connect pwm to pin on timer 0, channel B + sbi(TCCR0A, COM0B1); + OCR0B = val; // set pwm duty + break; + #endif + + #if defined(TCCR1A) && defined(COM1A1) + case TIMER1A: + // connect pwm to pin on timer 1, channel A + sbi(TCCR1A, COM1A1); + OCR1A = val; // set pwm duty + break; + #endif + + #if defined(TCCR1A) && defined(COM1B1) + case TIMER1B: + // connect pwm to pin on timer 1, channel B + sbi(TCCR1A, COM1B1); + OCR1B = val; // set pwm duty + break; + #endif + + #if defined(TCCR2) && defined(COM21) + case TIMER2: + // connect pwm to pin on timer 2, channel B + sbi(TCCR2, COM21); + OCR2 = val; // set pwm duty + break; + #endif + + #if defined(TCCR2A) && defined(COM2A1) + case TIMER2A: + // connect pwm to pin on timer 2, channel A + sbi(TCCR2A, COM2A1); + OCR2A = val; // set pwm duty + break; + #endif + + #if defined(TCCR2A) && defined(COM2B1) + case TIMER2B: + // connect pwm to pin on timer 2, channel B + sbi(TCCR2A, COM2B1); + OCR2B = val; // set pwm duty + break; + #endif + + #if defined(TCCR3A) && defined(COM3A1) + case TIMER3A: + // connect pwm to pin on timer 3, channel A + sbi(TCCR3A, COM3A1); + OCR3A = val; // set pwm duty + break; + #endif + + #if defined(TCCR3A) && defined(COM3B1) + case TIMER3B: + // connect pwm to pin on timer 3, channel B + sbi(TCCR3A, COM3B1); + OCR3B = val; // set pwm duty + break; + #endif + + #if defined(TCCR3A) && defined(COM3C1) + case TIMER3C: + // connect pwm to pin on timer 3, channel C + sbi(TCCR3A, COM3C1); + OCR3C = val; // set pwm duty + break; + #endif + + #if defined(TCCR4A) && defined(COM4A1) + case TIMER4A: + // connect pwm to pin on timer 4, channel A + sbi(TCCR4A, COM4A1); + OCR4A = val; // set pwm duty + break; + #endif + + #if defined(TCCR4A) && defined(COM4B1) + case TIMER4B: + // connect pwm to pin on timer 4, channel B + sbi(TCCR4A, COM4B1); + OCR4B = val; // set pwm duty + break; + #endif + + #if defined(TCCR4A) && defined(COM4C1) + case TIMER4C: + // connect pwm to pin on timer 4, channel C + sbi(TCCR4A, COM4C1); + OCR4C = val; // set pwm duty + break; + #endif + + #if defined(TCCR5A) && defined(COM5A1) + case TIMER5A: + // connect pwm to pin on timer 5, channel A + sbi(TCCR5A, COM5A1); + OCR5A = val; // set pwm duty + break; + #endif + + #if defined(TCCR5A) && defined(COM5B1) + case TIMER5B: + // connect pwm to pin on timer 5, channel B + sbi(TCCR5A, COM5B1); + OCR5B = val; // set pwm duty + break; + #endif + + // Mark Sproul: added this, Its missing from the main core files + #if defined(TCCR5A) && defined(COM5C1) + case TIMER5C: + // connect pwm to pin on timer 5, channel C + sbi(TCCR5A, COM5C1); + OCR5C = val; // set pwm duty + break; + #endif + + case NOT_ON_TIMER: + default: + if (val < 128) { + digitalWrite(pin, LOW); + } else { + digitalWrite(pin, HIGH); + } + } + } } diff --git a/hardware/arduino/cores/arduino/wiring_digital.c b/hardware/arduino/cores/arduino/wiring_digital.c index 1475f0c0478..0949da42d73 100755 --- a/hardware/arduino/cores/arduino/wiring_digital.c +++ b/hardware/arduino/cores/arduino/wiring_digital.c @@ -19,6 +19,8 @@ Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Modified 28 September 2010 by Mark Sproul + $Id: wiring.c 248 2007-02-03 15:36:30Z mellis $ */ @@ -56,32 +58,67 @@ void pinMode(uint8_t pin, uint8_t mode) // But shouldn't this be moved into pinMode? Seems silly to check and do on // each digitalread or write. // -static inline void turnOffPWM(uint8_t timer) __attribute__ ((always_inline)); -static inline void turnOffPWM(uint8_t timer) +// Mark Sproul: +// - Removed inline. Save 170 bytes on atmega1280 +// - changed to a switch statment; added 32 bytes but much easier to read and maintain. +// - Added more #ifdefs, now compiles for atmega645 +// +//static inline void turnOffPWM(uint8_t timer) __attribute__ ((always_inline)); +//static inline void turnOffPWM(uint8_t timer) +static void turnOffPWM(uint8_t timer) { - if (timer == TIMER1A) cbi(TCCR1A, COM1A1); - if (timer == TIMER1B) cbi(TCCR1A, COM1B1); - -#if defined(__AVR_ATmega8__) - if (timer == TIMER2) cbi(TCCR2, COM21); -#else - if (timer == TIMER0A) cbi(TCCR0A, COM0A1); - if (timer == TIMER0B) cbi(TCCR0A, COM0B1); - if (timer == TIMER2A) cbi(TCCR2A, COM2A1); - if (timer == TIMER2B) cbi(TCCR2A, COM2B1); -#endif - -#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) - if (timer == TIMER3A) cbi(TCCR3A, COM3A1); - if (timer == TIMER3B) cbi(TCCR3A, COM3B1); - if (timer == TIMER3C) cbi(TCCR3A, COM3C1); - if (timer == TIMER4A) cbi(TCCR4A, COM4A1); - if (timer == TIMER4B) cbi(TCCR4A, COM4B1); - if (timer == TIMER4C) cbi(TCCR4A, COM4C1); - if (timer == TIMER5A) cbi(TCCR5A, COM5A1); - if (timer == TIMER5B) cbi(TCCR5A, COM5B1); - if (timer == TIMER5C) cbi(TCCR5A, COM5C1); -#endif + switch (timer) + { + #if defined(TCCR1A) && defined(COM1A1) + case TIMER1A: cbi(TCCR1A, COM1A1); break; + #endif + #if defined(TCCR1A) && defined(COM1B1) + case TIMER1B: cbi(TCCR1A, COM1B1); break; + #endif + + #if defined(TCCR2) && defined(COM21) + case TIMER2: cbi(TCCR2, COM21); break; + #endif + + #if defined(TCCR0A) && defined(COM0A1) + case TIMER0A: cbi(TCCR0A, COM0A1); break; + #endif + + #if defined(TIMER0B) && defined(COM0B1) + case TIMER0B: cbi(TCCR0A, COM0B1); break; + #endif + #if defined(TCCR2A) && defined(COM2A1) + case TIMER2A: cbi(TCCR2A, COM2A1); break; + #endif + #if defined(TCCR2A) && defined(COM2B1) + case TIMER2B: cbi(TCCR2A, COM2B1); break; + #endif + + #if defined(TCCR3A) && defined(COM3A1) + case TIMER3A: cbi(TCCR3A, COM3A1); break; + #endif + #if defined(TCCR3A) && defined(COM3B1) + case TIMER3B: cbi(TCCR3A, COM3B1); break; + #endif + #if defined(TCCR3A) && defined(COM3C1) + case TIMER3C: cbi(TCCR3A, COM3C1); break; + #endif + + #if defined(TCCR4A) && defined(COM4A1) + case TIMER4A: cbi(TCCR4A, COM4A1); break; + #endif + #if defined(TCCR4A) && defined(COM4B1) + case TIMER4B: cbi(TCCR4A, COM4B1); break; + #endif + #if defined(TCCR4A) && defined(COM4C1) + case TIMER4C: cbi(TCCR4A, COM4C1); break; + #endif + #if defined(TCCR5A) + case TIMER5A: cbi(TCCR5A, COM5A1); break; + case TIMER5B: cbi(TCCR5A, COM5B1); break; + case TIMER5C: cbi(TCCR5A, COM5C1); break; + #endif + } } void digitalWrite(uint8_t pin, uint8_t val)