Compare commits

...

47 Commits
main ... main

Author SHA1 Message Date
48f0786566 обновлены ссылки на документацию по платам 2026-02-18 14:55:06 +07:00
c233edddd8 Добавлено примечание о версии драйвера ch340 2025-09-08 12:41:52 +03:00
00e8d1b1af Обновить docs/Elbear_description.md 2025-09-08 12:40:39 +03:00
0fbfd77518 v0.5.3
- начальный загрузчик для плат elbear, elsomik обновлен до версии 0.2.0
- исключено появление краткосрочных просадок при работе ШИМ с максимальным коэффициентом заполнения
- добавлена возможность пропускать код стандартного обработчика прерываний при использовании пользовательского обработчика
- добавлена возможность конфигурирования вывода на вход с притяжкой к земле (INPUT_PULLDOWN)
- исправление известных ошибок
2025-08-06 08:42:39 +03:00
8a675b2f61 Обновить docs/elsomik_description.md 2025-07-21 10:14:36 +03:00
fef9b6e2bf Удалить docs/pinout_ElsomikOEM.png 2025-07-18 10:45:28 +03:00
0a5482b7c9 Обновить docs/elsomik_description.md 2025-07-18 10:45:06 +03:00
5be685ce7b Загрузить файлы в «docs» 2025-07-18 10:44:47 +03:00
1d850f20d0 Обновить README.md 2025-07-18 09:25:49 +03:00
20c1b9bd4e Обновить docs/Instructions.md 2025-07-18 09:21:28 +03:00
6b50a0201c Обновить docs/debug_description.md 2025-07-18 09:19:20 +03:00
262826c3b6 Обновить docs/Instructions.md 2025-07-18 09:16:28 +03:00
1042468094 Обновить docs/debug_description.md 2025-07-18 06:26:16 +03:00
34c86da403 Обновить docs/Instructions.md 2025-07-18 06:23:33 +03:00
1a73000ae9 v0.5.2
- исправлены ошибки при работе с пользователями, в имени которых есть пробелы
- исправлены ошибки при работе с программатором на win11
- исправлены известные ошибки
2025-07-15 09:36:38 +03:00
f81c108d44 Добавил BMP280, VL53L0X, MCP2515 и DS18B20
Добавил BMP280, VL53L0X, MCP2515 и DS18B20 (:
2025-06-22 15:17:59 +03:00
df1d14a57c Добавлена функция инициализации параметров SPI по умолчанию 2025-06-04 12:33:52 +03:00
e39767832a Добавлена функция инициализации параметров SPI по умолчанию 2025-06-04 16:33:03 +07:00
149804cc07 Обновить README.md 2025-06-02 12:06:21 +03:00
643eb94344 Протестированные библиотеки вынесены в отдельный файл 2025-06-02 12:04:49 +03:00
eb9b1aa0c9 v0.5.1
- в модулях Wire, SPI, Serial приведена в соответствие нумерация используемых экземпляров и периферии микроконтроллера.
- в функции analogWrite() перед запуском ШИМ проверяется, не запущен ли уже указанный канал.
- добавлена возможность переопределения функции main() в скетчах.
- при старте программы задается граница кэшируемой области SPIFI в соответствии с размером текущего исполняемого кода.
- исправление выявленных ошибок.
Co-authored-by: KLASSENTS <klassen@elron.tech>
Co-committed-by: KLASSENTS <klassen@elron.tech>
2025-05-30 12:24:08 +03:00
f1e091bf77 Добавил AHT10, MCP472 и PIR
Добавил AHT10, MCP472 и PIR (AM312, SR501, SR602 и SR505)
2025-05-05 19:57:48 +03:00
d93e4e4ba4 Отделил таблицу 2025-05-05 12:12:42 +07:00
112614e93b обновление картинок в описании
Co-authored-by: KLASSENTS <klassen@elron.tech>
Co-committed-by: KLASSENTS <klassen@elron.tech>
2025-05-05 07:47:28 +03:00
f000b346e8 Уточнение про Arduino IDE 2.3.4 2025-04-28 09:32:24 +03:00
1c8e06634c v0.5.0
- добавлена поддержка платы ELBEAR ACE-NANO;
- добавлена поддержка плат ELSOMIK OEM и SE;
- добавлена возможность работы в режиме отладки для всех плат, входящих в состав пакета. Доступно для версии ArduinoIDE 2 и выше;
- добавлена поддержка библиотеки FreeRTOS;
- добавлена поддержка библиотеки IRremote;
- добавлена поддержка библиотеки OneWire;
- добавлена поддержка аппаратного I2C0 для плат START-MIK32 и ELSOMIK. Для работы с ним доступен экземпляр класса Wire1;
- добавлена поддержка аппаратного SPI0 для всех плат, входящих в пакет. Для работы с ним доступен экземпляр класса SPI1;
- увеличено быстродействие функций digitalWrite, digitalRead;
- исправлены известные ошибки.
Co-authored-by: KlassenTS <klassen@elron.tech>
Co-committed-by: KlassenTS <klassen@elron.tech>
2025-04-28 07:06:08 +03:00
de1f0d7fda Добавил HW-MS03
Датчик движения HW-MS03
2025-04-18 13:06:13 +03:00
54dc987661 LoRa модуль E32-170T30D
Добавил протестированный LoRa модуль E32-170T30D
2025-04-09 21:52:56 +03:00
56d5d07cfe Добавил гироскоп MPU6050
Модуль гироскопа и акселерометра MPU6050
2025-04-04 20:24:52 +03:00
5f300f9ac8 Добавил CC1101
Добавил радиомодуль CC1101 433 МГц и ссылки на видео для дисплея E-link 2.13 от Heltec
2025-04-01 15:26:05 +03:00
6db7afe564 Обновить docs/tested_shields.md 2025-03-31 09:49:16 +03:00
f322f19938 Добавлен список протестированных модулей 2025-03-31 09:19:33 +03:00
3cf1fdf3d0 Обновить README.md 2025-03-31 07:43:52 +03:00
a32d749c60 добавлена поддержка еще одного прерывания и еще двух выводов для ШИМ для
платы Elbear. добавлены флаги компиляции, необходимые для работы в
ArduinoIDE v1.8.19
2025-02-04 14:31:10 +07:00
f06650400b добавлена поддержка платы Start-MIK32 2025-02-04 14:24:52 +07:00
8c82685f37 fix for flashing on linux 2025-02-04 14:24:50 +07:00
fd9e0a1ce2 Обновить README.md 2025-02-04 14:24:50 +07:00
7261b03ea1 Обновление до версии 0.3.0
- обновлен elbear_fw_bootloader - добавлена проверка контрольной суммы каждой строки hex файла.
- в модуль работы с АЦП добавлена функция analogReadResolution(). Функция analogRead() теперь возвращает усредненное по 10 измерениям значение.
- общая функция обработки прерываний перенесена в память RAM. Обработчики прерываний модулей External Interrupts и Advanced I/O (функция tone()) так же перенесены в память RAM для увеличения скорости выполнения кода.
- в пакет добавлены библиотеки EEPROM, Servo, SoftSerial, NeoPixel, MFRC522 адаптированные для работы с платой Elbear Ace-Uno.
- добавлено описание особенностей работы с пакетом
2025-02-04 14:24:50 +07:00
2044614aba Обновлен README.md 2025-02-04 14:24:49 +07:00
66cbf1a67f Обновлен bootloader
- Притяжка к питанию на Rx
- Новая команда для full erase
- При получении "мусорных" байтов не реагируем и отключаемся по таймауту
2025-02-04 14:24:49 +07:00
a08072dc3b Удалить bootloaders/ace-uno/elbear_fw_bootloader_qpi_xip_cshigh_0.hex 2025-02-04 14:24:49 +07:00
295d68c3f4 Удалить bootloaders/ace-uno/bootloader.hex 2025-02-04 14:24:49 +07:00
221a587857 Merged with dev_beta 2025-02-04 14:24:49 +07:00
186e182c1d Добавлен файл Add_board.PNG 2025-02-04 14:24:49 +07:00
2b855b10e6 Удален файл Add_board.PNG 2025-02-04 14:24:49 +07:00
444e9e7af1 Обновила ссылку, надеюсь на финальную версию 2025-02-04 14:24:49 +07:00
0cc714ccf9 Merged with dev0.1.0 2025-02-04 14:24:49 +07:00
356 changed files with 111093 additions and 1738 deletions

2
.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
installed.json
.vscode/

113
README.md Normal file
View File

@ -0,0 +1,113 @@
# elbear_arduino_bsp
Пакет поддержки плат на базе микроконтроллера MIK32 Амур в среде программирования Arduino IDE.
## Установка пакета в ArduinoIDE и подготовка к работе
Для установки пакета в параметрах ArduinoIDE необходимо добавить ссылку `https://elron.tech/files/package_elbear_beta_index.json` в поле "Дополнительные ссылки для Менеджера плат".
Подробные шаги по установке, начальной настройке и записи начального загрузчика для всех поддерживаемых плат описаны в [инструкции](./docs/Instructions.md).
## Платы, входящие в состав пакета
Пакет включает в себя поддержку следующих плат:
- [ELBEAR ACE-UNO](./docs/Elbear_description.md) 8 Mb / 16 Mb / 32 Mb
- [ELBEAR ACE-NANO](./docs/nano_description.md)
- [ELSOMIK](./docs/elsomik_description.md)
- [START-MIK32](./docs/Start_mik32_description.md)
## Особенности использования пакета в ArduinoIDE
### Цифровые выводы
В отличие от стандартного функционала Arduino на платах, входящих в состав пакета, невозможно управлять притяжками цифрового вывода, настроенного на вход, с помощью функции `void digitalWrite(uint32_t PinNumber, uint32_t Val)`. Для включения притяжки к питанию необходимо воспользоваться функцией `pinMode(PinNumber, INPUT_PULLUP)`.
Доступна возможность конфигурирования цифрового вывода на вход с притяжкой к земле, для этого необходимо использовать макрос `INPUT_PULLDOWN` - `pinMode(PinNumber, INPUT_PULLDOWN)`.
Для инвертирования состояния цифровых выводов доступна функция `void digitalToggle(uint32_t PinNumber)`.
### Аналоговые выводы
#### АЦП
Встроенный в MIK32 АЦП обладает разрешением 12 бит, однако по умолчанию в Arduino IDE применяется разрешение 10 бит. С помощью функции `void analogReadResolution(uint8_t resolution)` можно изменять разрешение в диапазоне от 1 до 32 бит.
Функция `uint32_t analogRead(uint32_t PinNumber)` возвращает результаты измерения после усреднения по 10 значениям.
Номера выводов, поддерживающих АЦП, отличаются для каждой платы и перечислены в их описаниях.
#### ШИМ
По умолчанию частота сформированного ШИМ-сигнала составляет 1 кГц. Функция `void analogWriteFrequency(uint32_t freq)` позволяет изменить частоту сигнала в диапазоне от 1 Гц до 1 МГц.
По умолчанию разрешение, используемое в функции `void analogWrite(uint32_t PinNumber, uint32_t writeVal)`, составляет 8 бит. Функция `void analogWriteResolution(uint8_t resolution)` позволяет измененить разрешение в диапазоне от 1 до 32 бит.
Остановить генерацию ШИМ-сигнала можно, вызвав функцию `void analogWriteStop(uint32_t PinNumber)` или функции `void digitalWrite(uint32_t PinNumber, uint32_t Val)`/`int digitalRead(uint32_t PinNumber)`.
Номера выводов, поддерживающих ШИМ, отличаются для каждой платы и перечислены в их описаниях.
### Прерывания
Платы, входящих в состав пакета, позволяют использовать прерывания, настраиваемые функцией `void attachInterrupt(uint8_t interruptNum, void (*userFunc)(void), int mode)`. Номера выводов, поддерживающих прерывания, отличаются для каждой платы и перечислены в их описаниях.
Для получения номера прерывания по номеру вывода существует функция `int8_t digitalPinToInterrupt(uint32_t digPinNumber)`.
В микроконтроллере MIK32 предусмотрен всего один вектор прерывания. Когда срабатывает прерывание от любого источника, общая функция-обработчик последовательно проверяет все возможные источники и, при необходимости, вызывает соответствующие обработчики конкретных модулей. Поэтому важно, чтобы функции, вызываемые при прерываниях, были небольшими и обеспечивали максимально быстрое завершение обработки. Это позволит избежать задержек и снизит риск пропуска последующих прерываний.
Общая функция-обработчик прерываний располагается в RAM памяти. Это позволяет устранить задержки, связанные с кэшированием при работе из FLASH памяти. Обработчики прерываний, назначаемые на цифровые выводы с помощью функции `void attachInterrupt(uint8_t interruptNum, void (*userFunc)(void), int mode)`, и обработчик прерывания для функции `tone()` так же располагаются в памяти RAM.
Глобальное разрешение прерываний активируется после завершения функции `setup()`. Если необходимо использовать прерывания внутри самой функции `setup()`, их можно включить вручную, вызвав функцию `interrupts()` перед вызовом функций, работающих с прерываниями. Прерывания используются для приема данных модулями `Serial`, `Wire`, для работы библиотеки `Servo`, функцией `tone()`.
В пакете поддержки доступна возможность дополнения или замены стандартного обработчика прерываний пользовательской функцией-обработчиком. Для этого в своем скетче необходимо определить функцию `extern "C" bool ISR()`, она вызывается первой в стандартном обработчике. Внутри функции можно проверять флаги прерываний и реагировать на нужные. Важно очищать флаги обрабатываемых прерываний, чтобы обработчик работал корректно.
Если функция возвращает `false`, после ее выполнения так же будет выполнен код стандартного обработчика прерываний. Если функция возвращает `true`, выполнение кода стандартного обработчика будет пропущено.
Пользовательскую функцию необходимо располагать в RAM памяти, так как стандартный обработчик прерываний расположен именно там.
Ниже приведен пример пользовательского обработчика прерывания по переполнению от 16-битного таймера 1:
```
extern "C" __attribute__((section(".ram_text"))) bool ISR(void)
{
// обработка прерывания от 16-битного таймера
if (EPIC_CHECK_TIMER16_1())
{
if (TIM16_GET_ARRM_INT_STATUS(htimer16_1_))
{
// необходимые действия при переполнении таймера
}
// очистить флаги прерывания от таймера 1
TIM16_CLEAR_INT_MASK(htimer16_1_, 0xFFFFFFFF);
}
return false;
}
```
Для корректной работы функции из примера необходимо подключить в скетче следующие файлы:
```
#include "mik32_hal_timer16.h"
#include "wiring_LL.h"
```
### Serial
Для работы доступно два последовательных интерфейса. Нулевой интерфейс используется экземпляром класса `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 Амур и/или адаптированы для работы с ним.
|Библиотека|Описание|Заметки|
|---------|---------|------|
|[SPI](https://docs.arduino.cc/language-reference/en/functions/communication/SPI/)|Библиотека для работы с интерфейсом SPI|Для работы доступно два экземпляра класса - SPI (используется аппаратный SPI1) и SPI1 (используется аппаратный SPI0). Выводы, на которых доступны интерфейсы, перечислены в описании каждой платы. Доступные делители частоты - `SPI_CLOCK_DIV2`, `SPI_CLOCK_DIV4`, `SPI_CLOCK_DIV8`, `SPI_CLOCK_DIV16`, `SPI_CLOCK_DIV32`, `SPI_CLOCK_DIV64`, `SPI_CLOCK_DIV128`, `SPI_CLOCK_DIV256`, обеспечивают частоту работы от 125 кГц до 16 МГц. Скорость работы по умолчанию - 4 МГц. Для задания режима и скорости работы рекомендуется использовать `SPISettings(uint32_t speedMaximum, uint8_t dataOrder, uint8_t dataMode)`, а не соответствующие отдельные функции|
|[Wire](https://docs.arduino.cc/language-reference/en/functions/communication/Wire/)|Библиотека для работы с интерфейсом I2C|Для работы используется встроенный I2C1. Доступные частоты работы интерфейса: 100 кГц (`WIRE_FREQ_100K`), 400 кГц (`WIRE_FREQ_400K`), 1000 кГц (`WIRE_FREQ_1000K`). Скорость работы по умолчанию - 100 кГц. В режиме работы в качестве ведомого устройства функции, заданные через `void onReceive( void (*)(int)` и `void onRequest( void (*)(void) )`, выполняются в прерывании|
|[SoftwareSerial](https://docs.arduino.cc/learn/built-in-libraries/software-serial/)|Библиотека, реализующая программный последовательный интерфейс.|Доступные скорости работы - от 300 до 57600 бод. Для отправки данных (TX) можно использовать любой цифровой вывод. Для приема данных (RX) можно использовать только выводы, поддерживающие прерывания. Обработчик прерывания и связанные с ним функции располагаются в памяти RAM|
|[EEPROM](https://docs.arduino.cc/learn/built-in-libraries/eeprom/)|Библиотека для работы с памятью EEPROM|Для использования доступно 1024 байта встроенной EEPROM памяти. Для корректной работы библиотеки обязательно вызывать функцию `void EEPROM.begin()` перед началом работы с памятью|
|[Servo](https://docs.arduino.cc/libraries/servo/)|Библиотека для работы с сервоприводом|Библиотека использует 16-битный таймер 2 и прерывания от него. Любой цифровой вывод подходит для управления сервоприводом. Одновременно можно использовать до 12 сервоприводов. Для работы библиотеки используется таймер timer16_2|
|[NeoPixel](https://docs.arduino.cc/libraries/adafruit-neopixel/)|Библиотека для работы с адресными светодиодами|Функция, выводящая состояние пикселей на цифровой вывод платы, перенесена в память RAM для корректной работы на MIK32 Амур|
|[MFRC522](https://docs.arduino.cc/libraries/mfrc522/)|Библиотека для работы с RFID картами|Исправлен баг, вызывающий ошибку компиляции в новых компиляторах gcc|
|[OneWire](https://docs.arduino.cc/libraries/onewire/)|Библиотека для работы с интерфейсом 1-Wire|В стандартную библиотеку добавлена поддержка микроконтроллера MIK32 Amur|
|[IRremote](https://docs.arduino.cc/libraries/irremote/)|Библиотека позволяет отправлять и принимать инфракрасные сигналы, используя определенный набор протоколов|В стандартную библиотеку добавлена поддержка микроконтроллера MIK32 Amur. При приеме данных используется прерывание таймера timer16_0, работает с любым цифровым выводом. Для отправки данных с помощью встроенного ШИМ для плат Elbear Ace-Uno используется вывод D3, для платы START-MIK32 - вывод P0_0|
|[FreeRTOS](https://docs.arduino.cc/libraries/freertos/)|Библиотека для работы с операционной системой реального времени FreeRTOS|В стандартную библиотеку добавлена поддержка микроконтроллера MIK32 Amur. Период системного тика составляет 10 мс и формируется с помощью машинного таймера SysTick|
## Протестированные библиотеки
Список библиотек, работа которых была протестирована на платах, входящих в состав пакета поддержки, доступен [здесь](./docs/tested_libs.md).
## Протестированные модули
Список модулей и шилдов, работа которых была протестирована на платах, входящих в состав пакета поддержки, доступен [здесь](./docs/tested_shields.md).
## Режим отладки
Для всех плат, входящих в состав пакета, доступен режим отладки скетча в Arduino IDE версии 2.3.4 на Windows 10 x64. Подготовка к работе в режиме отладки описана в [инструкции.](./docs/debug_description.md) Функция отладки является экспериментальной.
## Полезные ссылки
* [Проблемы и их решения при работе с пакетом в Arduino IDE](https://docs.elron.tech/arduino/available-ide/arduinoIDE-bsp/bsp-troubleshooting)
* [Описание плат ELBEAR](https://docs.elron.tech/arduino/)
* [Материалы по платам ELBEAR ACE-UNO](https://docs.elron.tech/arduino/elbear-ace-uno)
* [Материалы по платам ELBEAR ACE-NANO](https://docs.elron.tech/arduino/elbear-ace-nano)
* [Материалы по платам ELSOMIK](https://docs.elron.tech/som/)
* [Материалы по плате START-MIK32](https://docs.mikron.ru/wiki/boards/start.html)
* [Телеграмм-канал компании](https://t.me/elrontech)
При возникновении вопросов или выявлении проблем можно оставить заявку [здесь](https://gitflic.ru/project/elron-tech/elbear_arduino_bsp/issue).

View File

@ -1,23 +1,161 @@
# See: https://arduino.github.io/arduino-cli/latest/platform-specification/
##############################################################
aceUno8Mb.name=Elbear Ace-Uno 8Mb
##################### ACE-UNO 8 Mb #####################
aceUno8Mb.name=ELBEAR ACE-UNO 8 Mb
# tool for firmware update
aceUno8Mb.upload.tool=elbear_uploader
aceUno8Mb.upload.protocol=elbear_uploader
aceUno8Mb.upload.maximum_size=8388608
aceUno8Mb.upload.maximum_data_size=16384
aceUno8Mb.upload.speed=230400
# tool for bootloader update
aceUno8Mb.bootloader.tool=mik32_upload
aceUno8Mb.bootloader.tool.default=mik32_upload
aceUno8Mb.bootloader.file=ace-uno/bootloader.hex
aceUno8Mb.bootloader.file=elbear/bootloader.hex
aceUno8Mb.bootloader.interface=ftdi/mikron-link.cfg
aceUno8Mb.bootloader.params.verbose=
# build options
aceUno8Mb.build.mcu=MIK32_Amur
aceUno8Mb.build.f_cpu=32000000UL
aceUno8Mb.build.board=ACE_UNO_8Mb
aceUno8Mb.build.board=ACE_UNO_8MB
aceUno8Mb.build.core=arduino
aceUno8Mb.build.variant=standart
aceUno8Mb.build.variant=elbear_ace_uno
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
aceUno16Mb.upload.speed=230400
# tool for bootloader update
aceUno16Mb.bootloader.tool=mik32_upload
aceUno16Mb.bootloader.tool.default=mik32_upload
aceUno16Mb.bootloader.file=elbear/bootloader.hex
aceUno16Mb.bootloader.interface=ftdi/mikron-link.cfg
aceUno16Mb.bootloader.params.verbose=
# 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=elbear_ace_uno
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
aceUno32Mb.upload.speed=230400
# tool for bootloader update
aceUno32Mb.bootloader.tool=mik32_upload
aceUno32Mb.bootloader.tool.default=mik32_upload
aceUno32Mb.bootloader.file=elbear/bootloader.hex
aceUno32Mb.bootloader.interface=ftdi/mikron-link.cfg
aceUno32Mb.bootloader.params.verbose=
# 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=elbear_ace_uno
aceUno32Mb.build.extra_flags=
aceUno32Mb.build.flags=
##################### ACE-NANO #####################
aceNano.name=ELBEAR ACE-NANO
# tool for firmware update
aceNano.upload.tool=elbear_uploader
aceNano.upload.protocol=elbear_uploader
aceNano.upload.maximum_size=8388608
aceNano.upload.maximum_data_size=16384
aceNano.upload.speed=230400
# tool for bootloader update
aceNano.bootloader.tool=mik32_upload
aceNano.bootloader.tool.default=mik32_upload
aceNano.bootloader.file=elbear/bootloader.hex
aceNano.bootloader.interface=ftdi/mikron-link.cfg
aceNano.bootloader.params.verbose=
# build options
aceNano.build.mcu=MIK32_Amur
aceNano.build.f_cpu=32000000UL
aceNano.build.board=ACE_NANO
aceNano.build.core=arduino
aceNano.build.variant=elbear_ace_nano
aceNano.build.extra_flags=
aceNano.build.flags=
##################### ELSOMIK #####################
elsomik.name=ELSOMIK
# tool for firmware update
elsomik.upload.tool=elbear_uploader
elsomik.upload.protocol=elbear_uploader
elsomik.upload.maximum_size=8388608
elsomik.upload.maximum_data_size=16384
elsomik.upload.speed=230400
# tool for bootloader update
elsomik.bootloader.tool=mik32_upload
elsomik.bootloader.tool.default=mik32_upload
elsomik.bootloader.file=elsomik/bootloader.hex
elsomik.bootloader.interface=ftdi/mikron-link.cfg
elsomik.bootloader.params.verbose=
# build options
elsomik.build.mcu=MIK32_Amur
elsomik.build.f_cpu=32000000UL
elsomik.build.board=ELSOMIK
elsomik.build.core=arduino
elsomik.build.variant=elsomik
elsomik.build.extra_flags=
elsomik.build.flags=
##################### START-MIK32-V1 #####################
start-mik32-v1.name=START-MIK32-V1
# tool for firmware update
start-mik32-v1.upload.tool=elbear_uploader
start-mik32-v1.upload.protocol=elbear_uploader
start-mik32-v1.upload.maximum_size=4194304
start-mik32-v1.upload.maximum_data_size=16384
start-mik32-v1.upload.speed=120000
# tool for bootloader update
start-mik32-v1.bootloader.tool=mik32_upload
start-mik32-v1.bootloader.tool.default=mik32_upload
start-mik32-v1.bootloader.file=start-mik32/bootloader.hex
start-mik32-v1.bootloader.interface=start-link.cfg
start-mik32-v1.bootloader.params.verbose=
# build options
start-mik32-v1.build.mcu=MIK32_Amur
start-mik32-v1.build.f_cpu=32000000UL
start-mik32-v1.build.board=START_MIK32_V1
start-mik32-v1.build.core=arduino
start-mik32-v1.build.variant=start
start-mik32-v1.build.extra_flags=
start-mik32-v1.build.flags=

View File

@ -1,247 +0,0 @@
:020000040100F9
:10000000FD62938202400100FD12E39E02FE374131
:10001000000213010100B701000293810100B7152E
:100020000001938505F137160001130606F4B706A3
:1000300000029386060039A083A2050023A0560083
:1000400091059106E3EAC5FEB7150001938505F415
:1000500037160001130606F4B7060002938606263B
:1000600039A083A2050023A0560091059106E3EA7A
:10007000C5FEB70500029385050337060002130687
:10008000062621A023A005009105E3EDC5FEB700DB
:100090000001E780C00AB7000001E780C00AB7008E
:1000A0000001E780007273005010F5BF82800000ED
:1000B0000000000000000000000000000000000040
:1000C0006F004000197106C20AC40EC612C816CAD3
:1000D0001ACC1ECE22D026D22AD42ED632D836DA48
:1000E0003ADC3EDEC2C0C6C2CAC4CEC6D2C8D6CA78
:1000F000DACCDECEE2D0E6D2EAD4EED6F2D8F6DA28
:10010000FADCFEDE970000009380E00482909240CB
:100110002241B2414242D2426243F24302549254DB
:100120002255B2554256D2566257F2570648964863
:100130002649B649464AD64A664BF64B065C965C5B
:10014000265DB65D465ED65E665FF65F096173004A
:10015000203001A03D432A876373C3029377F700E1
:10016000BDEFADE5937606FF3D8ABA960CC34CC34E
:100170000CC74CC74107E36BD7FE11E28280B30680
:10018000C3408A069702000096966780A600230760
:10019000B700A306B7002306B700A305B7002305E1
:1001A000B700A304B7002304B700A303B7002303D9
:1001B000B700A302B7002302B700A301B7002301D1
:1001C000B700A300B7002300B700828093F5F50FB6
:1001D00093968500D58D93960501D58D61B793963D
:1001E00027009702000096968682E78086FA96801E
:1001F000C1171D8F3E96E374C3F8A5B7B707050076
:100200000947D8CFB7170500938707C0984385667D
:1002100093860640558F98C3B71708009387074009
:1002200023A0070023A2070023A407001307A008A8
:10023000D8C77D57D8CF354798C3D84F9356570165
:100240008D8AE5DE8280B71708009387074023A0D8
:10025000070023A2070023A4070023A607007D5759
:10026000D8CF23A40702B7170500938707C0984388
:10027000F1769386F63F758F98C3B7070500D84F80
:1002800023AE07008280B71708009387074088D7FE
:10029000D84F137707046DDF828037070002B71548
:1002A000080037460F0023200704814781469385C5
:1002B000054013061624C84D137505020DC991CECD
:1002C0002320F70437470F00130707246397E7003D
:1002D000B707000205472383E700B7170800938795
:1002E0000740C8534205418182808546E9B78507AA
:1002F000E39DC7FEFDD2B7470F0093870724232055
:10030000F704F9B74111B707000222C413870700A9
:1003100006C6834667000547138407006390E6021C
:100320001305000F8D37B717080093870740D84F84
:10033000218B09C7D84F13678700D8CF2303040048
:10034000B240224441018280411106C622C426C225
:10035000AA84EF009013E1689388086A01488147F6
:10036000014781460146B70520C726853794980086
:10037000EF000077130414687D1419E40D45B240B2
:10038000224492444101828085452685EF00501128
:1003900005897DF10145E5B7411122C4370400020A
:1003A000930704008C43B70700804AC0BE95B70787
:1003B000000223ACB70206C626C293974501130478
:1003C00004003709000289E713058900EF00701A5D
:1003D0000C40B70400029386440413060010130572
:1003E0008900EF0050141C40370700028356470372
:1003F000938707101CC013060010B68763F4C6006D
:1004000093070010138444041305F400938707F046
:100410001306100F814513040410231AF7021D3B25
:10042000A285138544043D46EF00F0182320040004
:1004300023220400232404002316040023070400BD
:10044000B240224492440249410182805D71130608
:1004500080028145280886C6F539BD47230CF10086
:100460008947230EF1003ED2E177938707082C08D5
:100470000A85231AF1021923B640616182805D71F9
:10048000A2C4370400021305840086C6A6C2652BE9
:1004900013058400E525894513058400EF0050000D
:1004A0009377250085E3AA84854513058400EF0032
:1004B000207F13E62400AA851376F60F1305840027
:1004C000EF007001E1689388086A0148814701479D
:1004D00081460146B7052038130584001125E168DF
:1004E00038009388086A1308000285468147014650
:1004F000B70599EB1305840023040100D523B71534
:10050000000151469385C5EF6800EF00D00A9304BF
:1005100084009C406C0051463ED085473ED2681016
:10052000C1673ED4EF003009B70607009C42370789
:10053000F1FF7D17F98F08109CC2812BB64026442D
:10054000964461618280411106C6F5390D3FB707B7
:10055000008073905730B70000808290B240410114
:100560008280411106C622C426C24AC08347350094
:1005700005476383E70811472A846389E7008DCF25
:10058000B24022449244024941018280B7070002EE
:1005900083D7470391C30935834744000347540079
:1005A000E2074207BA9737070002232EF702370700
:1005B00000022320F700E9B73709000283544903FA
:1005C0000346050093054500370500021305450461
:1005D0002695EF00407E83470400BE94C204C1808C
:1005E000231A99029307F00FE3FC97F82244B240D4
:1005F0009244024941014DB33D457131B7070002B4
:1006000083D7470391C3493B2244B24092440249F5
:10061000410115BF3707000293070700B705000225
:1006200003DE470083A705043716080037450F008F
:1006300037480F00B708000201438146130707003F
:10064000130606401305152413080824938848153B
:1006500063EEC6016304030023A0F504834767002B
:10066000A9E73705000213054515E5BD81470323BA
:10067000C60113730302631F03008507E399A7FEF6
:10068000B7470F009387072423A0F504854723036A
:10069000F7008280E38607FF832E46023383D8006B
:1006A00085062300D301054365B78280011122CC62
:1006B0003704000226CA4AC84EC652C406CE1304E6
:1006C0000400930400061309E00FB7090002130A9F
:1006D0000003E136834764001375F50FA303A400FC
:1006E00099C30D31FDB7630F950063042503E31231
:1006F00045FF3D45493E553605052312A4003D45BD
:100700005936C1BF3D454136313783476400F1FB5F
:10071000FDB7138589000D397DD11305000FCDB7C5
:10072000011106CE22CC1D333704000213058400CC
:10073000192E130584009921E1689388086A0148FD
:100740008147780085460146B705D9EB130584003B
:10075000230601007126E168814701478146014671
:10076000B70538FF9388086A0148130584008D2E69
:10077000713437070002B715080037460F002320F1
:100780000704814781469385054013061624C84D0A
:100790001375050211CD85CA2320F70437470F00D2
:1007A000130707246391E702793B01A08546C5B78B
:1007B0008507E39DC7FE81CAB7470F0093870724CB
:1007C0002320F704D5B7DD350547AA876305E50281
:1007D00009476300E506054591EBB7060600DC4ACC
:1007E0007D771307F73FF98FDCCA014582807D17BB
:1007F00019EB0D4582809306004037A707001307C9
:100800000712B7050500905D7D8E75D2370606008C
:100810005C4A7D771307F73FF98FD58F41115CCA8A
:1008200002C613073006B2476359F700014541017C
:100830008280856693860680C9B7B24785073EC623
:10084000DDB791476307F50263EAA7008547630AAE
:10085000F50489476309F50405458280A147E31D36
:10086000F5FE0947094501A8FD1781EFC8D20D45DE
:10087000828005470D45B7A7070093870712B70683
:100880000500905E798E6DD28A05C98D4111CCD25A
:1008900002C613073006B247635AF700014541010B
:1008A00082801147C9BF21470145F1B7B24785078B
:1008B0003EC6D5B70547AA876305E5020947630227
:1008C000E506054591EBB70606009C4A7D771307C0
:1008D000F73FF98F9CCA014582807D1719EB0D45C2
:1008E00082809306004037A7070013070712B70559
:1008F0000500905D7D8E75D2370706001C4B7D7616
:100900001306F63FF18FD58F1CCB85471CCF4111C5
:1009100002C613073006B2476359F700014541018B
:1009200082808566938606807DBFB24785073EC676
:10093000DDB711C98547630DF50205458280FD17B6
:1009400091EB0D4582800946B7A7070093870712F0
:10095000B7060500985E718F7DD34111C8D602C6D7
:1009600013073006B2476357F70001454101828003
:100970000546D9BFB24785073EC6EDB7011126CA65
:10098000B7040600DC4806CE22CC4AC84EC652C484
:1009900056C2F19BDCC89C482A89C845F19B9CC87B
:1009A00083C7C5012E848A07DCC883C7D5018A079F
:1009B0009CC8193D0C44AA8A03454400593518487F
:1009C000B70705002A8A98C358480850D8C3184C5E
:1009D00098C7CD35AA894850A93F834704002A8784
:1009E00093F6170089E6D44893E62600D4C893F618
:1009F000270099E637060600544A93E6160054CAC3
:100A000093F6470099E637060600144A93E6260057
:100A100014CAA18B99E7B70606009C4A93E7170012
:100A20009CCAF24062442320590123224901232415
:100A300039012326E900D244B249224A924A4A8522
:100A4000424905618280011106CE22CC02C402C651
:100A50002147B707050037550800D8C705448D471B
:100A60008A85130505803EC022C2292A3755080011
:100A70009307C0038A851305058022C222C43EC0A5
:100A80001122F240624405618280411122C406C6EF
:100A90002A84553F18405C4F93E707015CCF1C4404
:100AA0001CCB5C4085CB1C43B7061000D58F1CC304
:100AB000144C5C48B240D606CE07D58F834604015D
:100AC000C206D58F8346C4012244E206D58F1CCFCF
:100AD000410182801C43B706F0FFFD16F58FC1BFB0
:100AE000032305002A8E0325C30113650502232E67
:100AF000A3002324C3001396260149824D8E23268A
:100B000003012322C300139605016354060299C210
:100B10000545B1CB01476346D700639C08020D45EC
:100B200082803386E700034606000507230AC300D8
:100B3000DDB799C2054505CB8147E3D0D7FE032633
:100B40000E00034546013306F70085072300A60083
:100B5000EDB783270E00FD18DC4F93F70702D5DFB2
:100B600011656D8D11E18280B707070083C74701CA
:100B700013F585001D8D3335A00082801C4141474F
:100B8000D8CF8280B7470800938707402A8863043C
:100B9000F508B7570800938707806304F50A3747BD
:100BA0000800630DE50A05458280331E1F01337678
:100BB000DE0129C683A345008843139318003396AA
:100BC0006F001346F6FF13F43300718D3314640085
:100BD000418D88C3638B5302638C0302084303AEC9
:100BE000C500718D331E6E003365C50108C3884290
:100BF000698E884533156500498E90C2850833D5C6
:100C00001E0145F53244410182802326C801F9B70F
:100C10002324C801E1B7B716050037170500B71739
:100C20000500938646C1130707C19387C7C083AEEB
:100C300005008148054F8D4F914233D51E0105EDCA
:100C40008280B716050037170500B7170500938691
:100C500006C21307C7C1938787C1D1BFB716050066
:100C600037170500B7170500938686C0130747C0DE
:100C7000938707C06DBF331E1F013376DE0119E273
:100C8000850865BF411122C635B7E1689388086AB7
:100C900001488147014781460146B705200689B5CD
:100CA000011106CEA307010089476393F502B7053A
:100CB0002035E1681307F1009388086A01488147ED
:100CC00085460146313DF2400345F10005618280D1
:100CD000B7052005F9BF011106CE22CC26CA23068E
:100CE000B100AA84A306C1004D37E1689388086A61
:100CF00001487C00014789460146B78520012685C9
:100D00000964F93B130414717D1419E40D45F24094
:100D10006244D24405618280854526855137058924
:100D200065F50145EDB7011106CE22CC26CA2E8409
:100D30004AC8AA84328936C6893FB247E16822860A
:100D40009388086A01480147CA86B78580022685CC
:100D5000616479331304146A7D1411C485452685B2
:100D60008137058975F9F2406244D24442490561F0
:100D70008280011106CE22CC26CA2EC6AA84313723
:100D80003246E1689388086A0148814701478146F5
:100D9000B705802026856164A1331304146A7D148D
:100DA00011C485452685ED3D058975F9F2406244FB
:100DB000D24405618280B3C7A5008D8BB308C500FE
:100DC000B1E78D4763F4C704937735002A87B9EB01
:100DD00013F6C8FFB306E6409307000263C8D706C0
:100DE000AE86BA876371C70203A806009107910611
:100DF00023AE07FFE3EAC7FE9307F6FF998FF19B47
:100E000091073E97BE956366170182802A87637EAD
:100E1000150383C7050005078505A30FF7FEE39AB1
:100E2000E8FE828083C60500050793773700A30F8D
:100E3000D7FE8505D1DF83C6050005079377370008
:100E4000A30FD7FE8505F9FF61B78280411122C645
:100E50001304000283A3050083A2450083AF85002D
:100E600003AFC50083AE050103AE450103A38501B1
:100E700003A8C501945113074702B307E640232E88
:100E800077FC232057FE2322F7FF2324E7FF2326A6
:100E9000D7FF2328C7FF232A67FE232C07FF232E13
:100EA000D7FE93854502E347F4FAAE86BA876371AD
:100EB000C70203A806009107910623AE07FFE3EAE5
:100EC000C7FE9307F6FF998FF19B91073E97BE955A
:100ED0006365170132444101828083C7050005071D
:100EE0008505A30FF7FEE387E8FE83C70500050726
:100EF0008505A30FF7FEE392E8FEE9BF200000009E
:100F0000010000000300000006000000EB000000EC
:100F10000000008000010000000007000000000049
:100F200000000000000000000000000000000000C1
:100F300000000000000000000000000000000000B1
:0400000501000000F6
:00000001FF

View File

@ -1,247 +0,0 @@
:020000040100F9
:10000000FD62938202400100FD12E39E02FE374131
:10001000000213010100B701000293810100B7152E
:100020000001938505F137160001130606F4B706A3
:1000300000029386060039A083A2050023A0560083
:1000400091059106E3EAC5FEB7150001938505F415
:1000500037160001130606F4B7060002938606263B
:1000600039A083A2050023A0560091059106E3EA7A
:10007000C5FEB70500029385050337060002130687
:10008000062621A023A005009105E3EDC5FEB700DB
:100090000001E780C00AB7000001E780C00AB7008E
:1000A0000001E780007273005010F5BF82800000ED
:1000B0000000000000000000000000000000000040
:1000C0006F004000197106C20AC40EC612C816CAD3
:1000D0001ACC1ECE22D026D22AD42ED632D836DA48
:1000E0003ADC3EDEC2C0C6C2CAC4CEC6D2C8D6CA78
:1000F000DACCDECEE2D0E6D2EAD4EED6F2D8F6DA28
:10010000FADCFEDE970000009380E00482909240CB
:100110002241B2414242D2426243F24302549254DB
:100120002255B2554256D2566257F2570648964863
:100130002649B649464AD64A664BF64B065C965C5B
:10014000265DB65D465ED65E665FF65F096173004A
:10015000203001A03D432A876373C3029377F700E1
:10016000BDEFADE5937606FF3D8ABA960CC34CC34E
:100170000CC74CC74107E36BD7FE11E28280B30680
:10018000C3408A069702000096966780A600230760
:10019000B700A306B7002306B700A305B7002305E1
:1001A000B700A304B7002304B700A303B7002303D9
:1001B000B700A302B7002302B700A301B7002301D1
:1001C000B700A300B7002300B700828093F5F50FB6
:1001D00093968500D58D93960501D58D61B793963D
:1001E00027009702000096968682E78086FA96801E
:1001F000C1171D8F3E96E374C3F8A5B7B707050076
:100200000947D8CFB7170500938707C0984385667D
:1002100093860640558F98C3B71708009387074009
:1002200023A0070023A2070023A407001307A008A8
:10023000D8C77D57D8CF354798C3D84F9356570165
:100240008D8AE5DE8280B71708009387074023A0D8
:10025000070023A2070023A4070023A607007D5759
:10026000D8CF23A40702B7170500938707C0984388
:10027000F1769386F63F758F98C3B7070500D84F80
:1002800023AE07008280B71708009387074088D7FE
:10029000D84F137707046DDF828037070002B71548
:1002A000080037460F0023200704814781469385C5
:1002B000054013061624C84D137505020DC991CECD
:1002C0002320F70437470F00130707246397E7003D
:1002D000B707000205472383E700B7170800938795
:1002E0000740C8534205418182808546E9B78507AA
:1002F000E39DC7FEFDD2B7470F0093870724232055
:10030000F704F9B74111B707000222C413870700A9
:1003100006C6834667000547138407006390E6021C
:100320001305000F8D37B717080093870740D84F84
:10033000218B09C7D84F13678700D8CF2303040048
:10034000B240224441018280411106C622C426C225
:10035000AA84EF009013E1689388086A01488147F6
:10036000014781460146B70520C726853794980086
:10037000EF000077130414687D1419E40D45B240B2
:10038000224492444101828085452685EF00501128
:1003900005897DF10145E5B7411122C4370400020A
:1003A000930704008C43B70700804AC0BE95B70787
:1003B000000223ACB70206C626C293974501130478
:1003C00004003709000289E713058900EF00701A5D
:1003D0000C40B70400029386440413060010130572
:1003E0008900EF0050141C40370700028356470372
:1003F000938707101CC013060010B68763F4C6006D
:1004000093070010138444041305F400938707F046
:100410001306100F814513040410231AF7021D3B25
:10042000A285138544043D46EF00F0182320040004
:1004300023220400232404002316040023070400BD
:10044000B240224492440249410182805D71130608
:1004500080028145280886C6F539BD47230CF10086
:100460008947230EF1003ED2E177938707082C08D5
:100470000A85231AF1021923B640616182805D71F9
:10048000A2C4370400021305840086C6A6C2652BE9
:1004900013058400E525894513058400EF0050000D
:1004A0009377250085E3AA84854513058400EF0032
:1004B000207F13E62400AA851376F60F1305840027
:1004C000EF007001E1689388086A0148814701479D
:1004D00081460146B7052038130584001125E168DF
:1004E00038009388086A1308000285468147014650
:1004F000B70599EB1305840023040100D523B71534
:10050000000151469385C5EF6800EF00D00A9304BF
:1005100084009C406C0051463ED085473ED2681016
:10052000C1673ED4EF003009B70607009C42370789
:10053000F1FF7D17F98F08109CC2812BB64026442D
:10054000964461618280411106C6F5390D3FB707B7
:10055000008073905730B70000808290B240410114
:100560008280411106C622C426C24AC08347350094
:1005700005476383E70811472A846389E7008DCF25
:10058000B24022449244024941018280B7070002EE
:1005900083D7470391C30935834744000347540079
:1005A000E2074207BA9737070002232EF702370700
:1005B00000022320F700E9B73709000283544903FA
:1005C0000346050093054500370500021305450461
:1005D0002695EF00407E83470400BE94C204C1808C
:1005E000231A99029307F00FE3FC97F82244B240D4
:1005F0009244024941014DB33D457131B7070002B4
:1006000083D7470391C3493B2244B24092440249F5
:10061000410115BF3707000293070700B705000225
:1006200003DE470083A705043716080037450F008F
:1006300037480F00B708000201438146130707003F
:10064000130606401305152413080824938848153B
:1006500063EEC6016304030023A0F504834767002B
:10066000A9E73705000213054515E5BD81470323BA
:10067000C60113730302631F03008507E399A7FEF6
:10068000B7470F009387072423A0F504854723036A
:10069000F7008280E38607FF832E46023383D8006B
:1006A00085062300D301054365B78280011122CC62
:1006B0003704000226CA4AC84EC652C406CE1304E6
:1006C0000400930400061309E00FB7090002130A9F
:1006D0000003E136834764001375F50FA303A400FC
:1006E00099C30D31FDB7630F950063042503E31231
:1006F00045FF3D45493E553605052312A4003D45BD
:100700005936C1BF3D454136313783476400F1FB5F
:10071000FDB7138589000D397DD11305000FCDB7C5
:10072000011106CE22CC1D333704000213058400CC
:10073000192E130584009921E1689388086A0148FD
:100740008147780085460146B705D9EB130584003B
:10075000230601007126E168814701478146014671
:10076000B70538FF9388086A0148130584008D2E69
:10077000713437070002B715080037460F002320F1
:100780000704814781469385054013061624C84D0A
:100790001375050211CD85CA2320F70437470F00D2
:1007A000130707246391E702793B01A08546C5B78B
:1007B0008507E39DC7FE81CAB7470F0093870724CB
:1007C0002320F704D5B7DD350547AA876305E50281
:1007D00009476300E506054591EBB7060600DC4ACC
:1007E0007D771307F73FF98FDCCA014582807D17BB
:1007F00019EB0D4582809306004037A707001307C9
:100800000712B7050500905D7D8E75D2370606008C
:100810005C4A7D771307F73FF98FD58F41115CCA8A
:1008200002C613073006B2476359F700014541017C
:100830008280856693860680C9B7B24785073EC623
:10084000DDB791476307F50263EAA7008547630AAE
:10085000F50489476309F50405458280A147E31D36
:10086000F5FE0947094501A8FD1781EFC8D20D45DE
:10087000828005470D45B7A7070093870712B70683
:100880000500905E798E6DD28A05C98D4111CCD25A
:1008900002C613073006B247635AF700014541010B
:1008A00082801147C9BF21470145F1B7B24785078B
:1008B0003EC6D5B70547AA876305E5020947630227
:1008C000E506054591EBB70606009C4A7D771307C0
:1008D000F73FF98F9CCA014582807D1719EB0D45C2
:1008E00082809306004037A7070013070712B70559
:1008F0000500905D7D8E75D2370706001C4B7D7616
:100900001306F63FF18FD58F1CCB85471CCF4111C5
:1009100002C613073006B2476359F700014541018B
:1009200082808566938606807DBFB24785073EC676
:10093000DDB711C98547630DF50205458280FD17B6
:1009400091EB0D4582800946B7A7070093870712F0
:10095000B7060500985E718F7DD34111C8D602C6D7
:1009600013073006B2476357F70001454101828003
:100970000546D9BFB24785073EC6EDB7011126CA65
:10098000B7040600DC4806CE22CC4AC84EC652C484
:1009900056C2F19BDCC89C482A89C845F19B9CC87B
:1009A00083C7C5012E848A07DCC883C7D5018A079F
:1009B0009CC8193D0C44AA8A03454400593518487F
:1009C000B70705002A8A98C358480850D8C3184C5E
:1009D00098C7CD35AA894850A93F834704002A8784
:1009E00093F6170089E6D44893E62600D4C893F618
:1009F000270099E637060600544A93E6160054CAC3
:100A000093F6470099E637060600144A93E6260057
:100A100014CAA18B99E7B70606009C4A93E7170012
:100A20009CCAF24062442320590123224901232415
:100A300039012326E900D244B249224A924A4A8522
:100A4000424905618280011106CE22CC02C402C651
:100A50002147B707050037550800D8C705448D471B
:100A60008A85130505803EC022C2292A3755080011
:100A70009307C0038A851305058022C222C43EC0A5
:100A80001122F240624405618280411122C406C6EF
:100A90002A84553F18405C4F93E707015CCF1C4404
:100AA0001CCB5C4085CB1C43B7061000D58F1CC304
:100AB000144C5C48B240D606CE07D58F834604015D
:100AC000C206D58F8346C4012244E206D58F1CCFCF
:100AD000410182801C43B706F0FFFD16F58FC1BFB0
:100AE000032305002A8E0325C30113650502232E67
:100AF000A3002324C3001396260149824D8E23268A
:100B000003012322C300139605016354060299C210
:100B10000545B1CB01476346D700639C08020D45EC
:100B200082803386E700034606000507230AC300D8
:100B3000DDB799C2054505CB8147E3D0D7FE032633
:100B40000E00034546013306F70085072300A60083
:100B5000EDB783270E00FD18DC4F93F70702D5DFB2
:100B600011656D8D11E18280B707070083C74701CA
:100B700013F585001D8D3335A00082801C4141474F
:100B8000D8CF8280B7470800938707402A8863043C
:100B9000F508B7570800938707806304F50A3747BD
:100BA0000800630DE50A05458280331E1F01337678
:100BB000DE0129C683A345008843139318003396AA
:100BC0006F001346F6FF13F43300718D3314640085
:100BD000418D88C3638B5302638C0302084303AEC9
:100BE000C500718D331E6E003365C50108C3884290
:100BF000698E884533156500498E90C2850833D5C6
:100C00001E0145F53244410182802326C801F9B70F
:100C10002324C801E1B7B716050037170500B71739
:100C20000500938646C1130707C19387C7C083AEEB
:100C300005008148054F8D4F914233D51E0105EDCA
:100C40008280B716050037170500B7170500938691
:100C500006C21307C7C1938787C1D1BFB716050066
:100C600037170500B7170500938686C0130747C0DE
:100C7000938707C06DBF331E1F013376DE0119E273
:100C8000850865BF411122C635B7E1689388086AB7
:100C900001488147014781460146B705200689B5CD
:100CA000011106CEA307010089476393F502B7053A
:100CB0002035E1681307F1009388086A01488147ED
:100CC00085460146313DF2400345F10005618280D1
:100CD000B7052005F9BF011106CE22CC26CA23068E
:100CE000B100AA84A306C1004D37E1689388086A61
:100CF00001487C00014789460146B78520012685C9
:100D00000964F93B130414717D1419E40D45F24094
:100D10006244D24405618280854526855137058924
:100D200065F50145EDB7011106CE22CC26CA2E8409
:100D30004AC8AA84328936C6893FB247E16822860A
:100D40009388086A01480147CA86B78580022685CC
:100D5000616479331304146A7D1411C485452685B2
:100D60008137058975F9F2406244D24442490561F0
:100D70008280011106CE22CC26CA2EC6AA84313723
:100D80003246E1689388086A0148814701478146F5
:100D9000B705802026856164A1331304146A7D148D
:100DA00011C485452685ED3D058975F9F2406244FB
:100DB000D24405618280B3C7A5008D8BB308C500FE
:100DC000B1E78D4763F4C704937735002A87B9EB01
:100DD00013F6C8FFB306E6409307000263C8D706C0
:100DE000AE86BA876371C70203A806009107910611
:100DF00023AE07FFE3EAC7FE9307F6FF998FF19B47
:100E000091073E97BE956366170182802A87637EAD
:100E1000150383C7050005078505A30FF7FEE39AB1
:100E2000E8FE828083C60500050793773700A30F8D
:100E3000D7FE8505D1DF83C6050005079377370008
:100E4000A30FD7FE8505F9FF61B78280411122C645
:100E50001304000283A3050083A2450083AF85002D
:100E600003AFC50083AE050103AE450103A38501B1
:100E700003A8C501945113074702B307E640232E88
:100E800077FC232057FE2322F7FF2324E7FF2326A6
:100E9000D7FF2328C7FF232A67FE232C07FF232E13
:100EA000D7FE93854502E347F4FAAE86BA876371AD
:100EB000C70203A806009107910623AE07FFE3EAE5
:100EC000C7FE9307F6FF998FF19B91073E97BE955A
:100ED0006365170132444101828083C7050005071D
:100EE0008505A30FF7FEE387E8FE83C70500050726
:100EF0008505A30FF7FEE392E8FEE9BF200000009E
:100F0000010000000300000006000000EB000000EC
:100F10000000008000010000000007000000000049
:100F200000000000000000000000000000000000C1
:100F300000000000000000000000000000000000B1
:0400000501000000F6
:00000001FF

View File

@ -0,0 +1,281 @@
:020000040100F9
:10000000FD6293820240FD12E39F02FE374100022F
:1000100013010100B711000293818193B71500010C
:10002000938585103716000113068613B706000264
:100030009386861539A083A2050023A0560091055A
:100040009106E3EAC5FEB70500019385850B3706E7
:10005000000113060621B70600029386060039A0A8
:1000600083A2050023A0560091059106E3EAC5FE90
:10007000B705000293858518370600021306464B24
:1000800021A023A005009105E3EDC5FEB702000203
:100090009382020C73905230B7000001E780600B2E
:1000A000B7000001E780600BB7100001E780E09324
:0800B00073005010F5BF8280BF
:1000B8000000000000000000000000000000000038
:1000C8000000000000000000000000000000000028
:1000D8000000000000000000000000000000000018
:1000E8000000000000000000000000000000000008
:1000F80000000000000000000000000000000000F8
:1001080000000000000000000000000000000000E7
:1001180000000000000000000000000000000000D7
:1001280000000000000000000000000000000000C7
:1001380000000000000000000000000000000000B7
:1001480000000000000000000000000000000000A7
:100158000000000000000000000000000000000097
:100168000000000000000000000000000000000087
:100178006F004000130141F806C00AC20EC412C63F
:1001880016C81ACA1ECC22CE26D02AD22ED432D6CF
:1001980036D83ADA3EDC42DEC6C0CAC2CEC4D2C6BF
:1001A800D6C8DACADECCE2CEE6D0EAD2EED4F2D6AF
:1001B800F6D8FADAFEDC97000000938000058290FA
:1001C80082401241A2413242C2425243E243724447
:1001D80082541255A2553256C2565257E257725897
:1001E80086481649A649364AC64A564BE64B764CC7
:1001F800865C165DA65D365EC65E565FE65F1301D9
:08020800C1077300203001A0C2
:100210003D432A876373C3029377F700BDEFADE5D3
:10022000937606FF3D8ABA960CC34CC30CC74CC7E5
:100230004107E36BD7FE11E28280B306C3408A0612
:100240009702000096966780A6002307B700A306D2
:10025000B7002306B700A305B7002305B700A30422
:10026000B7002304B700A303B7002303B700A3021A
:10027000B7002302B700A301B7002301B700A30012
:10028000B7002300B700828093F5F50F93968500A1
:10029000D58D93960501D58D61B79396270097026A
:1002A000000096968682E78086FA9680C1171D8F99
:1002B0003E96E374C3F8A5B7B70705000947D8CF42
:1002C000B7170500938707C0984385669386064055
:1002D000558F98C398471367074098C7B71708000A
:1002E0009387074023A0070023A2070023A4070049
:1002F0001307A008D8C77D57D8CF354798C3D84F24
:10030000935657018D8AE5DE8280B71708009387E0
:10031000074023A0070023A2070023A4070023A669
:1003200007007D57D8CF23A40702B717050093878E
:1003300007C09843F1769386F63F758F98C3984728
:100340001377F7BF98C7B7070500094798D382808E
:10035000B71708009387074088D7D84F137707044B
:100360006DDF828003A3418637150800B7450F0073
:1003700023A4018681470146130505409385152472
:100380000328C501B308F30013780802630A0802C2
:1003900011CE23A2118737470F0023A4F18613073C
:1003A00007246395E70005472387E184B717080012
:1003B00093870740C8534205418182800546C9B7EB
:1003C0008507E39DB7FE7DD2B7470F0093870724CB
:1003D00023A4F18623A21187F9B7411106C622C4CE
:1003E00026C2AA84EF007028E1689388086A014851
:1003F0008147014781460146B70520C726853794C6
:100400009800EF00F00B130414687D1419E40D45F7
:10041000B240224492444101828085452685EF0006
:10042000302605897DF10145E5B7411122C4130647
:1004300000109305F00F1385C18606C6D13B83A536
:1004400081849386C1861306001013850182EF0014
:1004500090341384C186814793050410130600105D
:10046000B306F4003387F50083C606000347070090
:10047000639AE6008507E395C7FE0545B24022442E
:10048000410182800145DDBF411126C293878184ED
:100490008C43B70700804AC0BE9523AEB18406C620
:1004A00022C4939745019384818489E7138501824F
:1004B000EF00302A8C409386C18613850182938693
:1004C000061013060010EF00102485371384C18630
:1004D00011E989472383F400B2402244924402493F
:1004E000410182809C4083D68185938707109CC000
:1004F00013060010B68763F4C600930700109387B5
:1005000007F01306100F9305F00F1305F410239C4A
:10051000F18413040420ED39A2853D461385C1966C
:10052000EF00D02822852244B240924402493D4641
:100530009305F00F4101E9B95D7113068002814511
:10054000280886C6F131BD47230CF1008947230EE8
:10055000F1003ED2E177938707082C080A85231A19
:10056000F102DD23B640616182805D71A2C4138512
:10057000018286C6A6C2CAC0EF00E06A1385018266
:10058000EF00C07D854513850182EF00700F8D4718
:10059000814463E3A700AA84894513850182EF00A3
:1005A000300E937725002A8689E713662500137697
:1005B000F60F9377060499C31376F60BA685138579
:1005C0000182EF00500FE1689388086A0148814773
:1005D000014781460146B705203813850182EF00A7
:1005E000206EE16838009388086A13080002854687
:1005F00081470146B70599EB138501822304010069
:10060000EF00006CB715000151469385450F680057
:10061000EF00D01913890182832709006C0051462D
:100620003ED085473ED26810C1673ED4EF00101817
:10063000B70607009C423707F1FF7D17F98F0810B6
:100640009CC22525B64026449644064961618280B5
:10065000411106C65D39113FB707008073905730CE
:10066000B70000808290B24041018280411122C4D3
:1006700006C69387818483C7670085461384818477
:10068000638ED70009476388E70023030400B24064
:100690002244410182801305000F5D39B71708001D
:1006A00093870740D84F218B09C7D84F136787001E
:1006B000D8CF793FD9BF411106C622C426C24AC04D
:1006C0008347350005476389E70611472A84638914
:1006D000E7009DC7B2402244924402494101828012
:1006E00083D7818591C34D3383474400034754002A
:1006F000E2074207BA9723A0F18623A4F184D9BF69
:1007000083D48185034604001385C19626959305FD
:100710004400EF00B00983470400BE94C204C180C6
:10072000239C91849307F00FE3F697FA2244B2409A
:1007300092440249410189BB3D45193983D78185DE
:1007400099E72244B24092440249410111B72D3B3E
:1007500083C7E184FDD7BDBF41119386818403DF48
:10076000460026C483A2818622C637150800B748F2
:100770000F0037430F004AC2814723AA018413099F
:10078000FFFF814E81468145814301480146138721
:100790008184130505409388182413030324138EC2
:1007A000C1A7636BE60363850E0009462303C700F8
:1007B00099C2A388F18499C123AA718463040800B3
:1007C00023A4518683476700A9E33244A244124917
:1007D0001385C1A74101C5B581420328C50113781E
:1007E0000802631908028502E39912FF99C2A388DF
:1007F000F18499C123AA7184B7470F009387072416
:1008000023A4F18685472303F7003244A24412490A
:1008100041018280E38C62FC03284502937FF80F3C
:10082000637D26011378F80FC29385453308CE0007
:100830002300F80105060548ADB7B307704093F7EC
:10084000F70F6394FF008546D5B7854EEDBF0111C4
:1008500026CA4EC652C4B7490F00371ADCBA22CC9A
:100860004AC856C25AC006CE938481849389F9231C
:10087000930A0006130B0009391AED3483A7418649
:10088000A383A40063F3F900E13383C7640099C331
:10089000F13BE5B783C67400638356096388660538
:1008A000930700036381F60603C701858D47998F7F
:1008B0008E07B357FA0093F7F70F639FF606930777
:1008C000170093F7F70F2388F1841147639DE70022
:1008D0003D45BD3C13850182093629CD1305000F26
:1008E000853C2388018423A2018641BF3D4523A284
:1008F000018623880184A93C0145993C0945893C2E
:100900000145B9349DBF3D4523A20186238801845A
:100910008134893C05052392A4003D45DDB73D4562
:1009200023A201862388018425343D3583C76400D2
:10093000A5F3E5B73D456DB7238801843DBF01119F
:1009400006CE22CCD53E13850182F12C138501827F
:100950003121E1689388086A01488147780085461B
:100960000146B705D9EB1385018223060100892EC4
:10097000E1689388086A014881470147814601463A
:10098000B70538FF13850182252EEFF0FF92C135A0
:100990000547AA876305E50209476300E5060545A3
:1009A00091EBB7060600DC4A7D771307F73FF98F16
:1009B000DCCA014582807D1719EB0D4582809306C4
:1009C000004037A7070013070712B7050500905D21
:1009D0007D8E75D2370606005C4A7D771307F73F98
:1009E000F98FD58F41115CCA02C613073006B24792
:1009F0006359F70001454101828085669386068030
:100A0000C9B7B24785073EC6DDB791476307F50210
:100A100063EAA7008547630AF50489476309F5047B
:100A200005458280A147E31DF5FE0947094501A858
:100A3000FD1781EFC8D20D45828005470D45B7A748
:100A4000070093870712B7060500905E798E6DD276
:100A50008A05C98D4111CCD202C613073006B247B0
:100A6000635AF7000145410182801147C9BF214700
:100A70000145F1B7B24785073EC6D5B70547AA87F6
:100A80006305E50209476304E506054591EBB706F2
:100A900006009C4A7D771307F73FF98F9CCA0145F2
:100AA00082807D1719EB0D4582809306004037A7A1
:100AB000070013070712B7050500905D7D8E75D2FC
:100AC000370706001C4B7D761306F63FF18FD58F56
:100AD0001CCB232C070085471CCF411102C61307EE
:100AE0003006B2476359F7000145410182808566AF
:100AF000938606806DBFB24785073EC6DDB711C934
:100B00008547630DF50205458280FD1791EB0D4584
:100B100082800946B7A7070093870712B70605002A
:100B2000985E718F7DD34111C8D602C61307300677
:100B3000B2476357F7000145410182800546D9BF9E
:100B4000B24785073EC6EDB7011126CAB7040600B5
:100B5000DC4806CE22CC4AC84EC652C456C2F19BCF
:100B6000DCC89C482A89C845F19B9CC8D84883C7E3
:100B7000C5012E84137737C08A07D98FDCC883C795
:100B8000D50198489A071377F7C393F7073CD98F95
:100B90009CC8FD3B0C44AA8A03454400BD35184857
:100BA000B70705002A8A98C358480850D8C3184C7C
:100BB00098C7E935AA8948509937834704002A879E
:100BC00093F6170089E6D44893E62600D4C893F636
:100BD000270099E637060600544A93E6160054CAE1
:100BE00093F6470099E637060600144A93E6260076
:100BF00014CAA18B99E7B70606009C4A93E7170031
:100C00009CCAF24062442320590123224901232433
:100C100039012326E900D244B249224A924A4A8540
:100C2000424905618280011106CE22CC02C402C66F
:100C30002147B707050037550800D8C705448D4739
:100C40008A85130505803EC022C2292A375508002F
:100C50009307C0038A851305058022C222C43EC0C3
:100C60001122F240624405618280411122C406C60D
:100C70002A84553F18405C4F93E707015CCF1C4422
:100C80001CCB5C4085CB1C43B7061000D58F1CC322
:100C9000144C5C48B240D606CE07D58F834604017B
:100CA000C206D58F8346C4012244E206D58F1CCFED
:100CB000410182801C43B706F0FFFD16F58FC1BFCE
:100CC000032305002A8E0325C30113650502232E85
:100CD000A3002324C3001396260149824D8E2326A8
:100CE00003012322C300139605016354060299C22F
:100CF0000545B1CB01476346D700639C08020D450B
:100D000082803386E700034606000507230AC300F6
:100D1000DDB799C2054505CB8147E3D0D7FE032651
:100D20000E00034546013306F70085072300A600A1
:100D3000EDB783270E00FD18DC4F93F70702D5DFD0
:100D400011656D8D11E18280B707070083C74701E8
:100D500013F585001D8D3335A00082801C4141476D
:100D6000D8CF8280B7470800938707402A8863045A
:100D7000F508B7570800938707806304F50A3747DB
:100D80000800630DE50A05458280331E1F01337696
:100D9000DE0129C683A345008843139318003396C8
:100DA0006F001346F6FF13F43300718D33146400A3
:100DB000418D88C3638B5302638C0302084303AEE7
:100DC000C500718D331E6E003365C50108C38842AE
:100DD000698E884533156500498E90C2850833D5E4
:100DE0001E0145F53244410182802326C801F9B72E
:100DF0002324C801E1B7B716050037170500B71758
:100E00000500938646C1130707C19387C7C083AE09
:100E100005008148054F8D4F914233D51E0105EDE8
:100E20008280B716050037170500B71705009386AF
:100E300006C21307C7C1938787C1D1BFB716050084
:100E400037170500B7170500938686C0130747C0FC
:100E5000938707C06DBF331E1F013376DE0119E291
:100E6000850865BF411122C635B7E1689388086AD5
:100E700001488147014781460146B705200689B5EB
:100E8000011106CEA307010089476393F502B70558
:100E90002035E1681307F1009388086A014881470B
:100EA00085460146313DF2400345F10005618280EF
:100EB000B7052005F9BF011106CE22CC26CA2306AC
:100EC000B100AA84A306C1004D37E1689388086A7F
:100ED00001487C00014789460146B78520012685E7
:100EE0000964F93B130414717D1419E40D45F240B3
:100EF0006244D24405618280854526855137058943
:100F000065F50145EDB7011106CE22CC26CA2E8427
:100F10004AC8AA84328936C6893FB247E168228628
:100F20009388086A01480147CA86B78580022685EA
:100F3000616479331304146A7D1411C485452685D0
:100F40008137058975F9F2406244D244424905610E
:100F50008280011106CE22CC26CA2EC6AA84313741
:100F60003246E1689388086A014881470147814613
:100F7000B705802026856164A1331304146A7D14AB
:100F800011C485452685ED3D058975F9F240624419
:100F9000D24405618280E16836879388086AB28608
:100FA00001482E868147B705800319BBB3C7A5004A
:100FB0008D8BB308C500B1E78D4763F4C704937701
:100FC00035002A87B9EB13F6C8FFB306E64093074E
:100FD000000263C8D706AE86BA876371C70203A84A
:100FE00006009107910623AE07FFE3EAC7FE9307C9
:100FF000F6FF998FF19B91073E97BE9563661701A7
:1010000082802A87637E150383C70500050785054F
:10101000A30FF7FEE39AE8FE828083C6050005076A
:1010200093773700A30FD7FE8505D1DF83C6050070
:10103000050793773700A30FD7FE8505F9FF61B742
:101040008280411122C61304000283A3050083A2FB
:10105000450083AF850003AFC50083AE050103AE35
:10106000450103A3850103A8C50194511307470255
:10107000B307E640232E77FC232057FE2322F7FFF9
:101080002324E7FF2326D7FF2328C7FF232A67FE51
:10109000232C07FF232ED7FE93854502E347F4FA5E
:1010A000AE86BA876371C70203A80600910791064E
:1010B00023AE07FFE3EAC7FE9307F6FF998FF19B84
:1010C00091073E97BE9563651701324441018280C6
:1010D00083C7050005078505A30FF7FEE387E8FE34
:1010E00083C7050005078505A30FF7FEE392E8FE19
:1010F000E9BF000020000000010000000300000024
:0811000006000000EB000000F6
:1011080000000700000000000000000000000000D0
:1011180000000000000000000000000000000000C7
:081128000000000000000000BF
:08113000000000800000000037
:0400000501000000F6
:00000001FF

View File

@ -0,0 +1,281 @@
:020000040100F9
:10000000FD6293820240FD12E39F02FE374100022F
:1000100013010100B711000293818193B71500010C
:10002000938585103716000113068613B706000264
:100030009386861539A083A2050023A0560091055A
:100040009106E3EAC5FEB70500019385850B3706E7
:10005000000113060621B70600029386060039A0A8
:1000600083A2050023A0560091059106E3EAC5FE90
:10007000B705000293858518370600021306464B24
:1000800021A023A005009105E3EDC5FEB702000203
:100090009382020C73905230B7000001E780600B2E
:1000A000B7000001E780600BB7100001E780E09324
:0800B00073005010F5BF8280BF
:1000B8000000000000000000000000000000000038
:1000C8000000000000000000000000000000000028
:1000D8000000000000000000000000000000000018
:1000E8000000000000000000000000000000000008
:1000F80000000000000000000000000000000000F8
:1001080000000000000000000000000000000000E7
:1001180000000000000000000000000000000000D7
:1001280000000000000000000000000000000000C7
:1001380000000000000000000000000000000000B7
:1001480000000000000000000000000000000000A7
:100158000000000000000000000000000000000097
:100168000000000000000000000000000000000087
:100178006F004000130141F806C00AC20EC412C63F
:1001880016C81ACA1ECC22CE26D02AD22ED432D6CF
:1001980036D83ADA3EDC42DEC6C0CAC2CEC4D2C6BF
:1001A800D6C8DACADECCE2CEE6D0EAD2EED4F2D6AF
:1001B800F6D8FADAFEDC97000000938000058290FA
:1001C80082401241A2413242C2425243E243724447
:1001D80082541255A2553256C2565257E257725897
:1001E80086481649A649364AC64A564BE64B764CC7
:1001F800865C165DA65D365EC65E565FE65F1301D9
:08020800C1077300203001A0C2
:100210003D432A876373C3029377F700BDEFADE5D3
:10022000937606FF3D8ABA960CC34CC30CC74CC7E5
:100230004107E36BD7FE11E28280B306C3408A0612
:100240009702000096966780A6002307B700A306D2
:10025000B7002306B700A305B7002305B700A30422
:10026000B7002304B700A303B7002303B700A3021A
:10027000B7002302B700A301B7002301B700A30012
:10028000B7002300B700828093F5F50F93968500A1
:10029000D58D93960501D58D61B79396270097026A
:1002A000000096968682E78086FA9680C1171D8F99
:1002B0003E96E374C3F8A5B7B70705000947D8CF42
:1002C000B7170500938707C0984385669386064055
:1002D000558F98C398471367074098C7B71708000A
:1002E0009387074023A0070023A2070023A4070049
:1002F0001307A008D8C77D57D8CF354798C3D84F24
:10030000935657018D8AE5DE8280B71708009387E0
:10031000074023A0070023A2070023A4070023A669
:1003200007007D57D8CF23A40702B717050093878E
:1003300007C09843F1769386F63F758F98C3984728
:100340001377F7BF98C7B7070500094798D382808E
:10035000B71708009387074088D7D84F137707044B
:100360006DDF828003A3418637150800B7450F0073
:1003700023A4018681470146130505409385152472
:100380000328C501B308F30013780802630A0802C2
:1003900011CE23A2118737470F0023A4F18613073C
:1003A00007246395E70005472387E184B717080012
:1003B00093870740C8534205418182800546C9B7EB
:1003C0008507E39DB7FE7DD2B7470F0093870724CB
:1003D00023A4F18623A21187F9B7411106C622C4CE
:1003E00026C2AA84EF007028E1689388086A014851
:1003F0008147014781460146B70520C726853794C6
:100400009800EF00F00B130414687D1419E40D45F7
:10041000B240224492444101828085452685EF0006
:10042000302605897DF10145E5B7411122C4130647
:1004300000109305F00F1385C18606C6D13B83A536
:1004400081849386C1861306001013850182EF0014
:1004500090341384C186814793050410130600105D
:10046000B306F4003387F50083C606000347070090
:10047000639AE6008507E395C7FE0545B24022442E
:10048000410182800145DDBF411126C293878184ED
:100490008C43B70700804AC0BE9523AEB18406C620
:1004A00022C4939745019384818489E7138501824F
:1004B000EF00302A8C409386C18613850182938693
:1004C000061013060010EF00102485371384C18630
:1004D00011E989472383F400B2402244924402493F
:1004E000410182809C4083D68185938707109CC000
:1004F00013060010B68763F4C600930700109387B5
:1005000007F01306100F9305F00F1305F410239C4A
:10051000F18413040420ED39A2853D461385C1966C
:10052000EF00D02822852244B240924402493D4641
:100530009305F00F4101E9B95D7113068002814511
:10054000280886C6F131BD47230CF1008947230EE8
:10055000F1003ED2E177938707082C080A85231A19
:10056000F102DD23B640616182805D71A2C4138512
:10057000018286C6A6C2CAC0EF00E06A1385018266
:10058000EF00C07D854513850182EF00700F8D4718
:10059000814463E3A700AA84894513850182EF00A3
:1005A000300E937725002A8689E713662500137697
:1005B000F60F9377060499C31376F60BA685138579
:1005C0000182EF00500FE1689388086A0148814773
:1005D000014781460146B705203813850182EF00A7
:1005E000206EE16838009388086A13080002854687
:1005F00081470146B70599EB138501822304010069
:10060000EF00006CB715000151469385450F680057
:10061000EF00D01913890182832709006C0051462D
:100620003ED085473ED26810C1673ED4EF00101817
:10063000B70607009C423707F1FF7D17F98F0810B6
:100640009CC22525B64026449644064961618280B5
:10065000411106C65D39113FB707008073905730CE
:10066000B70000808290B24041018280411122C4D3
:1006700006C69387818483C7670085461384818477
:10068000638ED70009476388E70023030400B24064
:100690002244410182801305000F5D39B71708001D
:1006A00093870740D84F218B09C7D84F136787001E
:1006B000D8CF793FD9BF411106C622C426C24AC04D
:1006C0008347350005476389E70611472A84638914
:1006D000E7009DC7B2402244924402494101828012
:1006E00083D7818591C34D3383474400034754002A
:1006F000E2074207BA9723A0F18623A4F184D9BF69
:1007000083D48185034604001385C19626959305FD
:100710004400EF00B00983470400BE94C204C180C6
:10072000239C91849307F00FE3F697FA2244B2409A
:1007300092440249410189BB3D45193983D78185DE
:1007400099E72244B24092440249410111B72D3B3E
:1007500083C7E184FDD7BDBF41119386818403DF48
:10076000460026C483A2818622C637150800B748F2
:100770000F0037430F004AC2814723AA018413099F
:10078000FFFF814E81468145814301480146138721
:100790008184130505409388182413030324138EC2
:1007A000C1A7636BE60363850E0009462303C700F8
:1007B00099C2A388F18499C123AA718463040800B3
:1007C00023A4518683476700A9E33244A244124917
:1007D0001385C1A74101C5B581420328C50113781E
:1007E0000802631908028502E39912FF99C2A388DF
:1007F000F18499C123AA7184B7470F009387072416
:1008000023A4F18685472303F7003244A24412490A
:1008100041018280E38C62FC03284502937FF80F3C
:10082000637D26011378F80FC29385453308CE0007
:100830002300F80105060548ADB7B307704093F7EC
:10084000F70F6394FF008546D5B7854EEDBF0111C4
:1008500026CA4EC652C4B7490F00371ADCBA22CC9A
:100860004AC856C25AC006CE938481849389F9231C
:10087000930A0006130B0009391AED3483A7418649
:10088000A383A40063F3F900E13383C7640099C331
:10089000F13BE5B783C67400638356096388660538
:1008A000930700036381F60603C701858D47998F7F
:1008B0008E07B357FA0093F7F70F639FF606930777
:1008C000170093F7F70F2388F1841147639DE70022
:1008D0003D45BD3C13850182093629CD1305000F26
:1008E000853C2388018423A2018641BF3D4523A284
:1008F000018623880184A93C0145993C0945893C2E
:100900000145B9349DBF3D4523A20186238801845A
:100910008134893C05052392A4003D45DDB73D4562
:1009200023A201862388018425343D3583C76400D2
:10093000A5F3E5B73D456DB7238801843DBF01119F
:1009400006CE22CCD53E13850182F12C138501827F
:100950003121E1689388086A01488147780085461B
:100960000146B705D9EB1385018223060100892EC4
:10097000E1689388086A014881470147814601463A
:10098000B70538FF13850182252EEFF0FF92C135A0
:100990000547AA876305E50209476300E5060545A3
:1009A00091EBB7060600DC4A7D771307F73FF98F16
:1009B000DCCA014582807D1719EB0D4582809306C4
:1009C000004037A7070013070712B7050500905D21
:1009D0007D8E75D2370606005C4A7D771307F73F98
:1009E000F98FD58F41115CCA02C613073006B24792
:1009F0006359F70001454101828085669386068030
:100A0000C9B7B24785073EC6DDB791476307F50210
:100A100063EAA7008547630AF50489476309F5047B
:100A200005458280A147E31DF5FE0947094501A858
:100A3000FD1781EFC8D20D45828005470D45B7A748
:100A4000070093870712B7060500905E798E6DD276
:100A50008A05C98D4111CCD202C613073006B247B0
:100A6000635AF7000145410182801147C9BF214700
:100A70000145F1B7B24785073EC6D5B70547AA87F6
:100A80006305E50209476304E506054591EBB706F2
:100A900006009C4A7D771307F73FF98F9CCA0145F2
:100AA00082807D1719EB0D4582809306004037A7A1
:100AB000070013070712B7050500905D7D8E75D2FC
:100AC000370706001C4B7D761306F63FF18FD58F56
:100AD0001CCB232C070085471CCF411102C61307EE
:100AE0003006B2476359F7000145410182808566AF
:100AF000938606806DBFB24785073EC6DDB711C934
:100B00008547630DF50205458280FD1791EB0D4584
:100B100082800946B7A7070093870712B70605002A
:100B2000985E718F7DD34111C8D602C61307300677
:100B3000B2476357F7000145410182800546D9BF9E
:100B4000B24785073EC6EDB7011126CAB7040600B5
:100B5000DC4806CE22CC4AC84EC652C456C2F19BCF
:100B6000DCC89C482A89C845F19B9CC8D84883C7E3
:100B7000C5012E84137737C08A07D98FDCC883C795
:100B8000D50198489A071377F7C393F7073CD98F95
:100B90009CC8FD3B0C44AA8A03454400BD35184857
:100BA000B70705002A8A98C358480850D8C3184C7C
:100BB00098C7E935AA8948509937834704002A879E
:100BC00093F6170089E6D44893E62600D4C893F636
:100BD000270099E637060600544A93E6160054CAE1
:100BE00093F6470099E637060600144A93E6260076
:100BF00014CAA18B99E7B70606009C4A93E7170031
:100C00009CCAF24062442320590123224901232433
:100C100039012326E900D244B249224A924A4A8540
:100C2000424905618280011106CE22CC02C402C66F
:100C30002147B707050037550800D8C705448D4739
:100C40008A85130505803EC022C2292A375508002F
:100C50009307C0038A851305058022C222C43EC0C3
:100C60001122F240624405618280411122C406C60D
:100C70002A84553F18405C4F93E707015CCF1C4422
:100C80001CCB5C4085CB1C43B7061000D58F1CC322
:100C9000144C5C48B240D606CE07D58F834604017B
:100CA000C206D58F8346C4012244E206D58F1CCFED
:100CB000410182801C43B706F0FFFD16F58FC1BFCE
:100CC000032305002A8E0325C30113650502232E85
:100CD000A3002324C3001396260149824D8E2326A8
:100CE00003012322C300139605016354060299C22F
:100CF0000545B1CB01476346D700639C08020D450B
:100D000082803386E700034606000507230AC300F6
:100D1000DDB799C2054505CB8147E3D0D7FE032651
:100D20000E00034546013306F70085072300A600A1
:100D3000EDB783270E00FD18DC4F93F70702D5DFD0
:100D400011656D8D11E18280B707070083C74701E8
:100D500013F585001D8D3335A00082801C4141476D
:100D6000D8CF8280B7470800938707402A8863045A
:100D7000F508B7570800938707806304F50A3747DB
:100D80000800630DE50A05458280331E1F01337696
:100D9000DE0129C683A345008843139318003396C8
:100DA0006F001346F6FF13F43300718D33146400A3
:100DB000418D88C3638B5302638C0302084303AEE7
:100DC000C500718D331E6E003365C50108C38842AE
:100DD000698E884533156500498E90C2850833D5E4
:100DE0001E0145F53244410182802326C801F9B72E
:100DF0002324C801E1B7B716050037170500B71758
:100E00000500938646C1130707C19387C7C083AE09
:100E100005008148054F8D4F914233D51E0105EDE8
:100E20008280B716050037170500B71705009386AF
:100E300006C21307C7C1938787C1D1BFB716050084
:100E400037170500B7170500938686C0130747C0FC
:100E5000938707C06DBF331E1F013376DE0119E291
:100E6000850865BF411122C635B7E1689388086AD5
:100E700001488147014781460146B705200689B5EB
:100E8000011106CEA307010089476393F502B70558
:100E90002035E1681307F1009388086A014881470B
:100EA00085460146313DF2400345F10005618280EF
:100EB000B7052005F9BF011106CE22CC26CA2306AC
:100EC000B100AA84A306C1004D37E1689388086A7F
:100ED00001487C00014789460146B78520012685E7
:100EE0000964F93B130414717D1419E40D45F240B3
:100EF0006244D24405618280854526855137058943
:100F000065F50145EDB7011106CE22CC26CA2E8427
:100F10004AC8AA84328936C6893FB247E168228628
:100F20009388086A01480147CA86B78580022685EA
:100F3000616479331304146A7D1411C485452685D0
:100F40008137058975F9F2406244D244424905610E
:100F50008280011106CE22CC26CA2EC6AA84313741
:100F60003246E1689388086A014881470147814613
:100F7000B705802026856164A1331304146A7D14AB
:100F800011C485452685ED3D058975F9F240624419
:100F9000D24405618280E16836879388086AB28608
:100FA00001482E868147B705800319BBB3C7A5004A
:100FB0008D8BB308C500B1E78D4763F4C704937701
:100FC00035002A87B9EB13F6C8FFB306E64093074E
:100FD000000263C8D706AE86BA876371C70203A84A
:100FE00006009107910623AE07FFE3EAC7FE9307C9
:100FF000F6FF998FF19B91073E97BE9563661701A7
:1010000082802A87637E150383C70500050785054F
:10101000A30FF7FEE39AE8FE828083C6050005076A
:1010200093773700A30FD7FE8505D1DF83C6050070
:10103000050793773700A30FD7FE8505F9FF61B742
:101040008280411122C61304000283A3050083A2FB
:10105000450083AF850003AFC50083AE050103AE35
:10106000450103A3850103A8C50194511307470255
:10107000B307E640232E77FC232057FE2322F7FFF9
:101080002324E7FF2326D7FF2328C7FF232A67FE51
:10109000232C07FF232ED7FE93854502E347F4FA5E
:1010A000AE86BA876371C70203A80600910791064E
:1010B00023AE07FFE3EAC7FE9307F6FF998FF19B84
:1010C00091073E97BE9563651701324441018280C6
:1010D00083C7050005078505A30FF7FEE387E8FE34
:1010E00083C7050005078505A30FF7FEE392E8FE19
:1010F000E9BF000020000000010000000300000024
:0811000006000000EB000000F6
:1011080000000700000000000000000000000000D0
:1011180000000000000000000000000000000000C7
:081128000000000000000000BF
:08113000000000800000000037
:0400000501000000F6
:00000001FF

View File

@ -0,0 +1,262 @@
:020000040100F9
:10000000FD62938202400100FD12E39E02FE374131
:10001000000213010100B701000293810100B7152E
:100020000001938505003716000113060603B70685
:1000300000029386060039A083A2050023A0560083
:1000400091059106E3EAC5FEB71500019385050306
:100050003716000113060603B7060002938606262C
:1000600039A083A2050023A0560091059106E3EA7A
:10007000C5FEB70500029385050337060002130687
:10008000062621A023A005009105E3EDC5FEB700DB
:100090000001E780C00AB7000001E780C00AB7107E
:1000A0000001E780808473005010F5BF828000005B
:1000B0000000000000000000000000000000000040
:1000C0006F004000197106C20AC40EC612C816CAD3
:1000D0001ACC1ECE22D026D22AD42ED632D836DA48
:1000E0003ADC3EDEC2C0C6C2CAC4CEC6D2C8D6CA78
:1000F000DACCDECEE2D0E6D2EAD4EED6F2D8F6DA28
:10010000FADCFEDE970000009380E00482909240CB
:100110002241B2414242D2426243F24302549254DB
:100120002255B2554256D2566257F2570648964863
:100130002649B649464AD64A664BF64B065C965C5B
:10014000265DB65D465ED65E665FF65F096173004A
:10015000203001A03D432A876373C3029377F700E1
:10016000BDEFADE5937606FF3D8ABA960CC34CC34E
:100170000CC74CC74107E36BD7FE11E28280B30680
:10018000C3408A069702000096966780A600230760
:10019000B700A306B7002306B700A305B7002305E1
:1001A000B700A304B7002304B700A303B7002303D9
:1001B000B700A302B7002302B700A301B7002301D1
:1001C000B700A300B7002300B700828093F5F50FB6
:1001D00093968500D58D93960501D58D61B793963D
:1001E00027009702000096968682E78086FA96801E
:1001F000C1171D8F3E96E374C3F8A5B7B707050076
:100200000947D8CFB7170500938707C0984385667D
:1002100093860640558F98C398471367074098C741
:10022000B71708009387074023A0070023A2070001
:1002300023A407001307B010D8C77D57D8CF354780
:1002400098C3D84F935657018D8AE5DE8280B71741
:1002500008009387074023A0070023A2070023A4D8
:10026000070023A607007D57D8CF23A40702B7179E
:100270000500938707C09843F1769386F63F758F04
:1002800098C398471377F7BF98C7B7070500094782
:1002900098D38280B71708009387074088D7D84F34
:1002A000137707046DDF82803707000203234704BA
:1002B000B706000237150800B7450F0023A406044F
:1002C0008147014613050540938515240328C50180
:1002D000B308F30013780802630C080205C2232256
:1002E000170537470F0023A4F60413070724639765
:1002F000E700B707000205472383E700B7170800A8
:1003000093870740C85342054181828005467DBFDF
:100310008507E39DB7FE7DD2B7470F00938707247B
:1003200023A4F60423221705E9B7411106C622C407
:1003300026C2AA84EF003024E1689388086A014845
:100340008147014781460146B70520C72685379476
:100350009800EF00B007130414687D1419E40D45EC
:10036000B240224492444101828085452685EF00B7
:10037000F02105897DF10145E5B7411122C437041B
:100380000002930704008C43B70700804AC0BE9563
:10039000B707000223AEB70206C626C293974501EF
:1003A000130404003709000289E713058900EF00F0
:1003B000102B0C40B70400029386C40413060010EF
:1003C00013058900EF00F0241C4037070002835614
:1003D0008703938707101CC013060010B68763F4C9
:1003E000C600930700101384C4041305F400938718
:1003F00007F01306100F814513040410231CF702A5
:10040000913BA2851385C4043D46EF00902923202B
:1004100004002322040023240400231604002307DD
:100420000400B240224492440249410182805D713D
:10043000130680028145280886C6293BBD47230C48
:10044000F1008947230EF1003ED2E1779387070838
:100450002C080A85231AF102F52BB64061618280CF
:100460005D71A2C4370400021305840086C6A6C2CB
:10047000CAC0C12513058400EF00007F8545130520
:100480008400EF00B0108D47814463E3A700AA8485
:10049000894513058400EF00700F937725002A86A5
:1004A00089E7136625001376F60FA68513058400E9
:1004B000EF003011E1689388086A014881470147DD
:1004C00081460146B7052038130584000127E168FD
:1004D00038009388086A1308000285468147014660
:1004E000B70599EB1305840023040100C525B71552
:1004F00000015146938585FE6800EF00901A1309AC
:100500008400832709006C0051463ED085473ED2C7
:100510006810C1673ED4EF00D018B70607009C42B0
:100520003707F1FF7D17F98F08109CC2A925B64047
:1005300026449644064961618280411106C6013B0A
:100540000537B707008073905730B700008082905E
:10055000B2404101828041113707000222C406C621
:100560009307070083C76700854613040700638E5F
:10057000D70009476388E70023030400B240224400
:10058000410182801305000F3133B71708009387AC
:100590000740D84F218B09C7D84F13678700D8CFA2
:1005A000693FD9BF411106C622C426C24AC083474B
:1005B000350005476383E70811472A846389E7000C
:1005C0008DCFB24022449244024941018280B70754
:1005D000000283D7870391C34D3383474400034709
:1005E0005400E2074207BA97370700022320F704B6
:1005F000370700022320F700E9B7370900028354C8
:1006000089030346050093054500370500021305DD
:10061000C5042695EF00F00883470400BE94C20489
:10062000C180231C99029307F00FE3FC97F8224442
:10063000B24092440249410189B33D45A139B7070F
:10064000000283D7870391C30D3B2244B2409244FA
:1006500002494101DDB53707000241119306070049
:1006600003DF460026C4B704000283A2840422C626
:100670003715080037040002B7480F0037430F0052
:10068000370E00024AC28147232A04021309FFFFE2
:10069000814E814681458143014801461307070089
:1006A000130505409388182413030324130ECE1555
:1006B000636FE60363850E0009462303C70089C6FE
:1006C000B7060002A388F60299C1232A74026304C4
:1006D000080023A4540483476700A9E73244A244D6
:1006E0001249370500021305C515410165BD814258
:1006F0000328C50113780802631B08028502E399E9
:1007000012FF89C6B7060002A388F60299C1232A00
:100710007402B7470F009387072423A4F404854786
:100720002303F7003244A244124941018280E38A44
:1007300062FC03284502937FF80F637D260113783E
:10074000F80FC29385453308CE002300F801050653
:100750000548B9BFB307704093F7F70F6394FF00E4
:100760008546D5B7854EEDBF011122CC4EC652C489
:1007700037040002B7490F00371ADCBA26CA4AC844
:1007800056C25AC006CE13040400370900029389EA
:10079000F923930A0003B7040002391A370B000249
:1007A000213683274904A303A40063F3F9007133BE
:1007B0008347640099C34533E5B783467400638873
:1007C0005605930700066381F60603C704038D47A9
:1007D000998F8E07B357FA0093F7F70F6393F606D6
:1007E0009307170093F7F70F2388F4021147639DCF
:1007F000E7003D45453413058B00053E29C113052F
:10080000000F493C238804022322090451BF3D45BF
:100810002322090423880402B53C793405052312F8
:10082000A4003D45853CADBF3D45232209042388F6
:1008300004028D340D3583476400B5FFDDB73D45B7
:10084000C9B723880402A9BF011106CE22CCC53640
:100850003704000213058400E92C130584002921C4
:10086000E1689388086A0148814778008546014617
:10087000B705D9EB1305840023060100812EE1683A
:100880009388086A01488147014781460146B705B8
:1008900038FF130584001D2E9532F9350547AA87C8
:1008A0006305E50209476300E506054591EBB706D8
:1008B0000600DC4A7D771307F73FF98FDCCA014554
:1008C00082807D1719EB0D4582809306004037A783
:1008D000070013070712B7050500905D7D8E75D2DE
:1008E000370606005C4A7D771307F73FF98FD58FEF
:1008F00041115CCA02C613073006B2476359F700BC
:10090000014541018280856693860680C9B7B2475A
:1009100085073EC6DDB791476307F50263EAA70086
:100920008547630AF50489476309F5040545828014
:10093000A147E31DF5FE0947094501A8FD1781EF11
:10094000C8D20D45828005470D45B7A7070093879C
:100950000712B7060500905E798E6DD28A05C98DA3
:100960004111CCD202C613073006B247635AF700D2
:100970000145410182801147C9BF21470145F1B7B7
:10098000B24785073EC6D5B70547AA876305E50286
:1009900009476304E506054591EBB70606009C4A46
:1009A0007D771307F73FF98F9CCA014582807D1739
:1009B00019EB0D4582809306004037A70700130707
:1009C0000712B7050500905D7D8E75D237070600CA
:1009D0001C4B7D761306F63FF18FD58F1CCB232C55
:1009E000070085471CCF411102C613073006B247E6
:1009F0006359F70001454101828085669386068030
:100A00006DBFB24785073EC6DDB711C98547630D87
:100A1000F50205458280FD1791EB0D458280094660
:100A2000B7A7070093870712B7060500985E718F76
:100A30007DD34111C8D602C613073006B2476357AB
:100A4000F7000145410182800546D9BFB2478507BD
:100A50003EC6EDB7011126CAB7040600DC4806CE33
:100A600022CC4AC84EC652C456C2F19BDCC89C4830
:100A70002A89C845F19B9CC8D84883C7C5012E84E4
:100A8000137737C08A07D98FDCC883C7D501984848
:100A90009A071377F7C393F7073CD98F9CC8FD3BA0
:100AA0000C44AA8A03454400BD351848B707050021
:100AB0002A8A98C358480850D8C3184C98C7E935B3
:100AC000AA8948509937834704002A8793F617006C
:100AD00089E6D44893E62600D4C893F6270099E621
:100AE00037060600544A93E6160054CA93F64700A8
:100AF00099E637060600144A93E6260014CAA18B2D
:100B000099E7B70606009C4A93E717009CCAF24093
:100B10006244232059012322490123243901232639
:100B2000E900D244B249224A924A4A8542490561C3
:100B30008280011106CE22CC02C402C62147B7072B
:100B4000050037550800D8C705448D478A85130529
:100B500005803EC022C2292A375508009307C003EA
:100B60008A851305058022C222C43EC01122F240AC
:100B7000624405618280411122C406C62A84553F21
:100B800018405C4F93E707015CCF1C441CCB5C40D2
:100B900085CB1C43B7061000D58F1CC3144C5C4892
:100BA000B240D606CE07D58F83460401C206D58F44
:100BB0008346C4012244E206D58F1CCF41018280C6
:100BC0001C43B706F0FFFD16F58FC1BF03230500D8
:100BD0002A8E0325C30113650502232EA3002324B7
:100BE000C3001396260149824D8E2326030123223A
:100BF000C300139605016354060299C20545B1CBA3
:100C000001476346D700639C08020D458280338606
:100C1000E700034606000507230AC300DDB799C2B3
:100C2000054505CB8147E3D0D7FE03260E000345DB
:100C300046013306F70085072300A600EDB783279A
:100C40000E00FD18DC4F93F70702D5DF11656D8D9F
:100C500011E18280B707070083C7470113F58500BC
:100C60001D8D3335A00082801C414147D8CF828042
:100C7000B7470800938707402A886304F508B757E9
:100C80000800938707806304F50A37470800630D5F
:100C9000E50A05458280331E1F013376DE0129C631
:100CA00083A3450088431393180033966F001346BF
:100CB000F6FF13F43300718D33146400418D88C343
:100CC000638B5302638C0302084303AEC500718D2E
:100CD000331E6E003365C50108C38842698E88459E
:100CE00033156500498E90C2850833D51E0145F540
:100CF0003244410182802326C801F9B72324C80168
:100D0000E1B7B716050037170500B717050093863A
:100D100046C1130707C19387C7C083AE050081484A
:100D2000054F8D4F914233D51E0105ED8280B716D8
:100D3000050037170500B7170500938606C213078D
:100D4000C7C1938787C1D1BFB71605003717050004
:100D5000B7170500938686C0130747C0938707C05F
:100D60006DBF331E1F013376DE0119E2850865BFB2
:100D7000411122C635B7E1689388086A0148814766
:100D8000014781460146B705200689B5011106CE07
:100D9000A307010089476393F502B7052035E16891
:100DA0001307F1009388086A014881478546014688
:100DB000313DF2400345F10005618280B705200511
:100DC000F9BF011106CE22CC26CA2306B100AA849F
:100DD000A306C1004D37E1689388086A01487C008A
:100DE000014789460146B785200126850964F93BFC
:100DF000130414717D1419E40D45F2406244D24489
:100E000005618280854526855137058965F501454F
:100E1000EDB7011106CE22CC26CA2E844AC8AA8478
:100E2000328936C6893FB247E16822869388086ACC
:100E300001480147CA86B7858002268561647933F7
:100E40001304146A7D1411C48545268581370589EC
:100E500075F9F2406244D244424905618280011131
:100E600006CE22CC26CA2EC6AA8431373246E16885
:100E70009388086A0148814701478146B705802069
:100E800026856164A1331304146A7D1411C4854559
:100E90002685ED3D058975F9F2406244D24405612D
:100EA0008280B3C7A5008D8BB308C500B1E78D471D
:100EB00063F4C704937735002A87B9EB13F6C8FFAC
:100EC000B306E6409307000263C8D706AE86BA872A
:100ED0006371C70203A806009107910623AE07FFBE
:100EE000E3EAC7FE9307F6FF998FF19B91073E97C0
:100EF000BE956366170182802A87637E150383C7C8
:100F0000050005078505A30FF7FEE39AE8FE82803A
:100F100083C60500050793773700A30FD7FE850525
:100F2000D1DF83C60500050793773700A30FD7FEEF
:100F30008505F9FF61B78280411122C613040002C2
:100F400083A3050083A2450083AF850003AFC500DE
:100F500083AE050103AE450103A3850103A8C501C6
:100F6000945113074702B307E640232E77FC232052
:100F700057FE2322F7FF2324E7FF2326D7FF23284A
:100F8000C7FF232A67FE232C07FF232ED7FE938556
:100F90004502E347F4FAAE86BA876371C70203A835
:100FA00006009107910623AE07FFE3EAC7FE930709
:100FB000F6FF998FF19B91073E97BE9563651701E8
:100FC00032444101828083C7050005078505A30FD0
:100FD000F7FEE387E8FE83C7050005078505A30F35
:100FE000F7FEE392E8FEE9BF2000000001000000E8
:100FF0000300000006000000EB00000000000000FD
:101000000000008000000000000007000000000059
:1010100000000000000000000000000000000000D0
:1010200000000000000000000000000000000000C0
:0400000501000000F6
:00000001FF

View File

@ -35,11 +35,6 @@
#include "wiring.h"
// define из avr-gcc (некоторые библиотеки ардуины им пользуются)
#define _BV(bit) (1 << (bit))
// void ErrorMsgHandler(const char * msg);
/* sketch */
#ifdef __cplusplus
extern "C" {

View File

@ -5,9 +5,17 @@
#include "HardwareSerial.h"
#include <uart_lib.h>
#include "mik32_hal_irq.h"
#include "wiring_LL.h"
// HardwareSerial class objects for use in Arduino IDE
HardwareSerial Serial0(0);
#if SERIAL_PORT_QTY > 1
HardwareSerial Serial1(1);
#endif
// default interface
HardwareSerial& Serial = DEFAULT_SERIAL;
// объект класса HardwareSerial для использования в arduino ide
HardwareSerial Serial;
void serialEvent() __attribute__((weak));
bool Serial0_available() __attribute__((weak));
@ -55,35 +63,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 +120,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_IS_RX_FIFO_EMPTY(uart))
{
c = UART_ReadByte(UART_0);
c = UART_READ_BYTE(uart);
if (i != _rx_buffer_tail)
{
// write if there is space in the buffer
@ -119,9 +143,16 @@ void HardwareSerial::rx_complete_irq(void)
}
// wrapper for use in С-files
extern "C" void serial_handler_wrapper(void)
extern "C" void __attribute__((optimize("O3"))) serial_interrupt_handler(uint8_t uartNumInt)
{
Serial.rx_complete_irq();
if (uartNumInt == 0)
{
Serial0.rx_complete_irq();
}
else if ((uartNumInt == 1) && (SERIAL_PORT_QTY > 1))
{
Serial1.rx_complete_irq();
}
}
int HardwareSerial::peek(void)
@ -151,8 +182,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 +220,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);
}

View File

@ -27,6 +27,7 @@
#include <inttypes.h>
#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);
@ -94,10 +100,16 @@ class HardwareSerial : public Stream
using Print::write; // pull in write(str)
operator bool() { return isInited; }
void rx_complete_irq(void);
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));
#endif

View File

@ -53,7 +53,6 @@ size_t Print::print(const __FlashStringHelper *ifsh)
else break;
}
return n;
// return print(reinterpret_cast<const char *>(ifsh));
}
size_t Print::print(const String &s)

View File

@ -3,6 +3,7 @@
#include "mik32_hal_timer16.h"
#include "mik32_hal_irq.h"
#include "wiring_LL.h"
#define PRESCALERS_QTY 7
typedef struct
@ -44,7 +45,7 @@ static void Timer16_Init(uint8_t prescaler)
htimer16_1.Trigger.TimeOut = TIMER16_TIMEOUT_DISABLE;
htimer16_1.Filter.ExternalClock = TIMER16_FILTER_NONE;
htimer16_1.Filter.Trigger = TIMER16_FILTER_NONE;
htimer16_1.Waveform.Enable = TIMER16_WAVEFORM_GENERATION_ENABLE;
htimer16_1.Waveform.Enable = TIMER16_WAVEFORM_GENERATION_DISABLE;
htimer16_1.Waveform.Polarity = TIMER16_WAVEFORM_POLARITY_NONINVERTED;
htimer16_1.EncoderMode = TIMER16_ENCODER_DISABLE;
HAL_Timer16_Init(&htimer16_1);
@ -78,6 +79,12 @@ static void calcFrequencyParams(FrequencyParams_t* params, unsigned int newFrequ
// start tone with frequency (in hertz) and duration (in milliseconds)
void tone(uint8_t pin, unsigned int frequency, unsigned long duration)
{
if ((pin>=pinCommonQty()))
{
ErrorMsgHandler("tone(): pin number exceeds the total number of pins");
return;
}
if (!timerIsOn) // if tone is not generated at the moment
{
// calculate the parameters necessary to ensure a given frequency if the frequency has changed
@ -100,7 +107,7 @@ void tone(uint8_t pin, unsigned int frequency, unsigned long duration)
HAL_EPIC_MaskLevelSet(HAL_EPIC_TIMER16_1_MASK);
pinMode(pin, OUTPUT);
timer_pin_port->CLEAR = timer_pin_mask;
GPIO_CLEAR_PIN((GPIO_TypeDef *)timer_pin_port, timer_pin_mask);
HAL_Timer16_Counter_Start_IT(&htimer16_1, frequencyParams.period_ticks);
timerIsOn = true;
@ -122,11 +129,18 @@ void tone(uint8_t pin, unsigned int frequency, unsigned long duration)
// stop tone
void noTone(uint8_t pin)
{
if ((pin>=pinCommonQty()))
{
ErrorMsgHandler("noTone(): pin number exceeds the total number of pins");
return;
}
if (timerIsOn)
{
timer_pin_port->CLEAR = timer_pin_mask; // pin to 0
htimer16_1.Instance->CR &= ~TIMER16_CR_ENABLE_M; // disable timer
HAL_EPIC_MaskLevelClear(HAL_EPIC_TIMER16_1_MASK);
// pin to 0
GPIO_CLEAR_PIN((GPIO_TypeDef *)timer_pin_port, timer_pin_mask);
TIM16_DISABLE(htimer16_1);
EPIC_LEVEL_CLEAR_BY_MASK(HAL_EPIC_TIMER16_1_MASK);
pinMode(pin, INPUT); // deinit pin
timer_pin = -1; // reset to default
timerIsOn = false;
@ -134,25 +148,26 @@ void noTone(uint8_t pin)
}
// irq handler
extern "C" void tone_interrupt_handler(void)
extern "C" void __attribute__((noinline, section(".ram_text"), optimize("O3"))) tone_interrupt_handler(void)
{
if ((htimer16_1.Instance->ISR & htimer16_1.Instance->IER) & TIMER16_ISR_ARR_MATCH_M)
if (TIM16_GET_ARRM_INT_STATUS(htimer16_1))
{
// timer period has passed, change the pin state
if (timer_toggle_count != 0)
{
timer_pin_port->OUTPUT_ ^= timer_pin_mask;
GPIO_TOGGLE_PIN((GPIO_TypeDef*)timer_pin_port, timer_pin_mask);
if (timer_toggle_count > 0)
timer_toggle_count--;
}
else
{
// turn off if the specified duration has passed
timer_pin_port->CLEAR = timer_pin_mask;
noTone(timer_pin);
GPIO_CLEAR_PIN((GPIO_TypeDef *)timer_pin_port, timer_pin_mask);
TIM16_DISABLE(htimer16_1);
EPIC_LEVEL_CLEAR_BY_MASK(HAL_EPIC_TIMER16_1_MASK);
timerIsOn = false;
}
}
// reset timer interrupt flags
htimer16_1.Instance->ICR = 0xFFFFFFFF;
TIM16_CLEAR_INT_MASK(htimer16_1, 0xFFFFFFFF);
}

View File

@ -4,8 +4,10 @@
#include "pins_arduino.h"
#include "wiring_digital.h"
#include "WInterrupts.h"
#include "wiring_LL.h"
extern void ErrorMsgHandler(const char * msg);
// interrupts are enabled by default after setup()
static bool intIsEnabled = true;
typedef void (*voidFuncPtr)(void);
@ -18,34 +20,40 @@ static void nothing(void)
// enable global interrupts
void interrupts(void)
{
HAL_IRQ_EnableInterrupts();
GLOBAL_IRQ_ENABLE();
intIsEnabled = true;
}
// disable global interrupts
void noInterrupts(void)
{
HAL_IRQ_DisableInterrupts();
GLOBAL_IRQ_DISABLE();
intIsEnabled = false;
}
// we can provide no more than 8 interrupts on gpio at the same time
static volatile voidFuncPtr intFunc[EXTERNAL_NUM_INTERRUPTS] =
bool isInterruptsEnabled(void)
{
#if EXTERNAL_NUM_INTERRUPTS > 7
return intIsEnabled;
}
// we can provide no more than 8 interrupts on gpio at the same time
static volatile voidFuncPtr intFunc[EXTERNAL_INTERRUPTS_QTY] =
{
#if EXTERNAL_INTERRUPTS_QTY > 7
nothing,
#endif
#if EXTERNAL_NUM_INTERRUPTS > 6
#if EXTERNAL_INTERRUPTS_QTY > 6
nothing,
#endif
#if EXTERNAL_NUM_INTERRUPTS > 5
#if EXTERNAL_INTERRUPTS_QTY > 5
nothing,
#endif
#if EXTERNAL_NUM_INTERRUPTS > 4
#if EXTERNAL_INTERRUPTS_QTY > 4
nothing,
#endif
#if EXTERNAL_NUM_INTERRUPTS > 3
#if EXTERNAL_INTERRUPTS_QTY > 3
nothing,
#endif
#if EXTERNAL_NUM_INTERRUPTS > 2
#if EXTERNAL_INTERRUPTS_QTY > 2
nothing,
#endif
nothing,
@ -55,7 +63,7 @@ static volatile voidFuncPtr intFunc[EXTERNAL_NUM_INTERRUPTS] =
void attachInterrupt(uint8_t interruptNum, void (*userFunc)(void), int mode)
{
// if the interrupt number does not exceed the total number
if(interruptNum < EXTERNAL_NUM_INTERRUPTS)
if(interruptNum < EXTERNAL_INTERRUPTS_QTY)
{
intFunc[interruptNum] = userFunc; // save pointer to irq handler
@ -86,7 +94,7 @@ void attachInterrupt(uint8_t interruptNum, void (*userFunc)(void), int mode)
void detachInterrupt(uint8_t interruptNum)
{
if(interruptNum < EXTERNAL_NUM_INTERRUPTS)
if(interruptNum < EXTERNAL_INTERRUPTS_QTY)
{
// disable the interrupt in line
HAL_GPIO_DeInitInterruptLine(interruptToGpioIntLine(interruptNum));
@ -99,34 +107,27 @@ void detachInterrupt(uint8_t interruptNum)
// disable single interrupt
void disableInterrupt(uint8_t interruptNum)
{
if(interruptNum < EXTERNAL_NUM_INTERRUPTS)
{
int irq_line_num = interruptToGpioIntLine(interruptNum) >> GPIO_IRQ_LINE_S;
if(interruptNum < EXTERNAL_INTERRUPTS_QTY)
// disable gpio interrupt line
GPIO_IRQ->ENABLE_CLEAR = (1 << irq_line_num);
}
GPIO_IRQ_LINE_DISABLE(interruptToGpioIntLine(interruptNum));
}
// enable single interrupt
void enableInterrupt(uint8_t interruptNum)
{
if(interruptNum < EXTERNAL_NUM_INTERRUPTS)
{
int irq_line_num = interruptToGpioIntLine(interruptNum) >> GPIO_IRQ_LINE_S;
if(interruptNum < EXTERNAL_INTERRUPTS_QTY)
// enable gpio interrupt line
GPIO_IRQ->ENABLE_SET = (1 << irq_line_num);
}
GPIO_IRQ_LINE_ENABLE(interruptToGpioIntLine(interruptNum));
}
// common gpio interrupt handler
void gpio_interrupts_handler(void)
void __attribute__((noinline, section(".ram_text"), optimize("O3"))) gpio_interrupt_handler(void)
{
// go through all the interrupts and call the handler for the triggered line
for (uint8_t i = 0; i < EXTERNAL_NUM_INTERRUPTS; i++)
for (uint8_t i = 0; i < EXTERNAL_INTERRUPTS_QTY; i++)
{
if (HAL_GPIO_LineInterruptState(interruptToGpioIntLine(i)))
if (GPIO_IRQ_LINE_STATE(interruptToGpioIntLine(i)))
intFunc[i]();
}
HAL_GPIO_ClearInterrupts();
GPIO_IRQ_CLEAR_ALL();
}

View File

@ -6,10 +6,12 @@ extern "C" {
#endif
#include <stdint.h>
#include "stdbool.h"
// enable/disable interrupts
void interrupts(void);
void noInterrupts(void);
bool isInterruptsEnabled(void);
// attach/detach interrupt to pin
void attachInterrupt(uint8_t interruptNum, void (*userFunc)(void), int mode);

View File

@ -19,6 +19,8 @@
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#pragma GCC diagnostic ignored "-Wrestrict" // for GCC and Clang
#include "WString.h"
#include "itoa.h"

View File

@ -1,11 +1,49 @@
#include "board.h"
#include "mik32_hal_pcc.h"
#include "mik32_hal_irq.h"
#include "Arduino.h"
// --------------------- init --------------------- //
// called before setup()
void pre_init(void)
// --------------------- 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)
{
// set irq vector to ram region
write_csr(mtvec, 0x02000000);
HAL_Init();
// gpio clock
@ -16,21 +54,27 @@ void pre_init(void)
// for delays
SysTick_Init();
// update flash cache limit by app size
updateCacheLimit();
}
// called after setup()
void post_init(void)
{
// enable global interrupts by default
interrupts();
if(isInterruptsEnabled()) // if user has called noInterrupts() in setup(), this value is false
interrupts(); // enable global interrupts
}
// --------------------- other --------------------- //
// print text if Serial is enabled
volatile bool use_error_messages = true;
// print error message to Serial
extern "C" void ErrorMsgHandler(const char * msg)
{
if(Serial)
Serial.println(msg);
// function works if Serial is used in sketch and user doesn't turn it off
#ifdef HardwareSerial_h
if(use_error_messages&&Serial)
Serial.println(msg);
#endif
}

View File

@ -1,8 +1,11 @@
#ifndef _BOARD_H_
#define _BOARD_H_
// functions for init called before and after setup()
void pre_init(void) ;
extern volatile bool use_error_messages;
#define DISABLE_ERROR_MESSAGES() (use_error_messages = false)
#define ENABLE_ERROR_MESSAGES() (use_error_messages = true)
// function for init called after setup()
void post_init(void);
#endif /* _BOARD_H_ */

View File

@ -2,9 +2,15 @@
#include "Arduino.h"
// Weak empty variant initialization function.
// May be redefined by variant files.
void initVariant() __attribute__((weak));
void initVariant() { }
extern "C" int main(void) __attribute__((weak));
int main()
{
pre_init();
initVariant(); // for freeRTOS
setup();
post_init();
@ -12,6 +18,4 @@ int main()
{
loop();
}
}
}

View File

@ -7,7 +7,7 @@ extern "C" {
#include "mik32_hal_def.h"
#include <mcu32_memory_map.h>
#include <eeprom.h>
#include <eeprom_def.h>
#include <power_manager.h>
#ifndef HAL_EEPROM_TIMEOUT

View File

@ -36,6 +36,7 @@ extern "C" {
*/
typedef enum __HAL_PinsTypeDef
{
NOT_A_PIN = (0 << 0), /**< Не выбран пин. */
GPIO_PIN_0 = (1 << 0), /**< Выбран пин 0. */
GPIO_PIN_1 = (1 << 1), /**< Выбран пин 1. */
GPIO_PIN_2 = (1 << 2), /**< Выбран пин 2. */
@ -375,14 +376,96 @@ typedef enum __HAL_GPIO_InterruptMode
HAL_StatusTypeDef HAL_GPIO_Init(GPIO_TypeDef *GPIO_x, GPIO_InitTypeDef *GPIO_Init);
HAL_StatusTypeDef HAL_GPIO_PinConfig(GPIO_TypeDef *GPIO_x, HAL_PinsTypeDef pin, HAL_GPIO_ModeTypeDef mode, HAL_GPIO_PullTypeDef pull, HAL_GPIO_DSTypeDef driveStrength);
GPIO_PinState HAL_GPIO_ReadPin(GPIO_TypeDef *GPIO_x, HAL_PinsTypeDef pin);
void HAL_GPIO_WritePin(GPIO_TypeDef *GPIO_x, HAL_PinsTypeDef pin, GPIO_PinState pinState);
void HAL_GPIO_TogglePin(GPIO_TypeDef *GPIO_x, HAL_PinsTypeDef pin);
HAL_StatusTypeDef HAL_GPIO_InitInterruptLine(HAL_GPIO_Line_Config mux, HAL_GPIO_InterruptMode mode);
HAL_StatusTypeDef HAL_GPIO_DeInitInterruptLine(HAL_GPIO_Line irqLine);
uint32_t HAL_GPIO_LineInterruptState(HAL_GPIO_Line irqLine);
GPIO_PinState HAL_GPIO_LinePinState(HAL_GPIO_Line irqLine);
void HAL_GPIO_ClearInterrupts();
/**
* @brief Считать текущее состояние выводов порта GPIO_x.
* @param GPIO_x порт GPIO_x, где x может быть (0, 1, 2).
* @param pin маска выводов порта GPIO_x, с которых считывание значение.
* @return @ref GPIO_PIN_HIGH если с одного или больше выводов, указанных в pin, считалась 1. Иначе @ref GPIO_PIN_LOW.
*/
static inline __attribute__((always_inline)) GPIO_PinState HAL_GPIO_ReadPin(GPIO_TypeDef *GPIO_x, HAL_PinsTypeDef pin)
{
if ((GPIO_x->SET & pin) != (uint32_t)GPIO_PIN_LOW)
return GPIO_PIN_HIGH;
else
return GPIO_PIN_LOW;
}
/**
* @brief Задать логический уровень выходного сигнала для указанных выводов порта GPIO_x.
* @param GPIO_x порт GPIO_x, где x может быть (0, 1, 2).
* @param pin маска выводов порта GPIO_x, к которым применяются указанные настройки.
* @param pinState значение состояние вывода, в которое будут установлены указанные выводы.
* Этот параметр должен быть одним из значений:
* - @ref GPIO_PIN_LOW низкий выходной уровень
* - @ref GPIO_PIN_HIGH высокий выходной уровень
*/
static inline __attribute__((always_inline)) void HAL_GPIO_WritePin(GPIO_TypeDef *GPIO_x, HAL_PinsTypeDef pin, GPIO_PinState pinState)
{
if (pinState == GPIO_PIN_LOW)
GPIO_x->CLEAR = pin;
else
GPIO_x->SET = pin;
}
/**
* @brief Переключить логический уровень выходного сигнала для указанных выводов порта GPIO_x.
* @param GPIO_x порт GPIO_x, где x может быть (0, 1, 2).
* @param pin маска выводов порта GPIO_x, к которым применяются указанные настройки.
*/
static inline __attribute__((always_inline)) void HAL_GPIO_TogglePin(GPIO_TypeDef *GPIO_x, HAL_PinsTypeDef pin)
{
GPIO_x->OUTPUT_ ^= pin;
}
/**
* @brief Возвращает направление вывода при работе в режиме вход/выход
* @param GPIO_x порт GPIO_x, где x может быть (0, 1, 2).
* @param pin маска вывода порта GPIO_x, направление которого необходимо узнать.
* @return Возвращает направление вывода - input или output.
*/
static inline __attribute__((always_inline)) HAL_GPIO_ModeTypeDef HAL_GPIO_GetPinDirection(GPIO_TypeDef *GPIO_x, HAL_PinsTypeDef pin)
{
return (GPIO_x->DIRECTION_IN & pin) == 0 ? HAL_GPIO_MODE_GPIO_OUTPUT : HAL_GPIO_MODE_GPIO_INPUT;
}
/**
* @brief Получить состояние линии прерывания.
* @param irqLine номер линии прерывания.
* @return Возвращает 1 если сработало прерывание данной линии, иначе 0.
*/
static inline __attribute__((always_inline)) uint32_t HAL_GPIO_LineInterruptState(HAL_GPIO_Line irqLine)
{
int irq_line_num = irqLine >> GPIO_IRQ_LINE_S;
return (GPIO_IRQ->INTERRUPT & (1 << (irq_line_num))) != 0;
}
/**
* @brief Функция чтения логического уровня вывода, подключенного к линии прерывания.
* @param irqLine номер линии прерывания.
* @return Логический уровень вывода.
*/
static inline __attribute__((always_inline)) GPIO_PinState HAL_GPIO_LinePinState(HAL_GPIO_Line irqLine)
{
int irq_line_num = irqLine >> GPIO_IRQ_LINE_S;
return (GPIO_PinState)((GPIO_IRQ->STATE & (1 << (irq_line_num))) >> irq_line_num);
}
/**
* @brief Функция сброса регистра состояния прерываний.
* @note Когда срабатывает прерывание на одной из линии, в регистре INTERRUPT
* выставляется 1 в разряде, соответствующем линии прерывания.
* После обработки прерывания необходимо сбросить данный регистр
* в обработчике прерывания trap_handler().
* Если после обработки прерывания регистр не был сброшен,
* обработчик будет вызван снова, программа будет бесконечно вызывать обработчик.
*/
static inline __attribute__((always_inline)) void HAL_GPIO_ClearInterrupts()
{
GPIO_IRQ->CLEAR = 0b11111111;
}
#ifdef __cplusplus
}

View File

@ -380,9 +380,6 @@ typedef struct
void HAL_I2C_MspInit(I2C_HandleTypeDef* hi2c);
void HAL_I2C_Disable(I2C_HandleTypeDef *hi2c);
void HAL_I2C_Reset(I2C_HandleTypeDef *hi2c);
void HAL_I2C_Enable(I2C_HandleTypeDef *hi2c);
void HAL_I2C_AnalogFilterInit(I2C_HandleTypeDef *hi2c, HAL_I2C_AnalogFilterTypeDef AnalogFilter);
void HAL_I2C_DigitalFilterInit(I2C_HandleTypeDef *hi2c, HAL_I2C_DigitalFilterTypeDef DigitalFilter);
void HAL_I2C_SetClockSpeed(I2C_HandleTypeDef *hi2c);
@ -394,6 +391,7 @@ void HAL_I2C_SBCMode(I2C_HandleTypeDef *hi2c, HAL_I2C_SBCModeTypeDef SBCMode);
void HAL_I2C_SlaveInit(I2C_HandleTypeDef *hi2c);
void HAL_I2C_MasterInit(I2C_HandleTypeDef *hi2c);
HAL_StatusTypeDef HAL_I2C_Init(I2C_HandleTypeDef *hi2c);
HAL_StatusTypeDef HAL_I2C_Deinit(I2C_HandleTypeDef *hi2c);
void HAL_I2C_AutoEnd(I2C_HandleTypeDef *hi2c, HAL_I2C_AutoEndModeTypeDef AutoEnd);
HAL_StatusTypeDef HAL_I2C_Master_WaitTXIS(I2C_HandleTypeDef *hi2c, uint32_t Timeout);
HAL_StatusTypeDef HAL_I2C_Master_WaitRXNE(I2C_HandleTypeDef *hi2c, uint32_t Timeout);
@ -427,6 +425,60 @@ HAL_StatusTypeDef HAL_I2C_Slave_Receive_IT(I2C_HandleTypeDef *hi2c, uint8_t *pDa
HAL_StatusTypeDef HAL_I2C_Slave_Receive_NOSTRETCH_IT(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t DataSize);
HAL_StatusTypeDef HAL_I2C_Slave_ReceiveSBC_IT(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t DataSize);
static inline __attribute__((always_inline)) void HAL_I2C_Disable(I2C_HandleTypeDef *hi2c)
{
hi2c->Instance->CR1 &= ~I2C_CR1_PE_M;
}
static inline __attribute__((always_inline)) void HAL_I2C_Reset(I2C_HandleTypeDef *hi2c)
{
hi2c->ErrorCode = I2C_ERROR_NONE;
hi2c->Instance->CR1 &= ~I2C_CR1_PE_M;
hi2c->Instance->CR1 |= I2C_CR1_PE_M;
}
static inline __attribute__((always_inline)) void HAL_I2C_Enable(I2C_HandleTypeDef *hi2c)
{
hi2c->Instance->CR1 |= I2C_CR1_PE_M;
}
static inline __attribute__((always_inline)) void HAL_I2C_Reset_Interrupt_Flag(I2C_HandleTypeDef *hi2c, uint32_t mask)
{
hi2c->Instance->ICR |= mask;
}
static inline __attribute__((always_inline)) void HAL_I2C_Reset_TXDR_Content(I2C_HandleTypeDef *hi2c)
{
hi2c->Instance->ISR |= I2C_ISR_TXE_M;
}
static inline __attribute__((always_inline)) uint32_t HAL_I2C_Get_Interrupts_Status(I2C_HandleTypeDef *hi2c)
{
return hi2c->Instance->ISR;
}
static inline __attribute__((always_inline)) uint32_t HAL_I2C_Get_CR1_Content(I2C_HandleTypeDef *hi2c)
{
return hi2c->Instance->CR1;
}
static inline __attribute__((always_inline)) void HAL_I2C_Write_TXDR(I2C_HandleTypeDef *hi2c, uint8_t value)
{
hi2c->Instance->TXDR = value;
}
static inline __attribute__((always_inline)) uint8_t HAL_I2C_Get_RXDR(I2C_HandleTypeDef *hi2c)
{
return hi2c->Instance->RXDR;
}
static inline __attribute__((always_inline)) void HAL_I2C_Clear_Reload(I2C_HandleTypeDef *hi2c)
{
hi2c->Instance->CR2 &= ~I2C_CR2_RELOAD_M;
}
static inline __attribute__((always_inline)) void HAL_I2C_ADDR_IRQ(I2C_HandleTypeDef *hi2c)
{
if (hi2c->Instance->CR1 & I2C_CR1_SBC_M)

View File

@ -253,7 +253,8 @@ void HAL_SPI_CS_Disable(SPI_HandleTypeDef *hspi);
HAL_StatusTypeDef HAL_SPI_Exchange(SPI_HandleTypeDef *hspi, uint8_t TransmitBytes[], uint8_t ReceiveBytes[], uint32_t Size, uint32_t Timeout);
HAL_StatusTypeDef HAL_SPI_ExchangeThreshold(SPI_HandleTypeDef *hspi, uint8_t TransmitBytes[], uint8_t ReceiveBytes[], uint32_t DataSize, uint32_t Timeout);
HAL_StatusTypeDef HAL_SPI_Exchange_IT(SPI_HandleTypeDef *hspi, uint8_t TransmitBytes[], uint8_t ReceiveBytes[], uint32_t Size);
void HAL_SPI_Set_Clock_Divider(SPI_HandleTypeDef *hspi);
void HAL_SPI_Set_Clock_Mode(SPI_HandleTypeDef *hspi);
/**
* @brief Разрешить прерывания в соответствии с маской.

View File

@ -144,8 +144,8 @@ typedef enum __HAL_Timer16_EncoderTypeDef
*/
typedef enum __HAL_Timer16_WaveformGenTypeDef
{
TIMER16_WAVEFORM_GENERATION_ENABLE = 0, /**< Выключить генерацию волновой формы. */
TIMER16_WAVEFORM_GENERATION_DISABLE = 1 /**< Включить генерацию волновой формы. */
TIMER16_WAVEFORM_GENERATION_ENABLE = 0, /**< Включить генерацию волновой формы. */
TIMER16_WAVEFORM_GENERATION_DISABLE = 1 /**< Выключить генерацию волновой формы. */
} HAL_Timer16_WaveformGenTypeDef;
/**
@ -230,8 +230,6 @@ typedef struct __Timer16_HandleTypeDef
void HAL_TIMER16_MspInit(Timer16_HandleTypeDef* htimer16);
void HAL_Timer16_Disable(Timer16_HandleTypeDef *htimer16);
void HAL_Timer16_Enable(Timer16_HandleTypeDef *htimer16);
void HAL_Timer16_SetActiveEdge(Timer16_HandleTypeDef *htimer16, uint8_t ActiveEdge);
void HAL_Timer16_SetSourceClock(Timer16_HandleTypeDef *htimer16, uint8_t SourceClock);
void HAL_Timer16_SetCountMode(Timer16_HandleTypeDef *htimer16, uint8_t CountMode);
@ -278,6 +276,26 @@ void HAL_Timer16_SetInterruptARRM(Timer16_HandleTypeDef *htimer16);
void HAL_Timer16_SetInterruptCMPM(Timer16_HandleTypeDef *htimer16);
void HAL_Timer16_InterruptInit(Timer16_HandleTypeDef *htimer16);
/**
* @brief Выключить таймер.
* Может использоваться для отключения таймера или при записи в регистр CFGR.
*
* @param htimer16 Указатель на структуру с настройками Timer16.
*/
static inline void __attribute__((always_inline)) HAL_Timer16_Disable(Timer16_HandleTypeDef *htimer16)
{
htimer16->Instance->CR &= ~TIMER16_CR_ENABLE_M;
}
/**
* @brief Включить таймер
* @param htimer16 Указатель на структуру с настройками Timer16.
*/
static inline void __attribute__((always_inline)) HAL_Timer16_Enable(Timer16_HandleTypeDef *htimer16)
{
htimer16->Instance->CR |= TIMER16_CR_ENABLE_M;
}
/**
* @brief Получить статус прерываний Timer16.
* Функция возвращает статус прерываний в соответствии с маской разрешенный прерываний.
@ -291,6 +309,16 @@ static inline __attribute__((always_inline)) uint32_t HAL_Timer16_GetInterruptSt
return interrupt_status;
}
/**
* @brief Получить статус прерывания по соответствию автозагрузке ARRM
* @param htimer16 Указатель на структуру с настройками Timer16
* @return Статус прерывания ARRM - true, если прерывание сработало
*/
static inline __attribute__((always_inline)) bool HAL_Timer16_GetInterruptStatus_ARRM(Timer16_HandleTypeDef *htimer16)
{
return (bool)((htimer16->Instance->ISR & htimer16->Instance->IER) & TIMER16_ISR_ARR_MATCH_M);
}
/**
* @brief Очистить флаг прерывания.
* @param htimer16 Указатель на структуру с настройками Timer16.

View File

@ -226,6 +226,7 @@ static inline __attribute__((always_inline)) HAL_StatusTypeDef HAL_Timer32_WaitF
void HAL_TIMER32_MspInit(TIMER32_HandleTypeDef* htimer32);
void HAL_TIMER32_Channel_MspInit(TIMER32_CHANNEL_HandleTypeDef* timerChannel);
HAL_StatusTypeDef HAL_Timer32_Init(TIMER32_HandleTypeDef *timer);
HAL_StatusTypeDef HAL_Timer32_Deinit(TIMER32_HandleTypeDef *timer);
void HAL_Timer32_State_Set(TIMER32_HandleTypeDef *timer, HAL_TIMER32_StateTypeDef state);
void HAL_Timer32_Top_Set(TIMER32_HandleTypeDef *timer, uint32_t top);
void HAL_Timer32_Prescaler_Set(TIMER32_HandleTypeDef *timer, uint32_t prescaler);

View File

@ -105,7 +105,7 @@ typedef enum __HAL_TSENS_ClockTypeDef
/**
* @brief Определение структуры TSENS Handle.
*/
typedef struct __SPI_HandleTypeDef
typedef struct __TSENS_HandleTypeDef
{
ANALOG_REG_TypeDef *Instance; /**< Адрес регистров блока управления аналоговой подсистемой. */
@ -119,7 +119,7 @@ typedef struct __SPI_HandleTypeDef
/**
* @brief Возвращаемая структура для функции @ref HAL_TSENS_SingleStart.
*/
typedef struct __WDT_ClockTypeDef
typedef struct __TSENS_ValueTypeDef
{
HAL_StatusTypeDef statusHAL; /**< Статус HAL. */

View File

@ -105,7 +105,7 @@ typedef struct __WDT_ClockTypeDef
} WDT_ClockTypeDef;
void HAL_RTC_MspInit(WDT_HandleTypeDef* hwdt);
void HAL_WDT_MspInit(WDT_HandleTypeDef* hwdt);
HAL_StatusTypeDef HAL_WDT_Init(WDT_HandleTypeDef *hwdt, uint32_t timeout);
HAL_StatusTypeDef HAL_WDT_Refresh(WDT_HandleTypeDef *hwdt, uint32_t timeout);
HAL_StatusTypeDef HAL_WDT_Start(WDT_HandleTypeDef *hwdt, uint32_t timeout);

View File

@ -93,58 +93,6 @@ HAL_StatusTypeDef HAL_GPIO_PinConfig(GPIO_TypeDef *GPIO_x, HAL_PinsTypeDef pin,
return HAL_GPIO_Init(GPIO_x, &GPIO_InitStruct);
}
/**
* @brief Считать текущее состояние выводов порта GPIO_x.
* @param GPIO_x порт GPIO_x, где x может быть (0, 1, 2).
* @param pin маска выводов порта GPIO_x, с которых считывание значение.
* @return @ref GPIO_PIN_HIGH если с одного или больше выводов, указанных в pin, считалась 1. Иначе @ref GPIO_PIN_LOW.
*/
GPIO_PinState HAL_GPIO_ReadPin(GPIO_TypeDef *GPIO_x, HAL_PinsTypeDef pin)
{
GPIO_PinState bitStatus;
if ((GPIO_x->SET & pin) != (uint32_t)GPIO_PIN_LOW)
{
bitStatus = GPIO_PIN_HIGH;
}
else
{
bitStatus = GPIO_PIN_LOW;
}
return bitStatus;
}
/**
* @brief Задать логический уровень выходного сигнала для указанных выводов порта GPIO_x.
* @param GPIO_x порт GPIO_x, где x может быть (0, 1, 2).
* @param pin маска выводов порта GPIO_x, к которым применяются указанные настройки.
* @param pinState значение состояние вывода, в которое будут установлены указанные выводы.
* Этот параметр должен быть одним из значений:
* - @ref GPIO_PIN_LOW низкий выходной уровень
* - @ref GPIO_PIN_HIGH высокий выходной уровень
*/
void HAL_GPIO_WritePin(GPIO_TypeDef *GPIO_x, HAL_PinsTypeDef pin, GPIO_PinState pinState)
{
if (pinState == GPIO_PIN_LOW)
{
GPIO_x->CLEAR = pin;
}
else
{
GPIO_x->SET = pin;
}
}
/**
* @brief Переключить логический уровень выходного сигнала для указанных выводов порта GPIO_x.
* @param GPIO_x порт GPIO_x, где x может быть (0, 1, 2).
* @param pin маска выводов порта GPIO_x, к которым применяются указанные настройки.
*/
void HAL_GPIO_TogglePin(GPIO_TypeDef *GPIO_x, HAL_PinsTypeDef pin)
{
GPIO_x->OUTPUT_ ^= pin;
}
/**
* @brief Функция инициализации линии прерывания.
* \param mux настройка мультиплексора линии прерывания.
@ -222,39 +170,3 @@ HAL_StatusTypeDef HAL_GPIO_DeInitInterruptLine(HAL_GPIO_Line irqLine)
return HAL_OK;
}
/**
* @brief Получить состояние линии прерывания.
* @param irqLine номер линии прерывания.
* @return Возвращает 1 если сработало прерывание данной линии, иначе 0.
*/
uint32_t HAL_GPIO_LineInterruptState(HAL_GPIO_Line irqLine)
{
int irq_line_num = irqLine >> GPIO_IRQ_LINE_S;
return (GPIO_IRQ->INTERRUPT & (1 << (irq_line_num))) != 0;
}
/**
* @brief Функция чтения логического уровня вывода, подключенного к линии прерывания.
* @param irqLine номер линии прерывания.
* @return Логический уровень вывода.
*/
GPIO_PinState HAL_GPIO_LinePinState(HAL_GPIO_Line irqLine)
{
int irq_line_num = irqLine >> GPIO_IRQ_LINE_S;
return (GPIO_PinState)((GPIO_IRQ->STATE & (1 << (irq_line_num))) >> irq_line_num);
}
/**
* @brief Функция сброса регистра состояния прерываний.
* @note Когда срабатывает прерывание на одной из линии, в регистре INTERRUPT
* выставляется 1 в разряде, соответствующем линии прерывания.
* После обработки прерывания необходимо сбросить данный регистр
* в обработчике прерывания trap_handler().
* Если после обработки прерывания регистр не был сброшен,
* обработчик будет вызван снова, программа будет бесконечно вызывать обработчик.
*/
void HAL_GPIO_ClearInterrupts()
{
GPIO_IRQ->CLEAR = 0b11111111;
}

View File

@ -26,24 +26,6 @@ __attribute__((weak)) void HAL_I2C_MspInit(I2C_HandleTypeDef* hi2c)
}
void HAL_I2C_Disable(I2C_HandleTypeDef *hi2c)
{
hi2c->Instance->CR1 &= ~I2C_CR1_PE_M;
}
void HAL_I2C_Reset(I2C_HandleTypeDef *hi2c)
{
hi2c->ErrorCode = I2C_ERROR_NONE;
hi2c->Instance->CR1 &= ~I2C_CR1_PE_M;
hi2c->Instance->CR1 |= I2C_CR1_PE_M;
}
void HAL_I2C_Enable(I2C_HandleTypeDef *hi2c)
{
hi2c->Instance->CR1 |= I2C_CR1_PE_M;
}
void HAL_I2C_AnalogFilterInit(I2C_HandleTypeDef *hi2c, HAL_I2C_AnalogFilterTypeDef AnalogFilter)
{
hi2c->Init.AnalogFilter = AnalogFilter;
@ -244,6 +226,24 @@ HAL_StatusTypeDef HAL_I2C_Init(I2C_HandleTypeDef *hi2c)
return HAL_OK;
}
HAL_StatusTypeDef HAL_I2C_Deinit(I2C_HandleTypeDef *hi2c)
{
HAL_I2C_Disable(hi2c);
if (hi2c->Instance == I2C_0)
{
__HAL_PCC_I2C_0_CLK_DISABLE();
HAL_GPIO_PinConfig(GPIO_0, GPIO_PIN_9 | GPIO_PIN_10, HAL_GPIO_MODE_GPIO_INPUT, HAL_GPIO_PULL_NONE, HAL_GPIO_DS_2MA);
}
else if(hi2c->Instance == I2C_1)
{
__HAL_PCC_I2C_1_CLK_DISABLE();
HAL_GPIO_PinConfig(GPIO_1, GPIO_PIN_12 | GPIO_PIN_13, HAL_GPIO_MODE_GPIO_INPUT, HAL_GPIO_PULL_NONE, HAL_GPIO_DS_2MA);
}
return HAL_OK;
}
void HAL_I2C_AutoEnd(I2C_HandleTypeDef *hi2c, HAL_I2C_AutoEndModeTypeDef AutoEnd)
{
hi2c->Instance->CR2 &= ~I2C_CR2_AUTOEND_M;

View File

@ -282,6 +282,37 @@ HAL_StatusTypeDef HAL_SPI_Init(SPI_HandleTypeDef *hspi)
return error_code;
}
/**
* @brief Установить новый делитель частоты
*
* @param hspi указатель на структуру SPI_HandleTypeDef, которая содержит
* информацию о конфигурации для модуля SPI.
*/
void HAL_SPI_Set_Clock_Divider(SPI_HandleTypeDef *hspi)
{
uint32_t config = hspi->Instance->CONFIG;
HAL_SPI_Disable(hspi);
config &= ~(0b111 << SPI_CONFIG_BAUD_RATE_DIV_S); // очистить
config |= (hspi->Init.BaudRateDiv << SPI_CONFIG_BAUD_RATE_DIV_S); // установить новое
hspi->Instance->CONFIG = config; // сохранить конфигурацию
}
/**
* @brief Установить новый режим работы
*
* @param hspi указатель на структуру SPI_HandleTypeDef, которая содержит
* информацию о конфигурации для модуля SPI.
*/
void HAL_SPI_Set_Clock_Mode(SPI_HandleTypeDef *hspi)
{
uint32_t config = hspi->Instance->CONFIG;
HAL_SPI_Disable(hspi);
config &= ~((1 << SPI_CONFIG_CLK_PH_S) | (1 << SPI_CONFIG_CLK_POL_S)); // очистить
config |= ((hspi->Init.CLKPhase << SPI_CONFIG_CLK_PH_S) |
(hspi->Init.CLKPolarity << SPI_CONFIG_CLK_POL_S)); // установить новые значения
hspi->Instance->CONFIG = config; // сохранить конфигурацию
}
/**
* @brief Очистить буфер TX_FIFO.
*
@ -425,6 +456,7 @@ HAL_StatusTypeDef HAL_SPI_Exchange(SPI_HandleTypeDef *hspi, uint8_t TransmitByte
goto error;
}
}
return error_code;
error:
__HAL_SPI_DISABLE(hspi);
@ -544,6 +576,7 @@ HAL_StatusTypeDef HAL_SPI_ExchangeThreshold(SPI_HandleTypeDef *hspi, uint8_t Tra
tx_counter = 0;
}
}
return error_code;
error:
__HAL_SPI_DISABLE(hspi);

View File

@ -99,26 +99,6 @@ __attribute__((weak)) void HAL_TIMER16_MspInit(Timer16_HandleTypeDef* htimer16)
}
}
/**
* @brief Выключить таймер.
* Может использоваться для отключения таймера или при записи в регистр CFGR.
*
* @param htimer16 Указатель на структуру с настройками Timer16.
*/
void HAL_Timer16_Disable(Timer16_HandleTypeDef *htimer16)
{
htimer16->Instance->CR &= ~TIMER16_CR_ENABLE_M;
}
/**
* @brief Включить таймер
* @param htimer16 Указатель на структуру с настройками Timer16.
*/
void HAL_Timer16_Enable(Timer16_HandleTypeDef *htimer16)
{
htimer16->Instance->CR |= TIMER16_CR_ENABLE_M;
}
/**
* @brief Установить активный фронт для подсчёта или задать подрежим энкодера.
* Используется при тактировании Timer16 от внешнего источника тактового сигнала на выводе Input1.

View File

@ -78,6 +78,41 @@ HAL_StatusTypeDef HAL_Timer32_Init(TIMER32_HandleTypeDef *timer)
return HAL_OK;
}
HAL_StatusTypeDef HAL_Timer32_Deinit(TIMER32_HandleTypeDef *timer)
{
if ((timer->Instance != TIMER32_0) && (timer->Instance != TIMER32_1) && (timer->Instance != TIMER32_2))
{
return HAL_ERROR;
}
if (timer->Instance == TIMER32_0)
{
__HAL_PCC_TIMER32_0_CLK_DISABLE();
}
if (timer->Instance == TIMER32_1)
{
__HAL_PCC_TIMER32_1_CLK_DISABLE();
if (timer->Clock.Source == TIMER32_SOURCE_TX_PAD)
HAL_GPIO_PinConfig(GPIO_0, GPIO_PIN_4, HAL_GPIO_MODE_GPIO_INPUT, HAL_GPIO_PULL_NONE, HAL_GPIO_DS_2MA);
}
if (timer->Instance == TIMER32_2)
{
__HAL_PCC_TIMER32_2_CLK_DISABLE();
if (timer->Clock.Source == TIMER32_SOURCE_TX_PAD)
HAL_GPIO_PinConfig(GPIO_1, GPIO_PIN_4, HAL_GPIO_MODE_GPIO_INPUT, HAL_GPIO_PULL_NONE, HAL_GPIO_DS_2MA);
}
HAL_Timer32_InterruptMask_Clear(timer, 0xFFFFFFFF);
HAL_Timer32_Prescaler_Set(timer, 0);
HAL_Timer32_InterruptFlags_ClearMask(timer, 0xFFFFFFFF);
HAL_Timer32_InterruptFlags_Clear(timer);
return HAL_OK;
}
void HAL_Timer32_State_Set(TIMER32_HandleTypeDef *timer, HAL_TIMER32_StateTypeDef state)
{
timer->State = state;
@ -199,7 +234,7 @@ HAL_StatusTypeDef HAL_Timer32_Channel_Init(TIMER32_CHANNEL_HandleTypeDef *timerC
return HAL_ERROR;
}
HAL_TIMER32_Channel_MspInit(timerChannel);
// HAL_TIMER32_Channel_MspInit(timerChannel); // здесь инициализируются сразу все каналы выбранного таймера, а нам такого не надо
timerChannel->Instance = (TIMER32_CHANNEL_TypeDef *)&(timerChannel->TimerInstance->CHANNELS[timerChannel->ChannelIndex]);
@ -220,6 +255,8 @@ HAL_StatusTypeDef HAL_Timer32_Channel_DeInit(TIMER32_CHANNEL_HandleTypeDef *time
return HAL_ERROR;
}
timerChannel->Instance = (TIMER32_CHANNEL_TypeDef *)&(timerChannel->TimerInstance->CHANNELS[timerChannel->ChannelIndex]);
HAL_Timer32_Channel_Disable(timerChannel);
HAL_Timer32_Channel_CaptureEdge_Set(timerChannel, 0);
HAL_Timer32_Channel_ICR_Clear(timerChannel);

View File

@ -3,14 +3,56 @@
uint16_t TimeOut = 20;
uint16_t WDT_prescale[] = {1, 2, 4, 16, 64, 256, 1024, 4096};
/**
* @brief Запись слова в регистр CON (конфигурация WDT)
* @param hwdt указатель на структуру WDT_HandleTypeDef, которая содержит
* информацию о конфигурации для модуля WDT.
* @param conValue 32-х битное слово
*/
static void __attribute__( ( noinline, section(".ram_text") ) ) HAL_WDT_Write_Word_To_CON(WDT_HandleTypeDef* hwdt, uint32_t conValue)
{
//Если позволить компилятору inlining, станет невозможно выделить функцию в отдельную секцию.
intptr_t ptr = (intptr_t)(hwdt->Instance);
/**
* Попытки избежать использования отдельной переменной-указателя, такие как:
* "sb a0,0x9C(%a0)\n\t"
* : "m" (*(hwdt->Instance))
* не работают из-за бага GCC (internal compiler error <...> riscv_print_operand_address)
* */
asm volatile(
"li a0,0x1E\n\t" //Store unlock byte somewhere
"sb a0,0x9C(%0)\n\t" //Write UNLOCK byte into WDT KEY register
"sw %1,0x84(%0)\n\t" //Write payload
:
: "r" (ptr), "r" (conValue)
: "a0"
);
}
/**
* @brief Запись байта в регистр KEY (пуск/остановка WDT)
* @param hwdt указатель на структуру WDT_HandleTypeDef, которая содержит
* информацию о конфигурации для модуля WDT.
* @param key байт для записи ( @ref WDT_KEY_START или @ref WDT_KEY_STOP )
*/
static void __attribute__( ( noinline, section(".ram_text") ) ) HAL_WDT_Write_Byte_To_KEY(WDT_HandleTypeDef* hwdt, uint8_t key)
{
intptr_t ptr = (intptr_t)(hwdt->Instance);
asm volatile(
"li a0,0x1E\n\t" //Store unlock byte somewhere
"sb a0,0x9C(%0)\n\t" //Write UNLOCK byte into WDT KEY register
"sb %1,0x9C(%0)\n\t" //Write payload
:
: "r" (ptr), "r" (key)
: "a0"
);
}
/**
* @brief Инициализация WDT MSP.
* @param hwdt указатель на структуру WDT_HandleTypeDef, которая содержит
* информацию о конфигурации для модуля WDT.
*
* информацию о конфигурации для модуля WDT.
*/
__attribute__((weak)) void HAL_RTC_MspInit(WDT_HandleTypeDef *hwdt)
__attribute__((weak)) void HAL_WDT_MspInit(WDT_HandleTypeDef *hwdt)
{
__HAL_PCC_WDT_CLK_ENABLE();
}
@ -82,7 +124,7 @@ HAL_StatusTypeDef HAL_WDT_Init(WDT_HandleTypeDef *hwdt, uint32_t timeout)
return HAL_ERROR;
}
HAL_RTC_MspInit(hwdt);
HAL_WDT_MspInit(hwdt);
if (HAL_WDT_Stop(hwdt, timeout) != HAL_OK)
@ -100,8 +142,7 @@ HAL_StatusTypeDef HAL_WDT_Init(WDT_HandleTypeDef *hwdt, uint32_t timeout)
}
uint32_t conValue = (wdtClock.divIndex << WDT_CON_PRESCALE_S) | WDT_CON_PRELOAD(wdtClock.tick);
hwdt->Instance->KEY = WDT_KEY_UNLOCK;
hwdt->Instance->CON = conValue;
HAL_WDT_Write_Word_To_CON(hwdt, conValue);
return HAL_OK;
}
@ -115,8 +156,7 @@ HAL_StatusTypeDef HAL_WDT_Init(WDT_HandleTypeDef *hwdt, uint32_t timeout)
*/
HAL_StatusTypeDef HAL_WDT_Refresh(WDT_HandleTypeDef *hwdt, uint32_t timeout)
{
hwdt->Instance->KEY = WDT_KEY_UNLOCK;
hwdt->Instance->KEY = WDT_KEY_START;
HAL_WDT_Write_Byte_To_KEY(hwdt, WDT_KEY_START);
while (timeout--)
{
@ -139,8 +179,7 @@ HAL_StatusTypeDef HAL_WDT_Refresh(WDT_HandleTypeDef *hwdt, uint32_t timeout)
*/
HAL_StatusTypeDef HAL_WDT_Start(WDT_HandleTypeDef *hwdt, uint32_t timeout)
{
hwdt->Instance->KEY = WDT_KEY_UNLOCK;
hwdt->Instance->KEY = WDT_KEY_START;
HAL_WDT_Write_Byte_To_KEY(hwdt, WDT_KEY_START);
while (timeout--)
{
@ -162,8 +201,7 @@ HAL_StatusTypeDef HAL_WDT_Start(WDT_HandleTypeDef *hwdt, uint32_t timeout)
*/
HAL_StatusTypeDef HAL_WDT_Stop(WDT_HandleTypeDef *hwdt, uint32_t timeout)
{
hwdt->Instance->KEY = WDT_KEY_UNLOCK;
hwdt->Instance->KEY = WDT_KEY_STOP;
HAL_WDT_Write_Byte_To_KEY(hwdt, WDT_KEY_STOP);
while (timeout--)
{
@ -185,8 +223,7 @@ HAL_StatusTypeDef HAL_WDT_Stop(WDT_HandleTypeDef *hwdt, uint32_t timeout)
void HAL_WDT_SetPrescale(WDT_HandleTypeDef *hwdt, HAL_WDT_Prescale prescale)
{
uint32_t conValue = (hwdt->Instance->CON & (~WDT_CON_PRESCALE_M)) | ((prescale << WDT_CON_PRESCALE_S) & WDT_CON_PRESCALE_M);
hwdt->Instance->KEY = WDT_KEY_UNLOCK;
hwdt->Instance->CON = conValue;
HAL_WDT_Write_Word_To_CON(hwdt, conValue);
}
/**
@ -198,6 +235,5 @@ void HAL_WDT_SetPrescale(WDT_HandleTypeDef *hwdt, HAL_WDT_Prescale prescale)
void HAL_WDT_SetPreload(WDT_HandleTypeDef *hwdt, HAL_WDT_Prescale preload)
{
uint32_t conValue = (hwdt->Instance->CON & (~WDT_CON_PRELOAD_M)) | WDT_CON_PRELOAD(preload);
hwdt->Instance->KEY = WDT_KEY_UNLOCK;
hwdt->Instance->CON = conValue;
HAL_WDT_Write_Word_To_CON(hwdt, conValue);
}

View File

@ -10,36 +10,52 @@ MEMORY {
}
STACK_SIZE = 1024;
HEAP_SIZE = 1024;
CL_SIZE = 16;
SECTIONS {
.text ORIGIN(ram) : {
PROVIDE(__TEXT_START__ = .);
*crt0.o(.text .text.*)
*crt0.S.o(.text .text.*)
*(.text.smallsysteminit)
*(.text.SmallSystemInit)
. = ORIGIN(ram) + 0xC0;
KEEP(*crt0.o(.trap_text))
KEEP(*crt0.S.o(.trap_text))
*(.text)
*(.text.*)
*(.rodata)
*(.rodata.*)
. = ALIGN(CL_SIZE);
PROVIDE(__TEXT_END__ = .);
} >ram
.init_array (READONLY) :
{
PROVIDE_HIDDEN (__init_array_start = .);
KEEP (*(SORT_BY_INIT_PRIORITY(.init_array.*) SORT_BY_INIT_PRIORITY(.ctors.*)))
KEEP (*(.init_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .ctors))
PROVIDE_HIDDEN (__init_array_end = .);
PROVIDE_HIDDEN (__fini_array_start = .);
KEEP(*(SORT_BY_INIT_PRIORITY(.fini_array.*)))
KEEP(*(.fini_array))
PROVIDE_HIDDEN (__fini_array_end = .);
PROVIDE(__TEXT_END__ = .);
} >ram AT>ram
.data :
AT( __TEXT_END__ ) {
PROVIDE(__DATA_START__ = .);
_gp = .;
*(.srodata.cst16) *(.srodata.cst8) *(.srodata.cst4) *(.srodata.cst2) *(.srodata*)
*(.sdata .sdata.* .gnu.linkonce.s.*)
*(.sdata .sdata.* .sdata* .sdata*.* .gnu.linkonce.s.*)
*(.data .data.*)
*(.ramfunc)
. = ALIGN(CL_SIZE);
} >ram
} >ram
__DATA_IMAGE_START__ = LOADADDR(.data);
__DATA_IMAGE_END__ = LOADADDR(.data) + SIZEOF(.data);
ASSERT(__DATA_IMAGE_END__ < ORIGIN(ram) + LENGTH(ram) - STACK_SIZE, "Data image overflows ram section")
@ -72,12 +88,19 @@ SECTIONS {
PROVIDE(__BSS_END__ = .);
} >ram
.heap : {
PROVIDE(__heap_start = .);
. += HEAP_SIZE;
. = ALIGN(CL_SIZE);
PROVIDE(__heap_end = .);
} >ram
_end = .;
PROVIDE(__end = .);
/* End of uninitalized data segement */
.stack ORIGIN(ram) + LENGTH(ram) - STACK_SIZE : {
.stack ORIGIN(ram) + LENGTH(ram) - STACK_SIZE: {
FILL(0);
PROVIDE(__STACK_START__ = .);
. += STACK_SIZE;

View File

@ -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);
@ -50,15 +49,17 @@ SECTIONS {
AT( __TEXT_END__ ) {
PROVIDE(__DATA_START__ = .);
_gp = .;
. = ORIGIN(ram) + 0xC0;
KEEP(*crt0.S.o(.trap_text))
*(.srodata.cst16) *(.srodata.cst8) *(.srodata.cst4) *(.srodata.cst2) *(.srodata*)
*(.sdata .sdata.* .sdata* .sdata*.* .gnu.linkonce.s.*)
*(.data .data.*)
. = ALIGN(CL_SIZE);
PROVIDE(__DATA_END__ = .);
} >ram
__DATA_IMAGE_START__ = LOADADDR(.data);
__DATA_IMAGE_END__ = LOADADDR(.data) + SIZEOF(.data);
ASSERT(__DATA_IMAGE_END__ < ORIGIN(rom) + LENGTH(rom), "Data image overflows rom section")
/* thread-local data segment */
.tdata : {
@ -84,10 +85,26 @@ SECTIONS {
.bss : {
*(.bss .bss.*)
*(COMMON)
. = ALIGN(CL_SIZE);
PROVIDE(__BSS_END__ = .);
} >ram
/* Code intended to be copied to REGION_RAM before execution */
.ram_text :
AT( ALIGN(__DATA_IMAGE_END__, CL_SIZE) ) {
PROVIDE(__RAM_TEXT_START__ = .);
*(.ram_text)
. = ALIGN(CL_SIZE);
PROVIDE(__RAM_TEXT_END__ = .);
} > ram
__RAM_TEXT_IMAGE_START__ = LOADADDR(.ram_text);
__RAM_TEXT_IMAGE_END__ = LOADADDR(.ram_text) + SIZEOF(.ram_text);
ASSERT(__RAM_TEXT_IMAGE_END__ < ORIGIN(rom) + LENGTH(rom), "rom segment overflows")
ASSERT(__RAM_TEXT_END__ < ORIGIN(ram) + LENGTH(ram) - STACK_SIZE - HEAP_SIZE, "REGION_RAM section overflows")
.heap : {
PROVIDE(__heap_start = .);
. += HEAP_SIZE;
@ -105,6 +122,7 @@ SECTIONS {
PROVIDE(__STACK_START__ = .);
. += STACK_SIZE;
PROVIDE(__C_STACK_TOP__ = .);
PROVIDE(__freertos_irq_stack_top = .);
PROVIDE(__STACK_END__ = .);
} >ram

View File

@ -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)) ;

View File

@ -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);
/** Ожидает, пока модуль примет данные

View File

@ -62,6 +62,11 @@ memset_2:
_start:
li t0, 128000
start_loop_delay:
nop
addi t0, t0, -1
bnez t0, start_loop_delay
# Init stack and global pointer
#
la_abs sp, __C_STACK_TOP__
@ -73,20 +78,19 @@ _start:
la_abs a2, __DATA_IMAGE_END__
la_abs a3, __DATA_START__
memcpy a1, a2, a3, t0
# Init ramfunc
#
la_abs a1, __RAM_TEXT_IMAGE_START__
la_abs a2, __RAM_TEXT_IMAGE_END__
la_abs a3, __RAM_TEXT_START__
memcpy a1, a2, a3, t0
# Clear bss
#
la_abs a1, __BSS_START__
la_abs a2, __BSS_END__
memset a1, a2, zero
#ifdef MIK32V0
# Enable pad_config clocking
#
li t0, (1 << 3)
li t1, 0x50014
sw t0, (t1)
#endif
jalr_abs ra, SmallSystemInit
jalr_abs ra, SystemInit

File diff suppressed because it is too large Load Diff

View File

@ -1,33 +1,97 @@
#include "mik32_hal_irq.h"
#include "mik32_hal_irq.h"
#include "wiring_LL.h"
// isr functions
extern void serial_handler_wrapper(void);
extern void gpio_interrupts_handler(void);
extern void serial_interrupt_handler(uint8_t uartNumInt);
extern void gpio_interrupt_handler(void);
extern void tone_interrupt_handler(void);
void __attribute__((weak)) wire_handler_wrapper(void)
void __attribute__((weak)) wire_interrupt_handler(uint8_t num)
{
// dummy function for case when wire library is not in use
}
void __attribute__((weak)) servo_interrupt_handler(void)
{
// dummy function for case when servo library is not in use
}
void __attribute__((weak)) IRremote_interrupt_handler(void)
{
// dummy function for case when IRremote library is not in use
}
bool __attribute__((section(".ram_text"), weak)) ISR(void)
{
/*
A dummy function for the case when additional interrupts are not used in the project.
In the project, you need to create a function of the form:
extern "C" __attribute__((section(".ram_text"))) bool ISR(void)
{
if (EPIC_CHECK_TIMER16_1())
{
// timer16 is taken as an example
if (TIM16_GET_ARRM_INT_STATUS(htimer16_1_))
{
// necessary actions
}
// reset timer interrupt flags
TIM16_CLEAR_INT_MASK(htimer16_1_, 0xFFFFFFFF);
}
return false;
}
If you don't need to call standard trap_handler() code, you can return true from this function
and trap_handler() code will be missed. But you must carefully clear interrupt flags by yourself
in your custom ISR() function.
libraries required to use this example:
#include "mik32_hal_timer16.h"
#include "wiring_LL.h"
*/
return false;
}
// ---------------------------------------------- //
void trap_handler(void)
void __attribute__((noinline, section(".ram_text"), optimize("O3"))) trap_handler (void)
{
// custom interrupt
if(ISR())
{
// reset all interrupts and miss trap_handler() code
EPIC_CLEAR_ALL();
return;
}
// gpio interrupt
if (EPIC_CHECK_GPIO_IRQ())
gpio_interrupt_handler();
// IRremote timer interrupt
if (EPIC_CHECK_TIMER16_0())
IRremote_interrupt_handler();
// tone timer interrupt
if (EPIC_CHECK_TIMER16_1())
tone_interrupt_handler();
// uart interrupt
if (EPIC_CHECK_UART_0())
serial_handler_wrapper();
// servo timer interrupt
if (EPIC_CHECK_TIMER16_2())
servo_interrupt_handler();
// gpio interrupt
if (EPIC_CHECK_GPIO_IRQ())
gpio_interrupts_handler();
// i2c interrupt
// uart0 interrupt
if (EPIC_CHECK_UART_0())
serial_interrupt_handler(0);
// uart1 interrupt
if (EPIC_CHECK_UART_1())
serial_interrupt_handler(1);
// i2c0 interrupt
if (EPIC_CHECK_I2C_0())
wire_interrupt_handler(0);
// i2c1 interrupt
if (EPIC_CHECK_I2C_1())
wire_handler_wrapper();
wire_interrupt_handler(1);
// reset all interrupts
HAL_EPIC_Clear(0xFFFFFFFF);
EPIC_CLEAR_ALL();
}

View File

@ -0,0 +1,6 @@
#ifndef __DELAY_H_
#define __DELAY_H_
#endif // __DELAY_H_

67
cores/arduino/wiring_LL.h Normal file
View File

@ -0,0 +1,67 @@
#ifndef _WIRING_LL_H_
#define _WIRING_LL_H_
#include "mik32_hal_irq.h"
#include "mik32_hal_gpio.h"
#include "mik32_hal_scr1_timer.h"
#include "mik32_hal_timer16.h"
#include "pad_config.h"
// ----------------- COMMON ----------------- //
// convert pin mask from HAL_PinsTypeDef to pin number
#define PIN_MASK_TO_PIN_NUMBER(mask) \
({ \
uint8_t pos; \
for (pos = 0; pos < 16; pos++) \
if ((mask >> pos) & 1) \
break; \
pos; \
})
// ----------------- SYSTICK ----------------- //
// get ticks from systick
#define SYSTICK_GET_TICKS() ((uint64_t)(SCR1_TIMER->MTIMEH)<<32 | SCR1_TIMER->MTIME)
// ----------------- UART ----------------- //
#define UART_READ_BYTE(pUart) ((uint16_t)pUart->RXDATA)
#define UART_IS_RX_FIFO_EMPTY(pUart) ((pUart->FLAGS & UART_FLAGS_RXNE_M) == 0)
// ----------------- TIMER16 ----------------- //
#define TIM16_DISABLE(htim16) (htim16.Instance->CR &= ~TIMER16_CR_ENABLE_M)
#define TIM16_CLEAR_INT_MASK(htim16, intMask) (htim16.Instance->ICR = intMask)
#define TIM16_GET_ARRM_INT_STATUS(htim16) ((bool)((htim16.Instance->ISR & htim16.Instance->IER) & TIMER16_ISR_ARR_MATCH_M))
#define TIM16_DISABLE_INT_BY_MASK(htim16,intMask) (htim16.Instance->IER &= ~(intMask))
// ----------------- EPIC ----------------- //
#define EPIC_LEVEL_SET_BY_MASK(mask) (EPIC->MASK_LEVEL_SET |= mask)
#define EPIC_LEVEL_CLEAR_BY_MASK(mask) (EPIC->MASK_LEVEL_CLEAR |= mask)
#define EPIC_CLEAR_ALL() (EPIC->CLEAR = 0xFFFFFFFF)
// ----------------- IRQ ----------------- //
#define GLOBAL_IRQ_DISABLE() (clear_csr(mie, MIE_MEIE))
#define GLOBAL_IRQ_ENABLE() set_csr(mstatus, MSTATUS_MIE); \
set_csr(mie, MIE_MEIE)
// ----------------- GPIO ----------------- //
#define GPIO_INPUT_MODE_PIN(GPIO_x, pinMask) ((GPIO_x)->DIRECTION_IN = (pinMask))
#define GPIO_OUTPUT_MODE_PIN(GPIO_x, pinMask) ((GPIO_x)->DIRECTION_OUT = (pinMask))
#define GPIO_SET_PIN(GPIO_x, pinMask) ((GPIO_x)->SET = (pinMask))
#define GPIO_CLEAR_PIN(GPIO_x, pinMask) ((GPIO_x)->CLEAR = (pinMask))
#define GPIO_TOGGLE_PIN(GPIO_x, pinMask) ((GPIO_x)->OUTPUT_ ^= pinMask)
#define GPIO_READ_PIN(GPIO_x, pinMask) (((GPIO_x)->SET & (pinMask)) != (uint32_t)GPIO_PIN_LOW ? GPIO_PIN_HIGH : GPIO_PIN_LOW)
// get pin state by it's number
#define GPIO_GET_PIN_STATE(GPIO_x, pinNumber) (((GPIO_x)->OUTPUT_ >> pinNumber) & 0b1)
// ----------------- GPIO IRQ ----------------- //
#define GPIO_IRQ_LINE_ENABLE(lineMask) ( GPIO_IRQ->ENABLE_SET = (1 << (lineMask >> GPIO_IRQ_LINE_S)) )
#define GPIO_IRQ_LINE_DISABLE(lineMask) ( GPIO_IRQ->ENABLE_CLEAR = (1 << (lineMask >> GPIO_IRQ_LINE_S)) )
#define GPIO_IRQ_LINE_STATE(lineMask) ((GPIO_IRQ->INTERRUPT & (1 << (lineMask >> GPIO_IRQ_LINE_S))) != 0)
#define GPIO_IRQ_CLEAR_ALL() ( GPIO_IRQ->CLEAR = 0b11111111)
// ----------------- PIN CONFIG ----------------- //
// return config of pin with pinNumber(0...16) in portReg (config, pupd, ds for ports 0...2)
#define PIN_GET_PAD_CONFIG(portReg, pinNumber) ((PAD_CONFIG->portReg >> (pinNumber<<1)) & 0b11)
#define PIN_SET_PAD_CONFIG(portReg, pinNumber, value) (PAD_CONFIG->portReg = (PAD_CONFIG->portReg & (~PAD_CONFIG_PIN_M(pinNumber))) \
| PAD_CONFIG_PIN(pinNumber, value))
#endif /* _WIRING_LL_H_ */

View File

@ -8,9 +8,13 @@ extern "C" {
#include "mik32_hal_gpio.h"
#include "mik32_hal_timer32.h"
extern void ErrorMsgHandler(const char * msg);
// -------------------------- Analog read -------------------------- //
#define ADC_SAMPLES_QTY 10 // samples quantity for averaging adc results
#define ADC_DEFAULT_RESOLUTION 10 // resolution for arduino compatibility
uint8_t currentResolution = ADC_DEFAULT_RESOLUTION; // resolution used for output results
// structure for ADC channel initialization. Only the channel number
// changes, everything else is the same
static ADC_HandleTypeDef hadc =
@ -21,6 +25,16 @@ static ADC_HandleTypeDef hadc =
.Init.Sel = 0
};
void analogReadResolution(uint8_t resolution)
{
// resolution limits
if (resolution > 32) resolution = 32;
if (resolution < 1) resolution = 1;
// save new resolution
currentResolution = resolution;
}
// initialize the channel, run a single measurement, wait for the result
uint32_t analogRead(uint32_t PinNumber)
{
@ -28,27 +42,38 @@ uint32_t analogRead(uint32_t PinNumber)
uint32_t adcChannel = analogInputToChannelNumber(PinNumber);
if (adcChannel != NC)
{
// if we use pin A5, we need to set SELA45 (1.15) to 1 to switch the output from A4 to A5
if (PinNumber == A5)
{
HAL_GPIO_PinConfig(GPIO_1, GPIO_PIN_15, HAL_GPIO_MODE_GPIO_OUTPUT, HAL_GPIO_PULL_NONE, HAL_GPIO_DS_2MA);
HAL_GPIO_WritePin(GPIO_1, GPIO_PIN_15, GPIO_PIN_HIGH);
}
else if(PinNumber == A4)
{
// return the switch to A4 in case A5 was previously read
HAL_GPIO_PinConfig(GPIO_1, GPIO_PIN_15, HAL_GPIO_MODE_GPIO_OUTPUT, HAL_GPIO_PULL_NONE, HAL_GPIO_DS_2MA);
HAL_GPIO_WritePin(GPIO_1, GPIO_PIN_15, GPIO_PIN_LOW);
}
additionalPinsInit(PinNumber);
// init channel
hadc.Init.Sel = adcChannel;
HAL_ADC_Init(&hadc);
// start the conversion twice in case another channel was polled before
// start the dummy conversion in case another channel was polled before
HAL_ADC_SINGLE_AND_SET_CH(hadc.Instance, adcChannel);
value = HAL_ADC_WaitAndGetValue(&hadc);
HAL_ADC_Single(&hadc);
value = HAL_ADC_WaitAndGetValue(&hadc);
HAL_ADC_WaitAndGetValue(&hadc);
// accumulate results
uint32_t acc = 0;
for (uint8_t i = 0; i<ADC_SAMPLES_QTY; i++)
{
HAL_ADC_Single(&hadc);
acc += HAL_ADC_WaitAndGetValue(&hadc);
}
// get value by averaging with MCU_ADC_RESOLUTION
value = acc/ADC_SAMPLES_QTY;
// map value to selected resolution
if (currentResolution > MCU_ADC_RESOLUTION)
{
// extra least significant bits are padded with zeros
value = (value << (currentResolution - MCU_ADC_RESOLUTION));
}
else
{
// extra least significant bits read from the ADC are discarded
value = (value >> (MCU_ADC_RESOLUTION - currentResolution));
}
additionalPinsDeinit(PinNumber);
}
else
ErrorMsgHandler("analogRead(): invalid analog pin number");
@ -62,31 +87,13 @@ uint32_t analogRead(uint32_t PinNumber)
#define PWM_RESOLUTION_DEFAULT 8
#define WRITE_VAL_MAX_DEFAULT ((1<<PWM_RESOLUTION_DEFAULT) - 1)
#define PWM_TOP_VAL_DEFAULT 32000 // corresponds 1000 Hz
#define PWM_FREQUENCY_MAX 1000000 // Hz
static TIMER32_HandleTypeDef htimer32;
static TIMER32_CHANNEL_HandleTypeDef htimer32_channel;
static uint32_t WriteValMax = WRITE_VAL_MAX_DEFAULT;
static uint32_t pwmTopVal = PWM_TOP_VAL_DEFAULT;
static bool pwmIsInited = false;
static uint8_t pwmIsInited = 0;
HAL_StatusTypeDef Timer32_Channel_Init(TIMER32_CHANNEL_HandleTypeDef *timerChannel)
{
if (timerChannel->TimerInstance == TIMER32_0)
return HAL_ERROR;
// gpio init removed from standard function
timerChannel->Instance = (TIMER32_CHANNEL_TypeDef *)&(timerChannel->TimerInstance->CHANNELS[timerChannel->ChannelIndex]);
HAL_Timer32_Channel_PWM_Invert_Set(timerChannel, timerChannel->PWM_Invert);
HAL_Timer32_Channel_Mode_Set(timerChannel, timerChannel->Mode);
HAL_Timer32_Channel_CaptureEdge_Set(timerChannel, timerChannel->CaptureEdge);
HAL_Timer32_Channel_OCR_Set(timerChannel, timerChannel->OCR);
HAL_Timer32_Channel_ICR_Clear(timerChannel);
HAL_Timer32_Channel_Noise_Set(timerChannel, timerChannel->Noise);
return HAL_OK;
}
/*
It is recommended to enable the timer in the following order:
@ -97,43 +104,64 @@ 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)
{
if (writeVal > WriteValMax) writeVal = WriteValMax;
// initialization of the required timer
htimer32.Instance = pwmPinToTimer(PinNumber);
htimer32.Top = pwmTopVal;
htimer32.State = TIMER32_STATE_DISABLE;
htimer32.Clock.Source = TIMER32_SOURCE_PRESCALER;
htimer32.Clock.Prescaler = 0; // Prescaler = 1
htimer32.InterruptMask = 0;
htimer32.CountMode = TIMER32_COUNTMODE_FORWARD;
HAL_Timer32_Init(&htimer32);
// gpio init as timer channel pin
HAL_GPIO_PinConfig(digitalPinToPort(PinNumber), digitalPinToBitMask(PinNumber),
HAL_GPIO_MODE_TIMER_SERIAL, HAL_GPIO_PULL_NONE, HAL_GPIO_DS_2MA);
htimer32_channel.TimerInstance = htimer32.Instance;
htimer32_channel.ChannelIndex = pwmPinToTimerChannel(PinNumber);
htimer32_channel.PWM_Invert = TIMER32_CHANNEL_NON_INVERTED_PWM;
htimer32_channel.Mode = TIMER32_CHANNEL_MODE_PWM;
htimer32_channel.CaptureEdge = TIMER32_CHANNEL_CAPTUREEDGE_RISING;
// cast to uint64_t to avoid overflow when multiplying
htimer32_channel.OCR = (uint32_t) (((uint64_t)pwmTopVal * writeVal) / WriteValMax);
htimer32_channel.Noise = TIMER32_CHANNEL_FILTER_OFF;
Timer32_Channel_Init(&htimer32_channel);
// start timer with initialized channel
HAL_Timer32_Channel_Enable(&htimer32_channel);
HAL_Timer32_Value_Clear(&htimer32);
HAL_Timer32_Start(&htimer32);
pwmIsInited = true; // if at least one channel is working, say that the module is initialized
// if we need max value, use digitalWrite to supply constant level
digitalWrite(PinNumber, HIGH);
}
else if(PinNumber == 10) // pin d10 has pwm, but you cannot use it while spi is running
ErrorMsgHandler("analogWrite(): D10 cannot be used as PWM pin while SPI is running");
else
ErrorMsgHandler("analogWrite(): invalid pwm pin number");
{
// if we need less then max, use pwm
int8_t pwmState = digitalPinPwmIsOn(PinNumber);
if (pwmState > 0) // pin has pwm and pwm is already on
{
// 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 (pwmState == 0) // pin has pwm and pwm is off
{
// init pin as pwm
uint32_t OCRval = (pwmTopVal * writeVal) / WriteValMax;
// initialization of the required timer
htimer32.Instance = pwmPinToTimer(PinNumber);
htimer32.Top = pwmTopVal;
htimer32.State = TIMER32_STATE_DISABLE;
htimer32.Clock.Source = TIMER32_SOURCE_PRESCALER;
htimer32.Clock.Prescaler = 0; // Prescaler = 1
htimer32.InterruptMask = 0;
htimer32.CountMode = TIMER32_COUNTMODE_FORWARD;
HAL_Timer32_Init(&htimer32);
// gpio init as timer channel pin
HAL_GPIO_PinConfig(digitalPinToPort(PinNumber), digitalPinToBitMask(PinNumber),
HAL_GPIO_MODE_TIMER_SERIAL, HAL_GPIO_PULL_NONE, HAL_GPIO_DS_2MA);
htimer32_channel.TimerInstance = htimer32.Instance;
htimer32_channel.ChannelIndex = pwmPinToTimerChannel(PinNumber);
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 = OCRval;
htimer32_channel.Noise = TIMER32_CHANNEL_FILTER_OFF;
HAL_Timer32_Channel_Init(&htimer32_channel);
// start timer with initialized channel
HAL_Timer32_Channel_Enable(&htimer32_channel);
HAL_Timer32_Value_Clear(&htimer32);
HAL_Timer32_Start(&htimer32);
pwmIsInited++; // increase inited channels qty
}
else // pin doesn't have pwm
ErrorMsgHandler("analogWrite(): invalid pwm pin number");
}
}
// Set the resolution of analogWrite parameters
@ -163,23 +191,31 @@ 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 (pwmIsInited)
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);
// in the initChannel function they do it inside, but in deinit they don't. We do it outside
htimer32_channel.Instance = (TIMER32_CHANNEL_TypeDef *)&(htimer32_channel.TimerInstance->CHANNELS[htimer32_channel.ChannelIndex]);
// и все чистим/отключаем
HAL_Timer32_InterruptMask_Clear(&htimer32, 0xFFFFFFFF);
HAL_Timer32_Prescaler_Set(&htimer32, 0);
HAL_Timer32_InterruptFlags_ClearMask(&htimer32, 0xFFFFFFFF);
htimer32.Instance->CHANNELS[htimer32_channel.ChannelIndex].OCR = 0;
htimer32_channel.TimerInstance = htimer32.Instance;
// deinit channel
HAL_Timer32_Channel_DeInit(&htimer32_channel);
HAL_Timer32_Stop(&htimer32);
pwmIsInited = false;
pwmIsInited--; // decrease inited channels qty
// stop timer if no inited channels left
if (pwmIsInited == 0)
{
HAL_Timer32_Stop(&htimer32);
HAL_Timer32_Deinit(&htimer32);
}
// config pin as input when timer channel off
HAL_GPIO_PinConfig(digitalPinToPort(PinNumber), digitalPinToBitMask(PinNumber),
HAL_GPIO_MODE_GPIO_INPUT, HAL_GPIO_PULL_NONE, HAL_GPIO_DS_2MA);
}
}

View File

@ -16,6 +16,13 @@ extern "C" {
*/
uint32_t analogRead(uint32_t PinNumber);
/*
* \brief Set the resolution of adc results. Default is 10 bits (range from 0 to 1023).
*
* \param resolution 1...32
*/
void analogReadResolution(uint8_t resolution);
/*
* \brief Writes an analog value (PWM wave) to a pin.
*

View File

@ -21,13 +21,16 @@
#include <stdbool.h>
#include <stdint.h>
#include "wiring_private.h"
#define HIGH 0x1
#define LOW 0x0
#define INPUT 0x0
#define OUTPUT 0x1
#define INPUT_PULLUP 0x2
#define NC 0xFFFFFFFF // Not connected
#define HIGH 0x1
#define LOW 0x0
#define INPUT 0x0
#define OUTPUT 0x1
#define INPUT_PULLUP 0x2
#define INPUT_PULLDOWN 0x3
#define NC 0xFFFFFFFF // Not connected
#define PI 3.1415926535897932384626433832795
#define HALF_PI 1.5707963267948966192313216916398
@ -55,32 +58,31 @@ enum BitOrder
#define NOT_AN_INTERRUPT -1
// Math
#ifdef __cplusplus
#include <algorithm>
using std::min;
using std::max;
#else // C
#include <stdlib.h>
#ifndef abs
#define abs(x) ((x)>0?(x):-(x))
#endif // abs
#include <stdlib.h>
// 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)
#define sq(x) ((x)*(x))
// 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 highByte(w) ((uint8_t) ((w) >> 8))

View File

@ -19,13 +19,12 @@
#include "Arduino.h"
#include "pins_arduino.h"
#include "mik32_hal_gpio.h"
#include "wiring_LL.h"
#ifdef __cplusplus
extern "C" {
#endif
extern void ErrorMsgHandler(const char * msg);
// initialization
void pinMode(uint32_t PinNumber, uint32_t PinMode)
{
@ -38,67 +37,69 @@ void pinMode(uint32_t PinNumber, uint32_t PinMode)
return;
}
if (digitalPinHasPWM(PinNumber))
// if the pin can use PWM, disable PWM
if (digitalPinPwmIsOn(PinNumber) > 0 )
// if the pin use PWM, disable PWM
analogWriteStop(PinNumber);
// adjusting pins
if (PinNumber == BTN_BUILTIN)
// determine the port and the pin number in the port
GPIO_TypeDef *GPIO_addr = digitalPinToPort(PinNumber);
GPIO_InitStruct.Pin = digitalPinToBitMask(PinNumber);
// set up direction and pull up/down
switch (PinMode)
{
// always set the button to input, otherwise the controller may burn out when pressed
GPIO_InitStruct.Pin = GPIO_PIN_6;
GPIO_InitStruct.Mode = HAL_GPIO_MODE_GPIO_INPUT;
GPIO_InitStruct.Pull = HAL_GPIO_PULL_NONE;
HAL_GPIO_Init(GPIO_2, &GPIO_InitStruct);
case INPUT:
GPIO_InitStruct.Mode = HAL_GPIO_MODE_GPIO_INPUT;
GPIO_InitStruct.Pull = HAL_GPIO_PULL_NONE;
break;
case INPUT_PULLUP:
GPIO_InitStruct.Mode = HAL_GPIO_MODE_GPIO_INPUT;
GPIO_InitStruct.Pull = HAL_GPIO_PULL_UP;
break;
case INPUT_PULLDOWN:
GPIO_InitStruct.Mode = HAL_GPIO_MODE_GPIO_INPUT;
GPIO_InitStruct.Pull = HAL_GPIO_PULL_DOWN;
break;
case OUTPUT:
GPIO_InitStruct.Mode = HAL_GPIO_MODE_GPIO_OUTPUT;
GPIO_InitStruct.Pull = HAL_GPIO_PULL_NONE;
break;
}
else // other pins
// init pin
HAL_GPIO_Init(GPIO_addr, &GPIO_InitStruct);
additionalPinsInit(PinNumber);
}
void fastPinMode(uint32_t PinNumber, uint32_t PinMode)
{
if ((PinNumber>=pinCommonQty()))
{
// determine the port and the pin number in the port
GPIO_TypeDef *GPIO_addr = digitalPinToPort(PinNumber);
GPIO_InitStruct.Pin = digitalPinToBitMask(PinNumber);
// set up direction and pull up/down
switch (PinMode)
{
case INPUT:
GPIO_InitStruct.Mode = HAL_GPIO_MODE_GPIO_INPUT;
GPIO_InitStruct.Pull = HAL_GPIO_PULL_NONE;
break;
case INPUT_PULLUP:
GPIO_InitStruct.Mode = HAL_GPIO_MODE_GPIO_INPUT;
GPIO_InitStruct.Pull = HAL_GPIO_PULL_UP;
break;
case OUTPUT:
GPIO_InitStruct.Mode = HAL_GPIO_MODE_GPIO_OUTPUT;
GPIO_InitStruct.Pull = HAL_GPIO_PULL_NONE;
break;
}
// init pin
HAL_GPIO_Init(GPIO_addr, &GPIO_InitStruct);
// if we use pin A5, we need to set SELA45 (1.15) to 1 to switch the output from A4 to A5
if (PinNumber == A5)
{
GPIO_InitStruct.Pin = GPIO_PIN_15;
GPIO_InitStruct.Mode = HAL_GPIO_MODE_GPIO_OUTPUT;
GPIO_InitStruct.Pull = HAL_GPIO_PULL_NONE;
HAL_GPIO_Init(GPIO_1, &GPIO_InitStruct);
HAL_GPIO_WritePin(GPIO_1, GPIO_PIN_15, GPIO_PIN_HIGH);
}
else if(PinNumber == A4)
{
GPIO_InitStruct.Pin = GPIO_PIN_15;
GPIO_InitStruct.Mode = HAL_GPIO_MODE_GPIO_OUTPUT;
GPIO_InitStruct.Pull = HAL_GPIO_PULL_NONE;
HAL_GPIO_Init(GPIO_1, &GPIO_InitStruct);
HAL_GPIO_WritePin(GPIO_1, GPIO_PIN_15, GPIO_PIN_LOW);
}
ErrorMsgHandler("fastPinMode(): pin number exceeds the total number of pins");
return;
}
GPIO_TypeDef* port = digitalPinToPort(PinNumber);
HAL_PinsTypeDef pinMask = digitalPinToBitMask(PinNumber);
// set direction
if (PinMode == OUTPUT)
GPIO_OUTPUT_MODE_PIN(port, pinMask);
else
GPIO_INPUT_MODE_PIN(port, pinMask);
// set pullup
if (PinMode == INPUT_PULLUP)
{
uint8_t pos = PIN_MASK_TO_PIN_NUMBER(pinMask);
if (port == GPIO_0) PIN_SET_PAD_CONFIG(PORT_0_PUPD, pos, HAL_GPIO_PULL_UP);
else if (port == GPIO_1) PIN_SET_PAD_CONFIG(PORT_1_PUPD, pos, HAL_GPIO_PULL_UP);
else PIN_SET_PAD_CONFIG(PORT_2_PUPD, pos, HAL_GPIO_PULL_UP);
}
}
// write pin
void digitalWrite(uint32_t PinNumber, uint32_t Val)
__attribute__((noinline, section(".ram_text"))) void digitalWrite(uint32_t PinNumber, uint32_t Val)
{
if ((PinNumber>=pinCommonQty()))
{
@ -106,48 +107,59 @@ void digitalWrite(uint32_t PinNumber, uint32_t Val)
return;
}
if (digitalPinHasPWM(PinNumber))
// if the pin can use PWM, disable PWM
GPIO_TypeDef* port = digitalPinToPort(PinNumber);
HAL_PinsTypeDef mask = digitalPinToBitMask(PinNumber);
if (digitalPinPwmIsOn(PinNumber) > 0)
{
// if the pin use PWM, disable PWM
analogWriteStop(PinNumber);
// just in case let's move on to the hal library state terms
GPIO_PinState pinState = (Val == HIGH) ? GPIO_PIN_HIGH : GPIO_PIN_LOW;
if (PinNumber != BTN_BUILTIN) // don't write anything to the button
HAL_GPIO_WritePin(digitalPinToPort(PinNumber), digitalPinToBitMask(PinNumber), pinState);
// and configure pin as output
HAL_GPIO_PinConfig(port, mask, HAL_GPIO_MODE_GPIO_OUTPUT, HAL_GPIO_PULL_NONE, HAL_GPIO_DS_2MA);
}
if (Val == HIGH)
GPIO_SET_PIN(port, mask);
else
GPIO_CLEAR_PIN(port, mask);
}
// read pin
int digitalRead(uint32_t PinNumber)
__attribute__((noinline, section(".ram_text"))) int digitalRead(uint32_t PinNumber)
{
if ((PinNumber>=pinCommonQty()))
{
ErrorMsgHandler("digitalRead(): pin number exceeds the total number of pins");
return -1;
}
if (digitalPinHasPWM(PinNumber))
// if the pin can use PWM, disable PWM
analogWriteStop(PinNumber);
GPIO_PinState pinState = HAL_GPIO_ReadPin(digitalPinToPort(PinNumber), digitalPinToBitMask(PinNumber));
int state = (pinState == GPIO_PIN_LOW) ? LOW : HIGH;
return state;
if (digitalPinPwmIsOn(PinNumber) > 0)
// if the pin use PWM, disable PWM
analogWriteStop(PinNumber); // pin is configured as input here
return GPIO_READ_PIN(digitalPinToPort(PinNumber), digitalPinToBitMask(PinNumber));
}
// toggle pin
void digitalToggle(uint32_t PinNumber)
__attribute__((noinline, section(".ram_text"))) void digitalToggle(uint32_t PinNumber)
{
if ((PinNumber>=pinCommonQty()))
{
ErrorMsgHandler("digitalToggle(): pin number exceeds the total number of pins");
return;
}
if (digitalPinHasPWM(PinNumber))
// if the pin can use PWM, disable PWM
GPIO_TypeDef* port = digitalPinToPort(PinNumber);
HAL_PinsTypeDef mask = digitalPinToBitMask(PinNumber);
if (digitalPinPwmIsOn(PinNumber) > 0)
{
// if the pin use PWM, disable PWM
analogWriteStop(PinNumber);
if (PinNumber != BTN_BUILTIN) // don't write anything to the button
HAL_GPIO_TogglePin(digitalPinToPort(PinNumber), digitalPinToBitMask(PinNumber));
// and configure pin as output
HAL_GPIO_PinConfig(port, mask, HAL_GPIO_MODE_GPIO_OUTPUT, HAL_GPIO_PULL_NONE, HAL_GPIO_DS_2MA);
}
GPIO_TOGGLE_PIN(port, mask);
}
#ifdef __cplusplus

View File

@ -26,26 +26,35 @@ extern "C" {
/**
* \brief Configures the specified pin to behave either as an input or an output.
*
* \param dwPin The number of the pin whose mode you wish to set
* \param dwMode Either INPUT, INPUT_PULLUP or OUTPUT
* \param PinNumber The number of the pin whose mode you wish to set
* \param PinMode Either INPUT, INPUT_PULLUP or OUTPUT
*/
void pinMode(uint32_t PinNumber, uint32_t PinMode);
/**
* \brief Configures the specified pin to behave either as an input or an output
* using quick macros and without calling checks
*
* \param PinNumber The number of the pin whose mode you wish to set
* \param PinMode Either INPUT, INPUT_PULLUP or OUTPUT
*/
void fastPinMode(uint32_t PinNumber, uint32_t PinMode);
/**
* \brief Write a HIGH or a LOW value to a digital pin.
*
* If the pin has been configured as an OUTPUT with pinMode(), its voltage will be set to the
* corresponding value: 3.3V for HIGH, 0V (ground) for LOW.
*
* \param dwPin the pin number
* \param dwVal HIGH or LOW
* \param PinNumber the pin number
* \param PinMode HIGH or LOW
*/
void digitalWrite(uint32_t PinNumber, uint32_t Val);
/**
* \brief Reads the value from a specified digital pin, either HIGH or LOW.
*
* \param ulPin The number of the digital pin you want to read (int)
* \param PinNumber The number of the digital pin you want to read (int)
*
* \return HIGH or LOW
*/
@ -54,7 +63,7 @@ int digitalRead(uint32_t PinNumber);
/**
* \brief Toggle the value from a specified digital pin.
*
* \param ulPin The number of the digital pin you want to toggle (int)
* \param PinNumber The number of the digital pin you want to toggle (int)
*/
void digitalToggle(uint32_t PinNumber);

View File

@ -10,6 +10,8 @@
extern "C"{
#endif
// available interrupts number
#define EXTERNAL_NUM_INTERRUPTS EXTERNAL_INTERRUPTS_QTY
typedef void (*voidFuncPtr)(void);

View File

@ -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);

View File

@ -39,6 +39,11 @@ void SysTick_Init(void)
HAL_SCR1_Timer_Init(&hscr1_timer); // Ticks are 32 MHz
}
uint64_t SysTick_GetTicks(void)
{
return TICKS_IN_SYSTIMER;
}
// number of microseconds since start of the program
uint32_t micros(void)
{

View File

@ -24,12 +24,22 @@
extern "C" {
#endif
#define clockCyclesPerMicrosecond() (F_CPU / 1000000L)
#define clockCyclesToMicroseconds(a) ((a) / clockCyclesPerMicrosecond())
#define microsecondsToClockCycles(a) ((a) * clockCyclesPerMicrosecond())
/**
* \brief Initialize timer for creating delays
*
*/
void SysTick_Init(void);
/**
* \brief Returns the number of ticks since the Arduino board began running the current program.
* \return Number of ticks since the program started
*/
uint64_t SysTick_GetTicks(void);
/**
* \brief Returns the number of milliseconds since the Arduino board began running the current program.

BIN
docs/Add_board.PNG Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB

BIN
docs/Blink_example.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 51 KiB

BIN
docs/Bootloader_.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 48 KiB

BIN
docs/Build_project_.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.6 KiB

View File

@ -0,0 +1,68 @@
# ELBEAR ACE-UNO
Особенности работы с платами ELBEAR ACE-UNO в среде программирования ArduinoIDE.
### Функциональное назначение выводов
![Pinout](pinout_uno.png)
### Цифровые выводы
На плате ELBEAR ACE-UNO доступны встроенные светодиод и кнопка. Для их использования необходимо воспользоваться макросами `LED_BUILTIN` и `BTN_BUILTIN`, передавая их в качестве аргументов функции вместо номера цифрового вывода. Макросу `LED_BUILTIN` соответствует номер вывода D22, а макросу `BTN_BUILTIN` - D23.
### Аналоговые выводы
Аналоговые выводы на плате могут использоваться как в аналоговом, так и в цифровом режиме.
Для использования вывода в качестве аналогового необходимо перевести соответствующий DIP-переключатель, расположенный рядом с аналоговыми выводами, в положение OFF. В этом режиме внешнее напряжение, подаваемое на вывод, будет понижаться резистивным делителем перед подачей на микроконтроллер.
Для использования вывода в качестве цифрового нужно перевести переключатель в положение ON. В этом случае напряжение с вывода платы передается на микроконтроллер без изменений. Вывод А5 недоступен для использования в качестве цифрового вывода.
Для аналоговых выводов режим цифрового вывода с подтяжкой к питанию(`INPUT_PULLUP`) не дает желаемого результата, так как на этих сигналах установлена неотключаемая подтяжка к земеле (10 кОм), а подтяжка к питанию внутри микроконтроллера осуществляется резистором 50 кОм. Для реализации такого режима на аналоговых выводах необходимо использовать внешний дополнительный резистор 1...2 кОм, подключенный к питанию.
Таблица соответствия выводов платы и номера DIP-переключателя представлена ниже. Переключатель 5 относится сразу к двум аналоговым выводам - А4, А5.
|Вывод|Номер переключателя|
|---------|---------|
|А0|1|
|А1|2|
|А2|3|
|А3|4|
|А4|5|
|А5|5|
#### ШИМ
На плате ELBEAR ACE-UNO доступно 8 выводов для формирования ШИМ-сигнала. Генерация сигнала осуществляется с помощью 32-битного таймера. Выводы, подключенные к одному и тому же таймеру, выдают ШИМ-сигнал одинаковой частоты.
Доступные выводы:
|Цифровой вывод|Используемый таймер|
|---------|---------|
|D3|таймер 1|
|D5|таймер 1|
|D6|таймер 1|
|D9|таймер 1|
|D10|таймер 2|
|D11|таймер 2|
|D12|таймер 2|
|D13|таймер 2|
Цифровые выводы D9, D10 не могут быть использованы для генерации ШИМ, если одновременно активен интерфейс SPI (при использовании экземпляра `SPI` недоступен ШИМ на выводе D10, при использовании экземпляра `SPI0` - на выводе D9). Это ограничение связано с особенностями работы микроконтроллера. Ограничение не распространяется на использование D9, D10 в качестве цифрового вывода при активном SPI.
### Прерывания
На плате ELBEAR ACE-UNO доступно 8 прерываний, настраиваемых функцией `void attachInterrupt(uint8_t interruptNum, void (*userFunc)(void), int mode)`:
|Цифровой вывод|Номер прерывания|
|---------|---------|
|D2|0|
|D3|1|
|D4|2|
|D5|3|
|D8|4|
|D9|5|
|A1|6|
|`BTN_BUILTIN`|7|
При использовании аналогового вывода A1 для работы с прерываниями необходимо предварительно перевести вывод в режим цифрового. Для этого нужно перевести DIP-переключатель номер 2 в положение ON.
### Serial
Интерфейс UART0 доступен на выводах D0, D1, для работы с ним используется экземпляр класса под названием `Serial`.
Интерфейс UART1 доступен на выводах D7, D8, используемый экземпляр класса - `Serial1`.
### SPI
Интерфейс SPI1 доступен на выводах D11, D12, D13. Для работы с ним используется экземпляр класса под названием `SPI`.
Интерфейс SPI0 доступен на выводах D3, D5, D6. Используемый экземпляр класса - `SPI0`.
### I2C
Интерфейс I2C1 доступен на выводах SDA и SCL, для работы с ним используется экземпляр класса под названием `Wire`.
## Драйверы
Для работы с платой по интерфейсу USB необходим драйвер для микросхемы CH340С, его можно скачать [здесь](https://www.wch-ic.com/downloads/CH341SER_ZIP.html). Были замечены ошибки при работе драйвера версии 2024 года, поэтому рекомендуется устанавливать драйвер более старой версии (например, 2019 года).
Подготовка к работе по интерфейсу JTAG и инструкция по записи начального загрузчика есть [здесь](Instructions.md).

BIN
docs/Flash_project_.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

BIN
docs/Flash_project_jtag.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 40 KiB

BIN
docs/Install_board_.PNG Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 46 KiB

57
docs/Instructions.md Normal file
View File

@ -0,0 +1,57 @@
# Установка пакета и предварительная подготовка к работе
## Установка пакета в ArduinoIDE
1. Установите [Arduino IDE](https://www.arduino.cc/en/software).
2. Откройте меню `Файл -> Параметры`.
3. Вставьте данную ссылку в поле "Дополнительные ссылки для Менеджера плат":
`https://elron.tech/files/package_elbear_beta_index.json`
![Add_board](Add_board.PNG)
4. Откройте меню `Инструменты -> Плата -> Менеджер плат...`.
5. В поиске найдите пакет `MIK32 Boards (Arduino BSP by Elron)`, выберите нужную версию пакета и нажмите кнопку `Установить`.
![Install_board](Install_board_.PNG)
6. Процесс установки может занять некоторое время. Результаты установки отобразятся в поле `Вывод`, а так же во всплывающих уведомлениях.
![Installation_process](Installation_process_.PNG)
## Запись начального загрузчика через ArduinoIDE
Для загрузки скетчей по USB в ArduinoIDE необходимо, чтобы на плате был специальный начальный загрузчик ([elbear_fw_bootloader](https://gitflic.ru/project/elron-tech/elbear_fw_bootloader) для плат ELBEAR). Если он уже есть на плате, можно сразу переходить к работе. Если загрузчика еще нет или необходимо обновить его на плате, ниже описан процесс загрузки. Актуальная версия начального загрузчика входит в состав пакета поддержки для всех плат, отдельно скачивать его не нужно.
Платы ELBEAR ACE-UNO ревизии 1.1.0, ELBEAR ACE-NANO, ELSOMIK готовы к использованию в ArduinoIDE из коробки, так как поставляются с предварительно записанным начальным загрузчиком.
Для записи начального загрузчика:
1. Подключите плату к ПК по интерфейсу JTAG.
Для подключения плат ELBEAR, ELSOMIK потребуется программатор [ELJTAG](https://elron.tech/eljtag-programmator-risc-v-mcu/).
Для подключения платы START-MIK32 необходимо на плате перевести переключатель режима программатора (COM/JTAG) в положение JTAG и подключить плату к ПК через USB разъем.
2. В ArduinoIDE выберите программатор: `Инструменты -> Программатор -> mik32 uploader`.
![programmer](programmer.png)
3. Для записи начального загрузчика выберите `Инструменты -> Записать Загрузчик`.
![Bootloader](Bootloader_.png)
4. При возникновении проблем с загрузкой ознакомьтесь с разделом `Настройка программатора` в [инструкции](https://elron.tech/wp-content/uploads/2025/07/instrukcija_po_pervomu_zapusku_140725.pdf) по первому запуску платы ELBEAR ACE-UNO или с [документацией](https://docs.mikron.ru/wiki/boards/start.html) по запуску платы START-MIK32 (ссылки на документацию по плате START-MIK32 актуальны на июль 2025 года, если они не действительны, возможно найти актуальную информацию на сайте производителя - https://mikron.ru/).
Теперь можно загружать скетчи в плату по USB.
## Начало работы
1. Подключите плату к ПК по USB.
2. Откройте ArduinoIDE и загрузите необходимый скетч. Для начала работы можно воспользоваться готовыми примерами, например - `Файл -> Примеры -> 01.Basics -> Blink`.
![Blink_example](Blink_example.png)
3. Выберите активную плату - `Инструменты -> Плата`.
![Set_board](Set_board_.png)
4. Выберите используемый COM порт - `Инструменты -> Порт`.
![Set_port](Set_port_.png)
Выбранные плата и порт в ArduinoIDE должны отображаться следующим образом:
![Selected_board_port](Selected_board_port_.png)
5. Проверьте скетч, нажав соответствующую кнопку.
![Build_project](Build_project_.png)
6. Загрузите полученную прошивку на плату.
![Flash_project](Flash_project_.png)
7. При необходимости можно открыть терминал и получать сообщения от платы по интерфейсу Serial. Для этого добавьте в скетч работу с интерфейсом и после загрузки прошивки выберите `Инструменты -> Монитор порта`.
![Monitor](Monitor_.png)
## Загрузка скетчей через программатор
ArduinoIDE позволяет так же загружать скетчи через программатор. Для этого:
1. Подключите плату к ПК по интерфейсу JTAG.
Для подключения плат ELBEAR, ELSOMIK потребуется программатор [ELJTAG](https://elron.tech/eljtag-programmator-risc-v-mcu/).
Для подключения платы START-MIK32 необходимо на плате перевести переключатель режима программатора (COM/JTAG) в положение JTAG и подключить плату к ПК через USB разъем.
2. Откройте ArduinoIDE и загрузите необходимый скетч. Для начала работы можно воспользоваться готовыми примерами, например - `Файл -> Примеры -> 01.Basics -> Blink`.
3. Выберите активную плату - `Инструменты -> Плата`.
4. Выберите программатор - `Инструменты -> Программатор -> mik32 uploader`.
5. Проверьте скетч, нажав соответствующую кнопку.
6. Для загрузки скетча через программатор выберите - `Скетч -> Загрузить на плату при помощи программатора`.
![Flash_project_jtag](Flash_project_jtag.png)

BIN
docs/Monitor_.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 46 KiB

BIN
docs/Registers.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 102 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

BIN
docs/Set_board_.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 87 KiB

BIN
docs/Set_port_.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 49 KiB

BIN
docs/Start_V1_pinout.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 MiB

View File

@ -0,0 +1,71 @@
# START-MIK32
Особенности работы с платой START-MIK32 в среде программирования ArduinoIDE.
### Функциональное назначение выводов
![Start_V1_pinout.png](Start_V1_pinout.png)
### Загрузка скетчей
Для загрузки скетчей в ArduinoIDE необходимо передвинуть переключатель режима программатора на плате в положение `COM`. Так же необходимо установить две перемычки на разъем 5 - первой перемычкой замкнуть выводы `COM_RX` и `MCU_TX`, а второй - выводы `COM_TX` и `MCU_RX`.
Для работы с платой по интерфейсу USB не требуется установка дополнительных драйверов.
Подготовка к работе по интерфейсу JTAG и инструкция по записи начального загрузчика есть [здесь](Instructions.md).
### Цифровые выводы
Выводы на плате START-MIK32 пронумерованы в соответствии с их принадлежностью к определенному GPIO-порту и конкретному пину внутри порта. Чтобы использовать цифровой вывод, необходимо передать в функцию номер порта и номер пина в формате `P0_1`, где "0" — это номер порта, а "1" — номер пина внутри порта. Например, для инициализации вывода 5 порта 2 на выход необходимо вызвать функцию `pinMode(P2_5, OUTPUT)`.
Для использования доступны следующие выводы: `P0_0 ... P0_15, P1_0 ... P1_15, P2_0 ... P2_7`.
На плате есть встроенные светодиоды и кнопка. Светодиоды подключены к выводам P0_3, P1_3. Кнопка подключена к выводу Р0_8. Для удобства при работе с ними можно воспользоваться макросами `LED_BUILTIN`(P0_3), `LED_BUILTIN1`(P1_3) и `BTN_BUILTIN`, передавая их в качестве аргументов функции вместо номера цифрового вывода.
### АЦП
На плате доступно 8 выводов, которые можно использовать в качестве каналов АЦП. Для работы с ними в функцию `analogRead()` необходимо передать номер канала или номер соответствующего цифрового вывода. Доступные каналы и их соответствие номерам выводов платы:
|Цифровой вывод|Номер канала АЦП|
|---------|---------|
|P1_5|A0|
|P1_7|A1|
|P0_2|A2|
|P0_4|A3|
|P0_7|A4|
|P0_9|A5|
|P0_11|A6|
|P0_13|A7|
#### ШИМ
На плате START-MIK32 в ArduinoIDE доступно 8 выводов для формирования ШИМ-сигнала. Генерация сигнала осуществляется с помощью 32-битного таймера. Выводы, подключенные к одному и тому же таймеру, выдают ШИМ-сигнал одинаковой частоты.
Доступные выводы:
|Цифровой вывод|Используемый таймер|
|---------|---------|
|P0_0|таймер 1|
|P0_1|таймер 1|
|P0_2|таймер 1|
|P0_3|таймер 1|
|P1_0|таймер 2|
|P1_1|таймер 2|
|P1_2|таймер 2|
|P1_3|таймер 2|
При использовании SPI формирование ШИМ сигнала на выводах P1_0 ... P1_3 недоступно.
### Прерывания
На плате START-MIK32 доступно 8 прерываний, настраиваемых функцией `void attachInterrupt(uint8_t interruptNum, void (*userFunc)(void), int mode)`:
|Цифровой вывод|Номер прерывания|
|---------|---------|
|`BTN_BUILTIN` (P0_8)|0|
|P1_9|1|
|P0_10|2|
|P1_15|3|
|P0_12|4|
|P0_13|5|
|P0_14|6|
|P0_15|7|
### 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 доступен на выводах 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 доступен на выводах SDA, SCL и P1_12, P1_13, для работы с ним используется экземпляр класса под названием `Wire`.
Интерфейс I2C0 доступен на выводах P0_9, P0_10, используемый экземпляр класса - `Wire0`.

BIN
docs/_pinout_ElsomikOEM.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 326 KiB

BIN
docs/debug_console.PNG Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 120 KiB

47
docs/debug_description.md Normal file
View File

@ -0,0 +1,47 @@
! **Внимание** Данная инструкция проверена и работает с версией Arduino IDE версии 2.3.4 на Windows 10 x64. На других версиях Arduino IDE работоспособность неизвестна. Функция отладки является экспериментальной.
# Режим отладки в ArduinoIDE 2
Начиная с версии пакета 0.5.0 для всех плат, входящих в состав пакета, доступен режим отладки скетчей.
Для отладки плат ELBEAR ACE-UNO, ELBEAR ACE-NANO, ELSOMIK понадобится программатор [ELJTAG](https://elron.tech/eljtag-programmator-risc-v-mcu/). Плата START-MIK32 содержит встроенный программатор, для использования которого необходимо передвинуть переключатель режима программатора на плате в положение `JTAG`.
Режим отладки доступен в ArduinoIDE версии 2 и выше.
# Предварительная подготовка
Для отладки в Arduino IDE используется плагин Cortex-Debug. По умолчанию в IDE установлена версия 1.5.1, но с указанной версией режим отладки для плат из состава пакета работает некорректно. Для корректной работы необходимо использовать более новую версию плагина.
Для подготовки к работе в режиме отладки необходимо сделать следующее:
* Установить драйвера для работы с программатором, если ранее они не были установлены. Подробности можно найти в [инструкции](https://elron.tech/wp-content/uploads/2025/07/instrukcija_po_pervomu_zapusku_140725.pdf) по первому запуску платы ELBEAR ACE-UNO или в [документации](https://docs.mikron.ru/wiki/boards/start.html) по запуску платы START-MIK32.
* Скачать архив, содержащий небходимую версию Cortex-Debug и все его зависимости, по [ссылке](https://elron.tech/files/mik32_arduinoIDE_debug_plagins.zip).
* Содержимое архива переместить в папку `plugins` из папки с установленной ArduinoIDE. Примерный путь - `C:\Program Files\Arduino IDE\resources\app\plugins`. Содержимое архива (несколько файлов с расширением `.vsix`) разместить в указанной папке, не создавая промежуточных папок.
* Запустить ArduinoIDE и по инструкции, описанной ниже, запустить режим отладки.
* Удостовериться, что при запуске отладки в первой строке консоли отладки отображается нужная версия плагина - 1.12.1:
`Cortex-Debug: VSCode debugger extension version 1.12.1 git(652d042). Usage info: https://github.com/Marus/cortex-debug#usage`
* При возникновении сложностей с вопросами можно обратиться в [телеграмм-канал компании](https://t.me/elrontech).
После установки новой версии плагина в строке меню и в области вывода информации появятся две новые вкладки - `MEMORY` и `xRTOS`. Это плагины, которые необходимы для работы Cortex-Debug. Они не используются непосредственно пользователем при работе, но удалять их нельзя, иначе режим отладки с установленной версией Cortex-Debug не запустится.
# Запуск отладки
Последовательность действий для запуска режима отладки:
1. В ArduinoIDE открыть скетч, который необходимо запустить в режиме отладки.
2. Выбрать нужную плату - `Инструменты -> Плата`.
3. Подключить плату к ПК через программатор. Для плат ELBEAR ACE-UNO, ELBEAR ACE-NANO, ELSOMIK использовать ELJTAG. На плате START-MIK32 передвинуть переключатель режима программатора в положение `JTAG`.
4. В ArduinoIDE выбрать используемый программатор - `Инструменты -> Программатор -> mik32 uploader`.
5. Активировать оптимизацию для отладки при сборке скетча - `Скетч -> Оптимизировать для отладки`. Если отладку запустить без указанной оптимизации, при пошаговом прохождении скетча могут возникнуть проблемы, например, с "перепрыгиванием" лишних строк кода, или значения некоторых переменных могут отображаться некорректно.
6. Скомпилировать скетч - `Скетч -> Проверить/Скомпилировать`.
7. Загрузить скетч на плату. Загружать скетч можно как по USB (`Скетч -> Загрузить на плату`), так и через программатор (`Скетч -> Загрузить на плату при помощи программатора`).
! При запуске отладки скетч не компилируется и не загружается на плату автоматически. Поэтому при внесении изменений в код необходимо вручную повторять пункты 6,7 перед запуском отладки.
8. Открыть панель отладочника в меню слева:
![Debug_panel.PNG](debug_panel.PNG)
После запуска отладки здесь будут доступны к просмотру стек вызовов функций, значения переменных, установленные точки останова, а также состояние периферийных регистров микроконтроллера.
9. Для запуска отладки необходимо нажать кнопку `Начать отладку` в верхней части экрана:
![Debug_start.PNG](debug_start.PNG)
При этом:
- Откроется новый терминал `gdb-server`, в котором запустится программа openocd. Терминал отображает статус соединения с микроконтроллером.
- Запустится режим отладки, а курсор выполнения программы остановится в начале функции `setup()`.
- Станут активными кнопки пошагового перемещения по программе.
- Во всех разделах на панели отладки обновится информация.
10. Для просмотра отладочной информации можно запустить консоль отладки. Для этого на панели отладки нужно нажать соответствующую кнопку:
![Debug_console.PNG](debug_console.PNG)
В [официальной статье](https://docs.arduino.cc/software/ide-v2/tutorials/ide-v2-debugger/) подробно описано, как работать с точками останова и пошаговой отладкой кода. Помимо этого, режим отладки позволяет получить доступ к системным регистрам и регистрам периферии микроконтроллера.
![Registers.PNG](Registers.png)
При работе с платами, входящими в состав пакета, накладывается ограничение на доступное количество точек останова - одновременно можно использовать не более 2-х точек. При этом вторая точка останова становится доступной после запуска отладки, когда курсор выполнения программы остановится на функции `setup()`. Режим отладки не запустится, если в скетче уже установлены обе точки останова.

BIN
docs/debug_panel.PNG Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 57 KiB

BIN
docs/debug_start.PNG Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 43 KiB

View File

@ -0,0 +1,79 @@
# ELSOMIK
Особенности работы с платой ELSOMIK в среде программирования ArduinoIDE.
### Функциональное назначение выводов платы ELSOMIK OEM
![pinout_Elsomik_OEM.png](_pinout_ElsomikOEM.png)
### Функциональное назначение выводов платы ELSOMIK SE
![pinout_Elsomik_SE.png](pinout_ElsomikSE.png)
### Загрузка скетчей
На плате отсутствуют встроенные преобразователи, позволяющие загружать скетчи по USB через COM-порт, однако каждая плата поставляется с предварительно записанным начальным загрузчиком. Для записи скетчей через USB потребуется использование внешнего USB-UART преобразователя, подключаемого к выводам платы P0_5 (RX0) и P0_6 (TX0), которые соответствуют интерфейсу UART0. Для корректной работы так же может потребоваться установка на ПК драйвера для микросхемы, используемой в преобразователе USB-UART.
Перед загрузкой скетча необходимо кратковременно ввести контроллер в состояние RESET. Если используется USB-UART преобразователь с выведенным сигналом DTR, необходимо соединить DTR с выводом RST на плате через керамический конденсатор емкостью от 0,47 мкФ до 2,2 мкФ. В случае отсутствия сигнала DTR, необходимо вручную соединить вывод RST платы с землей и отпустить его непосредственно перед началом записи скетча.
Для записи начального загрузчика или загрузки скетчей с помощью программатора необходимо подключить программатор (например, [ELJTAG](https://elron.tech/eljtag-programmator-risc-v-mcu/)) к выводам TDO, TDI, TCK, TMS, TRST, GND, 3V3, RST. Инструкцию по использованию программатора в Arduino IDE можно найти [здесь](Instructions.md).
### Цифровые выводы
Выводы на плате ELSOMIK пронумерованы в соответствии с их принадлежностью к определенному GPIO-порту и конкретному пину внутри порта. Чтобы использовать цифровой вывод, необходимо передать в функцию номер порта и номер пина в формате `P0_1`, где "0" — это номер порта, а "1" — номер пина внутри порта. Например, для инициализации вывода 5 порта 1 на выход необходимо вызвать функцию `pinMode(P1_5, OUTPUT)`.
Для использования доступны следующие выводы: `P0_0 ... P0_15, P1_0 ... P1_15, P2_6, P2_7`. Выводы `P0_11 ... P0_15` на плате обозначены иначе, ниже представлена таблица соответствия:
|Обозначение на плате|Номер вывода|
|---------|---------|
|TDI|P0_11|
|TCK|P0_12|
|TMS|P0_13|
|TRST|P0_14|
|TDO|P0_15|
### АЦП
На плате доступно 8 выводов, которые можно использовать в качестве каналов АЦП. Для работы с ними в функцию `analogRead()` необходимо передать номер канала или номер соответствующего цифрового вывода. Доступные каналы и их соответствие номерам выводов платы:
|Цифровой вывод|Номер канала АЦП|
|---------|---------|
|P1_5|A0|
|P1_7|A1|
|P0_2|A2|
|P0_4|A3|
|P0_7|A4|
|P0_9|A5|
|P0_11|A6|
|P0_13|A7|
#### ШИМ
На плате ELSOMIK в ArduinoIDE доступно 8 выводов для формирования ШИМ-сигнала. Генерация сигнала осуществляется с помощью 32-битного таймера. Выводы, подключенные к одному и тому же таймеру, выдают ШИМ-сигнал одинаковой частоты.
Доступные выводы:
|Цифровой вывод|Используемый таймер|
|---------|---------|
|P0_0|таймер 1|
|P0_1|таймер 1|
|P0_2|таймер 1|
|P0_3|таймер 1|
|P1_0|таймер 2|
|P1_1|таймер 2|
|P1_2|таймер 2|
|P1_3|таймер 2|
При использовании SPI формирование ШИМ сигнала на выводах P1_0 ... P1_3 недоступно.
### Прерывания
На плате ELSOMIK доступно 8 прерываний, настраиваемых функцией `void attachInterrupt(uint8_t interruptNum, void (*userFunc)(void), int mode)`:
|Цифровой вывод|Номер прерывания|
|---------|---------|
|P0_8|0|
|P1_4|1|
|P1_5|2|
|P1_6|3|
|P1_9|4|
|P1_10|5|
|P1_15|6|
|P2_7|7|
### Serial
Интерфейс UART0 доступен на выводах P0_5, P0_6, для работы с ним используется экземпляр класса под названием `Serial`.
Интерфейс UART1 доступен на выводах P1_8, P1_9, используемый экземпляр класса - `Serial1`.
### SPI
Интерфейс SPI1 доступен на выводах 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, используемый экземпляр класса - `Wire0`.

Binary file not shown.

After

Width:  |  Height:  |  Size: 53 KiB

71
docs/nano_description.md Normal file
View File

@ -0,0 +1,71 @@
# ELBEAR ACE-NANO
Особенности работы с платами ELBEAR ACE-NANO в среде программирования ArduinoIDE.
### Функциональное назначение выводов
![nano_pinout](nano_pinout.PNG)
### Цифровые выводы
На плате ELBEAR ACE-NANO доступен встроенный светодиод. Для его использования необходимо воспользоваться макросом `LED_BUILTIN`, передавая его в качестве аргумента функции вместо номера цифрового вывода. Макросу соответствует номер вывода D22.
### Аналоговые выводы
Аналоговые выводы на плате могут использоваться как в аналоговом, так и в цифровом режиме.
Для использования вывода в качестве аналогового необходимо перевести соответствующий DIP-переключатель, расположенный рядом с аналоговыми выводами, в положение OFF. В этом режиме внешнее напряжение, подаваемое на вывод, будет понижаться резистивным делителем перед подачей на микроконтроллер.
Для использования вывода в качестве цифрового нужно перевести переключатель в положение ON. В этом случае напряжение с вывода платы передается на микроконтроллер без изменений. Выводы А5, А6, А7 недоступны для использования в качестве цифровых выводов.
Выводы А4...А7 используют один и тот же канал АЦП, поэтому не могут использоваться одновременно.
Для аналоговых выводов режим цифрового вывода с подтяжкой к питанию(`INPUT_PULLUP`) не дает желаемого результата, так как на этих сигналах установлена неотключаемая подтяжка к земеле (10 кОм), а подтяжка к питанию внутри микроконтроллера осуществляется резистором 50 кОм. Для реализации такого режима на аналоговых выводах необходимо использовать внешний дополнительный резистор 1...2 кОм, подключенный к питанию.
Таблица соответствия выводов платы и номера DIP-переключателя представлена ниже. Переключатель 5 относится сразу к четырем аналоговым выводам - А4...А7.
|Вывод|Номер переключателя|
|---------|---------|
|А0|1|
|А1|2|
|А2|3|
|А3|4|
|А4|5|
|А5|5|
|А6|5|
|А7|5|
#### ШИМ
На плате ELBEAR ACE-NANO доступно 8 выводов для формирования ШИМ-сигнала. Генерация сигнала осуществляется с помощью 32-битного таймера. Выводы, подключенные к одному и тому же таймеру, выдают ШИМ-сигнал одинаковой частоты.
Доступные выводы:
|Цифровой вывод|Используемый таймер|
|---------|---------|
|D3|таймер 1|
|D5|таймер 1|
|D6|таймер 1|
|D9|таймер 1|
|D10|таймер 2|
|D11|таймер 2|
|D12|таймер 2|
|D13|таймер 2|
Цифровые выводы D9, D10 не могут быть использованы для генерации ШИМ, если одновременно активен интерфейс SPI (при использовании экземпляра `SPI` недоступен ШИМ на выводе D10, при использовании экземпляра `SPI0` - на выводе D9). Это ограничение связано с особенностями работы микроконтроллера. Ограничение не распространяется на использование D9, D10 в качестве цифрового вывода при активном SPI.
### Прерывания
На плате ELBEAR ACE-NANO доступно 8 прерываний, настраиваемых функцией `void attachInterrupt(uint8_t interruptNum, void (*userFunc)(void), int mode)`:
|Цифровой вывод|Номер прерывания|
|---------|---------|
|D2|0|
|D3|1|
|D4|2|
|D5|3|
|D6|4|
|D8|5|
|D9|6|
|A1|7|
При использовании аналогового вывода A1 для работы с прерываниями необходимо предварительно перевести вывод в режим цифрового. Для этого нужно перевести DIP-переключатель номер 2 в положение ON.
### Serial
Интерфейс UART0 доступен на выводах D0, D1, для работы с ним используется экземпляр класса под названием `Serial`.
Интерфейс UART1 доступен на выводах D7, D8, используемый экземпляр класса - `Serial1`.
### SPI
Интерфейс SPI1 доступен на выводах D11, D12, D13. Для работы с ним используется экземпляр класса под названием `SPI`.
Интерфейс SPI0 доступен на выводах D3, D5, D6. Используемый экземпляр класса - `SPI0`.
### I2C
Интерфейс I2C1 доступен на выводах A4 и A5, для работы с ним используется экземпляр класса под названием `Wire`.
## Драйверы
Для работы с платой по интерфейсу USB необходим драйвер для микросхемы CH343P, его можно скачать [здесь](https://www.wch-ic.com/downloads/CH343SER_ZIP.html).
Подготовка к работе по интерфейсу JTAG и инструкция по записи начального загрузчика есть [здесь](Instructions.md).

BIN
docs/nano_pinout.PNG Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 300 KiB

BIN
docs/pinout_ElsomikSE.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 468 KiB

BIN
docs/pinout_uno.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 293 KiB

BIN
docs/programmer.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 37 KiB

32
docs/tested_libs.md Normal file
View File

@ -0,0 +1,32 @@
# Протестированные библиотеки
|Библиотека|Описание|
|---------|---------|
|[RFID_MFRC522v2](https://docs.arduino.cc/libraries/rfid_mfrc522v2/)|Новая версия библиотеки MFRC522 для работы с RFID картами|
|[SD](https://www.arduino.cc/en/Reference/SD)|Библиотека, позволяющая считывать и записывать информацию на SD карты|
|[TimeLib](https://docs.arduino.cc/libraries/time/)|Библиотека для удобной работы с переменными времени|
|[Ds1302](https://reference.arduino.cc/reference/en/libraries/ds1302/)|Библиотека для работы с микросхемой часов реального времени DS1302|
|[DS1307RTC](https://docs.arduino.cc/libraries/ds1307rtc/)|Библиотека для работы с микросхемой часов реального времени DS1307|
|[microDS3231](https://docs.arduino.cc/libraries/microds3231/)|Легкая библиотека для работы с микросхемой часов реального времени DS3231|
|[Rtc](https://github.com/Makuna/Rtc/tree/master)|Библиотека для работы с разными микросхемами часов реального времени|
|[AHT10](https://github.com/enjoyneering/AHT10/tree/master)|Библиотека для работы с датчиками температуры и влажности AHT10, AHT15, AHT20|
|[DHT](https://docs.arduino.cc/libraries/dht-sensor-library/)|Библиотека для работы с датчиками температуры и влажности типа DHT|
|[Adafruit_BMP280](https://docs.arduino.cc/libraries/adafruit-bmp280-library/)|Библиотека для работы с датчиками давления и высоты BMP280|
|[MPU6050](https://reference.arduino.cc/reference/en/libraries/mpu6050/)|Библиотека для работы с акселерометром/гироскопом MPU6050|
|[Kalman](https://docs.arduino.cc/libraries/kalman-filter-library/)|Библиотека, реализующая фильтр Калмана|
|[LiquidCrystal_I2C](https://docs.arduino.cc/libraries/liquidcrystal-i2c/)|Библиотека для управления LCD дисплеями по интерфейсу I2C|
|[JoystickShield](https://github.com/sudar/JoystickShield/tree/master)|Библиотека для работы с шилдом JoystickShield|
|[RF24](https://docs.arduino.cc/libraries/rf24/)|Драйвер радиоустройств, библиотека для работы с микросхемами nRF24L01(+)|
|[Bonezegei_ULN2003_Stepper](https://docs.arduino.cc/libraries/bonezegei_uln2003_stepper/)|Библиотека драйвера шагового двигателя, управляемого микросхемой ULN2003|
|[Ethernet](https://docs.arduino.cc/libraries/ethernet/)|Библиотека, позволяющая использовать Ethernet шилд для подключения к Интернету|
|[AGS10_sensor](https://github.com/gina-seth/AGS10_sensor)|Библиотека для работы с датчиком газа AGS10|
|[TinyGPSPlus](https://docs.arduino.cc/libraries/tinygpsplus/)|Библиотека позволяет расшифровать данные GPS, сформированные по протоколу NMEA|
|[GPRS_Shield_Arduino](https://github.com/amperka/gprs-shield)|Библиотека для Arduino, позволяющая управлять GPRS Shieldом от Амперки|
|[Adafruit GFX](https://docs.arduino.cc/libraries/adafruit-gfx-library/)|Базовая графическая библиотека, от которой происходят все остальные графические библиотеки Adafruit|
|[Adafruit_SH110X](https://docs.arduino.cc/libraries/adafruit-sh110x/)|Библиотека драйверов SH110X OLED для монохромных дисплеев с драйверами SH1107 или SH1106G|
|[Adafruit_SSD1306](https://docs.arduino.cc/libraries/adafruit-ssd1306/)|Библиотека драйвера SSD1306 OLED для монохромных дисплеев с расширениями 128x64 и 128x32|
|[Adafruit_ST7789](https://docs.arduino.cc/libraries/adafruit-st7735-and-st7789-library/)|Библиотека для работы с дисплеем ST7789 по SPI|
|[Adafruit_ILI9341](https://docs.arduino.cc/libraries/adafruit-ili9341/)|Библиотека для работы с дисплеем Adafruit ILI9341|
|[TFT](https://docs.arduino.cc/libraries/tft/)|Графическая библиотека, совместимая с большинством TFT-дисплеев на базе чипа ST7735|
|[Adafruit_TCS34725](https://docs.arduino.cc/libraries/adafruit-tcs34725/)|Библиотека для работы с датчиком цвета с ИК-фильтром TCS34725|
|[DS18B20](https://docs.arduino.cc/libraries/ds18b20/)|Библиотека для работы с однопроводным датчиком температуры DS18B20|
|[CAN](https://docs.arduino.cc/libraries/can/)|Библиотека для передачи данных по шине CAN. Поддерживает модули на базе чипа MCP2515|

61
docs/tested_shields.md Normal file
View File

@ -0,0 +1,61 @@
## Модули, работающие без аппаратной модификации
|Модуль|Описание|Протестировано на|Ссылки на модуль|Материалы|
|---------|---------|------|---------|------|
|Датчик температуры DS18B20|Цифровой датчик|ELBEAR ACE-UNO,ELBEAR ACE-NANO, START-MIK32-V1|[Ozon](https://ozon.ru/t/dhmEm2y), [AliExpress](https://sl.aliexpress.ru/p?key=SMB63oS)|[Telegram](https://t.me/hutor_yanin/2612), [Gitflic](https://gitflic.ru/project/elron-tech/elbear_arduino_bsp/file?file=libraries%2FOneWire%2Fexamples%2FDS18x20_Temperature)|
|CAN-модуль MCP2515|CAN контроллер с SPI интерфейсом, модуль на базе MCP2515|ELBEAR ACE-UNO,ELBEAR ACE-NANO|[Ozon](https://ozon.ru/t/dhmEemf), [AliExpress](https://sl.aliexpress.ru/p?key=yeGH3aC)|[Telegram](https://t.me/hutor_yanin/2588), [Gitflic](https://gitflic.ru/project/ogneyar/arduino/file?file=ElbearAceUno%2FSPI_MCP2515_CAN)|
|Модуль лазерного дальномера VL53L0X|Подключение по I2C|ELBEAR ACE-UNO,ELBEAR ACE-NANO, START-MIK32-V1|[Ozon](https://ozon.ru/t/CKX9Vtg), [AliExpress](https://sl.aliexpress.ru/p?key=3yE73Ax)|[Telegram](https://t.me/hutor_yanin/2560), [Gitflic](https://gitflic.ru/project/ogneyar/arduino/file?file=ElbearAceUno%2FI2C_VL53L0X_test)|
|Модуль датчика температуры, давления BMP280|Цифровой датчик|ELBEAR ACE-UNO,ELBEAR ACE-NANO, START-MIK32-V1|[Ozon](https://ozon.ru/t/Q1zc8bJ), [AliExpress](https://sl.aliexpress.ru/p?key=N5WW3jN)|[Telegram](https://t.me/hutor_yanin/2536), [Gitflic](https://gitflic.ru/project/ogneyar/arduino/file?file=ElbearAceUno%2FI2C_BMP280_terminal)|
|Инфракрасный датчик движения (PIR)|Цифровой датчик. Протестированны разновидности: AM312, SR501, SR602 и SR505|ELBEAR ACE-NANO|[Ozon](https://ozon.ru/t/97BptDy), [AliExpress](https://sl.aliexpress.ru/p?key=oxyG3lk)|[Telegram](https://t.me/hutor_yanin/2417), [Gitflic](https://gitflic.ru/project/ogneyar/arduino/file?file=ElbearAceUno%2FReedSwitch_test)|
|Цифро-аналоговый преобразователь MCP4725 12 бит|Модуль MCP4725 представляет собой прецизионный 12-битный цифро-аналоговый преобразователь (ЦАП), подключение по I2C|ELBEAR ACE-UNO, START-MIK32-V1|[Ozon](https://ozon.ru/t/CK7qTXd), [AliExpress](https://sl.aliexpress.ru/p?key=ZW6s3Te)|[Telegram](https://t.me/hutor_yanin/1456), [Gitflic](https://gitflic.ru/project/ogneyar/arduino/file?file=ElbearAceUno%2FI2C_MCP4725_DAC_test)|
|Датчик температуры и влажности AHT10|Цифровой датчик, подключение по I2C|ELBEAR ACE-UNO, START-MIK32-V1|[Ozon](https://ozon.ru/t/amuSvQx), [AliExpress](https://sl.aliexpress.ru/p?key=TuCs33F)|[Telegram](https://t.me/hutor_yanin/1519?single), [Gitflic](https://gitflic.ru/project/ogneyar/arduino/file?file=ElbearAceUno%2FI2C_AHT10_terminal)|
|Датчик движения HW-MS03|Цифровой датчик|ELBEAR ACE-UNO, START-MIK32-V1|[Ozon](https://ozon.ru/t/RdiARs9), [AliExpress](https://sl.aliexpress.ru/p?key=G1bw3LH)|[Telegram](https://t.me/hutor_yanin/2376), [Gitflic](https://gitflic.ru/project/ogneyar/arduino/file?file=ElbearAceUno%2FHW_MS03_test&branch=master)|
|Bluetooth HC-05 (HC-06)|Bluetooth версия 2.0, подключение через UART|Elbear ACE-UNO|[Ozon](https://www.ozon.ru/product/modul-bluetooth-hc-05-arduino-971282989), [AliExpress](https://sl.aliexpress.ru/p?key=1mn8GcF)|[Telegram](https://t.me/hutor_yanin/2309), [Gitflic](https://gitflic.ru/project/ogneyar/arduino/file?file=ElbearAceUno%2FHC-05_demo&branch=master)|
|Радиомодуль CC1101 433 МГц|Модуль работает как приёмо-передатчик, подключение через SPI|ELBEAR ACE-UNO, START-MIK32-V1|[Ozon](https://www.ozon.ru/product/radiomodul-priemoperedatchik-na-cc1101-s-sma-antennoy-433-mgts-do-380-m-1565278116), [AliExpress](https://sl.aliexpress.ru/p?key=2mtQG9C)|[Telegram](https://t.me/hutor_yanin/2329), [Gitflic](https://gitflic.ru/project/ogneyar/arduino/file?file=ElbearAceUno%2FCC1101&branch=master)|
|Радиомодуль nrf24L01 2.4 ГГц|Беспроводной приемопередатчик, подключение через SPI|Elbear ACE-UNO|[Ozon](https://www.ozon.ru/product/radiomodul-nrf24l01-2-4-ggts-1420337483), [AliExpress](https://sl.aliexpress.ru/p?key=Pt0RGXV)|[Telegram](https://t.me/hutor_yanin/1643), [Gitflic](https://gitflic.ru/project/ogneyar/arduino/file?file=ElbearAceUno%2FSPI_nRF24L01_Transmitter&branch=master)|
|Дисплей 10-контактный 7-сегментный 3-значный|Без драйвера|Elbear ACE-UNO|[AliExpress](https://sl.aliexpress.ru/p?key=CXuRGJw)|[Telegram](https://t.me/hutor_yanin/2157), [Gitflic](https://gitflic.ru/project/ogneyar/arduino/file?file=ElbearAceUno%2FRenesasDriver_demo)|
|Цветной дисплей 170x320 1.9|Дисплей 1.9 дюйма с драйвером ST7789, подключение через SPI|Elbear ACE-UNO|[Ozon](https://www.ozon.ru/product/tsvetnoy-displey-1-9-tft-lcd-170x320-st7789-spi-interfeys-1781570948), [AliExpress](https://sl.aliexpress.ru/p?key=YHuRGO8)|[Telegram](https://t.me/hutor_yanin/2121), [Gitflic](https://gitflic.ru/project/ogneyar/arduino/file?file=ElbearAceUno%2FSPI_ST7789_170_320)|
|Дисплей E-link 2.13 от Heltec|Электронная бумага сохраняет изображение после отключения питания, подключение через SPI|ELBEAR ACE-UNO, START-MIK32-V1| [AliExpress](https://sl.aliexpress.ru/p?key=XOuRGfZ)|[Telegram](https://t.me/hutor_yanin/2047), [YouTube](https://youtu.be/Gz6e2d85w1s), [VK Видео](https://vkvideo.ru/video119909267_456239207), [Дзен](https://dzen.ru/video/watch/679e25b2a722f84498194c84), [RuTube](https://rutube.ru/video/3d85842b7a54fc8e5a721c4b96392ade), [Gitflic](https://gitflic.ru/project/ogneyar/arduino/file?file=ElbearAceUno%2FHeltec_Elink&branch=master)|
|IPS дисплей 80x160 0.9|Дисплей 0.9 дюйма с драйвером ST7735, подключение через SPI|Elbear ACE-UNO|[Ozon](https://www.ozon.ru/product/tsvetnoy-ips-tft-displey-na-st7735s-spi-80h160-0-96-933036270), [AliExpress](https://sl.aliexpress.ru/p?key=NjmRGBe)|[Telegram](https://t.me/hutor_yanin/2009), [Gitflic](https://gitflic.ru/project/ogneyar/arduino/file?file=ElbearAceUno%2FSPI_ST7735_80_160)|
|Цветной дисплей 320x240 3.2|Дисплей 3.2 дюйма с драйвером ILI9341, подключение через SPI|Elbear ACE-UNO|[Ozon](https://www.ozon.ru/product/tsvetnoy-sensornyy-displey-3-2-tft-lcd-320x240-ili9341-spi-interfeys-1347211506), [AliExpress](https://sl.aliexpress.ru/p?key=xc0RG4f)|[Telegram](https://t.me/hutor_yanin/1654), [Gitflic](https://gitflic.ru/project/ogneyar/arduino/file?file=ElbearAceUno%2FSPI_ILI9341_graphicstest&branch=master)|
|Цветной дисплей 240x280 1.69|Дисплей 1.69 дюйма с драйвером ST7789, подключение через SPI|Elbear ACE-UNO|[Ozon](https://www.ozon.ru/product/1-69-dyuymovyy-tft-displey-zhk-ekran-tsvetnoy-modul-240x280-st7789-v3-1376717173), [AliExpress](https://sl.aliexpress.ru/p?key=mH0RGWu)|[Telegram](https://t.me/hutor_yanin/1696), [Gitflic](https://gitflic.ru/project/ogneyar/arduino/file?file=ElbearAceUno%2FSPI_ST7789_240_280&branch=master)|
|Дисплей GMD12864-06D 128х64|Дисплей с драйвером ST7565, подключение через SPI|Elbear ACE-UNO|[Ozon](https://www.ozon.ru/product/zhk-displey-gmd12864-06d-128h64-pikseley-razmer-62h46h6-8mm-chernyy-s-belymi-simvolami-1840705753), [AliExpress](https://sl.aliexpress.ru/p?key=gcQRGT7)|[Telegram](https://t.me/hutor_yanin/1736) [Gitflic](https://gitflic.ru/project/ogneyar/arduino/file?file=ElbearAceUno%2FSPI_ST7565_HelloWorld&branch=master)|
|Дисплей GM12864-01A 128x64|Дисплей с драйвером ST7567, подключение через SPI|Elbear ACE-UNO|[AliExpress](https://sl.aliexpress.ru/p?key=rpmRGn7)|[Telegram](https://t.me/hutor_yanin/1960), [Gitflic](https://gitflic.ru/project/ogneyar/arduino/file?file=ElbearAceUno%2FSPI_ST7567_HelloAmur)|[Telegram](https://t.me/hutor_yanin/1736), [Gitflic](https://gitflic.ru/project/ogneyar/arduino/file?file=ElbearAceUno%2FSPI_ST7565_HelloWorld&branch=master)|
|OLED дисплей 0.96|Дисплей с драйвером SSD1306, подключение через I2C|Elbear ACE-UNO|[Ozon](https://www.ozon.ru/product/0-96-dyuymovyy-oled-modul-128x64-ssd1306-drayver-iic-i2c-posledovatelnyy-4-kontaktnyy-belyy-1783177523), [AliExpress](https://sl.aliexpress.ru/p?key=6EkRGk6)|[Telegram](https://t.me/hutor_yanin/1804), [Gitflic](https://gitflic.ru/project/ogneyar/arduino/file?file=ElbearAceUno%2FI2C_SSD1306_test&branch=master)|
|OLED дисплей 1.3|Дисплей с драйвером SH1106, подключение через I2C|Elbear ACE-UNO|[Ozon](https://www.ozon.ru/product/displey-oled-1-3-128-64-4kont-belye-simvoly-iic-i2c-1697780504), [AliExpress](https://sl.aliexpress.ru/p?key=5fkRGId)|[Telegram](https://t.me/hutor_yanin/1798), [Gitflic](https://gitflic.ru/project/ogneyar/arduino/file?file=ElbearAceUno%2FI2C_SH1106_128x64&branch=master)|
|LoRa модуль E32-170T30D|Модуль беспроводной передачи данных 433 МГц, подключение через USART|ELBEAR ACE-UNO, START-MIK32-V1|[AliExpress](https://sl.aliexpress.ru/p?key=ZyduGAA)|[Telegram](https://t.me/hutor_yanin/2347), [Gitflic](https://gitflic.ru/project/ogneyar/arduino/file?file=ElbearAceUno%2FLoRa_E32)|
|LoRa модуль SX1278|Модуль беспроводной передачи данных 433 МГц, подключение через SPI|Elbear ACE-UNO|[Ozon](https://www.ozon.ru/product/radiomodul-lora-drf1278f-na-sx1278-433-mgts-do-15-km-1226159993), [AliExpress](https://sl.aliexpress.ru/p?key=cemRGz9)|[Telegram](https://t.me/hutor_yanin/1983), [Gitflic](https://gitflic.ru/project/ogneyar/arduino/file?file=ElbearAceUno%2FLoRa)|
|GPS модуль GP-02-Kit|Высокопроизводительный многорежимный спутниковый навигационный приемник BDS GNSS GPS, подключение через USART|Elbear ACE-UNO|[Ozon](https://www.ozon.ru/product/vysokoproizvoditelnyy-mnogorezhimnyy-sputnikovyy-navigatsionnyy-priemnik-bds-gnss-soc-development-1817412682), [AliExpress](https://sl.aliexpress.ru/p?key=XSmRGno)|[Telegram](https://t.me/hutor_yanin/1914), [Gitflic](https://gitflic.ru/project/ogneyar/arduino/file?file=ElbearAceUno%2FGPS_GP_02_Satellites)|
|GPS шилд с NEO-6M|Шилд содержит модуль Neo-6m и модуль SD-карт, подключение через SPI|Elbear ACE-UNO|[Ozon](https://www.ozon.ru/product/gps-plata-rasshireniya-6m-slot-dlya-sd-karty-antenna-1599001299), [AliExpress](https://sl.aliexpress.ru/p?key=Zc9RGc5)|[Telegram](https://t.me/hutor_yanin/1764), [Gitflic](https://gitflic.ru/project/ogneyar/arduino/file?file=ElbearAceUno%2FGPS_NEO_6_tiny&branch=master)|
|Гироскоп MPU6050|Модуль акселерометра и гироскопа, подключение через I2C|ELBEAR ACE-UNO|[Ozon](https://ozon.ru/t/ytk86Ht), [AliExpress](https://sl.aliexpress.ru/p?key=KM09GtU)|[Telegram](https://t.me/hutor_yanin/1593), [Gitflic](https://gitflic.ru/project/ogneyar/arduino/blob?file=ElbearAceUno%2FMPU6050_surveyWithCalibration%2FMPU6050_surveyWithCalibration.ino&branch=master)|
|Электронный компас GY-271|Трехосевой цифровой компас на микросхеме HMC5883L|Elbear ACE-UNO|[Ozon](https://www.ozon.ru/product/modul-gy-271-trehosevoy-tsifrovoy-kompas-na-mikrosheme-hmc5883l-561309323), [AliExpress](https://sl.aliexpress.ru/p?key=8RuRGMI)|[Telegram](https://t.me/hutor_yanin/2278), [Gitflic](https://gitflic.ru/project/ogneyar/arduino/file?file=ElbearAceUno%2FQMC5883L_GY-271_xyz)|
|Модуль датчика LSM6DS3|Модуль 3-осевого акселерометра и гироскопа, подключение через SPI|Elbear ACE-UNO|[Ozon](https://www.ozon.ru/product/modul-3-osevogo-akselerometra-i-giroskopa-gy-lsm6ds3-1003876368), [AliExpress](https://sl.aliexpress.ru/p?key=4puRGGV)|[Telegram](https://t.me/hutor_yanin/2192), [Gitflic](https://gitflic.ru/project/ogneyar/arduino/file?file=ElbearAceUno%2FSPI_LSM6DS3_demo)|
|Датчик касания (сенсорная кнопка) HTTM|Емкостная кнопка, цифровой сигнал|Elbear ACE-UNO|[AliExpress](https://sl.aliexpress.ru/p?key=q6mRGDT)|[Telegram](https://t.me/hutor_yanin/1890), [Gitflic](https://gitflic.ru/project/ogneyar/arduino/file?file=ElbearAceUno%2FImpactSensor_test)|
|Датчик касания (сенсорная кнопка) TTP223B|Емкостная кнопка, цифровой сигнал|Elbear ACE-UNO|[Ozon](https://www.ozon.ru/product/datchik-kasaniya-sensornaya-knopka-ttp223b-arduino-1633188265), [AliExpress](https://sl.aliexpress.ru/p?key=C58RG9i)|[Telegram](https://t.me/hutor_yanin/1690), [Gitflic](https://gitflic.ru/project/ogneyar/arduino/file?file=ElbearAceUno%2FReedSwitch_test&branch=master)|
|Датчик температуры и влажности DHT11|Цифровой датчик содержит в себе АЦП для преобразования аналоговых значений влажности и температуры|Elbear ACE-UNO|[Ozon](https://www.ozon.ru/product/datchik-vlazhnosti-i-temperatury-dht11-arduino-1317541347), [AliExpress](https://sl.aliexpress.ru/p?key=5D0RGGR)|[Telegram](https://t.me/hutor_yanin/1712), [Gitflic](https://gitflic.ru/project/ogneyar/arduino/file?file=ElbearAceUno%2FDHT11_readTempAndHumidity&branch=master)|
|Датчик температуры и влажности DHT22|Цифровой датчик|Elbear ACE-UNO|[Ozon](https://www.ozon.ru/product/modul-tsifrovogo-datchika-temperatury-i-vlazhnosti-dht22-am2302-933031851), [AliExpress](https://sl.aliexpress.ru/p?key=86jRG0b)|[Telegram](https://t.me/hutor_yanin/1865), [Gitflic](https://gitflic.ru/project/ogneyar/arduino/file?file=ElbearAceUno%2FDHT22_readTempAndHumidity)|
|Датчик цвета TCS34725|Цифровой датчик|Elbear ACE-UNO|[Ozon](https://www.ozon.ru/product/datchik-tsveta-na-tcs3472-775174995), [AliExpress](https://sl.aliexpress.ru/p?key=6lmRGlD)|[Telegram](https://t.me/hutor_yanin/1855), [Gitflic](https://gitflic.ru/project/ogneyar/arduino/file?file=ElbearAceUno%2Ftcs3472_test)|
|Датчик качества воздуха AGS10|Цифровой датчик|Elbear ACE-UNO|[AliExpress](https://sl.aliexpress.ru/p?key=DgmRGXB)|[Telegram](https://t.me/hutor_yanin/1844), [Gitflic](https://gitflic.ru/project/ogneyar/arduino/file?file=ElbearAceUno%2FAGS10_readTVOC), [GitHub](https://github.com/ogneyar/AGS10_sensor)|
|Датчик пульса PulseSensor|Датчик сердечного ритма|Elbear ACE-UNO|[Ozon](https://www.ozon.ru/product/datchik-pulsa-datchik-serdtsebieniya-pulsesensor-414624875), [AliExpress](https://sl.aliexpress.ru/p?key=takRG2E)|[Telegram](https://t.me/hutor_yanin/1821), [Gitflic](https://gitflic.ru/project/ogneyar/arduino/file?file=ElbearAceUno2FSensorPulse_check), [GitHub](https://github.com/ogneyar/iarduino_SensorPulse)|
|Трансформаторный датчик тока ZMCT103C|Цифровой датчик|Elbear ACE-UNO|[Ozon](https://www.ozon.ru/product/transformatornyy-datchik-toka-zmct103c-reguliruemyy-278320605), [AliExpress](https://sl.aliexpress.ru/p?key=hykRGA9)|[Telegram](https://t.me/hutor_yanin/1796), [Gitflic](https://gitflic.ru/project/ogneyar/arduino/file?file=ElbearAceUno%2FZMCT103C_test&branch=master)|
|Датчик уровня воды|Аналоговый датчик|Elbear ACE-UNO|[Ozon](https://www.ozon.ru/product/datchik-urovnya-vody-zhidkosti-arduino-286889354), [AliExpress](https://sl.aliexpress.ru/p?key=fYkRGG0)|[Telegram](https://t.me/hutor_yanin/1791), [Gitflic](https://gitflic.ru/project/ogneyar/arduino/file?file=ElbearAceUno%2FImpactSensor_test&branch=master)|
|Модуль датчика удара KY-031 (HW-500)|Цифровой датчик|Elbear ACE-UNO|[Ozon](https://www.ozon.ru/product/modul-datchika-udara-ky-031-hw-500-dlya-arduino-1634989184), [AliExpress](https://sl.aliexpress.ru/p?key=JdEarUe)|[Telegram](https://t.me/hutor_yanin/1791), [Gitflic](https://gitflic.ru/project/ogneyar/arduino/file?file=ElbearAceUno%2FImpactSensor_test&branch=master)|
|Датчик вибрации (удара) SW-420|Mодуль датчика вибрации, цифровой сигнал|Elbear ACE-UNO|[Ozon](https://www.ozon.ru/product/datchik-vibratsii-udara-sw-420-276668454), [AliExpress](https://sl.aliexpress.ru/p?key=RQeRGTR)|[Telegram](https://t.me/hutor_yanin/1589), [Gitflic](https://gitflic.ru/project/ogneyar/arduino/file?file=ElbearAceUno%2FReedSwitch_test&branch=master)|
|Датчик звука KY-037|Цифровой датчик|Elbear ACE-UNO|[Ozon](https://www.ozon.ru/product/modul-zvuka-s-mikrofonom-s-tsifrovym-i-analogovym-vyhodami-b75-ky-037-arduino-294305993), [AliExpress](https://sl.aliexpress.ru/p?key=oD9RGsu)|[Telegram](https://t.me/hutor_yanin/1768), [Gitflic](https://gitflic.ru/project/ogneyar/arduino/file?file=ElbearAceUno%2FSoundSensor_led&branch=master)|
|Ультразвуковой датчик расстояния HC-SR04|Акустический датчик|Elbear ACE-UNO|[Ozon](https://www.ozon.ru/product/ultrazvukovoy-datchik-rasstoyaniya-hc-sr04-dalnomer-dlya-arduino-stm32-nodemcu-raspberry-982330663), [AliExpress](https://sl.aliexpress.ru/p?key=GwRRGSX)|[Telegram](https://t.me/hutor_yanin/1601), [Gitflic](https://gitflic.ru/project/ogneyar/arduino/file?file=ElbearAceUno%2FHC_SR04_test&branch=master)|
|Датчик препятствия KY-033 (HW-511)|Инфракрасный датчик, цифровой сигнал|Elbear ACE-UNO|[Ozon](https://www.ozon.ru/product/modul-datchika-linii-ky-033-hw-511-dlya-arduino-1635031318), [AliExpress](https://sl.aliexpress.ru/p?key=sjQRG71)|[Telegram](https://t.me/hutor_yanin/1748), [Gitflic](https://gitflic.ru/project/ogneyar/arduino/file?file=ElbearAceUno%2FReedSwitch_test&branch=master)|
|Лазерный модуль KY-008|Цифровой датчик|Elbear ACE-UNO|[Ozon](https://www.ozon.ru/product/lazernyy-modul-ky-008-arduino-1167219696), [AliExpress](https://sl.aliexpress.ru/p?key=LvQRG8S)|[Telegram](https://t.me/innatomeya_STM32_Linux/258), [Telegram](https://t.me/hutor_yanin/1744), [Gitflic](https://gitflic.ru/project/ogneyar/arduino/file?file=ElbearAceUno%2FKY-008_test&branch=master)|
|Датчик освещенности TEMT6000|Аналоговый датчик|Elbear ACE-UNO|[Ozon](https://www.ozon.ru/product/datchik-osveshchennosti-ampertok-temt6000-1-sht-501798149), [AliExpress](https://sl.aliexpress.ru/p?key=1TQRGpJ)|[Telegram](https://t.me/hutor_yanin/1741), [Gitflic](https://gitflic.ru/project/ogneyar/arduino/file?file=ElbearAceUno%2FTEMT6000_test&branch=master)|
|Датчик освещённости (фоторезистор)| Модуль с фоторезистором, цифровой сигнал|Elbear ACE-UNO|[Ozon](https://www.ozon.ru/product/datchik-sveta-fotorezistor-arduino-832150968), [AliExpress](https://sl.aliexpress.ru/p?key=3weRGMu)|[Telegram](https://t.me/hutor_yanin/1690), [Gitflic](https://gitflic.ru/project/ogneyar/arduino/file?file=ElbearAceUno%2FReedSwitch_test&branch=master)|
|Модуль MAX3232|Модуль преобразователя RS232, подключение через USART|Elbear ACE-UNO|[Ozon](https://www.ozon.ru/product/konverter-rs232-v-ttl-adapter-max3232-933520107), [AliExpress](https://sl.aliexpress.ru/p?key=Af1DrTQ)|[Telegram](https://t.me/hutor_yanin/1721)|
|Шаговый двигатель с драйвером ULN2003| - |Elbear ACE-UNO|[Ozon](https://www.ozon.ru/product/shagovyy-dvigatel-28byj-48-5v-s-drayverom-na-uln2003-933028639), [AliExpress](https://sl.aliexpress.ru/p?key=t6RRGjJ)|[Telegram](https://t.me/hutor_yanin/1603), [Gitflic](https://gitflic.ru/project/ogneyar/arduino/file?file=ElbearAceUno%2FStepper_ULN2003_basic&branch=master)|
|Модуль драйвера шагового двигателя DRV8833| - |Elbear ACE-UNO|[Ozon](https://www.ozon.ru/product/drv-8833-modul-drayvera-shagovogo-dvigatelya-motora-postoyannogo-toka-drayver-shagovogo-1572085339), [AliExpress](https://sl.aliexpress.ru/p?key=9G9RGYd)|[Telegram](https://t.me/hutor_yanin/1759), [Gitflic](https://gitflic.ru/project/ogneyar/arduino/file?file=ElbearAceUno%2FDRV8833_NL&branch=master), [Gitflic](https://gitflic.ru/project/ogneyar/arduino/file?file=ElbearAceUno%2FDRV8833_Stepper_NL&branch=master)|
|Motor Shield v.2|Драйвер моторов на двух микрочипах L293D|Elbear ACE-UNO|[Ozon](https://www.ozon.ru/product/drayver-dvigatelya-dlya-arduino-arduino-motor-shield-v-2-1142991783), [AliExpress](https://sl.aliexpress.ru/p?key=aeRRGsO)|[Telegram](https://t.me/hutor_yanin/1626), [Gitflic](https://gitflic.ru/project/ogneyar/motorshield_amura)|
|Герконовый датчик магнитного поля G123-08|Модуль с герконовым датчиком, цифровой сигнал|Elbear ACE-UNO|[Ozon](https://www.ozon.ru/product/gerkonovyy-datchik-magnitnogo-polya-g123-08-dlya-arduino-933032245), [AliExpress](https://sl.aliexpress.ru/p?key=FVeRGRF)|[Telegram](https://t.me/hutor_yanin/1589), [Gitflic](https://gitflic.ru/project/ogneyar/arduino/file?file=ElbearAceUno%2FReedSwitch_test&branch=master)|
|Датчик наклона SW520D|Модуль датчика наклона, цифровой сигнал|Elbear ACE-UNO|[Ozon](https://www.ozon.ru/product/datchik-naklona-i-vibratsii-sw520d-dlya-arduino-1320666786), [AliExpress](https://sl.aliexpress.ru/p?key=jFeRGot)|[Telegram](https://t.me/hutor_yanin/1589), [Gitflic](https://gitflic.ru/project/ogneyar/arduino/file?file=ElbearAceUno%2FReedSwitch_test&branch=master)|
## Модули, требующие аппаратную модификацию
|Модуль|Описание|Требуемые изменеия|Протестировано на|Ссылки на модуль|Материалы|
|---------|---------|------|---------|------|------|
|GPRS шилд с SIM900|Позволяет подключиться к сотовой сети, подключение через USART|Для использования SoftwareSerial при работе с шилдом необходимо убрать перемычку с вывода TX на плате шилда и проводом подключить его к выводу платы, который поддерживает работу с прерываниями|Elbear ACE-UNO|[Ozon](https://www.ozon.ru/product/plata-rasshireniya-gsm-gprs-shield-sim900-dlya-arduino-319034019), [AliExpress](https://sl.aliexpress.ru/p?key=ShjRGRZ)|[Telegram](https://t.me/hutor_yanin/1776), [YouTube](https://youtu.be/1TAkBW9u3uY), [VK Видео](https://vkvideo.ru/video119909267_456239202), [Дзен](https://dzen.ru/video/watch/67407260ca74f40671f8c7ee), [RuTube](https://rutube.ru/video/a626c1f30f3e464bb70ae27a4ad2d969), [Gitflic](https://gitflic.ru/project/ogneyar/arduino/file?file=ElbearAceUno%2FSIM900_sendSMS&branch=master)|
|Светодиодная матрица|Матрица с драйвером MAX7219|MAX7219 с АМУРом не заработала, матрицу приходится подключать напрямую, подпаиваясь к контактам|Elbear ACE-UNO|[Ozon](https://www.ozon.ru/product/svetodiodnaya-matritsa-arduino-s-drayverom-max7219-1161681177), [AliExpress](https://sl.aliexpress.ru/p?key=7tkRGjj)|[Telegram](https://t.me/hutor_yanin/1773), [Gitflic](https://gitflic.ru/project/ogneyar/arduino/file?file=ElbearAceUno%2FMatrix_led&branch=master)||
|Ethernet Shield W5500 v2.0|Позволяет подключиться к сети интернет до 100 МБит, подключение через SPI|Требуется припаять провода от ISCP разъёма к плате расширения|Elbear ACE-UNO|[AliExpress](https://sl.aliexpress.ru/p?key=JK0RGtp)|[Telegram](https://t.me/hutor_yanin/1463), [YouTube](https://youtu.be/fUFW2P_hY7E), [VK Видео](https://vk.com/video119909267_456239193), [RuTube](https://rutube.ru/video/afc7972188fa863f40fd860a3ee38954), [Gitflic](https://gitflic.ru/project/ogneyar/arduino/file?file=ElbearAceUno%2FEthernetShield_WebServer&branch=master)|

2
libraries/EEPROM/.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
installed.json
.vscode/

139
libraries/EEPROM/README.md Normal file
View File

@ -0,0 +1,139 @@
## **EEPROM Library V2.0** for Arduino
**Written by:** _Christopher Andrews_.
### **What is the EEPROM library.**
Th EEPROM library provides an easy to use interface to interact with the internal non-volatile storage found in AVR based Arduino boards. This library will work on many AVR devices like ATtiny and ATmega chips.
### **How to use it**
The EEPROM library is included in your IDE download. To add its functionality to your sketch you'll need to reference the library header file. You do this by adding an include directive to the top of your sketch.
```Arduino
#include <EEPROM.h>
void setup(){
}
void loop(){
}
```
The library provides a global variable named `EEPROM`, you use this variable to access the library functions. The methods provided in the EEPROM class are listed below.
You can view all the examples [here](examples/).
### **Library functions**
#### **`EEPROM.read( address )`** [[_example_]](examples/eeprom_read/eeprom_read.ino)
This function allows you to read a single byte of data from the eeprom.
Its only parameter is an `int` which should be set to the address you wish to read.
The function returns an `unsigned char` containing the value read.
#### **`EEPROM.write( address, value )`** [[_example_]](examples/eeprom_write/eeprom_write.ino)
The `write()` method allows you to write a single byte of data to the EEPROM.
Two parameters are needed. The first is an `int` containing the address that is to be written, and the second is a the data to be written (`unsigned char`).
This function does not return any value.
#### **`EEPROM.update( address, value )`** [[_example_]](examples/eeprom_update/eeprom_update.ino)
This function is similar to `EEPROM.write()` however this method will only write data if the cell contents pointed to by `address` is different to `value`. This method can help prevent unnecessary wear on the EEPROM cells.
This function does not return any value.
#### **`EEPROM.get( address, object )`** [[_example_]](examples/eeprom_get/eeprom_get.ino)
This function will retrieve any object from the EEPROM.
Two parameters are needed to call this function. The first is an `int` containing the address that is to be written, and the second is the object you would like to read.
This function returns a reference to the `object` passed in. It does not need to be used and is only returned for convenience.
#### **`EEPROM.put( address, object )`** [[_example_]](examples/eeprom_put/eeprom_put.ino)
This function will write any object to the EEPROM.
Two parameters are needed to call this function. The first is an `int` containing the address that is to be written, and the second is the object you would like to write.
This function uses the _update_ method to write its data, and therefore only rewrites changed cells.
This function returns a reference to the `object` passed in. It does not need to be used and is only returned for convenience.
#### **Subscript operator: `EEPROM[address]`** [[_example_]](examples/eeprom_crc/eeprom_crc.ino)
This operator allows using the identifier `EEPROM` like an array.
EEPROM cells can be read _and_ **_written_** directly using this method.
This operator returns a reference to the EEPROM cell.
```c++
unsigned char val;
//Read first EEPROM cell.
val = EEPROM[ 0 ];
//Write first EEPROM cell.
EEPROM[ 0 ] = val;
//Compare contents
if( val == EEPROM[ 0 ] ){
//Do something...
}
```
#### **`EEPROM.length()`**
This function returns an `unsigned int` containing the number of cells in the EEPROM.
---
### **Advanced features**
This library uses a component based approach to provide its functionality. This means you can also use these components to design a customized approach. Two background classes are available for use: `EERef` & `EEPtr`.
#### **`EERef` class**
This object references an EEPROM cell.
Its purpose is to mimic a typical byte of RAM, however its storage is the EEPROM.
This class has an overhead of two bytes, similar to storing a pointer to an EEPROM cell.
```C++
EERef ref = EEPROM[ 10 ]; //Create a reference to 11th cell.
ref = 4; //write to EEPROM cell.
unsigned char val = ref; //Read referenced cell.
```
#### **`EEPtr` class**
This object is a bidirectional pointer to EEPROM cells represented by `EERef` objects.
Just like a normal pointer type, this type can be dereferenced and repositioned using
increment/decrement operators.
```C++
EEPtr ptr = 10; //Create a pointer to 11th cell.
*ptr = 4; //dereference and write to EEPROM cell.
unsigned char val = *ptr; //dereference and read.
ptr++; //Move to next EEPROM cell.
```
#### **`EEPROM.begin()`**
This function returns an `EEPtr` pointing to the first cell in the EEPROM.
This is useful for STL objects, custom iteration and C++11 style ranged for loops.
#### **`EEPROM.end()`**
This function returns an `EEPtr` pointing at the location after the last EEPROM cell.
Used with `begin()` to provide custom iteration.
**Note:** The `EEPtr` returned is invalid as it is out of range. In fact the hardware causes wrapping of the address (overflow) and `EEPROM.end()` actually references the first EEPROM cell.

View File

@ -0,0 +1,32 @@
/*
* EEPROM Clear
*
* Sets all of the bytes of the EEPROM to 0.
* Please see eeprom_iteration for a more in depth
* look at how to traverse the EEPROM.
*
* This example code is in the public domain.
*/
#include <EEPROM.h>
void setup() {
// initialize the LED pin as an output.
pinMode(LED_BUILTIN, OUTPUT);
EEPROM.begin();
/***
Iterate through each byte of the EEPROM storage.
***/
for (int i = 0 ; i < EEPROM.length() ; i++) {
EEPROM.write(i, 0);
}
// turn the LED on when we're done
digitalWrite(LED_BUILTIN, HIGH);
}
void loop() {
/** Empty loop. **/
}

View File

@ -0,0 +1,51 @@
/***
CRC algorithm generated by pycrc ( https://github.com/tpircher/pycrc ).
A CRC is a simple way of checking whether data has changed or become corrupted.
This example calculates a CRC value directly on the EEPROM values.
The purpose of this example is to highlight how the EEPROM object can be used just like an array.
***/
#include <EEPROM.h>
void setup() {
//Start serial
Serial.begin(9600);
EEPROM.begin();
while (!Serial) {
; // wait for serial port to connect. Needed for native USB port only
}
//Print length of data to run CRC on.
Serial.print("EEPROM length: ");
Serial.println(EEPROM.length());
//Print the result of calling eeprom_crc()
Serial.print("CRC32 of EEPROM data: 0x");
Serial.println(eeprom_crc(), HEX);
Serial.print("\n\nDone!");
}
void loop() {
/* Empty loop */
}
unsigned long eeprom_crc(void) {
const unsigned long crc_table[16] = {
0x00000000, 0x1db71064, 0x3b6e20c8, 0x26d930ac,
0x76dc4190, 0x6b6b51f4, 0x4db26158, 0x5005713c,
0xedb88320, 0xf00f9344, 0xd6d6a3e8, 0xcb61b38c,
0x9b64c2b0, 0x86d3d2d4, 0xa00ae278, 0xbdbdf21c
};
unsigned long crc = ~0L;
for (int index = 0 ; index < EEPROM.length() ; ++index) {
crc = crc_table[(crc ^ EEPROM[index]) & 0x0f] ^ (crc >> 4);
crc = crc_table[(crc ^ (EEPROM[index] >> 4)) & 0x0f] ^ (crc >> 4);
crc = ~crc;
}
return crc;
}

View File

@ -0,0 +1,66 @@
/***
eeprom_get example.
This shows how to use the EEPROM.get() method.
To pre-set the EEPROM data, run the example sketch eeprom_put.
This sketch will run without it, however, the values shown
will be shown from what ever is already on the EEPROM.
This may cause the serial object to print out a large string
of garbage if there is no null character inside one of the strings
loaded.
***/
#include <EEPROM.h>
void setup() {
EEPROM.begin();
float f = 0.00f; //Variable to store data read from EEPROM.
int eeAddress = 0; //EEPROM address to start reading from
Serial.begin(9600);
while (!Serial) {
; // wait for serial port to connect. Needed for native USB port only
}
Serial.print("Read float from EEPROM: ");
//Get the float data from the EEPROM at position 'eeAddress'
EEPROM.get(eeAddress, f);
Serial.println(f, 3); //This may print 'ovf, nan' if the data inside the EEPROM is not a valid float.
/***
As get also returns a reference to 'f', you can use it inline.
E.g: Serial.print( EEPROM.get( eeAddress, f ) );
***/
/***
Get can be used with custom structures too.
I have separated this into an extra function.
***/
secondTest(); //Run the next test.
}
struct MyObject {
float field1;
byte field2;
char name[10];
};
void secondTest() {
int eeAddress = sizeof(float); //Move address to the next byte after float 'f'.
MyObject customVar; //Variable to store custom object read from EEPROM.
EEPROM.get(eeAddress, customVar);
Serial.println("Read custom object from EEPROM: ");
Serial.println(customVar.field1);
Serial.println(customVar.field2);
Serial.println(customVar.name);
}
void loop() {
/* Empty loop */
}

View File

@ -0,0 +1,55 @@
/***
eeprom_iteration example.
A set of example snippets highlighting the
simplest methods for traversing the EEPROM.
Running this sketch is not necessary, this is
simply highlighting certain programming methods.
***/
#include <EEPROM.h>
void setup() {
EEPROM.begin();
/***
Iterate the EEPROM using a for loop.
***/
for (int index = 0 ; index < EEPROM.length() ; index++) {
//Add one to each cell in the EEPROM
EEPROM[ index ] += 1;
}
/***
Iterate the EEPROM using a while loop.
***/
int index = 0;
while (index < EEPROM.length()) {
//Add one to each cell in the EEPROM
EEPROM[ index ] += 1;
index++;
}
/***
Iterate the EEPROM using a do-while loop.
***/
int idx = 0; //Used 'idx' to avoid name conflict with 'index' above.
do {
//Add one to each cell in the EEPROM
EEPROM[ idx ] += 1;
idx++;
} while (idx < EEPROM.length());
} //End of setup function.
void loop() {}

View File

@ -0,0 +1,56 @@
/***
eeprom_put example.
This shows how to use the EEPROM.put() method.
Also, this sketch will pre-set the EEPROM data for the
example sketch eeprom_get.
Note, unlike the single byte version EEPROM.write(),
the put method will use update semantics. As in a byte
will only be written to the EEPROM if the data is actually
different.
***/
#include <EEPROM.h>
struct MyObject {
float field1;
byte field2;
char name[10];
};
void setup() {
EEPROM.begin();
Serial.begin(9600);
while (!Serial) {
; // wait for serial port to connect. Needed for native USB port only
}
float f = 123.456f; //Variable to store in EEPROM.
int eeAddress = 0; //Location we want the data to be put.
//One simple call, with the address first and the object second.
EEPROM.put(eeAddress, f);
Serial.println("Written float data type!");
/** Put is designed for use with custom structures also. **/
//Data to store.
MyObject customVar = {
3.14f,
65,
"Working!"
};
eeAddress += sizeof(float); //Move address to the next byte after float 'f'.
EEPROM.put(eeAddress, customVar);
Serial.print("Written custom data type! \n\nView the example sketch eeprom_get to see how you can retrieve the values!");
}
void loop() {
/* Empty loop */
}

View File

@ -0,0 +1,38 @@
/*
* EEPROM Read
*
* Reads the value of each byte of the EEPROM and prints it
* to the computer.
*/
#include <EEPROM.h>
// start reading from the first byte (address 0) of the EEPROM
int address = 0;
byte value;
void setup() {
EEPROM.begin();
// initialize serial and wait for port to open:
Serial.begin(9600);
while (!Serial) {
; // wait for serial port to connect. Needed for native USB port only
}
}
void loop() {
// read a byte from the current address of the EEPROM
value = EEPROM.read(address);
Serial.print(address);
Serial.print("\t");
Serial.print(value, DEC);
Serial.println();
address = address + 1;
if (address == EEPROM.length()) {
address = 0;
}
delay(500);
}

View File

@ -0,0 +1,50 @@
/***
EEPROM Update method
Stores values read from analog input 0 into the EEPROM.
These values will stay in the EEPROM when the board is
turned off and may be retrieved later by another sketch.
If a value has not changed in the EEPROM, it is not overwritten
which would reduce the life span of the EEPROM unnecessarily.
***/
#include <EEPROM.h>
/** the current address in the EEPROM (i.e. which byte we're going to write to next) **/
int address = 0;
void setup() {
EEPROM.begin();
}
void loop() {
/***
need to divide by 4 because analog inputs range from
0 to 1023 and each byte of the EEPROM can only hold a
value from 0 to 255.
***/
int val = analogRead(0) / 4;
/***
Update the particular EEPROM cell.
these values will remain there when the board is
turned off.
***/
EEPROM.update(address, val);
/***
The function EEPROM.update(address, val) is equivalent to the following:
if( EEPROM.read(address) != val ){
EEPROM.write(address, val);
}
***/
address = address + 1;
if (address == EEPROM.length()) {
address = 0;
}
delay(100);
}

View File

@ -0,0 +1,41 @@
/*
* EEPROM Write
*
* Stores values read from analog input 0 into the EEPROM.
* These values will stay in the EEPROM when the board is
* turned off and may be retrieved later by another sketch.
*/
#include <EEPROM.h>
/** the current address in the EEPROM (i.e. which byte we're going to write to next) **/
int addr = 0;
void setup() {
EEPROM.begin();
}
void loop() {
/***
Need to divide by 4 because analog inputs range from
0 to 1023 and each byte of the EEPROM can only hold a
value from 0 to 255.
***/
int val = analogRead(0) / 4;
/***
Write the value to the appropriate byte of the EEPROM.
these values will remain there when the board is
turned off.
***/
EEPROM.write(addr, val);
addr = addr + 1;
if (addr == EEPROM.length()) {
addr = 0;
}
delay(100);
}

View File

@ -0,0 +1,22 @@
#######################################
# Syntax Coloring Map For EEPROM
#######################################
#######################################
# Datatypes (KEYWORD1)
#######################################
EEPROM KEYWORD1
EERef KEYWORD1
EEPtr KEYWORD2
#######################################
# Methods and Functions (KEYWORD2)
#######################################
update KEYWORD2
#######################################
# Constants (LITERAL1)
#######################################

View File

@ -0,0 +1,10 @@
name=EEPROM
version=0.0.0
author=Arduino, Christopher Andrews
maintainer=Elron
sentence=Enables reading and writing to the permanent board storage.
paragraph=This library allows to read and write data in a memory type, the EEPROM, that keeps its content also when the board is powered off. The amount of EEPROM available depends on the microcontroller type.
category=Data Storage
url=http://www.arduino.cc/en/Reference/EEPROM
architectures=MIK32_Amur

View File

@ -0,0 +1,119 @@
#include "EEPROM.h"
#include "mik32_hal_eeprom.h"
#include "mik32_hal.h"
HAL_EEPROM_HandleTypeDef heeprom;
void EEPROMClass:: begin()
{
heeprom.Instance = EEPROM_REGS;
heeprom.Mode = HAL_EEPROM_MODE_TWO_STAGE;
heeprom.ErrorCorrection = HAL_EEPROM_ECC_ENABLE;
heeprom.EnableInterrupt = HAL_EEPROM_SERR_DISABLE;
HAL_EEPROM_Init(&heeprom);
HAL_EEPROM_CalculateTimings(&heeprom, OSC_SYSTEM_VALUE);
}
uint8_t read_byte( int idx )
{
// check if idx is valid
if (idx < 0)
{
idx = -idx;
ErrorMsgHandler("EEPROM.read(): The eeprom cell address must be non-negative");
}
if ((uint32_t)idx >= (uint32_t)EEPROM_LENGHT)
{
idx = (int)((uint32_t)idx % EEPROM_LENGHT);
ErrorMsgHandler("EEPROM.read(): The address of the eeprom cell goes beyond the eeprom");
}
uint32_t read_data_buf[EEPROM_PAGE_WORDS] = {};
// calc start address of the desired page
uint32_t addr = EEPROM_START_ADDR + (((uint32_t)idx) / EEPROM_PAGE_SIZE) * EEPROM_PAGE_SIZE;
// read desired page
HAL_EEPROM_Read(&heeprom, (uint16_t)addr, read_data_buf, EEPROM_PAGE_WORDS, EEPROM_OP_TIMEOUT);
// address of the searched word in eeprom: EEPROM_START_ADDR + (uint32_t)idx
uint32_t word_addr = EEPROM_START_ADDR + (((uint32_t)idx) / EEPROM_WORD_SIZE) * EEPROM_WORD_SIZE;
// searched word index in the read_data_buf array: the word address in the eeprom minus the page beginning address
uint32_t word_idx = (word_addr - addr) / EEPROM_WORD_SIZE;
// byte number in a word
uint32_t byte_idx = ((uint32_t)idx) % EEPROM_WORD_SIZE;
// get desired byte from page data
return (uint8_t)(( read_data_buf[word_idx] & (((uint32_t)0xFF) << ((EEPROM_WORD_SIZE - byte_idx - 1) * 8)) ) >> ((EEPROM_WORD_SIZE - byte_idx - 1) * 8));
}
void write_byte( int idx, uint8_t val )
{
// check if idx is valid
if (idx < 0)
{
idx = -idx;
ErrorMsgHandler("EEPROM.write(): The eeprom cell address must be non-negative");
}
if ((uint32_t)idx >= (uint32_t)EEPROM_LENGHT)
{
idx = (int)((uint32_t)idx % EEPROM_LENGHT);
ErrorMsgHandler("EEPROM.write(): The address of the eeprom cell goes beyond the eeprom");
}
update_byte(idx, val);
}
void update_byte( int idx, uint8_t val )
{
// check if idx is valid
if (idx < 0)
{
idx = -idx;
ErrorMsgHandler("EEPROM.update(): The eeprom cell address must be non-negative");
}
if ((uint32_t)idx >= (uint32_t)EEPROM_LENGHT)
{
idx = (int)((uint32_t)idx % EEPROM_LENGHT);
ErrorMsgHandler("EEPROM.update(): The address of the eeprom cell goes beyond the eeprom");
}
uint32_t write_data_buf[EEPROM_PAGE_WORDS] = {};
// calc start address of the desired page
uint32_t addr = EEPROM_START_ADDR + (((uint32_t)idx) / EEPROM_PAGE_SIZE) * EEPROM_PAGE_SIZE;
// read desired page
HAL_EEPROM_Read(&heeprom, (uint16_t)addr, write_data_buf, EEPROM_PAGE_WORDS, EEPROM_OP_TIMEOUT);
// address of the searched word in eeprom: EEPROM_START_ADDR + (uint32_t)idx
uint32_t word_addr = EEPROM_START_ADDR + (((uint32_t)idx) / EEPROM_WORD_SIZE) * EEPROM_WORD_SIZE;
// searched word index in the write_data_buf array: the word address in the eeprom minus the page beginning address
uint32_t word_idx = (word_addr - addr) / EEPROM_WORD_SIZE;
// byte number in a word
uint32_t byte_idx = ((uint32_t)idx) % EEPROM_WORD_SIZE;
// get desired byte
uint32_t byte = ((uint32_t)val) << ((EEPROM_WORD_SIZE - byte_idx - 1) * 8);
uint8_t oldVal = (uint8_t)(*((uint8_t*)write_data_buf + word_idx * EEPROM_WORD_SIZE + (EEPROM_WORD_SIZE - byte_idx - 1)));
// checking if written byte is different from the new one
if(oldVal != val)
{
// clear page
HAL_EEPROM_Erase(&heeprom, (uint16_t)addr, EEPROM_PAGE_WORDS, HAL_EEPROM_WRITE_SINGLE, EEPROM_OP_TIMEOUT);
// get and replace the desired byte
write_data_buf[word_idx] = (write_data_buf[word_idx] & (~((uint32_t)(0xFF) << ((EEPROM_WORD_SIZE - byte_idx - 1) * 8)))) | byte;
HAL_EEPROM_Write(&heeprom, (uint16_t)addr, write_data_buf, EEPROM_PAGE_WORDS, HAL_EEPROM_WRITE_SINGLE, EEPROM_OP_TIMEOUT);
}
}
void HAL_read(uint16_t addr, uint32_t * data)
{
HAL_EEPROM_Read(&heeprom, (uint16_t)addr, data, EEPROM_PAGE_WORDS, EEPROM_OP_TIMEOUT);
}
void HAL_write(uint16_t addr, uint32_t * data)
{
HAL_EEPROM_Write(&heeprom, (uint16_t)addr, data, EEPROM_PAGE_WORDS, HAL_EEPROM_WRITE_SINGLE, EEPROM_OP_TIMEOUT);
}
void HAL_erase(uint16_t addr)
{
HAL_EEPROM_Erase(&heeprom, (uint16_t)addr, EEPROM_PAGE_WORDS, HAL_EEPROM_WRITE_SINGLE, EEPROM_OP_TIMEOUT);
}

View File

@ -0,0 +1,250 @@
#ifndef EEPROM_h
#define EEPROM_h
#include <Arduino.h>
#include <inttypes.h>
#include "string.h"
#define EEPROM_OP_TIMEOUT 100000
#define EEPROM_PAGE_WORDS 32 // words number per page
#define EEPROM_PAGE_COUNT 8 // user EEPROM pages number
#define EEPROM_START_ADDR 0x1C00 // user EEPROM start address
#define EEPROM_WORD_SIZE 4 // word takes 4 bytes
#define EEPROM_PAGE_SIZE ( EEPROM_PAGE_WORDS * EEPROM_WORD_SIZE ) // page takes 32*4 = 128 bytes
#define EEPROM_END 0x1FFF
#define EEPROM_LENGHT (EEPROM_PAGE_SIZE * EEPROM_PAGE_COUNT)
void HAL_read(uint16_t addr, uint32_t * data);
void HAL_write(uint16_t addr, uint32_t * data);
void HAL_erase(uint16_t addr);
uint8_t read_byte( int idx );
void write_byte( int idx, uint8_t val );
void update_byte( int idx, uint8_t val );
struct EERef{
EERef( const int index )
: index( index ) {}
uint8_t operator*() const { return read_byte( index ); }
operator uint8_t() const { return **this; }
EERef &operator=( const EERef &ref ) { return *this = *ref; }
EERef &operator=( uint8_t in ) { return write_byte( index, in ), *this; }
EERef &operator +=( uint8_t in ) { return *this = **this + in; }
EERef &operator -=( uint8_t in ) { return *this = **this - in; }
EERef &operator *=( uint8_t in ) { return *this = **this * in; }
EERef &operator /=( uint8_t in ) { return *this = **this / in; }
EERef &operator ^=( uint8_t in ) { return *this = **this ^ in; }
EERef &operator %=( uint8_t in ) { return *this = **this % in; }
EERef &operator &=( uint8_t in ) { return *this = **this & in; }
EERef &operator |=( uint8_t in ) { return *this = **this | in; }
EERef &operator <<=( uint8_t in ) { return *this = **this << in; }
EERef &operator >>=( uint8_t in ) { return *this = **this >> in; }
EERef &update( uint8_t in ) { return in != *this ? *this = in : *this; }
/** Prefix increment/decrement **/
EERef& operator++() { return *this += 1; }
EERef& operator--() { return *this -= 1; }
/** Postfix increment/decrement **/
uint8_t operator++ (int){
uint8_t ret = **this;
return ++(*this), ret;
}
uint8_t operator-- (int){
uint8_t ret = **this;
return --(*this), ret;
}
int index;
};
struct EEPtr{
EEPtr( const int index )
: index( index ) {}
operator int() const { return index; }
EEPtr &operator=( int in ) { return index = in, *this; }
bool operator!=( const EEPtr &ptr ) { return index != ptr.index; }
EERef operator*() { return index; }
EEPtr& operator++() { return ++index, *this; }
EEPtr& operator--() { return --index, *this; }
EEPtr operator++ (int) { return index++; }
EEPtr operator-- (int) { return index--; }
int index;
};
struct EEPROMClass{
//Basic user access methods.
EERef operator[]( const int idx ) { return idx; }
uint8_t read( int idx ) { return EERef( idx ); }
void write( int idx, uint8_t val ) { (EERef( idx )) = val; }
void update( int idx, uint8_t val ) { update_byte(idx, val); }
void begin();
EEPtr end() { return length(); } // Standards requires this to be the item after the last valid entry. The returned pointer is invalid.
uint16_t length() { return (uint16_t)EEPROM_LENGHT; }
template< typename T >
const T &put(int idx, const T &data)
{
void* dataPointer = (void*)&data;
// check if idx is valid
if (idx < 0)
{
idx = -idx;
ErrorMsgHandler("EEPROM.put(): The eeprom cell address must be non-negative");
}
if ((uint32_t)idx >= (uint32_t)EEPROM_LENGHT)
{
idx = (int)((uint32_t)idx % EEPROM_LENGHT);
ErrorMsgHandler("EEPROM.put(): The address of the eeprom cell goes beyond the eeprom");
}
uint32_t write_data_buf[EEPROM_PAGE_WORDS] = {};
uint32_t dataSize = sizeof(data); // writing data size
uint32_t dataShift = 0; // shift of the data writing start address
uint32_t writeSize = dataSize;
// calc start address of the desired page
uint32_t addr = EEPROM_START_ADDR + (((uint32_t)idx) / EEPROM_PAGE_SIZE) * EEPROM_PAGE_SIZE;
// address of the searched word in eeprom: EEPROM_START_ADDR + (uint32_t)idx
uint32_t word_addr = EEPROM_START_ADDR + (((uint32_t)idx) / EEPROM_WORD_SIZE) * EEPROM_WORD_SIZE;
// searched word index in the write_data_buf array: the word address in the eeprom minus the page beginning address
uint32_t word_idx = (word_addr - addr) / EEPROM_WORD_SIZE;
// page data start address
uint32_t byte_addr = (uint32_t)idx % EEPROM_PAGE_SIZE;
// byte number in a word
uint32_t byte_idx = ((uint32_t)idx) % EEPROM_WORD_SIZE;
// read first page
HAL_read((uint16_t)addr, write_data_buf);
// if data does not fit on the first page, then write down only what fits
if (EEPROM_PAGE_SIZE - byte_addr < dataSize)
writeSize = EEPROM_PAGE_SIZE - byte_addr;
uint32_t lastWord = (writeSize + byte_idx - 1) / EEPROM_WORD_SIZE + word_idx;
dataSize -= writeSize;
// write data page by page, first separately write the first page
memcpy((void *)((uint8_t *)write_data_buf + byte_addr), (void*)dataPointer, writeSize);
// prepare words for writing
for(uint8_t i = word_idx; i <= lastWord; i++)
{
uint32_t word = write_data_buf[i];
write_data_buf[i] = 0;
write_data_buf[i] = ((word & 0xFF)<<24) | ((word & (0xFF<<8))<<8) | ((word & (0xFF<<16))>>8) | ((word & (0xFF<<24))>>24);
}
HAL_erase((uint16_t)addr);
HAL_write((uint16_t)addr, write_data_buf);
// if there is data left after writing the first page, then write it page by page until it runs out
while (dataSize > 0)
{
addr += EEPROM_PAGE_SIZE;
// if reaching the eeprom end address, return to the initial address
if (addr == EEPROM_START_ADDR + EEPROM_LENGHT)
addr = EEPROM_START_ADDR;
HAL_read((uint16_t)addr, write_data_buf);
dataShift += writeSize;
writeSize = dataSize;
if (EEPROM_PAGE_SIZE < dataSize)
writeSize = EEPROM_PAGE_SIZE;
lastWord = (writeSize - 1) / EEPROM_WORD_SIZE;
memcpy((void *)(write_data_buf), (void*)((uint8_t *)dataPointer + dataShift), writeSize);
// prepare words for writing
for(uint8_t i = 0; i <= lastWord; i++)
{
uint32_t word = write_data_buf[i];
write_data_buf[i] = 0;
write_data_buf[i] = ((word & 0xFF)<<24) | ((word & (0xFF<<8))<<8) | ((word & (0xFF<<16))>>8) | ((word & (0xFF<<24))>>24);
}
HAL_erase((uint16_t)addr);
HAL_write((uint16_t)addr, write_data_buf);
dataSize -= writeSize;
}
return data;
}
template< typename T >
T &get(int idx, T &data)
{
void* dataPointer = (void*)&data;
// check if idx is valid
if (idx < 0)
{
idx = -idx;
ErrorMsgHandler("EEPROM.get(): The eeprom cell address must be non-negative");
}
if ((uint32_t)idx >= (uint32_t)EEPROM_LENGHT)
{
idx = (int)((uint32_t)idx % EEPROM_LENGHT);
ErrorMsgHandler("EEPROM.get(): The address of the eeprom cell goes beyond the eeprom");
}
uint32_t read_data_buf[EEPROM_PAGE_WORDS] = {};
uint32_t dataSize = sizeof(data); // reading data size
uint32_t dataShift = 0; // shift of the data reading start address
uint32_t readSize = dataSize;
// calc start address of the desired page
uint32_t addr = EEPROM_START_ADDR + (((uint32_t)idx) / EEPROM_PAGE_SIZE) * EEPROM_PAGE_SIZE;
// address of the searched word in eeprom: EEPROM_START_ADDR + (uint32_t)idx
uint32_t word_addr = EEPROM_START_ADDR + (((uint32_t)idx) / EEPROM_WORD_SIZE) * EEPROM_WORD_SIZE;
// searched word index in the read_data_buf array: the word address in the eeprom minus the page beginning address
uint32_t word_idx = (word_addr - addr) / EEPROM_WORD_SIZE;
// page data start address
uint32_t byte_addr = (uint32_t)idx % EEPROM_PAGE_SIZE;
// byte number in a word
uint32_t byte_idx = ((uint32_t)idx) % EEPROM_WORD_SIZE;
// read first page
HAL_read((uint16_t)addr, read_data_buf);
if (EEPROM_PAGE_SIZE - byte_addr < dataSize)
readSize = EEPROM_PAGE_SIZE - byte_addr;
uint32_t lastWord = (readSize + byte_idx - 1) / EEPROM_WORD_SIZE + word_idx;
dataSize -= readSize;
// prepare words
for(uint8_t i = word_idx; i <= lastWord; i++)
{
uint32_t word = read_data_buf[i];
read_data_buf[i] = 0;
read_data_buf[i] = ((word & 0xFF)<<24) | ((word & (0xFF<<8))<<8) | ((word & (0xFF<<16))>>8) | ((word & (0xFF<<24))>>24);
}
// read data page by page, first separately read the first page
memcpy((void *)dataPointer, (void*)((uint8_t *)read_data_buf + byte_addr), readSize);
// if there is data left after reading the first page, then read it page by page until it runs out
while (dataSize > 0)
{
addr += EEPROM_PAGE_SIZE;
// if reaching the eeprom end address, return to the initial address
if (addr == EEPROM_START_ADDR + EEPROM_LENGHT)
addr = EEPROM_START_ADDR;
HAL_read((uint16_t)addr, read_data_buf);
dataShift += readSize;
readSize = dataSize;
if (EEPROM_PAGE_SIZE < dataSize)
readSize = EEPROM_PAGE_SIZE;
lastWord = (dataSize - 1) / EEPROM_WORD_SIZE;
// prepare words
for(uint8_t i = 0; i <= lastWord; i++)
{
uint32_t word = read_data_buf[i];
read_data_buf[i] = 0;
read_data_buf[i] = ((word & 0xFF)<<24) | ((word & (0xFF<<8))<<8) | ((word & (0xFF<<16))>>8) | ((word & (0xFF<<24))>>24);
}
memcpy((void *)((uint8_t *)dataPointer + dataShift), (void*)(read_data_buf), readSize);
dataSize -= readSize;
}
return data; // Return passed object pointer with the read data
}
};
#pragma GCC diagnostic ignored "-Wunused-variable" // for GCC and Clang
static EEPROMClass EEPROM;
#endif

View File

@ -0,0 +1,76 @@
# Contributor Covenant Code of Conduct
## Our Pledge
In the interest of fostering an open and welcoming environment, we as
contributors and maintainers pledge to making participation in our project and
our community a harassment-free experience for everyone, regardless of age, body
size, disability, ethnicity, sex characteristics, gender identity and expression,
level of experience, education, socio-economic status, nationality, personal
appearance, race, religion, or sexual identity and orientation.
## Our Standards
Examples of behavior that contributes to creating a positive environment
include:
* Using welcoming and inclusive language
* Being respectful of differing viewpoints and experiences
* Gracefully accepting constructive criticism
* Focusing on what is best for the community
* Showing empathy towards other community members
Examples of unacceptable behavior by participants include:
* The use of sexualized language or imagery and unwelcome sexual attention or
advances
* Trolling, insulting/derogatory comments, and personal or political attacks
* Public or private harassment
* Publishing others' private information, such as a physical or electronic
address, without explicit permission
* Other conduct which could reasonably be considered inappropriate in a
professional setting
## Our Responsibilities
Project maintainers are responsible for clarifying the standards of acceptable
behavior and are expected to take appropriate and fair corrective action in
response to any instances of unacceptable behavior.
Project maintainers have the right and responsibility to remove, edit, or
reject comments, commits, code, wiki edits, issues, and other contributions
that are not aligned to this Code of Conduct, or to ban temporarily or
permanently any contributor for other behaviors that they deem inappropriate,
threatening, offensive, or harmful.
## Scope
This Code of Conduct applies both within project spaces and in public spaces
when an individual is representing the project or its community. Examples of
representing a project or community include using an official project e-mail
address, posting via an official social media account, or acting as an appointed
representative at an online or offline event. Representation of a project may be
further defined and clarified by project maintainers.
## Enforcement
Instances of abusive, harassing, or otherwise unacceptable behavior may be
reported by contacting the project team at phillip.stevens@gmail.com. All
complaints will be reviewed and investigated and will result in a response that
is deemed necessary and appropriate to the circumstances. The project team is
obligated to maintain confidentiality with regard to the reporter of an incident.
Further details of specific enforcement policies may be posted separately.
Project maintainers who do not follow or enforce the Code of Conduct in good
faith may face temporary or permanent repercussions as determined by other
members of the project's leadership.
## Attribution
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html
[homepage]: https://www.contributor-covenant.org
For answers to common questions about this code of conduct, see
https://www.contributor-covenant.org/faq

View File

@ -0,0 +1,20 @@
Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@ -0,0 +1,120 @@
#include <Arduino_FreeRTOS.h>
#include <semphr.h> // add the FreeRTOS functions for Semaphores (or Flags).
// Declare a mutex Semaphore Handle which we will use to manage the Serial Port.
// It will be used to ensure only one Task is accessing this resource at any time.
SemaphoreHandle_t xSerialSemaphore;
// define two Tasks for DigitalRead & AnalogRead
void TaskDigitalRead( void *pvParameters );
void TaskAnalogRead( void *pvParameters );
// the setup function runs once when you press reset or power the board
void setup() {
// initialize serial communication at 9600 bits per second:
Serial.begin(9600);
// Semaphores are useful to stop a Task proceeding, where it should be paused to wait,
// because it is sharing a resource, such as the Serial port.
// Semaphores should only be used whilst the scheduler is running, but we can set it up here.
if ( xSerialSemaphore == NULL ) // Check to confirm that the Serial Semaphore has not already been created.
{
xSerialSemaphore = xSemaphoreCreateMutex(); // Create a mutex semaphore we will use to manage the Serial Port
if ( ( xSerialSemaphore ) != NULL )
xSemaphoreGive( ( xSerialSemaphore ) ); // Make the Serial Port available for use, by "Giving" the Semaphore.
}
// Now set up two Tasks to run independently.
xTaskCreate(
TaskDigitalRead,
"DigitalRead", // A name just for humans
128, // This stack size can be checked & adjusted by reading the Stack Highwater
NULL, // Parameters for the task
2, // Priority, with 3 (configMAX_PRIORITIES - 1) being the highest, and 0 being the lowest.
NULL); // Task Handle
xTaskCreate(
TaskAnalogRead,
"AnalogRead", // A name just for humans
128, // Stack size
NULL, // Parameters for the task
1, // Priority
NULL); // Task Handle
// Now the Task scheduler, which takes over control of scheduling individual Tasks, is automatically started.
}
void loop()
{
// Empty. Things are done in Tasks.
}
/*--------------------------------------------------*/
/*---------------------- Tasks ---------------------*/
/*--------------------------------------------------*/
void TaskDigitalRead( void *pvParameters __attribute__((unused)) ) // This is a Task.
{
/*
DigitalReadSerial
Reads a digital input on pin pushButton, prints the result to the serial monitor
This example code is in the public domain.
*/
#ifdef BTN_BUILTIN
uint8_t pushButton = BTN_BUILTIN;
#elif (defined(ARDUINO_ELSOMIK))
uint8_t pushButton = P0_0;
#else
uint8_t pushButton = 2;
#endif
// make the pushbutton's pin an input:
pinMode(pushButton, INPUT);
for (;;) // A Task shall never return or exit.
{
// read the input pin:
int buttonState = digitalRead(pushButton);
// See if we can obtain or "Take" the Serial Semaphore.
// If the semaphore is not available, wait 5 ticks of the Scheduler to see if it becomes free.
if ( xSemaphoreTake( xSerialSemaphore, ( TickType_t ) 5 ) == pdTRUE )
{
// We were able to obtain or "Take" the semaphore and can now access the shared resource.
// We want to have the Serial Port for us alone, as it takes some time to print,
// so we don't want it getting stolen during the middle of a conversion.
// print out the state of the button:
Serial.println(buttonState);
xSemaphoreGive( xSerialSemaphore ); // Now free or "Give" the Serial Port for others.
}
vTaskDelay(1); // one tick delay (10ms) in between reads for stability
}
}
void TaskAnalogRead( void *pvParameters __attribute__((unused)) ) // This is a Task.
{
for (;;)
{
// read the input on analog pin 0:
int sensorValue = analogRead(A0);
// See if we can obtain or "Take" the Serial Semaphore.
// If the semaphore is not available, wait 5 ticks of the Scheduler to see if it becomes free.
if ( xSemaphoreTake( xSerialSemaphore, ( TickType_t ) 5 ) == pdTRUE )
{
// We were able to obtain or "Take" the semaphore and can now access the shared resource.
// We want to have the Serial Port for us alone, as it takes some time to print,
// so we don't want it getting stolen during the middle of a conversion.
// print out the value you read:
Serial.println(sensorValue);
xSemaphoreGive( xSerialSemaphore ); // Now free or "Give" the Serial Port for others.
}
vTaskDelay(1); // one tick delay (10ms) in between reads for stability
}
}

Some files were not shown because too many files have changed in this diff Show More