From cd050d05d1fa7ae87da68574a9e50edf6ac1ed8f Mon Sep 17 00:00:00 2001 From: "David A. Mellis" Date: Sat, 12 Feb 2011 14:47:08 -0500 Subject: Adding noAnalogWrite() function to disable PWM. Also, removing the inline version of digitalPinToTimer() (since we're not optimizing the functions that use it anyway). The noAnalogWrite() function is in wiring_analog.c, deriving from the previous turnOffPWM() which has moved from wiring_digital.c. http://code.google.com/p/arduino/issues/detail?id=476 --- cores/arduino/pins_arduino.h | 43 -------------------------- cores/arduino/wiring.h | 6 ++-- cores/arduino/wiring_analog.c | 56 +++++++++++++++++++++++++++++++++ cores/arduino/wiring_digital.c | 70 ------------------------------------------ 4 files changed, 58 insertions(+), 117 deletions(-) diff --git a/cores/arduino/pins_arduino.h b/cores/arduino/pins_arduino.h index 4bf6470..ca6a821 100644 --- a/cores/arduino/pins_arduino.h +++ b/cores/arduino/pins_arduino.h @@ -339,30 +339,6 @@ INLINED uint8_t inlined_digitalPinToBitMask(uint8_t pin) } } -// XXX: this needs to return false (or -1) if the pin doesn't have a timer, -// rather than throwing a compilation error. -INLINED uint8_t inlined_digitalPinToTimer(uint8_t pin) -{ - switch(pin) { - case 2: return TIMER3B; // PE 4 ** 2 ** PWM2 - case 3: return TIMER3C; // PE 5 ** 3 ** PWM3 - case 4: return TIMER0B; // PG 5 ** 4 ** PWM4 - case 5: return TIMER3A; // PE 3 ** 5 ** PWM5 - case 6: return TIMER4A; // PH 3 ** 6 ** PWM6 - case 7: return TIMER4B; // PH 4 ** 7 ** PWM7 - case 8: return TIMER4C; // PH 5 ** 8 ** PWM8 - case 9: return TIMER2B; // PH 6 ** 9 ** PWM9 - case 10: return TIMER2A; // PB 4 ** 10 ** PWM10 - case 11: return TIMER1A; // PB 5 ** 11 ** PWM11 - case 12: return TIMER1B; // PB 6 ** 12 ** PWM12 - case 13: return TIMER0A; // PB 7 ** 13 ** PWM13 - case 44: return TIMER5C; // PL 5 ** 44 ** D44 - case 45: return TIMER5B; // PL 4 ** 45 ** D45 - case 46: return TIMER5A; // PL 3 ** 46 ** D46 - default: invalidPinSpecified(); - } -} - #else // defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) INLINED volatile uint8_t *inlined_portModeRegister(uint8_t port_index) @@ -455,25 +431,6 @@ INLINED uint8_t inlined_digitalPinToBitMask(uint8_t pin) } } -// XXX: this needs to return false (or -1) if the pin doesn't have a timer, -// rather than throwing a compilation error. -INLINED uint8_t inlined_digitalPinToTimer(uint8_t pin) -{ - switch(pin) { -#if defined(__AVR_ATmega8__) - case 11: return TIMER2; -#else - case 3: return TIMER2B; - case 5: return TIMER0B; - case 6: return TIMER0A; - case 11: return TIMER2A; -#endif - case 9: return TIMER1A; - case 10: return TIMER1B; - default: invalidPinSpecified(); - } -} - #endif // defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) // Get the bit location within the hardware port of the given virtual pin. diff --git a/cores/arduino/wiring.h b/cores/arduino/wiring.h index 66ce2f7..2915b63 100755 --- a/cores/arduino/wiring.h +++ b/cores/arduino/wiring.h @@ -114,6 +114,7 @@ int digitalRead_lookup(uint8_t); int analogRead(uint8_t); void analogReference(uint8_t mode); void analogWrite(uint8_t, int); +void noAnalogWrite(uint8_t); unsigned long millis(void); unsigned long micros(void); @@ -145,10 +146,7 @@ INLINED uint8_t digitalPinToBitMask(uint8_t pin) { } INLINED uint8_t digitalPinToTimer(uint8_t pin) { - if (__builtin_constant_p(pin)) - return inlined_digitalPinToTimer(pin); - else - return pgm_read_byte( digital_pin_to_timer_PGM + pin ); + return pgm_read_byte( digital_pin_to_timer_PGM + pin ); } INLINED volatile uint8_t *portOutputRegister(uint8_t index) { diff --git a/cores/arduino/wiring_analog.c b/cores/arduino/wiring_analog.c index d248f4c..6185022 100644 --- a/cores/arduino/wiring_analog.c +++ b/cores/arduino/wiring_analog.c @@ -257,3 +257,59 @@ void analogWrite(uint8_t pin, int val) } } } + +void noAnalogWrite(uint8_t pin) +{ + switch (digitalPinToTimer(pin)) + { + #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 + } +} \ No newline at end of file diff --git a/cores/arduino/wiring_digital.c b/cores/arduino/wiring_digital.c index 9671045..20930c5 100755 --- a/cores/arduino/wiring_digital.c +++ b/cores/arduino/wiring_digital.c @@ -32,76 +32,6 @@ void pinMode_lookup(uint8_t pin, uint8_t val) pinMode_implementation(pin, val); } -// Forcing this inline keeps the callers from having to push their own stuff -// on the stack. It is a good performance win and only takes 1 more byte per -// user than calling. (It will take more bytes on the 168.) -// -// But shouldn't this be moved into pinMode? Seems silly to check and do on -// each digitalread or write. -// -// 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) -{ - 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_lookup(uint8_t pin, uint8_t val) { digitalWrite_implementation(pin, val); -- cgit v1.2.3-18-g5258