From 1aaf8c59ae370b6fe5c9b1226131cce453e4e64c Mon Sep 17 00:00:00 2001 From: klassents Date: Mon, 17 Mar 2025 07:53:28 +0300 Subject: [PATCH] wiring digital speed optimization MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Уменьшено время выполнения функций digitalRead/Write/Toggle для всех плат --- .../hal/peripherals/Include/mik32_hal_gpio.h | 1 + cores/arduino/wiring_digital.c | 28 ++++---- libraries/NeoPixel/src/NeoPixel.cpp | 2 +- variants/elbear_ace_nano/pins_arduino.h | 20 ++++-- variants/elbear_ace_nano/variant.c | 63 ++++++----------- variants/elbear_ace_uno/pins_arduino.h | 25 +++++-- variants/elbear_ace_uno/variant.c | 70 +++++++------------ variants/elsomik/pins_arduino.h | 15 ++-- variants/elsomik/variant.c | 33 ++++----- variants/start/pins_arduino.h | 16 +++-- variants/start/variant.c | 33 ++++----- 11 files changed, 146 insertions(+), 160 deletions(-) diff --git a/cores/arduino/mik32/hal/peripherals/Include/mik32_hal_gpio.h b/cores/arduino/mik32/hal/peripherals/Include/mik32_hal_gpio.h index bc3237d..4d90b46 100644 --- a/cores/arduino/mik32/hal/peripherals/Include/mik32_hal_gpio.h +++ b/cores/arduino/mik32/hal/peripherals/Include/mik32_hal_gpio.h @@ -36,6 +36,7 @@ extern "C" { */ typedef enum __HAL_PinsTypeDef { + NOT_A_PIN = (0 << 0), /**< Не выбран пин. */ GPIO_PIN_0 = (1 << 0), /**< Выбран пин 0. */ GPIO_PIN_1 = (1 << 1), /**< Выбран пин 1. */ GPIO_PIN_2 = (1 << 2), /**< Выбран пин 2. */ diff --git a/cores/arduino/wiring_digital.c b/cores/arduino/wiring_digital.c index 47d358d..7c678ef 100644 --- a/cores/arduino/wiring_digital.c +++ b/cores/arduino/wiring_digital.c @@ -95,50 +95,54 @@ void fastPinMode(uint32_t PinNumber, uint32_t PinMode) } // write pin -void digitalWrite(uint32_t PinNumber, uint32_t Val) +__attribute__((noinline, section(".ram_text"))) void digitalWrite(uint32_t PinNumber, uint32_t Val) { if ((PinNumber>=pinCommonQty())) { ErrorMsgHandler("digitalWrite(): pin number exceeds the total number of pins"); return; } - - if (digitalPinHasPWM(PinNumber)) + + if (digitalPinPwmIsOn(PinNumber)) // if the pin can use PWM, disable PWM analogWriteStop(PinNumber); - HAL_GPIO_WritePin(digitalPinToPort(PinNumber), digitalPinToBitMask(PinNumber), (Val == HIGH) ? GPIO_PIN_HIGH : GPIO_PIN_LOW); + if (Val == HIGH) + GPIO_SET_PIN(digitalPinToPort(PinNumber), digitalPinToBitMask(PinNumber)); + else + GPIO_CLEAR_PIN(digitalPinToPort(PinNumber), digitalPinToBitMask(PinNumber)); } // read pin -int digitalRead(uint32_t PinNumber) +__attribute__((noinline, section(".ram_text"))) int digitalRead(uint32_t PinNumber) { if ((PinNumber>=pinCommonQty())) { ErrorMsgHandler("digitalRead(): pin number exceeds the total number of pins"); return -1; } - if (digitalPinHasPWM(PinNumber)) + + if (digitalPinPwmIsOn(PinNumber)) // if the pin can use PWM, disable PWM analogWriteStop(PinNumber); - GPIO_PinState pinState = HAL_GPIO_ReadPin(digitalPinToPort(PinNumber), digitalPinToBitMask(PinNumber)); - return (pinState == GPIO_PIN_LOW) ? LOW : HIGH; + return GPIO_READ_PIN(digitalPinToPort(PinNumber), digitalPinToBitMask(PinNumber)); } // toggle pin -void digitalToggle(uint32_t PinNumber) +__attribute__((noinline, section(".ram_text"))) void digitalToggle(uint32_t PinNumber) { if ((PinNumber>=pinCommonQty())) { ErrorMsgHandler("digitalToggle(): pin number exceeds the total number of pins"); return; } - if (digitalPinHasPWM(PinNumber)) + + if (digitalPinPwmIsOn(PinNumber)) // if the pin can use PWM, disable PWM analogWriteStop(PinNumber); - - HAL_GPIO_TogglePin(digitalPinToPort(PinNumber), digitalPinToBitMask(PinNumber)); + + GPIO_TOGGLE_PIN(digitalPinToPort(PinNumber), digitalPinToBitMask(PinNumber)); } #ifdef __cplusplus diff --git a/libraries/NeoPixel/src/NeoPixel.cpp b/libraries/NeoPixel/src/NeoPixel.cpp index 11d00de..e2aabcc 100644 --- a/libraries/NeoPixel/src/NeoPixel.cpp +++ b/libraries/NeoPixel/src/NeoPixel.cpp @@ -65,7 +65,7 @@ static void __attribute__((noinline, section(".ram_text"))) mik32Show(GPIO_TypeD // not support 400khz if (!is800KHz) return; - if ((m_port != NULL) && (m_pin != NC)) + if ((m_port != NULL) && (m_pin != NOT_A_PIN)) { volatile uint32_t* set = &m_port->SET; volatile uint32_t* clr = &m_port->CLEAR; diff --git a/variants/elbear_ace_nano/pins_arduino.h b/variants/elbear_ace_nano/pins_arduino.h index 54cbc1e..c1e19df 100644 --- a/variants/elbear_ace_nano/pins_arduino.h +++ b/variants/elbear_ace_nano/pins_arduino.h @@ -32,6 +32,13 @@ extern "C" { #include "mik32_hal_gpio.h" #include "mik32_hal_timer32.h" +// total number of pins available for initialization +#define PINS_COMMON_QTY 26 +#define pinCommonQty() (PINS_COMMON_QTY) + +extern bool spi0NssPinIsBlocked; +extern bool spi1NssPinIsBlocked; + // analog pins #define PIN_A0 (14) #define PIN_A1 (15) @@ -63,8 +70,6 @@ static const uint8_t A7 = PIN_A7; GPIO_TypeDef* digitalPinToPort(uint32_t digPinNumber); // determines the pin address inside the port by the board pin number HAL_PinsTypeDef digitalPinToBitMask(uint32_t digPinNumber); -// total number of pins available for initialization -uint16_t pinCommonQty(void); // the function returns a reference to the OUTPUT address of the GPIO register volatile uint32_t* portOutputRegister(GPIO_TypeDef* GPIO_x); // the function returns a reference to the STATE address of the GPIO register @@ -84,8 +89,15 @@ uint32_t analogInputToChannelNumber(uint32_t PinNumber); // PWM #define PWM_FREQUENCY_MAX 1000000 // Hz -bool digitalPinHasPWM(uint8_t p); -bool digitalPinPwmIsOn(uint8_t digitalPin); // use only if digitalPinHasPWM() == true +static inline __attribute__((always_inline)) bool digitalPinHasPWM(uint8_t p) +{ + // if spi is in use D9 or D10 cannot work as pwm + if (p == 3 || p == 5 || p == 6 || (p >= 11 && p <= 13) || ((p == 9) && !spi0NssPinIsBlocked) || ((p == 10) && !spi1NssPinIsBlocked)) + return true; + return false; +} +// return true if digitalPin configured as pwm +bool digitalPinPwmIsOn(uint8_t digitalPin); // determines which timer the pin belongs to TIMER32_TypeDef* pwmPinToTimer(uint32_t digPinNumber); // determines which timer channel the pin belongs to diff --git a/variants/elbear_ace_nano/variant.c b/variants/elbear_ace_nano/variant.c index 7f1d016..d5f6a31 100644 --- a/variants/elbear_ace_nano/variant.c +++ b/variants/elbear_ace_nano/variant.c @@ -65,9 +65,8 @@ const HAL_PinsTypeDef digitalPinToGpioPinArray[] = }; // determines the address of the port by the board pin number to which this pin belongs on the MCU -GPIO_TypeDef* digitalPinToPort(uint32_t digPinNumber) +__attribute__((noinline, section(".ram_text"))) GPIO_TypeDef* digitalPinToPort(uint32_t digPinNumber) { - GPIO_TypeDef* gpioNum = NULL; if (digPinNumber >= pinCommonQty()) { ErrorMsgHandler("digitalPinToPort(): pin number exceeds the total number of pins"); @@ -76,41 +75,32 @@ GPIO_TypeDef* digitalPinToPort(uint32_t digPinNumber) // port 2 - led (22) if (digPinNumber == LED_BUILTIN) - gpioNum = GPIO_2; + return GPIO_2; // port 1 - board pins 7, 8, 10...13, 14(А0), 15(А1), 18,19 else if (digPinNumber == 7 || digPinNumber == 8 || (digPinNumber >= 10 && digPinNumber <= 15) || digPinNumber == 18 || digPinNumber == 19 || (digPinNumber == 9 && spi0NssPinIsBlocked)) - gpioNum = GPIO_1; + return GPIO_1; // port 0 - board pins 0...6, 9, 16(A2), 17(A3), 20(A4), 21(A5), 24(A6), 25(A7) else - gpioNum = GPIO_0; - - return gpioNum; + return GPIO_0; } // determines the pin address inside the port by the board pin number -HAL_PinsTypeDef digitalPinToBitMask(uint32_t digPinNumber) +__attribute__((noinline, section(".ram_text"))) HAL_PinsTypeDef digitalPinToBitMask(uint32_t digPinNumber) { if (digPinNumber >= pinCommonQty()) { ErrorMsgHandler("digitalPinToBitMask(): pin number exceeds the total number of pins"); - return NC; + return NOT_A_PIN; } - HAL_PinsTypeDef mask; // if spi is on default pin NSS_IN is needed for spi, board pin is replaced to pin NSS_OUT if ((digPinNumber == 10) && spi1NssPinIsBlocked) - mask = SPI1_NSS_OUT_PIN; + return SPI1_NSS_OUT_PIN; else if ((digPinNumber == 9) && spi0NssPinIsBlocked) - mask = SPI0_NSS_OUT_PIN; + return SPI0_NSS_OUT_PIN; else - mask = digitalPinToGpioPinArray[digPinNumber]; - return mask; -} - -uint16_t pinCommonQty(void) -{ - return (uint16_t)(sizeof(digitalPinToGpioPinArray)/sizeof(digitalPinToGpioPinArray[0])); + return digitalPinToGpioPinArray[digPinNumber]; } // the function returns a reference to the OUTPUT address of the GPIO register @@ -219,31 +209,22 @@ uint32_t analogInputToChannelNumber(uint32_t PinNumber) // use only if digitalPinHasPWM() == true // return true if digitalPin configured as pwm -bool digitalPinPwmIsOn(uint8_t digitalPin) +__attribute__((noinline, section(".ram_text"))) bool digitalPinPwmIsOn(uint8_t digitalPin) { - uint8_t config = 0; - uint8_t pinShift = PIN_MASK_TO_PIN_NUMBER(digitalPinToBitMask(digitalPin)); + if (digitalPinHasPWM(digitalPin)) + { + uint8_t config = 0; + uint8_t pinShift = PIN_MASK_TO_PIN_NUMBER(digitalPinToBitMask(digitalPin)); - if (PWM_PIN_TO_PORT_NUMBER(digitalPin) == 0) - config = PIN_GET_PAD_CONFIG(PORT_0_CFG, pinShift); - else - config = PIN_GET_PAD_CONFIG(PORT_1_CFG, pinShift); + if (PWM_PIN_TO_PORT_NUMBER(digitalPin) == 0) + config = PIN_GET_PAD_CONFIG(PORT_0_CFG, pinShift); + else + config = PIN_GET_PAD_CONFIG(PORT_1_CFG, pinShift); - if (config == 2) - return true; - else - return false; -} - -bool digitalPinHasPWM(uint8_t p) -{ - bool ret = false; - // if spi is in use D10 cannot work as pwm - if (((p == 9) && spi0NssPinIsBlocked) || ((p == 10) && spi1NssPinIsBlocked)) - ret = false; - else if (p == 3 || p == 5 || p == 6 || (p >= 9 && p <= 13)) - ret = true; - return ret; + if (config == 2) + return true; + } + return false; } // function is used only if digitalPinHasPWM() is true diff --git a/variants/elbear_ace_uno/pins_arduino.h b/variants/elbear_ace_uno/pins_arduino.h index 3095d54..553ed21 100644 --- a/variants/elbear_ace_uno/pins_arduino.h +++ b/variants/elbear_ace_uno/pins_arduino.h @@ -32,6 +32,13 @@ extern "C" { #include "mik32_hal_gpio.h" #include "mik32_hal_timer32.h" +// total number of pins available for initialization +#define PINS_COMMON_QTY 24 +#define pinCommonQty() (PINS_COMMON_QTY) + +extern bool spi0NssPinIsBlocked; +extern bool spi1NssPinIsBlocked; + // analog pins #define PIN_A0 (14) #define PIN_A1 (15) @@ -47,7 +54,6 @@ static const uint8_t A3 = PIN_A3; static const uint8_t A4 = PIN_A4; static const uint8_t A5 = PIN_A5; - // digital pins // D0...D13, D18, D19 @@ -55,12 +61,10 @@ static const uint8_t A5 = PIN_A5; #define LED_BUILTIN (22) #define BTN_BUILTIN (23) -// determines the address of the port by the board pin number to which this pin belongs on the MCU -GPIO_TypeDef* digitalPinToPort(uint32_t digPinNumber); +// determines the port address by the board pin number to which this pin belongs on the MCU +GPIO_TypeDef* digitalPinToPort(uint32_t digPinNumber); // determines the pin address inside the port by the board pin number HAL_PinsTypeDef digitalPinToBitMask(uint32_t digPinNumber); -// total number of pins available for initialization -uint16_t pinCommonQty(void); // the function returns a reference to the OUTPUT address of the GPIO register volatile uint32_t* portOutputRegister(GPIO_TypeDef* GPIO_x); // the function returns a reference to the STATE address of the GPIO register @@ -80,8 +84,15 @@ uint32_t analogInputToChannelNumber(uint32_t PinNumber); // PWM #define PWM_FREQUENCY_MAX 1000000 // Hz -bool digitalPinHasPWM(uint8_t p); -bool digitalPinPwmIsOn(uint8_t digitalPin); // use only if digitalPinHasPWM() == true +static inline __attribute__((always_inline)) bool digitalPinHasPWM(uint8_t p) +{ + // if spi is in use D9 or D10 cannot work as pwm + if (p == 3 || p == 5 || p == 6 || (p >= 11 && p <= 13) || ((p == 9) && !spi0NssPinIsBlocked) || ((p == 10) && !spi1NssPinIsBlocked)) + return true; + return false; +} +// return true if digitalPin configured as pwm +bool digitalPinPwmIsOn(uint8_t digitalPin); // determines which timer the pin belongs to TIMER32_TypeDef* pwmPinToTimer(uint32_t digPinNumber); // determines which timer channel the pin belongs to diff --git a/variants/elbear_ace_uno/variant.c b/variants/elbear_ace_uno/variant.c index 7cab048..9842331 100644 --- a/variants/elbear_ace_uno/variant.c +++ b/variants/elbear_ace_uno/variant.c @@ -34,7 +34,7 @@ bool spi0NssPinIsBlocked = false; bool spi1NssPinIsBlocked = false; // list of pin numbers from both ports with pins inside the port -const HAL_PinsTypeDef digitalPinToGpioPinArray[] = +const HAL_PinsTypeDef digitalPinToGpioPinArray[PINS_COMMON_QTY] = { GPIO_PIN_5, // D0 GPIO_PIN_6, // D1 @@ -62,10 +62,9 @@ const HAL_PinsTypeDef digitalPinToGpioPinArray[] = GPIO_PIN_6 // BTN(pin 23) }; -// etermines the address of the port by the board pin number to which this pin belongs on the MCU -GPIO_TypeDef* digitalPinToPort(uint32_t digPinNumber) +// determines the address of the port by the board pin number to which this pin belongs on the MCU +__attribute__((noinline, section(".ram_text"))) GPIO_TypeDef* digitalPinToPort(uint32_t digPinNumber) { - GPIO_TypeDef* gpioNum = NULL; if (digPinNumber >= pinCommonQty()) { ErrorMsgHandler("digitalPinToPort(): pin number exceeds the total number of pins"); @@ -74,41 +73,32 @@ GPIO_TypeDef* digitalPinToPort(uint32_t digPinNumber) // port 2 - led and button if (digPinNumber == LED_BUILTIN || digPinNumber == BTN_BUILTIN) - gpioNum = GPIO_2; + return GPIO_2; // port 1 - board pins 7, 8, 10...13, 14(А0), 15(А1), 18,19 else if (digPinNumber == 7 || digPinNumber == 8 || (digPinNumber >= 10 && digPinNumber <= 15) || digPinNumber == 18 || digPinNumber == 19 || (digPinNumber == 9 && spi0NssPinIsBlocked)) // 10 pieces - gpioNum = GPIO_1; + return GPIO_1; // port 0 - board pins 0...6, 9, 16(A2), 17(A3), 20(A4), 21(A5) else - gpioNum = GPIO_0; - - return gpioNum; -} + return GPIO_0; +} // determines the pin address inside the port by the board pin number -HAL_PinsTypeDef digitalPinToBitMask(uint32_t digPinNumber) +__attribute__((noinline, section(".ram_text"))) HAL_PinsTypeDef digitalPinToBitMask(uint32_t digPinNumber) { if (digPinNumber >= pinCommonQty()) { ErrorMsgHandler("digitalPinToBitMask(): pin number exceeds the total number of pins"); - return NC; + return NOT_A_PIN; } - HAL_PinsTypeDef mask; // if spi is on default pin NSS_IN is needed for spi, board pin is replaced to pin NSS_OUT if ((digPinNumber == 10) && spi1NssPinIsBlocked) - mask = SPI1_NSS_OUT_PIN; + return SPI1_NSS_OUT_PIN; else if ((digPinNumber == 9) && spi0NssPinIsBlocked) - mask = SPI0_NSS_OUT_PIN; + return SPI0_NSS_OUT_PIN; else - mask = digitalPinToGpioPinArray[digPinNumber]; - return mask; -} - -uint16_t pinCommonQty(void) -{ - return (uint16_t)(sizeof(digitalPinToGpioPinArray)/sizeof(digitalPinToGpioPinArray[0])); + return digitalPinToGpioPinArray[digPinNumber]; } // the function returns a reference to the OUTPUT address of the GPIO register @@ -180,33 +170,23 @@ uint32_t analogInputToChannelNumber(uint32_t PinNumber) // use only if digitalPinHasPWM() == true #define PWM_PIN_TO_PORT_NUMBER(pin) (((pin==10)||(pin==11)||(pin==12)||(pin==13)) ? 1:0) -// use only if digitalPinHasPWM() == true // return true if digitalPin configured as pwm -bool digitalPinPwmIsOn(uint8_t digitalPin) +__attribute__((noinline, section(".ram_text"))) bool digitalPinPwmIsOn(uint8_t digitalPin) { - uint8_t config = 0; - uint8_t pinShift = PIN_MASK_TO_PIN_NUMBER(digitalPinToBitMask(digitalPin)); + if (digitalPinHasPWM(digitalPin)) + { + uint8_t config = 0; + uint8_t pinShift = PIN_MASK_TO_PIN_NUMBER(digitalPinToBitMask(digitalPin)); - if (PWM_PIN_TO_PORT_NUMBER(digitalPin) == 0) - config = PIN_GET_PAD_CONFIG(PORT_0_CFG, pinShift); - else - config = PIN_GET_PAD_CONFIG(PORT_1_CFG, pinShift); + if (PWM_PIN_TO_PORT_NUMBER(digitalPin) == 0) + config = PIN_GET_PAD_CONFIG(PORT_0_CFG, pinShift); + else + config = PIN_GET_PAD_CONFIG(PORT_1_CFG, pinShift); - if (config == 2) - return true; - else - return false; -} - -bool digitalPinHasPWM(uint8_t p) -{ - bool ret = false; - // if spi is in use D9 or D10 cannot work as pwm - if (((p == 9) && spi0NssPinIsBlocked) || ((p == 10) && spi1NssPinIsBlocked)) - ret = false; - else if (p == 3 || p == 5 || p == 6 || (p >= 9 && p <= 13)) - ret = true; - return ret; + if (config == 2) + return true; + } + return false; } // function is used only if digitalPinHasPWM() is true diff --git a/variants/elsomik/pins_arduino.h b/variants/elsomik/pins_arduino.h index adebe90..282f608 100644 --- a/variants/elsomik/pins_arduino.h +++ b/variants/elsomik/pins_arduino.h @@ -71,6 +71,8 @@ typedef enum P2_7, // 33 PINS_COMMON_QTY, // 34 } DigitalPinsTypeDef; +// total number of pins available for initialization +#define pinCommonQty() (PINS_COMMON_QTY) // analog pins #define PIN_A0 (P1_5) @@ -96,11 +98,6 @@ static const uint8_t A7 = PIN_A7; GPIO_TypeDef* digitalPinToPort(uint32_t digPinNumber); // determines the pin address inside the port by the board pin number HAL_PinsTypeDef digitalPinToBitMask(uint32_t digitalPinNumber); -// total number of pins available for initialization -static inline uint16_t pinCommonQty(void) -{ - return (uint16_t)PINS_COMMON_QTY; -} // the function returns a reference to the OUTPUT address of the GPIO register volatile uint32_t* portOutputRegister(GPIO_TypeDef* GPIO_x); // the function returns a reference to the STATE address of the GPIO register @@ -120,8 +117,12 @@ uint32_t analogInputToChannelNumber(uint32_t PinNumber); // PWM #define PWM_FREQUENCY_MAX 1000000 // Hz -bool digitalPinHasPWM(uint8_t p); -bool digitalPinPwmIsOn(uint8_t digitalPin); // use only if digitalPinHasPWM() == true +static inline __attribute__((always_inline)) bool digitalPinHasPWM(uint8_t p) +{ + return (p <= P1_15) && ((p & 0xF) < 4); +} +// return true if digitalPin configured as pwm +bool digitalPinPwmIsOn(uint8_t digitalPin); // determines which timer the pin belongs to TIMER32_TypeDef* pwmPinToTimer(uint32_t digPinNumber); // determines which timer channel the pin belongs to diff --git a/variants/elsomik/variant.c b/variants/elsomik/variant.c index 5f51a41..c5eab70 100644 --- a/variants/elsomik/variant.c +++ b/variants/elsomik/variant.c @@ -21,7 +21,7 @@ * @return The address of the port corresponding to the board pin number. Can return 0 if the pin not exists */ -GPIO_TypeDef *digitalPinToPort(uint32_t digitalPinNumber) + __attribute__((noinline, section(".ram_text"))) GPIO_TypeDef *digitalPinToPort(uint32_t digitalPinNumber) { if (digitalPinNumber >= pinCommonQty()) { @@ -40,12 +40,12 @@ GPIO_TypeDef *digitalPinToPort(uint32_t digitalPinNumber) } // determines the pin address inside the port by the board pin number -HAL_PinsTypeDef digitalPinToBitMask(uint32_t digitalPinNumber) +__attribute__((noinline, section(".ram_text"))) HAL_PinsTypeDef digitalPinToBitMask(uint32_t digitalPinNumber) { if (digitalPinNumber >= PINS_COMMON_QTY) { ErrorMsgHandler("digitalPinToBitMask(): pin number exceeds the total number of pins"); - return NC; + return NOT_A_PIN; } if (digitalPinNumber >= P2_6) @@ -110,27 +110,24 @@ uint32_t analogInputToChannelNumber(uint32_t PinNumber) // use only if digitalPinHasPWM() == true // return true if digitalPin configured as pwm -bool digitalPinPwmIsOn(uint8_t digitalPin) +__attribute__((noinline, section(".ram_text"))) bool digitalPinPwmIsOn(uint8_t digitalPin) { - uint8_t config = 0; - uint8_t pinShift = digitalPin & 0x3; + if (digitalPinHasPWM(digitalPin)) + { + uint8_t config = 0; + uint8_t pinShift = digitalPin & 0x3; - if (PWM_PIN_TO_PORT_NUMBER(digitalPin) == 0) - config = PIN_GET_PAD_CONFIG(PORT_0_CFG, pinShift); - else - config = PIN_GET_PAD_CONFIG(PORT_1_CFG, pinShift); + if (PWM_PIN_TO_PORT_NUMBER(digitalPin) == 0) + config = PIN_GET_PAD_CONFIG(PORT_0_CFG, pinShift); + else + config = PIN_GET_PAD_CONFIG(PORT_1_CFG, pinShift); - if (config == 2) - return true; - else + if (config == 2) + return true; + } return false; } -bool digitalPinHasPWM(uint8_t digitalPin) -{ - return (digitalPin <= P1_15) && ((digitalPin & 0xF) < 4); -} - // function is used only if digitalPinHasPWM() is true TIMER32_TypeDef *pwmPinToTimer(uint32_t digPinNumber) { diff --git a/variants/start/pins_arduino.h b/variants/start/pins_arduino.h index cbca102..f785196 100644 --- a/variants/start/pins_arduino.h +++ b/variants/start/pins_arduino.h @@ -78,6 +78,9 @@ typedef enum PINS_COMMON_QTY, // 40 } DigitalPinsTypeDef; +// total number of pins available for initialization +#define pinCommonQty() (PINS_COMMON_QTY) + // analog pins #define PIN_A0 (P1_5) #define PIN_A1 (P1_7) @@ -108,11 +111,6 @@ static const uint8_t A7 = PIN_A7; GPIO_TypeDef* digitalPinToPort(uint32_t digPinNumber); // determines the pin address inside the port by the board pin number HAL_PinsTypeDef digitalPinToBitMask(uint32_t digitalPinNumber); -// total number of pins available for initialization -static inline uint16_t pinCommonQty(void) -{ - return (uint16_t)PINS_COMMON_QTY; -} // the function returns a reference to the OUTPUT address of the GPIO register volatile uint32_t* portOutputRegister(GPIO_TypeDef* GPIO_x); // the function returns a reference to the STATE address of the GPIO register @@ -132,8 +130,12 @@ uint32_t analogInputToChannelNumber(uint32_t PinNumber); // PWM #define PWM_FREQUENCY_MAX 1000000 // Hz -bool digitalPinHasPWM(uint8_t p); -bool digitalPinPwmIsOn(uint8_t digitalPin); // use only if digitalPinHasPWM() == true +static inline __attribute__((always_inline)) bool digitalPinHasPWM(uint8_t p) +{ + return (p < 32) && ((p & 0xF) < 4); +} +// return true if digitalPin configured as pwm +bool digitalPinPwmIsOn(uint8_t digitalPin); // determines which timer the pin belongs to TIMER32_TypeDef* pwmPinToTimer(uint32_t digPinNumber); // determines which timer channel the pin belongs to diff --git a/variants/start/variant.c b/variants/start/variant.c index dbd66cb..2e83da8 100644 --- a/variants/start/variant.c +++ b/variants/start/variant.c @@ -21,7 +21,7 @@ * @return The address of the port corresponding to the board pin number. Can return 0 if the pin not exists */ -GPIO_TypeDef *digitalPinToPort(uint32_t digitalPinNumber) + __attribute__((noinline, section(".ram_text"))) GPIO_TypeDef *digitalPinToPort(uint32_t digitalPinNumber) { GPIO_TypeDef* port = NULL; if (digitalPinNumber < pinCommonQty()) @@ -39,12 +39,12 @@ GPIO_TypeDef *digitalPinToPort(uint32_t digitalPinNumber) } // determines the pin address inside the port by the board pin number -HAL_PinsTypeDef digitalPinToBitMask(uint32_t digitalPinNumber) +__attribute__((noinline, section(".ram_text"))) HAL_PinsTypeDef digitalPinToBitMask(uint32_t digitalPinNumber) { if (digitalPinNumber >= pinCommonQty()) { ErrorMsgHandler("digitalPinToBitMask(): pin number exceeds the total number of pins"); - return NC; + return NOT_A_PIN; } return (HAL_PinsTypeDef)(1 << (digitalPinNumber & 0xF)); @@ -106,27 +106,24 @@ uint32_t analogInputToChannelNumber(uint32_t PinNumber) // use only if digitalPinHasPWM() == true // return true if digitalPin configured as pwm -bool digitalPinPwmIsOn(uint8_t digitalPin) +__attribute__((noinline, section(".ram_text"))) bool digitalPinPwmIsOn(uint8_t digitalPin) { - uint8_t config = 0; - uint8_t pinShift = digitalPin & 3; + if (digitalPinHasPWM(digitalPin)) + { + uint8_t config = 0; + uint8_t pinShift = digitalPin & 3; - if (PWM_PIN_TO_PORT_NUMBER(digitalPin) == 0) - config = PIN_GET_PAD_CONFIG(PORT_0_CFG, pinShift); - else - config = PIN_GET_PAD_CONFIG(PORT_1_CFG, pinShift); + if (PWM_PIN_TO_PORT_NUMBER(digitalPin) == 0) + config = PIN_GET_PAD_CONFIG(PORT_0_CFG, pinShift); + else + config = PIN_GET_PAD_CONFIG(PORT_1_CFG, pinShift); - if (config == 2) - return true; - else + if (config == 2) + return true; + } return false; } -bool digitalPinHasPWM(uint8_t p) -{ - return (p < 32) && ((p & 0xF) < 4); -} - // function is used only if digitalPinHasPWM() is true TIMER32_TypeDef *pwmPinToTimer(uint32_t digPinNumber) {