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
This commit is contained in:
David A. Mellis 2011-02-12 14:47:08 -05:00
parent aa1f1cbda9
commit 38d4a34fec
5 changed files with 59 additions and 117 deletions

View File

@ -153,6 +153,7 @@ digitalRead KEYWORD2 DigitalRead
interrupts KEYWORD2
millis KEYWORD2 Millis
micros KEYWORD2 Micros
noAnalogWrite KEYWORD2 NoAnalogWrite
noInterrupts KEYWORD2 NoInterrupts
noTone KEYWORD2 NoTone
pinMode KEYWORD2 PinMode

View File

@ -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.

View File

@ -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) {

View File

@ -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
}
}

View File

@ -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);