Compare commits

...

81 Commits

Author SHA1 Message Date
9eef73ebb2 Обновить README.md 2024-11-01 05:12:40 +03:00
c472f4e6ae Исправлена опечатка 2024-11-01 05:02:20 +03:00
161a9d30ef пытаюсь смержить 2024-10-17 12:24:05 +07:00
97474b0bba Обновить README.md 2024-10-17 07:35:21 +03:00
96a913bfb9 Обновить README.md 2024-10-17 05:44:58 +03:00
3d7d213531 Обновить README.md 2024-10-17 05:42:44 +03:00
4a5b245a95 Обновить README.md 2024-10-17 05:39:11 +03:00
7b3d050d00 Обновить README.md 2024-10-17 05:37:15 +03:00
d9cfefdc09 Обновить README.md 2024-10-17 05:36:26 +03:00
764a35d4ff Обновить README.md 2024-10-17 05:34:59 +03:00
0a5beed01e Обновить README.md 2024-10-17 05:33:12 +03:00
54feb55aa5 Обновить Instructions.md 2024-10-17 05:24:47 +03:00
73ef03cb02 Обновить Instructions.md 2024-10-17 05:23:56 +03:00
7b9c07026e Обновить README.md 2024-10-17 05:16:07 +03:00
201476ae45 Обновить README.md 2024-10-16 12:40:48 +03:00
3337237bab Обновить README.md 2024-10-16 12:40:16 +03:00
7c05a2bddd Обновить README.md 2024-10-16 10:52:17 +03:00
f4071495c2 Merge branch 'dev_beta' of https://git.lrnrpst.ru/Elron_dev/elbear_arduino_bsp_dev into dev_beta 2024-10-16 14:34:07 +07:00
32f103240e добавлена исправленная библиотека MFRC522 2024-10-16 14:33:25 +07:00
97b857eb5c Обновить README.md 2024-10-16 09:55:28 +03:00
775c6f1da9 Обновить README.md 2024-10-16 09:49:26 +03:00
9f72c43590 Обновить README.md 2024-10-16 09:26:27 +03:00
ea1417450b Обновить README.md 2024-10-16 08:47:40 +03:00
8e69b44932 Обновить README.md 2024-10-16 08:47:11 +03:00
b8344746f9 Обновить README.md 2024-10-16 08:46:36 +03:00
cc7cff834e Обновить README.md 2024-10-16 08:08:41 +03:00
47a3546a9b Обновить README.md 2024-10-16 08:06:45 +03:00
f30c3c8787 Обновить README.md 2024-10-16 08:06:04 +03:00
27d96d7f35 Обновить README.md 2024-10-16 08:02:28 +03:00
68f7fbc21c Обновить README.md 2024-10-16 07:43:53 +03:00
2b82239c59 Обновить README.md 2024-10-16 07:41:47 +03:00
8db0eb96e7 Обновить README.md 2024-10-16 07:38:35 +03:00
92cf55a9c9 Обновить README.md 2024-10-16 07:23:16 +03:00
a42199d6e7 Обновить README.md 2024-10-16 07:20:17 +03:00
ca644b2276 перевела комментарии 2024-10-15 15:18:23 +07:00
878d419808 Merge branch 'dev_beta' of https://git.lrnrpst.ru/Elron_dev/elbear_arduino_bsp_dev into dev_beta 2024-10-15 14:53:17 +07:00
0d8fb21261 добавила возможность отключать сообщения об ошибках. убрала лишнее подтягивание этой функции 2024-10-15 14:52:36 +07:00
af6526926a Обновить README.md 2024-10-15 10:47:47 +03:00
e77ae5935b исправила неточность 2024-10-15 13:43:22 +07:00
1bffc28767 Добавлена библиотека eeprom 2024-10-15 08:54:04 +03:00
033aaf9968 Обновить README.md 2024-10-15 08:28:45 +03:00
6e198069e9 Обновить README.md 2024-10-15 08:15:20 +03:00
58d6f95548 Обновить README.md 2024-10-15 08:04:26 +03:00
a5001c2359 Обновить README.md 2024-10-15 07:59:42 +03:00
98d90f84b8 Обновить README.md 2024-10-15 07:56:39 +03:00
149d485417 Обновить README.md 2024-10-15 07:54:35 +03:00
ad15de32c9 Обновить README.md 2024-10-15 07:43:47 +03:00
9b53c91156 Обновить README.md 2024-10-15 07:40:56 +03:00
87c6642cf5 Загрузить файлы в «docs» 2024-10-15 07:39:07 +03:00
f1d4d7a770 Обновить README.md 2024-10-15 07:28:03 +03:00
be75efb436 Обновить README.md 2024-10-15 07:27:33 +03:00
a08d61401f Обновить Instructions.md 2024-10-15 07:17:12 +03:00
4e806b6fc1 Обновить Instructions.md 2024-10-15 07:16:25 +03:00
7ed3f76aa2 Загрузить файлы в «/» 2024-10-15 07:10:42 +03:00
c0a5927145 добавлена библиотека neoPixels 2024-10-14 15:13:04 +07:00
978661626c в библиотеке заменила некоторые строчки на макросы из wiringLL.h. переименовала обработчик прерываний 2024-10-14 10:21:04 +07:00
47c01383e6 Добавлена библиотека softSerial. Общий обработчик прерываний, а также некоторые обработчики прерываний конкретных модулей перенесены в память ram
- добавлена библиотека softwareSerial. Скорость работы до 57600 включительно и на отправку, и на прием.
- в bootloader добавлена проверка контрольной суммы
- добавлен файл wiringLL.h, в котором собраны некоторые макросы. Этими макросами заменены функции в местах, чувствительных к длительности выполнения кода.
- общие функции обработки прерываний перенесены в ram память для увеличения скорости выполнения. Так же в память ram перенесены функции обработки прерываний модулей WInterrupt (прерывания от gpio), модуля tone, модуля softwareSerial
- добавлен файл-заглушка util/delay.h, необходимый для некоторых библиотек
2024-10-14 05:07:04 +03:00
a7468870fc dev_beta_Servo (#3)
Добавлена библиотека Servo
2024-10-03 08:16:43 +03:00
63217147e5 инициализация структуры spi перенесена в spi.begin, т.к. до этого функции-сеттеры зависали при попытке поработать с элементами этой структуры. Сами сеттеры тоже немного изменены 2024-09-12 14:12:24 +07:00
63e718e83f dev_beta_adcTest (#2)
- добавлена функция изменения разрешения ацп и соответствующие изменения в функции analogRead()
- при измерении ацп накапливает некоторое кол-во измерений и усредняет их
2024-09-12 06:46:31 +03:00
8f0a5b0a94 dev0.2_halRevision (#1)
- Реализация части функций в библиотеках hal перенесена в заголовочный файл, функции определены как inline.
- В модулях Tone, SPI, Wire работа с регистрами вынесена в библиотеку hal или в платозависимые файлы pins_arduino.h, variants.c
- В модуле wiring_analog при отключении работы ШИМ сначала проверяется, включен ли ШИМ на указанной ноге. Если включен, вывод после отключения таймера конфигурируется на вход.

Reviewed-on: #1
2024-09-11 10:50:22 +03:00
7a7c552743 Обновлен README.md 2024-09-11 09:09:57 +03:00
f020720e1f Обновлен README.md 2024-09-11 09:08:40 +03:00
47804d8382 Обновлен bootloader
- Притяжка к питанию на Rx
- Новая команда для full erase
- При получении "мусорных" байтов не реагируем и отключаемся по таймауту
2024-09-10 12:15:53 +03:00
f7923e8bf7 Удалить bootloaders/ace-uno/elbear_fw_bootloader_qpi_xip_cshigh_0.hex 2024-09-10 12:13:40 +03:00
f6fec5f3ca Удалить bootloaders/ace-uno/bootloader.hex 2024-09-10 12:13:34 +03:00
82fbe4939e Merged with dev_beta 2024-09-05 08:49:43 +03:00
a0c4b0ff0e Обновлен файл README.md 2024-09-05 08:47:03 +03:00
0ea1ec5b97 Merged with dev0.2_uart1 2024-09-05 05:48:33 +03:00
87e881aea1 добавила варианты плат по размеру flash 2024-09-03 15:56:58 +07:00
079b3c19bc Добавлен файл Add_board.PNG 2024-09-03 10:55:46 +03:00
8dcd341b77 Удален файл Add_board.PNG 2024-09-03 10:54:25 +03:00
d32773e7b8 Обновила ссылку, надеюсь на финальную версию 2024-09-03 10:54:09 +03:00
687984b356 Merged with dev0.1.0 2024-09-03 08:02:24 +03:00
fa310cfa0d Merged with dev 2024-08-31 14:56:58 +03:00
7e64bd224e Merged with dev 2024-08-25 15:07:33 +03:00
e37ab059a3 Merged with dev 2024-08-23 16:00:00 +03:00
926f03b87f Merged with dev 2024-08-22 16:33:25 +03:00
594ee96ffe Merged with dev 2024-08-22 14:01:22 +03:00
f8c00f6086 Merged with dev 2024-08-21 16:23:14 +03:00
8977dc59e1 Merged with dev 2024-08-21 15:41:11 +03:00
134 changed files with 11280 additions and 992 deletions

2
.gitignore vendored Normal file
View File

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

40
Instructions.md Normal file
View File

@ -0,0 +1,40 @@
## Установка пакета в ArduinoIDE
1. Установите [Arduino IDE](https://www.arduino.cc/en/software).
2. Откройте меню `Файл -> Параметры`.
3. Вставьте данную ссылку в поле "Дополнительные ссылки для Менеджера плат":
`https://elron.tech/files/package_elbear_beta_index.json`
![Add_board](docs/Add_board.PNG)
4. Откройте меню `Инструменты -> Плата -> Менеджер плат...`.
5. В поиске найдите плату `Elbear Ace-Uno`, выберите нужную версию и нажмите кнопку `Установить`.
![Install_board](docs/Install_board.PNG)
6. Процесс установки может занять некоторое время. Результаты установки отобразятся в поле `Вывод`, а так же во всплывающих уведомлениях.
![Installation_process](docs/Installation_process.PNG)
Для загрузки скетчей по USB в ArduinoIDE необходимо, чтобы на плате Elbear Ace-Uno был специальный начальный загрузчик ([elbear_fw_bootloader](https://gitflic.ru/project/elron-tech/elbear_fw_bootloader)). Если он уже есть на плате, можно сразу переходить к работе. Если загрузчика еще нет или необходимо обновить его на плате, ниже описан процесс загрузки. Актуальная версия начального загрузчика входит в состав пакета поддержки, отдельно скачивать его не нужно.
Платы ревизии 1.1.0 готовы к использованию в ArduinoIDE из коробки, так как поставляются с предварительно записанным начальным загрузчиком.
## Запись начального загрузчика через ArduinoIDE
1. Подключите плату Elbear Ace-Uno к ПК через программатор ELJTAG.
2. В ArduinoIDE выберите программатор: `Инструменты -> Программатор -> mik32 uploader`.
3. Для записи начального загрузчика выберите `Инструменты -> Записать Загрузчик`.
![Bootloader](docs/Bootloader.png)
4. При возникновении проблем с загрузкой ознакомьтесь с разделом `Настройка программатора` в [инструкции](https://elron.tech/wp-content/uploads/2024/05/instrukcija-po-pervomu-zapusku.pdf) по первому запуску платы ELBEAR ACE-UNO.
Теперь можно загружать скетчи в плату по USB.
## Начало работы
1. Подключите плату к ПК по USB.
2. Откройте ArduinoIDE и загрузите необходимый скетч. Для начала работы можно воспользоваться готовыми примерами, например - `Файл -> Примеры -> 01.Basics -> Blink`.
![Blink_example](docs/Blink_example.png)
3. Выберите активную плату - `Инструменты -> Плата`.
![Set_board](docs/Set_board.png)
4. Выберите используемый COM порт - `Инструменты -> Порт`.
![Set_port](docs/Set_port.png)
Выбранные плата и порт в ArduinoIDE должны отображаться следующим образом:
![Selected_board_port](docs/Selected_board_port.png)
5. Проверьте скетч, нажав соответствующую кнопку.
![Build_project](docs/Build_project.png)
6. Загрузите полученную прошивку на плату.
![Flash_project](docs/Flash_project.png)
7. При необходимости можно открыть терминал и получать сообщения от платы по интерфейсу Serial. Для этого добавьте в скетч работу с интерфейсом и после загрузки прошивки выберите `Инструменты -> Монитор порта`.
![Monitor](docs/Monitor.png)

95
README.md Normal file
View File

@ -0,0 +1,95 @@
# elbear_arduino_bsp
Пакет поддержки платы Elbear Ace-Uno на базе микроконтроллера MIK32 Амур в среде программирования Arduino IDE.
## Установка пакета в ArduinoIDE
Для установки пакета в параметрах ArduinoIDE необходимо добавить ссылку `https://elron.tech/files/package_elbear_beta_index.json` в поле "Дополнительные ссылки для Менеджера плат".
Подробные шаги по установке и начальной настройке описаны в [инструкции](./Instructions.md).
## Функциональное назначение выводов
![Pinout](docs/pinout.PNG)
## Особенности использования платы Elbear Ace-Uno в ArduinoIDE
### Цифровые выводы
На плате Elbear Ace-Uno доступны встроенные светодиод и кнопка. Для их использования необходимо воспользоваться макросами `LED_BUILTIN` и `BTN_BUILTIN`, передавая их в качестве аргументов функции вместо номера цифрового вывода. Макросу `LED_BUILTIN` соответствует номер вывода D22, а макросу `BTN_BUILTIN` - D23.
В отличие от стандартного функционала Arduino, на плате Elbear Ace-Uno невозможно управлять притяжками цифрового вывода, настроенного на вход, с помощью функции `void digitalWrite(uint32_t PinNumber, uint32_t Val)`. Для включения притяжки к питанию необходимо воспользоваться функцией `void pinMode(PinNumber, INPUT_PULLUP)`.
Для инвертирования состояния цифровых выводов доступна функция `void digitalToggle(uint32_t PinNumber)`.
### Аналоговые выводы
#### АЦП
Встроенный в MIK32 АЦП обладает разрешением 12 бит, однако по умолчанию в Arduino IDE применяется разрешение 10 бит. С помощью функции `void analogReadResolution(uint8_t resolution)` можно изменять разрешение в диапазоне от 1 до 32 бит.
Функция `uint32_t analogRead(uint32_t PinNumber)` возвращает результаты измерения после усреднения по 10 значениям.
#### ШИМ
На плате Elbear Ace-Uno доступны следующие выводы для формирования ШИМ-сигнала: D3, D5, D6, D9, D10, D11. Генерация сигнала осуществляется с помощью 32-битного таймера. Выводы D3, D5, D6, D9 подключены к таймеру 1, выводы D10, D11 подключены к таймеру 2. Выводы, подключенные к одному и тому же таймеру, выдают ШИМ-сигнал одинаковой частоты.
Цифровой вывод D10 не может быть использован для генерации ШИМ, если одновременно активен интерфейс SPI. Это ограничение связано с особенностями работы микроконтроллера. Ограничение не распространяется на использование D10 в качестве цифрового вывода при активном SPI.
По умолчанию частота сформированного ШИМ-сигнала составляет 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)`.
### Прерывания
На плате Elbear Ace-Uno доступно 7 прерываний, настраиваемых функцией `void attachInterrupt(uint8_t interruptNum, void (*userFunc)(void), int mode)`:
|Цифровой вывод|Номер прерывания|
|---------|---------|
|D2|0|
|D3|1|
|D4|2|
|D5|3|
|D8|4|
|D9|5|
|`BTN_BUILTIN`|6|
Для получения номера прерывания по номеру вывода существует функция `int8_t digitalPinToInterrupt(uint32_t digPinNumber)`.
В микроконтроллере MIK32 предусмотрен всего один вектор прерывания. Когда срабатывает прерывание от любого источника, общая функция-обработчик последовательно проверяет все возможные источники и, при необходимости, вызывает соответствующие обработчики конкретных модулей. Поэтому важно, чтобы функции, вызываемые при прерываниях, были небольшими и обеспечивали максимально быстрое завершение обработки. Это позволит избежать задержек и снизит риск пропуска последующих прерываний.
Общая функция-обработчик прерываний располагается в RAM памяти. Это позволяет устранить задержки, связанные с кэшированием при работе из FLASH памяти. Обработчики прерываний, назначаемые на цифровые выводы с помощью функции `void attachInterrupt(uint8_t interruptNum, void (*userFunc)(void), int mode)`, и обработчик прерывания для функции `tone()` так же располагаются в памяти RAM.
### Serial
Для работы доступно два последовательных интерфейса. Нулевой интерфейс доступен на выводах D0, D1, для работы с ним используется экземпляр класса под названием `Serial`. Нулевой интерфейс используется для вывода информации в Монитор порта в Arduino IDE.
Первый интерфейс доступен на выводах D7, D8, используемый экземпляр класса - `Serial1`.
Доступны следующие макросы для настройки режима работы каждого интерфейса в функции `Serial.begin()`: `SERIAL_7N1`, `SERIAL_8N1`, `SERIAL_7N2`, `SERIAL_8N2`, `SERIAL_7E1`, `SERIAL_8E1`, `SERIAL_7E2`, `SERIAL_8E2`, `SERIAL_7O1`, `SERIAL_8O1`, `SERIAL_7O2`, `SERIAL_8O2`. Здесь длина данных - 7 или 8 бит; бит четности - нет(N), четный(E), нечетный(O); стоп бит - 1 или 2 бита.
### Предупреждения об ошибках
Если в скетче используется интерфейс `Serial`, при возникновении ошибок при использовании какой-либо функции из пакета в порт может передаваться сообщение об этой ошибке с пояснением. Например, если в функцию будет передан некорректный номер цифрового вывода, предупреждение об этом появится в подключенном com порту.
По умолчанию вывод предупреждений включен. Если интерфейс `Serial` используется для коммуникации с другим устройством, вывод предупреждений можно отключить. Для этого в самом начале функции `void setup()` необходимо вызвать макрос `DISABLE_ERROR_MESSAGES();`. Вывод предупреждений можно включить обратно, вызвав макрос `ENABLE_ERROR_MESSAGES();` в любом месте программы.
### Библиотеки, входящие в состав пакета
Входящие в состав пакета библиотеки используют периферию микроконтроллера MIK32 Амур и/или адаптированы для работы с ним.
|Библиотека|Описание|Заметки|
|---------|---------|------|
|[SPI](https://docs.arduino.cc/language-reference/en/functions/communication/SPI/)|Библиотека для работы с интерфейсом SPI|Для работы используется встроенный SPI1. Доступные делители частоты - `SPI_CLOCK_DIV4`, `SPI_CLOCK_DIV8`, `SPI_CLOCK_DIV16`, `SPI_CLOCK_DIV32`, `SPI_CLOCK_DIV64`, `SPI_CLOCK_DIV128`, `SPI_CLOCK_DIV256`, обеспечивают частоту работы от 125 кГц до 8 МГц. Скорость работы по умолчанию - 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 сервоприводов|
|[NeoPixel](https://docs.arduino.cc/libraries/adafruit-neopixel/)|Библиотека для работы с адресными светодиодами|Функция, выводящая состояние пикселей на цифровой вывод платы, перенесена в память RAM для корректной работы на MIK32 Амур|
|[MFRC522](https://docs.arduino.cc/libraries/mfrc522/)|Библиотека для работы с RFID картами|Исправлен баг, вызывающий ошибку компиляции в новых компиляторах gcc|
## Протестированные библиотеки
|Библиотека|Описание|
|---------|---------|
|[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 шилд для подключения к Интернету|
# Полезные ссылки
* [Материалы по платам ELBEAR ACE-UNO](https://elron.tech/support/#elbear)
* [Телеграмм-канал компании (обновления по проекту ELBEAR и другим)](https://t.me/elrontech)
При возникновении вопросов или выявлении проблем можно оставить заявку [здесь](https://gitflic.ru/project/elron-tech/elbear_arduino_bsp/issue).

View File

@ -1,6 +1,8 @@
# 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
@ -16,8 +18,56 @@ aceUno8Mb.bootloader.file=ace-uno/bootloader.hex
# build options
aceUno8Mb.build.mcu=MIK32_Amur
aceUno8Mb.build.f_cpu=32000000UL
aceUno8Mb.build.board=ACE_UNO_8Mb
aceUno8Mb.build.board=ACE_UNO_8MB
aceUno8Mb.build.core=arduino
aceUno8Mb.build.variant=standart
aceUno8Mb.build.extra_flags=
aceUno8Mb.build.flags=
##################### Ace-Uno 16 Mb #####################
aceUno16Mb.name=Elbear Ace-Uno 16 Mb
# tool for firmware update
aceUno16Mb.upload.tool=elbear_uploader
aceUno16Mb.upload.protocol=elbear_uploader
aceUno16Mb.upload.maximum_size=16777216
aceUno16Mb.upload.maximum_data_size=16384
# tool for bootloader update
aceUno16Mb.bootloader.tool=mik32_upload
aceUno16Mb.bootloader.tool.default=mik32_upload
aceUno16Mb.bootloader.file=ace-uno/bootloader.hex
# build options
aceUno16Mb.build.mcu=MIK32_Amur
aceUno16Mb.build.f_cpu=32000000UL
aceUno16Mb.build.board=ACE_UNO_16MB
aceUno16Mb.build.core=arduino
aceUno16Mb.build.variant=standart
aceUno16Mb.build.extra_flags=
aceUno16Mb.build.flags=
##################### Ace-Uno 32 Mb #####################
aceUno32Mb.name=Elbear Ace-Uno 32 Mb
# tool for firmware update
aceUno32Mb.upload.tool=elbear_uploader
aceUno32Mb.upload.protocol=elbear_uploader
aceUno32Mb.upload.maximum_size=33554432
aceUno32Mb.upload.maximum_data_size=16384
# tool for bootloader update
aceUno32Mb.bootloader.tool=mik32_upload
aceUno32Mb.bootloader.tool.default=mik32_upload
aceUno32Mb.bootloader.file=ace-uno/bootloader.hex
# build options
aceUno32Mb.build.mcu=MIK32_Amur
aceUno32Mb.build.f_cpu=32000000UL
aceUno32Mb.build.board=ACE_UNO_32MB
aceUno32Mb.build.core=arduino
aceUno32Mb.build.variant=standart
aceUno32Mb.build.extra_flags=
aceUno32Mb.build.flags=

View File

@ -1,15 +1,15 @@
:020000040100F9
:10000000FD62938202400100FD12E39E02FE374131
:10001000000213010100B701000293810100B7152E
:100020000001938505F137160001130606F4B706A3
:100020000001938505FF3716000113060602B70687
:1000300000029386060039A083A2050023A0560083
:1000400091059106E3EAC5FEB7150001938505F415
:1000500037160001130606F4B7060002938606263B
:1000400091059106E3EAC5FEB71500019385050207
:100050003716000113060602B7060002938606262D
:1000600039A083A2050023A0560091059106E3EA7A
:10007000C5FEB70500029385050337060002130687
:10008000062621A023A005009105E3EDC5FEB700DB
:100090000001E780C00AB7000001E780C00AB7008E
:1000A0000001E780007273005010F5BF82800000ED
:100090000001E780C00AB7000001E780C00AB7107E
:1000A0000001E780808473005010F5BF828000005B
:1000B0000000000000000000000000000000000040
:1000C0006F004000197106C20AC40EC612C816CAD3
:1000D0001ACC1ECE22D026D22AD42ED632D836DA48
@ -32,216 +32,230 @@
: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
:1002100093860640558F98C398471367074098C741
:10022000B71708009387074023A0070023A2070001
:1002300023A407001307A008D8C77D57D8CF354798
:1002400098C3D84F935657018D8AE5DE8280B71741
:1002500008009387074023A0070023A2070023A4D8
:10026000070023A607007D57D8CF23A40702B7179E
:100270000500938707C09843F1769386F63F758F04
:1002800098C398471377F7BF98C7B7070500094782
:1002900098D38280B71708009387074088D7D84F34
:1002A000137707046DDF82803707000203234704BA
:1002B000B706000237150800B7450F0023A406044F
:1002C0008147014613050540938515240328C50180
:1002D000B308F30013780802630C080205C2232256
:1002E000170537470F0023A4F60413070724639765
:1002F000E700B707000205472383E700B7170800A8
:1003000093870740C85342054181828005467DBFDF
:100310008507E39DB7FE7DD2B7470F00938707247B
:1003200023A4F60423221705E9B7411106C622C407
:1003300026C2AA84EF00B022E1689388086A0148C7
:100340008147014781460146B70520C72685379476
:100350009800EF003006130414687D1419E40D456D
:10036000B240224492444101828085452685EF00B7
:10037000702005897DF10145E5B7411122C437049C
:100380000002930704008C43B70700804AC0BE9563
:10039000B707000223AEB70206C626C293974501EF
:1003A000130404003709000289E713058900EF00F0
:1003B00090290C40B70400029386C4041306001071
:1003C00013058900EF0070231C4037070002835695
:1003D0008703938707101CC013060010B68763F4C9
:1003E000C600930700101384C4041305F400938718
:1003F00007F01306100F814513040410231CF702A5
:10040000913BA2851385C4043D46EF0010282320AC
:1004100004002322040023240400231604002307DD
:100420000400B240224492440249410182805D713D
:10043000130680028145280886C6293BBD47230C48
:10044000F1008947230EF1003ED2E1779387070838
:100450002C080A85231AF102E52BB64061618280DF
:100460005D71A2C4370400021305840086C6A6C2CB
:10047000CAC0652513058400EF00807D85451305FE
:100480008400EF00300F8D47814463E3A700AA8406
:10049000894513058400EF00F00D937725002A8627
:1004A00089E7136625001376F60FA68513058400E9
:1004B000EF00B00FE1689388086A0148814701475F
:1004C00081460146B705203813058400E525E1681B
:1004D00038009388086A1308000285468147014660
:1004E000B70599EB1305840023040100E125B71536
:1004F00000015146938505FD6800EF0010191309AE
:100500008400832709006C0051463ED085473ED2C7
:100510006810C1673ED4EF005017B70607009C4231
:100520003707F1FF7D17F98F08109CC20D2DB640DB
:1005300026449644064961618280411106C6013B0A
:100540000537B707008073905730B700008082905E
:10055000B2404101828041113707000222C406C621
:100560009307070083C76700854613040700638E5F
:10057000D70009476388E70023030400B240224400
:10058000410182801305000F3133B71708009387AC
:100590000740D84F218B09C7D84F13678700D8CFA2
:1005A000693FD9BF411106C622C426C24AC083474B
:1005B000350005476383E70811472A846389E7000C
:1005C0008DCFB24022449244024941018280B70754
:1005D000000283D7870391C34D3383474400034709
:1005E0005400E2074207BA97370700022320F704B6
:1005F000370700022320F700E9B7370900028354C8
:1006000089030346050093054500370500021305DD
:10061000C5042695EF00700783470400BE94C2040A
: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
:100850003704000213058400C92413058400CD2E3B
:10086000E1689388086A0148814778008546014617
:10087000B705D9EB1305840023060100252EE16896
:100880009388086A01488147014781460146B705B8
:1008900038FF13058400392E9532F9350547AA87AC
:1008A0006305E50209476300E506054591EBB706D8
:1008B0000600DC4A7D771307F73FF98FDCCA014554
:1008C00082807D1719EB0D4582809306004037A783
:1008D000070013070712B7050500905D7D8E75D2DE
:1008E000370606005C4A7D771307F73FF98FD58FEF
:1008F00041115CCA02C613073006B2476359F700BC
:10090000014541018280856693860680C9B7B2475A
:1009100085073EC6DDB791476307F50263EAA70086
:100920008547630AF50489476309F5040545828014
:10093000A147E31DF5FE0947094501A8FD1781EF11
:10094000C8D20D45828005470D45B7A7070093879C
:100950000712B7060500905E798E6DD28A05C98DA3
:100960004111CCD202C613073006B247635AF700D2
:100970000145410182801147C9BF21470145F1B7B7
:10098000B24785073EC6D5B70547AA876305E50286
:1009900009476302E506054591EBB70606009C4A48
:1009A0007D771307F73FF98F9CCA014582807D1739
:1009B00019EB0D4582809306004037A70700130707
:1009C0000712B7050500905D7D8E75D237070600CA
:1009D0001C4B7D761306F63FF18FD58F1CCB8547D8
:1009E0001CCF411102C613073006B2476359F70006
:1009F0000145410182808566938606807DBFB247AE
:100A000085073EC6DDB711C98547630DF50205456B
:100A10008280FD1791EB0D4582800946B7A707003C
:100A200093870712B7060500985E718F7DD3411139
:100A3000C8D602C613073006B2476357F700014510
:100A4000410182800546D9BFB24785073EC6EDB752
:100A5000011126CAB7040600DC4806CE22CC4AC8DB
:100A60004EC652C456C2F19BDCC89C482A89C84570
:100A7000F19B9CC883C7C5012E848A07DCC883C745
:100A8000D5018A079CC8193D0C44AA8A0345440035
:100A900059351848B70705002A8A98C3584808509E
:100AA000D8C3184C98C7CD35AA894850A93F834769
:100AB00004002A8793F6170089E6D44893E62600B7
:100AC000D4C893F6270099E637060600544A93E601
:100AD000160054CA93F6470099E637060600144AF2
:100AE00093E6260014CAA18B99E7B70606009C4A34
:100AF00093E717009CCAF240624423205901232245
:100B00004901232439012326E900D244B249224A6B
:100B1000924A4A85424905618280011106CE22CC63
:100B200002C402C62147B707050037550800D8C7D9
:100B300005448D478A85130505803EC022C2292AB7
:100B4000375508009307C0038A851305058022C224
:100B500022C43EC01122F2406244056182804111EC
:100B600022C406C62A84553F18405C4F93E707010C
:100B70005CCF1C441CCB5C4085CB1C43B7061000EB
:100B8000D58F1CC3144C5C48B240D606CE07D58F17
:100B900083460401C206D58F8346C4012244E2067F
:100BA000D58F1CCF410182801C43B706F0FFFD1694
:100BB000F58FC1BF032305002A8E0325C3011365EA
:100BC0000502232EA3002324C30013962601498285
:100BD0004D8E232603012322C3001396050163547F
:100BE000060299C20545B1CB01476346D700639C15
:100BF00008020D4582803386E7000346060005079C
:100C0000230AC300DDB799C2054505CB8147E3D070
:100C1000D7FE03260E00034546013306F70085077D
:100C20002300A600EDB783270E00FD18DC4F93F7D5
:100C30000702D5DF11656D8D11E18280B7070700CE
:100C400083C7470113F585001D8D3335A0008280D1
:100C50001C414147D8CF8280B7470800938707409F
:100C60002A886304F508B757080093870780630450
:100C7000F50A37470800630DE50A05458280331EF3
:100C80001F013376DE0129C683A3450088431393F1
:100C9000180033966F001346F6FF13F43300718D7E
:100CA00033146400418D88C3638B5302638C030249
:100CB000084303AEC500718D331E6E003365C50158
:100CC00008C38842698E884533156500498E90C2F5
:100CD000850833D51E0145F5324441018280232623
:100CE000C801F9B72324C801E1B7B71605003717C3
:100CF0000500B7170500938646C1130707C1938700
:100D0000C7C083AE05008148054F8D4F914233D552
:100D10001E0105ED8280B716050037170500B717CD
:100D20000500938606C21307C7C1938787C1D1BF49
:100D3000B716050037170500B7170500938686C05C
:100D4000130747C0938707C06DBF331E1F0133765B
:100D5000DE0119E2850865BF411122C635B7E16899
:100D60009388086A01488147014781460146B705D3
:100D7000200689B5011106CEA307010089476393B8
:100D8000F502B7052035E1681307F1009388086A7A
:100D90000148814785460146313DF2400345F10057
:100DA00005618280B7052005F9BF011106CE22CC6E
:100DB00026CA2306B100AA84A306C1004D37E16804
:100DC0009388086A01487C00014789460146B78537
:100DD000200126850964F93B130414717D1419E47C
:100DE0000D45F2406244D2440561828085452685E6
:100DF0005137058965F50145EDB7011106CE22CCC5
:100E000026CA2E844AC8AA84328936C6893FB24788
:100E1000E16822869388086A01480147CA86B78537
:100E200080022685616479331304146A7D1411C429
:100E3000854526858137058975F9F2406244D2449B
:100E4000424905618280011106CE22CC26CA2EC6F7
:100E5000AA8431373246E1689388086A014881479D
:100E600001478146B705802026856164A1331304BC
:100E7000146A7D1411C485452685ED3D058975F9F3
:100E8000F2406244D24405618280B3C7A5008D8BD5
:100E9000B308C500B1E78D4763F4C7049377350005
:100EA0002A87B9EB13F6C8FFB306E64093070002A2
:100EB00063C8D706AE86BA876371C70203A8060067
:100EC0009107910623AE07FFE3EAC7FE9307F6FFFB
:100ED000998FF19B91073E97BE95636617018280BB
:100EE0002A87637E150383C7050005078505A30FC1
:100EF000F7FEE39AE8FE828083C605000507937734
:100F00003700A30FD7FE8505D1DF83C6050005078F
:100F100093773700A30FD7FE8505F9FF61B782806D
:100F2000411122C61304000283A3050083A24500D9
:100F300083AF850003AFC50083AE050103AE450155
:100F400003A3850103A8C501945113074702B30702
:100F5000E640232E77FC232057FE2322F7FF23248D
:100F6000E7FF2326D7FF2328C7FF232A67FE232C6A
:100F700007FF232ED7FE93854502E347F4FAAE869A
:100F8000BA876371C70203A806009107910623AED2
:100F900007FFE3EAC7FE9307F6FF998FF19B9107DE
:100FA0003E97BE956365170132444101828083C735
:100FB000050005078505A30FF7FEE387E8FE83C755
:100FC000050005078505A30FF7FEE392E8FEE9BFDC
:100FD00020000000010000000300000006000000E7
:100FE000EB00000000000000000000000000000016
:100FF000000000800000000000000700000000006A
:1010000000000000000000000000000000000000E0
:1010100000000000000000000000000000000000D0
: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

@ -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,14 @@
#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 Serial(0);
#if SERIAL_PORT_QTY > 1
HardwareSerial Serial1(1);
#endif
// объект класса HardwareSerial для использования в arduino ide
HardwareSerial Serial;
void serialEvent() __attribute__((weak));
bool Serial0_available() __attribute__((weak));
@ -51,39 +56,50 @@ void HardwareSerial::begin(unsigned long baud, uint8_t config)
// leaving the data length selected as 8 bits
// stop bit // stop bit = 1 - everything is zero, don't set anything
if ((config >> 3) & (0x01 == 1)) // stop bit = 2
if (((config >> 3) & 0x01) == 1) // stop bit = 2
reg2config |= UART_CONTROL2_STOP_1_M;
// turn on the receiver and transmitter, apply the parsed config
UART_Init(UART_0, brr, reg1config, reg2config, reg3config);
// Enable level-based interrupts for the EPIC_UART_0 line, we have only receive interrupt enabled
HAL_EPIC_MaskLevelSet(HAL_EPIC_UART_0_MASK);
isInited = true;
if (uartNum == 0)
{
UART_Init(UART_0, brr, reg1config, reg2config, reg3config);
// Enable level-based interrupts for the EPIC_UART_0 line, we have only receive interrupt enabled
HAL_EPIC_MaskLevelSet(HAL_EPIC_UART_0_MASK);
isInited = true;
}
else if (uartNum == 1)
{
UART_Init(UART_1, brr, reg1config, reg2config, reg3config);
// Enable level-based interrupts for the EPIC_UART_1 line, we have only receive interrupt enabled
HAL_EPIC_MaskLevelSet(HAL_EPIC_UART_1_MASK);
isInited = true;
}
}
void HardwareSerial::end()
{
if (isInited)
{
// wait for the data to be sent if necessary
flush();
// disable clock
__HAL_PCC_UART_0_CLK_DISABLE();
HAL_EPIC_MaskLevelClear(HAL_EPIC_UART_0_MASK);
// deinit uart and disable uart interrupt
if (uartNum == 0)
{
// wait for the data to be sent if necessary
UART_WaitDataTranferCompleteFlag(UART_0);
UART_Deinit(UART_0);
HAL_EPIC_MaskLevelClear(HAL_EPIC_UART_0_MASK);
isInited = false;
}
else if (uartNum == 1)
{
// wait for the data to be sent if necessary
UART_WaitDataTranferCompleteFlag(UART_1);
UART_Deinit(UART_1);
HAL_EPIC_MaskLevelClear(HAL_EPIC_UART_1_MASK);
isInited = false;
}
// reconfigure pins to z state
GPIO_InitTypeDef GPIO_InitStruct;
memset(&GPIO_InitStruct, 0, sizeof(GPIO_InitStruct));
GPIO_InitStruct.Pin = (HAL_PinsTypeDef)(GPIO_PIN_5 | GPIO_PIN_6);
GPIO_InitStruct.Mode = HAL_GPIO_MODE_GPIO_INPUT;
GPIO_InitStruct.Pull = HAL_GPIO_PULL_NONE;
HAL_GPIO_Init(GPIO_0, &GPIO_InitStruct);
// reset buffer indices
_rx_buffer_head = _rx_buffer_tail = 0;
isInited = false;
_rx_buffer_head = _rx_buffer_tail = 0;
}
}
@ -101,14 +117,19 @@ int HardwareSerial::availableForWrite(void)
void HardwareSerial::rx_complete_irq(void)
{
// which UART to use
UART_TypeDef* uart = UART_0;
if (uartNum == 1)
uart = UART_1;
// find next index in buffer with upper limit
uint8_t i = (uint8_t)(_rx_buffer_head + 1)%SERIAL_RX_BUFFER_SIZE;
unsigned char c;
// while there is something to receive, put the data into the buffer
// and edit the buffer index
while (!UART_IsRxFifoEmpty(UART_0))
while(!UART_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 +140,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)
{
if (uartNumInt == 0)
{
Serial.rx_complete_irq();
}
else if ((uartNumInt == 1) && (SERIAL_PORT_QTY > 1))
{
Serial1.rx_complete_irq();
}
}
int HardwareSerial::peek(void)
@ -151,8 +179,16 @@ size_t HardwareSerial::write(uint8_t c)
{
if (isInited)
{
UART_WriteByte(UART_0, c);
UART_WaitTransmission(UART_0);
if (uartNum == 0)
{
UART_WriteByte(UART_0, c);
UART_WaitTransmission(UART_0);
}
else if (uartNum == 1)
{
UART_WriteByte(UART_1, c);
UART_WaitTransmission(UART_1);
}
return 1;
}
else
@ -181,6 +217,8 @@ size_t HardwareSerial::write(const uint8_t *buffer, size_t size)
void HardwareSerial::flush()
{
// wait for the data transfer complete
while((UART_0->FLAGS & UART_FLAGS_TC_M) == 0)
;
if (uartNum == 0)
UART_WaitDataTranferCompleteFlag(UART_0);
else if (uartNum == 1)
UART_WaitDataTranferCompleteFlag(UART_1);
}

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,14 @@ 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;
#if SERIAL_PORT_QTY > 1
extern HardwareSerial Serial1;
#endif
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
@ -100,7 +101,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;
@ -124,9 +125,10 @@ void noTone(uint8_t pin)
{
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 +136,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,7 @@
#include "pins_arduino.h"
#include "wiring_digital.h"
#include "WInterrupts.h"
extern void ErrorMsgHandler(const char * msg);
#include "wiring_LL.h"
typedef void (*voidFuncPtr)(void);
@ -18,13 +17,13 @@ static void nothing(void)
// enable global interrupts
void interrupts(void)
{
HAL_IRQ_EnableInterrupts();
GLOBAL_IRQ_ENABLE();
}
// disable global interrupts
void noInterrupts(void)
{
HAL_IRQ_DisableInterrupts();
GLOBAL_IRQ_DISABLE();
}
// we can provide no more than 8 interrupts on gpio at the same time
@ -100,33 +99,26 @@ void detachInterrupt(uint8_t interruptNum)
void disableInterrupt(uint8_t interruptNum)
{
if(interruptNum < EXTERNAL_NUM_INTERRUPTS)
{
int irq_line_num = interruptToGpioIntLine(interruptNum) >> GPIO_IRQ_LINE_S;
// 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;
// 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++)
{
if (HAL_GPIO_LineInterruptState(interruptToGpioIntLine(i)))
if (GPIO_IRQ_LINE_STATE(interruptToGpioIntLine(i)))
intFunc[i]();
}
HAL_GPIO_ClearInterrupts();
GPIO_IRQ_CLEAR_ALL();
}

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,15 @@
#include "board.h"
#include "mik32_hal_pcc.h"
#include "mik32_hal_irq.h"
#include "Arduino.h"
// --------------------- init --------------------- //
// called before setup()
void pre_init(void)
{
// set irq vector to ram region
write_csr(mtvec, 0x02000000);
HAL_Init();
// gpio clock
@ -26,11 +30,15 @@ void post_init(void)
}
// --------------------- 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,6 +1,10 @@
#ifndef _BOARD_H_
#define _BOARD_H_
extern volatile bool use_error_messages;
#define DISABLE_ERROR_MESSAGES() (use_error_messages = false)
#define ENABLE_ERROR_MESSAGES() (use_error_messages = true)
// functions for init called before and after setup()
void pre_init(void) ;
void post_init(void);

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

@ -375,14 +375,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

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

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

@ -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,8 +21,8 @@ SECTIONS {
*crt0.S.o(.text .text.*)
*(.text.smallsysteminit)
*(.text.SmallSystemInit)
. = ORIGIN(rom) + 0xC0;
KEEP(*crt0.S.o(.trap_text))
/*. = ORIGIN(rom) + 0xC0;*/
/*KEEP(*crt0.S.o(.trap_text))*/
*(.text)
*(.text.*)
@ -50,15 +50,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 +86,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;

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

View File

@ -1,33 +1,46 @@
#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(void)
{
// dummy function for case when wire library is not in use
}
void __attribute__((weak)) servo_interrupt_handler(void)
{
// dummy function for case when wire library is not in use
}
// ---------------------------------------------- //
void trap_handler(void)
void __attribute__((noinline, section(".ram_text"), optimize("O3"))) trap_handler (void)
{
// gpio interrupt
if (EPIC_CHECK_GPIO_IRQ())
gpio_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();
// uart0 interrupt
if (EPIC_CHECK_UART_0())
serial_interrupt_handler(0);
// uart1 interrupt
if (EPIC_CHECK_UART_1())
serial_interrupt_handler(1);
// i2c interrupt
if (EPIC_CHECK_I2C_1())
wire_handler_wrapper();
wire_interrupt_handler();
// 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_

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

@ -0,0 +1,65 @@
#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"
// ----------------- 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_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_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)
{
@ -44,11 +58,31 @@ uint32_t analogRead(uint32_t PinNumber)
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));
}
}
else
ErrorMsgHandler("analogRead(): invalid analog pin number");
@ -68,25 +102,8 @@ 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:
@ -120,15 +137,15 @@ void analogWrite(uint32_t PinNumber, uint32_t writeVal)
htimer32_channel.PWM_Invert = TIMER32_CHANNEL_NON_INVERTED_PWM;
htimer32_channel.Mode = TIMER32_CHANNEL_MODE_PWM;
htimer32_channel.CaptureEdge = TIMER32_CHANNEL_CAPTUREEDGE_RISING;
// 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);
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 = true; // if at least one channel is working, say that the module is initialized
pwmIsInited++; // increase inited channels qty
}
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");
@ -165,21 +182,26 @@ It is recommended to turn off the timer in the following order:
*/
void analogWriteStop(uint32_t PinNumber)
{
if (pwmIsInited)
if ((pwmIsInited > 0) && (digitalPinPwmIsOn(PinNumber)))
{
// 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);
// 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,6 +21,7 @@
#include <stdbool.h>
#include <stdint.h>
#include "wiring_private.h"
#define HIGH 0x1
#define LOW 0x0
@ -80,7 +81,8 @@ enum BitOrder
#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

@ -24,8 +24,6 @@
extern "C" {
#endif
extern void ErrorMsgHandler(const char * msg);
// initialization
void pinMode(uint32_t PinNumber, uint32_t PinMode)
{

View File

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

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: 66 KiB

BIN
docs/Build_project.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

BIN
docs/Flash_project.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

BIN
docs/Install_board.PNG Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 65 KiB

BIN
docs/Monitor.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 79 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 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: 61 KiB

BIN
docs/pinout.PNG Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 233 KiB

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 >
T &put(int idx, 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,392 @@
MFRC522
=======
.. image:: https://img.shields.io/maintenance/no/2019.svg
:target: `development`_
.. image:: https://github.com/miguelbalboa/rfid/workflows/PlatformIO%20CI/badge.svg
:target: https://github.com/miguelbalboa/rfid/actions
:alt: GitHub Actions
.. image:: https://img.shields.io/badge/C%2B%2B-11-brightgreen.svg
:target: `compatible ide`_
.. image:: https://img.shields.io/github/release/miguelbalboa/rfid.svg?colorB=green
:target: https://github.com/miguelbalboa/rfid/releases
:alt: Releases
.. image:: https://img.shields.io/badge/ArduinoIDE-%3E%3D1.6.10-lightgrey.svg
:target: `compatible ide`_
Arduino library for MFRC522 and other RFID RC522 based modules.
Read and write different types of Radio-Frequency IDentification (RFID) cards
on your Arduino using a RC522 based reader connected via the Serial Peripheral
Interface (SPI) interface.
For advanced and further development please use library `RFID_MFRC522v2 <https://github.com/OSSLibraries/Arduino_MFRC522v2>`_.
.. _development:
Development
-----------
**The development by owner miguelbalboa has ended**.
**Feature status: complete freeze**; no function or API change.
**Code status: partial freeze**; just fixes/typos or documentation updates; *no* extensions for other boards; *no* new examples.
**Maintenance status: sporadically**.
**Why no further development?**
This library has a long history and is used in many projects. These projects often do not document what version they use. Committing changes might break those old projects and lead to bad experiences (for beginners) and support requests. For these reasons the library is in freeze mode. You can still commit typo, documentation or bug fixes.
.. _before buy:
Before buy
----------
Please notice that there are many sellers (ebay, aliexpress, ..) who sell mfrc522 boards. **The quality of these boards are extremely different.** Some are soldered with wrong/low quality capacitors or fake/defect mfrc522.
**Please consider buying several devices from different suppliers.** So the chance of getting a working device is higher.
If you got a bad board and you can tell us how to detect those boards (silk, chip description, ..), please share your knowledge.
.. _what works and not:
What works and not?
-------------------
* **Works**
#. Communication (Crypto1) with MIFARE Classic (1k, 4k, Mini).
#. Communication (Crypto1) with MIFARE Classic compatible PICCs.
#. Firmware self check of MFRC522.
#. Set the UID, write to sector 0, and unbrick Chinese UID changeable MIFARE cards.
#. Manage the SPI chip select pin (aka SS, SDA)
* **Works partially**
#. Communication with MIFARE Ultralight.
#. Other PICCs (Ntag216).
#. More than 2 modules, require a multiplexer `#191 <https://github.com/miguelbalboa/rfid/issues/191#issuecomment-242631153>`_.
* **Doesn't work**
#. MIFARE DESFire, MIFARE DESFire EV1/EV2, not supported by software.
#. Communication with 3DES or AES, not supported by software.
#. Peer-to-peer (ISO/IEC 18092), not `supported by hardware`_.
#. Communication with smart phone, not `supported by hardware`_.
#. Card emulation, not `supported by hardware`_.
#. Use of IRQ pin. But there is a proof-of-concept example.
#. With Intel Galileo (Gen2) see `#310 <https://github.com/miguelbalboa/rfid/issues/310>`__, not supported by software.
#. Power reduction modes `#269 <https://github.com/miguelbalboa/rfid/issues/269>`_, not supported by software.
#. I2C instead of SPI `#240 <https://github.com/miguelbalboa/rfid/issues/240>`_, not supported by software.
#. UART instead of SPI `#281 <https://github.com/miguelbalboa/rfid/issues/281>`_, not supported by software.
* **Need more?**
#. If software: code it and make a pull request.
#. If hardware: buy a more expensive like PN532 (supports NFC and many more, but costs about $15 and not usable with this library).
.. _compatible ide:
Compatible IDE
--------------
This library works with Arduino IDE 1.6, older versions are **not supported** and will cause compiler errors. The built-in library manager is supported.
If you use your own compiler, you have to enable ``c++11``-support.
.. _compatible boards:
Compatible boards
-----------------
**!!!Only for advanced users!!!**
This library is compatible with the Teensy and ESP8266 if you use the board plugin of the Arduino IDE. Not all examples are available for every board. You also have to change pins. See `pin layout`_.
Some user made some patches/suggestions/ports for other boards:
* Linux: https://github.com/miguelbalboa/rfid/pull/216
* chipKIT: https://github.com/miguelbalboa/rfid/pull/230
* ESP8266 (native): https://github.com/miguelbalboa/rfid/pull/235
* LPCOPen (in C): https://github.com/miguelbalboa/rfid/pull/258
Note that the main target/support of library is still Arduino.
.. _support issue:
Support/issue
-------------
1. First checkout `what works and not`_ and `troubleshooting`_ .
2. It seems to be a hardware issue or you need support to program your project?
Please ask in the official `Arduino forum`_, where you would get a much faster answer than on Github.
3. It seems to be a software issue?
Open an issue on Github.
.. _code style:
Code style
----------
Please use ``fixed integers``, see `stdint.h`_. Why? This library is compatible with different boards which use different architectures (16bit and 32bit.) Unfixed ``int`` variables have different sizes in different environments and may cause unpredictable behaviour.
.. _pin layout:
Pin Layout
----------
The following table shows the typical pin layout used:
+-----------+----------+-----------------------------------------------------------------------------------+
| | PCD | Arduino |
| +----------+-------------+---------+---------+-----------------+-----------+---------+---------+
| | MFRC522 | Uno / 101 | Mega | Nano v3 |Leonardo / Micro | Pro Micro | Yun [4]_| Due |
+-----------+----------+-------------+---------+---------+-----------------+-----------+---------+---------+
| Signal | Pin | Pin | Pin | Pin | Pin | Pin | Pin | Pin |
+===========+==========+=============+=========+=========+=================+===========+=========+=========+
| RST/Reset | RST | 9 [1]_ | 5 [1]_ | D9 | RESET / ICSP-5 | RST | Pin9 | 22 [1]_ |
+-----------+----------+-------------+---------+---------+-----------------+-----------+---------+---------+
| SPI SS | SDA [3]_ | 10 [2]_ | 53 [2]_ | D10 | 10 | 10 | Pin10 | 23 [2]_ |
+-----------+----------+-------------+---------+---------+-----------------+-----------+---------+---------+
| SPI MOSI | MOSI | 11 / ICSP-4 | 51 | D11 | ICSP-4 | 16 | ICSP4 | SPI-4 |
+-----------+----------+-------------+---------+---------+-----------------+-----------+---------+---------+
| SPI MISO | MISO | 12 / ICSP-1 | 50 | D12 | ICSP-1 | 14 | ICSP1 | SPI-1 |
+-----------+----------+-------------+---------+---------+-----------------+-----------+---------+---------+
| SPI SCK | SCK | 13 / ICSP-3 | 52 | D13 | ICSP-3 | 15 | ICSP3 | SPI-3 |
+-----------+----------+-------------+---------+---------+-----------------+-----------+---------+---------+
+-----------+---------------+--------------------------+-------------+
| | ESP8266 | Teensy | 8F328P-U |
| +---------------+--------+--------+--------+-------------+
| | Wemos D1 mini | 2.0 | ++ 2.0 | 3.1 | ALPHA |
+-----------+---------------+--------+--------+--------+-------------+
| Signal | Pin | Pin | Pin | Pin | Pin [5]_ |
+===========+===============+========+========+========+=============+
| RST/Reset | D3 | 7 | 4 | 9 | D9# [1]_ |
+-----------+---------------+--------+--------+--------+-------------+
| SPI SS | D8 | 0 | 20 | 10 | D10# [2]_ |
+-----------+---------------+--------+--------+--------+-------------+
| SPI MOSI | D7 | 2 | 22 | 11 | MOSI / D11# |
+-----------+---------------+--------+--------+--------+-------------+
| SPI MISO | D6 | 3 | 23 | 12 | MISO / D12# |
+-----------+---------------+--------+--------+--------+-------------+
| SPI SCK | D5 | 1 | 21 | 13 | SCK |
+-----------+---------------+--------+--------+--------+-------------+
.. [1] Configurable, typically defined as RST_PIN in sketch/program.
.. [2] Configurable, typically defined as SS_PIN in sketch/program.
.. [3] The SDA pin might be labeled SS on some/older MFRC522 boards.
.. [4] Source: `#111 <https://github.com/miguelbalboa/rfid/issues/111#issuecomment-420433658>`_ .
.. [5] Pin names from the back (empty) side of the board were used as more definitive.
Important: If your micro controller supports multiple SPI interfaces, the library only uses the **default (first) SPI** of the Arduino framework.
.. _hardware:
Hardware
--------
There are three hardware components involved:
1. **Micro Controller**:
* An `Arduino`_ or compatible executing the Sketch using this library.
* Prices vary from USD 7 for clones, to USD 75 for "starter kits" (which
might be a good choice if this is your first exposure to Arduino;
check if such kit already includes the Arduino, Reader, and some Tags).
2. **Proximity Coupling Device (PCD)**:
* The PCD is the actual RFID **Reader** based on the `NXP MFRC522`_ Contactless
Reader Integrated Circuit.
* Readers can be found on `eBay`_ for around USD 5: search for *"rc522"*.
* You can also find them on several web stores. They are often included in
*"starter kits"*, so check your favourite electronics provider as well.
3. **Proximity Integrated Circuit Card (PICC)**:
* The PICC is the RFID **Card** or **Tag** using the `ISO/IEC 14443A`_
interface, for example Mifare or NTAG203.
* One or two might be included with the Reader or *"starter kit"* already.
.. _protocol:
Protocols
---------
1. The micro controller and the reader use SPI for communication.
* The protocol is described in the `NXP MFRC522`_ datasheet.
* See the `Pin Layout`_ section for details on connecting the pins.
2. The reader and the tags communicate using a 13.56 MHz electromagnetic field.
* The protocol is defined in ISO/IEC 14443-3:2011 Part 3 Type A.
* Details are found in chapter 6 *"Type A Initialization and anticollision"*.
* See http://wg8.de/wg8n1496_17n3613_Ballot_FCD14443-3.pdf for a free version
of the final draft (which might be outdated in some areas).
* The reader does not support ISO/IEC 14443-3 Type B.
.. _security:
Security
--------
* The **UID** of a card **can not be used** as an unique identification for security related projects. Some Chinese cards allow to change the UID which means you can easily clone a card. For projects like *access control*, *door opener* or *payment systems* you **must implement** an **additional security mechanism** like a password or normal key.
* This library only supports crypto1-encrypted communication. Crypto1 has been known as `broken`_ for a few years, so it does NOT offer ANY security, it is virtually unencrypted communication. **Do not use it for any security related applications!**
* This library does not offer 3DES or AES authentication used by cards like the Mifare DESFire, it may be possible to be implemented because the datasheet says there is support. We hope for pull requests :).
.. _troubleshooting:
Troubleshooting
---------------
* **I don't get input from reader** or **WARNING: Communication failure, is the MFRC522 properly connected?**
#. Check your physical connection, see `Pin Layout`_ .
#. Check your pin settings/variables in the code, see `Pin Layout`_ .
#. Check your pin header soldering. Maybe you have cold solder joints.
#. Check your power supply. Maybe add a capacitor between 3.3V and GND to stabilize the power #560, sometimes an additional delay after `PCD_Init()` can help.
#. Check voltage. Most breakouts work with 3.3V.
#. SPI only works with 3.3V, most breakouts seem 5V tolerant, but try a level shifter.
#. SPI does not like long connections. Try shorter connections.
#. SPI does not like prototyping boards. Try soldered connections.
#. According to reports #101, #126 and #131, there may be a problem with the soldering on the MFRC522 breakout. You could fix this on your own.
* **Firmware Version: 0x12 = (unknown) or other random values**
#. The exact reason of this behaviour is unknown.
#. Some boards need more time after `PCD_Init()` to be ready. As workaround add a `delay(4)` directly after `PCD_Init()` to give the PCD more time.
#. If this sometimes appears, a bad connection or power source is the reason.
#. If the firmware version is reported permanent, it is very likely that the hardware is a fake or has a defect. Contact your supplier.
* **Sometimes I get timeouts** or **sometimes tag/card does not work.**
#. Try the other side of the antenna.
#. Try to decrease the distance between the MFRC522 and your tag.
#. Increase the antenna gain per firmware: ``mfrc522.PCD_SetAntennaGain(mfrc522.RxGain_max);``
#. Use better power supply.
#. Hardware may be corrupted, most products are from china and sometimes the quality is really poor. Contact your seller.
* **My tag/card doesn't work.**
#. Distance between antenna and token too large (>1cm).
#. You got the wrong type PICC. Is it really 13.56 MHz? Is it really a Mifare Type A?
#. NFC tokens are not supported. Some may work.
#. Animal RFID tags are not supported. They use a different frequency (125 kHz).
#. Hardware may be corrupted, most products are from china and sometimes the quality is really poor. Contact your seller.
#. Newer versions of Mifare cards like DESFire/Ultralight maybe not work according to missing authentication, see `security`_ or different `protocol`_.
#. Some boards bought from Chinese manufactures do not use the best components and this can affect the detection of different types of tag/card. In some of these boards, the L1 and L2 inductors do not have a high enough current so the signal generated is not enough to get Ultralight C and NTAG203 tags to work, replacing those with same inductance (2.2uH) but higher operating current inductors should make things work smoothly. Also, in some of those boards the harmonic and matching circuit needs to be tuned, for this replace C4 and C5 with 33pf capacitors and you are all set. (Source: `Mikro Elektronika`_)
* **My mobile phone doesn't recognize the MFRC522** or **my MFRC522 can't read data from other MFRC522**
#. Card simulation is not supported.
#. Communication with mobile phones is not supported.
#. Peer to peer communication is not supported.
* **I can only read the card UID.**
#. Maybe the `AccessBits` have been accidentally set and now an unknown password is set. This can not be reverted.
#. Probably the card is encrypted. Especially official cards like public transport, university or library cards. There is *no* way to get access with this library.
* **Where do I get more information?**
#. For general support from the community, see `Arduino Forum <https://forum.arduino.cc/>`_ or `StackOverflow <https://stackoverflow.com/questions/tagged/mifare>`_ .
#. Visit the `community mfrc522 wiki <https://github.com/miguelbalboa/rfid/wiki>`_ .
#. Read the datasheets!
#. Your preferred search engine.
* **I need more features.**
#. If software: code it and make a pull request.
#. If hardware: buy a more expensive chip like the PN532 (supports NFC and many more, but costs about $15)
.. _license:
License
-------
This is free and unencumbered software released into the public domain.
Anyone is free to copy, modify, publish, use, compile, sell, or
distribute this software, either in source code form or as a compiled
binary, for any purpose, commercial or non-commercial, and by any
means.
In jurisdictions that recognize copyright laws, the author or authors
of this software dedicate any and all copyright interest in the
software to the public domain. We make this dedication for the benefit
of the public at large and to the detriment of our heirs and
successors. We intend this dedication to be an overt act of
relinquishment in perpetuity of all present and future rights to this
software under copyright law.
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 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.
For more information, please refer to https://unlicense.org/
.. _dependency:
Dependency
----------
* **Arduino.h**
* From: Arduino IDE / target specific
* License: (target: Arduino) GNU Lesser General Public License 2.1
* **SPI.h**
* From: Arduino IDE / target specific
* License: (target: Arduino) GNU Lesser General Public License 2.1
* **stdint.h**
* From: Arduino IDE / Compiler and target specific
* License: different
History
-------
The MFRC522 library was first created in Jan 2012 by Miguel Balboa (from
http://circuitito.com) based on code by Dr. Leong (from http://B2CQSHOP.com)
for *"Arduino RFID module Kit 13.56 Mhz with Tags SPI W and R By COOQRobot"*.
It was translated into English and rewritten/refactored in the fall of 2013
by Søren Thing Andersen (from http://access.thing.dk).
It has been extended with functionality to alter sector 0 on Chinese UID changeable MIFARE card in Oct 2014 by Tom Clement (from http://tomclement.nl).
Maintained by miguelbalboa until 2016.
Maintained by Rotzbua from 2016 until 2022.
.. _arduino: https://arduino.cc/
.. _ebay: https://www.ebay.com/
.. _iso/iec 14443a: https://en.wikipedia.org/wiki/ISO/IEC_14443
.. _iso/iec 14443-3\:2011 part 3:
.. _nxp mfrc522: https://www.nxp.com/documents/data_sheet/MFRC522.pdf
.. _broken: https://eprint.iacr.org/2008/166
.. _supported by hardware: https://web.archive.org/web/20151210045625/http://www.nxp.com/documents/leaflet/939775017564.pdf
.. _Arduino forum: https://forum.arduino.cc
.. _stdint.h: https://en.wikibooks.org/wiki/C_Programming/C_Reference/stdint.h
.. _Mikro Elektronika: https://forum.mikroe.com/viewtopic.php?f=147&t=64203

View File

@ -0,0 +1,24 @@
This is free and unencumbered software released into the public domain.
Anyone is free to copy, modify, publish, use, compile, sell, or
distribute this software, either in source code form or as a compiled
binary, for any purpose, commercial or non-commercial, and by any
means.
In jurisdictions that recognize copyright laws, the author or authors
of this software dedicate any and all copyright interest in the
software to the public domain. We make this dedication for the benefit
of the public at large and to the detriment of our heirs and
successors. We intend this dedication to be an overt act of
relinquishment in perpetuity of all present and future rights to this
software under copyright law.
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 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.
For more information, please refer to <https://unlicense.org/>

View File

@ -0,0 +1,199 @@
-- Add changes to unreleased tag until we make a release.
xxxxx , v1.4.12
30 Dec 2023, v1.4.11
- fix: documentation
1 Nov 2021 , v1.4.10
- fix: timeout on Non-AVR boards; feat: Use yield() in busy wait loops @greezybacon
- fix PCD problem after selftest
31 Jul 2021, v1.4.9
- Removed example AccessControl
- Updated docs
30 Dec 2020, v1.4.8
- Fixed wrong SPI clock speed.
25 Jun 2020, v1.4.7
- Fixed typos
- Moved PICC memory layout to /doc
21 Jan 2020, v1.4.6
- Library in freeze mode, no new features, no new examples, just bugfixes to keep compatibility for old projects
- Updated documentation
- Removed deprecation warnings due code freeze
12 Jun 2019, v1.4.5
- Library in freeze mode, no new features, no new examples, just bugfixes to keep compatibility for old projects
- Updated README
31 Mar 2019, v1.4.4
- Fixed example
- Fixed UnbrickUidSector
- Updated comments
- Removed teensy from CI and PlatformIO config
27 Oct 2018, v1.4.3
- Added counterfeit detection and hint about bad boards
- Improved hardware based reset
04 Oct 2018, v1.4.2
- Fixed keywords
- Changed development status of library
04 Oct 2018, v1.4.1
- Replaced UINT8_MAX by UNUSED_PIN
- Replaced default value NULL for pointer with correct nullptr
- Added pin layout for wemos d1 mini @mmone
- Added alternative fritzing layout for mfrc522 reader @jose1711
- Added soft power control functions @Bill2462
- Fixed typo in example ReadAndWrite.ino @Drachenfrucht1
- Fixed grammar @KiddieD
- Fixed infinite loop in example AccessControl.ino @mads256c
- Fixed 0-index key ID equals to 0 fails in AccessControl.ino @thoaitrieu
- Changed type boolean to bool for a more common use @Rotzbua
- Fixed wrong var names in PICC_Select MFRC522.cpp @tuyethoa08041997
- Fixed hang PCD_Init() on non-arduino boards @heziegl
- Fixed possible infinite loop PCD_Reset() @psgreco
- And many thanks to all other contributors
13 Apr 2018, v1.4.0
- Replaced UINT8_MAX by UNUSED_PIN @Rotzbua
- Fixed hang PCD_Init() on non-arduino boards @heziegl
- deprecate MIFARE_SetAccessBits @Rotzbua
- IMPORTANT: v1.4.X will be last version under license "unlicense"
22 Mar 2017, v1.3.6
- Added deprecate and compiler warnings @Rotzbua
8 Apr 2017, v1.3.5
- Updated "AccessControl.ino", bugs fixed and alternate wipe button polling method without using other library @beyondszine reviewed by @omersiar
- Updated README notice about port for esp8266 @mmmmar
7 Apr 2017, v1.3.4
- Added new example "rfid_read_personal_data.ino" @ryand1011
- Updated example "rfid_write_personal_data.ino" code style to Arduino IDE @Rotzbua
- Removed (temp.) Teensy from travis build script because fails @Rotzbua
26 Mar 2017, v1.3.3
- Fixed bugs in MFRC522Extended, now should work with Desfire.h from JPG-Consulting @Rotzbua
- Fixed UINT8_MAX error @Rotzbua
15 Mar 2017, v1.3.2
- Added ESP8266 to library.properties
15 Mar 2017, v1.3.1
- Fixed compiler warning in MFRC522Extended @Rotzbua
- Removed unused function @Rotzbua
13 Mar 2017, v1.3.0
- Warning: Source has moved to folder src!
- Added addtional class to support ISO/IEC 14443-4 PICCs @JPG-Consulting
- Added RATS (Request for Answer To Select) @JPG-Consulting
- More information see https://github.com/miguelbalboa/rfid/pull/271 @JPG-Consulting
13 Mar 2017, v1.2.1
- Removed need for reset pin #275 @tkoester
- Added SPI speed option + Various minor changes #276 @tuyethoa08041997
- Updated documentation, travis build script and small code change @Rotzbua
3 Jan 2017, v1.2.0
- Warning: This version introduce usage of stdint.h, usage of not well defined int types are abandoned.
Interface has changed: e.g. long -> int32_t
@Rotzbua
- Removed problematic example examples/servo_motor/servo_motor.ino @omersiar
- Added examples/AccessControl/AccessControl.ino @omersiar
- Fixed minor issues reported in #211 @omersiar
- Added bad components hint to README @danielcbit
- Fixed selftest @surr
- Fixed auth problem with long UIDs @surr
26 Aug 2016, v1.1.9
- Warning: Only Arduino IDE version 1.6 is supported, please update your IDE to 1.6 to use this Library.
- Added ESP8266 platform support @Rotzbua
- Changed README.rst content to show more info @Rotzbua
- Minor Changes to examples/ReadUidMultiReader/ReadUidMultiReader.ino example @Rotzbua
11 Feb 2016, v1.1.8
- Added examples/MinimalInterrupt/MinimalInterrupt.ino example, Interrupt example @lmmeng
- Added .gitignore file allows the project to be more easily used as a subproject. @BenWiederhake
- Added Added Teensy 2.0 & Tensy++ 2.0 pinouts to README.rst @jkutianski
16 Jan 2016, v1.1.7
- README.rst Spelling and Grammar Tweak @cuthbertnibbles
- Added examples/servo_motor/servo_motor.ino example, Arduino RFID Access Control with a Servo Motor @techied
- Added examples/RFID-Cloner/RFID-Cloner.ino Copy from rfid cards with standard authentication @stefanblommaert
- Fix compile error at examples/RFID-Cloner/RFID-Cloner.ino, using MFRC522:::PICC_Type, @Rotzbua
06 Jan 2016, v1.1.6
- Fixed compilation error for examples/ReadNUID/ReadNUID.ino example. @Rotzbua
04 Jan 2016, v1.1.5
- Use settings functions on SPI libraries, setSPIConfig was deleted, now the library use SPI.beginTransaction() and SPI.endTransaction() @sophiekovalevsky
- Added examples/ReadNUID/ReadNUID.ino example, showing how to read new NUID from a PICC to serial. @sophiekovalevsky
03 Jan 2016, v1.1.4
- Added Authentication with Ntag 213,215,216 returns the pACK MFRC522::PCD_NTAG216_AUTH @Gargantuanman
- Starting to use versions http://semver.org/
- Continuous Integration @ivankravets
- functions return MFRC522::StatusCode and MFRC522::PICC_Type instead of generic byte @rotzbua
- removed int-values of MFRC522::StatusCode and MFRC522::PICC_Type @rotzbua
05 Dec 2015
- recognize infineon cards correctly @mayatforest
- added multi reader support, see example @lmmeng
10 Nov 2014
- Updated the changelog.
- Added makefile.
24 Oct 2014
- Added PlatformIO-based manifest file.
17 Jul 2014
- Written documentation for the library.
- Added rfid_default_keys example.
11 Jun 2014
- Updated example: ReadAndWrite.
14 Apr 2014
- Updated examples: DumpInfo, MifareClassicValueBlock, and ReadAndWrite.
12 Feb 2014
- Fixed resetPowerDownPin initial state.
29 Jan 2014
- Fixed chipSelectPin initial state.
30 Nov 2013
- Examples put in their own folders.
- Updated the keywords.txt file.
12 Nov 2013
- Updated examples: DumpInfo, MifareClassicValueBlock, and ReadAndWrite.
20 Oct 2013
- All constants, functions and parameters are now commented in English.
- Code refactored, most function names have changed.
- Support ISO-14443-3 anti collision and 4/7/10 byte UIDs (cascade levels).
- Added functions for MIFARE Classic Decrement/Increment/Restore/Transfer
and MIFARE Ultralight Write.
- New examples written.
19 Oct 2013
- Renamed library from RFID to MFRC522 (RFID seemed to generic).
- Register names changed to comply with datasheet.
- Global defines moved into class.
24 Sep 2013
- Turn off encryption when tag is halted.
27 Jan 2013
- Added README and small TODO list.
- Added example to show Serial on LCD display.
09 Sep 2012
- Initial commit to GitHub.

View File

@ -0,0 +1,67 @@
# Memory Layout of common PICCs
To read and write from MIFARE PICCs, the MIFARE protocol is used after the PICC has been selected.
## Datasheet References
The **MIFARE Classic** chips and protocol is described in the datasheets:
* 1K: https://www.mouser.com/ds/2/302/MF1S503x-89574.pdf
* 4K: https://datasheet.octopart.com/MF1S7035DA4,118-NXP-Semiconductors-datasheet-11046188.pdf
* Mini: http://www.idcardmarket.com/download/mifare_S20_datasheet.pdf
The **MIFARE Ultralight** chip and protocol is described in the datasheets:
* Ultralight: https://www.nxp.com/documents/data_sheet/MF0ICU1.pdf
* Ultralight C: https://www.nxp.com/documents/short_data_sheet/MF0ICU2_SDS.pdf
## MIFARE Classic 1K (MF1S503x)
Has 16 sectors4 blocks/sector16 bytes/block = 1024 bytes.
The blocks are numbered 0-63.
Block 3 in each sector is the Sector Trailer. See https://www.mouser.com/ds/2/302/MF1S503x-89574.pdf sections 8.6 and 8.7:
Bytes 0-5: Key A
Bytes 6-8: Access Bits
Bytes 9: User data
Bytes 10-15: Key B (or user data)
Block 0 is read-only manufacturer data.
To access a block, an authentication using a key from the block's sector must be performed first.
Example: To read from block 10, first authenticate using a key from sector 3 (blocks 8-11).
All keys are set to FFFFFFFFFFFFh at chip delivery.
Warning: Please read section 8.7 "Memory Access". It includes this text: if the PICC detects a format violation the whole sector is irreversibly blocked.
To use a block in "value block" mode (for Increment/Decrement operations) you need to change the sector trailer. Use PICC_SetAccessBits() to calculate the bit patterns.
## MIFARE Classic 4K (MF1S703x):
Has (32 sectors4 blocks/sector + 8 sectors16 blocks/sector)16 bytes/block = 4096 bytes.
The blocks are numbered 0-255.
The last block in each sector is the Sector Trailer like above.
## MIFARE Classic Mini (MF1 IC S20):
Has 5 sectors4 blocks/sector16 bytes/block = 320 bytes.
The blocks are numbered 0-19.
The last block in each sector is the Sector Trailer like above.
## MIFARE Ultralight (MF0ICU1):
Has 16 pages of 4 bytes = 64 bytes.
Pages 0 + 1 is used for the 7-byte UID.
Page 2 contains the last check digit for the UID, one byte manufacturer internal data, and the lock bytes (see https://www.nxp.com/documents/data_sheet/MF0ICU1.pdf section 8.5.2)
Page 3 is OTP, One Time Programmable bits. Once set to 1 they cannot revert to 0.
Pages 4-15 are read/write unless blocked by the lock bytes in page 2.
## MIFARE Ultralight C (MF0ICU2):
Has 48 pages of 4 bytes = 192 bytes.
Pages 0 + 1 is used for the 7-byte UID.
Page 2 contains the last check digit for the UID, one byte manufacturer internal data, and the lock bytes (see https://www.nxp.com/documents/data_sheet/MF0ICU1.pdf section 8.5.2)
Page 3 is OTP, One Time Programmable bits. Once set to 1 they cannot revert to 0.
Pages 4-39 are read/write unless blocked by the lock bytes in page 2.
Page 40 Lock bytes
Page 41 16 bit one way counter
Pages 42-43 Authentication configuration
Pages 44-47 Authentication key

Binary file not shown.

After

Width:  |  Height:  |  Size: 343 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 162 KiB

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,112 @@
/*
* --------------------------------------------------------------------------------------------------------------------
* Example to change UID of changeable MIFARE card.
* --------------------------------------------------------------------------------------------------------------------
* This is a MFRC522 library example; for further details and other examples see: https://github.com/miguelbalboa/rfid
*
* This sample shows how to set the UID on a UID changeable MIFARE card.
*
* @author Tom Clement
* @license Released into the public domain.
*
* Typical pin layout used:
* -----------------------------------------------------------------------------------------
* MFRC522 Arduino Arduino Arduino Arduino Arduino
* Reader/PCD Uno/101 Mega Nano v3 Leonardo/Micro Pro Micro
* Signal Pin Pin Pin Pin Pin Pin
* -----------------------------------------------------------------------------------------
* RST/Reset RST 9 5 D9 RESET/ICSP-5 RST
* SPI SS SDA(SS) 10 53 D10 10 10
* SPI MOSI MOSI 11 / ICSP-4 51 D11 ICSP-4 16
* SPI MISO MISO 12 / ICSP-1 50 D12 ICSP-1 14
* SPI SCK SCK 13 / ICSP-3 52 D13 ICSP-3 15
*
* More pin layouts for other boards can be found here: https://github.com/miguelbalboa/rfid#pin-layout
*/
#include <SPI.h>
#include <MFRC522.h>
#define RST_PIN 9 // Configurable, see typical pin layout above
#define SS_PIN 10 // Configurable, see typical pin layout above
MFRC522 mfrc522(SS_PIN, RST_PIN); // Create MFRC522 instance
/* Set your new UID here! */
#define NEW_UID {0xDE, 0xAD, 0xBE, 0xEF}
MFRC522::MIFARE_Key key;
void setup() {
Serial.begin(9600); // Initialize serial communications with the PC
while (!Serial); // Do nothing if no serial port is opened (added for Arduinos based on ATMEGA32U4)
SPI.begin(); // Init SPI bus
mfrc522.PCD_Init(); // Init MFRC522 card
Serial.println(F("Warning: this example overwrites the UID of your UID changeable card, use with care!"));
// Prepare key - all keys are set to FFFFFFFFFFFFh at chip delivery from the factory.
for (byte i = 0; i < 6; i++) {
key.keyByte[i] = 0xFF;
}
}
// Setting the UID can be as simple as this:
//void loop() {
// byte newUid[] = NEW_UID;
// if ( mfrc522.MIFARE_SetUid(newUid, (byte)4, true) ) {
// Serial.println("Wrote new UID to card.");
// }
// delay(1000);
//}
// But of course this is a more proper approach
void loop() {
// Reset the loop if no new card present on the sensor/reader. This saves the entire process when idle. And if present, select one.
if ( ! mfrc522.PICC_IsNewCardPresent() || ! mfrc522.PICC_ReadCardSerial() ) {
delay(50);
return;
}
// Now a card is selected. The UID and SAK is in mfrc522.uid.
// Dump UID
Serial.print(F("Card UID:"));
for (byte i = 0; i < mfrc522.uid.size; i++) {
Serial.print(mfrc522.uid.uidByte[i] < 0x10 ? " 0" : " ");
Serial.print(mfrc522.uid.uidByte[i], HEX);
}
Serial.println();
// Dump PICC type
// MFRC522::PICC_Type piccType = mfrc522.PICC_GetType(mfrc522.uid.sak);
// Serial.print(F("PICC type: "));
// Serial.print(mfrc522.PICC_GetTypeName(piccType));
// Serial.print(F(" (SAK "));
// Serial.print(mfrc522.uid.sak);
// Serial.print(")\r\n");
// if ( piccType != MFRC522::PICC_TYPE_MIFARE_MINI
// && piccType != MFRC522::PICC_TYPE_MIFARE_1K
// && piccType != MFRC522::PICC_TYPE_MIFARE_4K) {
// Serial.println(F("This sample only works with MIFARE Classic cards."));
// return;
// }
// Set new UID
byte newUid[] = NEW_UID;
if ( mfrc522.MIFARE_SetUid(newUid, (byte)4, true) ) {
Serial.println(F("Wrote new UID to card."));
}
// Halt PICC and re-select it so DumpToSerial doesn't get confused
mfrc522.PICC_HaltA();
if ( ! mfrc522.PICC_IsNewCardPresent() || ! mfrc522.PICC_ReadCardSerial() ) {
return;
}
// Dump the new memory contents
Serial.println(F("New UID and contents:"));
mfrc522.PICC_DumpToSerial(&(mfrc522.uid));
delay(2000);
}

View File

@ -0,0 +1,69 @@
/*
* --------------------------------------------------------------------------------------------------------------------
* Example sketch/program showing how to read data from a PICC to serial.
* --------------------------------------------------------------------------------------------------------------------
* This is a MFRC522 library example; for further details and other examples see: https://github.com/miguelbalboa/rfid
*
* Example sketch/program showing how to read data from a PICC (that is: a RFID Tag or Card) using a MFRC522 based RFID
* Reader on the Arduino SPI interface.
*
* When the Arduino and the MFRC522 module are connected (see the pin layout below), load this sketch into Arduino IDE
* then verify/compile and upload it. To see the output: use Tools, Serial Monitor of the IDE (hit Ctrl+Shft+M). When
* you present a PICC (that is: a RFID Tag or Card) at reading distance of the MFRC522 Reader/PCD, the serial output
* will show the ID/UID, type and any data blocks it can read. Note: you may see "Timeout in communication" messages
* when removing the PICC from reading distance too early.
*
* If your reader supports it, this sketch/program will read all the PICCs presented (that is: multiple tag reading).
* So if you stack two or more PICCs on top of each other and present them to the reader, it will first output all
* details of the first and then the next PICC. Note that this may take some time as all data blocks are dumped, so
* keep the PICCs at reading distance until complete.
*
* @license Released into the public domain.
*
* Typical pin layout used:
* -----------------------------------------------------------------------------------------
* MFRC522 Arduino Arduino Arduino Arduino Arduino
* Reader/PCD Uno/101 Mega Nano v3 Leonardo/Micro Pro Micro
* Signal Pin Pin Pin Pin Pin Pin
* -----------------------------------------------------------------------------------------
* RST/Reset RST 9 5 D9 RESET/ICSP-5 RST
* SPI SS SDA(SS) 10 53 D10 10 10
* SPI MOSI MOSI 11 / ICSP-4 51 D11 ICSP-4 16
* SPI MISO MISO 12 / ICSP-1 50 D12 ICSP-1 14
* SPI SCK SCK 13 / ICSP-3 52 D13 ICSP-3 15
*
* More pin layouts for other boards can be found here: https://github.com/miguelbalboa/rfid#pin-layout
*/
#include <SPI.h>
#include <MFRC522.h>
#define RST_PIN 9 // Configurable, see typical pin layout above
#define SS_PIN 10 // Configurable, see typical pin layout above
MFRC522 mfrc522(SS_PIN, RST_PIN); // Create MFRC522 instance
void setup() {
Serial.begin(9600); // Initialize serial communications with the PC
while (!Serial); // Do nothing if no serial port is opened (added for Arduinos based on ATMEGA32U4)
SPI.begin(); // Init SPI bus
mfrc522.PCD_Init(); // Init MFRC522
delay(4); // Optional delay. Some board do need more time after init to be ready, see Readme
mfrc522.PCD_DumpVersionToSerial(); // Show details of PCD - MFRC522 Card Reader details
Serial.println(F("Scan PICC to see UID, SAK, type, and data blocks..."));
}
void loop() {
// Reset the loop if no new card present on the sensor/reader. This saves the entire process when idle.
if ( ! mfrc522.PICC_IsNewCardPresent()) {
return;
}
// Select one of the cards
if ( ! mfrc522.PICC_ReadCardSerial()) {
return;
}
// Dump debug info about the card; PICC_HaltA() is automatically called
mfrc522.PICC_DumpToSerial(&(mfrc522.uid));
}

View File

@ -0,0 +1,55 @@
/*
* --------------------------------------------------------------------------------------------------------------------
* Example sketch/program to fix a broken UID changeable MIFARE cards.
* --------------------------------------------------------------------------------------------------------------------
* This is a MFRC522 library example; for further details and other examples see: https://github.com/miguelbalboa/rfid
*
* This sample shows how to fix a broken UID changeable MIFARE cards that have a corrupted sector 0.
*
* @author Tom Clement
* @license Released into the public domain.
*
* Typical pin layout used:
* -----------------------------------------------------------------------------------------
* MFRC522 Arduino Arduino Arduino Arduino Arduino
* Reader/PCD Uno/101 Mega Nano v3 Leonardo/Micro Pro Micro
* Signal Pin Pin Pin Pin Pin Pin
* -----------------------------------------------------------------------------------------
* RST/Reset RST 9 5 D9 RESET/ICSP-5 RST
* SPI SS SDA(SS) 10 53 D10 10 10
* SPI MOSI MOSI 11 / ICSP-4 51 D11 ICSP-4 16
* SPI MISO MISO 12 / ICSP-1 50 D12 ICSP-1 14
* SPI SCK SCK 13 / ICSP-3 52 D13 ICSP-3 15
*
* More pin layouts for other boards can be found here: https://github.com/miguelbalboa/rfid#pin-layout
*/
#include <SPI.h>
#include <MFRC522.h>
#define RST_PIN 9 // Configurable, see typical pin layout above
#define SS_PIN 10 // Configurable, see typical pin layout above
MFRC522 mfrc522(SS_PIN, RST_PIN); // Create MFRC522 instance
MFRC522::MIFARE_Key key;
void setup() {
Serial.begin(9600); // Initialize serial communications with the PC
while (!Serial); // Do nothing if no serial port is opened (added for Arduinos based on ATMEGA32U4)
SPI.begin(); // Init SPI bus
mfrc522.PCD_Init(); // Init MFRC522 card
Serial.println(F("Warning: this example clears your mifare UID, use with care!"));
// Prepare key - all keys are set to FFFFFFFFFFFFh at chip delivery from the factory.
for (byte i = 0; i < 6; i++) {
key.keyByte[i] = 0xFF;
}
}
void loop() {
if ( mfrc522.MIFARE_UnbrickUidSector(false) ) {
Serial.println(F("Cleared sector 0, set UID to 1234. Card should be responsive again now."));
}
delay(1000);
}

View File

@ -0,0 +1,321 @@
/**
* ----------------------------------------------------------------------------
* This is a MFRC522 library example; see https://github.com/miguelbalboa/rfid
* for further details and other examples.
*
* NOTE: The library file MFRC522.h has a lot of useful info. Please read it.
*
* Released into the public domain.
* ----------------------------------------------------------------------------
* This sample shows how to setup blocks on a MIFARE Classic PICC (= card/tag)
* to be in "Value Block" mode: in this mode the operations Increment/Decrement,
* Restore and Transfer can be used.
*
* BEWARE: Data will be written to the PICC, in sector #1 (blocks #4 to #7).
*
*
* Typical pin layout used:
* -----------------------------------------------------------------------------------------
* MFRC522 Arduino Arduino Arduino Arduino Arduino
* Reader/PCD Uno/101 Mega Nano v3 Leonardo/Micro Pro Micro
* Signal Pin Pin Pin Pin Pin Pin
* -----------------------------------------------------------------------------------------
* RST/Reset RST 9 5 D9 RESET/ICSP-5 RST
* SPI SS SDA(SS) 10 53 D10 10 10
* SPI MOSI MOSI 11 / ICSP-4 51 D11 ICSP-4 16
* SPI MISO MISO 12 / ICSP-1 50 D12 ICSP-1 14
* SPI SCK SCK 13 / ICSP-3 52 D13 ICSP-3 15
*
* More pin layouts for other boards can be found here: https://github.com/miguelbalboa/rfid#pin-layout
*
*/
#include <SPI.h>
#include <MFRC522.h>
#define RST_PIN 9 // Configurable, see typical pin layout above
#define SS_PIN 10 // Configurable, see typical pin layout above
MFRC522 mfrc522(SS_PIN, RST_PIN); // Create MFRC522 instance.
MFRC522::MIFARE_Key key;
/**
* Initialize.
*/
void setup() {
Serial.begin(9600); // Initialize serial communications with the PC
while (!Serial); // Do nothing if no serial port is opened (added for Arduinos based on ATMEGA32U4)
SPI.begin(); // Init SPI bus
mfrc522.PCD_Init(); // Init MFRC522 card
// Prepare the key (used both as key A and as key B)
// using FFFFFFFFFFFFh which is the default at chip delivery from the factory
for (byte i = 0; i < 6; i++) {
key.keyByte[i] = 0xFF;
}
Serial.println(F("Scan a MIFARE Classic PICC to demonstrate Value Block mode."));
Serial.print(F("Using key (for A and B):"));
dump_byte_array(key.keyByte, MFRC522::MF_KEY_SIZE);
Serial.println();
Serial.println(F("BEWARE: Data will be written to the PICC, in sector #1"));
}
/**
* Main loop.
*/
void loop() {
// Reset the loop if no new card present on the sensor/reader. This saves the entire process when idle.
if ( ! mfrc522.PICC_IsNewCardPresent())
return;
// Select one of the cards
if ( ! mfrc522.PICC_ReadCardSerial())
return;
// Show some details of the PICC (that is: the tag/card)
Serial.print(F("Card UID:"));
dump_byte_array(mfrc522.uid.uidByte, mfrc522.uid.size);
Serial.println();
Serial.print(F("PICC type: "));
MFRC522::PICC_Type piccType = mfrc522.PICC_GetType(mfrc522.uid.sak);
Serial.println(mfrc522.PICC_GetTypeName(piccType));
// Check for compatibility
if ( piccType != MFRC522::PICC_TYPE_MIFARE_MINI
&& piccType != MFRC522::PICC_TYPE_MIFARE_1K
&& piccType != MFRC522::PICC_TYPE_MIFARE_4K) {
Serial.println(F("This sample only works with MIFARE Classic cards."));
return;
}
// In this sample we use the second sector,
// that is: sector #1, covering block #4 up to and including block #7
byte sector = 1;
byte valueBlockA = 5;
byte valueBlockB = 6;
byte trailerBlock = 7;
MFRC522::StatusCode status;
byte buffer[18];
byte size = sizeof(buffer);
int32_t value;
// Authenticate using key A
Serial.println(F("Authenticating using key A..."));
status = mfrc522.PCD_Authenticate(MFRC522::PICC_CMD_MF_AUTH_KEY_A, trailerBlock, &key, &(mfrc522.uid));
if (status != MFRC522::STATUS_OK) {
Serial.print(F("PCD_Authenticate() failed: "));
Serial.println(mfrc522.GetStatusCodeName(status));
return;
}
// Show the whole sector as it currently is
Serial.println(F("Current data in sector:"));
mfrc522.PICC_DumpMifareClassicSectorToSerial(&(mfrc522.uid), &key, sector);
Serial.println();
// We need a sector trailer that defines blocks 5 and 6 as Value Blocks and enables key B
// The last block in a sector (block #3 for Mifare Classic 1K) is the Sector Trailer.
// See http://www.nxp.com/documents/data_sheet/MF1S503x.pdf sections 8.6 and 8.7:
// Bytes 0-5: Key A
// Bytes 6-8: Access Bits
// Bytes 9: User data
// Bytes 10-15: Key B (or user data)
byte trailerBuffer[] = {
255, 255, 255, 255, 255, 255, // Keep default key A
0, 0, 0,
0,
255, 255, 255, 255, 255, 255}; // Keep default key B
// The access bits are stored in a peculiar fashion.
// There are four groups:
// g[0] Access bits for block 0 (for sectors 0-31)
// or blocks 0-4 (for sectors 32-39)
// g[1] Access bits for block 1 (for sectors 0-31)
// or blocks 5-9 (for sectors 32-39)
// g[2] Access bits for block 2 (for sectors 0-31)
// or blocks 10-14 (for sectors 32-39)
// g[3] Access bits for the Sector Trailer: block 3 (for sectors 0-31)
// or block 15 (for sectors 32-39)
// Each group has access bits [C1 C2 C3], in this code C1 is MSB and C3 is LSB.
// Determine the bit pattern needed using MIFARE_SetAccessBits:
// g0=0 access bits for block 0 (of this sector) using [0 0 0] = 000b = 0
// which means key A|B have r/w for block 0 of this sector
// which (in this example) translates to block #4 within sector #1;
// this is the transport configuration (at factory delivery).
// g1=6 access bits for block 1 (of this sector) using [1 1 0] = 110b = 6
// which means block 1 (of this sector) is used as a value block,
// which (in this example) translates to block #5 within sector #1;
// where key A|B have r, key B has w, key B can increment,
// and key A|B can decrement, transfer, and restore.
// g2=6 same thing for block 2 (of this sector): set it to a value block;
// which (in this example) translates to block #6 within sector #1;
// g3=3 access bits for block 3 (of this sector): the Sector Trailer here;
// using [0 1 1] = 011b = 3 which means only key B has r/w access
// to the Sector Trailer (block 3 of this sector) from now on
// which (in this example) translates to block #7 within sector #1;
mfrc522.MIFARE_SetAccessBits(&trailerBuffer[6], 0, 6, 6, 3);
// Read the sector trailer as it is currently stored on the PICC
Serial.println(F("Reading sector trailer..."));
status = mfrc522.MIFARE_Read(trailerBlock, buffer, &size);
if (status != MFRC522::STATUS_OK) {
Serial.print(F("MIFARE_Read() failed: "));
Serial.println(mfrc522.GetStatusCodeName(status));
return;
}
// Check if it matches the desired access pattern already;
// because if it does, we don't need to write it again...
if ( buffer[6] != trailerBuffer[6]
|| buffer[7] != trailerBuffer[7]
|| buffer[8] != trailerBuffer[8]) {
// They don't match (yet), so write it to the PICC
Serial.println(F("Writing new sector trailer..."));
status = mfrc522.MIFARE_Write(trailerBlock, trailerBuffer, 16);
if (status != MFRC522::STATUS_OK) {
Serial.print(F("MIFARE_Write() failed: "));
Serial.println(mfrc522.GetStatusCodeName(status));
return;
}
}
// Authenticate using key B
Serial.println(F("Authenticating again using key B..."));
status = mfrc522.PCD_Authenticate(MFRC522::PICC_CMD_MF_AUTH_KEY_B, trailerBlock, &key, &(mfrc522.uid));
if (status != MFRC522::STATUS_OK) {
Serial.print(F("PCD_Authenticate() failed: "));
Serial.println(mfrc522.GetStatusCodeName(status));
return;
}
// A value block has a 32 bit signed value stored three times
// and an 8 bit address stored 4 times. Make sure that valueBlockA
// and valueBlockB have that format (note that it will only format
// the block when it doesn't comply to the expected format already).
formatValueBlock(valueBlockA);
formatValueBlock(valueBlockB);
// Add 1 to the value of valueBlockA and store the result in valueBlockA.
Serial.print("Adding 1 to value of block "); Serial.println(valueBlockA);
status = mfrc522.MIFARE_Increment(valueBlockA, 1);
if (status != MFRC522::STATUS_OK) {
Serial.print(F("MIFARE_Increment() failed: "));
Serial.println(mfrc522.GetStatusCodeName(status));
return;
}
status = mfrc522.MIFARE_Transfer(valueBlockA);
if (status != MFRC522::STATUS_OK) {
Serial.print(F("MIFARE_Transfer() failed: "));
Serial.println(mfrc522.GetStatusCodeName(status));
return;
}
// Show the new value of valueBlockA
status = mfrc522.MIFARE_GetValue(valueBlockA, &value);
if (status != MFRC522::STATUS_OK) {
Serial.print(F("mifare_GetValue() failed: "));
Serial.println(mfrc522.GetStatusCodeName(status));
return;
}
Serial.print("New value of value block "); Serial.print(valueBlockA);
Serial.print(" = "); Serial.println(value);
// Decrement 10 from the value of valueBlockB and store the result in valueBlockB.
Serial.print("Subtracting 10 from value of block "); Serial.println(valueBlockB);
status = mfrc522.MIFARE_Decrement(valueBlockB, 10);
if (status != MFRC522::STATUS_OK) {
Serial.print(F("MIFARE_Decrement() failed: "));
Serial.println(mfrc522.GetStatusCodeName(status));
return;
}
status = mfrc522.MIFARE_Transfer(valueBlockB);
if (status != MFRC522::STATUS_OK) {
Serial.print(F("MIFARE_Transfer() failed: "));
Serial.println(mfrc522.GetStatusCodeName(status));
return;
}
// Show the new value of valueBlockB
status = mfrc522.MIFARE_GetValue(valueBlockB, &value);
if (status != MFRC522::STATUS_OK) {
Serial.print(F("mifare_GetValue() failed: "));
Serial.println(mfrc522.GetStatusCodeName(status));
return;
}
Serial.print(F("New value of value block ")); Serial.print(valueBlockB);
Serial.print(F(" = ")); Serial.println(value);
// Check some boundary...
if (value <= -100) {
Serial.println(F("Below -100, so resetting it to 255 = 0xFF just for fun..."));
status = mfrc522.MIFARE_SetValue(valueBlockB, 255);
if (status != MFRC522::STATUS_OK) {
Serial.print(F("mifare_SetValue() failed: "));
Serial.println(mfrc522.GetStatusCodeName(status));
return;
}
}
// Dump the sector data
mfrc522.PICC_DumpMifareClassicSectorToSerial(&(mfrc522.uid), &key, sector);
Serial.println();
// Halt PICC
mfrc522.PICC_HaltA();
// Stop encryption on PCD
mfrc522.PCD_StopCrypto1();
}
/**
* Helper routine to dump a byte array as hex values to Serial.
*/
void dump_byte_array(byte *buffer, byte bufferSize) {
for (byte i = 0; i < bufferSize; i++) {
Serial.print(buffer[i] < 0x10 ? " 0" : " ");
Serial.print(buffer[i], HEX);
}
}
/**
* Ensure that a given block is formatted as a Value Block.
*/
void formatValueBlock(byte blockAddr) {
byte buffer[18];
byte size = sizeof(buffer);
MFRC522::StatusCode status;
Serial.print(F("Reading block ")); Serial.println(blockAddr);
status = mfrc522.MIFARE_Read(blockAddr, buffer, &size);
if (status != MFRC522::STATUS_OK) {
Serial.print(F("MIFARE_Read() failed: "));
Serial.println(mfrc522.GetStatusCodeName(status));
return;
}
if ( (buffer[0] == (byte)~buffer[4])
&& (buffer[1] == (byte)~buffer[5])
&& (buffer[2] == (byte)~buffer[6])
&& (buffer[3] == (byte)~buffer[7])
&& (buffer[0] == buffer[8])
&& (buffer[1] == buffer[9])
&& (buffer[2] == buffer[10])
&& (buffer[3] == buffer[11])
&& (buffer[12] == (byte)~buffer[13])
&& (buffer[12] == buffer[14])
&& (buffer[12] == (byte)~buffer[15])) {
Serial.println(F("Block has correct Value Block format."));
}
else {
Serial.println(F("Formatting as Value Block..."));
byte valueBlock[] = {
0, 0, 0, 0,
255, 255, 255, 255,
0, 0, 0, 0,
blockAddr, ~blockAddr, blockAddr, ~blockAddr };
status = mfrc522.MIFARE_Write(blockAddr, valueBlock, 16);
if (status != MFRC522::STATUS_OK) {
Serial.print(F("MIFARE_Write() failed: "));
Serial.println(mfrc522.GetStatusCodeName(status));
}
}
}

View File

@ -0,0 +1,139 @@
/**
* ----------------------------------------------------------------------------
* This is a MFRC522 library example; see https://github.com/miguelbalboa/rfid
* for further details and other examples.
*
* NOTE: The library file MFRC522.h has a lot of useful info. Please read it.
*
* Released into the public domain.
* ----------------------------------------------------------------------------
* Minimal example how to use the interrupts to read the UID of a MIFARE Classic PICC
* (= card/tag).
*
*
* Typical pin layout used:
* -----------------------------------------------------------------------------------------
* MFRC522 Arduino Arduino Arduino Arduino Arduino
* Reader/PCD Uno/101 Mega Nano v3 Leonardo/Micro Pro Micro
* Signal Pin Pin Pin Pin Pin Pin
* -----------------------------------------------------------------------------------------
* RST/Reset RST 9 5 D9 RESET/ICSP-5 RST
* SPI SS SDA(SS) 10 53 D10 3 10
* IRQ ? ? ? ? 2 10
* SPI MOSI MOSI 11 / ICSP-4 51 D11 ICSP-4 16
* SPI MISO MISO 12 / ICSP-1 50 D12 ICSP-1 14
* SPI SCK SCK 13 / ICSP-3 52 D13 ICSP-3 15
*
* More pin layouts for other boards can be found here: https://github.com/miguelbalboa/rfid#pin-layout
*
*/
#include <SPI.h>
#include <MFRC522.h>
#define RST_PIN 9 // Configurable, see typical pin layout above
#define SS_PIN 3 // Configurable, see typical pin layout above
#define IRQ_PIN 2 // Configurable, depends on hardware
MFRC522 mfrc522(SS_PIN, RST_PIN); // Create MFRC522 instance.
MFRC522::MIFARE_Key key;
volatile bool bNewInt = false;
byte regVal = 0x7F;
void activateRec(MFRC522 mfrc522);
void clearInt(MFRC522 mfrc522);
/**
* Initialize.
*/
void setup() {
Serial.begin(115200); // Initialize serial communications with the PC
while (!Serial); // Do nothing if no serial port is opened (added for Arduinos based on ATMEGA32U4)
SPI.begin(); // Init SPI bus
mfrc522.PCD_Init(); // Init MFRC522 card
/* read and printout the MFRC522 version (valid values 0x91 & 0x92)*/
Serial.print(F("Ver: 0x"));
byte readReg = mfrc522.PCD_ReadRegister(mfrc522.VersionReg);
Serial.println(readReg, HEX);
/* setup the IRQ pin*/
pinMode(IRQ_PIN, INPUT_PULLUP);
/*
* Allow the ... irq to be propagated to the IRQ pin
* For test purposes propagate the IdleIrq and loAlert
*/
regVal = 0xA0; //rx irq
mfrc522.PCD_WriteRegister(mfrc522.ComIEnReg, regVal);
bNewInt = false; //interrupt flag
/*Activate the interrupt*/
attachInterrupt(digitalPinToInterrupt(IRQ_PIN), readCard, FALLING);
do { //clear a spourious interrupt at start
;
} while (!bNewInt);
bNewInt = false;
Serial.println(F("End setup"));
}
/**
* Main loop.
*/
void loop() {
if (bNewInt) { //new read interrupt
Serial.print(F("Interrupt. "));
mfrc522.PICC_ReadCardSerial(); //read the tag data
// Show some details of the PICC (that is: the tag/card)
Serial.print(F("Card UID:"));
dump_byte_array(mfrc522.uid.uidByte, mfrc522.uid.size);
Serial.println();
clearInt(mfrc522);
mfrc522.PICC_HaltA();
bNewInt = false;
}
// The receiving block needs regular retriggering (tell the tag it should transmit??)
// (mfrc522.PCD_WriteRegister(mfrc522.FIFODataReg,mfrc522.PICC_CMD_REQA);)
activateRec(mfrc522);
delay(100);
} //loop()
/**
* Helper routine to dump a byte array as hex values to Serial.
*/
void dump_byte_array(byte *buffer, byte bufferSize) {
for (byte i = 0; i < bufferSize; i++) {
Serial.print(buffer[i] < 0x10 ? " 0" : " ");
Serial.print(buffer[i], HEX);
}
}
/**
* MFRC522 interrupt serving routine
*/
void readCard() {
bNewInt = true;
}
/*
* The function sending to the MFRC522 the needed commands to activate the reception
*/
void activateRec(MFRC522 mfrc522) {
mfrc522.PCD_WriteRegister(mfrc522.FIFODataReg, mfrc522.PICC_CMD_REQA);
mfrc522.PCD_WriteRegister(mfrc522.CommandReg, mfrc522.PCD_Transceive);
mfrc522.PCD_WriteRegister(mfrc522.BitFramingReg, 0x87);
}
/*
* The function to clear the pending interrupt bits after interrupt serving routine
*/
void clearInt(MFRC522 mfrc522) {
mfrc522.PCD_WriteRegister(mfrc522.ComIrqReg, 0x7F);
}

View File

@ -0,0 +1,62 @@
/*
* This example show how you can get Authenticated by the NTAG213,215,216. By default the tags are unprotected in order to protect them we need to write 4 different values:
* Using mfrc522.MIFARE_Ultralight_Write(PageNum, Data, #Databytes))
* 1.- We need to write the 32bit passWord to page 0xE5 !for ntag 213 and 215 page is different refer to nxp documentation!
* 2.- Now Write the 16 bits pACK to the page 0xE6 use the 2 high bytes like this: pACKH + pACKL + 00 + 00 after an authentication the tag will return this secret bytes
* 3.- Now we need to write the first page we want to protect this is a 1 byte data in page 0xE3 we need to write 00 + 00 + 00 + firstPage all pages after this one are write protected
* Now WRITE protection is ACTIVATED so we need to get authenticated in order to write the last data
* 4.- Finally we need to write an access record in order to READ protect the card this step is optional only if you want to read protect also write 80 + 00 + 00 + 00 to 0xE4
* After completing all these steps you will nee to authenticate first in order to read or write ant page after the first page you selected to protect.
* To disengage protection just write the page (0xE3) to 00 + 00 + 00 + FF that going to remove all protection.
*
* @author GARGANTUA from RoboCreators.com & paradoxalabs.com
* @license Released into the public domain.
*/
#include <SPI.h>
#include <MFRC522.h>
#define RST_PIN 9 //
#define SS_PIN 10 //
MFRC522 mfrc522(SS_PIN, RST_PIN); // Create MFRC522 instance
void setup() {
Serial.begin(9600); // Initialize serial communications with the PC
while (!Serial); // Do nothing if no serial port is opened (added for Arduinos based on ATMEGA32U4)
SPI.begin(); // Init SPI bus
mfrc522.PCD_Init(); // Init MFRC522
Serial.println(F("Scan PICC to see UID, type, and data blocks..."));
}
void loop() {
// Reset the loop if no new card present on the sensor/reader. This saves the entire process when idle.
if ( ! mfrc522.PICC_IsNewCardPresent()) {
return;
}
// Select one of the cards
if ( ! mfrc522.PICC_ReadCardSerial()) {
return;
}
byte PSWBuff[] = {0xFF, 0xFF, 0xFF, 0xFF}; // 32 bit password default FFFFFFFF.
byte pACK[] = {0, 0}; // 16 bit password ACK returned by the NFCtag.
Serial.print("Auth: ");
Serial.println(mfrc522.PCD_NTAG216_AUTH(&PSWBuff[0], pACK)); // Request authentification if return STATUS_OK we are good.
//Print PassWordACK
Serial.print(pACK[0], HEX);
Serial.println(pACK[1], HEX);
byte WBuff[] = {0x00, 0x00, 0x00, 0x04};
byte RBuff[18];
//Serial.print("CHG BLK: ");
//Serial.println(mfrc522.MIFARE_Ultralight_Write(0xE3, WBuff, 4)); // How to write to a page.
mfrc522.PICC_DumpMifareUltralightToSerial(); // This is a modifier dump just change the for circle to < 232 instead of < 16 in order to see all the pages on NTAG216.
delay(3000);
}

View File

@ -0,0 +1,314 @@
/*
* Copy the RFID card data into variables and then
* scan the second empty card to copy all the data
* ----------------------------------------------------------------------------
* Example sketch/program which will try the most used default keys listed in
* https://code.google.com/p/mfcuk/wiki/MifareClassicDefaultKeys to dump the
* block 0 of a MIFARE RFID card using a RFID-RC522 reader.
*
* Typical pin layout used:
* -----------------------------------------------------------------------------------------
* MFRC522 Arduino Arduino Arduino Arduino Arduino
* Reader/PCD Uno/101 Mega Nano v3 Leonardo/Micro Pro Micro
* Signal Pin Pin Pin Pin Pin Pin
* -----------------------------------------------------------------------------------------
* RST/Reset RST 9 5 D9 RESET/ICSP-5 RST
* SPI SS SDA(SS) 10 53 D10 10 10
* SPI MOSI MOSI 11 / ICSP-4 51 D11 ICSP-4 16
* SPI MISO MISO 12 / ICSP-1 50 D12 ICSP-1 14
* SPI SCK SCK 13 / ICSP-3 52 D13 ICSP-3 15
*
* More pin layouts for other boards can be found here: https://github.com/miguelbalboa/rfid#pin-layout
*
*/
#include <SPI.h>
#include <MFRC522.h>
#define RST_PIN 9 // Configurable, see typical pin layout above
#define SS_PIN 10 // Configurable, see typical pin layout above
MFRC522 mfrc522(SS_PIN, RST_PIN); // Create MFRC522 instance.
byte buffer[18];
byte block;
byte waarde[64][16];
MFRC522::StatusCode status;
MFRC522::MIFARE_Key key;
// Number of known default keys (hard-coded)
// NOTE: Synchronize the NR_KNOWN_KEYS define with the defaultKeys[] array
#define NR_KNOWN_KEYS 8
// Known keys, see: https://code.google.com/p/mfcuk/wiki/MifareClassicDefaultKeys
byte knownKeys[NR_KNOWN_KEYS][MFRC522::MF_KEY_SIZE] = {
{0xff, 0xff, 0xff, 0xff, 0xff, 0xff}, // FF FF FF FF FF FF = factory default
{0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5}, // A0 A1 A2 A3 A4 A5
{0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5}, // B0 B1 B2 B3 B4 B5
{0x4d, 0x3a, 0x99, 0xc3, 0x51, 0xdd}, // 4D 3A 99 C3 51 DD
{0x1a, 0x98, 0x2c, 0x7e, 0x45, 0x9a}, // 1A 98 2C 7E 45 9A
{0xd3, 0xf7, 0xd3, 0xf7, 0xd3, 0xf7}, // D3 F7 D3 F7 D3 F7
{0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff}, // AA BB CC DD EE FF
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00} // 00 00 00 00 00 00
};
char choice;
/*
* Initialize.
*/
void setup() {
Serial.begin(9600); // Initialize serial communications with the PC
while (!Serial); // Do nothing if no serial port is opened (added for Arduinos based on ATMEGA32U4)
SPI.begin(); // Init SPI bus
mfrc522.PCD_Init(); // Init MFRC522 card
Serial.println(F("Try the most used default keys to print block 0 to 63 of a MIFARE PICC."));
Serial.println("1.Read card \n2.Write to card \n3.Copy the data.");
for (byte i = 0; i < 6; i++) {
key.keyByte[i] = 0xFF;
}
}
//Via seriele monitor de bytes uitlezen in hexadecimaal
void dump_byte_array(byte *buffer, byte bufferSize) {
for (byte i = 0; i < bufferSize; i++) {
Serial.print(buffer[i] < 0x10 ? " 0" : " ");
Serial.print(buffer[i], HEX);
}
}
//Via seriele monitor de bytes uitlezen in ASCI
void dump_byte_array1(byte *buffer, byte bufferSize) {
for (byte i = 0; i < bufferSize; i++) {
Serial.print(buffer[i] < 0x10 ? " 0" : " ");
Serial.write(buffer[i]);
}
}
/*
* Try using the PICC (the tag/card) with the given key to access block 0 to 63.
* On success, it will show the key details, and dump the block data on Serial.
*
* @return true when the given key worked, false otherwise.
*/
bool try_key(MFRC522::MIFARE_Key *key)
{
bool result = false;
for(byte block = 0; block < 64; block++){
// Serial.println(F("Authenticating using key A..."));
status = mfrc522.PCD_Authenticate(MFRC522::PICC_CMD_MF_AUTH_KEY_A, block, key, &(mfrc522.uid));
if (status != MFRC522::STATUS_OK) {
Serial.print(F("PCD_Authenticate() failed: "));
Serial.println(mfrc522.GetStatusCodeName(status));
return false;
}
// Read block
byte byteCount = sizeof(buffer);
status = mfrc522.MIFARE_Read(block, buffer, &byteCount);
if (status != MFRC522::STATUS_OK) {
Serial.print(F("MIFARE_Read() failed: "));
Serial.println(mfrc522.GetStatusCodeName(status));
}
else {
// Successful read
result = true;
Serial.print(F("Success with key:"));
dump_byte_array((*key).keyByte, MFRC522::MF_KEY_SIZE);
Serial.println();
// Dump block data
Serial.print(F("Block ")); Serial.print(block); Serial.print(F(":"));
dump_byte_array1(buffer, 16); //omzetten van hex naar ASCI
Serial.println();
for (int p = 0; p < 16; p++) //De 16 bits uit de block uitlezen
{
waarde [block][p] = buffer[p];
Serial.print(waarde[block][p]);
Serial.print(" ");
}
}
}
Serial.println();
Serial.println("1.Read card \n2.Write to card \n3.Copy the data.");
mfrc522.PICC_HaltA(); // Halt PICC
mfrc522.PCD_StopCrypto1(); // Stop encryption on PCD
return result;
start();
}
/*
* Main loop.
*/
void loop() {
start();
}
void start(){
choice = Serial.read();
if(choice == '1')
{
Serial.println("Read the card");
keuze1();
}
else if(choice == '2')
{
Serial.println("See what is in the variables");
keuze2();
}
else if(choice == '3')
{
Serial.println("Copying the data on to the new card");
keuze3();
}
}
void keuze2(){ //Test waardes in blokken
for(block = 4; block <= 62; block++){
if(block == 7 || block == 11 || block == 15 || block == 19 || block == 23 || block == 27 || block == 31 || block == 35 || block == 39 || block == 43 || block == 47 || block == 51 || block == 55 || block == 59){
block ++;
}
Serial.print(F("Writing data into block "));
Serial.print(block);
Serial.println("\n");
for(int j = 0; j < 16; j++){
Serial.print(waarde[block][j]);
Serial.print(" ");
}
Serial.println("\n");
}
Serial.println("1.Read card \n2.Write to card \n3.Copy the data.");
start();
}
void keuze3(){ //Copy the data in the new card
Serial.println("Insert new card...");
// Look for new cards
if ( ! mfrc522.PICC_IsNewCardPresent())
return;
// Select one of the cards
if ( ! mfrc522.PICC_ReadCardSerial())
return;
// Show some details of the PICC (that is: the tag/card)
Serial.print(F("Card UID:"));
dump_byte_array(mfrc522.uid.uidByte, mfrc522.uid.size);
Serial.println();
Serial.print(F("PICC type: "));
MFRC522::PICC_Type piccType = mfrc522.PICC_GetType(mfrc522.uid.sak);
Serial.println(mfrc522.PICC_GetTypeName(piccType));
// Try the known default keys
/*MFRC522::MIFARE_Key key;
for (byte k = 0; k < NR_KNOWN_KEYS; k++) {
// Copy the known key into the MIFARE_Key structure
for (byte i = 0; i < MFRC522::MF_KEY_SIZE; i++) {
key.keyByte[i] = knownKeys[k][i];
}
}*/
for (byte i = 0; i < 6; i++) {
key.keyByte[i] = 0xFF;
}
for(int i = 4; i <= 62; i++){ //De blocken 4 tot 62 kopieren, behalve al deze onderstaande blocken (omdat deze de authenticatie blokken zijn)
if(i == 7 || i == 11 || i == 15 || i == 19 || i == 23 || i == 27 || i == 31 || i == 35 || i == 39 || i == 43 || i == 47 || i == 51 || i == 55 || i == 59){
i++;
}
block = i;
// Authenticate using key A
Serial.println(F("Authenticating using key A..."));
status = (MFRC522::StatusCode) mfrc522.PCD_Authenticate(MFRC522::PICC_CMD_MF_AUTH_KEY_A, block, &key, &(mfrc522.uid));
if (status != MFRC522::STATUS_OK) {
Serial.print(F("PCD_Authenticate() failed: "));
Serial.println(mfrc522.GetStatusCodeName(status));
return;
}
// Authenticate using key B
Serial.println(F("Authenticating again using key B..."));
status = (MFRC522::StatusCode) mfrc522.PCD_Authenticate(MFRC522::PICC_CMD_MF_AUTH_KEY_B, block, &key, &(mfrc522.uid));
if (status != MFRC522::STATUS_OK) {
Serial.print(F("PCD_Authenticate() failed: "));
Serial.println(mfrc522.GetStatusCodeName(status));
return;
}
// Write data to the block
Serial.print(F("Writing data into block "));
Serial.print(block);
Serial.println("\n");
dump_byte_array(waarde[block], 16);
status = (MFRC522::StatusCode) mfrc522.MIFARE_Write(block, waarde[block], 16);
if (status != MFRC522::STATUS_OK) {
Serial.print(F("MIFARE_Write() failed: "));
Serial.println(mfrc522.GetStatusCodeName(status));
}
Serial.println("\n");
}
mfrc522.PICC_HaltA(); // Halt PICC
mfrc522.PCD_StopCrypto1(); // Stop encryption on PCD
Serial.println("1.Read card \n2.Write to card \n3.Copy the data.");
start();
}
void keuze1(){ //Read card
Serial.println("Insert card...");
// Look for new cards
if ( ! mfrc522.PICC_IsNewCardPresent())
return;
// Select one of the cards
if ( ! mfrc522.PICC_ReadCardSerial())
return;
// Show some details of the PICC (that is: the tag/card)
Serial.print(F("Card UID:"));
dump_byte_array(mfrc522.uid.uidByte, mfrc522.uid.size);
Serial.println();
Serial.print(F("PICC type: "));
MFRC522::PICC_Type piccType = mfrc522.PICC_GetType(mfrc522.uid.sak);
Serial.println(mfrc522.PICC_GetTypeName(piccType));
// Try the known default keys
MFRC522::MIFARE_Key key;
for (byte k = 0; k < NR_KNOWN_KEYS; k++) {
// Copy the known key into the MIFARE_Key structure
for (byte i = 0; i < MFRC522::MF_KEY_SIZE; i++) {
key.keyByte[i] = knownKeys[k][i];
}
// Try the key
if (try_key(&key)) {
// Found and reported on the key and block,
// no need to try other keys for this PICC
break;
}
}
}

View File

@ -0,0 +1,202 @@
/**
* ----------------------------------------------------------------------------
* This is a MFRC522 library example; see https://github.com/miguelbalboa/rfid
* for further details and other examples.
*
* NOTE: The library file MFRC522.h has a lot of useful info. Please read it.
*
* Released into the public domain.
* ----------------------------------------------------------------------------
* This sample shows how to read and write data blocks on a MIFARE Classic PICC
* (= card/tag).
*
* BEWARE: Data will be written to the PICC, in sector #1 (blocks #4 to #7).
*
*
* Typical pin layout used:
* -----------------------------------------------------------------------------------------
* MFRC522 Arduino Arduino Arduino Arduino Arduino
* Reader/PCD Uno/101 Mega Nano v3 Leonardo/Micro Pro Micro
* Signal Pin Pin Pin Pin Pin Pin
* -----------------------------------------------------------------------------------------
* RST/Reset RST 9 5 D9 RESET/ICSP-5 RST
* SPI SS SDA(SS) 10 53 D10 10 10
* SPI MOSI MOSI 11 / ICSP-4 51 D11 ICSP-4 16
* SPI MISO MISO 12 / ICSP-1 50 D12 ICSP-1 14
* SPI SCK SCK 13 / ICSP-3 52 D13 ICSP-3 15
*
* More pin layouts for other boards can be found here: https://github.com/miguelbalboa/rfid#pin-layout
*
*/
#include <SPI.h>
#include <MFRC522.h>
#define RST_PIN 9 // Configurable, see typical pin layout above
#define SS_PIN 10 // Configurable, see typical pin layout above
MFRC522 mfrc522(SS_PIN, RST_PIN); // Create MFRC522 instance.
MFRC522::MIFARE_Key key;
/**
* Initialize.
*/
void setup() {
Serial.begin(9600); // Initialize serial communications with the PC
while (!Serial); // Do nothing if no serial port is opened (added for Arduinos based on ATMEGA32U4)
SPI.begin(); // Init SPI bus
mfrc522.PCD_Init(); // Init MFRC522 card
// Prepare the key (used both as key A and as key B)
// using FFFFFFFFFFFFh which is the default at chip delivery from the factory
for (byte i = 0; i < 6; i++) {
key.keyByte[i] = 0xFF;
}
Serial.println(F("Scan a MIFARE Classic PICC to demonstrate read and write."));
Serial.print(F("Using key (for A and B):"));
dump_byte_array(key.keyByte, MFRC522::MF_KEY_SIZE);
Serial.println();
Serial.println(F("BEWARE: Data will be written to the PICC, in sector #1"));
}
/**
* Main loop.
*/
void loop() {
// Reset the loop if no new card present on the sensor/reader. This saves the entire process when idle.
if ( ! mfrc522.PICC_IsNewCardPresent())
return;
// Select one of the cards
if ( ! mfrc522.PICC_ReadCardSerial())
return;
// Show some details of the PICC (that is: the tag/card)
Serial.print(F("Card UID:"));
dump_byte_array(mfrc522.uid.uidByte, mfrc522.uid.size);
Serial.println();
Serial.print(F("PICC type: "));
MFRC522::PICC_Type piccType = mfrc522.PICC_GetType(mfrc522.uid.sak);
Serial.println(mfrc522.PICC_GetTypeName(piccType));
// Check for compatibility
if ( piccType != MFRC522::PICC_TYPE_MIFARE_MINI
&& piccType != MFRC522::PICC_TYPE_MIFARE_1K
&& piccType != MFRC522::PICC_TYPE_MIFARE_4K) {
Serial.println(F("This sample only works with MIFARE Classic cards."));
return;
}
// In this sample we use the second sector,
// that is: sector #1, covering block #4 up to and including block #7
byte sector = 1;
byte blockAddr = 4;
byte dataBlock[] = {
0x01, 0x02, 0x03, 0x04, // 1, 2, 3, 4,
0x05, 0x06, 0x07, 0x08, // 5, 6, 7, 8,
0x09, 0x0a, 0xff, 0x0b, // 9, 10, 255, 11,
0x0c, 0x0d, 0x0e, 0x0f // 12, 13, 14, 15
};
byte trailerBlock = 7;
MFRC522::StatusCode status;
byte buffer[18];
byte size = sizeof(buffer);
// Authenticate using key A
Serial.println(F("Authenticating using key A..."));
status = (MFRC522::StatusCode) mfrc522.PCD_Authenticate(MFRC522::PICC_CMD_MF_AUTH_KEY_A, trailerBlock, &key, &(mfrc522.uid));
if (status != MFRC522::STATUS_OK) {
Serial.print(F("PCD_Authenticate() failed: "));
Serial.println(mfrc522.GetStatusCodeName(status));
return;
}
// Show the whole sector as it currently is
Serial.println(F("Current data in sector:"));
mfrc522.PICC_DumpMifareClassicSectorToSerial(&(mfrc522.uid), &key, sector);
Serial.println();
// Read data from the block
Serial.print(F("Reading data from block ")); Serial.print(blockAddr);
Serial.println(F(" ..."));
status = (MFRC522::StatusCode) mfrc522.MIFARE_Read(blockAddr, buffer, &size);
if (status != MFRC522::STATUS_OK) {
Serial.print(F("MIFARE_Read() failed: "));
Serial.println(mfrc522.GetStatusCodeName(status));
}
Serial.print(F("Data in block ")); Serial.print(blockAddr); Serial.println(F(":"));
dump_byte_array(buffer, 16); Serial.println();
Serial.println();
// Authenticate using key B
Serial.println(F("Authenticating again using key B..."));
status = (MFRC522::StatusCode) mfrc522.PCD_Authenticate(MFRC522::PICC_CMD_MF_AUTH_KEY_B, trailerBlock, &key, &(mfrc522.uid));
if (status != MFRC522::STATUS_OK) {
Serial.print(F("PCD_Authenticate() failed: "));
Serial.println(mfrc522.GetStatusCodeName(status));
return;
}
// Write data to the block
Serial.print(F("Writing data into block ")); Serial.print(blockAddr);
Serial.println(F(" ..."));
dump_byte_array(dataBlock, 16); Serial.println();
status = (MFRC522::StatusCode) mfrc522.MIFARE_Write(blockAddr, dataBlock, 16);
if (status != MFRC522::STATUS_OK) {
Serial.print(F("MIFARE_Write() failed: "));
Serial.println(mfrc522.GetStatusCodeName(status));
}
Serial.println();
// Read data from the block (again, should now be what we have written)
Serial.print(F("Reading data from block ")); Serial.print(blockAddr);
Serial.println(F(" ..."));
status = (MFRC522::StatusCode) mfrc522.MIFARE_Read(blockAddr, buffer, &size);
if (status != MFRC522::STATUS_OK) {
Serial.print(F("MIFARE_Read() failed: "));
Serial.println(mfrc522.GetStatusCodeName(status));
}
Serial.print(F("Data in block ")); Serial.print(blockAddr); Serial.println(F(":"));
dump_byte_array(buffer, 16); Serial.println();
// Check that data in block is what we have written
// by counting the number of bytes that are equal
Serial.println(F("Checking result..."));
byte count = 0;
for (byte i = 0; i < 16; i++) {
// Compare buffer (= what we've read) with dataBlock (= what we've written)
if (buffer[i] == dataBlock[i])
count++;
}
Serial.print(F("Number of bytes that match = ")); Serial.println(count);
if (count == 16) {
Serial.println(F("Success :-)"));
} else {
Serial.println(F("Failure, no match :-("));
Serial.println(F(" perhaps the write didn't work properly..."));
}
Serial.println();
// Dump the sector data
Serial.println(F("Current data in sector:"));
mfrc522.PICC_DumpMifareClassicSectorToSerial(&(mfrc522.uid), &key, sector);
Serial.println();
// Halt PICC
mfrc522.PICC_HaltA();
// Stop encryption on PCD
mfrc522.PCD_StopCrypto1();
}
/**
* Helper routine to dump a byte array as hex values to Serial.
*/
void dump_byte_array(byte *buffer, byte bufferSize) {
for (byte i = 0; i < bufferSize; i++) {
Serial.print(buffer[i] < 0x10 ? " 0" : " ");
Serial.print(buffer[i], HEX);
}
}

View File

@ -0,0 +1,129 @@
/*
* --------------------------------------------------------------------------------------------------------------------
* Example sketch/program showing how to read new NUID from a PICC to serial.
* --------------------------------------------------------------------------------------------------------------------
* This is a MFRC522 library example; for further details and other examples see: https://github.com/miguelbalboa/rfid
*
* Example sketch/program showing how to the read data from a PICC (that is: a RFID Tag or Card) using a MFRC522 based RFID
* Reader on the Arduino SPI interface.
*
* When the Arduino and the MFRC522 module are connected (see the pin layout below), load this sketch into Arduino IDE
* then verify/compile and upload it. To see the output: use Tools, Serial Monitor of the IDE (hit Ctrl+Shft+M). When
* you present a PICC (that is: a RFID Tag or Card) at reading distance of the MFRC522 Reader/PCD, the serial output
* will show the type, and the NUID if a new card has been detected. Note: you may see "Timeout in communication" messages
* when removing the PICC from reading distance too early.
*
* @license Released into the public domain.
*
* Typical pin layout used:
* -----------------------------------------------------------------------------------------
* MFRC522 Arduino Arduino Arduino Arduino Arduino
* Reader/PCD Uno/101 Mega Nano v3 Leonardo/Micro Pro Micro
* Signal Pin Pin Pin Pin Pin Pin
* -----------------------------------------------------------------------------------------
* RST/Reset RST 9 5 D9 RESET/ICSP-5 RST
* SPI SS SDA(SS) 10 53 D10 10 10
* SPI MOSI MOSI 11 / ICSP-4 51 D11 ICSP-4 16
* SPI MISO MISO 12 / ICSP-1 50 D12 ICSP-1 14
* SPI SCK SCK 13 / ICSP-3 52 D13 ICSP-3 15
*
* More pin layouts for other boards can be found here: https://github.com/miguelbalboa/rfid#pin-layout
*/
#include <SPI.h>
#include <MFRC522.h>
#define SS_PIN 10
#define RST_PIN 9
MFRC522 rfid(SS_PIN, RST_PIN); // Instance of the class
MFRC522::MIFARE_Key key;
// Init array that will store new NUID
byte nuidPICC[4];
void setup() {
Serial.begin(9600);
SPI.begin(); // Init SPI bus
rfid.PCD_Init(); // Init MFRC522
for (byte i = 0; i < 6; i++) {
key.keyByte[i] = 0xFF;
}
Serial.println(F("This code scan the MIFARE Classsic NUID."));
Serial.print(F("Using the following key:"));
printHex(key.keyByte, MFRC522::MF_KEY_SIZE);
}
void loop() {
// Reset the loop if no new card present on the sensor/reader. This saves the entire process when idle.
if ( ! rfid.PICC_IsNewCardPresent())
return;
// Verify if the NUID has been readed
if ( ! rfid.PICC_ReadCardSerial())
return;
Serial.print(F("PICC type: "));
MFRC522::PICC_Type piccType = rfid.PICC_GetType(rfid.uid.sak);
Serial.println(rfid.PICC_GetTypeName(piccType));
// Check is the PICC of Classic MIFARE type
if (piccType != MFRC522::PICC_TYPE_MIFARE_MINI &&
piccType != MFRC522::PICC_TYPE_MIFARE_1K &&
piccType != MFRC522::PICC_TYPE_MIFARE_4K) {
Serial.println(F("Your tag is not of type MIFARE Classic."));
return;
}
if (rfid.uid.uidByte[0] != nuidPICC[0] ||
rfid.uid.uidByte[1] != nuidPICC[1] ||
rfid.uid.uidByte[2] != nuidPICC[2] ||
rfid.uid.uidByte[3] != nuidPICC[3] ) {
Serial.println(F("A new card has been detected."));
// Store NUID into nuidPICC array
for (byte i = 0; i < 4; i++) {
nuidPICC[i] = rfid.uid.uidByte[i];
}
Serial.println(F("The NUID tag is:"));
Serial.print(F("In hex: "));
printHex(rfid.uid.uidByte, rfid.uid.size);
Serial.println();
Serial.print(F("In dec: "));
printDec(rfid.uid.uidByte, rfid.uid.size);
Serial.println();
}
else Serial.println(F("Card read previously."));
// Halt PICC
rfid.PICC_HaltA();
// Stop encryption on PCD
rfid.PCD_StopCrypto1();
}
/**
* Helper routine to dump a byte array as hex values to Serial.
*/
void printHex(byte *buffer, byte bufferSize) {
for (byte i = 0; i < bufferSize; i++) {
Serial.print(buffer[i] < 0x10 ? " 0" : " ");
Serial.print(buffer[i], HEX);
}
}
/**
* Helper routine to dump a byte array as dec values to Serial.
*/
void printDec(byte *buffer, byte bufferSize) {
for (byte i = 0; i < bufferSize; i++) {
Serial.print(' ');
Serial.print(buffer[i], DEC);
}
}

View File

@ -0,0 +1,99 @@
/**
* --------------------------------------------------------------------------------------------------------------------
* Example sketch/program showing how to read data from more than one PICC to serial.
* --------------------------------------------------------------------------------------------------------------------
* This is a MFRC522 library example; for further details and other examples see: https://github.com/miguelbalboa/rfid
*
* Example sketch/program showing how to read data from more than one PICC (that is: a RFID Tag or Card) using a
* MFRC522 based RFID Reader on the Arduino SPI interface.
*
* Warning: This may not work! Multiple devices at one SPI are difficult and cause many trouble!! Engineering skill
* and knowledge are required!
*
* @license Released into the public domain.
*
* Typical pin layout used:
* -----------------------------------------------------------------------------------------
* MFRC522 Arduino Arduino Arduino Arduino Arduino
* Reader/PCD Uno/101 Mega Nano v3 Leonardo/Micro Pro Micro
* Signal Pin Pin Pin Pin Pin Pin
* -----------------------------------------------------------------------------------------
* RST/Reset RST 9 5 D9 RESET/ICSP-5 RST
* SPI SS 1 SDA(SS) ** custom, take a unused pin, only HIGH/LOW required **
* SPI SS 2 SDA(SS) ** custom, take a unused pin, only HIGH/LOW required **
* SPI MOSI MOSI 11 / ICSP-4 51 D11 ICSP-4 16
* SPI MISO MISO 12 / ICSP-1 50 D12 ICSP-1 14
* SPI SCK SCK 13 / ICSP-3 52 D13 ICSP-3 15
*
* More pin layouts for other boards can be found here: https://github.com/miguelbalboa/rfid#pin-layout
*
*/
#include <SPI.h>
#include <MFRC522.h>
#define RST_PIN 9 // Configurable, see typical pin layout above
#define SS_1_PIN 10 // Configurable, take a unused pin, only HIGH/LOW required, must be different to SS 2
#define SS_2_PIN 8 // Configurable, take a unused pin, only HIGH/LOW required, must be different to SS 1
#define NR_OF_READERS 2
byte ssPins[] = {SS_1_PIN, SS_2_PIN};
MFRC522 mfrc522[NR_OF_READERS]; // Create MFRC522 instance.
/**
* Initialize.
*/
void setup() {
Serial.begin(9600); // Initialize serial communications with the PC
while (!Serial); // Do nothing if no serial port is opened (added for Arduinos based on ATMEGA32U4)
SPI.begin(); // Init SPI bus
for (uint8_t reader = 0; reader < NR_OF_READERS; reader++) {
mfrc522[reader].PCD_Init(ssPins[reader], RST_PIN); // Init each MFRC522 card
Serial.print(F("Reader "));
Serial.print(reader);
Serial.print(F(": "));
mfrc522[reader].PCD_DumpVersionToSerial();
}
}
/**
* Main loop.
*/
void loop() {
for (uint8_t reader = 0; reader < NR_OF_READERS; reader++) {
// Look for new cards
if (mfrc522[reader].PICC_IsNewCardPresent() && mfrc522[reader].PICC_ReadCardSerial()) {
Serial.print(F("Reader "));
Serial.print(reader);
// Show some details of the PICC (that is: the tag/card)
Serial.print(F(": Card UID:"));
dump_byte_array(mfrc522[reader].uid.uidByte, mfrc522[reader].uid.size);
Serial.println();
Serial.print(F("PICC type: "));
MFRC522::PICC_Type piccType = mfrc522[reader].PICC_GetType(mfrc522[reader].uid.sak);
Serial.println(mfrc522[reader].PICC_GetTypeName(piccType));
// Halt PICC
mfrc522[reader].PICC_HaltA();
// Stop encryption on PCD
mfrc522[reader].PCD_StopCrypto1();
} //if (mfrc522[reader].PICC_IsNewC
} //for(uint8_t reader
}
/**
* Helper routine to dump a byte array as hex values to Serial.
*/
void dump_byte_array(byte *buffer, byte bufferSize) {
for (byte i = 0; i < bufferSize; i++) {
Serial.print(buffer[i] < 0x10 ? " 0" : " ");
Serial.print(buffer[i], HEX);
}
}

View File

@ -0,0 +1,63 @@
/*
* --------------------------------------------------------------------------------------------------------------------
* Example sketch/program to test your firmware.
* --------------------------------------------------------------------------------------------------------------------
* This is a MFRC522 library example; for further details and other examples see: https://github.com/miguelbalboa/rfid
*
* This example test the firmware of your MFRC522 reader module, only known version can be checked. If the test passed
* it do not mean that your module is faultless! Some modules have bad or broken antennas or the PICC is broken.
*
* @author Rotzbua
* @license Released into the public domain.
*
* Typical pin layout used:
* -----------------------------------------------------------------------------------------
* MFRC522 Arduino Arduino Arduino Arduino Arduino
* Reader/PCD Uno/101 Mega Nano v3 Leonardo/Micro Pro Micro
* Signal Pin Pin Pin Pin Pin Pin
* -----------------------------------------------------------------------------------------
* RST/Reset RST 9 5 D9 RESET/ICSP-5 RST
* SPI SS SDA(SS) 10 53 D10 10 10
* SPI MOSI MOSI 11 / ICSP-4 51 D11 ICSP-4 16
* SPI MISO MISO 12 / ICSP-1 50 D12 ICSP-1 14
* SPI SCK SCK 13 / ICSP-3 52 D13 ICSP-3 15
*
* More pin layouts for other boards can be found here: https://github.com/miguelbalboa/rfid#pin-layout
*/
#include <SPI.h>
#include <MFRC522.h>
#define RST_PIN 9 // Configurable, see typical pin layout above
#define SS_PIN 10 // Configurable, see typical pin layout above
MFRC522 mfrc522(SS_PIN, RST_PIN); // Create MFRC522 instance
/**
* Check firmware only once at startup
*/
void setup() {
Serial.begin(9600); // Initialize serial communications with the PC
while (!Serial); // Do nothing if no serial port is opened (added for Arduinos based on ATMEGA32U4)
SPI.begin(); // Init SPI bus
mfrc522.PCD_Init(); // Init MFRC522 module
Serial.println(F("*****************************"));
Serial.println(F("MFRC522 Digital self test"));
Serial.println(F("*****************************"));
mfrc522.PCD_DumpVersionToSerial(); // Show version of PCD - MFRC522 Card Reader
Serial.println(F("-----------------------------"));
Serial.println(F("Only known versions supported"));
Serial.println(F("-----------------------------"));
Serial.println(F("Performing test..."));
bool result = mfrc522.PCD_PerformSelfTest(); // perform the test
Serial.println(F("-----------------------------"));
Serial.print(F("Result: "));
if (result)
Serial.println(F("OK"));
else
Serial.println(F("DEFECT or UNKNOWN"));
Serial.println();
}
void loop() {} // nothing to do

View File

@ -0,0 +1,160 @@
/*
* ----------------------------------------------------------------------------
* This is a MFRC522 library example; see https://github.com/miguelbalboa/rfid
* for further details and other examples.
*
* NOTE: The library file MFRC522.h has a lot of useful info. Please read it.
*
* Released into the public domain.
* ----------------------------------------------------------------------------
* Example sketch/program which will try the most used default keys listed in
* https://code.google.com/p/mfcuk/wiki/MifareClassicDefaultKeys to dump the
* block 0 of a MIFARE RFID card using a RFID-RC522 reader.
*
* Typical pin layout used:
* -----------------------------------------------------------------------------------------
* MFRC522 Arduino Arduino Arduino Arduino Arduino
* Reader/PCD Uno/101 Mega Nano v3 Leonardo/Micro Pro Micro
* Signal Pin Pin Pin Pin Pin Pin
* -----------------------------------------------------------------------------------------
* RST/Reset RST 9 5 D9 RESET/ICSP-5 RST
* SPI SS SDA(SS) 10 53 D10 10 10
* SPI MOSI MOSI 11 / ICSP-4 51 D11 ICSP-4 16
* SPI MISO MISO 12 / ICSP-1 50 D12 ICSP-1 14
* SPI SCK SCK 13 / ICSP-3 52 D13 ICSP-3 15
*
* More pin layouts for other boards can be found here: https://github.com/miguelbalboa/rfid#pin-layout
*
*/
#include <SPI.h>
#include <MFRC522.h>
#define RST_PIN 9 // Configurable, see typical pin layout above
#define SS_PIN 10 // Configurable, see typical pin layout above
MFRC522 mfrc522(SS_PIN, RST_PIN); // Create MFRC522 instance.
// Number of known default keys (hard-coded)
// NOTE: Synchronize the NR_KNOWN_KEYS define with the defaultKeys[] array
#define NR_KNOWN_KEYS 8
// Known keys, see: https://code.google.com/p/mfcuk/wiki/MifareClassicDefaultKeys
byte knownKeys[NR_KNOWN_KEYS][MFRC522::MF_KEY_SIZE] = {
{0xff, 0xff, 0xff, 0xff, 0xff, 0xff}, // FF FF FF FF FF FF = factory default
{0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5}, // A0 A1 A2 A3 A4 A5
{0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5}, // B0 B1 B2 B3 B4 B5
{0x4d, 0x3a, 0x99, 0xc3, 0x51, 0xdd}, // 4D 3A 99 C3 51 DD
{0x1a, 0x98, 0x2c, 0x7e, 0x45, 0x9a}, // 1A 98 2C 7E 45 9A
{0xd3, 0xf7, 0xd3, 0xf7, 0xd3, 0xf7}, // D3 F7 D3 F7 D3 F7
{0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff}, // AA BB CC DD EE FF
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00} // 00 00 00 00 00 00
};
/*
* Initialize.
*/
void setup() {
Serial.begin(9600); // Initialize serial communications with the PC
while (!Serial); // Do nothing if no serial port is opened (added for Arduinos based on ATMEGA32U4)
SPI.begin(); // Init SPI bus
mfrc522.PCD_Init(); // Init MFRC522 card
Serial.println(F("Try the most used default keys to print block 0 of a MIFARE PICC."));
}
/*
* Helper routine to dump a byte array as hex values to Serial.
*/
void dump_byte_array(byte *buffer, byte bufferSize) {
for (byte i = 0; i < bufferSize; i++) {
Serial.print(buffer[i] < 0x10 ? " 0" : " ");
Serial.print(buffer[i], HEX);
}
}
/*
* Try using the PICC (the tag/card) with the given key to access block 0.
* On success, it will show the key details, and dump the block data on Serial.
*
* @return true when the given key worked, false otherwise.
*/
bool try_key(MFRC522::MIFARE_Key *key)
{
bool result = false;
byte buffer[18];
byte block = 0;
MFRC522::StatusCode status;
// Serial.println(F("Authenticating using key A..."));
status = mfrc522.PCD_Authenticate(MFRC522::PICC_CMD_MF_AUTH_KEY_A, block, key, &(mfrc522.uid));
if (status != MFRC522::STATUS_OK) {
// Serial.print(F("PCD_Authenticate() failed: "));
// Serial.println(mfrc522.GetStatusCodeName(status));
return false;
}
// Read block
byte byteCount = sizeof(buffer);
status = mfrc522.MIFARE_Read(block, buffer, &byteCount);
if (status != MFRC522::STATUS_OK) {
// Serial.print(F("MIFARE_Read() failed: "));
// Serial.println(mfrc522.GetStatusCodeName(status));
}
else {
// Successful read
result = true;
Serial.print(F("Success with key:"));
dump_byte_array((*key).keyByte, MFRC522::MF_KEY_SIZE);
Serial.println();
// Dump block data
Serial.print(F("Block ")); Serial.print(block); Serial.print(F(":"));
dump_byte_array(buffer, 16);
Serial.println();
}
Serial.println();
mfrc522.PICC_HaltA(); // Halt PICC
mfrc522.PCD_StopCrypto1(); // Stop encryption on PCD
return result;
}
/*
* Main loop.
*/
void loop() {
// Reset the loop if no new card present on the sensor/reader. This saves the entire process when idle.
if ( ! mfrc522.PICC_IsNewCardPresent())
return;
// Select one of the cards
if ( ! mfrc522.PICC_ReadCardSerial())
return;
// Show some details of the PICC (that is: the tag/card)
Serial.print(F("Card UID:"));
dump_byte_array(mfrc522.uid.uidByte, mfrc522.uid.size);
Serial.println();
Serial.print(F("PICC type: "));
MFRC522::PICC_Type piccType = mfrc522.PICC_GetType(mfrc522.uid.sak);
Serial.println(mfrc522.PICC_GetTypeName(piccType));
// Try the known default keys
MFRC522::MIFARE_Key key;
for (byte k = 0; k < NR_KNOWN_KEYS; k++) {
// Copy the known key into the MIFARE_Key structure
for (byte i = 0; i < MFRC522::MF_KEY_SIZE; i++) {
key.keyByte[i] = knownKeys[k][i];
}
// Try the key
if (try_key(&key)) {
// Found and reported on the key and block,
// no need to try other keys for this PICC
break;
}
// http://arduino.stackexchange.com/a/14316
if ( ! mfrc522.PICC_IsNewCardPresent())
break;
if ( ! mfrc522.PICC_ReadCardSerial())
break;
}
}

View File

@ -0,0 +1,140 @@
/*
* Initial Author: ryand1011 (https://github.com/ryand1011)
*
* Reads data written by a program such as "rfid_write_personal_data.ino"
*
* See: https://github.com/miguelbalboa/rfid/tree/master/examples/rfid_write_personal_data
*
* Uses MIFARE RFID card using RFID-RC522 reader
* Uses MFRC522 - Library
* -----------------------------------------------------------------------------------------
* MFRC522 Arduino Arduino Arduino Arduino Arduino
* Reader/PCD Uno/101 Mega Nano v3 Leonardo/Micro Pro Micro
* Signal Pin Pin Pin Pin Pin Pin
* -----------------------------------------------------------------------------------------
* RST/Reset RST 9 5 D9 RESET/ICSP-5 RST
* SPI SS SDA(SS) 10 53 D10 10 10
* SPI MOSI MOSI 11 / ICSP-4 51 D11 ICSP-4 16
* SPI MISO MISO 12 / ICSP-1 50 D12 ICSP-1 14
* SPI SCK SCK 13 / ICSP-3 52 D13 ICSP-3 15
*
* More pin layouts for other boards can be found here: https://github.com/miguelbalboa/rfid#pin-layout
*/
#include <SPI.h>
#include <MFRC522.h>
#define RST_PIN 9 // Configurable, see typical pin layout above
#define SS_PIN 10 // Configurable, see typical pin layout above
MFRC522 mfrc522(SS_PIN, RST_PIN); // Create MFRC522 instance
//*****************************************************************************************//
void setup() {
Serial.begin(9600); // Initialize serial communications with the PC
SPI.begin(); // Init SPI bus
mfrc522.PCD_Init(); // Init MFRC522 card
Serial.println(F("Read personal data on a MIFARE PICC:")); //shows in serial that it is ready to read
}
//*****************************************************************************************//
void loop() {
// Prepare key - all keys are set to FFFFFFFFFFFFh at chip delivery from the factory.
MFRC522::MIFARE_Key key;
for (byte i = 0; i < 6; i++) key.keyByte[i] = 0xFF;
//some variables we need
byte block;
byte len;
MFRC522::StatusCode status;
//-------------------------------------------
// Reset the loop if no new card present on the sensor/reader. This saves the entire process when idle.
if ( ! mfrc522.PICC_IsNewCardPresent()) {
return;
}
// Select one of the cards
if ( ! mfrc522.PICC_ReadCardSerial()) {
return;
}
Serial.println(F("**Card Detected:**"));
//-------------------------------------------
mfrc522.PICC_DumpDetailsToSerial(&(mfrc522.uid)); //dump some details about the card
//mfrc522.PICC_DumpToSerial(&(mfrc522.uid)); //uncomment this to see all blocks in hex
//-------------------------------------------
Serial.print(F("Name: "));
byte buffer1[18];
block = 4;
len = 18;
//------------------------------------------- GET FIRST NAME
status = mfrc522.PCD_Authenticate(MFRC522::PICC_CMD_MF_AUTH_KEY_A, 4, &key, &(mfrc522.uid)); //line 834 of MFRC522.cpp file
if (status != MFRC522::STATUS_OK) {
Serial.print(F("Authentication failed: "));
Serial.println(mfrc522.GetStatusCodeName(status));
return;
}
status = mfrc522.MIFARE_Read(block, buffer1, &len);
if (status != MFRC522::STATUS_OK) {
Serial.print(F("Reading failed: "));
Serial.println(mfrc522.GetStatusCodeName(status));
return;
}
//PRINT FIRST NAME
for (uint8_t i = 0; i < 16; i++)
{
if (buffer1[i] != 32)
{
Serial.write(buffer1[i]);
}
}
Serial.print(" ");
//---------------------------------------- GET LAST NAME
byte buffer2[18];
block = 1;
status = mfrc522.PCD_Authenticate(MFRC522::PICC_CMD_MF_AUTH_KEY_A, 1, &key, &(mfrc522.uid)); //line 834
if (status != MFRC522::STATUS_OK) {
Serial.print(F("Authentication failed: "));
Serial.println(mfrc522.GetStatusCodeName(status));
return;
}
status = mfrc522.MIFARE_Read(block, buffer2, &len);
if (status != MFRC522::STATUS_OK) {
Serial.print(F("Reading failed: "));
Serial.println(mfrc522.GetStatusCodeName(status));
return;
}
//PRINT LAST NAME
for (uint8_t i = 0; i < 16; i++) {
Serial.write(buffer2[i] );
}
//----------------------------------------
Serial.println(F("\n**End Reading**\n"));
delay(1000); //change value if you want to read cards faster
mfrc522.PICC_HaltA();
mfrc522.PCD_StopCrypto1();
}
//*****************************************************************************************//

View File

@ -0,0 +1,158 @@
/*
* Write personal data of a MIFARE RFID card using a RFID-RC522 reader
* Uses MFRC522 - Library to use ARDUINO RFID MODULE KIT 13.56 MHZ WITH TAGS SPI W AND R BY COOQROBOT.
* -----------------------------------------------------------------------------------------
* MFRC522 Arduino Arduino Arduino Arduino Arduino
* Reader/PCD Uno/101 Mega Nano v3 Leonardo/Micro Pro Micro
* Signal Pin Pin Pin Pin Pin Pin
* -----------------------------------------------------------------------------------------
* RST/Reset RST 9 5 D9 RESET/ICSP-5 RST
* SPI SS SDA(SS) 10 53 D10 10 10
* SPI MOSI MOSI 11 / ICSP-4 51 D11 ICSP-4 16
* SPI MISO MISO 12 / ICSP-1 50 D12 ICSP-1 14
* SPI SCK SCK 13 / ICSP-3 52 D13 ICSP-3 15
*
* More pin layouts for other boards can be found here: https://github.com/miguelbalboa/rfid#pin-layout
*
* Hardware required:
* Arduino
* PCD (Proximity Coupling Device): NXP MFRC522 Contactless Reader IC
* PICC (Proximity Integrated Circuit Card): A card or tag using the ISO 14443A interface, eg Mifare or NTAG203.
* The reader can be found on eBay for around 5 dollars. Search for "mf-rc522" on ebay.com.
*/
#include <SPI.h>
#include <MFRC522.h>
#define RST_PIN 9 // Configurable, see typical pin layout above
#define SS_PIN 10 // Configurable, see typical pin layout above
MFRC522 mfrc522(SS_PIN, RST_PIN); // Create MFRC522 instance
void setup() {
Serial.begin(9600); // Initialize serial communications with the PC
SPI.begin(); // Init SPI bus
mfrc522.PCD_Init(); // Init MFRC522 card
Serial.println(F("Write personal data on a MIFARE PICC "));
}
void loop() {
// Prepare key - all keys are set to FFFFFFFFFFFFh at chip delivery from the factory.
MFRC522::MIFARE_Key key;
for (byte i = 0; i < 6; i++) key.keyByte[i] = 0xFF;
// Reset the loop if no new card present on the sensor/reader. This saves the entire process when idle.
if ( ! mfrc522.PICC_IsNewCardPresent()) {
return;
}
// Select one of the cards
if ( ! mfrc522.PICC_ReadCardSerial()) {
return;
}
Serial.print(F("Card UID:")); //Dump UID
for (byte i = 0; i < mfrc522.uid.size; i++) {
Serial.print(mfrc522.uid.uidByte[i] < 0x10 ? " 0" : " ");
Serial.print(mfrc522.uid.uidByte[i], HEX);
}
Serial.print(F(" PICC type: ")); // Dump PICC type
MFRC522::PICC_Type piccType = mfrc522.PICC_GetType(mfrc522.uid.sak);
Serial.println(mfrc522.PICC_GetTypeName(piccType));
byte buffer[34];
byte block;
MFRC522::StatusCode status;
byte len;
Serial.setTimeout(20000L) ; // wait until 20 seconds for input from serial
// Ask personal data: Family name
Serial.println(F("Type Family name, ending with #"));
len = Serial.readBytesUntil('#', (char *) buffer, 30) ; // read family name from serial
for (byte i = len; i < 30; i++) buffer[i] = ' '; // pad with spaces
block = 1;
//Serial.println(F("Authenticating using key A..."));
status = mfrc522.PCD_Authenticate(MFRC522::PICC_CMD_MF_AUTH_KEY_A, block, &key, &(mfrc522.uid));
if (status != MFRC522::STATUS_OK) {
Serial.print(F("PCD_Authenticate() failed: "));
Serial.println(mfrc522.GetStatusCodeName(status));
return;
}
else Serial.println(F("PCD_Authenticate() success: "));
// Write block
status = mfrc522.MIFARE_Write(block, buffer, 16);
if (status != MFRC522::STATUS_OK) {
Serial.print(F("MIFARE_Write() failed: "));
Serial.println(mfrc522.GetStatusCodeName(status));
return;
}
else Serial.println(F("MIFARE_Write() success: "));
block = 2;
//Serial.println(F("Authenticating using key A..."));
status = mfrc522.PCD_Authenticate(MFRC522::PICC_CMD_MF_AUTH_KEY_A, block, &key, &(mfrc522.uid));
if (status != MFRC522::STATUS_OK) {
Serial.print(F("PCD_Authenticate() failed: "));
Serial.println(mfrc522.GetStatusCodeName(status));
return;
}
// Write block
status = mfrc522.MIFARE_Write(block, &buffer[16], 16);
if (status != MFRC522::STATUS_OK) {
Serial.print(F("MIFARE_Write() failed: "));
Serial.println(mfrc522.GetStatusCodeName(status));
return;
}
else Serial.println(F("MIFARE_Write() success: "));
// Ask personal data: First name
Serial.println(F("Type First name, ending with #"));
len = Serial.readBytesUntil('#', (char *) buffer, 20) ; // read first name from serial
for (byte i = len; i < 20; i++) buffer[i] = ' '; // pad with spaces
block = 4;
//Serial.println(F("Authenticating using key A..."));
status = mfrc522.PCD_Authenticate(MFRC522::PICC_CMD_MF_AUTH_KEY_A, block, &key, &(mfrc522.uid));
if (status != MFRC522::STATUS_OK) {
Serial.print(F("PCD_Authenticate() failed: "));
Serial.println(mfrc522.GetStatusCodeName(status));
return;
}
// Write block
status = mfrc522.MIFARE_Write(block, buffer, 16);
if (status != MFRC522::STATUS_OK) {
Serial.print(F("MIFARE_Write() failed: "));
Serial.println(mfrc522.GetStatusCodeName(status));
return;
}
else Serial.println(F("MIFARE_Write() success: "));
block = 5;
//Serial.println(F("Authenticating using key A..."));
status = mfrc522.PCD_Authenticate(MFRC522::PICC_CMD_MF_AUTH_KEY_A, block, &key, &(mfrc522.uid));
if (status != MFRC522::STATUS_OK) {
Serial.print(F("PCD_Authenticate() failed: "));
Serial.println(mfrc522.GetStatusCodeName(status));
return;
}
// Write block
status = mfrc522.MIFARE_Write(block, &buffer[16], 16);
if (status != MFRC522::STATUS_OK) {
Serial.print(F("MIFARE_Write() failed: "));
Serial.println(mfrc522.GetStatusCodeName(status));
return;
}
else Serial.println(F("MIFARE_Write() success: "));
Serial.println(" ");
mfrc522.PICC_HaltA(); // Halt PICC
mfrc522.PCD_StopCrypto1(); // Stop encryption on PCD
}

View File

@ -0,0 +1,223 @@
#######################################
# Syntax Coloring Map for library MFRC522
#######################################
#######################################
# KEYWORD1 Classes, datatypes, and C++ keywords
#######################################
MFRC522 KEYWORD1
MFRC522Extended KEYWORD1
PCD_Register KEYWORD1
PCD_Command KEYWORD1
PCD_RxGain KEYWORD1
PICC_Command KEYWORD1
MIFARE_Misc KEYWORD1
PICC_Type KEYWORD1
StatusCode KEYWORD1
TagBitRates KEYWORD1
Uid KEYWORD1
CardInfo KEYWORD1
MIFARE_Key KEYWORD1
PcbBlock KEYWORD1
#######################################
# KEYWORD2 Methods and functions
#######################################
# Basic interface functions for communicating with the MFRC522
PCD_WriteRegister KEYWORD2
PCD_WriteRegister KEYWORD2
PCD_ReadRegister KEYWORD2
PCD_ReadRegister KEYWORD2
setBitMask KEYWORD2
PCD_SetRegisterBitMask KEYWORD2
PCD_ClearRegisterBitMask KEYWORD2
PCD_CalculateCRC KEYWORD2
# Functions for manipulating the MFRC522
PCD_Init KEYWORD2
PCD_Reset KEYWORD2
PCD_AntennaOn KEYWORD2
PCD_AntennaOff KEYWORD2
PCD_GetAntennaGain KEYWORD2
PCD_SetAntennaGain KEYWORD2
PCD_PerformSelfTest KEYWORD2
# Power control functions MFRC522
PCD_SoftPowerDown KEYWORD2
PCD_SoftPowerUp KEYWORD2
# Functions for communicating with PICCs
PCD_TransceiveData KEYWORD2
PCD_CommunicateWithPICC KEYWORD2
PICC_RequestA KEYWORD2
PICC_WakeupA KEYWORD2
PICC_REQA_or_WUPA KEYWORD2
PICC_Select KEYWORD2
PICC_HaltA KEYWORD2
PICC_RATS KEYWORD2
PICC_PPS KEYWORD2
# Functions for communicating with ISO/IEC 14433-4 cards
TCL_Transceive KEYWORD2
TCL_TransceiveRBlock KEYWORD2
TCL_Deselect KEYWORD2
# Functions for communicating with MIFARE PICCs
PCD_Authenticate KEYWORD2
PCD_StopCrypto1 KEYWORD2
MIFARE_Read KEYWORD2
MIFARE_Write KEYWORD2
MIFARE_Increment KEYWORD2
MIFARE_Ultralight_Write KEYWORD2
MIFARE_GetValue KEYWORD2
MIFARE_SetValue KEYWORD2
PCD_NTAG216_AUTH KEYWORD2
# Support functions
PCD_MIFARE_Transceive KEYWORD2
GetStatusCodeName KEYWORD2
PICC_GetType KEYWORD2
PICC_GetTypeName KEYWORD2
# Support functions for debuging
PCD_DumpVersionToSerial KEYWORD2
PICC_DumpToSerial KEYWORD2
PICC_DumpDetailsToSerial KEYWORD2
PICC_DumpMifareClassicToSerial KEYWORD2
PICC_DumpMifareClassicSectorToSerial KEYWORD2
PICC_DumpMifareUltralightToSerial KEYWORD2
PICC_DumpISO14443_4 KEYWORD2
# Advanced functions for MIFARE
MIFARE_SetAccessBits KEYWORD2
MIFARE_OpenUidBackdoor KEYWORD2
MIFARE_SetUid KEYWORD2
MIFARE_UnbrickUidSector KEYWORD2
# Convenience functions - does not add extra functionality
PICC_IsNewCardPresent KEYWORD2
PICC_ReadCardSerial KEYWORD2
#######################################
# KEYWORD3 setup and loop functions, as well as the Serial keywords
#######################################
#######################################
# LITERAL1 Constants
#######################################
CommandReg LITERAL1
ComIEnReg LITERAL1
DivIEnReg LITERAL1
ComIrqReg LITERAL1
DivIrqReg LITERAL1
ErrorReg LITERAL1
Status1Reg LITERAL1
Status2Reg LITERAL1
FIFODataReg LITERAL1
FIFOLevelReg LITERAL1
WaterLevelReg LITERAL1
ControlReg LITERAL1
BitFramingReg LITERAL1
CollReg LITERAL1
ModeReg LITERAL1
TxModeReg LITERAL1
RxModeReg LITERAL1
TxControlReg LITERAL1
TxASKReg LITERAL1
TxSelReg LITERAL1
RxSelReg LITERAL1
RxThresholdReg LITERAL1
DemodReg LITERAL1
MfTxReg LITERAL1
MfRxReg LITERAL1
SerialSpeedReg LITERAL1
CRCResultRegH LITERAL1
CRCResultRegL LITERAL1
ModWidthReg LITERAL1
RFCfgReg LITERAL1
GsNReg LITERAL1
CWGsPReg LITERAL1
ModGsPReg LITERAL1
TModeReg LITERAL1
TPrescalerReg LITERAL1
TReloadRegH LITERAL1
TReloadRegL LITERAL1
TCounterValueRegH LITERAL1
TCounterValueRegL LITERAL1
TestSel1Reg LITERAL1
TestSel2Reg LITERAL1
TestPinEnReg LITERAL1
TestPinValueReg LITERAL1
TestBusReg LITERAL1
AutoTestReg LITERAL1
VersionReg LITERAL1
AnalogTestReg LITERAL1
TestDAC1Reg LITERAL1
TestDAC2Reg LITERAL1
TestADCReg LITERAL1
PCD_Idle LITERAL1
PCD_Mem LITERAL1
PCD_GenerateRandomID LITERAL1
PCD_CalcCRC LITERAL1
PCD_Transmit LITERAL1
PCD_NoCmdChange LITERAL1
PCD_Receive LITERAL1
PCD_Transceive LITERAL1
PCD_MFAuthent LITERAL1
PCD_SoftReset LITERAL1
RxGain_18dB LITERAL1
RxGain_23dB LITERAL1
RxGain_18dB_2 LITERAL1
RxGain_23dB_2 LITERAL1
RxGain_33dB LITERAL1
RxGain_38dB LITERAL1
RxGain_43dB LITERAL1
RxGain_48dB LITERAL1
RxGain_min LITERAL1
RxGain_avg LITERAL1
RxGain_max LITERAL1
PICC_CMD_REQA LITERAL1
PICC_CMD_WUPA LITERAL1
PICC_CMD_CT LITERAL1
PICC_CMD_SEL_CL1 LITERAL1
PICC_CMD_SEL_CL2 LITERAL1
PICC_CMD_SEL_CL3 LITERAL1
PICC_CMD_HLTA LITERAL1
PICC_CMD_RATS LITERAL1
PICC_CMD_MF_AUTH_KEY_A LITERAL1
PICC_CMD_MF_AUTH_KEY_B LITERAL1
PICC_CMD_MF_READ LITERAL1
PICC_CMD_MF_WRITE LITERAL1
PICC_CMD_MF_DECREMENT LITERAL1
PICC_CMD_MF_INCREMENT LITERAL1
PICC_CMD_MF_RESTORE LITERAL1
PICC_CMD_MF_TRANSFER LITERAL1
PICC_CMD_UL_WRITE LITERAL1
MF_ACK LITERAL1
MF_KEY_SIZE LITERAL1
PICC_TYPE_UNKNOWN LITERAL1
PICC_TYPE_ISO_14443_4 LITERAL1
PICC_TYPE_ISO_18092 LITERAL1
PICC_TYPE_MIFARE_MINI LITERAL1
PICC_TYPE_MIFARE_1K LITERAL1
PICC_TYPE_MIFARE_4K LITERAL1
PICC_TYPE_MIFARE_UL LITERAL1
PICC_TYPE_MIFARE_PLUS LITERAL1
PICC_TYPE_MIFARE_DESFIRE LITERAL1
PICC_TYPE_TNP3XXX LITERAL1
PICC_TYPE_NOT_COMPLETE LITERAL1
STATUS_OK LITERAL1
STATUS_ERROR LITERAL1
STATUS_COLLISION LITERAL1
STATUS_TIMEOUT LITERAL1
STATUS_NO_ROOM LITERAL1
STATUS_INTERNAL_ERROR LITERAL1
STATUS_INVALID LITERAL1
STATUS_CRC_WRONG LITERAL1
STATUS_MIFARE_NACK LITERAL1
FIFO_SIZE LITERAL1
BITRATE_106KBITS LITERAL1
BITRATE_212KBITS LITERAL1
BITRATE_424KBITS LITERAL1
BITRATE_848KBITS LITERAL1

View File

@ -0,0 +1,15 @@
{
"name": "MFRC522",
"version": "1.4.11",
"license": "Unlicense",
"keywords": "rfid, spi",
"description": "Arduino RFID Library for MFRC522 (SPI). Read/Write a RFID Card or Tag using the ISO/IEC 14443A/MIFARE interface.",
"repository":
{
"type": "git",
"url": "https://github.com/miguelbalboa/rfid.git"
},
"exclude": "doc",
"frameworks": "arduino",
"platforms": ["atmelavr", "atmelsam", "ststm32", "espressif8266", "espressif32", "samd"]
}

View File

@ -0,0 +1,9 @@
name=MFRC522
version=1.4.11
author=GithubCommunity
maintainer=GithubCommunity
sentence=Arduino RFID Library for MFRC522 (SPI)
paragraph=Read/Write a RFID Card or Tag using the ISO/IEC 14443A/MIFARE interface.
category=Communication
url=https://github.com/miguelbalboa/rfid
architectures=avr,megaavr,STM32F1,teensy,esp8266,esp32,samd,atmelsam,MIK32_Amur

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,375 @@
/**
* Library to use Arduino MFRC522 module.
*
* @authors Dr.Leong, Miguel Balboa, Søren Thing Andersen, Tom Clement, many more! See GitLog.
*
* For more information read the README.
*
* Please read this file for an overview and then MFRC522.cpp for comments on the specific functions.
*/
#ifndef MFRC522_h
#define MFRC522_h
#include "require_cpp11.h"
#include "deprecated.h"
// Enable integer limits
#define __STDC_LIMIT_MACROS
#include <stdint.h>
#include <Arduino.h>
#include <SPI.h>
#ifndef MFRC522_SPICLOCK
#define MFRC522_SPICLOCK (4000000u) // MFRC522 accept upto 10MHz, set to 4MHz.
#endif
// Firmware data for self-test
// Reference values based on firmware version
// Hint: if needed, you can remove unused self-test data to save flash memory
//
// Version 0.0 (0x90)
// Philips Semiconductors; Preliminary Specification Revision 2.0 - 01 August 2005; 16.1 self-test
const byte MFRC522_firmware_referenceV0_0[] PROGMEM = {
0x00, 0x87, 0x98, 0x0f, 0x49, 0xFF, 0x07, 0x19,
0xBF, 0x22, 0x30, 0x49, 0x59, 0x63, 0xAD, 0xCA,
0x7F, 0xE3, 0x4E, 0x03, 0x5C, 0x4E, 0x49, 0x50,
0x47, 0x9A, 0x37, 0x61, 0xE7, 0xE2, 0xC6, 0x2E,
0x75, 0x5A, 0xED, 0x04, 0x3D, 0x02, 0x4B, 0x78,
0x32, 0xFF, 0x58, 0x3B, 0x7C, 0xE9, 0x00, 0x94,
0xB4, 0x4A, 0x59, 0x5B, 0xFD, 0xC9, 0x29, 0xDF,
0x35, 0x96, 0x98, 0x9E, 0x4F, 0x30, 0x32, 0x8D
};
// Version 1.0 (0x91)
// NXP Semiconductors; Rev. 3.8 - 17 September 2014; 16.1.1 self-test
const byte MFRC522_firmware_referenceV1_0[] PROGMEM = {
0x00, 0xC6, 0x37, 0xD5, 0x32, 0xB7, 0x57, 0x5C,
0xC2, 0xD8, 0x7C, 0x4D, 0xD9, 0x70, 0xC7, 0x73,
0x10, 0xE6, 0xD2, 0xAA, 0x5E, 0xA1, 0x3E, 0x5A,
0x14, 0xAF, 0x30, 0x61, 0xC9, 0x70, 0xDB, 0x2E,
0x64, 0x22, 0x72, 0xB5, 0xBD, 0x65, 0xF4, 0xEC,
0x22, 0xBC, 0xD3, 0x72, 0x35, 0xCD, 0xAA, 0x41,
0x1F, 0xA7, 0xF3, 0x53, 0x14, 0xDE, 0x7E, 0x02,
0xD9, 0x0F, 0xB5, 0x5E, 0x25, 0x1D, 0x29, 0x79
};
// Version 2.0 (0x92)
// NXP Semiconductors; Rev. 3.8 - 17 September 2014; 16.1.1 self-test
const byte MFRC522_firmware_referenceV2_0[] PROGMEM = {
0x00, 0xEB, 0x66, 0xBA, 0x57, 0xBF, 0x23, 0x95,
0xD0, 0xE3, 0x0D, 0x3D, 0x27, 0x89, 0x5C, 0xDE,
0x9D, 0x3B, 0xA7, 0x00, 0x21, 0x5B, 0x89, 0x82,
0x51, 0x3A, 0xEB, 0x02, 0x0C, 0xA5, 0x00, 0x49,
0x7C, 0x84, 0x4D, 0xB3, 0xCC, 0xD2, 0x1B, 0x81,
0x5D, 0x48, 0x76, 0xD5, 0x71, 0x61, 0x21, 0xA9,
0x86, 0x96, 0x83, 0x38, 0xCF, 0x9D, 0x5B, 0x6D,
0xDC, 0x15, 0xBA, 0x3E, 0x7D, 0x95, 0x3B, 0x2F
};
// Clone
// Fudan Semiconductor FM17522 (0x88)
const byte FM17522_firmware_reference[] PROGMEM = {
0x00, 0xD6, 0x78, 0x8C, 0xE2, 0xAA, 0x0C, 0x18,
0x2A, 0xB8, 0x7A, 0x7F, 0xD3, 0x6A, 0xCF, 0x0B,
0xB1, 0x37, 0x63, 0x4B, 0x69, 0xAE, 0x91, 0xC7,
0xC3, 0x97, 0xAE, 0x77, 0xF4, 0x37, 0xD7, 0x9B,
0x7C, 0xF5, 0x3C, 0x11, 0x8F, 0x15, 0xC3, 0xD7,
0xC1, 0x5B, 0x00, 0x2A, 0xD0, 0x75, 0xDE, 0x9E,
0x51, 0x64, 0xAB, 0x3E, 0xE9, 0x15, 0xB5, 0xAB,
0x56, 0x9A, 0x98, 0x82, 0x26, 0xEA, 0x2A, 0x62
};
class MFRC522 {
public:
// Size of the MFRC522 FIFO
static constexpr byte FIFO_SIZE = 64; // The FIFO is 64 bytes.
// Default value for unused pin
static constexpr uint8_t UNUSED_PIN = UINT8_MAX;
// MFRC522 registers. Described in chapter 9 of the datasheet.
// When using SPI all addresses are shifted one bit left in the "SPI address byte" (section 8.1.2.3)
enum PCD_Register : byte {
// Page 0: Command and status
// 0x00 // reserved for future use
CommandReg = 0x01 << 1, // starts and stops command execution
ComIEnReg = 0x02 << 1, // enable and disable interrupt request control bits
DivIEnReg = 0x03 << 1, // enable and disable interrupt request control bits
ComIrqReg = 0x04 << 1, // interrupt request bits
DivIrqReg = 0x05 << 1, // interrupt request bits
ErrorReg = 0x06 << 1, // error bits showing the error status of the last command executed
Status1Reg = 0x07 << 1, // communication status bits
Status2Reg = 0x08 << 1, // receiver and transmitter status bits
FIFODataReg = 0x09 << 1, // input and output of 64 byte FIFO buffer
FIFOLevelReg = 0x0A << 1, // number of bytes stored in the FIFO buffer
WaterLevelReg = 0x0B << 1, // level for FIFO underflow and overflow warning
ControlReg = 0x0C << 1, // miscellaneous control registers
BitFramingReg = 0x0D << 1, // adjustments for bit-oriented frames
CollReg = 0x0E << 1, // bit position of the first bit-collision detected on the RF interface
// 0x0F // reserved for future use
// Page 1: Command
// 0x10 // reserved for future use
ModeReg = 0x11 << 1, // defines general modes for transmitting and receiving
TxModeReg = 0x12 << 1, // defines transmission data rate and framing
RxModeReg = 0x13 << 1, // defines reception data rate and framing
TxControlReg = 0x14 << 1, // controls the logical behavior of the antenna driver pins TX1 and TX2
TxASKReg = 0x15 << 1, // controls the setting of the transmission modulation
TxSelReg = 0x16 << 1, // selects the internal sources for the antenna driver
RxSelReg = 0x17 << 1, // selects internal receiver settings
RxThresholdReg = 0x18 << 1, // selects thresholds for the bit decoder
DemodReg = 0x19 << 1, // defines demodulator settings
// 0x1A // reserved for future use
// 0x1B // reserved for future use
MfTxReg = 0x1C << 1, // controls some MIFARE communication transmit parameters
MfRxReg = 0x1D << 1, // controls some MIFARE communication receive parameters
// 0x1E // reserved for future use
SerialSpeedReg = 0x1F << 1, // selects the speed of the serial UART interface
// Page 2: Configuration
// 0x20 // reserved for future use
CRCResultRegH = 0x21 << 1, // shows the MSB and LSB values of the CRC calculation
CRCResultRegL = 0x22 << 1,
// 0x23 // reserved for future use
ModWidthReg = 0x24 << 1, // controls the ModWidth setting?
// 0x25 // reserved for future use
RFCfgReg = 0x26 << 1, // configures the receiver gain
GsNReg = 0x27 << 1, // selects the conductance of the antenna driver pins TX1 and TX2 for modulation
CWGsPReg = 0x28 << 1, // defines the conductance of the p-driver output during periods of no modulation
ModGsPReg = 0x29 << 1, // defines the conductance of the p-driver output during periods of modulation
TModeReg = 0x2A << 1, // defines settings for the internal timer
TPrescalerReg = 0x2B << 1, // the lower 8 bits of the TPrescaler value. The 4 high bits are in TModeReg.
TReloadRegH = 0x2C << 1, // defines the 16-bit timer reload value
TReloadRegL = 0x2D << 1,
TCounterValueRegH = 0x2E << 1, // shows the 16-bit timer value
TCounterValueRegL = 0x2F << 1,
// Page 3: Test Registers
// 0x30 // reserved for future use
TestSel1Reg = 0x31 << 1, // general test signal configuration
TestSel2Reg = 0x32 << 1, // general test signal configuration
TestPinEnReg = 0x33 << 1, // enables pin output driver on pins D1 to D7
TestPinValueReg = 0x34 << 1, // defines the values for D1 to D7 when it is used as an I/O bus
TestBusReg = 0x35 << 1, // shows the status of the internal test bus
AutoTestReg = 0x36 << 1, // controls the digital self-test
VersionReg = 0x37 << 1, // shows the software version
AnalogTestReg = 0x38 << 1, // controls the pins AUX1 and AUX2
TestDAC1Reg = 0x39 << 1, // defines the test value for TestDAC1
TestDAC2Reg = 0x3A << 1, // defines the test value for TestDAC2
TestADCReg = 0x3B << 1 // shows the value of ADC I and Q channels
// 0x3C // reserved for production tests
// 0x3D // reserved for production tests
// 0x3E // reserved for production tests
// 0x3F // reserved for production tests
};
// MFRC522 commands. Described in chapter 10 of the datasheet.
enum PCD_Command : byte {
PCD_Idle = 0x00, // no action, cancels current command execution
PCD_Mem = 0x01, // stores 25 bytes into the internal buffer
PCD_GenerateRandomID = 0x02, // generates a 10-byte random ID number
PCD_CalcCRC = 0x03, // activates the CRC coprocessor or performs a self-test
PCD_Transmit = 0x04, // transmits data from the FIFO buffer
PCD_NoCmdChange = 0x07, // no command change, can be used to modify the CommandReg register bits without affecting the command, for example, the PowerDown bit
PCD_Receive = 0x08, // activates the receiver circuits
PCD_Transceive = 0x0C, // transmits data from FIFO buffer to antenna and automatically activates the receiver after transmission
PCD_MFAuthent = 0x0E, // performs the MIFARE standard authentication as a reader
PCD_SoftReset = 0x0F // resets the MFRC522
};
// MFRC522 RxGain[2:0] masks, defines the receiver's signal voltage gain factor (on the PCD).
// Described in 9.3.3.6 / table 98 of the datasheet at http://www.nxp.com/documents/data_sheet/MFRC522.pdf
enum PCD_RxGain : byte {
RxGain_18dB = 0x00 << 4, // 000b - 18 dB, minimum
RxGain_23dB = 0x01 << 4, // 001b - 23 dB
RxGain_18dB_2 = 0x02 << 4, // 010b - 18 dB, it seems 010b is a duplicate for 000b
RxGain_23dB_2 = 0x03 << 4, // 011b - 23 dB, it seems 011b is a duplicate for 001b
RxGain_33dB = 0x04 << 4, // 100b - 33 dB, average, and typical default
RxGain_38dB = 0x05 << 4, // 101b - 38 dB
RxGain_43dB = 0x06 << 4, // 110b - 43 dB
RxGain_48dB = 0x07 << 4, // 111b - 48 dB, maximum
RxGain_min = 0x00 << 4, // 000b - 18 dB, minimum, convenience for RxGain_18dB
RxGain_avg = 0x04 << 4, // 100b - 33 dB, average, convenience for RxGain_33dB
RxGain_max = 0x07 << 4 // 111b - 48 dB, maximum, convenience for RxGain_48dB
};
// Commands sent to the PICC.
enum PICC_Command : byte {
// The commands used by the PCD to manage communication with several PICCs (ISO 14443-3, Type A, section 6.4)
PICC_CMD_REQA = 0x26, // REQuest command, Type A. Invites PICCs in state IDLE to go to READY and prepare for anticollision or selection. 7 bit frame.
PICC_CMD_WUPA = 0x52, // Wake-UP command, Type A. Invites PICCs in state IDLE and HALT to go to READY(*) and prepare for anticollision or selection. 7 bit frame.
PICC_CMD_CT = 0x88, // Cascade Tag. Not really a command, but used during anti collision.
PICC_CMD_SEL_CL1 = 0x93, // Anti collision/Select, Cascade Level 1
PICC_CMD_SEL_CL2 = 0x95, // Anti collision/Select, Cascade Level 2
PICC_CMD_SEL_CL3 = 0x97, // Anti collision/Select, Cascade Level 3
PICC_CMD_HLTA = 0x50, // HaLT command, Type A. Instructs an ACTIVE PICC to go to state HALT.
PICC_CMD_RATS = 0xE0, // Request command for Answer To Reset.
// The commands used for MIFARE Classic (from http://www.mouser.com/ds/2/302/MF1S503x-89574.pdf, Section 9)
// Use PCD_MFAuthent to authenticate access to a sector, then use these commands to read/write/modify the blocks on the sector.
// The read/write commands can also be used for MIFARE Ultralight.
PICC_CMD_MF_AUTH_KEY_A = 0x60, // Perform authentication with Key A
PICC_CMD_MF_AUTH_KEY_B = 0x61, // Perform authentication with Key B
PICC_CMD_MF_READ = 0x30, // Reads one 16 byte block from the authenticated sector of the PICC. Also used for MIFARE Ultralight.
PICC_CMD_MF_WRITE = 0xA0, // Writes one 16 byte block to the authenticated sector of the PICC. Called "COMPATIBILITY WRITE" for MIFARE Ultralight.
PICC_CMD_MF_DECREMENT = 0xC0, // Decrements the contents of a block and stores the result in the internal data register.
PICC_CMD_MF_INCREMENT = 0xC1, // Increments the contents of a block and stores the result in the internal data register.
PICC_CMD_MF_RESTORE = 0xC2, // Reads the contents of a block into the internal data register.
PICC_CMD_MF_TRANSFER = 0xB0, // Writes the contents of the internal data register to a block.
// The commands used for MIFARE Ultralight (from http://www.nxp.com/documents/data_sheet/MF0ICU1.pdf, Section 8.6)
// The PICC_CMD_MF_READ and PICC_CMD_MF_WRITE can also be used for MIFARE Ultralight.
PICC_CMD_UL_WRITE = 0xA2 // Writes one 4 byte page to the PICC.
};
// MIFARE constants that does not fit anywhere else
enum MIFARE_Misc {
MF_ACK = 0xA, // The MIFARE Classic uses a 4 bit ACK/NAK. Any other value than 0xA is NAK.
MF_KEY_SIZE = 6 // A Mifare Crypto1 key is 6 bytes.
};
// PICC types we can detect. Remember to update PICC_GetTypeName() if you add more.
// last value set to 0xff, then compiler uses less ram, it seems some optimisations are triggered
enum PICC_Type : byte {
PICC_TYPE_UNKNOWN ,
PICC_TYPE_ISO_14443_4 , // PICC compliant with ISO/IEC 14443-4
PICC_TYPE_ISO_18092 , // PICC compliant with ISO/IEC 18092 (NFC)
PICC_TYPE_MIFARE_MINI , // MIFARE Classic protocol, 320 bytes
PICC_TYPE_MIFARE_1K , // MIFARE Classic protocol, 1KB
PICC_TYPE_MIFARE_4K , // MIFARE Classic protocol, 4KB
PICC_TYPE_MIFARE_UL , // MIFARE Ultralight or Ultralight C
PICC_TYPE_MIFARE_PLUS , // MIFARE Plus
PICC_TYPE_MIFARE_DESFIRE, // MIFARE DESFire
PICC_TYPE_TNP3XXX , // Only mentioned in NXP AN 10833 MIFARE Type Identification Procedure
PICC_TYPE_NOT_COMPLETE = 0xff // SAK indicates UID is not complete.
};
// Return codes from the functions in this class. Remember to update GetStatusCodeName() if you add more.
// last value set to 0xff, then compiler uses less ram, it seems some optimisations are triggered
enum StatusCode : byte {
STATUS_OK , // Success
STATUS_ERROR , // Error in communication
STATUS_COLLISION , // Collission detected
STATUS_TIMEOUT , // Timeout in communication.
STATUS_NO_ROOM , // A buffer is not big enough.
STATUS_INTERNAL_ERROR , // Internal error in the code. Should not happen ;-)
STATUS_INVALID , // Invalid argument.
STATUS_CRC_WRONG , // The CRC_A does not match
STATUS_MIFARE_NACK = 0xff // A MIFARE PICC responded with NAK.
};
// A struct used for passing the UID of a PICC.
typedef struct {
byte size; // Number of bytes in the UID. 4, 7 or 10.
byte uidByte[10];
byte sak; // The SAK (Select acknowledge) byte returned from the PICC after successful selection.
} Uid;
// A struct used for passing a MIFARE Crypto1 key
typedef struct {
byte keyByte[MF_KEY_SIZE];
} MIFARE_Key;
// Member variables
Uid uid; // Used by PICC_ReadCardSerial().
/////////////////////////////////////////////////////////////////////////////////////
// Functions for setting up the Arduino
/////////////////////////////////////////////////////////////////////////////////////
MFRC522();
MFRC522(byte resetPowerDownPin);
MFRC522(byte chipSelectPin, byte resetPowerDownPin);
/////////////////////////////////////////////////////////////////////////////////////
// Basic interface functions for communicating with the MFRC522
/////////////////////////////////////////////////////////////////////////////////////
void PCD_WriteRegister(PCD_Register reg, byte value);
void PCD_WriteRegister(PCD_Register reg, byte count, byte *values);
byte PCD_ReadRegister(PCD_Register reg);
void PCD_ReadRegister(PCD_Register reg, byte count, byte *values, byte rxAlign = 0);
void PCD_SetRegisterBitMask(PCD_Register reg, byte mask);
void PCD_ClearRegisterBitMask(PCD_Register reg, byte mask);
StatusCode PCD_CalculateCRC(byte *data, byte length, byte *result);
/////////////////////////////////////////////////////////////////////////////////////
// Functions for manipulating the MFRC522
/////////////////////////////////////////////////////////////////////////////////////
void PCD_Init();
void PCD_Init(byte resetPowerDownPin);
void PCD_Init(byte chipSelectPin, byte resetPowerDownPin);
void PCD_Reset();
void PCD_AntennaOn();
void PCD_AntennaOff();
byte PCD_GetAntennaGain();
void PCD_SetAntennaGain(byte mask);
bool PCD_PerformSelfTest();
/////////////////////////////////////////////////////////////////////////////////////
// Power control functions
/////////////////////////////////////////////////////////////////////////////////////
void PCD_SoftPowerDown();
void PCD_SoftPowerUp();
/////////////////////////////////////////////////////////////////////////////////////
// Functions for communicating with PICCs
/////////////////////////////////////////////////////////////////////////////////////
StatusCode PCD_TransceiveData(byte *sendData, byte sendLen, byte *backData, byte *backLen, byte *validBits = nullptr, byte rxAlign = 0, bool checkCRC = false);
StatusCode PCD_CommunicateWithPICC(byte command, byte waitIRq, byte *sendData, byte sendLen, byte *backData = nullptr, byte *backLen = nullptr, byte *validBits = nullptr, byte rxAlign = 0, bool checkCRC = false);
StatusCode PICC_RequestA(byte *bufferATQA, byte *bufferSize);
StatusCode PICC_WakeupA(byte *bufferATQA, byte *bufferSize);
StatusCode PICC_REQA_or_WUPA(byte command, byte *bufferATQA, byte *bufferSize);
virtual StatusCode PICC_Select(Uid *uid, byte validBits = 0);
StatusCode PICC_HaltA();
/////////////////////////////////////////////////////////////////////////////////////
// Functions for communicating with MIFARE PICCs
/////////////////////////////////////////////////////////////////////////////////////
StatusCode PCD_Authenticate(byte command, byte blockAddr, MIFARE_Key *key, Uid *uid);
void PCD_StopCrypto1();
StatusCode MIFARE_Read(byte blockAddr, byte *buffer, byte *bufferSize);
StatusCode MIFARE_Write(byte blockAddr, byte *buffer, byte bufferSize);
StatusCode MIFARE_Ultralight_Write(byte page, byte *buffer, byte bufferSize);
StatusCode MIFARE_Decrement(byte blockAddr, int32_t delta);
StatusCode MIFARE_Increment(byte blockAddr, int32_t delta);
StatusCode MIFARE_Restore(byte blockAddr);
StatusCode MIFARE_Transfer(byte blockAddr);
StatusCode MIFARE_GetValue(byte blockAddr, int32_t *value);
StatusCode MIFARE_SetValue(byte blockAddr, int32_t value);
StatusCode PCD_NTAG216_AUTH(byte *passWord, byte pACK[]);
/////////////////////////////////////////////////////////////////////////////////////
// Support functions
/////////////////////////////////////////////////////////////////////////////////////
StatusCode PCD_MIFARE_Transceive(byte *sendData, byte sendLen, bool acceptTimeout = false);
// old function used too much memory, now name moved to flash; if you need char, copy from flash to memory
//const char *GetStatusCodeName(byte code);
static const __FlashStringHelper *GetStatusCodeName(StatusCode code);
static PICC_Type PICC_GetType(byte sak);
// old function used too much memory, now name moved to flash; if you need char, copy from flash to memory
//const char *PICC_GetTypeName(byte type);
static const __FlashStringHelper *PICC_GetTypeName(PICC_Type type);
static const __FlashStringHelper *PICC_GetTypeName(byte type)
{
return PICC_GetTypeName(static_cast<PICC_Type>(type));
}
// Support functions for debuging
void PCD_DumpVersionToSerial();
void PICC_DumpToSerial(Uid *uid);
void PICC_DumpDetailsToSerial(Uid *uid);
void PICC_DumpMifareClassicToSerial(Uid *uid, PICC_Type piccType, MIFARE_Key *key);
void PICC_DumpMifareClassicSectorToSerial(Uid *uid, MIFARE_Key *key, byte sector);
void PICC_DumpMifareUltralightToSerial();
// Advanced functions for MIFARE
void MIFARE_SetAccessBits(byte *accessBitBuffer, byte g0, byte g1, byte g2, byte g3);
bool MIFARE_OpenUidBackdoor(bool logErrors);
bool MIFARE_SetUid(byte *newUid, byte uidSize, bool logErrors);
bool MIFARE_UnbrickUidSector(bool logErrors);
/////////////////////////////////////////////////////////////////////////////////////
// Convenience functions - does not add extra functionality
/////////////////////////////////////////////////////////////////////////////////////
virtual bool PICC_IsNewCardPresent();
virtual bool PICC_ReadCardSerial();
protected:
byte _chipSelectPin; // Arduino pin connected to MFRC522's SPI slave select input (Pin 24, NSS, active low)
byte _resetPowerDownPin; // Arduino pin connected to MFRC522's reset and power down input (Pin 6, NRSTPD, active low)
StatusCode MIFARE_TwoStepHelper(byte command, byte blockAddr, int32_t data);
};
#endif

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