wiring digital speed optimization

Уменьшено время выполнения функций digitalRead/Write/Toggle для всех плат
This commit was merged in pull request #15.
This commit is contained in:
klassents committed 2025-03-17 07:53:28 +03:00
1 parent 0adc8293d7
commit 1aaf8c59ae
11 files changed
+146 -160

No files matched your search

+18 -7
View File
@@ -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
+25 -45
View File
@@ -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