Skip to content

Commit

Permalink
Adding noAnalogWrite() function to disable PWM.
Browse files Browse the repository at this point in the history
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
  • Loading branch information
damellis committed Feb 12, 2011
1 parent aa1f1cb commit 38d4a34
Show file tree
Hide file tree
Showing 5 changed files with 59 additions and 117 deletions.
1 change: 1 addition & 0 deletions build/shared/lib/keywords.txt
Expand Up @@ -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
Expand Down
43 changes: 0 additions & 43 deletions hardware/arduino/cores/arduino/pins_arduino.h
Expand Up @@ -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)
Expand Down Expand Up @@ -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.
Expand Down
6 changes: 2 additions & 4 deletions hardware/arduino/cores/arduino/wiring.h
Expand Up @@ -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);
Expand Down Expand Up @@ -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) {
Expand Down
56 changes: 56 additions & 0 deletions hardware/arduino/cores/arduino/wiring_analog.c
Expand Up @@ -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
}
}
70 changes: 0 additions & 70 deletions hardware/arduino/cores/arduino/wiring_digital.c
Expand Up @@ -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);
Expand Down

0 comments on commit 38d4a34

Please sign in to comment.