From 613c80e6145233300bdd5c7bdc4374275a18a402 Mon Sep 17 00:00:00 2001 From: Martino Facchin Date: Wed, 20 Nov 2019 15:19:33 +0100 Subject: [PATCH] Restructure core bindings Trying to adapt the C scoped core functions to the dual usage (standalone and as mbed library) ended up with suboptimal results; this commit tries to make everything more clear, without any side effect. Fixes https://github.com/arduino/ArduinoCore-nRF528x-mbedos/issues/30 --- cores/arduino/Arduino.h | 3 ++ cores/arduino/Interrupts.cpp | 39 ++++---------- cores/arduino/macros.h | 35 +++++++------ cores/arduino/pinToIndex.cpp | 10 ++++ cores/arduino/wiring_analog.cpp | 44 ++++------------ cores/arduino/wiring_digital.cpp | 70 ++++++++++++++++++-------- variants/ARDUINO_NANO33BLE/variant.cpp | 68 ++++++++++++------------- 7 files changed, 133 insertions(+), 136 deletions(-) create mode 100644 cores/arduino/pinToIndex.cpp diff --git a/cores/arduino/Arduino.h b/cores/arduino/Arduino.h index d18ab8d4..b7727f98 100644 --- a/cores/arduino/Arduino.h +++ b/cores/arduino/Arduino.h @@ -86,8 +86,11 @@ typedef struct _PinDescription PinName name; mbed::InterruptIn* irq; mbed::PwmOut* pwm; + gpio_t* gpio; } PinDescription ; +int PinNameToIndex(PinName P); + /* Pins table to be instantiated into variant.cpp */ extern PinDescription g_APinDescription[]; diff --git a/cores/arduino/Interrupts.cpp b/cores/arduino/Interrupts.cpp index da7c41a4..7a65563d 100644 --- a/cores/arduino/Interrupts.cpp +++ b/cores/arduino/Interrupts.cpp @@ -19,44 +19,19 @@ #include "Arduino.h" #ifdef digitalPinToInterruptObj -static mbed::InterruptIn* PinNameToInterruptObj(PinName P) { - // reverse search for pinName in g_APinDescription[P].name fields - for (pin_size_t i=0; i < PINS_COUNT; i++) { - if (g_APinDescription[i].name == P) { - return g_APinDescription[i].irq; - } - } - return NULL; -} -#endif void detachInterrupt(PinName interruptNum) { -#ifdef digitalPinToInterruptObj - if (PinNameToInterruptObj(interruptNum) != NULL) { - delete PinNameToInterruptObj(interruptNum); - } -#endif + detachInterrupt(PinNameToIndex(interruptNum)); } void detachInterrupt(pin_size_t interruptNum) { -#ifdef digitalPinToInterruptObj if (digitalPinToInterruptObj(interruptNum) != NULL) { delete digitalPinToInterruptObj(interruptNum); } -#endif } void attachInterruptParam(PinName interruptNum, voidFuncPtrParam func, PinStatus mode, void* param) { - detachInterrupt(interruptNum); - mbed::InterruptIn* irq = new mbed::InterruptIn(interruptNum); - if (mode == FALLING) { - irq->fall(mbed::callback(func, param)); - } else { - irq->rise(mbed::callback(func, param)); - } -#ifdef digitalPinToInterruptObj - digitalPinToInterruptObj(interruptNum) = irq; -#endif + attachInterruptParam(PinNameToIndex(interruptNum), func, mode, param); } void attachInterrupt(PinName interruptNum, voidFuncPtr func, PinStatus mode) { @@ -71,11 +46,15 @@ void attachInterruptParam(pin_size_t interruptNum, voidFuncPtrParam func, PinSta } else { irq->rise(mbed::callback(func, param)); } -#ifdef digitalPinToInterruptObj digitalPinToInterruptObj(interruptNum) = irq; -#endif } void attachInterrupt(pin_size_t interruptNum, voidFuncPtr func, PinStatus mode) { attachInterruptParam(interruptNum, (voidFuncPtrParam)func, mode, NULL); -} \ No newline at end of file +} + +#else + +#warning "Arduino style interrupts can only be used with boards defining an Arduino pinmap" + +#endif \ No newline at end of file diff --git a/cores/arduino/macros.h b/cores/arduino/macros.h index 27d0a6ca..6fdd5415 100644 --- a/cores/arduino/macros.h +++ b/cores/arduino/macros.h @@ -23,25 +23,28 @@ #pragma once #ifdef USE_ARDUINO_PINOUT -#define analogPinToPinName(P) (P < A0 ? g_APinDescription[P+A0].name : g_APinDescription[P].name) -#define digitalPinToPinName(P) (g_APinDescription[P].name) -#define digitalPinToInterrupt(P) (P) -#define digitalPinToInterruptObj(P) (g_APinDescription[P].irq) -#define digitalPinToPwmObj(P) (g_APinDescription[P].pwm) +#define analogPinToPinName(P) (P < A0 ? g_APinDescription[P+A0].name : g_APinDescription[P].name) +#define digitalPinToPinName(P) (g_APinDescription[P].name) +#define digitalPinToInterruptObj(P) (g_APinDescription[P].irq) +#define digitalPinToPwm(P) (g_APinDescription[P].pwm) +#define digitalPinToGpio(P) (g_APinDescription[P].gpio) + +// this is needed for backwards compatibility +#define digitalPinToInterrupt(P) (P) #else -#define analogPinToPinName(P) ((PinName)P) -#define digitalPinToPinName(P) ((PinName)P) -#define digitalPinToInterrupt(P) ((PinName)P) +#define analogPinToPinName(P) ((PinName)P) +#define digitalPinToPinName(P) ((PinName)P) +#define digitalPinToInterrupt(P) ((PinName)P) #endif -#define REDIRECT_STDOUT_TO(stream) namespace mbed { \ - FileHandle *mbed_override_console(int fd) { \ - return &stream; \ - } \ - FileHandle *mbed_target_override_console(int fd) { \ - return &stream; \ - } \ - } +#define REDIRECT_STDOUT_TO(stream) namespace mbed { \ + FileHandle *mbed_override_console(int fd) { \ + return &stream; \ + } \ + FileHandle *mbed_target_override_console(int fd) { \ + return &stream; \ + } \ + } diff --git a/cores/arduino/pinToIndex.cpp b/cores/arduino/pinToIndex.cpp new file mode 100644 index 00000000..82d896de --- /dev/null +++ b/cores/arduino/pinToIndex.cpp @@ -0,0 +1,10 @@ +#include "Arduino.h" + +inline int PinNameToIndex(PinName P) { + for (pin_size_t i=0; i < PINS_COUNT; i++) { + if (g_APinDescription[i].name == P) { + return i; + } + } + return NOT_A_PIN; +} \ No newline at end of file diff --git a/cores/arduino/wiring_analog.cpp b/cores/arduino/wiring_analog.cpp index 5c694cb7..8e53df07 100644 --- a/cores/arduino/wiring_analog.cpp +++ b/cores/arduino/wiring_analog.cpp @@ -26,47 +26,23 @@ static int write_resolution = 8; static int read_resolution = 10; -#ifdef digitalPinToPwmObj -static mbed::PwmOut* PinNameToPwmObj(PinName P) { - // reverse search for pinName in g_APinDescription[P].name fields - for (pin_size_t i=0; i < PINS_COUNT; i++) { - if (g_APinDescription[i].name == P) { - return g_APinDescription[i].pwm; - } - } - return NULL; -} -#endif +#ifdef digitalPinToPwm void analogWrite(PinName pin, int val) { - float percent = (float)val/(float)(1 << write_resolution); -#ifdef digitalPinToPwmObj - mbed::PwmOut* pwm = PinNameToPwmObj(pin); - if (pwm == NULL) { - pwm = new mbed::PwmOut(pin); - digitalPinToPwmObj(pin) = pwm; - pwm->period_ms(2); //500Hz - } -#else - // attention: this leaks badly - mbed::PwmOut* pwm = new mbed::PwmOut(digitalPinToPinName(pin)); -#endif - pwm->write(percent); + analogWrite(PinNameToIndex(pin), val); } void analogWrite(pin_size_t pin, int val) { float percent = (float)val/(float)(1 << write_resolution); -#ifdef digitalPinToPwmObj - mbed::PwmOut* pwm = digitalPinToPwmObj(pin); + mbed::PwmOut* pwm = digitalPinToPwm(pin); if (pwm == NULL) { pwm = new mbed::PwmOut(digitalPinToPinName(pin)); - digitalPinToPwmObj(pin) = pwm; + digitalPinToPwm(pin) = pwm; pwm->period_ms(2); //500Hz } pwm->write(percent); -#endif } void analogWriteResolution(int bits) @@ -74,21 +50,21 @@ void analogWriteResolution(int bits) write_resolution = bits; } +#else + +#warning "Arduino style analogWrite can only be used with boards defining an Arduino pinmap" + +#endif //digitalPinToPwm + int analogRead(PinName pin) { int multiply_factor = 1; -#ifdef ANALOG_BUG_MBED - multiply_factor = 4; -#endif return (mbed::AnalogIn(pin).read_u16() >> (16 - read_resolution)) * multiply_factor; } int analogRead(pin_size_t pin) { int multiply_factor = 1; -#ifdef ANALOG_BUG_MBED - multiply_factor = 4; -#endif return (mbed::AnalogIn(analogPinToPinName(pin)).read_u16() >> (16 - read_resolution)) * multiply_factor; } diff --git a/cores/arduino/wiring_digital.cpp b/cores/arduino/wiring_digital.cpp index c73b12fe..feddd092 100644 --- a/cores/arduino/wiring_digital.cpp +++ b/cores/arduino/wiring_digital.cpp @@ -23,58 +23,84 @@ #include "Arduino.h" #include "pins_arduino.h" +#ifdef digitalPinToGpio + void pinMode(PinName pin, PinMode mode) { - switch (mode) { - case INPUT: - mbed::DigitalIn(pin, PullNone); - break; - case OUTPUT: - mbed::DigitalOut(pin, 0); - break; - case INPUT_PULLUP: - mbed::DigitalIn(pin, PullUp); - break; - case INPUT_PULLDOWN: - mbed::DigitalIn(pin, PullDown); - break; - } + pinMode(PinNameToIndex(pin), mode); } void pinMode(pin_size_t pin, PinMode mode) { + gpio_t* gpio = digitalPinToGpio(pin); + if (gpio == NULL) { + gpio = new gpio_t(); + digitalPinToGpio(pin) = gpio; + } + switch (mode) { case INPUT: - mbed::DigitalIn(digitalPinToPinName(pin), PullNone); + gpio_init_in_ex(gpio, digitalPinToPinName(pin), PullNone); break; case OUTPUT: - mbed::DigitalOut(digitalPinToPinName(pin)); + gpio_init_out(gpio, digitalPinToPinName(pin)); break; case INPUT_PULLUP: - mbed::DigitalIn(digitalPinToPinName(pin), PullUp); + gpio_init_in_ex(gpio, digitalPinToPinName(pin), PullUp); break; case INPUT_PULLDOWN: - mbed::DigitalIn(digitalPinToPinName(pin), PullDown); + gpio_init_in_ex(gpio, digitalPinToPinName(pin), PullDown); break; } } void digitalWrite(PinName pin, PinStatus val) { - mbed::DigitalOut(pin).write((int)val); + digitalWrite(PinNameToIndex(pin), val); } void digitalWrite(pin_size_t pin, PinStatus val) { - mbed::DigitalOut(digitalPinToPinName(pin)).write((int)val); + gpio_write(digitalPinToGpio(pin), (int)val); +} + +PinStatus digitalRead(PinName pin) +{ + return (PinStatus)digitalRead(PinNameToIndex(pin)); +} + +PinStatus digitalRead(pin_size_t pin) +{ + return (PinStatus)gpio_read(digitalPinToGpio(pin)); +} + +#else + +void pinMode(PinName pin, PinMode mode) { +} + +void pinMode(pin_size_t pin, PinMode mode) { + return pinMode((PinName)pin, mode); } PinStatus digitalRead(PinName pin) { + #warning "digitalRead always applies default pull" return (PinStatus)mbed::DigitalIn(pin).read(); } PinStatus digitalRead(pin_size_t pin) { - return (PinStatus)mbed::DigitalIn(digitalPinToPinName(pin)).read(); -} \ No newline at end of file + return digitalRead((PinName)pin); +} + +void digitalWrite(PinName pin, PinStatus val) +{ + mbed::DigitalOut(pin, (int)val); +} + +void digitalWrite(pin_size_t pin, PinStatus val) { + digitalWrite((PinName)pin, val); +} + +#endif // digitalPinToGpio diff --git a/variants/ARDUINO_NANO33BLE/variant.cpp b/variants/ARDUINO_NANO33BLE/variant.cpp index 7df6b8c1..8483b804 100644 --- a/variants/ARDUINO_NANO33BLE/variant.cpp +++ b/variants/ARDUINO_NANO33BLE/variant.cpp @@ -2,53 +2,53 @@ PinDescription g_APinDescription[] = { // D0 - D7 - P1_3, NULL, NULL, // D0/TX - P1_10, NULL, NULL, // D1/RX - P1_11, NULL, NULL, // D2 - P1_12, NULL, NULL, // D3 - P1_15, NULL, NULL, // D4 - P1_13, NULL, NULL, // D5 - P1_14, NULL, NULL, // D6 - P0_23, NULL, NULL, // D7 + P1_3, NULL, NULL, NULL, // D0/TX + P1_10, NULL, NULL, NULL, // D1/RX + P1_11, NULL, NULL, NULL, // D2 + P1_12, NULL, NULL, NULL, // D3 + P1_15, NULL, NULL, NULL, // D4 + P1_13, NULL, NULL, NULL, // D5 + P1_14, NULL, NULL, NULL, // D6 + P0_23, NULL, NULL, NULL, // D7 // D8 - D13 - P0_21, NULL, NULL, // D8 - P0_27, NULL, NULL, // D9 - P1_2, NULL, NULL, // D10 - P1_1, NULL, NULL, // D11/MOSI - P1_8, NULL, NULL, // D12/MISO - P0_13, NULL, NULL, // D13/SCK/LED + P0_21, NULL, NULL, NULL, // D8 + P0_27, NULL, NULL, NULL, // D9 + P1_2, NULL, NULL, NULL, // D10 + P1_1, NULL, NULL, NULL, // D11/MOSI + P1_8, NULL, NULL, NULL, // D12/MISO + P0_13, NULL, NULL, NULL, // D13/SCK/LED // A0 - A7 - P0_4, NULL, NULL, // A0 - P0_5, NULL, NULL, // A1 - P0_30, NULL, NULL, // A2 - P0_29, NULL, NULL, // A3 - P0_31, NULL, NULL, // A4/SDA - P0_2, NULL, NULL, // A5/SCL - P0_28, NULL, NULL, // A6 - P0_3, NULL, NULL, // A7 + P0_4, NULL, NULL, NULL, // A0 + P0_5, NULL, NULL, NULL, // A1 + P0_30, NULL, NULL, NULL, // A2 + P0_29, NULL, NULL, NULL, // A3 + P0_31, NULL, NULL, NULL, // A4/SDA + P0_2, NULL, NULL, NULL, // A5/SCL + P0_28, NULL, NULL, NULL, // A6 + P0_3, NULL, NULL, NULL, // A7 // LEDs - P0_24, NULL, NULL, // LED R - P0_16, NULL, NULL, // LED G - P0_6, NULL, NULL, // LED B - P1_9, NULL, NULL, // LED PWR + P0_24, NULL, NULL, NULL, // LED R + P0_16, NULL, NULL, NULL, // LED G + P0_6, NULL, NULL, NULL, // LED B + P1_9, NULL, NULL, NULL, // LED PWR - P0_19, NULL, NULL, // INT APDS + P0_19, NULL, NULL, NULL, // INT APDS // PDM - P0_17, NULL, NULL, // PDM PWR - P0_26, NULL, NULL, // PDM CLK - P0_25, NULL, NULL, // PDM DIN + P0_17, NULL, NULL, NULL, // PDM PWR + P0_26, NULL, NULL, NULL, // PDM CLK + P0_25, NULL, NULL, NULL, // PDM DIN // Internal I2C - P0_14, NULL, NULL, // SDA2 - P0_15, NULL, NULL, // SCL2 + P0_14, NULL, NULL, NULL, // SDA2 + P0_15, NULL, NULL, NULL, // SCL2 // Internal I2C - P1_0, NULL, NULL, // I2C_PULL - P0_22, NULL, NULL, // VDD_ENV_ENABLE + P1_0, NULL, NULL, NULL, // I2C_PULL + P0_22, NULL, NULL, NULL, // VDD_ENV_ENABLE }; extern "C" {