diff --git a/hardware/arduino/cores/arduino/Arduino.h b/hardware/arduino/cores/arduino/Arduino.h index b265825894a..5f218dcc466 100755 --- a/hardware/arduino/cores/arduino/Arduino.h +++ b/hardware/arduino/cores/arduino/Arduino.h @@ -8,6 +8,7 @@ #include #include #include +#include #include "binary.h" @@ -45,7 +46,7 @@ extern "C"{ #define DEFAULT 0 #define EXTERNAL 1 #define INTERNAL 2 -#else +#else #if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) || defined(__AVR_ATmega1284P__) || defined(__AVR_ATmega644P__) #define INTERNAL1V1 2 #define INTERNAL2V56 3 @@ -95,9 +96,9 @@ typedef uint8_t byte; void init(void); -void pinMode(uint8_t, uint8_t); -void digitalWrite(uint8_t, uint8_t); -int digitalRead(uint8_t); +static inline void pinMode(uint8_t, uint8_t); +static inline void digitalWrite(uint8_t, uint8_t); +static inline int digitalRead(uint8_t); int analogRead(uint8_t); void analogReference(uint8_t mode); void analogWrite(uint8_t, int); @@ -122,66 +123,12 @@ void loop(void); #define analogInPinToBit(P) (P) -// On the ATmega1280, the addresses of some of the port registers are -// greater than 255, so we can't store them in uint8_t's. -extern const uint16_t PROGMEM port_to_mode_PGM[]; -extern const uint16_t PROGMEM port_to_input_PGM[]; -extern const uint16_t PROGMEM port_to_output_PGM[]; - -extern const uint8_t PROGMEM digital_pin_to_port_PGM[]; -// extern const uint8_t PROGMEM digital_pin_to_bit_PGM[]; -extern const uint8_t PROGMEM digital_pin_to_bit_mask_PGM[]; -extern const uint8_t PROGMEM digital_pin_to_timer_PGM[]; - // Get the bit location within the hardware port of the given virtual pin. // This comes from the pins_*.c file for the active board configuration. -// +// // These perform slightly better as macros compared to inline functions // -#define digitalPinToPort(P) ( pgm_read_byte( digital_pin_to_port_PGM + (P) ) ) -#define digitalPinToBitMask(P) ( pgm_read_byte( digital_pin_to_bit_mask_PGM + (P) ) ) -#define digitalPinToTimer(P) ( pgm_read_byte( digital_pin_to_timer_PGM + (P) ) ) #define analogInPinToBit(P) (P) -#define portOutputRegister(P) ( (volatile uint8_t *)( pgm_read_word( port_to_output_PGM + (P))) ) -#define portInputRegister(P) ( (volatile uint8_t *)( pgm_read_word( port_to_input_PGM + (P))) ) -#define portModeRegister(P) ( (volatile uint8_t *)( pgm_read_word( port_to_mode_PGM + (P))) ) - -#define NOT_A_PIN 0 -#define NOT_A_PORT 0 - -#ifdef ARDUINO_MAIN -#define PA 1 -#define PB 2 -#define PC 3 -#define PD 4 -#define PE 5 -#define PF 6 -#define PG 7 -#define PH 8 -#define PJ 10 -#define PK 11 -#define PL 12 -#endif - -#define NOT_ON_TIMER 0 -#define TIMER0A 1 -#define TIMER0B 2 -#define TIMER1A 3 -#define TIMER1B 4 -#define TIMER2 5 -#define TIMER2A 6 -#define TIMER2B 7 - -#define TIMER3A 8 -#define TIMER3B 9 -#define TIMER3C 10 -#define TIMER4A 11 -#define TIMER4B 12 -#define TIMER4C 13 -#define TIMER4D 14 -#define TIMER5A 15 -#define TIMER5B 16 -#define TIMER5C 17 #ifdef __cplusplus } // extern "C" @@ -210,6 +157,6 @@ long map(long, long, long, long, long); #endif -#include "pins_arduino.h" +#include "pin_functions.h" #endif diff --git a/hardware/arduino/cores/arduino/pin_functions.h b/hardware/arduino/cores/arduino/pin_functions.h new file mode 100644 index 00000000000..b1997afc9d8 --- /dev/null +++ b/hardware/arduino/cores/arduino/pin_functions.h @@ -0,0 +1,339 @@ +/* + * This header includes pins_arduino.h to get board-specific pin data, + * then lays out the functions for inlining digital reads & writes based + * on that pin data. + */ +#ifndef _PIN_FUNCTIONS_H +#define _PIN_FUNCTIONS_H + +#ifdef __cplusplus +extern "C" { +#endif + +#define NOT_A_PIN 0 +#define NOT_A_PORT 0 + +#define NOT_ON_TIMER 0 +#define TIMER0A 1 +#define TIMER0B 2 +#define TIMER1A 3 +#define TIMER1B 4 +#define TIMER2 5 +#define TIMER2A 6 +#define TIMER2B 7 + +#define TIMER3A 8 +#define TIMER3B 9 +#define TIMER3C 10 +#define TIMER4A 11 +#define TIMER4B 12 +#define TIMER4C 13 +#define TIMER4D 14 +#define TIMER5A 15 +#define TIMER5B 16 +#define TIMER5C 17 + +#define PA 1 +#define PB 2 +#define PC 3 +#define PD 4 +#define PE 5 +#define PF 6 +#define PG 7 +#define PH 8 +#define PJ 10 +#define PK 11 +#define PL 12 + +#include "pins_arduino.h" + +#define INLINED __attribute__((always_inline)) static inline + +// The extern PROGMEM versions of each of these is for runtime lookups, +// the static const versions are for lookups when the pin is known at compile time +// (see the below inline functions, and wiring_digital.c) +// Source of the pin mappings is pins_arduino.h + +extern const uint16_t PROGMEM port_to_mode_P[]; +static const uint16_t port_to_mode[] = { PORT_TO_MODE }; + +extern const uint16_t PROGMEM port_to_output_P[]; +static const uint16_t port_to_output[] = { PORT_TO_OUTPUT }; + +extern const uint16_t PROGMEM port_to_input_P[]; +static const uint16_t port_to_input[] = { PORT_TO_INPUT }; + +extern const uint8_t PROGMEM digital_pin_to_port_P[]; +static const uint8_t digital_pin_to_port[] = { DIGITAL_PIN_TO_PORT }; + +extern const uint8_t PROGMEM digital_pin_to_bit_mask_P[]; +static const uint8_t digital_pin_to_bit_mask[] = { DIGITAL_PIN_TO_BIT_MASK }; + + extern const uint8_t PROGMEM digital_pin_to_timer_P[]; + static const uint8_t digital_pin_to_timer[] = { DIGITAL_PIN_TO_TIMER }; + +INLINED uint8_t digitalPinToPort(uint8_t pin) { + return __builtin_constant_p(pin) ? digital_pin_to_port[pin] + : pgm_read_byte( digital_pin_to_port_P + pin ); +} + +/* These internal lookup functions will automatically resolve from the static const + * tables if evaluated at compile time, or the PROGMEM tables if evaluated + * at runtime: + */ + +INLINED volatile uint8_t *portOutputRegister(uint8_t port_idx) { + return (volatile uint8_t *)( __builtin_constant_p(port_idx) ? + port_to_output[port_idx] + : pgm_read_word( port_to_output_P + port_idx) ); +} + +INLINED volatile uint8_t *portDirectionRegister(uint8_t port_idx) { + return (volatile uint8_t *)( __builtin_constant_p(port_idx) ? + port_to_mode[port_idx] + : pgm_read_word( port_to_mode_P + port_idx ) ); +} + +INLINED volatile uint8_t *portInputRegister(uint8_t port_idx) { + return (volatile uint8_t *)( __builtin_constant_p(port_idx) ? + port_to_input[port_idx] + : pgm_read_word( port_to_input_P + port_idx ) ); +} + +INLINED uint8_t digitalPinToBitMask(uint8_t pin) { + return __builtin_constant_p(pin) ? digital_pin_to_bit_mask[pin] + : pgm_read_byte( digital_pin_to_bit_mask_P + pin ); +} + +INLINED uint8_t digitalPinToTimer(uint8_t pin) { + return __builtin_constant_p(pin) ? digital_pin_to_timer[pin] + : pgm_read_byte( digital_pin_to_timer_P + pin ); +} + + +/* +* Check if a given pin can be accessed in a single instruction. +* +* When accessing lower 32 IO ports we can use SBI/CBI instructions, which are atomic. However +* other IO ports require load+modify+store and we need to make them atomic by disabling +* interrupts. +* +* This routine only returns true if the port is known at compile time, because +* we'll be using memory mapped I/O regardless in the latter case. +* +* We test __builtin_constant_p on pin not port because testing the latter doesn't +* work in gcc 4.3.2, although gcc 4.3.2 does successfully optimise away the +* comparison... +* +*/ +INLINED int portIsAtomic(uint8_t pin, volatile uint8_t *port) { + /* SBI/CBI instructions only work on lower 32 IO ports */ + return __builtin_constant_p(pin) && (uint16_t)port <= 0x1F + __SFR_OFFSET; +} + + +/* + * The following functions (pinMode, digitalWrite, digitalRead, + * turnOffPWM) all follow a pattern: + * + * _xxxxInline is a version of the function that is capable of being + * inlined at compile time. Where the pin number is known at compile + * time, this function can optimise down to the minimal number of + * instructions possible. The function still works adequately even + * if the pin number is not known at compile time. + * + * _xxxxRuntime is an extern version of the function suitable for + * being called at runtime (for when the pin number is not known at + * compile time.) The implementation is in wiring_digital.c, but it + * actually just inlines _xxxxInline to provide the matching + * non-inline implementation. + * + * 'xxxx' is the actual version of the function, which just chooses + * between _xxxxInline (inlined) or _xxxxRuntime (called + * conventionally) at compile time, based on whether the pin number is + * known. + * + */ + +INLINED void _pinModeInline(uint8_t pin, uint8_t mode) { + const uint8_t port = digitalPinToPort(pin); + volatile uint8_t *dir = portDirectionRegister(port); + volatile uint8_t *out = portOutputRegister(port); + const uint8_t bitmask = digitalPinToBitMask(pin); + + if (pin >= NUM_DIGITAL_PINS) return; + + // We can only do this without disabling interrupts if + // both registers can use sbi/cbi + const int is_atomic = portIsAtomic(pin, dir) + && ((__builtin_constant_p(mode) && mode == OUTPUT) || portIsAtomic(pin, out)); + uint8_t oldSREG; + + if(!is_atomic) { // Resolves at compile time + oldSREG = SREG; + cli(); + } + + if(mode == INPUT_PULLUP) { + *out |= bitmask; + } else if(mode == INPUT) { + *out &= ~bitmask; + } + if(mode == INPUT_PULLUP || mode == INPUT) { + *dir &= ~bitmask; + } else { + *dir |= bitmask; + } + + if(!is_atomic) // Resolves at compile time + SREG = oldSREG; +} + +void _pinModeRuntime(uint8_t, uint8_t); + +INLINED void pinMode(uint8_t pin, uint8_t mode) { + // If we know the pin number, inline directly. Otherwise make a function call. + if(__builtin_constant_p(pin)) + _pinModeInline(pin,mode); + else + _pinModeRuntime(pin,mode); +} + + +INLINED void _turnOffPWMInline(uint8_t pin) +{ + const uint8_t timer = digitalPinToTimer(pin); + switch (timer) + { +#if defined(TCCR1A) && defined(COM1A1) + case TIMER1A: TCCR1A &= ~_BV(COM1A1); break; +#endif +#if defined(TCCR1A) && defined(COM1B1) + case TIMER1B: TCCR1A &= ~_BV(COM1B1); break; +#endif + +#if defined(TCCR2) && defined(COM21) + case TIMER2: TCCR2 &= ~_BV(COM21); break; +#endif + +#if defined(TCCR0A) && defined(COM0A1) + case TIMER0A: TCCR0A &= ~_BV(COM0A1); break; +#endif + +#if defined(TIMER0B) && defined(COM0B1) + case TIMER0B: TCCR0A &= ~_BV(COM0B1); break; +#endif +#if defined(TCCR2A) && defined(COM2A1) + case TIMER2A: TCCR2A &= ~_BV(COM2A1); break; +#endif +#if defined(TCCR2A) && defined(COM2B1) + case TIMER2B: TCCR2A &= ~_BV(COM2B1); break; +#endif + +#if defined(TCCR3A) && defined(COM3A1) + case TIMER3A: TCCR3A &= ~_BV(COM3A1); break; +#endif +#if defined(TCCR3A) && defined(COM3B1) + case TIMER3B: TCCR3A &= ~_BV(COM3B1); break; +#endif +#if defined(TCCR3A) && defined(COM3C1) + case TIMER3C: TCCR3A &= ~_BV(COM3C1); break; +#endif + +#if defined(TCCR4A) && defined(COM4A1) + case TIMER4A: TCCR4A &= ~_BV(COM4A1); break; +#endif +#if defined(TCCR4A) && defined(COM4B1) + case TIMER4B: TCCR4A &= ~_BV(COM4B1); break; +#endif +#if defined(TCCR4A) && defined(COM4C1) + case TIMER4C: TCCR4A &= ~_BV(COM4C1); break; +#endif +#if defined(TCCR4C) && defined(COM4D1) + case TIMER4D: TCCR4C &= ~_BV(COM4D1); break; +#endif + +#if defined(TCCR5A) + case TIMER5A: TCCR5A &= ~_BV(COM5A1); break; + case TIMER5B: TCCR5A &= ~_BV(COM5B1); break; + case TIMER5C: TCCR5A &= ~_BV(COM5C1); break; +#endif + } +} + +void _turnOffPWMRuntime(uint8_t pin); + +INLINED void turnOffPWM(const uint8_t pin) { + if(__builtin_constant_p(pin)) + _turnOffPWMInline(pin); + else + _turnOffPWMRuntime(pin); +} + +INLINED void _digitalWriteInline(const uint8_t pin, const uint8_t value) { + const uint8_t port = digitalPinToPort(pin); + volatile uint8_t *out = portOutputRegister(port); + const uint8_t bitmask = digitalPinToBitMask(pin); + + if (pin >= NUM_DIGITAL_PINS) return; + + turnOffPWM(pin); + + const int is_atomic = portIsAtomic(pin, out); // Resolves at compile time + + uint8_t oldSREG; + if(!is_atomic) { // Resolves at compile time + oldSREG = SREG; + cli(); + } + + if(value) + *out |= bitmask; + else + *out &= ~bitmask; + + if(!is_atomic) // Resolves at compile time + SREG = oldSREG; +} + +void _digitalWriteRuntime(uint8_t, uint8_t); + +INLINED void digitalWrite(uint8_t pin, uint8_t value) { + // If we know the pin number, inline directly. Otherwise make a function call. + if(__builtin_constant_p(pin)) + _digitalWriteInline(pin,value); + else + _digitalWriteRuntime(pin,value); +} + + +INLINED int _digitalReadInline(uint8_t pin) { + const uint8_t port = digitalPinToPort(pin); + const volatile uint8_t *in = portInputRegister(port); + const uint8_t bitmask = digitalPinToBitMask(pin); + + if (port == NOT_A_PIN) return LOW; + if (pin >= NUM_DIGITAL_PINS) return LOW; + + turnOffPWM(pin); + + if (*in & bitmask) return HIGH; + return LOW; +} + +int _digitalReadRuntime(uint8_t); + +INLINED int digitalRead(uint8_t pin) { + // If we know the pin number, inline directly. Otherwise make a function call. + if(__builtin_constant_p(pin)) + return _digitalReadInline(pin); + else + return _digitalReadRuntime(pin); +} + +#ifdef __cplusplus +} +#endif +#endif + + diff --git a/hardware/arduino/cores/arduino/wiring_digital.c b/hardware/arduino/cores/arduino/wiring_digital.c index be323b1dfef..cc34f81211a 100644 --- a/hardware/arduino/cores/arduino/wiring_digital.c +++ b/hardware/arduino/cores/arduino/wiring_digital.c @@ -26,153 +26,35 @@ #define ARDUINO_MAIN #include "wiring_private.h" -#include "pins_arduino.h" +#include "pin_functions.h" -void pinMode(uint8_t pin, uint8_t mode) -{ - uint8_t bit = digitalPinToBitMask(pin); - uint8_t port = digitalPinToPort(pin); - volatile uint8_t *reg, *out; - - if (port == NOT_A_PIN) return; +// This are versions that call back into, where the pin isn't known +// at compile-time. - // JWS: can I let the optimizer do this? - reg = portModeRegister(port); - out = portOutputRegister(port); +const uint16_t port_to_mode_P[] = { PORT_TO_MODE }; +const uint16_t PROGMEM port_to_output_P[] = { PORT_TO_OUTPUT }; +const uint16_t PROGMEM port_to_input_P[] = { PORT_TO_INPUT }; +const uint8_t PROGMEM digital_pin_to_port_P[] = { DIGITAL_PIN_TO_PORT }; +const uint8_t PROGMEM digital_pin_to_bit_mask_P[] = { DIGITAL_PIN_TO_BIT_MASK }; +const uint8_t PROGMEM digital_pin_to_timer_P[] = { DIGITAL_PIN_TO_TIMER }; - if (mode == INPUT) { - uint8_t oldSREG = SREG; - cli(); - *reg &= ~bit; - *out &= ~bit; - SREG = oldSREG; - } else if (mode == INPUT_PULLUP) { - uint8_t oldSREG = SREG; - cli(); - *reg &= ~bit; - *out |= bit; - SREG = oldSREG; - } else { - uint8_t oldSREG = SREG; - cli(); - *reg |= bit; - SREG = oldSREG; - } +void _pinModeRuntime(uint8_t pin, uint8_t mode) +{ + _pinModeInline(pin, mode); } -// 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) +void _digitalWriteRuntime(uint8_t pin, uint8_t val) { - 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(TCCR4C) && defined(COM4D1) - case TIMER4D: cbi(TCCR4C, COM4D1); break; - #endif - - #if defined(TCCR5A) - case TIMER5A: cbi(TCCR5A, COM5A1); break; - case TIMER5B: cbi(TCCR5A, COM5B1); break; - case TIMER5C: cbi(TCCR5A, COM5C1); break; - #endif - } + _digitalWriteInline(pin, val); } -void digitalWrite(uint8_t pin, uint8_t val) +int _digitalReadRuntime(uint8_t pin) { - uint8_t timer = digitalPinToTimer(pin); - uint8_t bit = digitalPinToBitMask(pin); - uint8_t port = digitalPinToPort(pin); - volatile uint8_t *out; - - if (port == NOT_A_PIN) return; - - // If the pin that support PWM output, we need to turn it off - // before doing a digital write. - if (timer != NOT_ON_TIMER) turnOffPWM(timer); - - out = portOutputRegister(port); - - uint8_t oldSREG = SREG; - cli(); - - if (val == LOW) { - *out &= ~bit; - } else { - *out |= bit; - } - - SREG = oldSREG; + return _digitalReadInline(pin); } -int digitalRead(uint8_t pin) +void _turnOffPWMRuntime(uint8_t pin) { - uint8_t timer = digitalPinToTimer(pin); - uint8_t bit = digitalPinToBitMask(pin); - uint8_t port = digitalPinToPort(pin); - - if (port == NOT_A_PIN) return LOW; - - // If the pin that support PWM output, we need to turn it off - // before getting a digital reading. - if (timer != NOT_ON_TIMER) turnOffPWM(timer); - - if (*portInputRegister(port) & bit) return HIGH; - return LOW; + _turnOffPWMInline(pin); } + diff --git a/hardware/arduino/variants/leonardo/pins_arduino.h b/hardware/arduino/variants/leonardo/pins_arduino.h index 2c7f8372f45..2c391444981 100644 --- a/hardware/arduino/variants/leonardo/pins_arduino.h +++ b/hardware/arduino/variants/leonardo/pins_arduino.h @@ -132,8 +132,6 @@ static const uint8_t A11 = 29; // D12 extern const uint8_t PROGMEM analog_pin_to_channel_PGM[]; #define analogPinToChannel(P) ( pgm_read_byte( analog_pin_to_channel_PGM + (P) ) ) -#ifdef ARDUINO_MAIN - // On the Arduino board, digital pins are also used // for the analog output (software PWM). Analog input // pins are a separate set. @@ -177,146 +175,142 @@ extern const uint8_t PROGMEM analog_pin_to_channel_PGM[]; // these arrays map port names (e.g. port B) to the // appropriate addresses for various functions (e.g. reading // and writing) -const uint16_t PROGMEM port_to_mode_PGM[] = { - NOT_A_PORT, - NOT_A_PORT, - (uint16_t) &DDRB, - (uint16_t) &DDRC, - (uint16_t) &DDRD, - (uint16_t) &DDRE, - (uint16_t) &DDRF, -}; +#define PORT_TO_MODE \ + NOT_A_PORT, \ + NOT_A_PORT, \ + (uint16_t) &DDRB, \ + (uint16_t) &DDRC, \ + (uint16_t) &DDRD, \ + (uint16_t) &DDRE, \ + (uint16_t) &DDRF, -const uint16_t PROGMEM port_to_output_PGM[] = { - NOT_A_PORT, - NOT_A_PORT, - (uint16_t) &PORTB, - (uint16_t) &PORTC, - (uint16_t) &PORTD, - (uint16_t) &PORTE, - (uint16_t) &PORTF, -}; +#define PORT_TO_OUTPUT \ + NOT_A_PORT, \ + NOT_A_PORT, \ + (uint16_t) &PORTB, \ + (uint16_t) &PORTC, \ + (uint16_t) &PORTD, \ + (uint16_t) &PORTE, \ + (uint16_t) &PORTF, -const uint16_t PROGMEM port_to_input_PGM[] = { - NOT_A_PORT, - NOT_A_PORT, - (uint16_t) &PINB, - (uint16_t) &PINC, - (uint16_t) &PIND, - (uint16_t) &PINE, - (uint16_t) &PINF, -}; +#define PORT_TO_INPUT \ + NOT_A_PORT, \ + NOT_A_PORT, \ + (uint16_t) &PINB, \ + (uint16_t) &PINC, \ + (uint16_t) &PIND, \ + (uint16_t) &PINE, \ + (uint16_t) &PINF, \ -const uint8_t PROGMEM digital_pin_to_port_PGM[] = { - PD, // D0 - PD2 - PD, // D1 - PD3 - PD, // D2 - PD1 - PD, // D3 - PD0 - PD, // D4 - PD4 - PC, // D5 - PC6 - PD, // D6 - PD7 - PE, // D7 - PE6 - - PB, // D8 - PB4 - PB, // D9 - PB5 - PB, // D10 - PB6 - PB, // D11 - PB7 - PD, // D12 - PD6 - PC, // D13 - PC7 - - PB, // D14 - MISO - PB3 - PB, // D15 - SCK - PB1 - PB, // D16 - MOSI - PB2 - PB, // D17 - SS - PB0 - - PF, // D18 - A0 - PF7 - PF, // D19 - A1 - PF6 - PF, // D20 - A2 - PF5 - PF, // D21 - A3 - PF4 - PF, // D22 - A4 - PF1 - PF, // D23 - A5 - PF0 - - PD, // D24 / D4 - A6 - PD4 - PD, // D25 / D6 - A7 - PD7 - PB, // D26 / D8 - A8 - PB4 - PB, // D27 / D9 - A9 - PB5 - PB, // D28 / D10 - A10 - PB6 - PD, // D29 / D12 - A11 - PD6 -}; +#define DIGITAL_PIN_TO_PORT \ + PD, /* D0 - PD2 */ \ + PD, /* D1 - PD3 */ \ + PD, /* D2 - PD1 */ \ + PD, /* D3 - PD0 */ \ + PD, /* D4 - PD4 */ \ + PC, /* D5 - PC6 */ \ + PD, /* D6 - PD7 */ \ + PE, /* D7 - PE6 */ \ + \ + PB, /* D8 - PB4 */ \ + PB, /* D9 - PB5 */ \ + PB, /* D10 - PB6 */ \ + PB, /* D11 - PB7 */ \ + PD, /* D12 - PD6 */ \ + PC, /* D13 - PC7 */ \ + \ + PB, /* D14 - MISO - PB3 */ \ + PB, /* D15 - SCK - PB1 */ \ + PB, /* D16 - MOSI - PB2 */ \ + PB, /* D17 - SS - PB0 */ \ + \ + PF, /* D18 - A0 - PF7 */ \ + PF, /* D19 - A1 - PF6 */ \ + PF, /* D20 - A2 - PF5 */ \ + PF, /* D21 - A3 - PF4 */ \ + PF, /* D22 - A4 - PF1 */ \ + PF, /* D23 - A5 - PF0 */ \ + \ + PD, /* D24 / D4 - A6 - PD4 */ \ + PD, /* D25 / D6 - A7 - PD7 */ \ + PB, /* D26 / D8 - A8 - PB4 */ \ + PB, /* D27 / D9 - A9 - PB5 */ \ + PB, /* D28 / D10 - A10 - PB6 */ \ + PD, /* D29 / D12 - A11 - PD6 */ -const uint8_t PROGMEM digital_pin_to_bit_mask_PGM[] = { - _BV(2), // D0 - PD2 - _BV(3), // D1 - PD3 - _BV(1), // D2 - PD1 - _BV(0), // D3 - PD0 - _BV(4), // D4 - PD4 - _BV(6), // D5 - PC6 - _BV(7), // D6 - PD7 - _BV(6), // D7 - PE6 - - _BV(4), // D8 - PB4 - _BV(5), // D9 - PB5 - _BV(6), // D10 - PB6 - _BV(7), // D11 - PB7 - _BV(6), // D12 - PD6 - _BV(7), // D13 - PC7 - - _BV(3), // D14 - MISO - PB3 - _BV(1), // D15 - SCK - PB1 - _BV(2), // D16 - MOSI - PB2 - _BV(0), // D17 - SS - PB0 - - _BV(7), // D18 - A0 - PF7 - _BV(6), // D19 - A1 - PF6 - _BV(5), // D20 - A2 - PF5 - _BV(4), // D21 - A3 - PF4 - _BV(1), // D22 - A4 - PF1 - _BV(0), // D23 - A5 - PF0 - - _BV(4), // D24 / D4 - A6 - PD4 - _BV(7), // D25 / D6 - A7 - PD7 - _BV(4), // D26 / D8 - A8 - PB4 - _BV(5), // D27 / D9 - A9 - PB5 - _BV(6), // D28 / D10 - A10 - PB6 - _BV(6), // D29 / D12 - A11 - PD6 -}; +#define DIGITAL_PIN_TO_BIT_MASK \ + _BV(2), /* D0 - PD2 */ \ + _BV(3), /* D1 - PD3 */ \ + _BV(1), /* D2 - PD1 */ \ + _BV(0), /* D3 - PD0 */ \ + _BV(4), /* D4 - PD4 */ \ + _BV(6), /* D5 - PC6 */ \ + _BV(7), /* D6 - PD7 */ \ + _BV(6), /* D7 - PE6 */ \ + \ + _BV(4), /* D8 - PB4 */ \ + _BV(5), /* D9 - PB5 */ \ + _BV(6), /* D10 - PB6 */ \ + _BV(7), /* D11 - PB7 */ \ + _BV(6), /* D12 - PD6 */ \ + _BV(7), /* D13 - PC7 */ \ + \ + _BV(3), /* D14 - MISO - PB3 */ \ + _BV(1), /* D15 - SCK - PB1 */ \ + _BV(2), /* D16 - MOSI - PB2 */ \ + _BV(0), /* D17 - SS - PB0 */ \ + \ + _BV(7), /* D18 - A0 - PF7 */ \ + _BV(6), /* D19 - A1 - PF6 */ \ + _BV(5), /* D20 - A2 - PF5 */ \ + _BV(4), /* D21 - A3 - PF4 */ \ + _BV(1), /* D22 - A4 - PF1 */ \ + _BV(0), /* D23 - A5 - PF0 */ \ + \ + _BV(4), /* D24 / D4 - A6 - PD4 */ \ + _BV(7), /* D25 / D6 - A7 - PD7 */ \ + _BV(4), /* D26 / D8 - A8 - PB4 */ \ + _BV(5), /* D27 / D9 - A9 - PB5 */ \ + _BV(6), /* D28 / D10 - A10 - PB6 */ \ + _BV(6), /* D29 / D12 - A11 - PD6 */ -const uint8_t PROGMEM digital_pin_to_timer_PGM[] = { - NOT_ON_TIMER, - NOT_ON_TIMER, - NOT_ON_TIMER, - TIMER0B, /* 3 */ - NOT_ON_TIMER, - TIMER3A, /* 5 */ - TIMER4D, /* 6 */ - NOT_ON_TIMER, - - NOT_ON_TIMER, - TIMER1A, /* 9 */ - TIMER1B, /* 10 */ - TIMER0A, /* 11 */ - - NOT_ON_TIMER, - TIMER4A, /* 13 */ - - NOT_ON_TIMER, - NOT_ON_TIMER, - NOT_ON_TIMER, - NOT_ON_TIMER, - NOT_ON_TIMER, - NOT_ON_TIMER, +#define DIGITAL_PIN_TO_TIMER \ + NOT_ON_TIMER, \ + NOT_ON_TIMER, \ + NOT_ON_TIMER, \ + TIMER0B, /* 3 */ \ + NOT_ON_TIMER, \ + TIMER3A, /* 5 */ \ + TIMER4D, /* 6 */ \ + NOT_ON_TIMER, \ + \ + NOT_ON_TIMER, \ + TIMER1A, /* 9 */ \ + TIMER1B, /* 10 */ \ + TIMER0A, /* 11 */ \ + \ + NOT_ON_TIMER, \ + TIMER4A, /* 13 */ \ + \ + NOT_ON_TIMER, \ + NOT_ON_TIMER, \ + NOT_ON_TIMER, \ + NOT_ON_TIMER, \ + NOT_ON_TIMER, \ + NOT_ON_TIMER, \ + \ + NOT_ON_TIMER, \ + NOT_ON_TIMER, \ + NOT_ON_TIMER, \ + NOT_ON_TIMER, \ + NOT_ON_TIMER, \ + NOT_ON_TIMER, \ + NOT_ON_TIMER, \ + NOT_ON_TIMER, \ + NOT_ON_TIMER, \ + NOT_ON_TIMER, - NOT_ON_TIMER, - NOT_ON_TIMER, - NOT_ON_TIMER, - NOT_ON_TIMER, - NOT_ON_TIMER, - NOT_ON_TIMER, - NOT_ON_TIMER, - NOT_ON_TIMER, - NOT_ON_TIMER, - NOT_ON_TIMER, -}; +#ifdef ARDUINO_MAIN const uint8_t PROGMEM analog_pin_to_channel_PGM[] = { 7, // A0 PF7 ADC7 @@ -333,5 +327,6 @@ const uint8_t PROGMEM analog_pin_to_channel_PGM[] = { 9 // A11 D12 PD6 ADC9 }; -#endif /* ARDUINO_MAIN */ +#endif + #endif /* Pins_Arduino_h */ diff --git a/hardware/arduino/variants/mega/pins_arduino.h b/hardware/arduino/variants/mega/pins_arduino.h index 5a9b4cb09b5..26e4c572ec2 100644 --- a/hardware/arduino/variants/mega/pins_arduino.h +++ b/hardware/arduino/variants/mega/pins_arduino.h @@ -83,281 +83,274 @@ static const uint8_t A15 = 69; ( (((p) >= 62) && ((p) <= 69)) ? ((p) - 62) : \ 0 ) ) ) ) ) ) -#ifdef ARDUINO_MAIN +#define PORT_TO_MODE \ + NOT_A_PORT, \ + (uint16_t) &DDRA, \ + (uint16_t) &DDRB, \ + (uint16_t) &DDRC, \ + (uint16_t) &DDRD, \ + (uint16_t) &DDRE, \ + (uint16_t) &DDRF, \ + (uint16_t) &DDRG, \ + (uint16_t) &DDRH, \ + NOT_A_PORT, \ + (uint16_t) &DDRJ, \ + (uint16_t) &DDRK, \ + (uint16_t) &DDRL, -const uint16_t PROGMEM port_to_mode_PGM[] = { - NOT_A_PORT, - (uint16_t) &DDRA, - (uint16_t) &DDRB, - (uint16_t) &DDRC, - (uint16_t) &DDRD, - (uint16_t) &DDRE, - (uint16_t) &DDRF, - (uint16_t) &DDRG, - (uint16_t) &DDRH, - NOT_A_PORT, - (uint16_t) &DDRJ, - (uint16_t) &DDRK, - (uint16_t) &DDRL, -}; +#define PORT_TO_OUTPUT \ + NOT_A_PORT, \ + (uint16_t) &PORTA, \ + (uint16_t) &PORTB, \ + (uint16_t) &PORTC, \ + (uint16_t) &PORTD, \ + (uint16_t) &PORTE, \ + (uint16_t) &PORTF, \ + (uint16_t) &PORTG, \ + (uint16_t) &PORTH, \ + NOT_A_PORT, \ + (uint16_t) &PORTJ, \ + (uint16_t) &PORTK, \ + (uint16_t) &PORTL, -const uint16_t PROGMEM port_to_output_PGM[] = { - NOT_A_PORT, - (uint16_t) &PORTA, - (uint16_t) &PORTB, - (uint16_t) &PORTC, - (uint16_t) &PORTD, - (uint16_t) &PORTE, - (uint16_t) &PORTF, - (uint16_t) &PORTG, - (uint16_t) &PORTH, - NOT_A_PORT, - (uint16_t) &PORTJ, - (uint16_t) &PORTK, - (uint16_t) &PORTL, -}; +#define PORT_TO_INPUT \ + NOT_A_PIN, \ + (uint16_t) &PINA, \ + (uint16_t) &PINB, \ + (uint16_t) &PINC, \ + (uint16_t) &PIND, \ + (uint16_t) &PINE, \ + (uint16_t) &PINF, \ + (uint16_t) &PING, \ + (uint16_t) &PINH, \ + NOT_A_PIN, \ + (uint16_t) &PINJ, \ + (uint16_t) &PINK, \ + (uint16_t) &PINL, -const uint16_t PROGMEM port_to_input_PGM[] = { - NOT_A_PIN, - (uint16_t) &PINA, - (uint16_t) &PINB, - (uint16_t) &PINC, - (uint16_t) &PIND, - (uint16_t) &PINE, - (uint16_t) &PINF, - (uint16_t) &PING, - (uint16_t) &PINH, - NOT_A_PIN, - (uint16_t) &PINJ, - (uint16_t) &PINK, - (uint16_t) &PINL, -}; -const uint8_t PROGMEM digital_pin_to_port_PGM[] = { - // PORTLIST - // ------------------------------------------- - PE , // PE 0 ** 0 ** USART0_RX - PE , // PE 1 ** 1 ** USART0_TX - PE , // PE 4 ** 2 ** PWM2 - PE , // PE 5 ** 3 ** PWM3 - PG , // PG 5 ** 4 ** PWM4 - PE , // PE 3 ** 5 ** PWM5 - PH , // PH 3 ** 6 ** PWM6 - PH , // PH 4 ** 7 ** PWM7 - PH , // PH 5 ** 8 ** PWM8 - PH , // PH 6 ** 9 ** PWM9 - PB , // PB 4 ** 10 ** PWM10 - PB , // PB 5 ** 11 ** PWM11 - PB , // PB 6 ** 12 ** PWM12 - PB , // PB 7 ** 13 ** PWM13 - PJ , // PJ 1 ** 14 ** USART3_TX - PJ , // PJ 0 ** 15 ** USART3_RX - PH , // PH 1 ** 16 ** USART2_TX - PH , // PH 0 ** 17 ** USART2_RX - PD , // PD 3 ** 18 ** USART1_TX - PD , // PD 2 ** 19 ** USART1_RX - PD , // PD 1 ** 20 ** I2C_SDA - PD , // PD 0 ** 21 ** I2C_SCL - PA , // PA 0 ** 22 ** D22 - PA , // PA 1 ** 23 ** D23 - PA , // PA 2 ** 24 ** D24 - PA , // PA 3 ** 25 ** D25 - PA , // PA 4 ** 26 ** D26 - PA , // PA 5 ** 27 ** D27 - PA , // PA 6 ** 28 ** D28 - PA , // PA 7 ** 29 ** D29 - PC , // PC 7 ** 30 ** D30 - PC , // PC 6 ** 31 ** D31 - PC , // PC 5 ** 32 ** D32 - PC , // PC 4 ** 33 ** D33 - PC , // PC 3 ** 34 ** D34 - PC , // PC 2 ** 35 ** D35 - PC , // PC 1 ** 36 ** D36 - PC , // PC 0 ** 37 ** D37 - PD , // PD 7 ** 38 ** D38 - PG , // PG 2 ** 39 ** D39 - PG , // PG 1 ** 40 ** D40 - PG , // PG 0 ** 41 ** D41 - PL , // PL 7 ** 42 ** D42 - PL , // PL 6 ** 43 ** D43 - PL , // PL 5 ** 44 ** D44 - PL , // PL 4 ** 45 ** D45 - PL , // PL 3 ** 46 ** D46 - PL , // PL 2 ** 47 ** D47 - PL , // PL 1 ** 48 ** D48 - PL , // PL 0 ** 49 ** D49 - PB , // PB 3 ** 50 ** SPI_MISO - PB , // PB 2 ** 51 ** SPI_MOSI - PB , // PB 1 ** 52 ** SPI_SCK - PB , // PB 0 ** 53 ** SPI_SS - PF , // PF 0 ** 54 ** A0 - PF , // PF 1 ** 55 ** A1 - PF , // PF 2 ** 56 ** A2 - PF , // PF 3 ** 57 ** A3 - PF , // PF 4 ** 58 ** A4 - PF , // PF 5 ** 59 ** A5 - PF , // PF 6 ** 60 ** A6 - PF , // PF 7 ** 61 ** A7 - PK , // PK 0 ** 62 ** A8 - PK , // PK 1 ** 63 ** A9 - PK , // PK 2 ** 64 ** A10 - PK , // PK 3 ** 65 ** A11 - PK , // PK 4 ** 66 ** A12 - PK , // PK 5 ** 67 ** A13 - PK , // PK 6 ** 68 ** A14 - PK , // PK 7 ** 69 ** A15 -}; +#define DIGITAL_PIN_TO_PORT \ + /* PORTLIST */ \ + /* ------------------------------------------- */ \ + PE , /* PE 0 ** 0 ** USART0_RX */ \ + PE , /* PE 1 ** 1 ** USART0_TX */ \ + PE , /* PE 4 ** 2 ** PWM2 */ \ + PE , /* PE 5 ** 3 ** PWM3 */ \ + PG , /* PG 5 ** 4 ** PWM4 */ \ + PE , /* PE 3 ** 5 ** PWM5 */ \ + PH , /* PH 3 ** 6 ** PWM6 */ \ + PH , /* PH 4 ** 7 ** PWM7 */ \ + PH , /* PH 5 ** 8 ** PWM8 */ \ + PH , /* PH 6 ** 9 ** PWM9 */ \ + PB , /* PB 4 ** 10 ** PWM10 */ \ + PB , /* PB 5 ** 11 ** PWM11 */ \ + PB , /* PB 6 ** 12 ** PWM12 */ \ + PB , /* PB 7 ** 13 ** PWM13 */ \ + PJ , /* PJ 1 ** 14 ** USART3_TX */ \ + PJ , /* PJ 0 ** 15 ** USART3_RX */ \ + PH , /* PH 1 ** 16 ** USART2_TX */ \ + PH , /* PH 0 ** 17 ** USART2_RX */ \ + PD , /* PD 3 ** 18 ** USART1_TX */ \ + PD , /* PD 2 ** 19 ** USART1_RX */ \ + PD , /* PD 1 ** 20 ** I2C_SDA */ \ + PD , /* PD 0 ** 21 ** I2C_SCL */ \ + PA , /* PA 0 ** 22 ** D22 */ \ + PA , /* PA 1 ** 23 ** D23 */ \ + PA , /* PA 2 ** 24 ** D24 */ \ + PA , /* PA 3 ** 25 ** D25 */ \ + PA , /* PA 4 ** 26 ** D26 */ \ + PA , /* PA 5 ** 27 ** D27 */ \ + PA , /* PA 6 ** 28 ** D28 */ \ + PA , /* PA 7 ** 29 ** D29 */ \ + PC , /* PC 7 ** 30 ** D30 */ \ + PC , /* PC 6 ** 31 ** D31 */ \ + PC , /* PC 5 ** 32 ** D32 */ \ + PC , /* PC 4 ** 33 ** D33 */ \ + PC , /* PC 3 ** 34 ** D34 */ \ + PC , /* PC 2 ** 35 ** D35 */ \ + PC , /* PC 1 ** 36 ** D36 */ \ + PC , /* PC 0 ** 37 ** D37 */ \ + PD , /* PD 7 ** 38 ** D38 */ \ + PG , /* PG 2 ** 39 ** D39 */ \ + PG , /* PG 1 ** 40 ** D40 */ \ + PG , /* PG 0 ** 41 ** D41 */ \ + PL , /* PL 7 ** 42 ** D42 */ \ + PL , /* PL 6 ** 43 ** D43 */ \ + PL , /* PL 5 ** 44 ** D44 */ \ + PL , /* PL 4 ** 45 ** D45 */ \ + PL , /* PL 3 ** 46 ** D46 */ \ + PL , /* PL 2 ** 47 ** D47 */ \ + PL , /* PL 1 ** 48 ** D48 */ \ + PL , /* PL 0 ** 49 ** D49 */ \ + PB , /* PB 3 ** 50 ** SPI_MISO */ \ + PB , /* PB 2 ** 51 ** SPI_MOSI */ \ + PB , /* PB 1 ** 52 ** SPI_SCK */ \ + PB , /* PB 0 ** 53 ** SPI_SS */ \ + PF , /* PF 0 ** 54 ** A0 */ \ + PF , /* PF 1 ** 55 ** A1 */ \ + PF , /* PF 2 ** 56 ** A2 */ \ + PF , /* PF 3 ** 57 ** A3 */ \ + PF , /* PF 4 ** 58 ** A4 */ \ + PF , /* PF 5 ** 59 ** A5 */ \ + PF , /* PF 6 ** 60 ** A6 */ \ + PF , /* PF 7 ** 61 ** A7 */ \ + PK , /* PK 0 ** 62 ** A8 */ \ + PK , /* PK 1 ** 63 ** A9 */ \ + PK , /* PK 2 ** 64 ** A10 */ \ + PK , /* PK 3 ** 65 ** A11 */ \ + PK , /* PK 4 ** 66 ** A12 */ \ + PK , /* PK 5 ** 67 ** A13 */ \ + PK , /* PK 6 ** 68 ** A14 */ \ + PK , /* PK 7 ** 69 ** A15 */ -const uint8_t PROGMEM digital_pin_to_bit_mask_PGM[] = { - // PIN IN PORT - // ------------------------------------------- - _BV( 0 ) , // PE 0 ** 0 ** USART0_RX - _BV( 1 ) , // PE 1 ** 1 ** USART0_TX - _BV( 4 ) , // PE 4 ** 2 ** PWM2 - _BV( 5 ) , // PE 5 ** 3 ** PWM3 - _BV( 5 ) , // PG 5 ** 4 ** PWM4 - _BV( 3 ) , // PE 3 ** 5 ** PWM5 - _BV( 3 ) , // PH 3 ** 6 ** PWM6 - _BV( 4 ) , // PH 4 ** 7 ** PWM7 - _BV( 5 ) , // PH 5 ** 8 ** PWM8 - _BV( 6 ) , // PH 6 ** 9 ** PWM9 - _BV( 4 ) , // PB 4 ** 10 ** PWM10 - _BV( 5 ) , // PB 5 ** 11 ** PWM11 - _BV( 6 ) , // PB 6 ** 12 ** PWM12 - _BV( 7 ) , // PB 7 ** 13 ** PWM13 - _BV( 1 ) , // PJ 1 ** 14 ** USART3_TX - _BV( 0 ) , // PJ 0 ** 15 ** USART3_RX - _BV( 1 ) , // PH 1 ** 16 ** USART2_TX - _BV( 0 ) , // PH 0 ** 17 ** USART2_RX - _BV( 3 ) , // PD 3 ** 18 ** USART1_TX - _BV( 2 ) , // PD 2 ** 19 ** USART1_RX - _BV( 1 ) , // PD 1 ** 20 ** I2C_SDA - _BV( 0 ) , // PD 0 ** 21 ** I2C_SCL - _BV( 0 ) , // PA 0 ** 22 ** D22 - _BV( 1 ) , // PA 1 ** 23 ** D23 - _BV( 2 ) , // PA 2 ** 24 ** D24 - _BV( 3 ) , // PA 3 ** 25 ** D25 - _BV( 4 ) , // PA 4 ** 26 ** D26 - _BV( 5 ) , // PA 5 ** 27 ** D27 - _BV( 6 ) , // PA 6 ** 28 ** D28 - _BV( 7 ) , // PA 7 ** 29 ** D29 - _BV( 7 ) , // PC 7 ** 30 ** D30 - _BV( 6 ) , // PC 6 ** 31 ** D31 - _BV( 5 ) , // PC 5 ** 32 ** D32 - _BV( 4 ) , // PC 4 ** 33 ** D33 - _BV( 3 ) , // PC 3 ** 34 ** D34 - _BV( 2 ) , // PC 2 ** 35 ** D35 - _BV( 1 ) , // PC 1 ** 36 ** D36 - _BV( 0 ) , // PC 0 ** 37 ** D37 - _BV( 7 ) , // PD 7 ** 38 ** D38 - _BV( 2 ) , // PG 2 ** 39 ** D39 - _BV( 1 ) , // PG 1 ** 40 ** D40 - _BV( 0 ) , // PG 0 ** 41 ** D41 - _BV( 7 ) , // PL 7 ** 42 ** D42 - _BV( 6 ) , // PL 6 ** 43 ** D43 - _BV( 5 ) , // PL 5 ** 44 ** D44 - _BV( 4 ) , // PL 4 ** 45 ** D45 - _BV( 3 ) , // PL 3 ** 46 ** D46 - _BV( 2 ) , // PL 2 ** 47 ** D47 - _BV( 1 ) , // PL 1 ** 48 ** D48 - _BV( 0 ) , // PL 0 ** 49 ** D49 - _BV( 3 ) , // PB 3 ** 50 ** SPI_MISO - _BV( 2 ) , // PB 2 ** 51 ** SPI_MOSI - _BV( 1 ) , // PB 1 ** 52 ** SPI_SCK - _BV( 0 ) , // PB 0 ** 53 ** SPI_SS - _BV( 0 ) , // PF 0 ** 54 ** A0 - _BV( 1 ) , // PF 1 ** 55 ** A1 - _BV( 2 ) , // PF 2 ** 56 ** A2 - _BV( 3 ) , // PF 3 ** 57 ** A3 - _BV( 4 ) , // PF 4 ** 58 ** A4 - _BV( 5 ) , // PF 5 ** 59 ** A5 - _BV( 6 ) , // PF 6 ** 60 ** A6 - _BV( 7 ) , // PF 7 ** 61 ** A7 - _BV( 0 ) , // PK 0 ** 62 ** A8 - _BV( 1 ) , // PK 1 ** 63 ** A9 - _BV( 2 ) , // PK 2 ** 64 ** A10 - _BV( 3 ) , // PK 3 ** 65 ** A11 - _BV( 4 ) , // PK 4 ** 66 ** A12 - _BV( 5 ) , // PK 5 ** 67 ** A13 - _BV( 6 ) , // PK 6 ** 68 ** A14 - _BV( 7 ) , // PK 7 ** 69 ** A15 -}; -const uint8_t PROGMEM digital_pin_to_timer_PGM[] = { - // TIMERS - // ------------------------------------------- - NOT_ON_TIMER , // PE 0 ** 0 ** USART0_RX - NOT_ON_TIMER , // PE 1 ** 1 ** USART0_TX - TIMER3B , // PE 4 ** 2 ** PWM2 - TIMER3C , // PE 5 ** 3 ** PWM3 - TIMER0B , // PG 5 ** 4 ** PWM4 - TIMER3A , // PE 3 ** 5 ** PWM5 - TIMER4A , // PH 3 ** 6 ** PWM6 - TIMER4B , // PH 4 ** 7 ** PWM7 - TIMER4C , // PH 5 ** 8 ** PWM8 - TIMER2B , // PH 6 ** 9 ** PWM9 - TIMER2A , // PB 4 ** 10 ** PWM10 - TIMER1A , // PB 5 ** 11 ** PWM11 - TIMER1B , // PB 6 ** 12 ** PWM12 - TIMER0A , // PB 7 ** 13 ** PWM13 - NOT_ON_TIMER , // PJ 1 ** 14 ** USART3_TX - NOT_ON_TIMER , // PJ 0 ** 15 ** USART3_RX - NOT_ON_TIMER , // PH 1 ** 16 ** USART2_TX - NOT_ON_TIMER , // PH 0 ** 17 ** USART2_RX - NOT_ON_TIMER , // PD 3 ** 18 ** USART1_TX - NOT_ON_TIMER , // PD 2 ** 19 ** USART1_RX - NOT_ON_TIMER , // PD 1 ** 20 ** I2C_SDA - NOT_ON_TIMER , // PD 0 ** 21 ** I2C_SCL - NOT_ON_TIMER , // PA 0 ** 22 ** D22 - NOT_ON_TIMER , // PA 1 ** 23 ** D23 - NOT_ON_TIMER , // PA 2 ** 24 ** D24 - NOT_ON_TIMER , // PA 3 ** 25 ** D25 - NOT_ON_TIMER , // PA 4 ** 26 ** D26 - NOT_ON_TIMER , // PA 5 ** 27 ** D27 - NOT_ON_TIMER , // PA 6 ** 28 ** D28 - NOT_ON_TIMER , // PA 7 ** 29 ** D29 - NOT_ON_TIMER , // PC 7 ** 30 ** D30 - NOT_ON_TIMER , // PC 6 ** 31 ** D31 - NOT_ON_TIMER , // PC 5 ** 32 ** D32 - NOT_ON_TIMER , // PC 4 ** 33 ** D33 - NOT_ON_TIMER , // PC 3 ** 34 ** D34 - NOT_ON_TIMER , // PC 2 ** 35 ** D35 - NOT_ON_TIMER , // PC 1 ** 36 ** D36 - NOT_ON_TIMER , // PC 0 ** 37 ** D37 - NOT_ON_TIMER , // PD 7 ** 38 ** D38 - NOT_ON_TIMER , // PG 2 ** 39 ** D39 - NOT_ON_TIMER , // PG 1 ** 40 ** D40 - NOT_ON_TIMER , // PG 0 ** 41 ** D41 - NOT_ON_TIMER , // PL 7 ** 42 ** D42 - NOT_ON_TIMER , // PL 6 ** 43 ** D43 - TIMER5C , // PL 5 ** 44 ** D44 - TIMER5B , // PL 4 ** 45 ** D45 - TIMER5A , // PL 3 ** 46 ** D46 - NOT_ON_TIMER , // PL 2 ** 47 ** D47 - NOT_ON_TIMER , // PL 1 ** 48 ** D48 - NOT_ON_TIMER , // PL 0 ** 49 ** D49 - NOT_ON_TIMER , // PB 3 ** 50 ** SPI_MISO - NOT_ON_TIMER , // PB 2 ** 51 ** SPI_MOSI - NOT_ON_TIMER , // PB 1 ** 52 ** SPI_SCK - NOT_ON_TIMER , // PB 0 ** 53 ** SPI_SS - NOT_ON_TIMER , // PF 0 ** 54 ** A0 - NOT_ON_TIMER , // PF 1 ** 55 ** A1 - NOT_ON_TIMER , // PF 2 ** 56 ** A2 - NOT_ON_TIMER , // PF 3 ** 57 ** A3 - NOT_ON_TIMER , // PF 4 ** 58 ** A4 - NOT_ON_TIMER , // PF 5 ** 59 ** A5 - NOT_ON_TIMER , // PF 6 ** 60 ** A6 - NOT_ON_TIMER , // PF 7 ** 61 ** A7 - NOT_ON_TIMER , // PK 0 ** 62 ** A8 - NOT_ON_TIMER , // PK 1 ** 63 ** A9 - NOT_ON_TIMER , // PK 2 ** 64 ** A10 - NOT_ON_TIMER , // PK 3 ** 65 ** A11 - NOT_ON_TIMER , // PK 4 ** 66 ** A12 - NOT_ON_TIMER , // PK 5 ** 67 ** A13 - NOT_ON_TIMER , // PK 6 ** 68 ** A14 - NOT_ON_TIMER , // PK 7 ** 69 ** A15 -}; +#define DIGITAL_PIN_TO_BIT_MASK \ + /* PIN IN PORT */ \ + /* ------------------------------------------- */ \ + _BV( 0 ) , /* PE 0 ** 0 ** USART0_RX */ \ + _BV( 1 ) , /* PE 1 ** 1 ** USART0_TX */ \ + _BV( 4 ) , /* PE 4 ** 2 ** PWM2 */ \ + _BV( 5 ) , /* PE 5 ** 3 ** PWM3 */ \ + _BV( 5 ) , /* PG 5 ** 4 ** PWM4 */ \ + _BV( 3 ) , /* PE 3 ** 5 ** PWM5 */ \ + _BV( 3 ) , /* PH 3 ** 6 ** PWM6 */ \ + _BV( 4 ) , /* PH 4 ** 7 ** PWM7 */ \ + _BV( 5 ) , /* PH 5 ** 8 ** PWM8 */ \ + _BV( 6 ) , /* PH 6 ** 9 ** PWM9 */ \ + _BV( 4 ) , /* PB 4 ** 10 ** PWM10 */ \ + _BV( 5 ) , /* PB 5 ** 11 ** PWM11 */ \ + _BV( 6 ) , /* PB 6 ** 12 ** PWM12 */ \ + _BV( 7 ) , /* PB 7 ** 13 ** PWM13 */ \ + _BV( 1 ) , /* PJ 1 ** 14 ** USART3_TX */ \ + _BV( 0 ) , /* PJ 0 ** 15 ** USART3_RX */ \ + _BV( 1 ) , /* PH 1 ** 16 ** USART2_TX */ \ + _BV( 0 ) , /* PH 0 ** 17 ** USART2_RX */ \ + _BV( 3 ) , /* PD 3 ** 18 ** USART1_TX */ \ + _BV( 2 ) , /* PD 2 ** 19 ** USART1_RX */ \ + _BV( 1 ) , /* PD 1 ** 20 ** I2C_SDA */ \ + _BV( 0 ) , /* PD 0 ** 21 ** I2C_SCL */ \ + _BV( 0 ) , /* PA 0 ** 22 ** D22 */ \ + _BV( 1 ) , /* PA 1 ** 23 ** D23 */ \ + _BV( 2 ) , /* PA 2 ** 24 ** D24 */ \ + _BV( 3 ) , /* PA 3 ** 25 ** D25 */ \ + _BV( 4 ) , /* PA 4 ** 26 ** D26 */ \ + _BV( 5 ) , /* PA 5 ** 27 ** D27 */ \ + _BV( 6 ) , /* PA 6 ** 28 ** D28 */ \ + _BV( 7 ) , /* PA 7 ** 29 ** D29 */ \ + _BV( 7 ) , /* PC 7 ** 30 ** D30 */ \ + _BV( 6 ) , /* PC 6 ** 31 ** D31 */ \ + _BV( 5 ) , /* PC 5 ** 32 ** D32 */ \ + _BV( 4 ) , /* PC 4 ** 33 ** D33 */ \ + _BV( 3 ) , /* PC 3 ** 34 ** D34 */ \ + _BV( 2 ) , /* PC 2 ** 35 ** D35 */ \ + _BV( 1 ) , /* PC 1 ** 36 ** D36 */ \ + _BV( 0 ) , /* PC 0 ** 37 ** D37 */ \ + _BV( 7 ) , /* PD 7 ** 38 ** D38 */ \ + _BV( 2 ) , /* PG 2 ** 39 ** D39 */ \ + _BV( 1 ) , /* PG 1 ** 40 ** D40 */ \ + _BV( 0 ) , /* PG 0 ** 41 ** D41 */ \ + _BV( 7 ) , /* PL 7 ** 42 ** D42 */ \ + _BV( 6 ) , /* PL 6 ** 43 ** D43 */ \ + _BV( 5 ) , /* PL 5 ** 44 ** D44 */ \ + _BV( 4 ) , /* PL 4 ** 45 ** D45 */ \ + _BV( 3 ) , /* PL 3 ** 46 ** D46 */ \ + _BV( 2 ) , /* PL 2 ** 47 ** D47 */ \ + _BV( 1 ) , /* PL 1 ** 48 ** D48 */ \ + _BV( 0 ) , /* PL 0 ** 49 ** D49 */ \ + _BV( 3 ) , /* PB 3 ** 50 ** SPI_MISO */ \ + _BV( 2 ) , /* PB 2 ** 51 ** SPI_MOSI */ \ + _BV( 1 ) , /* PB 1 ** 52 ** SPI_SCK */ \ + _BV( 0 ) , /* PB 0 ** 53 ** SPI_SS */ \ + _BV( 0 ) , /* PF 0 ** 54 ** A0 */ \ + _BV( 1 ) , /* PF 1 ** 55 ** A1 */ \ + _BV( 2 ) , /* PF 2 ** 56 ** A2 */ \ + _BV( 3 ) , /* PF 3 ** 57 ** A3 */ \ + _BV( 4 ) , /* PF 4 ** 58 ** A4 */ \ + _BV( 5 ) , /* PF 5 ** 59 ** A5 */ \ + _BV( 6 ) , /* PF 6 ** 60 ** A6 */ \ + _BV( 7 ) , /* PF 7 ** 61 ** A7 */ \ + _BV( 0 ) , /* PK 0 ** 62 ** A8 */ \ + _BV( 1 ) , /* PK 1 ** 63 ** A9 */ \ + _BV( 2 ) , /* PK 2 ** 64 ** A10 */ \ + _BV( 3 ) , /* PK 3 ** 65 ** A11 */ \ + _BV( 4 ) , /* PK 4 ** 66 ** A12 */ \ + _BV( 5 ) , /* PK 5 ** 67 ** A13 */ \ + _BV( 6 ) , /* PK 6 ** 68 ** A14 */ \ + _BV( 7 ) , /* PK 7 ** 69 ** A15 */ -#endif -#endif \ No newline at end of file +#define DIGITAL_PIN_TO_TIMER \ +/* TIMERS */ \ + /* ------------------------------------------- */ \ + NOT_ON_TIMER , /* PE 0 ** 0 ** USART0_RX */ \ + NOT_ON_TIMER , /* PE 1 ** 1 ** USART0_TX */ \ + TIMER3B , /* PE 4 ** 2 ** PWM2 */ \ + TIMER3C , /* PE 5 ** 3 ** PWM3 */ \ + TIMER0B , /* PG 5 ** 4 ** PWM4 */ \ + TIMER3A , /* PE 3 ** 5 ** PWM5 */ \ + TIMER4A , /* PH 3 ** 6 ** PWM6 */ \ + TIMER4B , /* PH 4 ** 7 ** PWM7 */ \ + TIMER4C , /* PH 5 ** 8 ** PWM8 */ \ + TIMER2B , /* PH 6 ** 9 ** PWM9 */ \ + TIMER2A , /* PB 4 ** 10 ** PWM10 */ \ + TIMER1A , /* PB 5 ** 11 ** PWM11 */ \ + TIMER1B , /* PB 6 ** 12 ** PWM12 */ \ + TIMER0A , /* PB 7 ** 13 ** PWM13 */ \ + NOT_ON_TIMER , /* PJ 1 ** 14 ** USART3_TX */ \ + NOT_ON_TIMER , /* PJ 0 ** 15 ** USART3_RX */ \ + NOT_ON_TIMER , /* PH 1 ** 16 ** USART2_TX */ \ + NOT_ON_TIMER , /* PH 0 ** 17 ** USART2_RX */ \ + NOT_ON_TIMER , /* PD 3 ** 18 ** USART1_TX */ \ + NOT_ON_TIMER , /* PD 2 ** 19 ** USART1_RX */ \ + NOT_ON_TIMER , /* PD 1 ** 20 ** I2C_SDA */ \ + NOT_ON_TIMER , /* PD 0 ** 21 ** I2C_SCL */ \ + NOT_ON_TIMER , /* PA 0 ** 22 ** D22 */ \ + NOT_ON_TIMER , /* PA 1 ** 23 ** D23 */ \ + NOT_ON_TIMER , /* PA 2 ** 24 ** D24 */ \ + NOT_ON_TIMER , /* PA 3 ** 25 ** D25 */ \ + NOT_ON_TIMER , /* PA 4 ** 26 ** D26 */ \ + NOT_ON_TIMER , /* PA 5 ** 27 ** D27 */ \ + NOT_ON_TIMER , /* PA 6 ** 28 ** D28 */ \ + NOT_ON_TIMER , /* PA 7 ** 29 ** D29 */ \ + NOT_ON_TIMER , /* PC 7 ** 30 ** D30 */ \ + NOT_ON_TIMER , /* PC 6 ** 31 ** D31 */ \ + NOT_ON_TIMER , /* PC 5 ** 32 ** D32 */ \ + NOT_ON_TIMER , /* PC 4 ** 33 ** D33 */ \ + NOT_ON_TIMER , /* PC 3 ** 34 ** D34 */ \ + NOT_ON_TIMER , /* PC 2 ** 35 ** D35 */ \ + NOT_ON_TIMER , /* PC 1 ** 36 ** D36 */ \ + NOT_ON_TIMER , /* PC 0 ** 37 ** D37 */ \ + NOT_ON_TIMER , /* PD 7 ** 38 ** D38 */ \ + NOT_ON_TIMER , /* PG 2 ** 39 ** D39 */ \ + NOT_ON_TIMER , /* PG 1 ** 40 ** D40 */ \ + NOT_ON_TIMER , /* PG 0 ** 41 ** D41 */ \ + NOT_ON_TIMER , /* PL 7 ** 42 ** D42 */ \ + NOT_ON_TIMER , /* PL 6 ** 43 ** D43 */ \ + TIMER5C , /* PL 5 ** 44 ** D44 */ \ + TIMER5B , /* PL 4 ** 45 ** D45 */ \ + TIMER5A , /* PL 3 ** 46 ** D46 */ \ + NOT_ON_TIMER , /* PL 2 ** 47 ** D47 */ \ + NOT_ON_TIMER , /* PL 1 ** 48 ** D48 */ \ + NOT_ON_TIMER , /* PL 0 ** 49 ** D49 */ \ + NOT_ON_TIMER , /* PB 3 ** 50 ** SPI_MISO */ \ + NOT_ON_TIMER , /* PB 2 ** 51 ** SPI_MOSI */ \ + NOT_ON_TIMER , /* PB 1 ** 52 ** SPI_SCK */ \ + NOT_ON_TIMER , /* PB 0 ** 53 ** SPI_SS */ \ + NOT_ON_TIMER , /* PF 0 ** 54 ** A0 */ \ + NOT_ON_TIMER , /* PF 1 ** 55 ** A1 */ \ + NOT_ON_TIMER , /* PF 2 ** 56 ** A2 */ \ + NOT_ON_TIMER , /* PF 3 ** 57 ** A3 */ \ + NOT_ON_TIMER , /* PF 4 ** 58 ** A4 */ \ + NOT_ON_TIMER , /* PF 5 ** 59 ** A5 */ \ + NOT_ON_TIMER , /* PF 6 ** 60 ** A6 */ \ + NOT_ON_TIMER , /* PF 7 ** 61 ** A7 */ \ + NOT_ON_TIMER , /* PK 0 ** 62 ** A8 */ \ + NOT_ON_TIMER , /* PK 1 ** 63 ** A9 */ \ + NOT_ON_TIMER , /* PK 2 ** 64 ** A10 */ \ + NOT_ON_TIMER , /* PK 3 ** 65 ** A11 */ \ + NOT_ON_TIMER , /* PK 4 ** 66 ** A12 */ \ + NOT_ON_TIMER , /* PK 5 ** 67 ** A13 */ \ + NOT_ON_TIMER , /* PK 6 ** 68 ** A14 */ \ + NOT_ON_TIMER , /* PK 7 ** 69 ** A15 */ + +#endif diff --git a/hardware/arduino/variants/standard/pins_arduino.h b/hardware/arduino/variants/standard/pins_arduino.h index 30b42663065..9016e2e8c42 100644 --- a/hardware/arduino/variants/standard/pins_arduino.h +++ b/hardware/arduino/variants/standard/pins_arduino.h @@ -60,8 +60,6 @@ static const uint8_t A7 = 21; #define digitalPinToPCMSK(p) (((p) <= 7) ? (&PCMSK2) : (((p) <= 13) ? (&PCMSK0) : (((p) <= 21) ? (&PCMSK1) : ((uint8_t *)0)))) #define digitalPinToPCMSKbit(p) (((p) <= 7) ? (p) : (((p) <= 13) ? ((p) - 8) : ((p) - 14))) -#ifdef ARDUINO_MAIN - // On the Arduino board, digital pins are also used // for the analog output (software PWM). Analog input // pins are a separate set. @@ -102,117 +100,103 @@ static const uint8_t A7 = 21; // A8-A15 PK0-PK7 -// these arrays map port names (e.g. port B) to the +// these macros map port names (e.g. port B) to the // appropriate addresses for various functions (e.g. reading // and writing) -const uint16_t PROGMEM port_to_mode_PGM[] = { - NOT_A_PORT, - NOT_A_PORT, - (uint16_t) &DDRB, - (uint16_t) &DDRC, - (uint16_t) &DDRD, -}; - -const uint16_t PROGMEM port_to_output_PGM[] = { - NOT_A_PORT, - NOT_A_PORT, - (uint16_t) &PORTB, - (uint16_t) &PORTC, - (uint16_t) &PORTD, -}; - -const uint16_t PROGMEM port_to_input_PGM[] = { - NOT_A_PORT, - NOT_A_PORT, - (uint16_t) &PINB, - (uint16_t) &PINC, - (uint16_t) &PIND, -}; - -const uint8_t PROGMEM digital_pin_to_port_PGM[] = { - PD, /* 0 */ - PD, - PD, - PD, - PD, - PD, - PD, - PD, - PB, /* 8 */ - PB, - PB, - PB, - PB, - PB, - PC, /* 14 */ - PC, - PC, - PC, - PC, - PC, -}; - -const uint8_t PROGMEM digital_pin_to_bit_mask_PGM[] = { - _BV(0), /* 0, port D */ - _BV(1), - _BV(2), - _BV(3), - _BV(4), - _BV(5), - _BV(6), - _BV(7), - _BV(0), /* 8, port B */ - _BV(1), - _BV(2), - _BV(3), - _BV(4), - _BV(5), - _BV(0), /* 14, port C */ - _BV(1), - _BV(2), - _BV(3), - _BV(4), - _BV(5), -}; - -const uint8_t PROGMEM digital_pin_to_timer_PGM[] = { - NOT_ON_TIMER, /* 0 - port D */ - NOT_ON_TIMER, - NOT_ON_TIMER, - // on the ATmega168, digital pin 3 has hardware pwm -#if defined(__AVR_ATmega8__) - NOT_ON_TIMER, -#else - TIMER2B, -#endif - NOT_ON_TIMER, - // on the ATmega168, digital pins 5 and 6 have hardware pwm -#if defined(__AVR_ATmega8__) - NOT_ON_TIMER, - NOT_ON_TIMER, -#else - TIMER0B, - TIMER0A, -#endif - NOT_ON_TIMER, - NOT_ON_TIMER, /* 8 - port B */ - TIMER1A, - TIMER1B, +#define PORT_TO_MODE \ + NOT_A_PORT, \ + NOT_A_PORT, \ + (uint16_t)&DDRB, \ + (uint16_t)&DDRC, \ + (uint16_t)&DDRD, + +#define PORT_TO_OUTPUT \ + NOT_A_PORT, \ + NOT_A_PORT, \ + (uint16_t)&PORTB, \ + (uint16_t)&PORTC, \ + (uint16_t)&PORTD, + + +#define PORT_TO_INPUT \ + NOT_A_PORT, \ + NOT_A_PORT, \ + (uint16_t)&PINB, \ + (uint16_t)&PINC, \ + (uint16_t)&PIND, + + +#define DIGITAL_PIN_TO_PORT \ + PD, /* 0 */ \ + PD, \ + PD, \ + PD, \ + PD, \ + PD, \ + PD, \ + PD, \ + PB, /* 8 */ \ + PB, \ + PB, \ + PB, \ + PB, \ + PB, \ + PC, /* 14 */ \ + PC, \ + PC, \ + PC, \ + PC, \ + PC, + + +#define DIGITAL_PIN_TO_BIT_MASK \ + _BV(0), /* 0, port D */ \ + _BV(1), \ + _BV(2), \ + _BV(3), \ + _BV(4), \ + _BV(5), \ + _BV(6), \ + _BV(7), \ + _BV(0), /* 8, port B */ \ + _BV(1), \ + _BV(2), \ + _BV(3), \ + _BV(4), \ + _BV(5), \ + _BV(0), /* 14, port C */ \ + _BV(1), \ + _BV(2), \ + _BV(3), \ + _BV(4), \ + _BV(5), + #if defined(__AVR_ATmega8__) - TIMER2, -#else - TIMER2A, +#define TIMER2B NOT_ON_TIMER +#define TIMER0A NOT_ON_TIMER +#define TIMER0B NOT_ON_TIMER +#define TIMER2A TIMER2 #endif - NOT_ON_TIMER, - NOT_ON_TIMER, - NOT_ON_TIMER, - NOT_ON_TIMER, /* 14 - port C */ - NOT_ON_TIMER, - NOT_ON_TIMER, - NOT_ON_TIMER, - NOT_ON_TIMER, -}; -#endif +#define DIGITAL_PIN_TO_TIMER \ + NOT_ON_TIMER, /* 0 - port D */ \ + NOT_ON_TIMER, \ + NOT_ON_TIMER, \ + TIMER2B, \ + TIMER0B, \ + TIMER0A, \ + NOT_ON_TIMER, \ + NOT_ON_TIMER, /* 8 - port B */ \ + TIMER1A, \ + TIMER1B, \ + TIMER2A, \ + NOT_ON_TIMER, \ + NOT_ON_TIMER, \ + NOT_ON_TIMER, \ + NOT_ON_TIMER, /* 14 - port C */ \ + NOT_ON_TIMER, \ + NOT_ON_TIMER, \ + NOT_ON_TIMER, \ + NOT_ON_TIMER, #endif