Проверка в analogWrite(), добавление экземпляров для Wire, SPI, Serial

В функции analogWrite() добавлена проверка, включен ли уже канал - если включен, применяется новое значение только если оно отличается от текущего.
В модулях Wire, SPI, Serial теперь по два экземпляра в соответствии с периферией МК. Для каждой платы задается свой экземпляр, используемый по умолчанию
Co-authored-by: KLASSENTS <klassen@elron.tech>
Co-committed-by: KLASSENTS <klassen@elron.tech>
This commit is contained in:
KLASSENTS 2025-05-27 12:35:36 +03:00 committed by klassents
parent f1e091bf77
commit 778608b576
29 changed files with 186 additions and 130 deletions

View File

@ -8,10 +8,13 @@
#include "wiring_LL.h"
// HardwareSerial class objects for use in Arduino IDE
HardwareSerial Serial(0);
HardwareSerial Serial0(0);
#if SERIAL_PORT_QTY > 1
HardwareSerial Serial1(1);
#endif
// default interface
HardwareSerial& Serial = DEFAULT_SERIAL;
void serialEvent() __attribute__((weak));
bool Serial0_available() __attribute__((weak));
@ -144,7 +147,7 @@ extern "C" void __attribute__((optimize("O3"))) serial_interrupt_handler(uint8_t
{
if (uartNumInt == 0)
{
Serial.rx_complete_irq();
Serial0.rx_complete_irq();
}
else if ((uartNumInt == 1) && (SERIAL_PORT_QTY > 1))
{

View File

@ -103,10 +103,12 @@ class HardwareSerial : public Stream
inline void rx_complete_irq(void) __attribute__((always_inline, optimize("O3")));
};
extern HardwareSerial Serial;
extern HardwareSerial Serial0;
#if SERIAL_PORT_QTY > 1
extern HardwareSerial Serial1;
#endif
// default interface
extern HardwareSerial& Serial;
extern void serialEventRun(void) __attribute__((weak));

View File

@ -104,9 +104,23 @@ It is recommended to enable the timer in the following order:
*/
void analogWrite(uint32_t PinNumber, uint32_t writeVal)
{
if (digitalPinHasPWM(PinNumber))
if (writeVal > WriteValMax) writeVal = WriteValMax;
if (digitalPinPwmIsOn(PinNumber) > 0) // pin has pwm and pwm is already on
{
if (writeVal > WriteValMax) writeVal = WriteValMax;
// we can only change writeVal if it is differ from current value
TIMER32_TypeDef* timer = pwmPinToTimer(PinNumber);
uint32_t newOCR = (uint32_t) (((uint64_t)pwmTopVal * writeVal) / WriteValMax);
if (timer->CHANNELS[pwmPinToTimerChannel(PinNumber)].OCR != newOCR)
{
// if new ocr differs from current, set new ocr
timer->CHANNELS[pwmPinToTimerChannel(PinNumber)].OCR = newOCR;
}
}
else if (digitalPinPwmIsOn(PinNumber) == 0) // pin has pwm and pwm is off
{
// init pin as pwm
uint32_t OCRval = (uint32_t) (((uint64_t)pwmTopVal * writeVal) / WriteValMax);
// initialization of the required timer
htimer32.Instance = pwmPinToTimer(PinNumber);
@ -127,7 +141,7 @@ void analogWrite(uint32_t PinNumber, uint32_t writeVal)
htimer32_channel.PWM_Invert = TIMER32_CHANNEL_NON_INVERTED_PWM;
htimer32_channel.Mode = TIMER32_CHANNEL_MODE_PWM;
htimer32_channel.CaptureEdge = TIMER32_CHANNEL_CAPTUREEDGE_RISING;
htimer32_channel.OCR = (uint32_t) (((uint64_t)pwmTopVal * writeVal) / WriteValMax);
htimer32_channel.OCR = OCRval;
htimer32_channel.Noise = TIMER32_CHANNEL_FILTER_OFF;
HAL_Timer32_Channel_Init(&htimer32_channel);
@ -137,7 +151,7 @@ void analogWrite(uint32_t PinNumber, uint32_t writeVal)
HAL_Timer32_Start(&htimer32);
pwmIsInited++; // increase inited channels qty
}
else
else // pin doesn't have pwm
ErrorMsgHandler("analogWrite(): invalid pwm pin number");
}
@ -168,14 +182,17 @@ It is recommended to turn off the timer in the following order:
- Write 0 to the INT_CLEAR register;
- Set TIM_EN to 0.
*/
// use only if digitalPinPwmIsOn(PinNumber) > 0
void analogWriteStop(uint32_t PinNumber)
{
if (digitalPinHasPWM(PinNumber) && (pwmIsInited > 0) && digitalPinPwmIsOn(PinNumber))
if ((pwmIsInited > 0))
{
// load the timer address and channel number corresponding to the specified pin
htimer32.Instance = pwmPinToTimer(PinNumber);
htimer32_channel.TimerInstance = htimer32.Instance;
htimer32_channel.ChannelIndex = pwmPinToTimerChannel(PinNumber);
htimer32.Instance->CHANNELS[htimer32_channel.ChannelIndex].OCR = 0;
htimer32_channel.TimerInstance = htimer32.Instance;
// deinit channel
HAL_Timer32_Channel_DeInit(&htimer32_channel);
pwmIsInited--; // decrease inited channels qty

View File

@ -37,8 +37,8 @@ void pinMode(uint32_t PinNumber, uint32_t PinMode)
return;
}
if (digitalPinHasPWM(PinNumber))
// if the pin can use PWM, disable PWM
if (digitalPinPwmIsOn(PinNumber))
// if the pin use PWM, disable PWM
analogWriteStop(PinNumber);
// determine the port and the pin number in the port
@ -104,7 +104,7 @@ __attribute__((noinline, section(".ram_text"))) void digitalWrite(uint32_t PinNu
}
if (digitalPinPwmIsOn(PinNumber))
// if the pin can use PWM, disable PWM
// if the pin use PWM, disable PWM
analogWriteStop(PinNumber);
if (Val == HIGH)
@ -123,7 +123,7 @@ __attribute__((noinline, section(".ram_text"))) int digitalRead(uint32_t PinNumb
}
if (digitalPinPwmIsOn(PinNumber))
// if the pin can use PWM, disable PWM
// if the pin use PWM, disable PWM
analogWriteStop(PinNumber);
return GPIO_READ_PIN(digitalPinToPort(PinNumber), digitalPinToBitMask(PinNumber));
@ -139,7 +139,7 @@ __attribute__((noinline, section(".ram_text"))) void digitalToggle(uint32_t PinN
}
if (digitalPinPwmIsOn(PinNumber))
// if the pin can use PWM, disable PWM
// if the pin use PWM, disable PWM
analogWriteStop(PinNumber);
GPIO_TOGGLE_PIN(digitalPinToPort(PinNumber), digitalPinToBitMask(PinNumber));

View File

@ -13,7 +13,7 @@ unsigned long pulseIn(int pin, int state, unsigned long timeout)
ErrorMsgHandler("pulseIn(): pin number exceeds the total number of pins");
return -1;
}
if (digitalPinHasPWM(pin))
if (digitalPinPwmIsOn(pin) > 0)
// pwm off
analogWriteStop(pin);

View File

@ -1,7 +1,7 @@
# ELBEAR ACE-UNO
Особенности работы с платами ELBEAR ACE-UNO в среде программирования ArduinoIDE.
### Функциональное назначение выводов
![Pinout](uno_pinout.png)
![Pinout](pinout_uno.png)
### Цифровые выводы
На плате ELBEAR ACE-UNO доступны встроенные светодиод и кнопка. Для их использования необходимо воспользоваться макросами `LED_BUILTIN` и `BTN_BUILTIN`, передавая их в качестве аргументов функции вместо номера цифрового вывода. Макросу `LED_BUILTIN` соответствует номер вывода D22, а макросу `BTN_BUILTIN` - D23.
### Аналоговые выводы
@ -9,6 +9,7 @@
Для использования вывода в качестве аналогового необходимо перевести соответствующий DIP-переключатель, расположенный рядом с аналоговыми выводами, в положение OFF. В этом режиме внешнее напряжение, подаваемое на вывод, будет понижаться резистивным делителем перед подачей на микроконтроллер.
Для использования вывода в качестве цифрового нужно перевести переключатель в положение ON. В этом случае напряжение с вывода платы передается на микроконтроллер без изменений.
Таблица соответствия выводов платы и номера DIP-переключателя представлена ниже. Переключатель 5 относится сразу к двум аналоговым выводам - А4, А5.
|Вывод|Номер переключателя|
|---------|---------|
|А0|1|
@ -17,9 +18,10 @@
|А3|4|
|А4|5|
|А5|5|
#### ШИМ
На плате ELBEAR ACE-UNO доступно 8 выводов для формирования ШИМ-сигнала: D3, D5, D6, D9...D13. Генерация сигнала осуществляется с помощью 32-битного таймера. Выводы D3, D5, D6, D9 подключены к таймеру 1, выводы D10...D13 подключены к таймеру 2. Выводы, подключенные к одному и тому же таймеру, выдают ШИМ-сигнал одинаковой частоты.
Цифровые выводы D9, D10 не могут быть использованы для генерации ШИМ, если одновременно активен интерфейс SPI (при использовании экземпляра `SPI` недоступен ШИМ на выводе D10, при использовании экземпляра `SPI1` - на выводе D9). Это ограничение связано с особенностями работы микроконтроллера. Ограничение не распространяется на использование D9, D10 в качестве цифрового вывода при активном SPI.
Цифровые выводы D9, D10 не могут быть использованы для генерации ШИМ, если одновременно активен интерфейс SPI (при использовании экземпляра `SPI` недоступен ШИМ на выводе D10, при использовании экземпляра `SPI0` - на выводе D9). Это ограничение связано с особенностями работы микроконтроллера. Ограничение не распространяется на использование D9, D10 в качестве цифрового вывода при активном SPI.
### Прерывания
На плате ELBEAR ACE-UNO доступно 8 прерываний, настраиваемых функцией `void attachInterrupt(uint8_t interruptNum, void (*userFunc)(void), int mode)`:
@ -42,4 +44,10 @@
### SPI
Интерфейс SPI1 доступен на выводах D11, D12, D13. Для работы с ним используется экземпляр класса под названием `SPI`.
Интерфейс SPI0 доступен на выводах D3, D5, D6. Используемый экземпляр класса - `SPI1`.
Интерфейс SPI0 доступен на выводах D3, D5, D6. Используемый экземпляр класса - `SPI0`.
### I2C
Интерфейс I2C1 доступен на выводах SDA и SCL, для работы с ним используется экземпляр класса под названием `Wire`.
## Драйверы
Для работы с платой по интерфейсу USB необходим драйвер для микросхемы CH340С, его можно скачать [здесь](https://www.wch-ic.com/downloads/CH341SER_ZIP.html).

Binary file not shown.

Before

Width:  |  Height:  |  Size: 340 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 470 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.0 MiB

View File

@ -53,16 +53,16 @@
|P0_15|7|
### Serial
Интерфейс UART0 доступен на выводах P0_5, P0_6, для работы с ним используется экземпляр класса под названием `Serial`.
Интерфейс UART0 доступен на выводах RX, TX и P0_5, P0_6. Для работы с ним используется экземпляр класса под названием `Serial`.
Интерфейс UART1 доступен на выводах P1_8, P1_9, используемый экземпляр класса - `Serial1`.
USB-UART преобразователь, установленный на плате, поддерживает стандартные скорости UART до 57600 бод. Нестандартные скорости должны быть кратны
12*32=384, например, 240000 бод, 768000 бод.
### SPI
Интерфейс SPI1 доступен на выводах P1_0, P1_1, P1_2. Для работы с ним используется экземпляр класса под названием `SPI`.
Интерфейс SPI0 доступен на выводах P0_0, P0_1, P0_2. Используемый экземпляр класса - `SPI1`.
Интерфейс SPI1 доступен на выводах MOSI, MISO, CLK и P1_0, P1_1, P1_2. Для работы с ним используется экземпляр класса под названием `SPI`.
Интерфейс SPI0 доступен на выводах P0_0, P0_1, P0_2. Используемый экземпляр класса - `SPI0`.
Для корректной работы аппаратного SPI микроконтроллер так же использует выводы P1_3 при работе SPI1 и P0_3 при работе SPI0. В связи с этим данные выводы недоступны для использования при работе соответствующего SPI.
### I2C
Интерфейс I2C1 доступен на выводах P1_12, P1_13, для работы с ним используется экземпляр класса под названием `Wire`.
Интерфейс I2C0 доступен на выводах P0_9, P0_10, используемый экземпляр класса - `Wire1`.
Интерфейс I2C1 доступен на выводах SDA, SCL и P1_12, P1_13, для работы с ним используется экземпляр класса под названием `Wire`.
Интерфейс I2C0 доступен на выводах P0_9, P0_10, используемый экземпляр класса - `Wire0`.

View File

@ -1,9 +1,9 @@
# ELSOMIK
Особенности работы с платой ELSOMIK в среде программирования ArduinoIDE.
### Функциональное назначение выводов платы ELSOMIK OEM
![Elsomik_OEM_pinout.png](Elsomik_OEM_pinout.png)
![pinout_Elsomik_OEM.png](pinout_ElsomikOEM.png)
### Функциональное назначение выводов платы ELSOMIK SE
![Elsomik_SE_pinout.png](Elsomik_SE_pinout.png)
![pinout_Elsomik_SE.png](pinout_ElsomikSE.png)
### Загрузка скетчей
На плате отсутствуют встроенные преобразователи, позволяющие загружать скетчи по USB через COM-порт, однако каждая плата поставляется с предварительно записанным начальным загрузчиком. Для записи скетчей через USB потребуется использование внешнего USB-UART преобразователя, подключаемого к выводам платы P0_5 (RX0) и P0_6 (TX0), которые соответствуют интерфейсу UART0.
@ -33,6 +33,7 @@
|P0_9|A5|
|P0_11|A6|
|P0_13|A7|
#### ШИМ
На плате ELSOMIK в ArduinoIDE доступно 8 выводов для формирования ШИМ-сигнала. Генерация сигнала осуществляется с помощью 32-битного таймера. Выводы, подключенные к одному и тому же таймеру, выдают ШИМ-сигнал одинаковой частоты.
Доступные выводы:
@ -69,9 +70,9 @@
### SPI
Интерфейс SPI1 доступен на выводах P1_0, P1_1, P1_2. Для работы с ним используется экземпляр класса под названием `SPI`.
Интерфейс SPI0 доступен на выводах P0_0, P0_1, P0_2. Используемый экземпляр класса - `SPI1`.
Интерфейс SPI0 доступен на выводах P0_0, P0_1, P0_2. Используемый экземпляр класса - `SPI0`.
Для корректной работы аппаратного SPI микроконтроллер так же использует выводы P1_3 при работе SPI1 и P0_3 при работе SPI0. В связи с этим данные выводы недоступны для использования при работе соответствующего SPI.
### I2C
Интерфейс I2C1 доступен на выводах P1_12, P1_13, для работы с ним используется экземпляр класса под названием `Wire`.
Интерфейс I2C0 доступен на выводах P0_9, P0_10, используемый экземпляр класса - `Wire1`.
Интерфейс I2C0 доступен на выводах P0_9, P0_10, используемый экземпляр класса - `Wire0`.

View File

@ -1,7 +1,7 @@
# ELBEAR ACE-NANO
Особенности работы с платами ELBEAR ACE-NANO в среде программирования ArduinoIDE.
### Функциональное назначение выводов
![Pinout_nano](Pinout_nano.PNG)
![nano_pinout](nano_pinout.PNG)
### Цифровые выводы
На плате ELBEAR ACE-NANO доступен встроенный светодиод. Для его использования необходимо воспользоваться макросом `LED_BUILTIN`, передавая его в качестве аргумента функции вместо номера цифрового вывода. Макросу соответствует номер вывода D22.
### Аналоговые выводы
@ -10,6 +10,7 @@
Для использования вывода в качестве цифрового нужно перевести переключатель в положение ON. В этом случае напряжение с вывода платы передается на микроконтроллер без изменений.
Выводы А4...А7 используют один и тот же канал АЦП, поэтому не могут использоваться одновременно.
Таблица соответствия выводов платы и номера DIP-переключателя представлена ниже. Переключатель 5 относится сразу к четырем аналоговым выводам - А4...А7.
|Вывод|Номер переключателя|
|---------|---------|
|А0|1|
@ -20,9 +21,10 @@
|А5|5|
|А6|5|
|А7|5|
#### ШИМ
На плате ELBEAR ACE-NANO доступно 8 выводов для формирования ШИМ-сигнала: D3, D5, D6, D9...D13. Генерация сигнала осуществляется с помощью 32-битного таймера. Выводы D3, D5, D6, D9 подключены к таймеру 1, выводы D10...D13 подключены к таймеру 2. Выводы, подключенные к одному и тому же таймеру, выдают ШИМ-сигнал одинаковой частоты.
Цифровые выводы D9, D10 не могут быть использованы для генерации ШИМ, если одновременно активен интерфейс SPI (при использовании экземпляра `SPI` недоступен ШИМ на выводе D10, при использовании экземпляра `SPI1` - на выводе D9). Это ограничение связано с особенностями работы микроконтроллера. Ограничение не распространяется на использование D9, D10 в качестве цифрового вывода при активном SPI.
Цифровые выводы D9, D10 не могут быть использованы для генерации ШИМ, если одновременно активен интерфейс SPI (при использовании экземпляра `SPI` недоступен ШИМ на выводе D10, при использовании экземпляра `SPI0` - на выводе D9). Это ограничение связано с особенностями работы микроконтроллера. Ограничение не распространяется на использование D9, D10 в качестве цифрового вывода при активном SPI.
### Прерывания
На плате ELBEAR ACE-NANO доступно 8 прерываний, настраиваемых функцией `void attachInterrupt(uint8_t interruptNum, void (*userFunc)(void), int mode)`:
@ -45,4 +47,10 @@
### SPI
Интерфейс SPI1 доступен на выводах D11, D12, D13. Для работы с ним используется экземпляр класса под названием `SPI`.
Интерфейс SPI0 доступен на выводах D3, D5, D6. Используемый экземпляр класса - `SPI1`.
Интерфейс SPI0 доступен на выводах D3, D5, D6. Используемый экземпляр класса - `SPI0`.
### I2C
Интерфейс I2C1 доступен на выводах A4 и A5, для работы с ним используется экземпляр класса под названием `Wire`.
## Драйверы
Для работы с платой по интерфейсу USB необходим драйвер для микросхемы CH343P, его можно скачать [здесь](https://www.wch-ic.com/downloads/CH343SER_ZIP.html).

BIN
docs/nano_pinout.PNG Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 300 KiB

BIN
docs/pinout_ElsomikOEM.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 310 KiB

BIN
docs/pinout_ElsomikSE.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 468 KiB

BIN
docs/pinout_uno.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 293 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.3 MiB

View File

@ -1,9 +1,11 @@
#include "SPI.h"
SPIClass SPI(1);
SPIClass SPI1(1);
#if SPI_COMMON_QTY > 1
SPIClass SPI1(0);
SPIClass SPI0(0);
#endif
// default interface
SPIClass& SPI = DEFAULT_SPI;
static uint8_t reverse_bits(uint8_t byte);

View File

@ -127,9 +127,11 @@ public:
void setClockDivider(uint8_t clockDiv);
};
extern SPIClass SPI;
#if SPI_COMMON_QTY > 1
extern SPIClass SPI1;
#if SPI_COMMON_QTY > 1
extern SPIClass SPI0;
#endif
// default interface
extern SPIClass& SPI;
#endif

View File

@ -287,15 +287,17 @@ void TwoWire::onRequest( void (*function)(void) )
extern "C" void __attribute__((optimize("O3"))) wire_interrupt_handler(uint8_t num)
{
if (num == 1)
twi_interruptHandler(Wire.getHandler());
twi_interruptHandler(Wire1.getHandler());
#if I2C_COMMON_QTY>1
else if (num == 0)
twi_interruptHandler(Wire1.getHandler());
twi_interruptHandler(Wire0.getHandler());
#endif
}
// ----------------------------- Preinstantiate Objects ----------------------------- //
TwoWire Wire = TwoWire(1);
#if I2C_COMMON_QTY>1
TwoWire Wire1 = TwoWire(0);
TwoWire Wire1 = TwoWire(1); // I2C1 is always available
#if I2C_COMMON_QTY > 1
TwoWire Wire0 = TwoWire(0); // I2C0 is available on some boards
#endif
// default interface
TwoWire& Wire = DEFAULT_WIRE;

View File

@ -90,9 +90,11 @@ class TwoWire : public Stream
void onRequest( void (*)(void) );
};
extern TwoWire Wire;
#if I2C_COMMON_QTY>1
extern TwoWire Wire1;
#if I2C_COMMON_QTY>1
extern TwoWire Wire0;
#endif
// default interface
extern TwoWire& Wire;
#endif

View File

@ -81,6 +81,7 @@ void additionalPinsDeinit(uint32_t PinNumber);
// UART
// available uarts quantity
#define SERIAL_PORT_QTY 2
#define DEFAULT_SERIAL Serial0
// ADC
#define MCU_ADC_RESOLUTION 12 // bits
@ -97,7 +98,7 @@ static inline __attribute__((always_inline)) bool digitalPinHasPWM(uint8_t p)
return false;
}
// return true if digitalPin configured as pwm
bool digitalPinPwmIsOn(uint8_t digitalPin);
int8_t 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
@ -105,6 +106,7 @@ HAL_TIMER32_CHANNEL_IndexTypeDef pwmPinToTimerChannel(uint32_t digPinNumber);
// SPI
#define SPI_COMMON_QTY 2
#define DEFAULT_SPI SPI1
#define PIN_SPI_SS 10
#define PIN_SPI_MOSI 11
@ -116,14 +118,14 @@ static const uint8_t MISO = PIN_SPI_MISO;
static const uint8_t SCK = PIN_SPI_SCK;
#define PIN_SPI1_SS 9
#define PIN_SPI1_MOSI 5
#define PIN_SPI1_MISO 3
#define PIN_SPI1_SCK 6
static const uint8_t SS1 = PIN_SPI1_SS;
static const uint8_t MOSI1 = PIN_SPI1_MOSI;
static const uint8_t MISO1 = PIN_SPI1_MISO;
static const uint8_t SCK1 = PIN_SPI1_SCK;
#define PIN_SPI0_SS 9
#define PIN_SPI0_MOSI 5
#define PIN_SPI0_MISO 3
#define PIN_SPI0_SCK 6
static const uint8_t SS0 = PIN_SPI0_SS;
static const uint8_t MOSI0 = PIN_SPI0_MOSI;
static const uint8_t MISO0 = PIN_SPI0_MISO;
static const uint8_t SCK0 = PIN_SPI0_SCK;
// config SEL_NSS1 to replace D10 to different controller pin,
// because NSS which is D9/D10 by default is needed to spi
@ -131,9 +133,10 @@ void spi_onBegin(uint8_t spiNum);
void spi_onEnd(uint8_t spiNum);
// I2C
#define I2C_COMMON_QTY 1
#define DEFAULT_WIRE Wire1 // use I2C1 by default
#define PIN_WIRE_SDA 18
#define PIN_WIRE_SCL 19
#define I2C_COMMON_QTY 1
static const uint8_t SDA = PIN_WIRE_SDA;
static const uint8_t SCL = PIN_WIRE_SCL;
// available frequencies

View File

@ -204,27 +204,27 @@ uint32_t analogInputToChannelNumber(uint32_t PinNumber)
}
// ---------------------- PWM ---------------------- //
// 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
__attribute__((noinline, section(".ram_text"))) bool digitalPinPwmIsOn(uint8_t digitalPin)
// return 1 if digitalPin configured as pwm and enabled,
// 0 if pwm on pin is disabled,
// -1 if pin doesn't support pwm
__attribute__((noinline, section(".ram_text"))) int8_t digitalPinPwmIsOn(uint8_t 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
if ((digitalPin==10)||(digitalPin==11)||(digitalPin==12)||(digitalPin==13))
config = PIN_GET_PAD_CONFIG(PORT_1_CFG, pinShift);
else
config = PIN_GET_PAD_CONFIG(PORT_0_CFG, pinShift);
if (config == 2)
return true;
return 1; // pwm is on
else
return 0; // pwm is off
}
return false;
return -1; // pin doesn't support pwm
}
// function is used only if digitalPinHasPWM() is true

View File

@ -76,6 +76,7 @@ static inline void additionalPinsDeinit(uint32_t PinNumber){}
// UART
// available uarts quantity
#define SERIAL_PORT_QTY 2
#define DEFAULT_SERIAL Serial0
// ADC
#define MCU_ADC_RESOLUTION 12 // bits
@ -92,7 +93,7 @@ static inline __attribute__((always_inline)) bool digitalPinHasPWM(uint8_t p)
return false;
}
// return true if digitalPin configured as pwm
bool digitalPinPwmIsOn(uint8_t digitalPin);
int8_t 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
@ -100,6 +101,7 @@ HAL_TIMER32_CHANNEL_IndexTypeDef pwmPinToTimerChannel(uint32_t digPinNumber);
// SPI
#define SPI_COMMON_QTY 2
#define DEFAULT_SPI SPI1
#define PIN_SPI_SS 10
#define PIN_SPI_MOSI 11
@ -110,14 +112,14 @@ static const uint8_t MOSI = PIN_SPI_MOSI;
static const uint8_t MISO = PIN_SPI_MISO;
static const uint8_t SCK = PIN_SPI_SCK;
#define PIN_SPI1_SS 9
#define PIN_SPI1_MOSI 5
#define PIN_SPI1_MISO 3
#define PIN_SPI1_SCK 6
static const uint8_t SS1 = PIN_SPI1_SS;
static const uint8_t MOSI1 = PIN_SPI1_MOSI;
static const uint8_t MISO1 = PIN_SPI1_MISO;
static const uint8_t SCK1 = PIN_SPI1_SCK;
#define PIN_SPI0_SS 9
#define PIN_SPI0_MOSI 5
#define PIN_SPI0_MISO 3
#define PIN_SPI0_SCK 6
static const uint8_t SS1 = PIN_SPI0_SS;
static const uint8_t MOSI1 = PIN_SPI0_MOSI;
static const uint8_t MISO1 = PIN_SPI0_MISO;
static const uint8_t SCK1 = PIN_SPI0_SCK;
// config SEL_NSS1 to replace D10 to different controller pin,
// because NSS which is D9/D10 by default is needed to spi
@ -125,9 +127,10 @@ void spi_onBegin(uint8_t spiNum);
void spi_onEnd(uint8_t spiNum);
// I2C
#define I2C_COMMON_QTY (1)
#define DEFAULT_WIRE Wire1 // use I2C1 by default
#define PIN_WIRE_SDA (18)
#define PIN_WIRE_SCL (19)
#define I2C_COMMON_QTY (1)
static const uint8_t SDA = PIN_WIRE_SDA;
static const uint8_t SCL = PIN_WIRE_SCL;
// available frequencies

View File

@ -167,26 +167,27 @@ uint32_t analogInputToChannelNumber(uint32_t PinNumber)
}
// ---------------------- PWM ---------------------- //
// use only if digitalPinHasPWM() == true
#define PWM_PIN_TO_PORT_NUMBER(pin) (((pin==10)||(pin==11)||(pin==12)||(pin==13)) ? 1:0)
// return true if digitalPin configured as pwm
__attribute__((noinline, section(".ram_text"))) bool digitalPinPwmIsOn(uint8_t digitalPin)
// return 1 if digitalPin configured as pwm and enabled,
// 0 if pwm on pin is disabled,
// -1 if pin doesn't support pwm
__attribute__((noinline, section(".ram_text"))) int8_t digitalPinPwmIsOn(uint8_t 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
if ((digitalPin==10)||(digitalPin==11)||(digitalPin==12)||(digitalPin==13))
config = PIN_GET_PAD_CONFIG(PORT_1_CFG, pinShift);
else
config = PIN_GET_PAD_CONFIG(PORT_0_CFG, pinShift);
if (config == 2)
return true;
return 1; // pwm is on
else
return 0; // pwm is off
}
return false;
return -1; // pin doesn't support pwm
}
// function is used only if digitalPinHasPWM() is true

View File

@ -109,6 +109,7 @@ static inline void additionalPinsDeinit(uint32_t PinNumber){}
// UART
// available uarts quantity
#define SERIAL_PORT_QTY 2
#define DEFAULT_SERIAL Serial0
// ADC
#define MCU_ADC_RESOLUTION 12 // bits
@ -122,7 +123,7 @@ 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);
int8_t 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
@ -130,6 +131,7 @@ HAL_TIMER32_CHANNEL_IndexTypeDef pwmPinToTimerChannel(uint32_t digPinNumber);
// SPI
#define SPI_COMMON_QTY 2
#define DEFAULT_SPI SPI1
#define PIN_SPI_SS P1_3
#define PIN_SPI_MOSI P1_1
@ -140,14 +142,14 @@ static const uint8_t MOSI = PIN_SPI_MOSI;
static const uint8_t MISO = PIN_SPI_MISO;
static const uint8_t SCK = PIN_SPI_SCK;
#define PIN_SPI1_SS P0_3
#define PIN_SPI1_MOSI P0_1
#define PIN_SPI1_MISO P0_0
#define PIN_SPI1_SCK P0_2
static const uint8_t SS1 = PIN_SPI1_SS;
static const uint8_t MOSI1 = PIN_SPI1_MOSI;
static const uint8_t MISO1 = PIN_SPI1_MISO;
static const uint8_t SCK1 = PIN_SPI1_SCK;
#define PIN_SPI0_SS P0_3
#define PIN_SPI0_MOSI P0_1
#define PIN_SPI0_MISO P0_0
#define PIN_SPI0_SCK P0_2
static const uint8_t SS1 = PIN_SPI0_SS;
static const uint8_t MOSI1 = PIN_SPI0_MOSI;
static const uint8_t MISO1 = PIN_SPI0_MISO;
static const uint8_t SCK1 = PIN_SPI0_SCK;
// check if pwm is used on spi pins
void spi_onBegin(uint8_t spiNum);
@ -155,12 +157,13 @@ static inline void spi_onEnd(uint8_t spiNum){}
// I2C
#define I2C_COMMON_QTY 2
// Wire (I2C1)
#define DEFAULT_WIRE Wire0 // use I2C0 by default
// Wire1 (I2C1)
#define PIN_WIRE_SDA P1_12
#define PIN_WIRE_SCL P1_13
static const uint8_t SDA = PIN_WIRE_SDA;
static const uint8_t SCL = PIN_WIRE_SCL;
// Wire1 (I2C0)
// Wire0 (I2C0)
#define PIN_WIRE_SDA1 P0_9
#define PIN_WIRE_SCL1 P0_10
static const uint8_t SDA1 = PIN_WIRE_SDA1;

View File

@ -105,27 +105,25 @@ uint32_t analogInputToChannelNumber(uint32_t PinNumber)
}
// ---------------------- PWM ---------------------- //
// use only if digitalPinHasPWM() == true
#define PWM_PIN_TO_PORT_NUMBER(pin) (((pin) & 16) ? 1 : 0)
// use only if digitalPinHasPWM() == true
// return true if digitalPin configured as pwm
__attribute__((noinline, section(".ram_text"))) bool digitalPinPwmIsOn(uint8_t digitalPin)
// return 1 if digitalPin configured as pwm and enabled,
// 0 if pwm on pin is disabled,
// -1 if pin doesn't support pwm
__attribute__((noinline, section(".ram_text"))) int8_t digitalPinPwmIsOn(uint8_t digitalPin)
{
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);
if ((digitalPin & 16) == 0)
config = PIN_GET_PAD_CONFIG(PORT_0_CFG, (digitalPin & 0x3));
else
config = PIN_GET_PAD_CONFIG(PORT_1_CFG, pinShift);
config = PIN_GET_PAD_CONFIG(PORT_1_CFG, (digitalPin & 0x3));
if (config == 2)
return true;
return 1; // pwm is on
else
return 0; // pwm is off
}
return false;
return -1; // pin doesn't support pwm
}
// function is used only if digitalPinHasPWM() is true

View File

@ -122,6 +122,7 @@ static inline void additionalPinsDeinit(uint32_t PinNumber){}
// UART
// available uarts quantity
#define SERIAL_PORT_QTY 2
#define DEFAULT_SERIAL Serial0
// ADC
#define MCU_ADC_RESOLUTION 12 // bits
@ -135,7 +136,7 @@ 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);
int8_t 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
@ -143,6 +144,7 @@ HAL_TIMER32_CHANNEL_IndexTypeDef pwmPinToTimerChannel(uint32_t digPinNumber);
// SPI
#define SPI_COMMON_QTY 2
#define DEFAULT_SPI SPI1
#define PIN_SPI_SS P1_3
#define PIN_SPI_MOSI P1_1
@ -153,14 +155,14 @@ static const uint8_t MOSI = PIN_SPI_MOSI;
static const uint8_t MISO = PIN_SPI_MISO;
static const uint8_t SCK = PIN_SPI_SCK;
#define PIN_SPI1_SS P0_3
#define PIN_SPI1_MOSI P0_1
#define PIN_SPI1_MISO P0_0
#define PIN_SPI1_SCK P0_2
static const uint8_t SS1 = PIN_SPI1_SS;
static const uint8_t MOSI1 = PIN_SPI1_MOSI;
static const uint8_t MISO1 = PIN_SPI1_MISO;
static const uint8_t SCK1 = PIN_SPI1_SCK;
#define PIN_SPI0_SS P0_3
#define PIN_SPI0_MOSI P0_1
#define PIN_SPI0_MISO P0_0
#define PIN_SPI0_SCK P0_2
static const uint8_t SS0 = PIN_SPI0_SS;
static const uint8_t MOSI0 = PIN_SPI0_MOSI;
static const uint8_t MISO0 = PIN_SPI0_MISO;
static const uint8_t SCK0 = PIN_SPI0_SCK;
// check if pwm is used on spi pins
void spi_onBegin(uint8_t spiNum);
@ -168,12 +170,13 @@ static inline void spi_onEnd(uint8_t spiNum){}
// I2C
#define I2C_COMMON_QTY 2
// Wire (I2C1)
#define DEFAULT_WIRE Wire0 // use I2C0 by default
// Wire1 (I2C1)
#define PIN_WIRE_SDA P1_12
#define PIN_WIRE_SCL P1_13
static const uint8_t SDA = PIN_WIRE_SDA;
static const uint8_t SCL = PIN_WIRE_SCL;
// Wire1 (I2C0)
// Wire0 (I2C0)
#define PIN_WIRE_SDA1 P0_9
#define PIN_WIRE_SCL1 P0_10
static const uint8_t SDA1 = PIN_WIRE_SDA1;

View File

@ -101,27 +101,25 @@ uint32_t analogInputToChannelNumber(uint32_t PinNumber)
}
// ---------------------- PWM ---------------------- //
// use only if digitalPinHasPWM() == true
#define PWM_PIN_TO_PORT_NUMBER(pin) (((pin) & 16) ? 1 : 0)
// use only if digitalPinHasPWM() == true
// return true if digitalPin configured as pwm
__attribute__((noinline, section(".ram_text"))) bool digitalPinPwmIsOn(uint8_t digitalPin)
// return 1 if digitalPin configured as pwm and enabled,
// 0 if pwm on pin is disabled,
// -1 if pin doesn't support pwm
__attribute__((noinline, section(".ram_text"))) int8_t digitalPinPwmIsOn(uint8_t digitalPin)
{
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);
if ((digitalPin & 16) == 0)
config = PIN_GET_PAD_CONFIG(PORT_0_CFG, (digitalPin & 3));
else
config = PIN_GET_PAD_CONFIG(PORT_1_CFG, pinShift);
config = PIN_GET_PAD_CONFIG(PORT_1_CFG, (digitalPin & 3));
if (config == 2)
return true;
return 1; // pwm is on
else
return 0; // pwm is off
}
return false;
return -1; // pin doesn't support pwm
}
// function is used only if digitalPinHasPWM() is true