1
0
mirror of https://github.com/esp8266/Arduino.git synced 2025-06-16 11:21:18 +03:00

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 interrupts KEYWORD2
millis KEYWORD2 Millis millis KEYWORD2 Millis
micros KEYWORD2 Micros micros KEYWORD2 Micros
noAnalogWrite KEYWORD2 NoAnalogWrite
noInterrupts KEYWORD2 NoInterrupts noInterrupts KEYWORD2 NoInterrupts
noTone KEYWORD2 NoTone noTone KEYWORD2 NoTone
pinMode KEYWORD2 PinMode 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__) #else // defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
INLINED volatile uint8_t *inlined_portModeRegister(uint8_t port_index) 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__) #endif // defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
// Get the bit location within the hardware port of the given virtual pin. // 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); int analogRead(uint8_t);
void analogReference(uint8_t mode); void analogReference(uint8_t mode);
void analogWrite(uint8_t, int); void analogWrite(uint8_t, int);
void noAnalogWrite(uint8_t);
unsigned long millis(void); unsigned long millis(void);
unsigned long micros(void); unsigned long micros(void);
@ -145,10 +146,7 @@ INLINED uint8_t digitalPinToBitMask(uint8_t pin) {
} }
INLINED uint8_t digitalPinToTimer(uint8_t pin) { INLINED uint8_t digitalPinToTimer(uint8_t pin) {
if (__builtin_constant_p(pin)) return pgm_read_byte( digital_pin_to_timer_PGM + pin );
return inlined_digitalPinToTimer(pin);
else
return pgm_read_byte( digital_pin_to_timer_PGM + pin );
} }
INLINED volatile uint8_t *portOutputRegister(uint8_t index) { 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); 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) void digitalWrite_lookup(uint8_t pin, uint8_t val)
{ {
digitalWrite_implementation(pin, val); digitalWrite_implementation(pin, val);