diff --git a/README.md b/README.md index e4882f0..d83417c 100644 --- a/README.md +++ b/README.md @@ -42,11 +42,15 @@ Для работы доступно два последовательных интерфейса. Нулевой интерфейс используется экземпляром класса `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 бита. +### Переопределение функции main +В ArduinoIDE доступна возможность определить пользовательскую функцию `main()` в скетче. Для этого необходимо удалить из скетча функции `setup()` и `loop()` и определить свою функцию `int main(void){}`. Чтобы весь функционал пакета поддержки работал корректно, перед заходом в бесконечный цикл необходимо вызвать функцию `post_init()`, внутри которой глобально разрешаются прерывания. Пример переопределения представлен ниже. +![main_redefine_example_.png](docs/main_redefine_example_.png) + ### Предупреждения об ошибках Если в скетче используется интерфейс `Serial`, при возникновении ошибок при использовании какой-либо функции из пакета в порт может передаваться сообщение об этой ошибке с пояснением. Например, если в функцию будет передан некорректный номер цифрового вывода, предупреждение об этом появится в подключенном com порту. По умолчанию вывод предупреждений включен. Если интерфейс `Serial` используется для коммуникации с другим устройством, вывод предупреждений можно отключить. Для этого в самом начале функции `void setup()` необходимо вызвать макрос `DISABLE_ERROR_MESSAGES();`. Вывод предупреждений можно включить обратно, вызвав макрос `ENABLE_ERROR_MESSAGES();` в любом месте программы. -### Библиотеки, входящие в состав пакета +## Библиотеки, входящие в состав пакета Входящие в состав пакета библиотеки используют периферию микроконтроллера MIK32 Амур и/или адаптированы для работы с ним. |Библиотека|Описание|Заметки| @@ -97,7 +101,7 @@ ## Протестированные модули Список модулей и шилдов, работа которых была протестирована на платах, входящих в состав пакета поддержки, доступен [здесь](./docs/tested_shields.md). -# Режим отладки +## Режим отладки Для всех плат, входящих в состав пакета, доступен режим отладки скетча в ArduinoIDE версии 2. Подготовка к работе в режиме отладки описана в [инструкции.](./docs/debug_description.md) # Полезные ссылки diff --git a/cores/arduino/HardwareSerial.cpp b/cores/arduino/HardwareSerial.cpp index 284d8fc..a0a6642 100644 --- a/cores/arduino/HardwareSerial.cpp +++ b/cores/arduino/HardwareSerial.cpp @@ -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)) { diff --git a/cores/arduino/HardwareSerial.h b/cores/arduino/HardwareSerial.h index d7f60a1..792bf13 100644 --- a/cores/arduino/HardwareSerial.h +++ b/cores/arduino/HardwareSerial.h @@ -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)); diff --git a/cores/arduino/board.cpp b/cores/arduino/board.cpp index 591676c..37d08f0 100644 --- a/cores/arduino/board.cpp +++ b/cores/arduino/board.cpp @@ -3,6 +3,40 @@ #include "mik32_hal_irq.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 --------------------- // // called from crt0.S before constructors initialization extern "C" void SystemInit(void) @@ -20,6 +54,8 @@ extern "C" void SystemInit(void) // for delays SysTick_Init(); + // update flash cache limit by app size + updateCacheLimit(); } // called after setup() diff --git a/cores/arduino/main.cpp b/cores/arduino/main.cpp index 77b6e0b..0fcf31d 100644 --- a/cores/arduino/main.cpp +++ b/cores/arduino/main.cpp @@ -7,6 +7,7 @@ void initVariant() __attribute__((weak)); void initVariant() { } +extern "C" int main(void) __attribute__((weak)); int main() { initVariant(); // for freeRTOS @@ -17,6 +18,4 @@ int main() { loop(); } -} - - +} \ No newline at end of file diff --git a/cores/arduino/mik32/shared/ldscripts/spifi_cpp.ld b/cores/arduino/mik32/shared/ldscripts/spifi_cpp.ld index 0e80a68..d88e2ad 100644 --- a/cores/arduino/mik32/shared/ldscripts/spifi_cpp.ld +++ b/cores/arduino/mik32/shared/ldscripts/spifi_cpp.ld @@ -21,11 +21,10 @@ SECTIONS { *crt0.S.o(.text .text.*) *(.text.smallsysteminit) *(.text.SmallSystemInit) - /*. = ORIGIN(rom) + 0xC0;*/ - /*KEEP(*crt0.S.o(.trap_text))*/ *(.text) *(.text.*) + PROVIDE(__RODATA__ = .); *(.rodata) *(.rodata.*) . = ALIGN(CL_SIZE); diff --git a/cores/arduino/wiring_analog.c b/cores/arduino/wiring_analog.c index 1dc6775..c497b6b 100644 --- a/cores/arduino/wiring_analog.c +++ b/cores/arduino/wiring_analog.c @@ -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 diff --git a/cores/arduino/wiring_constants.h b/cores/arduino/wiring_constants.h index 1231a2f..f46dc93 100644 --- a/cores/arduino/wiring_constants.h +++ b/cores/arduino/wiring_constants.h @@ -56,25 +56,23 @@ enum BitOrder #define NOT_AN_INTERRUPT -1 // Math -#ifdef __cplusplus - #include - using std::min; - using std::max; -#else // C - #include - #ifndef abs - #define abs(x) ((x)>0?(x):-(x)) - #endif // abs +#include +// undefine stdlib's abs if encountered +#ifdef abs +#undef abs +#endif +#ifndef abs + #define abs(x) ((x)>0?(x):-(x)) +#endif // abs - #ifndef min - #define min(a,b) ((a)<(b)?(a):(b)) - #endif // min +#ifndef min + #define min(a,b) ((a)<(b)?(a):(b)) +#endif // min - #ifndef max - #define max(a,b) ((a)>(b)?(a):(b)) - #endif // max +#ifndef max + #define max(a,b) ((a)>(b)?(a):(b)) +#endif // max -#endif // __cplusplus #define constrain(amt,low,high) ((amt)<(low)?(low):((amt)>(high)?(high):(amt))) #define radians(deg) ((deg)*DEG_TO_RAD) #define degrees(rad) ((rad)*RAD_TO_DEG) diff --git a/cores/arduino/wiring_digital.c b/cores/arduino/wiring_digital.c index 7c678ef..e4f6633 100644 --- a/cores/arduino/wiring_digital.c +++ b/cores/arduino/wiring_digital.c @@ -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)); diff --git a/cores/arduino/wiring_pulse.cpp b/cores/arduino/wiring_pulse.cpp index eefd0f9..522b74f 100644 --- a/cores/arduino/wiring_pulse.cpp +++ b/cores/arduino/wiring_pulse.cpp @@ -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); diff --git a/docs/Elbear_description.md b/docs/Elbear_description.md index dc8f0f0..7379833 100644 --- a/docs/Elbear_description.md +++ b/docs/Elbear_description.md @@ -1,7 +1,7 @@ # ELBEAR ACE-UNO Особенности работы с платами ELBEAR ACE-UNO в среде программирования ArduinoIDE. ### Функциональное назначение выводов -![Pinout](uno_pinout.png) +![Pinout](pinout_uno.png) ### Цифровые выводы На плате ELBEAR ACE-UNO доступны встроенные светодиод и кнопка. Для их использования необходимо воспользоваться макросами `LED_BUILTIN` и `BTN_BUILTIN`, передавая их в качестве аргументов функции вместо номера цифрового вывода. Макросу `LED_BUILTIN` соответствует номер вывода D22, а макросу `BTN_BUILTIN` - D23. ### Аналоговые выводы @@ -9,6 +9,7 @@ Для использования вывода в качестве аналогового необходимо перевести соответствующий DIP-переключатель, расположенный рядом с аналоговыми выводами, в положение OFF. В этом режиме внешнее напряжение, подаваемое на вывод, будет понижаться резистивным делителем перед подачей на микроконтроллер. Для использования вывода в качестве цифрового нужно перевести переключатель в положение ON. В этом случае напряжение с вывода платы передается на микроконтроллер без изменений. Таблица соответствия выводов платы и номера DIP-переключателя представлена ниже. Переключатель 5 относится сразу к двум аналоговым выводам - А4, А5. + |Вывод|Номер переключателя| |---------|---------| |А0|1| @@ -17,9 +18,10 @@ |А3|4| |А4|5| |А5|5| + #### ШИМ На плате ELBEAR ACE-UNO доступно 8 выводов для формирования ШИМ-сигнала: D3, D5, D6, D9...D13. Генерация сигнала осуществляется с помощью 32-битного таймера. Выводы D3, D5, D6, D9 подключены к таймеру 1, выводы D10...D13 подключены к таймеру 2. Выводы, подключенные к одному и тому же таймеру, выдают ШИМ-сигнал одинаковой частоты. -Цифровые выводы D9, D10 не могут быть использованы для генерации ШИМ, если одновременно активен интерфейс SPI (при использовании экземпляра `SPI` недоступен ШИМ на выводе D10, при использовании экземпляра `SPI1` - на выводе D9). Это ограничение связано с особенностями работы микроконтроллера. Ограничение не распространяется на использование D9, D10 в качестве цифрового вывода при активном SPI. +Цифровые выводы D9, D10 не могут быть использованы для генерации ШИМ, если одновременно активен интерфейс SPI (при использовании экземпляра `SPI` недоступен ШИМ на выводе D10, при использовании экземпляра `SPI0` - на выводе D9). Это ограничение связано с особенностями работы микроконтроллера. Ограничение не распространяется на использование D9, D10 в качестве цифрового вывода при активном SPI. ### Прерывания На плате ELBEAR ACE-UNO доступно 8 прерываний, настраиваемых функцией `void attachInterrupt(uint8_t interruptNum, void (*userFunc)(void), int mode)`: @@ -42,4 +44,10 @@ ### SPI Интерфейс SPI1 доступен на выводах D11, D12, D13. Для работы с ним используется экземпляр класса под названием `SPI`. -Интерфейс SPI0 доступен на выводах D3, D5, D6. Используемый экземпляр класса - `SPI1`. \ No newline at end of file +Интерфейс SPI0 доступен на выводах D3, D5, D6. Используемый экземпляр класса - `SPI0`. + +### I2C +Интерфейс I2C1 доступен на выводах SDA и SCL, для работы с ним используется экземпляр класса под названием `Wire`. + +## Драйверы +Для работы с платой по интерфейсу USB необходим драйвер для микросхемы CH340С, его можно скачать [здесь](https://www.wch-ic.com/downloads/CH341SER_ZIP.html). \ No newline at end of file diff --git a/docs/Elsomik_OEM_pinout.png b/docs/Elsomik_OEM_pinout.png deleted file mode 100644 index 664f1fc..0000000 Binary files a/docs/Elsomik_OEM_pinout.png and /dev/null differ diff --git a/docs/Elsomik_SE_pinout.png b/docs/Elsomik_SE_pinout.png deleted file mode 100644 index 768f57c..0000000 Binary files a/docs/Elsomik_SE_pinout.png and /dev/null differ diff --git a/docs/Pinout_nano.PNG b/docs/Pinout_nano.PNG deleted file mode 100644 index 5d2f5c3..0000000 Binary files a/docs/Pinout_nano.PNG and /dev/null differ diff --git a/docs/Start_mik32_description.md b/docs/Start_mik32_description.md index 16be9ea..5520583 100644 --- a/docs/Start_mik32_description.md +++ b/docs/Start_mik32_description.md @@ -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`. \ No newline at end of file +Интерфейс I2C1 доступен на выводах SDA, SCL и P1_12, P1_13, для работы с ним используется экземпляр класса под названием `Wire`. +Интерфейс I2C0 доступен на выводах P0_9, P0_10, используемый экземпляр класса - `Wire0`. \ No newline at end of file diff --git a/docs/elsomik_description.md b/docs/elsomik_description.md index 7fdf133..8f68718 100644 --- a/docs/elsomik_description.md +++ b/docs/elsomik_description.md @@ -1,9 +1,9 @@ # ELSOMIK Особенности работы с платой ELSOMIK в среде программирования ArduinoIDE. ### Функциональное назначение выводов платы ELSOMIK OEM -![Elsomik_OEM_pinout.png](Elsomik_OEM_pinout.png) +![pinout_Elsomik_OEM.png](pinout_ElsomikOEM.png) ### Функциональное назначение выводов платы ELSOMIK SE -![Elsomik_SE_pinout.png](Elsomik_SE_pinout.png) +![pinout_Elsomik_SE.png](pinout_ElsomikSE.png) ### Загрузка скетчей На плате отсутствуют встроенные преобразователи, позволяющие загружать скетчи по USB через COM-порт, однако каждая плата поставляется с предварительно записанным начальным загрузчиком. Для записи скетчей через USB потребуется использование внешнего USB-UART преобразователя, подключаемого к выводам платы P0_5 (RX0) и P0_6 (TX0), которые соответствуют интерфейсу UART0. @@ -33,6 +33,7 @@ |P0_9|A5| |P0_11|A6| |P0_13|A7| + #### ШИМ На плате ELSOMIK в ArduinoIDE доступно 8 выводов для формирования ШИМ-сигнала. Генерация сигнала осуществляется с помощью 32-битного таймера. Выводы, подключенные к одному и тому же таймеру, выдают ШИМ-сигнал одинаковой частоты. Доступные выводы: @@ -69,9 +70,9 @@ ### SPI Интерфейс SPI1 доступен на выводах P1_0, P1_1, P1_2. Для работы с ним используется экземпляр класса под названием `SPI`. -Интерфейс SPI0 доступен на выводах P0_0, P0_1, P0_2. Используемый экземпляр класса - `SPI1`. +Интерфейс SPI0 доступен на выводах P0_0, P0_1, P0_2. Используемый экземпляр класса - `SPI0`. Для корректной работы аппаратного SPI микроконтроллер так же использует выводы P1_3 при работе SPI1 и P0_3 при работе SPI0. В связи с этим данные выводы недоступны для использования при работе соответствующего SPI. ### I2C Интерфейс I2C1 доступен на выводах P1_12, P1_13, для работы с ним используется экземпляр класса под названием `Wire`. -Интерфейс I2C0 доступен на выводах P0_9, P0_10, используемый экземпляр класса - `Wire1`. \ No newline at end of file +Интерфейс I2C0 доступен на выводах P0_9, P0_10, используемый экземпляр класса - `Wire0`. \ No newline at end of file diff --git a/docs/main_redefine_example_.png b/docs/main_redefine_example_.png new file mode 100644 index 0000000..95689bd Binary files /dev/null and b/docs/main_redefine_example_.png differ diff --git a/docs/nano_description.md b/docs/nano_description.md index 27bb587..f5b92c3 100644 --- a/docs/nano_description.md +++ b/docs/nano_description.md @@ -1,7 +1,7 @@ # ELBEAR ACE-NANO Особенности работы с платами ELBEAR ACE-NANO в среде программирования ArduinoIDE. ### Функциональное назначение выводов -![Pinout_nano](Pinout_nano.PNG) +![nano_pinout](nano_pinout.PNG) ### Цифровые выводы На плате ELBEAR ACE-NANO доступен встроенный светодиод. Для его использования необходимо воспользоваться макросом `LED_BUILTIN`, передавая его в качестве аргумента функции вместо номера цифрового вывода. Макросу соответствует номер вывода D22. ### Аналоговые выводы @@ -10,6 +10,7 @@ Для использования вывода в качестве цифрового нужно перевести переключатель в положение ON. В этом случае напряжение с вывода платы передается на микроконтроллер без изменений. Выводы А4...А7 используют один и тот же канал АЦП, поэтому не могут использоваться одновременно. Таблица соответствия выводов платы и номера DIP-переключателя представлена ниже. Переключатель 5 относится сразу к четырем аналоговым выводам - А4...А7. + |Вывод|Номер переключателя| |---------|---------| |А0|1| @@ -20,9 +21,10 @@ |А5|5| |А6|5| |А7|5| + #### ШИМ На плате ELBEAR ACE-NANO доступно 8 выводов для формирования ШИМ-сигнала: D3, D5, D6, D9...D13. Генерация сигнала осуществляется с помощью 32-битного таймера. Выводы D3, D5, D6, D9 подключены к таймеру 1, выводы D10...D13 подключены к таймеру 2. Выводы, подключенные к одному и тому же таймеру, выдают ШИМ-сигнал одинаковой частоты. -Цифровые выводы D9, D10 не могут быть использованы для генерации ШИМ, если одновременно активен интерфейс SPI (при использовании экземпляра `SPI` недоступен ШИМ на выводе D10, при использовании экземпляра `SPI1` - на выводе D9). Это ограничение связано с особенностями работы микроконтроллера. Ограничение не распространяется на использование D9, D10 в качестве цифрового вывода при активном SPI. +Цифровые выводы D9, D10 не могут быть использованы для генерации ШИМ, если одновременно активен интерфейс SPI (при использовании экземпляра `SPI` недоступен ШИМ на выводе D10, при использовании экземпляра `SPI0` - на выводе D9). Это ограничение связано с особенностями работы микроконтроллера. Ограничение не распространяется на использование D9, D10 в качестве цифрового вывода при активном SPI. ### Прерывания На плате ELBEAR ACE-NANO доступно 8 прерываний, настраиваемых функцией `void attachInterrupt(uint8_t interruptNum, void (*userFunc)(void), int mode)`: @@ -45,4 +47,10 @@ ### SPI Интерфейс SPI1 доступен на выводах D11, D12, D13. Для работы с ним используется экземпляр класса под названием `SPI`. -Интерфейс SPI0 доступен на выводах D3, D5, D6. Используемый экземпляр класса - `SPI1`. \ No newline at end of file +Интерфейс SPI0 доступен на выводах D3, D5, D6. Используемый экземпляр класса - `SPI0`. + +### I2C +Интерфейс I2C1 доступен на выводах A4 и A5, для работы с ним используется экземпляр класса под названием `Wire`. + +## Драйверы +Для работы с платой по интерфейсу USB необходим драйвер для микросхемы CH343P, его можно скачать [здесь](https://www.wch-ic.com/downloads/CH343SER_ZIP.html). \ No newline at end of file diff --git a/docs/nano_pinout.PNG b/docs/nano_pinout.PNG new file mode 100644 index 0000000..9974dd6 Binary files /dev/null and b/docs/nano_pinout.PNG differ diff --git a/docs/pinout_ElsomikOEM.png b/docs/pinout_ElsomikOEM.png new file mode 100644 index 0000000..4501e0a Binary files /dev/null and b/docs/pinout_ElsomikOEM.png differ diff --git a/docs/pinout_ElsomikSE.png b/docs/pinout_ElsomikSE.png new file mode 100644 index 0000000..018eae5 Binary files /dev/null and b/docs/pinout_ElsomikSE.png differ diff --git a/docs/pinout_uno.png b/docs/pinout_uno.png new file mode 100644 index 0000000..93b25f7 Binary files /dev/null and b/docs/pinout_uno.png differ diff --git a/docs/uno_pinout.png b/docs/uno_pinout.png deleted file mode 100644 index d09b7e0..0000000 Binary files a/docs/uno_pinout.png and /dev/null differ diff --git a/libraries/EEPROM/src/EEPROM.h b/libraries/EEPROM/src/EEPROM.h index 315c4e0..780a89e 100644 --- a/libraries/EEPROM/src/EEPROM.h +++ b/libraries/EEPROM/src/EEPROM.h @@ -94,7 +94,7 @@ struct EEPROMClass{ uint16_t length() { return (uint16_t)EEPROM_LENGHT; } template< typename T > - T &put(int idx, T &data) + const T &put(int idx, const T &data) { void* dataPointer = (void*)&data; // check if idx is valid diff --git a/libraries/SPI/src/SPI.cpp b/libraries/SPI/src/SPI.cpp index 1050ef6..23ae81f 100644 --- a/libraries/SPI/src/SPI.cpp +++ b/libraries/SPI/src/SPI.cpp @@ -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); diff --git a/libraries/SPI/src/SPI.h b/libraries/SPI/src/SPI.h index cee0433..c0b9cd5 100644 --- a/libraries/SPI/src/SPI.h +++ b/libraries/SPI/src/SPI.h @@ -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 diff --git a/libraries/Wire/src/Wire.cpp b/libraries/Wire/src/Wire.cpp index 10ee740..363bc6a 100644 --- a/libraries/Wire/src/Wire.cpp +++ b/libraries/Wire/src/Wire.cpp @@ -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; diff --git a/libraries/Wire/src/Wire.h b/libraries/Wire/src/Wire.h index ca62b8e..9296644 100644 --- a/libraries/Wire/src/Wire.h +++ b/libraries/Wire/src/Wire.h @@ -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 diff --git a/platform.txt b/platform.txt index 2392730..2920a9b 100644 --- a/platform.txt +++ b/platform.txt @@ -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.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.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.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 -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.ar.flags=rc compiler.elf2bin.flags=-O binary diff --git a/variants/elbear_ace_nano/pins_arduino.h b/variants/elbear_ace_nano/pins_arduino.h index c1e19df..5c8546a 100644 --- a/variants/elbear_ace_nano/pins_arduino.h +++ b/variants/elbear_ace_nano/pins_arduino.h @@ -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 diff --git a/variants/elbear_ace_nano/variant.c b/variants/elbear_ace_nano/variant.c index d5f6a31..9847f3b 100644 --- a/variants/elbear_ace_nano/variant.c +++ b/variants/elbear_ace_nano/variant.c @@ -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 diff --git a/variants/elbear_ace_uno/pins_arduino.h b/variants/elbear_ace_uno/pins_arduino.h index 553ed21..f6fb144 100644 --- a/variants/elbear_ace_uno/pins_arduino.h +++ b/variants/elbear_ace_uno/pins_arduino.h @@ -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 diff --git a/variants/elbear_ace_uno/variant.c b/variants/elbear_ace_uno/variant.c index 9842331..a68047c 100644 --- a/variants/elbear_ace_uno/variant.c +++ b/variants/elbear_ace_uno/variant.c @@ -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 diff --git a/variants/elsomik/pins_arduino.h b/variants/elsomik/pins_arduino.h index 282f608..248d0a4 100644 --- a/variants/elsomik/pins_arduino.h +++ b/variants/elsomik/pins_arduino.h @@ -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; diff --git a/variants/elsomik/variant.c b/variants/elsomik/variant.c index c5eab70..7c65693 100644 --- a/variants/elsomik/variant.c +++ b/variants/elsomik/variant.c @@ -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 diff --git a/variants/start/pins_arduino.h b/variants/start/pins_arduino.h index f785196..dba76fe 100644 --- a/variants/start/pins_arduino.h +++ b/variants/start/pins_arduino.h @@ -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; diff --git a/variants/start/variant.c b/variants/start/variant.c index 2e83da8..08e2be2 100644 --- a/variants/start/variant.c +++ b/variants/start/variant.c @@ -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