diff --git a/cores/arduino/pins_arduino.c b/cores/arduino/pins_arduino.c index 70c8d0556c..eeebdd8e15 100644 --- a/cores/arduino/pins_arduino.c +++ b/cores/arduino/pins_arduino.c @@ -26,10 +26,12 @@ void __libc_init_array(void); WEAK uint32_t pinNametoDigitalPin(PinName p) { - uint32_t i = 0; - for(i = 0; i < NUM_DIGITAL_PINS; i++) { - if (digitalPin[i] == p) - break; + uint32_t i = NC; + if(STM_VALID_PINNAME(p)) { + for(i = 0; i < NUM_DIGITAL_PINS; i++) { + if (digitalPin[i] == p) + break; + } } return i; } diff --git a/cores/arduino/pins_arduino.h b/cores/arduino/pins_arduino.h index d43b24394a..203b38febd 100644 --- a/cores/arduino/pins_arduino.h +++ b/cores/arduino/pins_arduino.h @@ -32,38 +32,51 @@ extern "C" { # include /** RedHat Newlib minimal stub */ #endif -#define NOT_AN_INTERRUPT NC // -1 +#define NOT_AN_INTERRUPT NC // -1 -#define NUM_DIGITAL_PINS DEND -#define NUM_ANALOG_INPUTS (AEND-A0) +#define NUM_DIGITAL_PINS DEND +#define NUM_ANALOG_INPUTS (AEND-A0) // Convert a digital pin number Dxx to a PinName Pxy // Note: Analog pin is also a digital pin. -#define digitalPinToPinName(p) ((p < NUM_DIGITAL_PINS) ? digitalPin[p] : (STM_VALID_PINNAME(p))? (PinName)p : NC) +#define digitalPinToPinName(p) ((p < NUM_DIGITAL_PINS) ? digitalPin[p] : NC) // Convert a PinName Pxy to a digital pin number uint32_t pinNametoDigitalPin(PinName p); // Convert an analog pin number to a digital pin number // Used by analogRead api to have A0 == 0 -#define analogInputToDigitalPin(p) ((p < NUM_ANALOG_INPUTS) ? (p+A0) : p) +#define analogInputToDigitalPin(p) ((p < NUM_ANALOG_INPUTS) ? (p+A0) : p) // Convert an analog pin number Axx to a PinName Pxy -#define analogInputToPinName(p) (digitalPinToPinName(analogInputToDigitalPin(p))) +#define analogInputToPinName(p) (digitalPinToPinName(analogInputToDigitalPin(p))) // All pins could manage EXTI -#define digitalPinToInterrupt(p) ((p>=D0) && (p < NUM_DIGITAL_PINS) ? p : NOT_AN_INTERRUPT) +#define digitalPinToInterrupt(p) ((digitalPinIsValid(p) ? p : NOT_AN_INTERRUPT) -#define digitalPinHasI2C(p) (pin_in_pinmap(digitalPinToPinName(p), PinMap_I2C_SDA) ||\ - pin_in_pinmap(digitalPinToPinName(p), PinMap_I2C_SCL)) -#define digitalPinHasPWM(p) (pin_in_pinmap(digitalPinToPinName(p), PinMap_PWM)) -#define digitalPinHasSerial(p) (pin_in_pinmap(digitalPinToPinName(p), PinMap_UART_RX) ||\ - pin_in_pinmap(digitalPinToPinName(p), PinMap_UART_TX)) -#define digitalPinHasSPI(p) (pin_in_pinmap(digitalPinToPinName(p), PinMap_SPI_MOSI) ||\ - pin_in_pinmap(digitalPinToPinName(p), PinMap_SPI_MISO) ||\ - pin_in_pinmap(digitalPinToPinName(p), PinMap_SPI_SCLK) ||\ - pin_in_pinmap(digitalPinToPinName(p), PinMap_SPI_SSEL)) +#define digitalPinHasI2C(p) (pin_in_pinmap(digitalPinToPinName(p), PinMap_I2C_SDA) ||\ + pin_in_pinmap(digitalPinToPinName(p), PinMap_I2C_SCL)) +#define digitalPinHasPWM(p) (pin_in_pinmap(digitalPinToPinName(p), PinMap_PWM)) +#define digitalPinHasSerial(p) (pin_in_pinmap(digitalPinToPinName(p), PinMap_UART_RX) ||\ + pin_in_pinmap(digitalPinToPinName(p), PinMap_UART_TX)) +#define digitalPinHasSPI(p) (pin_in_pinmap(digitalPinToPinName(p), PinMap_SPI_MOSI) ||\ + pin_in_pinmap(digitalPinToPinName(p), PinMap_SPI_MISO) ||\ + pin_in_pinmap(digitalPinToPinName(p), PinMap_SPI_SCLK) ||\ + pin_in_pinmap(digitalPinToPinName(p), PinMap_SPI_SSEL)) -#define digitalPinToPort(p) ( get_GPIO_Port(digitalPinToPinName(p)) ) -#define digitalPinToBitMask(p) ( STM_GPIO_PIN(digitalPinToPinName(p)) ) +#define digitalPinToPort(p) (get_GPIO_Port(digitalPinToPinName(p))) +#define digitalPinToBitMask(p) (STM_GPIO_PIN(digitalPinToPinName(p))) + +#define digitalPinIsValid(p) (digitalPinToPinName(p) != NC) + +// As some pin could be duplicated in digitalPin[] +// return first occurence of linked PinName (PYx) +#define digitalPinFirstOccurence(p) (pinNametoDigitalPin(digitalPinToPinName(p))) + +// Specific for Firmata. As some pins could be duplicated, +// ensure 'p' is not one of the serial pins +#if defined(PIN_SERIAL_RX) && defined(PIN_SERIAL_TX) +#define pinIsSerial(p) ((digitalPinFirstOccurence(p) == PIN_SERIAL_RX) ||\ + (digitalPinFirstOccurence(p) == PIN_SERIAL_TX)) +#endif #ifdef __cplusplus } diff --git a/libraries/Firmata/Boards.h b/libraries/Firmata/Boards.h index 82e6c725cf..5f1278035c 100644 --- a/libraries/Firmata/Boards.h +++ b/libraries/Firmata/Boards.h @@ -771,14 +771,14 @@ writePort(port, value, bitmask): Write an 8 bit port. #define TOTAL_PORTS MAX_NB_PORT #define VERSION_BLINK_PIN LED_BUILTIN // PIN_SERIALY_RX/TX defined in the variant.h -#define IS_PIN_DIGITAL(p) ((p != PIN_SERIAL_RX) && (p != PIN_SERIAL_TX) && (p < TOTAL_PINS)) -#define IS_PIN_ANALOG(p) ((p) >= A0 && (p) < AEND) -#define IS_PIN_PWM(p) digitalPinHasPWM(p) +#define IS_PIN_DIGITAL(p) (digitalPinIsValid(p) && !pinIsSerial(p)) +#define IS_PIN_ANALOG(p) ((p >= A0) && (p < AEND) && !pinIsSerial(p)) +#define IS_PIN_PWM(p) (IS_PIN_DIGITAL(p) && digitalPinHasPWM(p)) #define IS_PIN_SERVO(p) IS_PIN_DIGITAL(p) -#define IS_PIN_I2C(p) digitalPinHasI2C(p) -#define IS_PIN_SPI(p) digitalPinHasSPI(p) -#define IS_PIN_INTERRUPT(p) (digitalPinToInterrupt(p) > NOT_AN_INTERRUPT) -#define IS_PIN_SERIAL(p) digitalPinHasSerial(p) +#define IS_PIN_I2C(p) (IS_PIN_DIGITAL(p) && digitalPinHasI2C(p)) +#define IS_PIN_SPI(p) (IS_PIN_DIGITAL(p) && digitalPinHasSPI(p)) +#define IS_PIN_INTERRUPT(p) (IS_PIN_DIGITAL(p) && (digitalPinToInterrupt(p) > NOT_AN_INTERRUPT))) +#define IS_PIN_SERIAL(p) (digitalPinHasSerial(p)) #define PIN_TO_DIGITAL(p) (p) #define PIN_TO_ANALOG(p) (p-A0) #define PIN_TO_PWM(p) (p)