Merged with dev0.1.0
51
README.md
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
# elbear_arduino_bsp
|
||||||
|
Пакет поддержки платы Elbear Ace-Uno на базе микроконтроллера MIK32 Амур в среде программирования Arduino IDE.
|
||||||
|
|
||||||
|
|
||||||
|
## Установка пакета в ArduinoIDE
|
||||||
|
1. Установите [Arduino IDE](https://www.arduino.cc/en/software).
|
||||||
|
2. Откройте меню `Файл -> Параметры`.
|
||||||
|
3. Вставьте данную ссылку в поле "Дополнительные ссылки для Менеджера плат":
|
||||||
|
`https://gitflic.ru/project/elron-tech/elbear_arduino_board_manager_files/blob/raw?file=package_elbear_beta_index.json`
|
||||||
|

|
||||||
|
4. Откройте меню `Инструменты -> Плата -> Менеджер плат...`.
|
||||||
|
5. В поиске найдите плату `Elbear Ace-Uno`, выберите нужную версию и нажмите кнопку `Установить`.
|
||||||
|

|
||||||
|
6. Процесс установки может занять некоторое время. Результаты установки отобразятся в поле `Вывод`, а так же во всплывающих уведомлениях.
|
||||||
|

|
||||||
|
|
||||||
|
Для загрузки скетчей по USB в ArduinoIDE необходимо, чтобы на плату Elbear Ace-Uno была загружена специальная программа-загрузчик ([elbear_fw_bootloader](https://gitflic.ru/project/elron-tech/elbear_fw_bootloader)). Если она уже есть на плате, можно сразу переходить к работе. Если загрузчика еще нет или необходимо обновить его на плате, ниже описан процесс загрузки. Актуальная версия программы-загрузчика входит в состав пакета поддержки, отдельно скачивать её не нужно.
|
||||||
|
|
||||||
|
Платы ревизии 1.1.0 готовы к использованию в ArduinoIDE из коробки, так как поставляются с предварительно загруженной программой-загрузчиком.
|
||||||
|
|
||||||
|
## Загрузка программы-загрузчика через ArduinoIDE
|
||||||
|
1. Подключите плату Elbear Ace-Uno к ПК через программатор ELJTAG.
|
||||||
|
2. В ArduinoIDE выберите программатор: `Инструменты -> Программатор -> mik32 uploader`.
|
||||||
|
3. Для загрузки программы-загрузчика выберите `Инструменты -> Записать Загрузчик`.
|
||||||
|

|
||||||
|
4. При возникновении проблем с загрузкой ознакомьтесь с разделом `Настройка программатора` в [инструкции](https://elron.tech/wp-content/uploads/2024/05/instrukcija-po-pervomu-zapusku.pdf) по первому запуску платы ELBEAR ACE-UNO.
|
||||||
|
Теперь можно загружать скетчи в плату по USB.
|
||||||
|
|
||||||
|
## Начало работы
|
||||||
|
1. Подключите плату к ПК по USB.
|
||||||
|
2. Откройте ArduinoIDE и загрузите необходимый скетч. Для начала работы можно воспользоваться готовыми примерами, например - `Файл -> Примеры -> 01.Basics -> Blink`.
|
||||||
|

|
||||||
|
3. Выберите активную плату - `Инструменты -> Плата`.
|
||||||
|

|
||||||
|
4. Выберите используемый COM порт - `Инструменты -> Порт`.
|
||||||
|

|
||||||
|
Выбранные плата и порт в ArduinoIDE должны отображаться следующим образом:
|
||||||
|

|
||||||
|
5. Проверьте скетч, нажав соответствующую кнопку.
|
||||||
|

|
||||||
|
6. Загрузите полученную прошивку на плату.
|
||||||
|

|
||||||
|
7. При необходимости можно открыть терминал и получать сообщения от платы по интерфейсу Serial. Для этого выберите `Инструменты -> Монитор порта`.
|
||||||
|

|
||||||
|
|
||||||
|
|
||||||
|
При возникновении вопросов или выявлении проблем можно оставить заявку [здесь](https://gitflic.ru/project/elron-tech/elbear_arduino_bsp/issue).
|
||||||
|
|
||||||
|
# Полезные ссылки
|
||||||
|
* [Описание платы и ее распиновка](https://elron.tech/russian-arduino-compatible-board/)
|
||||||
|
* [Материалы для плат разных ревизий](https://elron.tech/materialy-dlja-elbear-ace-uno/)
|
||||||
@ -1,6 +1,6 @@
|
|||||||
# See: https://arduino.github.io/arduino-cli/latest/platform-specification/
|
# See: https://arduino.github.io/arduino-cli/latest/platform-specification/
|
||||||
##############################################################
|
##############################################################
|
||||||
aceUno8Mb.name=Elbear Ace-Uno 8Mb
|
aceUno8Mb.name=Elbear Ace-Uno
|
||||||
|
|
||||||
# tool for firmware update
|
# tool for firmware update
|
||||||
aceUno8Mb.upload.tool=elbear_uploader
|
aceUno8Mb.upload.tool=elbear_uploader
|
||||||
@ -16,7 +16,7 @@ aceUno8Mb.bootloader.file=ace-uno/bootloader.hex
|
|||||||
# build options
|
# build options
|
||||||
aceUno8Mb.build.mcu=MIK32_Amur
|
aceUno8Mb.build.mcu=MIK32_Amur
|
||||||
aceUno8Mb.build.f_cpu=32000000UL
|
aceUno8Mb.build.f_cpu=32000000UL
|
||||||
aceUno8Mb.build.board=ACE_UNO_8Mb
|
aceUno8Mb.build.board=ACE_UNO
|
||||||
aceUno8Mb.build.core=arduino
|
aceUno8Mb.build.core=arduino
|
||||||
aceUno8Mb.build.variant=standart
|
aceUno8Mb.build.variant=standart
|
||||||
aceUno8Mb.build.extra_flags=
|
aceUno8Mb.build.extra_flags=
|
||||||
|
|||||||
@ -35,11 +35,6 @@
|
|||||||
|
|
||||||
#include "wiring.h"
|
#include "wiring.h"
|
||||||
|
|
||||||
// define из avr-gcc (некоторые библиотеки ардуины им пользуются)
|
|
||||||
#define _BV(bit) (1 << (bit))
|
|
||||||
|
|
||||||
// void ErrorMsgHandler(const char * msg);
|
|
||||||
|
|
||||||
/* sketch */
|
/* sketch */
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
|||||||
@ -53,7 +53,6 @@ size_t Print::print(const __FlashStringHelper *ifsh)
|
|||||||
else break;
|
else break;
|
||||||
}
|
}
|
||||||
return n;
|
return n;
|
||||||
// return print(reinterpret_cast<const char *>(ifsh));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t Print::print(const String &s)
|
size_t Print::print(const String &s)
|
||||||
|
|||||||
@ -425,6 +425,7 @@ HAL_StatusTypeDef HAL_SPI_Exchange(SPI_HandleTypeDef *hspi, uint8_t TransmitByte
|
|||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return error_code;
|
||||||
|
|
||||||
error:
|
error:
|
||||||
__HAL_SPI_DISABLE(hspi);
|
__HAL_SPI_DISABLE(hspi);
|
||||||
@ -544,6 +545,7 @@ HAL_StatusTypeDef HAL_SPI_ExchangeThreshold(SPI_HandleTypeDef *hspi, uint8_t Tra
|
|||||||
tx_counter = 0;
|
tx_counter = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return error_code;
|
||||||
|
|
||||||
error:
|
error:
|
||||||
__HAL_SPI_DISABLE(hspi);
|
__HAL_SPI_DISABLE(hspi);
|
||||||
|
|||||||
@ -21,6 +21,7 @@
|
|||||||
|
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
#include "wiring_private.h"
|
||||||
|
|
||||||
#define HIGH 0x1
|
#define HIGH 0x1
|
||||||
#define LOW 0x0
|
#define LOW 0x0
|
||||||
@ -80,7 +81,8 @@ enum BitOrder
|
|||||||
#define sq(x) ((x)*(x))
|
#define sq(x) ((x)*(x))
|
||||||
|
|
||||||
// Bits and Bytes
|
// Bits and Bytes
|
||||||
#define bit(b) (1UL << (b))
|
#define _BV(bit) (1 << (bit)) // from avr-gcc (some arduino libs uses it)
|
||||||
|
#define bit(b) (1UL << (b))
|
||||||
#define lowByte(w) ((uint8_t) ((w) & 0xff))
|
#define lowByte(w) ((uint8_t) ((w) & 0xff))
|
||||||
#define highByte(w) ((uint8_t) ((w) >> 8))
|
#define highByte(w) ((uint8_t) ((w) >> 8))
|
||||||
|
|
||||||
|
|||||||
@ -10,6 +10,8 @@
|
|||||||
extern "C"{
|
extern "C"{
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// available interrupts number
|
||||||
|
#define EXTERNAL_NUM_INTERRUPTS 7
|
||||||
|
|
||||||
typedef void (*voidFuncPtr)(void);
|
typedef void (*voidFuncPtr)(void);
|
||||||
|
|
||||||
|
|||||||
BIN
docs/Add_board.PNG
Normal file
|
After Width: | Height: | Size: 47 KiB |
BIN
docs/Blink_example.png
Normal file
|
After Width: | Height: | Size: 51 KiB |
BIN
docs/Bootloader.png
Normal file
|
After Width: | Height: | Size: 66 KiB |
BIN
docs/Build_project.png
Normal file
|
After Width: | Height: | Size: 14 KiB |
BIN
docs/Flash_project.png
Normal file
|
After Width: | Height: | Size: 14 KiB |
BIN
docs/Install_board.PNG
Normal file
|
After Width: | Height: | Size: 24 KiB |
BIN
docs/Installation_process.PNG
Normal file
|
After Width: | Height: | Size: 65 KiB |
BIN
docs/Monitor.png
Normal file
|
After Width: | Height: | Size: 79 KiB |
BIN
docs/Selected_board_port.png
Normal file
|
After Width: | Height: | Size: 33 KiB |
BIN
docs/Set_board.png
Normal file
|
After Width: | Height: | Size: 87 KiB |
BIN
docs/Set_port.png
Normal file
|
After Width: | Height: | Size: 61 KiB |
@ -1,4 +1,5 @@
|
|||||||
#include "SPI.h"
|
#include "SPI.h"
|
||||||
|
#include "mik32_hal_spi.h"
|
||||||
|
|
||||||
SPI_HandleTypeDef hspi;
|
SPI_HandleTypeDef hspi;
|
||||||
bool newConfig = false;
|
bool newConfig = false;
|
||||||
@ -204,7 +205,7 @@ uint8_t SPIClass::transfer(uint8_t data)
|
|||||||
data = reverse_bits(data);
|
data = reverse_bits(data);
|
||||||
|
|
||||||
// send and recieve data
|
// send and recieve data
|
||||||
HAL_StatusTypeDef SPI_Status = exchange(&hspi, &data, &rxByte, 1, SPI_TIMEOUT_DEFAULT*2);
|
HAL_StatusTypeDef SPI_Status = HAL_SPI_Exchange(&hspi, &data, &rxByte, 1, SPI_TIMEOUT_DEFAULT*2);
|
||||||
if (SPI_Status != HAL_OK)
|
if (SPI_Status != HAL_OK)
|
||||||
HAL_SPI_ClearError(&hspi);
|
HAL_SPI_ClearError(&hspi);
|
||||||
|
|
||||||
@ -236,7 +237,7 @@ uint16_t SPIClass::transfer16(uint16_t data)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// send and recieve data
|
// send and recieve data
|
||||||
HAL_StatusTypeDef SPI_Status = exchange(&hspi, buf, buf, 2, SPI_TIMEOUT_DEFAULT*2);
|
HAL_StatusTypeDef SPI_Status = HAL_SPI_Exchange(&hspi, buf, buf, 2, SPI_TIMEOUT_DEFAULT*2);
|
||||||
if (SPI_Status != HAL_OK)
|
if (SPI_Status != HAL_OK)
|
||||||
HAL_SPI_ClearError(&hspi);
|
HAL_SPI_ClearError(&hspi);
|
||||||
|
|
||||||
@ -267,7 +268,7 @@ void SPIClass::transfer(void *buf, size_t count)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// send and recieve data using the same buffer
|
// send and recieve data using the same buffer
|
||||||
HAL_StatusTypeDef SPI_Status = exchange(&hspi, (uint8_t*)buf, (uint8_t*)buf, count, SPI_TIMEOUT_DEFAULT*2);
|
HAL_StatusTypeDef SPI_Status = HAL_SPI_Exchange(&hspi, (uint8_t*)buf, (uint8_t*)buf, count, SPI_TIMEOUT_DEFAULT*2);
|
||||||
if (SPI_Status != HAL_OK)
|
if (SPI_Status != HAL_OK)
|
||||||
HAL_SPI_ClearError(&hspi);
|
HAL_SPI_ClearError(&hspi);
|
||||||
|
|
||||||
@ -329,66 +330,6 @@ void SPIClass::setClockDivider(uint8_t clockDiv)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
HAL_StatusTypeDef SPIClass::exchange(SPI_HandleTypeDef *hspi, uint8_t TransmitBytes[], uint8_t ReceiveBytes[], uint32_t DataSize, uint32_t Timeout)
|
|
||||||
{
|
|
||||||
uint32_t txallowed = 1;
|
|
||||||
HAL_StatusTypeDef error_code = HAL_OK;
|
|
||||||
uint32_t timeout_counter = 0;
|
|
||||||
|
|
||||||
hspi->ErrorCode = HAL_SPI_ERROR_NONE;
|
|
||||||
hspi->pRxBuffPtr = (uint8_t *)ReceiveBytes;
|
|
||||||
hspi->RxCount = DataSize;
|
|
||||||
hspi->pTxBuffPtr = (uint8_t *)TransmitBytes;
|
|
||||||
hspi->TxCount = DataSize;
|
|
||||||
|
|
||||||
hspi->Instance->TX_THR = 1;
|
|
||||||
|
|
||||||
/* Включить SPI если выключено */
|
|
||||||
if (!(hspi->Instance->ENABLE & SPI_ENABLE_M))
|
|
||||||
{
|
|
||||||
__HAL_SPI_ENABLE(hspi);
|
|
||||||
}
|
|
||||||
|
|
||||||
while ((hspi->TxCount > 0) || (hspi->RxCount > 0))
|
|
||||||
{
|
|
||||||
/* Проверка флага TX_FIFO_NOT_FULL */
|
|
||||||
if ((hspi->Instance->INT_STATUS & SPI_INT_STATUS_TX_FIFO_NOT_FULL_M) && (hspi->TxCount > 0) && (txallowed == 1))
|
|
||||||
{
|
|
||||||
hspi->Instance->TXDATA = *(hspi->pTxBuffPtr);
|
|
||||||
hspi->pTxBuffPtr++;
|
|
||||||
hspi->TxCount--;
|
|
||||||
/* Следующие данные - прием (Rx). Tx не разрешен */
|
|
||||||
txallowed = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Ожидание когда установится флаг RX_FIFO_NOT_EMPTY */
|
|
||||||
if ((hspi->Instance->INT_STATUS & SPI_INT_STATUS_RX_FIFO_NOT_EMPTY_M) && (hspi->RxCount > 0))
|
|
||||||
{
|
|
||||||
*(hspi->pRxBuffPtr) = hspi->Instance->RXDATA;
|
|
||||||
hspi->pRxBuffPtr++;
|
|
||||||
hspi->RxCount--;
|
|
||||||
/* Следующие данные - передача (Tx). Tx разрешается */
|
|
||||||
txallowed = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (((timeout_counter++) >= Timeout) || (Timeout == 0U))
|
|
||||||
{
|
|
||||||
error_code = HAL_TIMEOUT;
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return error_code;
|
|
||||||
|
|
||||||
error:
|
|
||||||
__HAL_SPI_DISABLE(hspi);
|
|
||||||
hspi->Instance->ENABLE |= SPI_ENABLE_CLEAR_TX_FIFO_M | SPI_ENABLE_CLEAR_RX_FIFO_M; /* Очистка буферов RX и TX */
|
|
||||||
volatile uint32_t unused = hspi->Instance->INT_STATUS; /* Очистка флагов ошибок чтением */
|
|
||||||
(void) unused;
|
|
||||||
|
|
||||||
|
|
||||||
return error_code;
|
|
||||||
}
|
|
||||||
|
|
||||||
static uint8_t reverse_bits(uint8_t byte)
|
static uint8_t reverse_bits(uint8_t byte)
|
||||||
{
|
{
|
||||||
byte = (byte & 0xF0) >> 4 | (byte & 0x0F) << 4;
|
byte = (byte & 0xF0) >> 4 | (byte & 0x0F) << 4;
|
||||||
|
|||||||
@ -15,7 +15,6 @@
|
|||||||
#define _SPI_H_INCLUDED
|
#define _SPI_H_INCLUDED
|
||||||
|
|
||||||
#include <Arduino.h>
|
#include <Arduino.h>
|
||||||
#include "mik32_hal_spi.h"
|
|
||||||
|
|
||||||
// SPI_HAS_TRANSACTION means SPI has beginTransaction(), endTransaction(),
|
// SPI_HAS_TRANSACTION means SPI has beginTransaction(), endTransaction(),
|
||||||
// usingInterrupt(), and SPISetting(clock, bitOrder, dataMode)
|
// usingInterrupt(), and SPISetting(clock, bitOrder, dataMode)
|
||||||
@ -121,9 +120,6 @@ public:
|
|||||||
// This function is deprecated. New applications should use
|
// This function is deprecated. New applications should use
|
||||||
// beginTransaction() to configure SPI settings.
|
// beginTransaction() to configure SPI settings.
|
||||||
void setClockDivider(uint8_t clockDiv);
|
void setClockDivider(uint8_t clockDiv);
|
||||||
|
|
||||||
// A temporary function until this error is fixed in the HAL library
|
|
||||||
HAL_StatusTypeDef exchange(SPI_HandleTypeDef *hspi, uint8_t TransmitBytes[], uint8_t ReceiveBytes[], uint32_t DataSize, uint32_t Timeout);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
extern SPIClass SPI;
|
extern SPIClass SPI;
|
||||||
|
|||||||
@ -63,9 +63,9 @@ HAL_PinsTypeDef digitalPinToBitMask(uint32_t digPinNumber);
|
|||||||
// total number of pins available for initialization
|
// total number of pins available for initialization
|
||||||
uint16_t pinCommonQty(void);
|
uint16_t pinCommonQty(void);
|
||||||
// the function returns a reference to the OUTPUT address of the GPIO register
|
// the function returns a reference to the OUTPUT address of the GPIO register
|
||||||
uint32_t* portOutputRegister(GPIO_TypeDef* GPIO_x);
|
volatile uint32_t* portOutputRegister(GPIO_TypeDef* GPIO_x);
|
||||||
// the function returns a reference to the STATE address of the GPIO register
|
// the function returns a reference to the STATE address of the GPIO register
|
||||||
uint32_t* portInputRegister(GPIO_TypeDef* GPIO_x);
|
volatile uint32_t* portInputRegister(GPIO_TypeDef* GPIO_x);
|
||||||
|
|
||||||
// ADC
|
// ADC
|
||||||
// determines the ADC channel number by the board pin number
|
// determines the ADC channel number by the board pin number
|
||||||
@ -110,7 +110,6 @@ static const uint8_t SCL = PIN_WIRE_SCL;
|
|||||||
#define WIRE_FREQ_1000K 1000000
|
#define WIRE_FREQ_1000K 1000000
|
||||||
|
|
||||||
// interrupts
|
// interrupts
|
||||||
#define EXTERNAL_NUM_INTERRUPTS 7
|
|
||||||
// determines the board pin number by interrupt number
|
// determines the board pin number by interrupt number
|
||||||
uint32_t interruptToDigitalPin(uint8_t interruptNum);
|
uint32_t interruptToDigitalPin(uint8_t interruptNum);
|
||||||
// determines interrupt number by the board pin number
|
// determines interrupt number by the board pin number
|
||||||
|
|||||||
@ -95,24 +95,24 @@ uint16_t pinCommonQty(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// the function returns a reference to the OUTPUT address of the GPIO register
|
// the function returns a reference to the OUTPUT address of the GPIO register
|
||||||
uint32_t* portOutputRegister(GPIO_TypeDef* GPIO_x)
|
volatile uint32_t* portOutputRegister(GPIO_TypeDef* GPIO_x)
|
||||||
{
|
{
|
||||||
return &GPIO_x->OUTPUT_;
|
return &GPIO_x->OUTPUT_;
|
||||||
}
|
}
|
||||||
|
|
||||||
// the function returns a reference to the STATE address of the GPIO register
|
// the function returns a reference to the STATE address of the GPIO register
|
||||||
uint32_t* portInputRegister(GPIO_TypeDef* GPIO_x)
|
volatile uint32_t* portInputRegister(GPIO_TypeDef* GPIO_x)
|
||||||
{
|
{
|
||||||
return &GPIO_x->STATE;
|
return &GPIO_x->STATE;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---------------------- АЦП ---------------------- //
|
// ---------------------- ADC ---------------------- //
|
||||||
// determines the ADC channel number by the board pin number
|
// determines the ADC channel number by the board pin number
|
||||||
uint32_t analogInputToChannelNumber(uint32_t PinNumber)
|
uint32_t analogInputToChannelNumber(uint32_t PinNumber)
|
||||||
{
|
{
|
||||||
uint32_t adcChannel = 0;
|
uint32_t adcChannel = 0;
|
||||||
|
|
||||||
// if passed a value from 0 - 5, instead of A0 - A5
|
// if get a value 0...5 instead of A0...A5
|
||||||
if (PinNumber < 4) PinNumber += 14;
|
if (PinNumber < 4) PinNumber += 14;
|
||||||
else if (PinNumber < 6) PinNumber += 16;
|
else if (PinNumber < 6) PinNumber += 16;
|
||||||
|
|
||||||
|
|||||||