Проверка в analogWrite(), добавление экземпляров для Wire, SPI, Serial
В функции analogWrite() добавлена проверка, включен ли уже канал - если включен, применяется новое значение только если оно отличается от текущего. В модулях Wire, SPI, Serial теперь по два экземпляра в соответствии с периферией МК. Для каждой платы задается свой экземпляр, используемый по умолчанию Co-authored-by: KLASSENTS <klassen@elron.tech> Co-committed-by: KLASSENTS <klassen@elron.tech>
@ -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))
|
||||
{
|
||||
|
||||
@ -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));
|
||||
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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));
|
||||
|
||||
@ -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);
|
||||
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
# ELBEAR ACE-UNO
|
||||
Особенности работы с платами ELBEAR ACE-UNO в среде программирования ArduinoIDE.
|
||||
### Функциональное назначение выводов
|
||||

|
||||

|
||||
### Цифровые выводы
|
||||
На плате 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).
|
||||
|
Before Width: | Height: | Size: 340 KiB |
|
Before Width: | Height: | Size: 470 KiB |
|
Before Width: | Height: | Size: 1.0 MiB |
@ -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`.
|
||||
@ -1,9 +1,9 @@
|
||||
# ELSOMIK
|
||||
Особенности работы с платой ELSOMIK в среде программирования ArduinoIDE.
|
||||
### Функциональное назначение выводов платы ELSOMIK OEM
|
||||

|
||||

|
||||
### Функциональное назначение выводов платы ELSOMIK SE
|
||||

|
||||

|
||||
|
||||
### Загрузка скетчей
|
||||
На плате отсутствуют встроенные преобразователи, позволяющие загружать скетчи по 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`.
|
||||
@ -1,7 +1,7 @@
|
||||
# ELBEAR ACE-NANO
|
||||
Особенности работы с платами ELBEAR ACE-NANO в среде программирования ArduinoIDE.
|
||||
### Функциональное назначение выводов
|
||||

|
||||

|
||||
### Цифровые выводы
|
||||
На плате 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
|
After Width: | Height: | Size: 300 KiB |
BIN
docs/pinout_ElsomikOEM.png
Normal file
|
After Width: | Height: | Size: 310 KiB |
BIN
docs/pinout_ElsomikSE.png
Normal file
|
After Width: | Height: | Size: 468 KiB |
BIN
docs/pinout_uno.png
Normal file
|
After Width: | Height: | Size: 293 KiB |
|
Before Width: | Height: | Size: 2.3 MiB |
@ -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);
|
||||
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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
|
||||
|
||||