v0.5.1
- в модулях Wire, SPI, Serial приведена в соответствие нумерация используемых экземпляров и периферии микроконтроллера. - в функции analogWrite() перед запуском ШИМ проверяется, не запущен ли уже указанный канал. - добавлена возможность переопределения функции main() в скетчах. - при старте программы задается граница кэшируемой области SPIFI в соответствии с размером текущего исполняемого кода. - исправление выявленных ошибок. Co-authored-by: KLASSENTS <klassen@elron.tech> Co-committed-by: KLASSENTS <klassen@elron.tech>
@ -42,11 +42,15 @@
|
|||||||
Для работы доступно два последовательных интерфейса. Нулевой интерфейс используется экземпляром класса `Serial`. Информации в Монитор порта в Arduino IDE поступает через него. Первый интерфейс используется экземпляром класса `Serial1`. Выводы, на которых доступны указанные интерфейсы, перечислены в описании отдельных плат.
|
Для работы доступно два последовательных интерфейса. Нулевой интерфейс используется экземпляром класса `Serial`. Информации в Монитор порта в Arduino IDE поступает через него. Первый интерфейс используется экземпляром класса `Serial1`. Выводы, на которых доступны указанные интерфейсы, перечислены в описании отдельных плат.
|
||||||
Доступны следующие макросы для настройки режима работы каждого интерфейса в функции `Serial.begin()`: `SERIAL_7N1`, `SERIAL_8N1`, `SERIAL_7N2`, `SERIAL_8N2`, `SERIAL_7E1`, `SERIAL_8E1`, `SERIAL_7E2`, `SERIAL_8E2`, `SERIAL_7O1`, `SERIAL_8O1`, `SERIAL_7O2`, `SERIAL_8O2`. Здесь длина данных - 7 или 8 бит; бит четности - нет(N), четный(E), нечетный(O); стоп бит - 1 или 2 бита.
|
Доступны следующие макросы для настройки режима работы каждого интерфейса в функции `Serial.begin()`: `SERIAL_7N1`, `SERIAL_8N1`, `SERIAL_7N2`, `SERIAL_8N2`, `SERIAL_7E1`, `SERIAL_8E1`, `SERIAL_7E2`, `SERIAL_8E2`, `SERIAL_7O1`, `SERIAL_8O1`, `SERIAL_7O2`, `SERIAL_8O2`. Здесь длина данных - 7 или 8 бит; бит четности - нет(N), четный(E), нечетный(O); стоп бит - 1 или 2 бита.
|
||||||
|
|
||||||
|
### Переопределение функции main
|
||||||
|
В ArduinoIDE доступна возможность определить пользовательскую функцию `main()` в скетче. Для этого необходимо удалить из скетча функции `setup()` и `loop()` и определить свою функцию `int main(void){}`. Чтобы весь функционал пакета поддержки работал корректно, перед заходом в бесконечный цикл необходимо вызвать функцию `post_init()`, внутри которой глобально разрешаются прерывания. Пример переопределения представлен ниже.
|
||||||
|

|
||||||
|
|
||||||
### Предупреждения об ошибках
|
### Предупреждения об ошибках
|
||||||
Если в скетче используется интерфейс `Serial`, при возникновении ошибок при использовании какой-либо функции из пакета в порт может передаваться сообщение об этой ошибке с пояснением. Например, если в функцию будет передан некорректный номер цифрового вывода, предупреждение об этом появится в подключенном com порту.
|
Если в скетче используется интерфейс `Serial`, при возникновении ошибок при использовании какой-либо функции из пакета в порт может передаваться сообщение об этой ошибке с пояснением. Например, если в функцию будет передан некорректный номер цифрового вывода, предупреждение об этом появится в подключенном com порту.
|
||||||
По умолчанию вывод предупреждений включен. Если интерфейс `Serial` используется для коммуникации с другим устройством, вывод предупреждений можно отключить. Для этого в самом начале функции `void setup()` необходимо вызвать макрос `DISABLE_ERROR_MESSAGES();`. Вывод предупреждений можно включить обратно, вызвав макрос `ENABLE_ERROR_MESSAGES();` в любом месте программы.
|
По умолчанию вывод предупреждений включен. Если интерфейс `Serial` используется для коммуникации с другим устройством, вывод предупреждений можно отключить. Для этого в самом начале функции `void setup()` необходимо вызвать макрос `DISABLE_ERROR_MESSAGES();`. Вывод предупреждений можно включить обратно, вызвав макрос `ENABLE_ERROR_MESSAGES();` в любом месте программы.
|
||||||
|
|
||||||
### Библиотеки, входящие в состав пакета
|
## Библиотеки, входящие в состав пакета
|
||||||
Входящие в состав пакета библиотеки используют периферию микроконтроллера MIK32 Амур и/или адаптированы для работы с ним.
|
Входящие в состав пакета библиотеки используют периферию микроконтроллера MIK32 Амур и/или адаптированы для работы с ним.
|
||||||
|
|
||||||
|Библиотека|Описание|Заметки|
|
|Библиотека|Описание|Заметки|
|
||||||
@ -97,7 +101,7 @@
|
|||||||
## Протестированные модули
|
## Протестированные модули
|
||||||
Список модулей и шилдов, работа которых была протестирована на платах, входящих в состав пакета поддержки, доступен [здесь](./docs/tested_shields.md).
|
Список модулей и шилдов, работа которых была протестирована на платах, входящих в состав пакета поддержки, доступен [здесь](./docs/tested_shields.md).
|
||||||
|
|
||||||
# Режим отладки
|
## Режим отладки
|
||||||
Для всех плат, входящих в состав пакета, доступен режим отладки скетча в ArduinoIDE версии 2. Подготовка к работе в режиме отладки описана в [инструкции.](./docs/debug_description.md)
|
Для всех плат, входящих в состав пакета, доступен режим отладки скетча в ArduinoIDE версии 2. Подготовка к работе в режиме отладки описана в [инструкции.](./docs/debug_description.md)
|
||||||
|
|
||||||
# Полезные ссылки
|
# Полезные ссылки
|
||||||
|
|||||||
@ -8,10 +8,13 @@
|
|||||||
#include "wiring_LL.h"
|
#include "wiring_LL.h"
|
||||||
|
|
||||||
// HardwareSerial class objects for use in Arduino IDE
|
// HardwareSerial class objects for use in Arduino IDE
|
||||||
HardwareSerial Serial(0);
|
HardwareSerial Serial0(0);
|
||||||
#if SERIAL_PORT_QTY > 1
|
#if SERIAL_PORT_QTY > 1
|
||||||
HardwareSerial Serial1(1);
|
HardwareSerial Serial1(1);
|
||||||
#endif
|
#endif
|
||||||
|
// default interface
|
||||||
|
HardwareSerial& Serial = DEFAULT_SERIAL;
|
||||||
|
|
||||||
|
|
||||||
void serialEvent() __attribute__((weak));
|
void serialEvent() __attribute__((weak));
|
||||||
bool Serial0_available() __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)
|
if (uartNumInt == 0)
|
||||||
{
|
{
|
||||||
Serial.rx_complete_irq();
|
Serial0.rx_complete_irq();
|
||||||
}
|
}
|
||||||
else if ((uartNumInt == 1) && (SERIAL_PORT_QTY > 1))
|
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")));
|
inline void rx_complete_irq(void) __attribute__((always_inline, optimize("O3")));
|
||||||
};
|
};
|
||||||
|
|
||||||
extern HardwareSerial Serial;
|
extern HardwareSerial Serial0;
|
||||||
#if SERIAL_PORT_QTY > 1
|
#if SERIAL_PORT_QTY > 1
|
||||||
extern HardwareSerial Serial1;
|
extern HardwareSerial Serial1;
|
||||||
#endif
|
#endif
|
||||||
|
// default interface
|
||||||
|
extern HardwareSerial& Serial;
|
||||||
|
|
||||||
extern void serialEventRun(void) __attribute__((weak));
|
extern void serialEventRun(void) __attribute__((weak));
|
||||||
|
|
||||||
|
|||||||
@ -3,6 +3,40 @@
|
|||||||
#include "mik32_hal_irq.h"
|
#include "mik32_hal_irq.h"
|
||||||
#include "Arduino.h"
|
#include "Arduino.h"
|
||||||
|
|
||||||
|
// --------------------- flash cache limit --------------------- //
|
||||||
|
#include "mcu32_memory_map.h"
|
||||||
|
#include "mik32_hal_spifi_w25.h"
|
||||||
|
|
||||||
|
// define board flash size
|
||||||
|
#if defined(ARDUINO_START_MIK32_V1)
|
||||||
|
#define FLASH_SIZE 0x00400000 // 4 Mb
|
||||||
|
#elif defined(ARDUINO_ACE_UNO_16MB)
|
||||||
|
#define FLASH_SIZE 0x01000000 // 16 Mb
|
||||||
|
#elif defined(ARDUINO_ACE_UNO_32MB)
|
||||||
|
#define FLASH_SIZE 0x02000000 // 32 Mb
|
||||||
|
#else
|
||||||
|
#define FLASH_SIZE 0x00800000 // 8 Mb
|
||||||
|
#endif
|
||||||
|
// define margin from flash end
|
||||||
|
#define FLASH_END_OFFSET 0x1000
|
||||||
|
|
||||||
|
// values from ld script
|
||||||
|
extern uint8_t __RODATA__[];
|
||||||
|
|
||||||
|
// RAM-function for updating flash cache limit by app size to improve performance
|
||||||
|
__attribute__((section(".ram_text"))) void updateCacheLimit(void)
|
||||||
|
{
|
||||||
|
uint32_t new_limit = (uintptr_t)__RODATA__ - SPIFI_BASE_ADDRESS;
|
||||||
|
// limit cache size by flash size with margin
|
||||||
|
if (new_limit > (FLASH_SIZE - FLASH_END_OFFSET))
|
||||||
|
new_limit = FLASH_SIZE - FLASH_END_OFFSET;
|
||||||
|
|
||||||
|
uint32_t MCMDbackup = SPIFI_CONFIG->MCMD; // save current value from MCMD
|
||||||
|
SPIFI_CONFIG->STAT |= SPIFI_CONFIG_STAT_RESET_M; // reset MCMD mode for writing new CLIMIT
|
||||||
|
SPIFI_CONFIG->CLIMIT = new_limit; // set new CLIMIT
|
||||||
|
SPIFI_CONFIG->MCMD = MCMDbackup; // restore MCMD value
|
||||||
|
}
|
||||||
|
|
||||||
// --------------------- init --------------------- //
|
// --------------------- init --------------------- //
|
||||||
// called from crt0.S before constructors initialization
|
// called from crt0.S before constructors initialization
|
||||||
extern "C" void SystemInit(void)
|
extern "C" void SystemInit(void)
|
||||||
@ -20,6 +54,8 @@ extern "C" void SystemInit(void)
|
|||||||
|
|
||||||
// for delays
|
// for delays
|
||||||
SysTick_Init();
|
SysTick_Init();
|
||||||
|
// update flash cache limit by app size
|
||||||
|
updateCacheLimit();
|
||||||
}
|
}
|
||||||
|
|
||||||
// called after setup()
|
// called after setup()
|
||||||
|
|||||||
@ -7,6 +7,7 @@
|
|||||||
void initVariant() __attribute__((weak));
|
void initVariant() __attribute__((weak));
|
||||||
void initVariant() { }
|
void initVariant() { }
|
||||||
|
|
||||||
|
extern "C" int main(void) __attribute__((weak));
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
initVariant(); // for freeRTOS
|
initVariant(); // for freeRTOS
|
||||||
@ -18,5 +19,3 @@ int main()
|
|||||||
loop();
|
loop();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -21,11 +21,10 @@ SECTIONS {
|
|||||||
*crt0.S.o(.text .text.*)
|
*crt0.S.o(.text .text.*)
|
||||||
*(.text.smallsysteminit)
|
*(.text.smallsysteminit)
|
||||||
*(.text.SmallSystemInit)
|
*(.text.SmallSystemInit)
|
||||||
/*. = ORIGIN(rom) + 0xC0;*/
|
|
||||||
/*KEEP(*crt0.S.o(.trap_text))*/
|
|
||||||
|
|
||||||
*(.text)
|
*(.text)
|
||||||
*(.text.*)
|
*(.text.*)
|
||||||
|
PROVIDE(__RODATA__ = .);
|
||||||
*(.rodata)
|
*(.rodata)
|
||||||
*(.rodata.*)
|
*(.rodata.*)
|
||||||
. = ALIGN(CL_SIZE);
|
. = ALIGN(CL_SIZE);
|
||||||
|
|||||||
@ -104,9 +104,23 @@ It is recommended to enable the timer in the following order:
|
|||||||
*/
|
*/
|
||||||
void analogWrite(uint32_t PinNumber, uint32_t writeVal)
|
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
|
// initialization of the required timer
|
||||||
htimer32.Instance = pwmPinToTimer(PinNumber);
|
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.PWM_Invert = TIMER32_CHANNEL_NON_INVERTED_PWM;
|
||||||
htimer32_channel.Mode = TIMER32_CHANNEL_MODE_PWM;
|
htimer32_channel.Mode = TIMER32_CHANNEL_MODE_PWM;
|
||||||
htimer32_channel.CaptureEdge = TIMER32_CHANNEL_CAPTUREEDGE_RISING;
|
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;
|
htimer32_channel.Noise = TIMER32_CHANNEL_FILTER_OFF;
|
||||||
HAL_Timer32_Channel_Init(&htimer32_channel);
|
HAL_Timer32_Channel_Init(&htimer32_channel);
|
||||||
|
|
||||||
@ -137,7 +151,7 @@ void analogWrite(uint32_t PinNumber, uint32_t writeVal)
|
|||||||
HAL_Timer32_Start(&htimer32);
|
HAL_Timer32_Start(&htimer32);
|
||||||
pwmIsInited++; // increase inited channels qty
|
pwmIsInited++; // increase inited channels qty
|
||||||
}
|
}
|
||||||
else
|
else // pin doesn't have pwm
|
||||||
ErrorMsgHandler("analogWrite(): invalid pwm pin number");
|
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;
|
- Write 0 to the INT_CLEAR register;
|
||||||
- Set TIM_EN to 0.
|
- Set TIM_EN to 0.
|
||||||
*/
|
*/
|
||||||
|
// use only if digitalPinPwmIsOn(PinNumber) > 0
|
||||||
void analogWriteStop(uint32_t PinNumber)
|
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
|
// load the timer address and channel number corresponding to the specified pin
|
||||||
htimer32.Instance = pwmPinToTimer(PinNumber);
|
htimer32.Instance = pwmPinToTimer(PinNumber);
|
||||||
htimer32_channel.TimerInstance = htimer32.Instance;
|
|
||||||
htimer32_channel.ChannelIndex = pwmPinToTimerChannel(PinNumber);
|
htimer32_channel.ChannelIndex = pwmPinToTimerChannel(PinNumber);
|
||||||
|
htimer32.Instance->CHANNELS[htimer32_channel.ChannelIndex].OCR = 0;
|
||||||
|
htimer32_channel.TimerInstance = htimer32.Instance;
|
||||||
|
|
||||||
// deinit channel
|
// deinit channel
|
||||||
HAL_Timer32_Channel_DeInit(&htimer32_channel);
|
HAL_Timer32_Channel_DeInit(&htimer32_channel);
|
||||||
pwmIsInited--; // decrease inited channels qty
|
pwmIsInited--; // decrease inited channels qty
|
||||||
|
|||||||
@ -56,25 +56,23 @@ enum BitOrder
|
|||||||
#define NOT_AN_INTERRUPT -1
|
#define NOT_AN_INTERRUPT -1
|
||||||
|
|
||||||
// Math
|
// Math
|
||||||
#ifdef __cplusplus
|
#include <stdlib.h>
|
||||||
#include <algorithm>
|
// undefine stdlib's abs if encountered
|
||||||
using std::min;
|
#ifdef abs
|
||||||
using std::max;
|
#undef abs
|
||||||
#else // C
|
#endif
|
||||||
#include <stdlib.h>
|
#ifndef abs
|
||||||
#ifndef abs
|
#define abs(x) ((x)>0?(x):-(x))
|
||||||
#define abs(x) ((x)>0?(x):-(x))
|
#endif // abs
|
||||||
#endif // abs
|
|
||||||
|
|
||||||
#ifndef min
|
#ifndef min
|
||||||
#define min(a,b) ((a)<(b)?(a):(b))
|
#define min(a,b) ((a)<(b)?(a):(b))
|
||||||
#endif // min
|
#endif // min
|
||||||
|
|
||||||
#ifndef max
|
#ifndef max
|
||||||
#define max(a,b) ((a)>(b)?(a):(b))
|
#define max(a,b) ((a)>(b)?(a):(b))
|
||||||
#endif // max
|
#endif // max
|
||||||
|
|
||||||
#endif // __cplusplus
|
|
||||||
#define constrain(amt,low,high) ((amt)<(low)?(low):((amt)>(high)?(high):(amt)))
|
#define constrain(amt,low,high) ((amt)<(low)?(low):((amt)>(high)?(high):(amt)))
|
||||||
#define radians(deg) ((deg)*DEG_TO_RAD)
|
#define radians(deg) ((deg)*DEG_TO_RAD)
|
||||||
#define degrees(rad) ((rad)*RAD_TO_DEG)
|
#define degrees(rad) ((rad)*RAD_TO_DEG)
|
||||||
|
|||||||
@ -37,8 +37,8 @@ void pinMode(uint32_t PinNumber, uint32_t PinMode)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (digitalPinHasPWM(PinNumber))
|
if (digitalPinPwmIsOn(PinNumber))
|
||||||
// if the pin can use PWM, disable PWM
|
// if the pin use PWM, disable PWM
|
||||||
analogWriteStop(PinNumber);
|
analogWriteStop(PinNumber);
|
||||||
|
|
||||||
// determine the port and the pin number in the port
|
// 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 (digitalPinPwmIsOn(PinNumber))
|
||||||
// if the pin can use PWM, disable PWM
|
// if the pin use PWM, disable PWM
|
||||||
analogWriteStop(PinNumber);
|
analogWriteStop(PinNumber);
|
||||||
|
|
||||||
if (Val == HIGH)
|
if (Val == HIGH)
|
||||||
@ -123,7 +123,7 @@ __attribute__((noinline, section(".ram_text"))) int digitalRead(uint32_t PinNumb
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (digitalPinPwmIsOn(PinNumber))
|
if (digitalPinPwmIsOn(PinNumber))
|
||||||
// if the pin can use PWM, disable PWM
|
// if the pin use PWM, disable PWM
|
||||||
analogWriteStop(PinNumber);
|
analogWriteStop(PinNumber);
|
||||||
|
|
||||||
return GPIO_READ_PIN(digitalPinToPort(PinNumber), digitalPinToBitMask(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 (digitalPinPwmIsOn(PinNumber))
|
||||||
// if the pin can use PWM, disable PWM
|
// if the pin use PWM, disable PWM
|
||||||
analogWriteStop(PinNumber);
|
analogWriteStop(PinNumber);
|
||||||
|
|
||||||
GPIO_TOGGLE_PIN(digitalPinToPort(PinNumber), digitalPinToBitMask(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");
|
ErrorMsgHandler("pulseIn(): pin number exceeds the total number of pins");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if (digitalPinHasPWM(pin))
|
if (digitalPinPwmIsOn(pin) > 0)
|
||||||
// pwm off
|
// pwm off
|
||||||
analogWriteStop(pin);
|
analogWriteStop(pin);
|
||||||
|
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
# ELBEAR ACE-UNO
|
# ELBEAR ACE-UNO
|
||||||
Особенности работы с платами ELBEAR ACE-UNO в среде программирования ArduinoIDE.
|
Особенности работы с платами ELBEAR ACE-UNO в среде программирования ArduinoIDE.
|
||||||
### Функциональное назначение выводов
|
### Функциональное назначение выводов
|
||||||

|

|
||||||
### Цифровые выводы
|
### Цифровые выводы
|
||||||
На плате ELBEAR ACE-UNO доступны встроенные светодиод и кнопка. Для их использования необходимо воспользоваться макросами `LED_BUILTIN` и `BTN_BUILTIN`, передавая их в качестве аргументов функции вместо номера цифрового вывода. Макросу `LED_BUILTIN` соответствует номер вывода D22, а макросу `BTN_BUILTIN` - D23.
|
На плате ELBEAR ACE-UNO доступны встроенные светодиод и кнопка. Для их использования необходимо воспользоваться макросами `LED_BUILTIN` и `BTN_BUILTIN`, передавая их в качестве аргументов функции вместо номера цифрового вывода. Макросу `LED_BUILTIN` соответствует номер вывода D22, а макросу `BTN_BUILTIN` - D23.
|
||||||
### Аналоговые выводы
|
### Аналоговые выводы
|
||||||
@ -9,6 +9,7 @@
|
|||||||
Для использования вывода в качестве аналогового необходимо перевести соответствующий DIP-переключатель, расположенный рядом с аналоговыми выводами, в положение OFF. В этом режиме внешнее напряжение, подаваемое на вывод, будет понижаться резистивным делителем перед подачей на микроконтроллер.
|
Для использования вывода в качестве аналогового необходимо перевести соответствующий DIP-переключатель, расположенный рядом с аналоговыми выводами, в положение OFF. В этом режиме внешнее напряжение, подаваемое на вывод, будет понижаться резистивным делителем перед подачей на микроконтроллер.
|
||||||
Для использования вывода в качестве цифрового нужно перевести переключатель в положение ON. В этом случае напряжение с вывода платы передается на микроконтроллер без изменений.
|
Для использования вывода в качестве цифрового нужно перевести переключатель в положение ON. В этом случае напряжение с вывода платы передается на микроконтроллер без изменений.
|
||||||
Таблица соответствия выводов платы и номера DIP-переключателя представлена ниже. Переключатель 5 относится сразу к двум аналоговым выводам - А4, А5.
|
Таблица соответствия выводов платы и номера DIP-переключателя представлена ниже. Переключатель 5 относится сразу к двум аналоговым выводам - А4, А5.
|
||||||
|
|
||||||
|Вывод|Номер переключателя|
|
|Вывод|Номер переключателя|
|
||||||
|---------|---------|
|
|---------|---------|
|
||||||
|А0|1|
|
|А0|1|
|
||||||
@ -17,9 +18,10 @@
|
|||||||
|А3|4|
|
|А3|4|
|
||||||
|А4|5|
|
|А4|5|
|
||||||
|А5|5|
|
|А5|5|
|
||||||
|
|
||||||
#### ШИМ
|
#### ШИМ
|
||||||
На плате ELBEAR ACE-UNO доступно 8 выводов для формирования ШИМ-сигнала: D3, D5, D6, D9...D13. Генерация сигнала осуществляется с помощью 32-битного таймера. Выводы D3, D5, D6, D9 подключены к таймеру 1, выводы D10...D13 подключены к таймеру 2. Выводы, подключенные к одному и тому же таймеру, выдают ШИМ-сигнал одинаковой частоты.
|
На плате 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)`:
|
На плате ELBEAR ACE-UNO доступно 8 прерываний, настраиваемых функцией `void attachInterrupt(uint8_t interruptNum, void (*userFunc)(void), int mode)`:
|
||||||
|
|
||||||
@ -42,4 +44,10 @@
|
|||||||
|
|
||||||
### SPI
|
### SPI
|
||||||
Интерфейс SPI1 доступен на выводах D11, D12, D13. Для работы с ним используется экземпляр класса под названием `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|
|
|P0_15|7|
|
||||||
|
|
||||||
### Serial
|
### Serial
|
||||||
Интерфейс UART0 доступен на выводах P0_5, P0_6, для работы с ним используется экземпляр класса под названием `Serial`.
|
Интерфейс UART0 доступен на выводах RX, TX и P0_5, P0_6. Для работы с ним используется экземпляр класса под названием `Serial`.
|
||||||
Интерфейс UART1 доступен на выводах P1_8, P1_9, используемый экземпляр класса - `Serial1`.
|
Интерфейс UART1 доступен на выводах P1_8, P1_9, используемый экземпляр класса - `Serial1`.
|
||||||
USB-UART преобразователь, установленный на плате, поддерживает стандартные скорости UART до 57600 бод. Нестандартные скорости должны быть кратны
|
USB-UART преобразователь, установленный на плате, поддерживает стандартные скорости UART до 57600 бод. Нестандартные скорости должны быть кратны
|
||||||
12*32=384, например, 240000 бод, 768000 бод.
|
12*32=384, например, 240000 бод, 768000 бод.
|
||||||
|
|
||||||
### SPI
|
### SPI
|
||||||
Интерфейс SPI1 доступен на выводах P1_0, P1_1, P1_2. Для работы с ним используется экземпляр класса под названием `SPI`.
|
Интерфейс SPI1 доступен на выводах MOSI, MISO, CLK и 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.
|
Для корректной работы аппаратного SPI микроконтроллер так же использует выводы P1_3 при работе SPI1 и P0_3 при работе SPI0. В связи с этим данные выводы недоступны для использования при работе соответствующего SPI.
|
||||||
|
|
||||||
### I2C
|
### I2C
|
||||||
Интерфейс I2C1 доступен на выводах P1_12, P1_13, для работы с ним используется экземпляр класса под названием `Wire`.
|
Интерфейс I2C1 доступен на выводах SDA, SCL и P1_12, P1_13, для работы с ним используется экземпляр класса под названием `Wire`.
|
||||||
Интерфейс I2C0 доступен на выводах P0_9, P0_10, используемый экземпляр класса - `Wire1`.
|
Интерфейс I2C0 доступен на выводах P0_9, P0_10, используемый экземпляр класса - `Wire0`.
|
||||||
@ -1,9 +1,9 @@
|
|||||||
# ELSOMIK
|
# ELSOMIK
|
||||||
Особенности работы с платой ELSOMIK в среде программирования ArduinoIDE.
|
Особенности работы с платой ELSOMIK в среде программирования ArduinoIDE.
|
||||||
### Функциональное назначение выводов платы ELSOMIK OEM
|
### Функциональное назначение выводов платы ELSOMIK OEM
|
||||||

|

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

|

|
||||||
|
|
||||||
### Загрузка скетчей
|
### Загрузка скетчей
|
||||||
На плате отсутствуют встроенные преобразователи, позволяющие загружать скетчи по USB через COM-порт, однако каждая плата поставляется с предварительно записанным начальным загрузчиком. Для записи скетчей через USB потребуется использование внешнего USB-UART преобразователя, подключаемого к выводам платы P0_5 (RX0) и P0_6 (TX0), которые соответствуют интерфейсу UART0.
|
На плате отсутствуют встроенные преобразователи, позволяющие загружать скетчи по USB через COM-порт, однако каждая плата поставляется с предварительно записанным начальным загрузчиком. Для записи скетчей через USB потребуется использование внешнего USB-UART преобразователя, подключаемого к выводам платы P0_5 (RX0) и P0_6 (TX0), которые соответствуют интерфейсу UART0.
|
||||||
@ -33,6 +33,7 @@
|
|||||||
|P0_9|A5|
|
|P0_9|A5|
|
||||||
|P0_11|A6|
|
|P0_11|A6|
|
||||||
|P0_13|A7|
|
|P0_13|A7|
|
||||||
|
|
||||||
#### ШИМ
|
#### ШИМ
|
||||||
На плате ELSOMIK в ArduinoIDE доступно 8 выводов для формирования ШИМ-сигнала. Генерация сигнала осуществляется с помощью 32-битного таймера. Выводы, подключенные к одному и тому же таймеру, выдают ШИМ-сигнал одинаковой частоты.
|
На плате ELSOMIK в ArduinoIDE доступно 8 выводов для формирования ШИМ-сигнала. Генерация сигнала осуществляется с помощью 32-битного таймера. Выводы, подключенные к одному и тому же таймеру, выдают ШИМ-сигнал одинаковой частоты.
|
||||||
Доступные выводы:
|
Доступные выводы:
|
||||||
@ -69,9 +70,9 @@
|
|||||||
|
|
||||||
### SPI
|
### SPI
|
||||||
Интерфейс SPI1 доступен на выводах P1_0, P1_1, P1_2. Для работы с ним используется экземпляр класса под названием `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.
|
Для корректной работы аппаратного SPI микроконтроллер так же использует выводы P1_3 при работе SPI1 и P0_3 при работе SPI0. В связи с этим данные выводы недоступны для использования при работе соответствующего SPI.
|
||||||
|
|
||||||
### I2C
|
### I2C
|
||||||
Интерфейс I2C1 доступен на выводах P1_12, P1_13, для работы с ним используется экземпляр класса под названием `Wire`.
|
Интерфейс I2C1 доступен на выводах P1_12, P1_13, для работы с ним используется экземпляр класса под названием `Wire`.
|
||||||
Интерфейс I2C0 доступен на выводах P0_9, P0_10, используемый экземпляр класса - `Wire1`.
|
Интерфейс I2C0 доступен на выводах P0_9, P0_10, используемый экземпляр класса - `Wire0`.
|
||||||
BIN
docs/main_redefine_example_.png
Normal file
|
After Width: | Height: | Size: 53 KiB |
@ -1,7 +1,7 @@
|
|||||||
# ELBEAR ACE-NANO
|
# ELBEAR ACE-NANO
|
||||||
Особенности работы с платами ELBEAR ACE-NANO в среде программирования ArduinoIDE.
|
Особенности работы с платами ELBEAR ACE-NANO в среде программирования ArduinoIDE.
|
||||||
### Функциональное назначение выводов
|
### Функциональное назначение выводов
|
||||||

|

|
||||||
### Цифровые выводы
|
### Цифровые выводы
|
||||||
На плате ELBEAR ACE-NANO доступен встроенный светодиод. Для его использования необходимо воспользоваться макросом `LED_BUILTIN`, передавая его в качестве аргумента функции вместо номера цифрового вывода. Макросу соответствует номер вывода D22.
|
На плате ELBEAR ACE-NANO доступен встроенный светодиод. Для его использования необходимо воспользоваться макросом `LED_BUILTIN`, передавая его в качестве аргумента функции вместо номера цифрового вывода. Макросу соответствует номер вывода D22.
|
||||||
### Аналоговые выводы
|
### Аналоговые выводы
|
||||||
@ -10,6 +10,7 @@
|
|||||||
Для использования вывода в качестве цифрового нужно перевести переключатель в положение ON. В этом случае напряжение с вывода платы передается на микроконтроллер без изменений.
|
Для использования вывода в качестве цифрового нужно перевести переключатель в положение ON. В этом случае напряжение с вывода платы передается на микроконтроллер без изменений.
|
||||||
Выводы А4...А7 используют один и тот же канал АЦП, поэтому не могут использоваться одновременно.
|
Выводы А4...А7 используют один и тот же канал АЦП, поэтому не могут использоваться одновременно.
|
||||||
Таблица соответствия выводов платы и номера DIP-переключателя представлена ниже. Переключатель 5 относится сразу к четырем аналоговым выводам - А4...А7.
|
Таблица соответствия выводов платы и номера DIP-переключателя представлена ниже. Переключатель 5 относится сразу к четырем аналоговым выводам - А4...А7.
|
||||||
|
|
||||||
|Вывод|Номер переключателя|
|
|Вывод|Номер переключателя|
|
||||||
|---------|---------|
|
|---------|---------|
|
||||||
|А0|1|
|
|А0|1|
|
||||||
@ -20,9 +21,10 @@
|
|||||||
|А5|5|
|
|А5|5|
|
||||||
|А6|5|
|
|А6|5|
|
||||||
|А7|5|
|
|А7|5|
|
||||||
|
|
||||||
#### ШИМ
|
#### ШИМ
|
||||||
На плате ELBEAR ACE-NANO доступно 8 выводов для формирования ШИМ-сигнала: D3, D5, D6, D9...D13. Генерация сигнала осуществляется с помощью 32-битного таймера. Выводы D3, D5, D6, D9 подключены к таймеру 1, выводы D10...D13 подключены к таймеру 2. Выводы, подключенные к одному и тому же таймеру, выдают ШИМ-сигнал одинаковой частоты.
|
На плате 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)`:
|
На плате ELBEAR ACE-NANO доступно 8 прерываний, настраиваемых функцией `void attachInterrupt(uint8_t interruptNum, void (*userFunc)(void), int mode)`:
|
||||||
|
|
||||||
@ -45,4 +47,10 @@
|
|||||||
|
|
||||||
### SPI
|
### SPI
|
||||||
Интерфейс SPI1 доступен на выводах D11, D12, D13. Для работы с ним используется экземпляр класса под названием `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 |
@ -94,7 +94,7 @@ struct EEPROMClass{
|
|||||||
uint16_t length() { return (uint16_t)EEPROM_LENGHT; }
|
uint16_t length() { return (uint16_t)EEPROM_LENGHT; }
|
||||||
|
|
||||||
template< typename T >
|
template< typename T >
|
||||||
T &put(int idx, T &data)
|
const T &put(int idx, const T &data)
|
||||||
{
|
{
|
||||||
void* dataPointer = (void*)&data;
|
void* dataPointer = (void*)&data;
|
||||||
// check if idx is valid
|
// check if idx is valid
|
||||||
|
|||||||
@ -1,9 +1,11 @@
|
|||||||
#include "SPI.h"
|
#include "SPI.h"
|
||||||
|
|
||||||
SPIClass SPI(1);
|
SPIClass SPI1(1);
|
||||||
#if SPI_COMMON_QTY > 1
|
#if SPI_COMMON_QTY > 1
|
||||||
SPIClass SPI1(0);
|
SPIClass SPI0(0);
|
||||||
#endif
|
#endif
|
||||||
|
// default interface
|
||||||
|
SPIClass& SPI = DEFAULT_SPI;
|
||||||
|
|
||||||
static uint8_t reverse_bits(uint8_t byte);
|
static uint8_t reverse_bits(uint8_t byte);
|
||||||
|
|
||||||
|
|||||||
@ -127,9 +127,11 @@ public:
|
|||||||
void setClockDivider(uint8_t clockDiv);
|
void setClockDivider(uint8_t clockDiv);
|
||||||
};
|
};
|
||||||
|
|
||||||
extern SPIClass SPI;
|
|
||||||
#if SPI_COMMON_QTY > 1
|
|
||||||
extern SPIClass SPI1;
|
extern SPIClass SPI1;
|
||||||
|
#if SPI_COMMON_QTY > 1
|
||||||
|
extern SPIClass SPI0;
|
||||||
#endif
|
#endif
|
||||||
|
// default interface
|
||||||
|
extern SPIClass& SPI;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@ -287,15 +287,17 @@ void TwoWire::onRequest( void (*function)(void) )
|
|||||||
extern "C" void __attribute__((optimize("O3"))) wire_interrupt_handler(uint8_t num)
|
extern "C" void __attribute__((optimize("O3"))) wire_interrupt_handler(uint8_t num)
|
||||||
{
|
{
|
||||||
if (num == 1)
|
if (num == 1)
|
||||||
twi_interruptHandler(Wire.getHandler());
|
twi_interruptHandler(Wire1.getHandler());
|
||||||
#if I2C_COMMON_QTY>1
|
#if I2C_COMMON_QTY>1
|
||||||
else if (num == 0)
|
else if (num == 0)
|
||||||
twi_interruptHandler(Wire1.getHandler());
|
twi_interruptHandler(Wire0.getHandler());
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
// ----------------------------- Preinstantiate Objects ----------------------------- //
|
// ----------------------------- Preinstantiate Objects ----------------------------- //
|
||||||
TwoWire Wire = TwoWire(1);
|
TwoWire Wire1 = TwoWire(1); // I2C1 is always available
|
||||||
#if I2C_COMMON_QTY>1
|
#if I2C_COMMON_QTY > 1
|
||||||
TwoWire Wire1 = TwoWire(0);
|
TwoWire Wire0 = TwoWire(0); // I2C0 is available on some boards
|
||||||
#endif
|
#endif
|
||||||
|
// default interface
|
||||||
|
TwoWire& Wire = DEFAULT_WIRE;
|
||||||
|
|||||||
@ -90,9 +90,11 @@ class TwoWire : public Stream
|
|||||||
void onRequest( void (*)(void) );
|
void onRequest( void (*)(void) );
|
||||||
};
|
};
|
||||||
|
|
||||||
extern TwoWire Wire;
|
|
||||||
#if I2C_COMMON_QTY>1
|
|
||||||
extern TwoWire Wire1;
|
extern TwoWire Wire1;
|
||||||
|
#if I2C_COMMON_QTY>1
|
||||||
|
extern TwoWire Wire0;
|
||||||
#endif
|
#endif
|
||||||
|
// default interface
|
||||||
|
extern TwoWire& Wire;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@ -34,8 +34,8 @@ compiler.optimization_flags.debug=-Og -g3
|
|||||||
|
|
||||||
compiler.extra_flags = -march=rv32imc_zicsr_zifencei -mabi=ilp32 -mcmodel=medlow -Wall -fsigned-char -ffunction-sections
|
compiler.extra_flags = -march=rv32imc_zicsr_zifencei -mabi=ilp32 -mcmodel=medlow -Wall -fsigned-char -ffunction-sections
|
||||||
compiler.S.flags = {compiler.extra_flags} -x assembler-with-cpp {compiler.define} -I"{runtime.platform.path}/libraries/FreeRTOS/src" {compiler.optimization_flags} {compiler.warning_flags} {compiler.MIK32_Amur.extra_include}
|
compiler.S.flags = {compiler.extra_flags} -x assembler-with-cpp {compiler.define} -I"{runtime.platform.path}/libraries/FreeRTOS/src" {compiler.optimization_flags} {compiler.warning_flags} {compiler.MIK32_Amur.extra_include}
|
||||||
compiler.c.flags = -c -std=gnu11 {compiler.extra_flags} {compiler.define} {compiler.warning_flags} {compiler.optimization_flags} {compiler.MIK32_Amur.extra_include}
|
compiler.c.flags = -c -std=gnu11 -Werror=return-type {compiler.extra_flags} {compiler.define} {compiler.warning_flags} {compiler.optimization_flags} {compiler.MIK32_Amur.extra_include}
|
||||||
compiler.cpp.flags = -c -std=gnu++17 -fabi-version=0 -fno-exceptions -fno-rtti -fno-use-cxa-atexit -fno-threadsafe-statics {compiler.extra_flags} {compiler.define} {compiler.warning_flags} {compiler.optimization_flags} {compiler.MIK32_Amur.extra_include}
|
compiler.cpp.flags = -c -std=gnu++17 -fabi-version=0 -fno-exceptions -fno-rtti -fno-use-cxa-atexit -fno-threadsafe-statics -Werror=return-type {compiler.extra_flags} {compiler.define} {compiler.warning_flags} {compiler.optimization_flags} {compiler.MIK32_Amur.extra_include}
|
||||||
compiler.c.elf.flags = -march=rv32imc_zicsr_zifencei -mabi=ilp32 -mcmodel=medlow -nostartfiles -Xlinker
|
compiler.c.elf.flags = -march=rv32imc_zicsr_zifencei -mabi=ilp32 -mcmodel=medlow -nostartfiles -Xlinker
|
||||||
compiler.ar.flags=rc
|
compiler.ar.flags=rc
|
||||||
compiler.elf2bin.flags=-O binary
|
compiler.elf2bin.flags=-O binary
|
||||||
|
|||||||
@ -81,6 +81,7 @@ void additionalPinsDeinit(uint32_t PinNumber);
|
|||||||
// UART
|
// UART
|
||||||
// available uarts quantity
|
// available uarts quantity
|
||||||
#define SERIAL_PORT_QTY 2
|
#define SERIAL_PORT_QTY 2
|
||||||
|
#define DEFAULT_SERIAL Serial0
|
||||||
|
|
||||||
// ADC
|
// ADC
|
||||||
#define MCU_ADC_RESOLUTION 12 // bits
|
#define MCU_ADC_RESOLUTION 12 // bits
|
||||||
@ -97,7 +98,7 @@ static inline __attribute__((always_inline)) bool digitalPinHasPWM(uint8_t p)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
// return true if digitalPin configured as pwm
|
// 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
|
// determines which timer the pin belongs to
|
||||||
TIMER32_TypeDef* pwmPinToTimer(uint32_t digPinNumber);
|
TIMER32_TypeDef* pwmPinToTimer(uint32_t digPinNumber);
|
||||||
// determines which timer channel the pin belongs to
|
// determines which timer channel the pin belongs to
|
||||||
@ -105,6 +106,7 @@ HAL_TIMER32_CHANNEL_IndexTypeDef pwmPinToTimerChannel(uint32_t digPinNumber);
|
|||||||
|
|
||||||
// SPI
|
// SPI
|
||||||
#define SPI_COMMON_QTY 2
|
#define SPI_COMMON_QTY 2
|
||||||
|
#define DEFAULT_SPI SPI1
|
||||||
|
|
||||||
#define PIN_SPI_SS 10
|
#define PIN_SPI_SS 10
|
||||||
#define PIN_SPI_MOSI 11
|
#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;
|
static const uint8_t SCK = PIN_SPI_SCK;
|
||||||
|
|
||||||
|
|
||||||
#define PIN_SPI1_SS 9
|
#define PIN_SPI0_SS 9
|
||||||
#define PIN_SPI1_MOSI 5
|
#define PIN_SPI0_MOSI 5
|
||||||
#define PIN_SPI1_MISO 3
|
#define PIN_SPI0_MISO 3
|
||||||
#define PIN_SPI1_SCK 6
|
#define PIN_SPI0_SCK 6
|
||||||
static const uint8_t SS1 = PIN_SPI1_SS;
|
static const uint8_t SS0 = PIN_SPI0_SS;
|
||||||
static const uint8_t MOSI1 = PIN_SPI1_MOSI;
|
static const uint8_t MOSI0 = PIN_SPI0_MOSI;
|
||||||
static const uint8_t MISO1 = PIN_SPI1_MISO;
|
static const uint8_t MISO0 = PIN_SPI0_MISO;
|
||||||
static const uint8_t SCK1 = PIN_SPI1_SCK;
|
static const uint8_t SCK0 = PIN_SPI0_SCK;
|
||||||
|
|
||||||
// config SEL_NSS1 to replace D10 to different controller pin,
|
// config SEL_NSS1 to replace D10 to different controller pin,
|
||||||
// because NSS which is D9/D10 by default is needed to spi
|
// 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);
|
void spi_onEnd(uint8_t spiNum);
|
||||||
|
|
||||||
// I2C
|
// I2C
|
||||||
|
#define I2C_COMMON_QTY 1
|
||||||
|
#define DEFAULT_WIRE Wire1 // use I2C1 by default
|
||||||
#define PIN_WIRE_SDA 18
|
#define PIN_WIRE_SDA 18
|
||||||
#define PIN_WIRE_SCL 19
|
#define PIN_WIRE_SCL 19
|
||||||
#define I2C_COMMON_QTY 1
|
|
||||||
static const uint8_t SDA = PIN_WIRE_SDA;
|
static const uint8_t SDA = PIN_WIRE_SDA;
|
||||||
static const uint8_t SCL = PIN_WIRE_SCL;
|
static const uint8_t SCL = PIN_WIRE_SCL;
|
||||||
// available frequencies
|
// available frequencies
|
||||||
|
|||||||
@ -204,27 +204,27 @@ uint32_t analogInputToChannelNumber(uint32_t PinNumber)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ---------------------- PWM ---------------------- //
|
// ---------------------- PWM ---------------------- //
|
||||||
// use only if digitalPinHasPWM() == true
|
// return 1 if digitalPin configured as pwm and enabled,
|
||||||
#define PWM_PIN_TO_PORT_NUMBER(pin) (((pin==10)||(pin==11)||(pin==12)||(pin==13)) ? 1:0)
|
// 0 if pwm on pin is disabled,
|
||||||
|
// -1 if pin doesn't support pwm
|
||||||
// use only if digitalPinHasPWM() == true
|
__attribute__((noinline, section(".ram_text"))) int8_t digitalPinPwmIsOn(uint8_t digitalPin)
|
||||||
// return true if digitalPin configured as pwm
|
|
||||||
__attribute__((noinline, section(".ram_text"))) bool digitalPinPwmIsOn(uint8_t digitalPin)
|
|
||||||
{
|
{
|
||||||
if (digitalPinHasPWM(digitalPin))
|
if (digitalPinHasPWM(digitalPin))
|
||||||
{
|
{
|
||||||
uint8_t config = 0;
|
uint8_t config = 0;
|
||||||
uint8_t pinShift = PIN_MASK_TO_PIN_NUMBER(digitalPinToBitMask(digitalPin));
|
uint8_t pinShift = PIN_MASK_TO_PIN_NUMBER(digitalPinToBitMask(digitalPin));
|
||||||
|
|
||||||
if (PWM_PIN_TO_PORT_NUMBER(digitalPin) == 0)
|
if ((digitalPin==10)||(digitalPin==11)||(digitalPin==12)||(digitalPin==13))
|
||||||
config = PIN_GET_PAD_CONFIG(PORT_0_CFG, pinShift);
|
|
||||||
else
|
|
||||||
config = PIN_GET_PAD_CONFIG(PORT_1_CFG, pinShift);
|
config = PIN_GET_PAD_CONFIG(PORT_1_CFG, pinShift);
|
||||||
|
else
|
||||||
|
config = PIN_GET_PAD_CONFIG(PORT_0_CFG, pinShift);
|
||||||
|
|
||||||
if (config == 2)
|
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
|
// function is used only if digitalPinHasPWM() is true
|
||||||
|
|||||||
@ -76,6 +76,7 @@ static inline void additionalPinsDeinit(uint32_t PinNumber){}
|
|||||||
// UART
|
// UART
|
||||||
// available uarts quantity
|
// available uarts quantity
|
||||||
#define SERIAL_PORT_QTY 2
|
#define SERIAL_PORT_QTY 2
|
||||||
|
#define DEFAULT_SERIAL Serial0
|
||||||
|
|
||||||
// ADC
|
// ADC
|
||||||
#define MCU_ADC_RESOLUTION 12 // bits
|
#define MCU_ADC_RESOLUTION 12 // bits
|
||||||
@ -92,7 +93,7 @@ static inline __attribute__((always_inline)) bool digitalPinHasPWM(uint8_t p)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
// return true if digitalPin configured as pwm
|
// 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
|
// determines which timer the pin belongs to
|
||||||
TIMER32_TypeDef* pwmPinToTimer(uint32_t digPinNumber);
|
TIMER32_TypeDef* pwmPinToTimer(uint32_t digPinNumber);
|
||||||
// determines which timer channel the pin belongs to
|
// determines which timer channel the pin belongs to
|
||||||
@ -100,6 +101,7 @@ HAL_TIMER32_CHANNEL_IndexTypeDef pwmPinToTimerChannel(uint32_t digPinNumber);
|
|||||||
|
|
||||||
// SPI
|
// SPI
|
||||||
#define SPI_COMMON_QTY 2
|
#define SPI_COMMON_QTY 2
|
||||||
|
#define DEFAULT_SPI SPI1
|
||||||
|
|
||||||
#define PIN_SPI_SS 10
|
#define PIN_SPI_SS 10
|
||||||
#define PIN_SPI_MOSI 11
|
#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 MISO = PIN_SPI_MISO;
|
||||||
static const uint8_t SCK = PIN_SPI_SCK;
|
static const uint8_t SCK = PIN_SPI_SCK;
|
||||||
|
|
||||||
#define PIN_SPI1_SS 9
|
#define PIN_SPI0_SS 9
|
||||||
#define PIN_SPI1_MOSI 5
|
#define PIN_SPI0_MOSI 5
|
||||||
#define PIN_SPI1_MISO 3
|
#define PIN_SPI0_MISO 3
|
||||||
#define PIN_SPI1_SCK 6
|
#define PIN_SPI0_SCK 6
|
||||||
static const uint8_t SS1 = PIN_SPI1_SS;
|
static const uint8_t SS1 = PIN_SPI0_SS;
|
||||||
static const uint8_t MOSI1 = PIN_SPI1_MOSI;
|
static const uint8_t MOSI1 = PIN_SPI0_MOSI;
|
||||||
static const uint8_t MISO1 = PIN_SPI1_MISO;
|
static const uint8_t MISO1 = PIN_SPI0_MISO;
|
||||||
static const uint8_t SCK1 = PIN_SPI1_SCK;
|
static const uint8_t SCK1 = PIN_SPI0_SCK;
|
||||||
|
|
||||||
// config SEL_NSS1 to replace D10 to different controller pin,
|
// config SEL_NSS1 to replace D10 to different controller pin,
|
||||||
// because NSS which is D9/D10 by default is needed to spi
|
// 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);
|
void spi_onEnd(uint8_t spiNum);
|
||||||
|
|
||||||
// I2C
|
// I2C
|
||||||
|
#define I2C_COMMON_QTY (1)
|
||||||
|
#define DEFAULT_WIRE Wire1 // use I2C1 by default
|
||||||
#define PIN_WIRE_SDA (18)
|
#define PIN_WIRE_SDA (18)
|
||||||
#define PIN_WIRE_SCL (19)
|
#define PIN_WIRE_SCL (19)
|
||||||
#define I2C_COMMON_QTY (1)
|
|
||||||
static const uint8_t SDA = PIN_WIRE_SDA;
|
static const uint8_t SDA = PIN_WIRE_SDA;
|
||||||
static const uint8_t SCL = PIN_WIRE_SCL;
|
static const uint8_t SCL = PIN_WIRE_SCL;
|
||||||
// available frequencies
|
// available frequencies
|
||||||
|
|||||||
@ -167,26 +167,27 @@ uint32_t analogInputToChannelNumber(uint32_t PinNumber)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ---------------------- PWM ---------------------- //
|
// ---------------------- PWM ---------------------- //
|
||||||
// use only if digitalPinHasPWM() == true
|
// return 1 if digitalPin configured as pwm and enabled,
|
||||||
#define PWM_PIN_TO_PORT_NUMBER(pin) (((pin==10)||(pin==11)||(pin==12)||(pin==13)) ? 1:0)
|
// 0 if pwm on pin is disabled,
|
||||||
|
// -1 if pin doesn't support pwm
|
||||||
// return true if digitalPin configured as pwm
|
__attribute__((noinline, section(".ram_text"))) int8_t digitalPinPwmIsOn(uint8_t digitalPin)
|
||||||
__attribute__((noinline, section(".ram_text"))) bool digitalPinPwmIsOn(uint8_t digitalPin)
|
|
||||||
{
|
{
|
||||||
if (digitalPinHasPWM(digitalPin))
|
if (digitalPinHasPWM(digitalPin))
|
||||||
{
|
{
|
||||||
uint8_t config = 0;
|
uint8_t config = 0;
|
||||||
uint8_t pinShift = PIN_MASK_TO_PIN_NUMBER(digitalPinToBitMask(digitalPin));
|
uint8_t pinShift = PIN_MASK_TO_PIN_NUMBER(digitalPinToBitMask(digitalPin));
|
||||||
|
|
||||||
if (PWM_PIN_TO_PORT_NUMBER(digitalPin) == 0)
|
if ((digitalPin==10)||(digitalPin==11)||(digitalPin==12)||(digitalPin==13))
|
||||||
config = PIN_GET_PAD_CONFIG(PORT_0_CFG, pinShift);
|
|
||||||
else
|
|
||||||
config = PIN_GET_PAD_CONFIG(PORT_1_CFG, pinShift);
|
config = PIN_GET_PAD_CONFIG(PORT_1_CFG, pinShift);
|
||||||
|
else
|
||||||
|
config = PIN_GET_PAD_CONFIG(PORT_0_CFG, pinShift);
|
||||||
|
|
||||||
if (config == 2)
|
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
|
// function is used only if digitalPinHasPWM() is true
|
||||||
|
|||||||
@ -109,6 +109,7 @@ static inline void additionalPinsDeinit(uint32_t PinNumber){}
|
|||||||
// UART
|
// UART
|
||||||
// available uarts quantity
|
// available uarts quantity
|
||||||
#define SERIAL_PORT_QTY 2
|
#define SERIAL_PORT_QTY 2
|
||||||
|
#define DEFAULT_SERIAL Serial0
|
||||||
|
|
||||||
// ADC
|
// ADC
|
||||||
#define MCU_ADC_RESOLUTION 12 // bits
|
#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 (p <= P1_15) && ((p & 0xF) < 4);
|
||||||
}
|
}
|
||||||
// return true if digitalPin configured as pwm
|
// 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
|
// determines which timer the pin belongs to
|
||||||
TIMER32_TypeDef* pwmPinToTimer(uint32_t digPinNumber);
|
TIMER32_TypeDef* pwmPinToTimer(uint32_t digPinNumber);
|
||||||
// determines which timer channel the pin belongs to
|
// determines which timer channel the pin belongs to
|
||||||
@ -130,6 +131,7 @@ HAL_TIMER32_CHANNEL_IndexTypeDef pwmPinToTimerChannel(uint32_t digPinNumber);
|
|||||||
|
|
||||||
// SPI
|
// SPI
|
||||||
#define SPI_COMMON_QTY 2
|
#define SPI_COMMON_QTY 2
|
||||||
|
#define DEFAULT_SPI SPI1
|
||||||
|
|
||||||
#define PIN_SPI_SS P1_3
|
#define PIN_SPI_SS P1_3
|
||||||
#define PIN_SPI_MOSI P1_1
|
#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 MISO = PIN_SPI_MISO;
|
||||||
static const uint8_t SCK = PIN_SPI_SCK;
|
static const uint8_t SCK = PIN_SPI_SCK;
|
||||||
|
|
||||||
#define PIN_SPI1_SS P0_3
|
#define PIN_SPI0_SS P0_3
|
||||||
#define PIN_SPI1_MOSI P0_1
|
#define PIN_SPI0_MOSI P0_1
|
||||||
#define PIN_SPI1_MISO P0_0
|
#define PIN_SPI0_MISO P0_0
|
||||||
#define PIN_SPI1_SCK P0_2
|
#define PIN_SPI0_SCK P0_2
|
||||||
static const uint8_t SS1 = PIN_SPI1_SS;
|
static const uint8_t SS1 = PIN_SPI0_SS;
|
||||||
static const uint8_t MOSI1 = PIN_SPI1_MOSI;
|
static const uint8_t MOSI1 = PIN_SPI0_MOSI;
|
||||||
static const uint8_t MISO1 = PIN_SPI1_MISO;
|
static const uint8_t MISO1 = PIN_SPI0_MISO;
|
||||||
static const uint8_t SCK1 = PIN_SPI1_SCK;
|
static const uint8_t SCK1 = PIN_SPI0_SCK;
|
||||||
|
|
||||||
// check if pwm is used on spi pins
|
// check if pwm is used on spi pins
|
||||||
void spi_onBegin(uint8_t spiNum);
|
void spi_onBegin(uint8_t spiNum);
|
||||||
@ -155,12 +157,13 @@ static inline void spi_onEnd(uint8_t spiNum){}
|
|||||||
|
|
||||||
// I2C
|
// I2C
|
||||||
#define I2C_COMMON_QTY 2
|
#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_SDA P1_12
|
||||||
#define PIN_WIRE_SCL P1_13
|
#define PIN_WIRE_SCL P1_13
|
||||||
static const uint8_t SDA = PIN_WIRE_SDA;
|
static const uint8_t SDA = PIN_WIRE_SDA;
|
||||||
static const uint8_t SCL = PIN_WIRE_SCL;
|
static const uint8_t SCL = PIN_WIRE_SCL;
|
||||||
// Wire1 (I2C0)
|
// Wire0 (I2C0)
|
||||||
#define PIN_WIRE_SDA1 P0_9
|
#define PIN_WIRE_SDA1 P0_9
|
||||||
#define PIN_WIRE_SCL1 P0_10
|
#define PIN_WIRE_SCL1 P0_10
|
||||||
static const uint8_t SDA1 = PIN_WIRE_SDA1;
|
static const uint8_t SDA1 = PIN_WIRE_SDA1;
|
||||||
|
|||||||
@ -105,27 +105,25 @@ uint32_t analogInputToChannelNumber(uint32_t PinNumber)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ---------------------- PWM ---------------------- //
|
// ---------------------- PWM ---------------------- //
|
||||||
// use only if digitalPinHasPWM() == true
|
// return 1 if digitalPin configured as pwm and enabled,
|
||||||
#define PWM_PIN_TO_PORT_NUMBER(pin) (((pin) & 16) ? 1 : 0)
|
// 0 if pwm on pin is disabled,
|
||||||
|
// -1 if pin doesn't support pwm
|
||||||
// use only if digitalPinHasPWM() == true
|
__attribute__((noinline, section(".ram_text"))) int8_t digitalPinPwmIsOn(uint8_t digitalPin)
|
||||||
// return true if digitalPin configured as pwm
|
|
||||||
__attribute__((noinline, section(".ram_text"))) bool digitalPinPwmIsOn(uint8_t digitalPin)
|
|
||||||
{
|
{
|
||||||
if (digitalPinHasPWM(digitalPin))
|
if (digitalPinHasPWM(digitalPin))
|
||||||
{
|
{
|
||||||
uint8_t config = 0;
|
uint8_t config = 0;
|
||||||
uint8_t pinShift = digitalPin & 0x3;
|
if ((digitalPin & 16) == 0)
|
||||||
|
config = PIN_GET_PAD_CONFIG(PORT_0_CFG, (digitalPin & 0x3));
|
||||||
if (PWM_PIN_TO_PORT_NUMBER(digitalPin) == 0)
|
|
||||||
config = PIN_GET_PAD_CONFIG(PORT_0_CFG, pinShift);
|
|
||||||
else
|
else
|
||||||
config = PIN_GET_PAD_CONFIG(PORT_1_CFG, pinShift);
|
config = PIN_GET_PAD_CONFIG(PORT_1_CFG, (digitalPin & 0x3));
|
||||||
|
|
||||||
if (config == 2)
|
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
|
// function is used only if digitalPinHasPWM() is true
|
||||||
|
|||||||
@ -122,6 +122,7 @@ static inline void additionalPinsDeinit(uint32_t PinNumber){}
|
|||||||
// UART
|
// UART
|
||||||
// available uarts quantity
|
// available uarts quantity
|
||||||
#define SERIAL_PORT_QTY 2
|
#define SERIAL_PORT_QTY 2
|
||||||
|
#define DEFAULT_SERIAL Serial0
|
||||||
|
|
||||||
// ADC
|
// ADC
|
||||||
#define MCU_ADC_RESOLUTION 12 // bits
|
#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 (p < 32) && ((p & 0xF) < 4);
|
||||||
}
|
}
|
||||||
// return true if digitalPin configured as pwm
|
// 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
|
// determines which timer the pin belongs to
|
||||||
TIMER32_TypeDef* pwmPinToTimer(uint32_t digPinNumber);
|
TIMER32_TypeDef* pwmPinToTimer(uint32_t digPinNumber);
|
||||||
// determines which timer channel the pin belongs to
|
// determines which timer channel the pin belongs to
|
||||||
@ -143,6 +144,7 @@ HAL_TIMER32_CHANNEL_IndexTypeDef pwmPinToTimerChannel(uint32_t digPinNumber);
|
|||||||
|
|
||||||
// SPI
|
// SPI
|
||||||
#define SPI_COMMON_QTY 2
|
#define SPI_COMMON_QTY 2
|
||||||
|
#define DEFAULT_SPI SPI1
|
||||||
|
|
||||||
#define PIN_SPI_SS P1_3
|
#define PIN_SPI_SS P1_3
|
||||||
#define PIN_SPI_MOSI P1_1
|
#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 MISO = PIN_SPI_MISO;
|
||||||
static const uint8_t SCK = PIN_SPI_SCK;
|
static const uint8_t SCK = PIN_SPI_SCK;
|
||||||
|
|
||||||
#define PIN_SPI1_SS P0_3
|
#define PIN_SPI0_SS P0_3
|
||||||
#define PIN_SPI1_MOSI P0_1
|
#define PIN_SPI0_MOSI P0_1
|
||||||
#define PIN_SPI1_MISO P0_0
|
#define PIN_SPI0_MISO P0_0
|
||||||
#define PIN_SPI1_SCK P0_2
|
#define PIN_SPI0_SCK P0_2
|
||||||
static const uint8_t SS1 = PIN_SPI1_SS;
|
static const uint8_t SS0 = PIN_SPI0_SS;
|
||||||
static const uint8_t MOSI1 = PIN_SPI1_MOSI;
|
static const uint8_t MOSI0 = PIN_SPI0_MOSI;
|
||||||
static const uint8_t MISO1 = PIN_SPI1_MISO;
|
static const uint8_t MISO0 = PIN_SPI0_MISO;
|
||||||
static const uint8_t SCK1 = PIN_SPI1_SCK;
|
static const uint8_t SCK0 = PIN_SPI0_SCK;
|
||||||
|
|
||||||
// check if pwm is used on spi pins
|
// check if pwm is used on spi pins
|
||||||
void spi_onBegin(uint8_t spiNum);
|
void spi_onBegin(uint8_t spiNum);
|
||||||
@ -168,12 +170,13 @@ static inline void spi_onEnd(uint8_t spiNum){}
|
|||||||
|
|
||||||
// I2C
|
// I2C
|
||||||
#define I2C_COMMON_QTY 2
|
#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_SDA P1_12
|
||||||
#define PIN_WIRE_SCL P1_13
|
#define PIN_WIRE_SCL P1_13
|
||||||
static const uint8_t SDA = PIN_WIRE_SDA;
|
static const uint8_t SDA = PIN_WIRE_SDA;
|
||||||
static const uint8_t SCL = PIN_WIRE_SCL;
|
static const uint8_t SCL = PIN_WIRE_SCL;
|
||||||
// Wire1 (I2C0)
|
// Wire0 (I2C0)
|
||||||
#define PIN_WIRE_SDA1 P0_9
|
#define PIN_WIRE_SDA1 P0_9
|
||||||
#define PIN_WIRE_SCL1 P0_10
|
#define PIN_WIRE_SCL1 P0_10
|
||||||
static const uint8_t SDA1 = PIN_WIRE_SDA1;
|
static const uint8_t SDA1 = PIN_WIRE_SDA1;
|
||||||
|
|||||||
@ -101,27 +101,25 @@ uint32_t analogInputToChannelNumber(uint32_t PinNumber)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ---------------------- PWM ---------------------- //
|
// ---------------------- PWM ---------------------- //
|
||||||
// use only if digitalPinHasPWM() == true
|
// return 1 if digitalPin configured as pwm and enabled,
|
||||||
#define PWM_PIN_TO_PORT_NUMBER(pin) (((pin) & 16) ? 1 : 0)
|
// 0 if pwm on pin is disabled,
|
||||||
|
// -1 if pin doesn't support pwm
|
||||||
// use only if digitalPinHasPWM() == true
|
__attribute__((noinline, section(".ram_text"))) int8_t digitalPinPwmIsOn(uint8_t digitalPin)
|
||||||
// return true if digitalPin configured as pwm
|
|
||||||
__attribute__((noinline, section(".ram_text"))) bool digitalPinPwmIsOn(uint8_t digitalPin)
|
|
||||||
{
|
{
|
||||||
if (digitalPinHasPWM(digitalPin))
|
if (digitalPinHasPWM(digitalPin))
|
||||||
{
|
{
|
||||||
uint8_t config = 0;
|
uint8_t config = 0;
|
||||||
uint8_t pinShift = digitalPin & 3;
|
if ((digitalPin & 16) == 0)
|
||||||
|
config = PIN_GET_PAD_CONFIG(PORT_0_CFG, (digitalPin & 3));
|
||||||
if (PWM_PIN_TO_PORT_NUMBER(digitalPin) == 0)
|
|
||||||
config = PIN_GET_PAD_CONFIG(PORT_0_CFG, pinShift);
|
|
||||||
else
|
else
|
||||||
config = PIN_GET_PAD_CONFIG(PORT_1_CFG, pinShift);
|
config = PIN_GET_PAD_CONFIG(PORT_1_CFG, (digitalPin & 3));
|
||||||
|
|
||||||
if (config == 2)
|
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
|
// function is used only if digitalPinHasPWM() is true
|
||||||
|
|||||||