From 82fbe4939e7ca5a6778f981ec5e779e03458e42d Mon Sep 17 00:00:00 2001 From: klassents Date: Thu, 5 Sep 2024 08:49:43 +0300 Subject: [PATCH] Merged with dev_beta --- .gitignore | 1 + README.md | 2 +- boards.txt | 54 +++++++++++- cores/arduino/HardwareSerial.cpp | 98 +++++++++++++++------- cores/arduino/HardwareSerial.h | 12 ++- cores/arduino/mik32/shared/libs/uart_lib.c | 23 +++++ cores/arduino/mik32/shared/libs/uart_lib.h | 15 ++++ cores/arduino/trap_handler.c | 10 ++- variants/standart/pins_arduino.h | 7 +- 9 files changed, 184 insertions(+), 38 deletions(-) create mode 100644 .gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..5d15477 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +installed.json \ No newline at end of file diff --git a/README.md b/README.md index 45f5543..e34f703 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ # elbear_arduino_bsp Пакет поддержки платы Elbear Ace-Uno на базе микроконтроллера MIK32 Амур в среде программирования Arduino IDE. - + ## Установка пакета в ArduinoIDE 1. Установите [Arduino IDE](https://www.arduino.cc/en/software). 2. Откройте меню `Файл -> Параметры`. diff --git a/boards.txt b/boards.txt index c1d912d..2ad43bd 100644 --- a/boards.txt +++ b/boards.txt @@ -1,6 +1,8 @@ # See: https://arduino.github.io/arduino-cli/latest/platform-specification/ ############################################################## -aceUno8Mb.name=Elbear Ace-Uno + +##################### Ace-Uno 8 Mb ##################### +aceUno8Mb.name=Elbear Ace-Uno 8 Mb # tool for firmware update aceUno8Mb.upload.tool=elbear_uploader @@ -16,8 +18,56 @@ aceUno8Mb.bootloader.file=ace-uno/bootloader.hex # build options aceUno8Mb.build.mcu=MIK32_Amur aceUno8Mb.build.f_cpu=32000000UL -aceUno8Mb.build.board=ACE_UNO +aceUno8Mb.build.board=ACE_UNO_8MB aceUno8Mb.build.core=arduino aceUno8Mb.build.variant=standart aceUno8Mb.build.extra_flags= aceUno8Mb.build.flags= + + +##################### Ace-Uno 16 Mb ##################### +aceUno16Mb.name=Elbear Ace-Uno 16 Mb + +# tool for firmware update +aceUno16Mb.upload.tool=elbear_uploader +aceUno16Mb.upload.protocol=elbear_uploader +aceUno16Mb.upload.maximum_size=16777216 +aceUno16Mb.upload.maximum_data_size=16384 + +# tool for bootloader update +aceUno16Mb.bootloader.tool=mik32_upload +aceUno16Mb.bootloader.tool.default=mik32_upload +aceUno16Mb.bootloader.file=ace-uno/bootloader.hex + +# build options +aceUno16Mb.build.mcu=MIK32_Amur +aceUno16Mb.build.f_cpu=32000000UL +aceUno16Mb.build.board=ACE_UNO_16MB +aceUno16Mb.build.core=arduino +aceUno16Mb.build.variant=standart +aceUno16Mb.build.extra_flags= +aceUno16Mb.build.flags= + + +##################### Ace-Uno 32 Mb ##################### +aceUno32Mb.name=Elbear Ace-Uno 32 Mb + +# tool for firmware update +aceUno32Mb.upload.tool=elbear_uploader +aceUno32Mb.upload.protocol=elbear_uploader +aceUno32Mb.upload.maximum_size=33554432 +aceUno32Mb.upload.maximum_data_size=16384 + +# tool for bootloader update +aceUno32Mb.bootloader.tool=mik32_upload +aceUno32Mb.bootloader.tool.default=mik32_upload +aceUno32Mb.bootloader.file=ace-uno/bootloader.hex + +# build options +aceUno32Mb.build.mcu=MIK32_Amur +aceUno32Mb.build.f_cpu=32000000UL +aceUno32Mb.build.board=ACE_UNO_32MB +aceUno32Mb.build.core=arduino +aceUno32Mb.build.variant=standart +aceUno32Mb.build.extra_flags= +aceUno32Mb.build.flags= \ No newline at end of file diff --git a/cores/arduino/HardwareSerial.cpp b/cores/arduino/HardwareSerial.cpp index 9dc60ec..0ee296f 100644 --- a/cores/arduino/HardwareSerial.cpp +++ b/cores/arduino/HardwareSerial.cpp @@ -6,8 +6,13 @@ #include #include "mik32_hal_irq.h" -// объект класса HardwareSerial для использования в arduino ide -HardwareSerial Serial; + +// HardwareSerial class objects for use in Arduino IDE +HardwareSerial Serial(0); +#if SERIAL_PORT_QTY > 1 +HardwareSerial Serial1(1); +#endif + void serialEvent() __attribute__((weak)); bool Serial0_available() __attribute__((weak)); @@ -55,35 +60,46 @@ void HardwareSerial::begin(unsigned long baud, uint8_t config) reg2config |= UART_CONTROL2_STOP_1_M; // turn on the receiver and transmitter, apply the parsed config - UART_Init(UART_0, brr, reg1config, reg2config, reg3config); - // Enable level-based interrupts for the EPIC_UART_0 line, we have only receive interrupt enabled - HAL_EPIC_MaskLevelSet(HAL_EPIC_UART_0_MASK); - - isInited = true; + if (uartNum == 0) + { + UART_Init(UART_0, brr, reg1config, reg2config, reg3config); + // Enable level-based interrupts for the EPIC_UART_0 line, we have only receive interrupt enabled + HAL_EPIC_MaskLevelSet(HAL_EPIC_UART_0_MASK); + isInited = true; + } + else if (uartNum == 1) + { + UART_Init(UART_1, brr, reg1config, reg2config, reg3config); + // Enable level-based interrupts for the EPIC_UART_1 line, we have only receive interrupt enabled + HAL_EPIC_MaskLevelSet(HAL_EPIC_UART_1_MASK); + isInited = true; + } } void HardwareSerial::end() { if (isInited) { - // wait for the data to be sent if necessary - flush(); - - // disable clock - __HAL_PCC_UART_0_CLK_DISABLE(); - HAL_EPIC_MaskLevelClear(HAL_EPIC_UART_0_MASK); + // deinit uart and disable uart interrupt + if (uartNum == 0) + { + // wait for the data to be sent if necessary + UART_WaitDataTranferCompleteFlag(UART_0); + UART_Deinit(UART_0); + HAL_EPIC_MaskLevelClear(HAL_EPIC_UART_0_MASK); + isInited = false; + } + else if (uartNum == 1) + { + // wait for the data to be sent if necessary + UART_WaitDataTranferCompleteFlag(UART_1); + UART_Deinit(UART_1); + HAL_EPIC_MaskLevelClear(HAL_EPIC_UART_1_MASK); + isInited = false; + } - // reconfigure pins to z state - GPIO_InitTypeDef GPIO_InitStruct; - memset(&GPIO_InitStruct, 0, sizeof(GPIO_InitStruct)); - GPIO_InitStruct.Pin = (HAL_PinsTypeDef)(GPIO_PIN_5 | GPIO_PIN_6); - GPIO_InitStruct.Mode = HAL_GPIO_MODE_GPIO_INPUT; - GPIO_InitStruct.Pull = HAL_GPIO_PULL_NONE; - HAL_GPIO_Init(GPIO_0, &GPIO_InitStruct); // reset buffer indices - _rx_buffer_head = _rx_buffer_tail = 0; - - isInited = false; + _rx_buffer_head = _rx_buffer_tail = 0; } } @@ -101,14 +117,19 @@ int HardwareSerial::availableForWrite(void) void HardwareSerial::rx_complete_irq(void) { + // which UART to use + UART_TypeDef* uart = UART_0; + if (uartNum == 1) + uart = UART_1; + // find next index in buffer with upper limit uint8_t i = (uint8_t)(_rx_buffer_head + 1)%SERIAL_RX_BUFFER_SIZE; unsigned char c; // while there is something to receive, put the data into the buffer // and edit the buffer index - while (!UART_IsRxFifoEmpty(UART_0)) + while (!UART_IsRxFifoEmpty(uart)) { - c = UART_ReadByte(UART_0); + c = UART_ReadByte(uart); if (i != _rx_buffer_tail) { // write if there is space in the buffer @@ -119,9 +140,16 @@ void HardwareSerial::rx_complete_irq(void) } // wrapper for use in С-files -extern "C" void serial_handler_wrapper(void) +extern "C" void serial_handler_wrapper(uint8_t uartNumInt) { + if (uartNumInt == 0) + { Serial.rx_complete_irq(); + } + else if ((uartNumInt == 1) && (SERIAL_PORT_QTY > 1)) + { + Serial1.rx_complete_irq(); + } } int HardwareSerial::peek(void) @@ -151,8 +179,16 @@ size_t HardwareSerial::write(uint8_t c) { if (isInited) { - UART_WriteByte(UART_0, c); - UART_WaitTransmission(UART_0); + if (uartNum == 0) + { + UART_WriteByte(UART_0, c); + UART_WaitTransmission(UART_0); + } + else if (uartNum == 1) + { + UART_WriteByte(UART_1, c); + UART_WaitTransmission(UART_1); + } return 1; } else @@ -181,6 +217,8 @@ size_t HardwareSerial::write(const uint8_t *buffer, size_t size) void HardwareSerial::flush() { // wait for the data transfer complete - while((UART_0->FLAGS & UART_FLAGS_TC_M) == 0) - ; + if (uartNum == 0) + UART_WaitDataTranferCompleteFlag(UART_0); + else if (uartNum == 1) + UART_WaitDataTranferCompleteFlag(UART_1); } diff --git a/cores/arduino/HardwareSerial.h b/cores/arduino/HardwareSerial.h index 2847de9..d763cd6 100644 --- a/cores/arduino/HardwareSerial.h +++ b/cores/arduino/HardwareSerial.h @@ -27,6 +27,7 @@ #include #include "stdint.h" #include "Stream.h" +#include "pins_arduino.h" // Define constants and variables for buffering incoming serial data. We're // using a ring buffer (I think), in which head is the index of the location @@ -73,9 +74,14 @@ class HardwareSerial : public Stream private: bool isInited = false; + uint8_t uartNum; public: - inline HardwareSerial(){}; + inline HardwareSerial(uint8_t num) + { + // Set the UART to be used + uartNum = (num < SERIAL_PORT_QTY) ? num : 0; // UART0 by default + } void begin(unsigned long baud) { begin(baud, SERIAL_8N1); } void begin(unsigned long, uint8_t); @@ -98,6 +104,10 @@ class HardwareSerial : public Stream }; extern HardwareSerial Serial; +#if SERIAL_PORT_QTY > 1 +extern HardwareSerial Serial1; +#endif + extern void serialEventRun(void) __attribute__((weak)); #endif diff --git a/cores/arduino/mik32/shared/libs/uart_lib.c b/cores/arduino/mik32/shared/libs/uart_lib.c index 2fa0711..05e9f6d 100644 --- a/cores/arduino/mik32/shared/libs/uart_lib.c +++ b/cores/arduino/mik32/shared/libs/uart_lib.c @@ -64,6 +64,21 @@ bool UART_Init(UART_TypeDef* uart, return true; } +void UART_Deinit(UART_TypeDef* uart) +{ + if (uart == UART_0) + { + __HAL_PCC_UART_0_CLK_DISABLE(); + // reconfigure pins to z state + HAL_GPIO_PinConfig(GPIO_0, GPIO_PIN_5 | GPIO_PIN_6, HAL_GPIO_MODE_GPIO_INPUT, HAL_GPIO_PULL_NONE, HAL_GPIO_DS_2MA); + } + else if (uart == UART_1) + { + __HAL_PCC_UART_1_CLK_DISABLE(); + // reconfigure pins to z state + HAL_GPIO_PinConfig(GPIO_1, GPIO_PIN_8 | GPIO_PIN_9, HAL_GPIO_MODE_GPIO_INPUT, HAL_GPIO_PULL_NONE, HAL_GPIO_DS_2MA); + } +} bool UART_IsTransmissionFinished(UART_TypeDef* uart) { @@ -78,6 +93,14 @@ bool UART_IsTransmissionFinished(UART_TypeDef* uart) } } +void UART_WaitDataTranferCompleteFlag(UART_TypeDef* uart) +{ + // с этим флагом есть какая-то доп задержка в стоп-битах длиной почти с бит, + // но можно отслеживать полное завершение отправки посылки + while((uart->FLAGS & UART_FLAGS_TC_M) == 0) + ; +} + void UART_WaitTransmission(UART_TypeDef* uart) { while (!UART_IsTransmissionFinished(uart)) ; diff --git a/cores/arduino/mik32/shared/libs/uart_lib.h b/cores/arduino/mik32/shared/libs/uart_lib.h index 8cc75de..b910f88 100644 --- a/cores/arduino/mik32/shared/libs/uart_lib.h +++ b/cores/arduino/mik32/shared/libs/uart_lib.h @@ -38,6 +38,16 @@ bool UART_Init(UART_TypeDef* uart, uint32_t divider, uint32_t control1, uint32_t control2, uint32_t control3 ); +/** Деинициализирует контроллер USART + + Функция отключает тактирование модуля и перенастраивает + используемые для модуля выводы портов + + \param uart указатель для доступа к UART + +*/ +void UART_Deinit(UART_TypeDef* uart); + /** Определяет, активен ли передатчик модуля @@ -54,6 +64,11 @@ bool UART_IsTransmissionFinished(UART_TypeDef* uart); */ void UART_WaitTransmission(UART_TypeDef* uart); +/** Ожидает, пока модуль полностью завершит передачу + + \param uart указатель для доступа к UART + */ +void UART_WaitDataTranferCompleteFlag(UART_TypeDef* uart); /** Ожидает, пока модуль примет данные diff --git a/cores/arduino/trap_handler.c b/cores/arduino/trap_handler.c index aefc54f..5d01229 100644 --- a/cores/arduino/trap_handler.c +++ b/cores/arduino/trap_handler.c @@ -1,7 +1,7 @@ #include "mik32_hal_irq.h" // isr functions -extern void serial_handler_wrapper(void); +extern void serial_handler_wrapper(uint8_t uartNumInt); extern void gpio_interrupts_handler(void); extern void tone_interrupt_handler(void); void __attribute__((weak)) wire_handler_wrapper(void) @@ -16,9 +16,13 @@ void trap_handler(void) if (EPIC_CHECK_TIMER16_1()) tone_interrupt_handler(); - // uart interrupt + // uart0 interrupt if (EPIC_CHECK_UART_0()) - serial_handler_wrapper(); + serial_handler_wrapper(0); + + // uart1 interrupt + if (EPIC_CHECK_UART_1()) + serial_handler_wrapper(1); // gpio interrupt if (EPIC_CHECK_GPIO_IRQ()) diff --git a/variants/standart/pins_arduino.h b/variants/standart/pins_arduino.h index 1dcccfb..dabd353 100644 --- a/variants/standart/pins_arduino.h +++ b/variants/standart/pins_arduino.h @@ -23,13 +23,14 @@ #ifndef Pins_Arduino_h #define Pins_Arduino_h +#include "wiring_constants.h" + #ifdef __cplusplus extern "C" { #endif #include "mik32_hal_gpio.h" #include "mik32_hal_timer32.h" -#include "wiring_constants.h" extern bool spiNssPinIsBlocked; @@ -67,6 +68,10 @@ volatile uint32_t* portOutputRegister(GPIO_TypeDef* GPIO_x); // the function returns a reference to the STATE address of the GPIO register volatile uint32_t* portInputRegister(GPIO_TypeDef* GPIO_x); +// UART +// available uarts quantity +#define SERIAL_PORT_QTY 2 + // ADC // determines the ADC channel number by the board pin number uint32_t analogInputToChannelNumber(uint32_t PinNumber);