Обновление до версии 0.3.0
- обновлен elbear_fw_bootloader - добавлена проверка контрольной суммы каждой строки hex файла. - в модуль работы с АЦП добавлена функция analogReadResolution(). Функция analogRead() теперь возвращает усредненное по 10 измерениям значение. - общая функция обработки прерываний перенесена в память RAM. Обработчики прерываний модулей External Interrupts и Advanced I/O (функция tone()) так же перенесены в память RAM для увеличения скорости выполнения кода. - в пакет добавлены библиотеки EEPROM, Servo, SoftSerial, NeoPixel, MFRC522 адаптированные для работы с платой Elbear Ace-Uno. - добавлено описание особенностей работы с пакетом
This commit is contained in:
parent
2044614aba
commit
7261b03ea1
1
.gitignore
vendored
1
.gitignore
vendored
@ -1 +1,2 @@
|
|||||||
installed.json
|
installed.json
|
||||||
|
.vscode/
|
||||||
40
Instructions.md
Normal file
40
Instructions.md
Normal 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`
|
||||||
|

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

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

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

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

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

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

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

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

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

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

|
||||||
116
README.md
116
README.md
@ -3,49 +3,93 @@
|
|||||||
|
|
||||||
|
|
||||||
## Установка пакета в ArduinoIDE
|
## Установка пакета в ArduinoIDE
|
||||||
1. Установите [Arduino IDE](https://www.arduino.cc/en/software).
|
Для установки пакета в параметрах ArduinoIDE необходимо добавить ссылку `https://elron.tech/files/package_elbear_beta_index.json` в поле "Дополнительные ссылки для Менеджера плат".
|
||||||
2. Откройте меню `Файл -> Параметры`.
|
Подробные шаги по установке и начальной настройке описаны в [инструкции](./Instructions.md).
|
||||||
3. Вставьте данную ссылку в поле "Дополнительные ссылки для Менеджера плат":
|
|
||||||
`https://elron.tech/files/package_elbear_beta_index.json`
|
|
||||||

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

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

|
|
||||||
|
|
||||||
Для загрузки скетчей по USB в ArduinoIDE необходимо, чтобы на плату Elbear Ace-Uno была загружена специальная программа-загрузчик ([elbear_fw_bootloader](https://gitflic.ru/project/elron-tech/elbear_fw_bootloader)). Если она уже есть на плате, можно сразу переходить к работе. Если загрузчика еще нет или необходимо обновить его на плате, ниже описан процесс загрузки. Актуальная версия программы-загрузчика входит в состав пакета поддержки, отдельно скачивать её не нужно.
|
## Функциональное назначение выводов
|
||||||
|

|
||||||
|
|
||||||
Платы ревизии 1.1.0 готовы к использованию в ArduinoIDE из коробки, так как поставляются с предварительно загруженной программой-загрузчиком.
|
## Особенности использования платы 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)`.
|
||||||
|
|
||||||
## Загрузка программы-загрузчика через ArduinoIDE
|
### Аналоговые выводы
|
||||||
1. Подключите плату Elbear Ace-Uno к ПК через программатор ELJTAG.
|
#### АЦП
|
||||||
2. В ArduinoIDE выберите программатор: `Инструменты -> Программатор -> mik32 uploader`.
|
Встроенный в MIK32 АЦП обладает разрешением 12 бит, однако по умолчанию в Arduino IDE применяется разрешение 10 бит. С помощью функции `void analogReadResolution(uint8_t resolution)` можно изменять разрешение в диапазоне от 1 до 32 бит.
|
||||||
3. Для загрузки программы-загрузчика выберите `Инструменты -> Записать Загрузчик`.
|
Функция `uint32_t analogRead(uint32_t PinNumber)` возвращает результаты измерения после усреднения по 10 значениям.
|
||||||

|
#### ШИМ
|
||||||
4. При возникновении проблем с загрузкой ознакомьтесь с разделом `Настройка программатора` в [инструкции](https://elron.tech/wp-content/uploads/2024/05/instrukcija-po-pervomu-zapusku.pdf) по первому запуску платы ELBEAR ACE-UNO.
|
На плате Elbear Ace-Uno доступны следующие выводы для формирования ШИМ-сигнала: D3, D5, D6, D9, D10, D11. Генерация сигнала осуществляется с помощью 32-битного таймера. Выводы D3, D5, D6, D9 подключены к таймеру 1, выводы D10, D11 подключены к таймеру 2. Выводы, подключенные к одному и тому же таймеру, выдают ШИМ-сигнал одинаковой частоты.
|
||||||
Теперь можно загружать скетчи в плату по USB.
|
Цифровой вывод 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)`.
|
||||||
|
|
||||||
## Начало работы
|
### Прерывания
|
||||||
1. Подключите плату к ПК по USB.
|
На плате Elbear Ace-Uno доступно 7 прерываний, настраиваемых функцией `void attachInterrupt(uint8_t interruptNum, void (*userFunc)(void), int mode)`:
|
||||||
2. Откройте ArduinoIDE и загрузите необходимый скетч. Для начала работы можно воспользоваться готовыми примерами, например - `Файл -> Примеры -> 01.Basics -> Blink`.
|
|
||||||

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

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

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

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

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

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

|
|
||||||
|
|
||||||
|
|Цифровой вывод|Номер прерывания|
|
||||||
|
|---------|---------|
|
||||||
|
|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`.
|
||||||
|
Доступны следующие настройки режима работы каждого интерфейса: длина данных - 7 или 8 бит; бит четности - нет, четный, нечетный; стоп бит - 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 шилд для подключения к Интернету|
|
||||||
|
|
||||||
При возникновении вопросов или выявлении проблем можно оставить заявку [здесь](https://gitflic.ru/project/elron-tech/elbear_arduino_bsp/issue).
|
|
||||||
|
|
||||||
# Полезные ссылки
|
# Полезные ссылки
|
||||||
* [Материалы по платам ELBEAR ACE-UNO](https://elron.tech/support/#elbear)
|
* [Материалы по платам ELBEAR ACE-UNO](https://elron.tech/support/#elbear)
|
||||||
* [Телеграмм-канал компании (обновления по проекту ELBEAR и другим)](https://t.me/elrontech)
|
* [Телеграмм-канал компании (обновления по проекту ELBEAR и другим)](https://t.me/elrontech)
|
||||||
|
|
||||||
|
При возникновении вопросов или выявлении проблем можно оставить заявку [здесь](https://gitflic.ru/project/elron-tech/elbear_arduino_bsp/issue).
|
||||||
|
|||||||
@ -1,15 +1,15 @@
|
|||||||
:020000040100F9
|
:020000040100F9
|
||||||
:10000000FD62938202400100FD12E39E02FE374131
|
:10000000FD62938202400100FD12E39E02FE374131
|
||||||
:10001000000213010100B701000293810100B7152E
|
:10001000000213010100B701000293810100B7152E
|
||||||
:100020000001938505F537160001130606F8B7069B
|
:100020000001938505FF3716000113060602B70687
|
||||||
:1000300000029386060039A083A2050023A0560083
|
:1000300000029386060039A083A2050023A0560083
|
||||||
:1000400091059106E3EAC5FEB7150001938505F811
|
:1000400091059106E3EAC5FEB71500019385050207
|
||||||
:1000500037160001130606F8B70600029386062637
|
:100050003716000113060602B7060002938606262D
|
||||||
:1000600039A083A2050023A0560091059106E3EA7A
|
:1000600039A083A2050023A0560091059106E3EA7A
|
||||||
:10007000C5FEB70500029385050337060002130687
|
:10007000C5FEB70500029385050337060002130687
|
||||||
:10008000062621A023A005009105E3EDC5FEB700DB
|
:10008000062621A023A005009105E3EDC5FEB700DB
|
||||||
:100090000001E780C00AB7000001E780C00AB7008E
|
:100090000001E780C00AB7000001E780C00AB7107E
|
||||||
:1000A0000001E780207B73005010F5BF82800000C4
|
:1000A0000001E780808473005010F5BF828000005B
|
||||||
:1000B0000000000000000000000000000000000040
|
:1000B0000000000000000000000000000000000040
|
||||||
:1000C0006F004000197106C20AC40EC612C816CAD3
|
:1000C0006F004000197106C20AC40EC612C816CAD3
|
||||||
:1000D0001ACC1ECE22D026D22AD42ED632D836DA48
|
:1000D0001ACC1ECE22D026D22AD42ED632D836DA48
|
||||||
@ -39,213 +39,223 @@
|
|||||||
:1002500008009387074023A0070023A2070023A4D8
|
:1002500008009387074023A0070023A2070023A4D8
|
||||||
:10026000070023A607007D57D8CF23A40702B7179E
|
:10026000070023A607007D57D8CF23A40702B7179E
|
||||||
:100270000500938707C09843F1769386F63F758F04
|
:100270000500938707C09843F1769386F63F758F04
|
||||||
:1002800098C398471377F7BF98C7B7070500D84FAB
|
:1002800098C398471377F7BF98C7B7070500094782
|
||||||
:1002900023AE07008280B71708009387074088D7EE
|
:1002900098D38280B71708009387074088D7D84F34
|
||||||
:1002A000D84F137707046DDF8280370700020323DE
|
:1002A000137707046DDF82803707000203234704BA
|
||||||
:1002B000C703B706000237150800B7450F0023A093
|
:1002B000B706000237150800B7450F0023A406044F
|
||||||
:1002C000060481470146130505409385152403283C
|
:1002C0008147014613050540938515240328C50180
|
||||||
:1002D000C501B308F30013780802630C080205C2D5
|
:1002D000B308F30013780802630C080205C2232256
|
||||||
:1002E000232E170337470F0023A0F6041307072414
|
:1002E000170537470F0023A4F60413070724639765
|
||||||
:1002F0006397E700B707000205472383E700B717B6
|
:1002F000E700B707000205472383E700B7170800A8
|
||||||
:10030000080093870740C853420541818280054613
|
:1003000093870740C85342054181828005467DBFDF
|
||||||
:100310007DBF8507E39DB7FE7DD2B7470F0093876A
|
:100310008507E39DB7FE7DD2B7470F00938707247B
|
||||||
:10032000072423A0F604232E1703E9B7411106C6BC
|
:1003200023A4F60423221705E9B7411106C622C407
|
||||||
:1003300022C426C2AA84EF003019E1689388086AB3
|
:1003300026C2AA84EF00B022E1689388086A0148C7
|
||||||
:1003400001488147014781460146B70520C72685F8
|
:100340008147014781460146B70520C72685379476
|
||||||
:1003500037949800EF00A07C130414687D1419E40E
|
:100350009800EF003006130414687D1419E40D456D
|
||||||
:100360000D45B24022449244410182808545268554
|
:10036000B240224492444101828085452685EF00B7
|
||||||
:10037000EF00F01605897DF10145E5B7411122C472
|
:10037000702005897DF10145E5B7411122C437049C
|
||||||
:1003800037040002930704008C43B70700804AC07B
|
:100380000002930704008C43B70700804AC0BE9563
|
||||||
:10039000BE95B707000223AAB70206C626C29397E6
|
:10039000B707000223AEB70206C626C293974501EF
|
||||||
:1003A0004501130404003709000289E71305890099
|
:1003A000130404003709000289E713058900EF00F0
|
||||||
:1003B000EF0010200C40B70400029386440413069B
|
:1003B00090290C40B70400029386C4041306001071
|
||||||
:1003C000001013058900EF00F0191C4037070002E8
|
:1003C00013058900EF0070231C4037070002835695
|
||||||
:1003D00083562703938707101CC013060010B687A7
|
:1003D0008703938707101CC013060010B68763F4C9
|
||||||
:1003E00063F4C60093070010138444041305F4005B
|
:1003E000C600930700101384C4041305F400938718
|
||||||
:1003F000938707F01306100F814513040410231987
|
:1003F00007F01306100F814513040410231CF702A5
|
||||||
:10040000F702893BA285138544043D46EF00901E08
|
:10040000913BA2851385C4043D46EF0010282320AC
|
||||||
:1004100023200400232204002324040023160400C4
|
:1004100004002322040023240400231604002307DD
|
||||||
:1004200023070400B24022449244024941018280E1
|
:100420000400B240224492440249410182805D713D
|
||||||
:100430005D71130680028145280886C6213BBD47B1
|
:10043000130680028145280886C6293BBD47230C48
|
||||||
:10044000230CF1008947230EF1003ED2E177938718
|
:10044000F1008947230EF1003ED2E1779387070838
|
||||||
:1004500007082C080A85231AF1028523B64061613A
|
:100450002C080A85231AF102E52BB64061618280DF
|
||||||
:1004600082805D71A2C4370400021305840086C631
|
:100460005D71A2C4370400021305840086C6A6C2CB
|
||||||
:10047000A6C2092D13058400EF00207489451305D9
|
:10047000CAC0652513058400EF00807D85451305FE
|
||||||
:100480008400EF00D0059377250085E3AA84854595
|
:100480008400EF00300F8D47814463E3A700AA8406
|
||||||
:1004900013058400EF00B00413E62400AA85137648
|
:10049000894513058400EF00F00D937725002A8627
|
||||||
:1004A000F60F13058400EF00F006E1689388086AF0
|
:1004A00089E7136625001376F60FA68513058400E9
|
||||||
:1004B00001488147014781460146B70520381305A9
|
:1004B000EF00B00FE1689388086A0148814701475F
|
||||||
:1004C0008400B12DE16838009388086A130800029F
|
:1004C00081460146B705203813058400E525E1681B
|
||||||
:1004D000854681470146B70599EB1305840023043F
|
:1004D00038009388086A1308000285468147014660
|
||||||
:1004E0000100352DB715000151469385C5F368000D
|
:1004E000B70599EB1305840023040100E125B71536
|
||||||
:1004F000EF005010930484009C406C0051463ED0A5
|
:1004F00000015146938505FD6800EF0010191309AE
|
||||||
:1005000085473ED26810C1673ED4EF00B00EB706F3
|
:100500008400832709006C0051463ED085473ED2C7
|
||||||
:1005100007009C423707F1FF7D17F98F08109CC236
|
:100510006810C1673ED4EF005017B70607009C4231
|
||||||
:100520006523B6402644964461618280411106C627
|
:100520003707F1FF7D17F98F08109CC20D2DB640DB
|
||||||
:10053000393B053FB707008073905730B700008004
|
:1005300026449644064961618280411106C6013B0A
|
||||||
:100540008290B240410182804111B707000222C46B
|
:100540000537B707008073905730B700008082905E
|
||||||
:100550001387070006C68346670005471384070014
|
:10055000B2404101828041113707000222C406C621
|
||||||
:10056000639EE600B717080093870740D84F218B9A
|
:100560009307070083C76700854613040700638E5F
|
||||||
:1005700009C7D84F13678700D8CF4D3F2303040026
|
:10057000D70009476388E70023030400B240224400
|
||||||
:10058000B240224441018280411106C622C426C2E3
|
:10058000410182801305000F3133B71708009387AC
|
||||||
:100590004AC08347350005476383E70811472A842B
|
:100590000740D84F218B09C7D84F13678700D8CFA2
|
||||||
:1005A0006389E7008DCFB240224492440249410161
|
:1005A000693FD9BF411106C622C426C24AC083474B
|
||||||
:1005B0008280B707000283D7270391C3C1338347E3
|
:1005B000350005476383E70811472A846389E7000C
|
||||||
:1005C000440003475400E2074207BA973707000286
|
:1005C0008DCFB24022449244024941018280B70754
|
||||||
:1005D000232CF702370700022320F700E9B7370979
|
:1005D000000283D7870391C34D3383474400034709
|
||||||
:1005E000000283542903034605009305450037059F
|
:1005E0005400E2074207BA97370700022320F704B6
|
||||||
:1005F0000002130545042695EF00C07F83470400E1
|
:1005F000370700022320F700E9B7370900028354C8
|
||||||
:10060000BE94C204C180231999029307F00FE3FC42
|
:1006000089030346050093054500370500021305DD
|
||||||
:1006100097F82244B24092440249410185B33D45D6
|
:10061000C5042695EF00700783470400BE94C2040A
|
||||||
:100620009D39B707000283D7270391C3813B22443A
|
:10062000C180231C99029307F00FE3FC97F8224442
|
||||||
:10063000B240924402494101D5BD370700029307F9
|
:10063000B24092440249410189B33D45A139B7070F
|
||||||
:100640000700B705000203DE470083A7050437163D
|
:10064000000283D7870391C30D3B2244B2409244FA
|
||||||
:10065000080037450F0037480F00B7080002014374
|
:1006500002494101DDB53707000241119306070049
|
||||||
:1006600081461307070013060640130515241308D7
|
:1006600003DF460026C4B704000283A2840422C626
|
||||||
:1006700008249388481563EEC6016304030023A091
|
:100670003715080037040002B7480F0037430F0052
|
||||||
:10068000F50483476700A9E7370500021305451500
|
:10068000370E00024AC28147232A04021309FFFFE2
|
||||||
:10069000E5BD81470323C60113730302631F0300F3
|
:10069000814E814681458143014801461307070089
|
||||||
:1006A0008507E399A7FEB7470F009387072423A088
|
:1006A000130505409388182413030324130ECE1555
|
||||||
:1006B000F50485472303F7008280E38607FF832E36
|
:1006B000636FE60363850E0009462303C70089C6FE
|
||||||
:1006C00046023383D80085062300D301054365B76E
|
:1006C000B7060002A388F60299C1232A74026304C4
|
||||||
:1006D0008280011122CC4EC652C437040002B749B1
|
:1006D000080023A4540483476700A9E73244A244D6
|
||||||
:1006E0000F00371ADCBA26CA4AC856C25AC006CE0C
|
:1006E0001249370500021305C515410165BD814258
|
||||||
:1006F00013040400370900029389F923930A0003C5
|
:1006F0000328C50113780802631B08028502E399E9
|
||||||
:10070000B7040002391A370B000245368327C903A4
|
:1007000012FF89C6B7060002A388F60299C1232A00
|
||||||
:10071000A303A40063F3F900113D8347640099C368
|
:100710007402B7470F009387072423A4F404854786
|
||||||
:100720002535E5B7834674006388560593070006B0
|
:100720002303F7003244A244124941018280E38A44
|
||||||
:100730006381F60603C704038D47998F8E07B3576D
|
:1007300062FC03284502937FF80F637D260113783E
|
||||||
:10074000FA0093F7F70F6393F6069307170093F7F2
|
:10074000F80FC29385453308CE002300F801050653
|
||||||
:10075000F70F2388F4021147639DE7003D45253ECE
|
:100750000548B9BFB307704093F7F70F6394FF00E4
|
||||||
:1007600013058B00E13629C11305000F2D362388B0
|
:100760008546D5B7854EEDBF011122CC4EC652C489
|
||||||
:100770000402232E090251BF3D45232E090223887E
|
:1007700037040002B7490F00371ADCBA26CA4AC844
|
||||||
:100780000402113E1D3605052312A4003D45213605
|
:1007800056C25AC006CE13040400370900029389EA
|
||||||
:10079000ADBF3D45232E090223880402ED3C713D87
|
:10079000F923930A0003B7040002391A370B000249
|
||||||
:1007A00083476400B5FFDDB73D45C9B72388040220
|
:1007A000213683274904A303A40063F3F9007133BE
|
||||||
:1007B000A9BF011106CE22CCA539370400021305CA
|
:1007B0008347640099C34533E5B783467400638873
|
||||||
:1007C0008400C92413058400CD2EE1689388086A4B
|
:1007C0005605930700066381F60603C704038D47A9
|
||||||
:1007D00001488147780085460146B705D9EB1305E6
|
:1007D000998F8E07B357FA0093F7F70F6393F606D6
|
||||||
:1007E000840023060100252EE1689388086A0148E9
|
:1007E0009307170093F7F70F2388F4021147639DCF
|
||||||
:1007F0008147014781460146B70538FF130584004C
|
:1007F000E7003D45453413058B00053E29C113052F
|
||||||
:10080000392EED3AF9350547AA876305E502094710
|
:10080000000F493C238804022322090451BF3D45BF
|
||||||
:100810006300E506054591EBB7060600DC4A7D77E7
|
:100810002322090423880402B53C793405052312F8
|
||||||
:100820001307F73FF98FDCCA014582807D1719EB6A
|
:10082000A4003D45853CADBF3D45232209042388F6
|
||||||
:100830000D4582809306004037A707001307071273
|
:1008300004028D340D3583476400B5FFDDB73D45B7
|
||||||
:10084000B7050500905D7D8E75D2370606005C4ABF
|
:10084000C9B723880402A9BF011106CE22CCC53640
|
||||||
:100850007D771307F73FF98FD58F41115CCA02C628
|
:100850003704000213058400C92413058400CD2E3B
|
||||||
:1008600013073006B2476359F70001454101828002
|
:10086000E1689388086A0148814778008546014617
|
||||||
:10087000856693860680C9B7B24785073EC6DDB751
|
:10087000B705D9EB1305840023060100252EE16896
|
||||||
:1008800091476307F50263EAA7008547630AF50409
|
:100880009388086A01488147014781460146B705B8
|
||||||
:1008900089476309F50405458280A147E31DF5FEFC
|
:1008900038FF13058400392E9532F9350547AA87AC
|
||||||
:1008A0000947094501A8FD1781EFC8D20D4582808F
|
:1008A0006305E50209476300E506054591EBB706D8
|
||||||
:1008B00005470D45B7A7070093870712B706050040
|
:1008B0000600DC4A7D771307F73FF98FDCCA014554
|
||||||
:1008C000905E798E6DD28A05C98D4111CCD202C657
|
:1008C00082807D1719EB0D4582809306004037A783
|
||||||
:1008D00013073006B247635AF70001454101828091
|
:1008D000070013070712B7050500905D7D8E75D2DE
|
||||||
:1008E0001147C9BF21470145F1B7B24785073EC649
|
:1008E000370606005C4A7D771307F73FF98FD58FEF
|
||||||
:1008F000D5B70547AA876305E50209476302E50600
|
:1008F00041115CCA02C613073006B2476359F700BC
|
||||||
:10090000054591EBB70606009C4A7D771307F73F34
|
:10090000014541018280856693860680C9B7B2475A
|
||||||
:10091000F98F9CCA014582807D1719EB0D458280B5
|
:1009100085073EC6DDB791476307F50263EAA70086
|
||||||
:100920009306004037A7070013070712B705050015
|
:100920008547630AF50489476309F5040545828014
|
||||||
:10093000905D7D8E75D2370706001C4B7D761306C1
|
:10093000A147E31DF5FE0947094501A8FD1781EF11
|
||||||
:10094000F63FF18FD58F1CCB85471CCF411102C6D6
|
:10094000C8D20D45828005470D45B7A7070093879C
|
||||||
:1009500013073006B2476359F70001454101828011
|
:100950000712B7060500905E798E6DD28A05C98DA3
|
||||||
:100960008566938606807DBFB24785073EC6DDB7A4
|
:100960004111CCD202C613073006B247635AF700D2
|
||||||
:1009700011C98547630DF50205458280FD1791EB8E
|
:100970000145410182801147C9BF21470145F1B7B7
|
||||||
:100980000D4582800946B7A7070093870712B7066F
|
:10098000B24785073EC6D5B70547AA876305E50286
|
||||||
:100990000500985E718F7DD34111C8D602C613073A
|
:1009900009476302E506054591EBB70606009C4A48
|
||||||
:1009A0003006B2476357F700014541018280054692
|
:1009A0007D771307F73FF98F9CCA014582807D1739
|
||||||
:1009B000D9BFB24785073EC6EDB7011126CAB704B5
|
:1009B00019EB0D4582809306004037A70700130707
|
||||||
:1009C0000600DC4806CE22CC4AC84EC652C456C2E7
|
:1009C0000712B7050500905D7D8E75D237070600CA
|
||||||
:1009D000F19BDCC89C482A89C845F19B9CC883C709
|
:1009D0001C4B7D761306F63FF18FD58F1CCB8547D8
|
||||||
:1009E000C5012E848A07DCC883C7D5018A079CC845
|
:1009E0001CCF411102C613073006B2476359F70006
|
||||||
:1009F000193D0C44AA8A0345440059351848B707E5
|
:1009F0000145410182808566938606807DBFB247AE
|
||||||
:100A000005002A8A98C358480850D8C3184C98C77C
|
:100A000085073EC6DDB711C98547630DF50205456B
|
||||||
:100A1000CD35AA894850A93F834704002A8793F619
|
:100A10008280FD1791EB0D4582800946B7A707003C
|
||||||
:100A2000170089E6D44893E62600D4C893F6270039
|
:100A200093870712B7060500985E718F7DD3411139
|
||||||
:100A300099E637060600544A93E6160054CA93F620
|
:100A3000C8D602C613073006B2476357F700014510
|
||||||
:100A4000470099E637060600144A93E6260014CAC2
|
:100A4000410182800546D9BFB24785073EC6EDB752
|
||||||
:100A5000A18B99E7B70606009C4A93E717009CCA4A
|
:100A5000011126CAB7040600DC4806CE22CC4AC8DB
|
||||||
:100A6000F240624423205901232249012324390101
|
:100A60004EC652C456C2F19BDCC89C482A89C84570
|
||||||
:100A70002326E900D244B249224A924A4A85424991
|
:100A7000F19B9CC883C7C5012E848A07DCC883C745
|
||||||
:100A800005618280011106CE22CC02C402C6214734
|
:100A8000D5018A079CC8193D0C44AA8A0345440035
|
||||||
:100A9000B707050037550800D8C705448D478A8534
|
:100A900059351848B70705002A8A98C3584808509E
|
||||||
:100AA000130505803EC022C2292A37550800930746
|
:100AA000D8C3184C98C7CD35AA894850A93F834769
|
||||||
:100AB000C0038A851305058022C222C43EC01122CC
|
:100AB00004002A8793F6170089E6D44893E62600B7
|
||||||
:100AC000F240624405618280411122C406C62A8434
|
:100AC000D4C893F6270099E637060600544A93E601
|
||||||
:100AD000553F18405C4F93E707015CCF1C441CCB8B
|
:100AD000160054CA93F6470099E637060600144AF2
|
||||||
:100AE0005C4085CB1C43B7061000D58F1CC3144C4B
|
:100AE00093E6260014CAA18B99E7B70606009C4A34
|
||||||
:100AF0005C48B240D606CE07D58F83460401C206B5
|
:100AF00093E717009CCAF240624423205901232245
|
||||||
:100B0000D58F8346C4012244E206D58F1CCF410114
|
:100B00004901232439012326E900D244B249224A6B
|
||||||
:100B100082801C43B706F0FFFD16F58FC1BF03238B
|
:100B1000924A4A85424905618280011106CE22CC63
|
||||||
:100B200005002A8E0325C30113650502232EA300A9
|
:100B200002C402C62147B707050037550800D8C7D9
|
||||||
:100B30002324C3001396260149824D8E23260301E8
|
:100B300005448D478A85130505803EC022C2292AB7
|
||||||
:100B40002322C300139605016354060299C205458A
|
:100B4000375508009307C0038A851305058022C224
|
||||||
:100B5000B1CB01476346D700639C08020D458280F4
|
:100B500022C43EC01122F2406244056182804111EC
|
||||||
:100B60003386E700034606000507230AC300DDB706
|
:100B600022C406C62A84553F18405C4F93E707010C
|
||||||
:100B700099C2054505CB8147E3D0D7FE03260E0079
|
:100B70005CCF1C441CCB5C4085CB1C43B7061000EB
|
||||||
:100B8000034546013306F70085072300A600EDB7AD
|
:100B8000D58F1CC3144C5C48B240D606CE07D58F17
|
||||||
:100B900083270E00FD18DC4F93F70702D5DF1165A0
|
:100B900083460401C206D58F8346C4012244E2067F
|
||||||
:100BA0006D8D11E18280B707070083C7470113F5F8
|
:100BA000D58F1CCF410182801C43B706F0FFFD1694
|
||||||
:100BB00085001D8D3335A00082801C414147D8CF70
|
:100BB000F58FC1BF032305002A8E0325C3011365EA
|
||||||
:100BC0008280B7470800938707402A886304F508A6
|
:100BC0000502232EA3002324C30013962601498285
|
||||||
:100BD000B7570800938707806304F50A3747080072
|
:100BD0004D8E232603012322C3001396050163547F
|
||||||
:100BE000630DE50A05458280331E1F013376DE0161
|
:100BE000060299C20545B1CB01476346D700639C15
|
||||||
:100BF00029C683A3450088431393180033966F00DA
|
:100BF00008020D4582803386E7000346060005079C
|
||||||
:100C00001346F6FF13F43300718D33146400418DE5
|
:100C0000230AC300DDB799C2054505CB8147E3D070
|
||||||
:100C100088C3638B5302638C0302084303AEC50091
|
:100C1000D7FE03260E00034546013306F70085077D
|
||||||
:100C2000718D331E6E003365C50108C38842698E1D
|
:100C20002300A600EDB783270E00FD18DC4F93F7D5
|
||||||
:100C3000884533156500498E90C2850833D51E015D
|
:100C30000702D5DF11656D8D11E18280B7070700CE
|
||||||
:100C400045F53244410182802326C801F9B72324A7
|
:100C400083C7470113F585001D8D3335A0008280D1
|
||||||
:100C5000C801E1B7B716050037170500B71705003B
|
:100C50001C414147D8CF8280B7470800938707409F
|
||||||
:100C6000938646C1130707C19387C7C083AE0500AB
|
:100C60002A886304F508B757080093870780630450
|
||||||
:100C70008148054F8D4F914233D51E0105ED82808D
|
:100C7000F50A37470800630DE50A05458280331EF3
|
||||||
:100C8000B716050037170500B7170500938606C28B
|
:100C80001F013376DE0129C683A3450088431393F1
|
||||||
:100C90001307C7C1938787C1D1BFB71605003717A0
|
:100C9000180033966F001346F6FF13F43300718D7E
|
||||||
:100CA0000500B7170500938686C0130747C09387D2
|
:100CA00033146400418D88C3638B5302638C030249
|
||||||
:100CB00007C06DBF331E1F013376DE0119E28508C0
|
:100CB000084303AEC500718D331E6E003365C50158
|
||||||
:100CC00065BF411122C635B7E1689388086A0148BB
|
:100CC00008C38842698E884533156500498E90C2F5
|
||||||
:100CD0008147014781460146B705200689B50111C4
|
:100CD000850833D51E0145F5324441018280232623
|
||||||
:100CE00006CEA307010089476393F502B7052035B7
|
:100CE000C801F9B72324C801E1B7B71605003717C3
|
||||||
:100CF000E1681307F1009388086A01488147854637
|
:100CF0000500B7170500938646C1130707C1938700
|
||||||
:100D00000146313DF2400345F10005618280B7059F
|
:100D0000C7C083AE05008148054F8D4F914233D552
|
||||||
:100D10002005F9BF011106CE22CC26CA2306B10058
|
:100D10001E0105ED8280B716050037170500B717CD
|
||||||
:100D2000AA84A306C1004D37E1689388086A014888
|
:100D20000500938606C21307C7C1938787C1D1BF49
|
||||||
:100D30007C00014789460146B78520012685096464
|
:100D3000B716050037170500B7170500938686C05C
|
||||||
:100D4000F93B130414717D1419E40D45F24062441B
|
:100D4000130747C0938707C06DBF331E1F0133765B
|
||||||
:100D5000D24405618280854526855137058965F530
|
:100D5000DE0119E2850865BF411122C635B7E16899
|
||||||
:100D60000145EDB7011106CE22CC26CA2E844AC811
|
:100D60009388086A01488147014781460146B705D3
|
||||||
:100D7000AA84328936C6893FB247E16822869388C1
|
:100D7000200689B5011106CEA307010089476393B8
|
||||||
:100D8000086A01480147CA86B785800226856164E2
|
:100D8000F502B7052035E1681307F1009388086A7A
|
||||||
:100D900079331304146A7D1411C48545268581377F
|
:100D90000148814785460146313DF2400345F10057
|
||||||
:100DA000058975F9F2406244D24442490561828066
|
:100DA00005618280B7052005F9BF011106CE22CC6E
|
||||||
:100DB000011106CE22CC26CA2EC6AA84313732466D
|
:100DB00026CA2306B100AA84A306C1004D37E16804
|
||||||
:100DC000E1689388086A0148814701478146B70571
|
:100DC0009388086A01487C00014789460146B78537
|
||||||
:100DD000802026856164A1331304146A7D1411C434
|
:100DD000200126850964F93B130414717D1419E47C
|
||||||
:100DE00085452685ED3D058975F9F2406244D2447A
|
:100DE0000D45F2406244D2440561828085452685E6
|
||||||
:100DF00005618280B3C7A5008D8BB308C500B1E73C
|
:100DF0005137058965F50145EDB7011106CE22CCC5
|
||||||
:100E00008D4763F4C704937735002A87B9EB13F64F
|
:100E000026CA2E844AC8AA84328936C6893FB24788
|
||||||
:100E1000C8FFB306E6409307000263C8D706AE8654
|
:100E1000E16822869388086A01480147CA86B78537
|
||||||
:100E2000BA876371C70203A806009107910623AE33
|
:100E200080022685616479331304146A7D1411C429
|
||||||
:100E300007FFE3EAC7FE9307F6FF998FF19B91073F
|
:100E3000854526858137058975F9F2406244D2449B
|
||||||
:100E40003E97BE956366170182802A87637E1503ED
|
:100E4000424905618280011106CE22CC26CA2EC6F7
|
||||||
:100E500083C7050005078505A30FF7FEE39AE8FEA3
|
:100E5000AA8431373246E1689388086A014881479D
|
||||||
:100E6000828083C60500050793773700A30FD7FE5E
|
:100E600001478146B705802026856164A1331304BC
|
||||||
:100E70008505D1DF83C60500050793773700A30FEB
|
:100E7000146A7D1411C485452685ED3D058975F9F3
|
||||||
:100E8000D7FE8505F9FF61B78280411122C61304A0
|
:100E8000F2406244D24405618280B3C7A5008D8BD5
|
||||||
:100E9000000283A3050083A2450083AF850003AF52
|
:100E9000B308C500B1E78D4763F4C7049377350005
|
||||||
:100EA000C50083AE050103AE450103A3850103A878
|
:100EA0002A87B9EB13F6C8FFB306E64093070002A2
|
||||||
:100EB000C501945113074702B307E640232E77FC80
|
:100EB00063C8D706AE86BA876371C70203A8060067
|
||||||
:100EC000232057FE2322F7FF2324E7FF2326D7FF03
|
:100EC0009107910623AE07FFE3EAC7FE9307F6FFFB
|
||||||
:100ED0002328C7FF232A67FE232C07FF232ED7FED4
|
:100ED000998FF19B91073E97BE95636617018280BB
|
||||||
:100EE00093854502E347F4FAAE86BA876371C70279
|
:100EE0002A87637E150383C7050005078505A30FC1
|
||||||
:100EF00003A806009107910623AE07FFE3EAC7FEA9
|
:100EF000F7FEE39AE8FE828083C605000507937734
|
||||||
:100F00009307F6FF998FF19B91073E97BE95636516
|
:100F00003700A30FD7FE8505D1DF83C6050005078F
|
||||||
:100F1000170132444101828083C70500050785051A
|
:100F100093773700A30FD7FE8505F9FF61B782806D
|
||||||
:100F2000A30FF7FEE387E8FE83C7050005078505E5
|
:100F2000411122C61304000283A3050083A24500D9
|
||||||
:100F3000A30FF7FEE392E8FEE9BF000020000000E7
|
:100F300083AF850003AFC50083AE050103AE450155
|
||||||
:100F4000010000000300000006000000EB000000AC
|
:100F400003A3850103A8C501945113074702B30702
|
||||||
:100F5000000000800000000000000700000000000A
|
:100F5000E640232E77FC232057FE2322F7FF23248D
|
||||||
:100F60000000000000000000000000000000000081
|
:100F6000E7FF2326D7FF2328C7FF232A67FE232C6A
|
||||||
:100F70000000000000000000000000000000000071
|
:100F700007FF232ED7FE93854502E347F4FAAE869A
|
||||||
|
:100F8000BA876371C70203A806009107910623AED2
|
||||||
|
:100F900007FFE3EAC7FE9307F6FF998FF19B9107DE
|
||||||
|
:100FA0003E97BE956365170132444101828083C735
|
||||||
|
:100FB000050005078505A30FF7FEE387E8FE83C755
|
||||||
|
:100FC000050005078505A30FF7FEE392E8FEE9BFDC
|
||||||
|
:100FD00020000000010000000300000006000000E7
|
||||||
|
:100FE000EB00000000000000000000000000000016
|
||||||
|
:100FF000000000800000000000000700000000006A
|
||||||
|
:1010000000000000000000000000000000000000E0
|
||||||
|
:1010100000000000000000000000000000000000D0
|
||||||
:0400000501000000F6
|
:0400000501000000F6
|
||||||
:00000001FF
|
:00000001FF
|
||||||
|
|||||||
@ -5,7 +5,7 @@
|
|||||||
#include "HardwareSerial.h"
|
#include "HardwareSerial.h"
|
||||||
#include <uart_lib.h>
|
#include <uart_lib.h>
|
||||||
#include "mik32_hal_irq.h"
|
#include "mik32_hal_irq.h"
|
||||||
|
#include "wiring_LL.h"
|
||||||
|
|
||||||
// HardwareSerial class objects for use in Arduino IDE
|
// HardwareSerial class objects for use in Arduino IDE
|
||||||
HardwareSerial Serial(0);
|
HardwareSerial Serial(0);
|
||||||
@ -127,9 +127,9 @@ void HardwareSerial::rx_complete_irq(void)
|
|||||||
unsigned char c;
|
unsigned char c;
|
||||||
// while there is something to receive, put the data into the buffer
|
// while there is something to receive, put the data into the buffer
|
||||||
// and edit the buffer index
|
// and edit the buffer index
|
||||||
while (!UART_IsRxFifoEmpty(uart))
|
while(!UART_IS_RX_FIFO_EMPTY(uart))
|
||||||
{
|
{
|
||||||
c = UART_ReadByte(uart);
|
c = UART_READ_BYTE(uart);
|
||||||
if (i != _rx_buffer_tail)
|
if (i != _rx_buffer_tail)
|
||||||
{
|
{
|
||||||
// write if there is space in the buffer
|
// write if there is space in the buffer
|
||||||
@ -140,7 +140,7 @@ void HardwareSerial::rx_complete_irq(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// wrapper for use in С-files
|
// wrapper for use in С-files
|
||||||
extern "C" void serial_handler_wrapper(uint8_t uartNumInt)
|
extern "C" void __attribute__((optimize("O3"))) serial_interrupt_handler(uint8_t uartNumInt)
|
||||||
{
|
{
|
||||||
if (uartNumInt == 0)
|
if (uartNumInt == 0)
|
||||||
{
|
{
|
||||||
|
|||||||
@ -100,7 +100,7 @@ class HardwareSerial : public Stream
|
|||||||
using Print::write; // pull in write(str)
|
using Print::write; // pull in write(str)
|
||||||
operator bool() { return isInited; }
|
operator bool() { return isInited; }
|
||||||
|
|
||||||
void rx_complete_irq(void);
|
inline void rx_complete_irq(void) __attribute__((always_inline, optimize("O3")));
|
||||||
};
|
};
|
||||||
|
|
||||||
extern HardwareSerial Serial;
|
extern HardwareSerial Serial;
|
||||||
|
|||||||
@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
#include "mik32_hal_timer16.h"
|
#include "mik32_hal_timer16.h"
|
||||||
#include "mik32_hal_irq.h"
|
#include "mik32_hal_irq.h"
|
||||||
|
#include "wiring_LL.h"
|
||||||
|
|
||||||
#define PRESCALERS_QTY 7
|
#define PRESCALERS_QTY 7
|
||||||
typedef struct
|
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);
|
HAL_EPIC_MaskLevelSet(HAL_EPIC_TIMER16_1_MASK);
|
||||||
|
|
||||||
pinMode(pin, OUTPUT);
|
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);
|
HAL_Timer16_Counter_Start_IT(&htimer16_1, frequencyParams.period_ticks);
|
||||||
timerIsOn = true;
|
timerIsOn = true;
|
||||||
@ -124,9 +125,10 @@ void noTone(uint8_t pin)
|
|||||||
{
|
{
|
||||||
if (timerIsOn)
|
if (timerIsOn)
|
||||||
{
|
{
|
||||||
timer_pin_port->CLEAR = timer_pin_mask; // pin to 0
|
// pin to 0
|
||||||
htimer16_1.Instance->CR &= ~TIMER16_CR_ENABLE_M; // disable timer
|
GPIO_CLEAR_PIN((GPIO_TypeDef *)timer_pin_port, timer_pin_mask);
|
||||||
HAL_EPIC_MaskLevelClear(HAL_EPIC_TIMER16_1_MASK);
|
TIM16_DISABLE(htimer16_1);
|
||||||
|
EPIC_LEVEL_CLEAR_BY_MASK(HAL_EPIC_TIMER16_1_MASK);
|
||||||
pinMode(pin, INPUT); // deinit pin
|
pinMode(pin, INPUT); // deinit pin
|
||||||
timer_pin = -1; // reset to default
|
timer_pin = -1; // reset to default
|
||||||
timerIsOn = false;
|
timerIsOn = false;
|
||||||
@ -134,25 +136,26 @@ void noTone(uint8_t pin)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// irq handler
|
// 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
|
// timer period has passed, change the pin state
|
||||||
if (timer_toggle_count != 0)
|
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)
|
if (timer_toggle_count > 0)
|
||||||
timer_toggle_count--;
|
timer_toggle_count--;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// turn off if the specified duration has passed
|
// turn off if the specified duration has passed
|
||||||
timer_pin_port->CLEAR = timer_pin_mask;
|
GPIO_CLEAR_PIN((GPIO_TypeDef *)timer_pin_port, timer_pin_mask);
|
||||||
noTone(timer_pin);
|
TIM16_DISABLE(htimer16_1);
|
||||||
|
EPIC_LEVEL_CLEAR_BY_MASK(HAL_EPIC_TIMER16_1_MASK);
|
||||||
|
timerIsOn = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// reset timer interrupt flags
|
// reset timer interrupt flags
|
||||||
htimer16_1.Instance->ICR = 0xFFFFFFFF;
|
TIM16_CLEAR_INT_MASK(htimer16_1, 0xFFFFFFFF);
|
||||||
}
|
}
|
||||||
@ -4,8 +4,7 @@
|
|||||||
#include "pins_arduino.h"
|
#include "pins_arduino.h"
|
||||||
#include "wiring_digital.h"
|
#include "wiring_digital.h"
|
||||||
#include "WInterrupts.h"
|
#include "WInterrupts.h"
|
||||||
|
#include "wiring_LL.h"
|
||||||
extern void ErrorMsgHandler(const char * msg);
|
|
||||||
|
|
||||||
typedef void (*voidFuncPtr)(void);
|
typedef void (*voidFuncPtr)(void);
|
||||||
|
|
||||||
@ -18,13 +17,13 @@ static void nothing(void)
|
|||||||
// enable global interrupts
|
// enable global interrupts
|
||||||
void interrupts(void)
|
void interrupts(void)
|
||||||
{
|
{
|
||||||
HAL_IRQ_EnableInterrupts();
|
GLOBAL_IRQ_ENABLE();
|
||||||
}
|
}
|
||||||
|
|
||||||
// disable global interrupts
|
// disable global interrupts
|
||||||
void noInterrupts(void)
|
void noInterrupts(void)
|
||||||
{
|
{
|
||||||
HAL_IRQ_DisableInterrupts();
|
GLOBAL_IRQ_DISABLE();
|
||||||
}
|
}
|
||||||
|
|
||||||
// we can provide no more than 8 interrupts on gpio at the same time
|
// 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)
|
void disableInterrupt(uint8_t interruptNum)
|
||||||
{
|
{
|
||||||
if(interruptNum < EXTERNAL_NUM_INTERRUPTS)
|
if(interruptNum < EXTERNAL_NUM_INTERRUPTS)
|
||||||
{
|
|
||||||
int irq_line_num = interruptToGpioIntLine(interruptNum) >> GPIO_IRQ_LINE_S;
|
|
||||||
// disable gpio interrupt line
|
// disable gpio interrupt line
|
||||||
GPIO_IRQ->ENABLE_CLEAR = (1 << irq_line_num);
|
GPIO_IRQ_LINE_DISABLE(interruptToGpioIntLine(interruptNum));
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// enable single interrupt
|
// enable single interrupt
|
||||||
void enableInterrupt(uint8_t interruptNum)
|
void enableInterrupt(uint8_t interruptNum)
|
||||||
{
|
{
|
||||||
if(interruptNum < EXTERNAL_NUM_INTERRUPTS)
|
if(interruptNum < EXTERNAL_NUM_INTERRUPTS)
|
||||||
{
|
|
||||||
int irq_line_num = interruptToGpioIntLine(interruptNum) >> GPIO_IRQ_LINE_S;
|
|
||||||
// enable gpio interrupt line
|
// enable gpio interrupt line
|
||||||
GPIO_IRQ->ENABLE_SET = (1 << irq_line_num);
|
GPIO_IRQ_LINE_ENABLE(interruptToGpioIntLine(interruptNum));
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// common gpio interrupt handler
|
// 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
|
// go through all the interrupts and call the handler for the triggered line
|
||||||
for (uint8_t i = 0; i < EXTERNAL_NUM_INTERRUPTS; i++)
|
for (uint8_t i = 0; i < EXTERNAL_NUM_INTERRUPTS; i++)
|
||||||
{
|
{
|
||||||
if (HAL_GPIO_LineInterruptState(interruptToGpioIntLine(i)))
|
if (GPIO_IRQ_LINE_STATE(interruptToGpioIntLine(i)))
|
||||||
intFunc[i]();
|
intFunc[i]();
|
||||||
}
|
}
|
||||||
|
GPIO_IRQ_CLEAR_ALL();
|
||||||
HAL_GPIO_ClearInterrupts();
|
|
||||||
}
|
}
|
||||||
@ -19,6 +19,8 @@
|
|||||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
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 "WString.h"
|
||||||
#include "itoa.h"
|
#include "itoa.h"
|
||||||
|
|
||||||
|
|||||||
@ -1,11 +1,15 @@
|
|||||||
#include "board.h"
|
#include "board.h"
|
||||||
#include "mik32_hal_pcc.h"
|
#include "mik32_hal_pcc.h"
|
||||||
|
#include "mik32_hal_irq.h"
|
||||||
#include "Arduino.h"
|
#include "Arduino.h"
|
||||||
|
|
||||||
// --------------------- init --------------------- //
|
// --------------------- init --------------------- //
|
||||||
// called before setup()
|
// called before setup()
|
||||||
void pre_init(void)
|
void pre_init(void)
|
||||||
{
|
{
|
||||||
|
// set irq vector to ram region
|
||||||
|
write_csr(mtvec, 0x02000000);
|
||||||
|
|
||||||
HAL_Init();
|
HAL_Init();
|
||||||
|
|
||||||
// gpio clock
|
// gpio clock
|
||||||
@ -26,11 +30,15 @@ void post_init(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// --------------------- other --------------------- //
|
// --------------------- 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)
|
extern "C" void ErrorMsgHandler(const char * msg)
|
||||||
{
|
{
|
||||||
if(Serial)
|
// function works if Serial is used in sketch and user doesn't turn it off
|
||||||
Serial.println(msg);
|
#ifdef HardwareSerial_h
|
||||||
|
if(use_error_messages&&Serial)
|
||||||
|
Serial.println(msg);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -1,6 +1,10 @@
|
|||||||
#ifndef _BOARD_H_
|
#ifndef _BOARD_H_
|
||||||
#define _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()
|
// functions for init called before and after setup()
|
||||||
void pre_init(void) ;
|
void pre_init(void) ;
|
||||||
void post_init(void);
|
void post_init(void);
|
||||||
|
|||||||
@ -7,7 +7,7 @@ extern "C" {
|
|||||||
|
|
||||||
#include "mik32_hal_def.h"
|
#include "mik32_hal_def.h"
|
||||||
#include <mcu32_memory_map.h>
|
#include <mcu32_memory_map.h>
|
||||||
#include <eeprom.h>
|
#include <eeprom_def.h>
|
||||||
#include <power_manager.h>
|
#include <power_manager.h>
|
||||||
|
|
||||||
#ifndef HAL_EEPROM_TIMEOUT
|
#ifndef HAL_EEPROM_TIMEOUT
|
||||||
|
|||||||
@ -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_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);
|
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_InitInterruptLine(HAL_GPIO_Line_Config mux, HAL_GPIO_InterruptMode mode);
|
||||||
HAL_StatusTypeDef HAL_GPIO_DeInitInterruptLine(HAL_GPIO_Line irqLine);
|
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
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|||||||
@ -380,9 +380,6 @@ typedef struct
|
|||||||
|
|
||||||
|
|
||||||
void HAL_I2C_MspInit(I2C_HandleTypeDef* hi2c);
|
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_AnalogFilterInit(I2C_HandleTypeDef *hi2c, HAL_I2C_AnalogFilterTypeDef AnalogFilter);
|
||||||
void HAL_I2C_DigitalFilterInit(I2C_HandleTypeDef *hi2c, HAL_I2C_DigitalFilterTypeDef DigitalFilter);
|
void HAL_I2C_DigitalFilterInit(I2C_HandleTypeDef *hi2c, HAL_I2C_DigitalFilterTypeDef DigitalFilter);
|
||||||
void HAL_I2C_SetClockSpeed(I2C_HandleTypeDef *hi2c);
|
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_SlaveInit(I2C_HandleTypeDef *hi2c);
|
||||||
void HAL_I2C_MasterInit(I2C_HandleTypeDef *hi2c);
|
void HAL_I2C_MasterInit(I2C_HandleTypeDef *hi2c);
|
||||||
HAL_StatusTypeDef HAL_I2C_Init(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);
|
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_WaitTXIS(I2C_HandleTypeDef *hi2c, uint32_t Timeout);
|
||||||
HAL_StatusTypeDef HAL_I2C_Master_WaitRXNE(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_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);
|
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)
|
static inline __attribute__((always_inline)) void HAL_I2C_ADDR_IRQ(I2C_HandleTypeDef *hi2c)
|
||||||
{
|
{
|
||||||
if (hi2c->Instance->CR1 & I2C_CR1_SBC_M)
|
if (hi2c->Instance->CR1 & I2C_CR1_SBC_M)
|
||||||
|
|||||||
@ -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_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_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);
|
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 Разрешить прерывания в соответствии с маской.
|
* @brief Разрешить прерывания в соответствии с маской.
|
||||||
|
|||||||
@ -230,8 +230,6 @@ typedef struct __Timer16_HandleTypeDef
|
|||||||
|
|
||||||
|
|
||||||
void HAL_TIMER16_MspInit(Timer16_HandleTypeDef* htimer16);
|
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_SetActiveEdge(Timer16_HandleTypeDef *htimer16, uint8_t ActiveEdge);
|
||||||
void HAL_Timer16_SetSourceClock(Timer16_HandleTypeDef *htimer16, uint8_t SourceClock);
|
void HAL_Timer16_SetSourceClock(Timer16_HandleTypeDef *htimer16, uint8_t SourceClock);
|
||||||
void HAL_Timer16_SetCountMode(Timer16_HandleTypeDef *htimer16, uint8_t CountMode);
|
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_SetInterruptCMPM(Timer16_HandleTypeDef *htimer16);
|
||||||
void HAL_Timer16_InterruptInit(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.
|
* @brief Получить статус прерываний Timer16.
|
||||||
* Функция возвращает статус прерываний в соответствии с маской разрешенный прерываний.
|
* Функция возвращает статус прерываний в соответствии с маской разрешенный прерываний.
|
||||||
@ -291,6 +309,16 @@ static inline __attribute__((always_inline)) uint32_t HAL_Timer16_GetInterruptSt
|
|||||||
return interrupt_status;
|
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 Очистить флаг прерывания.
|
* @brief Очистить флаг прерывания.
|
||||||
* @param htimer16 Указатель на структуру с настройками Timer16.
|
* @param htimer16 Указатель на структуру с настройками Timer16.
|
||||||
|
|||||||
@ -226,6 +226,7 @@ static inline __attribute__((always_inline)) HAL_StatusTypeDef HAL_Timer32_WaitF
|
|||||||
void HAL_TIMER32_MspInit(TIMER32_HandleTypeDef* htimer32);
|
void HAL_TIMER32_MspInit(TIMER32_HandleTypeDef* htimer32);
|
||||||
void HAL_TIMER32_Channel_MspInit(TIMER32_CHANNEL_HandleTypeDef* timerChannel);
|
void HAL_TIMER32_Channel_MspInit(TIMER32_CHANNEL_HandleTypeDef* timerChannel);
|
||||||
HAL_StatusTypeDef HAL_Timer32_Init(TIMER32_HandleTypeDef *timer);
|
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_State_Set(TIMER32_HandleTypeDef *timer, HAL_TIMER32_StateTypeDef state);
|
||||||
void HAL_Timer32_Top_Set(TIMER32_HandleTypeDef *timer, uint32_t top);
|
void HAL_Timer32_Top_Set(TIMER32_HandleTypeDef *timer, uint32_t top);
|
||||||
void HAL_Timer32_Prescaler_Set(TIMER32_HandleTypeDef *timer, uint32_t prescaler);
|
void HAL_Timer32_Prescaler_Set(TIMER32_HandleTypeDef *timer, uint32_t prescaler);
|
||||||
|
|||||||
@ -93,58 +93,6 @@ HAL_StatusTypeDef HAL_GPIO_PinConfig(GPIO_TypeDef *GPIO_x, HAL_PinsTypeDef pin,
|
|||||||
return HAL_GPIO_Init(GPIO_x, &GPIO_InitStruct);
|
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 Функция инициализации линии прерывания.
|
* @brief Функция инициализации линии прерывания.
|
||||||
* \param mux настройка мультиплексора линии прерывания.
|
* \param mux настройка мультиплексора линии прерывания.
|
||||||
@ -222,39 +170,3 @@ HAL_StatusTypeDef HAL_GPIO_DeInitInterruptLine(HAL_GPIO_Line irqLine)
|
|||||||
|
|
||||||
return HAL_OK;
|
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;
|
|
||||||
}
|
|
||||||
|
|||||||
@ -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)
|
void HAL_I2C_AnalogFilterInit(I2C_HandleTypeDef *hi2c, HAL_I2C_AnalogFilterTypeDef AnalogFilter)
|
||||||
{
|
{
|
||||||
hi2c->Init.AnalogFilter = AnalogFilter;
|
hi2c->Init.AnalogFilter = AnalogFilter;
|
||||||
@ -244,6 +226,24 @@ HAL_StatusTypeDef HAL_I2C_Init(I2C_HandleTypeDef *hi2c)
|
|||||||
return HAL_OK;
|
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)
|
void HAL_I2C_AutoEnd(I2C_HandleTypeDef *hi2c, HAL_I2C_AutoEndModeTypeDef AutoEnd)
|
||||||
{
|
{
|
||||||
hi2c->Instance->CR2 &= ~I2C_CR2_AUTOEND_M;
|
hi2c->Instance->CR2 &= ~I2C_CR2_AUTOEND_M;
|
||||||
|
|||||||
@ -282,6 +282,37 @@ HAL_StatusTypeDef HAL_SPI_Init(SPI_HandleTypeDef *hspi)
|
|||||||
return error_code;
|
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.
|
* @brief Очистить буфер TX_FIFO.
|
||||||
*
|
*
|
||||||
|
|||||||
@ -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 Установить активный фронт для подсчёта или задать подрежим энкодера.
|
* @brief Установить активный фронт для подсчёта или задать подрежим энкодера.
|
||||||
* Используется при тактировании Timer16 от внешнего источника тактового сигнала на выводе Input1.
|
* Используется при тактировании Timer16 от внешнего источника тактового сигнала на выводе Input1.
|
||||||
|
|||||||
@ -78,6 +78,41 @@ HAL_StatusTypeDef HAL_Timer32_Init(TIMER32_HandleTypeDef *timer)
|
|||||||
return HAL_OK;
|
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)
|
void HAL_Timer32_State_Set(TIMER32_HandleTypeDef *timer, HAL_TIMER32_StateTypeDef state)
|
||||||
{
|
{
|
||||||
timer->State = state;
|
timer->State = state;
|
||||||
@ -199,7 +234,7 @@ HAL_StatusTypeDef HAL_Timer32_Channel_Init(TIMER32_CHANNEL_HandleTypeDef *timerC
|
|||||||
return HAL_ERROR;
|
return HAL_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
HAL_TIMER32_Channel_MspInit(timerChannel);
|
// HAL_TIMER32_Channel_MspInit(timerChannel); // здесь инициализируются сразу все каналы выбранного таймера, а нам такого не надо
|
||||||
|
|
||||||
timerChannel->Instance = (TIMER32_CHANNEL_TypeDef *)&(timerChannel->TimerInstance->CHANNELS[timerChannel->ChannelIndex]);
|
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;
|
return HAL_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
timerChannel->Instance = (TIMER32_CHANNEL_TypeDef *)&(timerChannel->TimerInstance->CHANNELS[timerChannel->ChannelIndex]);
|
||||||
|
|
||||||
HAL_Timer32_Channel_Disable(timerChannel);
|
HAL_Timer32_Channel_Disable(timerChannel);
|
||||||
HAL_Timer32_Channel_CaptureEdge_Set(timerChannel, 0);
|
HAL_Timer32_Channel_CaptureEdge_Set(timerChannel, 0);
|
||||||
HAL_Timer32_Channel_ICR_Clear(timerChannel);
|
HAL_Timer32_Channel_ICR_Clear(timerChannel);
|
||||||
|
|||||||
@ -10,33 +10,49 @@ MEMORY {
|
|||||||
}
|
}
|
||||||
|
|
||||||
STACK_SIZE = 1024;
|
STACK_SIZE = 1024;
|
||||||
|
HEAP_SIZE = 1024;
|
||||||
|
|
||||||
CL_SIZE = 16;
|
CL_SIZE = 16;
|
||||||
|
|
||||||
SECTIONS {
|
SECTIONS {
|
||||||
.text ORIGIN(ram) : {
|
.text ORIGIN(ram) : {
|
||||||
PROVIDE(__TEXT_START__ = .);
|
PROVIDE(__TEXT_START__ = .);
|
||||||
*crt0.o(.text .text.*)
|
*crt0.S.o(.text .text.*)
|
||||||
*(.text.smallsysteminit)
|
*(.text.smallsysteminit)
|
||||||
*(.text.SmallSystemInit)
|
*(.text.SmallSystemInit)
|
||||||
. = ORIGIN(ram) + 0xC0;
|
. = ORIGIN(ram) + 0xC0;
|
||||||
KEEP(*crt0.o(.trap_text))
|
KEEP(*crt0.S.o(.trap_text))
|
||||||
|
|
||||||
*(.text)
|
*(.text)
|
||||||
*(.text.*)
|
*(.text.*)
|
||||||
*(.rodata)
|
*(.rodata)
|
||||||
*(.rodata.*)
|
*(.rodata.*)
|
||||||
. = ALIGN(CL_SIZE);
|
. = ALIGN(CL_SIZE);
|
||||||
PROVIDE(__TEXT_END__ = .);
|
|
||||||
} >ram
|
} >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 :
|
.data :
|
||||||
AT( __TEXT_END__ ) {
|
AT( __TEXT_END__ ) {
|
||||||
PROVIDE(__DATA_START__ = .);
|
PROVIDE(__DATA_START__ = .);
|
||||||
_gp = .;
|
_gp = .;
|
||||||
*(.srodata.cst16) *(.srodata.cst8) *(.srodata.cst4) *(.srodata.cst2) *(.srodata*)
|
*(.srodata.cst16) *(.srodata.cst8) *(.srodata.cst4) *(.srodata.cst2) *(.srodata*)
|
||||||
*(.sdata .sdata.* .gnu.linkonce.s.*)
|
*(.sdata .sdata.* .sdata* .sdata*.* .gnu.linkonce.s.*)
|
||||||
*(.data .data.*)
|
*(.data .data.*)
|
||||||
|
*(.ramfunc)
|
||||||
. = ALIGN(CL_SIZE);
|
. = ALIGN(CL_SIZE);
|
||||||
} >ram
|
} >ram
|
||||||
|
|
||||||
@ -72,12 +88,19 @@ SECTIONS {
|
|||||||
PROVIDE(__BSS_END__ = .);
|
PROVIDE(__BSS_END__ = .);
|
||||||
} >ram
|
} >ram
|
||||||
|
|
||||||
|
.heap : {
|
||||||
|
PROVIDE(__heap_start = .);
|
||||||
|
. += HEAP_SIZE;
|
||||||
|
. = ALIGN(CL_SIZE);
|
||||||
|
PROVIDE(__heap_end = .);
|
||||||
|
} >ram
|
||||||
|
|
||||||
_end = .;
|
_end = .;
|
||||||
PROVIDE(__end = .);
|
PROVIDE(__end = .);
|
||||||
|
|
||||||
/* End of uninitalized data segement */
|
/* End of uninitalized data segement */
|
||||||
|
|
||||||
.stack ORIGIN(ram) + LENGTH(ram) - STACK_SIZE : {
|
.stack ORIGIN(ram) + LENGTH(ram) - STACK_SIZE: {
|
||||||
FILL(0);
|
FILL(0);
|
||||||
PROVIDE(__STACK_START__ = .);
|
PROVIDE(__STACK_START__ = .);
|
||||||
. += STACK_SIZE;
|
. += STACK_SIZE;
|
||||||
|
|||||||
@ -21,8 +21,8 @@ SECTIONS {
|
|||||||
*crt0.S.o(.text .text.*)
|
*crt0.S.o(.text .text.*)
|
||||||
*(.text.smallsysteminit)
|
*(.text.smallsysteminit)
|
||||||
*(.text.SmallSystemInit)
|
*(.text.SmallSystemInit)
|
||||||
. = ORIGIN(rom) + 0xC0;
|
/*. = ORIGIN(rom) + 0xC0;*/
|
||||||
KEEP(*crt0.S.o(.trap_text))
|
/*KEEP(*crt0.S.o(.trap_text))*/
|
||||||
|
|
||||||
*(.text)
|
*(.text)
|
||||||
*(.text.*)
|
*(.text.*)
|
||||||
@ -50,15 +50,17 @@ SECTIONS {
|
|||||||
AT( __TEXT_END__ ) {
|
AT( __TEXT_END__ ) {
|
||||||
PROVIDE(__DATA_START__ = .);
|
PROVIDE(__DATA_START__ = .);
|
||||||
_gp = .;
|
_gp = .;
|
||||||
|
. = ORIGIN(ram) + 0xC0;
|
||||||
|
KEEP(*crt0.S.o(.trap_text))
|
||||||
*(.srodata.cst16) *(.srodata.cst8) *(.srodata.cst4) *(.srodata.cst2) *(.srodata*)
|
*(.srodata.cst16) *(.srodata.cst8) *(.srodata.cst4) *(.srodata.cst2) *(.srodata*)
|
||||||
*(.sdata .sdata.* .sdata* .sdata*.* .gnu.linkonce.s.*)
|
*(.sdata .sdata.* .sdata* .sdata*.* .gnu.linkonce.s.*)
|
||||||
*(.data .data.*)
|
*(.data .data.*)
|
||||||
. = ALIGN(CL_SIZE);
|
. = ALIGN(CL_SIZE);
|
||||||
|
PROVIDE(__DATA_END__ = .);
|
||||||
} >ram
|
} >ram
|
||||||
|
|
||||||
__DATA_IMAGE_START__ = LOADADDR(.data);
|
__DATA_IMAGE_START__ = LOADADDR(.data);
|
||||||
__DATA_IMAGE_END__ = LOADADDR(.data) + SIZEOF(.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 */
|
/* thread-local data segment */
|
||||||
.tdata : {
|
.tdata : {
|
||||||
@ -84,10 +86,26 @@ SECTIONS {
|
|||||||
|
|
||||||
.bss : {
|
.bss : {
|
||||||
*(.bss .bss.*)
|
*(.bss .bss.*)
|
||||||
|
*(COMMON)
|
||||||
. = ALIGN(CL_SIZE);
|
. = ALIGN(CL_SIZE);
|
||||||
PROVIDE(__BSS_END__ = .);
|
PROVIDE(__BSS_END__ = .);
|
||||||
} >ram
|
} >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 : {
|
.heap : {
|
||||||
PROVIDE(__heap_start = .);
|
PROVIDE(__heap_start = .);
|
||||||
. += HEAP_SIZE;
|
. += HEAP_SIZE;
|
||||||
|
|||||||
@ -62,6 +62,11 @@ memset_2:
|
|||||||
|
|
||||||
_start:
|
_start:
|
||||||
|
|
||||||
|
li t0, 128000
|
||||||
|
start_loop_delay:
|
||||||
|
nop
|
||||||
|
addi t0, t0, -1
|
||||||
|
bnez t0, start_loop_delay
|
||||||
# Init stack and global pointer
|
# Init stack and global pointer
|
||||||
#
|
#
|
||||||
la_abs sp, __C_STACK_TOP__
|
la_abs sp, __C_STACK_TOP__
|
||||||
@ -74,20 +79,19 @@ _start:
|
|||||||
la_abs a3, __DATA_START__
|
la_abs a3, __DATA_START__
|
||||||
memcpy a1, a2, a3, t0
|
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
|
# Clear bss
|
||||||
#
|
#
|
||||||
la_abs a1, __BSS_START__
|
la_abs a1, __BSS_START__
|
||||||
la_abs a2, __BSS_END__
|
la_abs a2, __BSS_END__
|
||||||
memset a1, a2, zero
|
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, SmallSystemInit
|
||||||
jalr_abs ra, SystemInit
|
jalr_abs ra, SystemInit
|
||||||
|
|
||||||
|
|||||||
@ -1,37 +1,46 @@
|
|||||||
#include "mik32_hal_irq.h"
|
#include "mik32_hal_irq.h"
|
||||||
|
#include "wiring_LL.h"
|
||||||
|
|
||||||
// isr functions
|
// isr functions
|
||||||
extern void serial_handler_wrapper(uint8_t uartNumInt);
|
extern void serial_interrupt_handler(uint8_t uartNumInt);
|
||||||
extern void gpio_interrupts_handler(void);
|
extern void gpio_interrupt_handler(void);
|
||||||
extern void tone_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
|
// 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
|
// tone timer interrupt
|
||||||
if (EPIC_CHECK_TIMER16_1())
|
if (EPIC_CHECK_TIMER16_1())
|
||||||
tone_interrupt_handler();
|
tone_interrupt_handler();
|
||||||
|
|
||||||
|
// servo timer interrupt
|
||||||
|
if (EPIC_CHECK_TIMER16_2())
|
||||||
|
servo_interrupt_handler();
|
||||||
|
|
||||||
// uart0 interrupt
|
// uart0 interrupt
|
||||||
if (EPIC_CHECK_UART_0())
|
if (EPIC_CHECK_UART_0())
|
||||||
serial_handler_wrapper(0);
|
serial_interrupt_handler(0);
|
||||||
|
|
||||||
// uart1 interrupt
|
// uart1 interrupt
|
||||||
if (EPIC_CHECK_UART_1())
|
if (EPIC_CHECK_UART_1())
|
||||||
serial_handler_wrapper(1);
|
serial_interrupt_handler(1);
|
||||||
|
|
||||||
// gpio interrupt
|
|
||||||
if (EPIC_CHECK_GPIO_IRQ())
|
|
||||||
gpio_interrupts_handler();
|
|
||||||
|
|
||||||
// i2c interrupt
|
// i2c interrupt
|
||||||
if (EPIC_CHECK_I2C_1())
|
if (EPIC_CHECK_I2C_1())
|
||||||
wire_handler_wrapper();
|
wire_interrupt_handler();
|
||||||
|
|
||||||
// reset all interrupts
|
// reset all interrupts
|
||||||
HAL_EPIC_Clear(0xFFFFFFFF);
|
EPIC_CLEAR_ALL();
|
||||||
}
|
}
|
||||||
|
|||||||
6
cores/arduino/util/delay.h
Normal file
6
cores/arduino/util/delay.h
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
#ifndef __DELAY_H_
|
||||||
|
#define __DELAY_H_
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#endif // __DELAY_H_
|
||||||
65
cores/arduino/wiring_LL.h
Normal file
65
cores/arduino/wiring_LL.h
Normal 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_ */
|
||||||
@ -8,9 +8,13 @@ extern "C" {
|
|||||||
#include "mik32_hal_gpio.h"
|
#include "mik32_hal_gpio.h"
|
||||||
#include "mik32_hal_timer32.h"
|
#include "mik32_hal_timer32.h"
|
||||||
|
|
||||||
extern void ErrorMsgHandler(const char * msg);
|
|
||||||
|
|
||||||
// -------------------------- Analog read -------------------------- //
|
// -------------------------- 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
|
// structure for ADC channel initialization. Only the channel number
|
||||||
// changes, everything else is the same
|
// changes, everything else is the same
|
||||||
static ADC_HandleTypeDef hadc =
|
static ADC_HandleTypeDef hadc =
|
||||||
@ -21,6 +25,16 @@ static ADC_HandleTypeDef hadc =
|
|||||||
.Init.Sel = 0
|
.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
|
// initialize the channel, run a single measurement, wait for the result
|
||||||
uint32_t analogRead(uint32_t PinNumber)
|
uint32_t analogRead(uint32_t PinNumber)
|
||||||
{
|
{
|
||||||
@ -44,11 +58,31 @@ uint32_t analogRead(uint32_t PinNumber)
|
|||||||
hadc.Init.Sel = adcChannel;
|
hadc.Init.Sel = adcChannel;
|
||||||
HAL_ADC_Init(&hadc);
|
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);
|
HAL_ADC_SINGLE_AND_SET_CH(hadc.Instance, adcChannel);
|
||||||
value = HAL_ADC_WaitAndGetValue(&hadc);
|
HAL_ADC_WaitAndGetValue(&hadc);
|
||||||
HAL_ADC_Single(&hadc);
|
|
||||||
value = 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
|
else
|
||||||
ErrorMsgHandler("analogRead(): invalid analog pin number");
|
ErrorMsgHandler("analogRead(): invalid analog pin number");
|
||||||
@ -68,25 +102,8 @@ static TIMER32_HandleTypeDef htimer32;
|
|||||||
static TIMER32_CHANNEL_HandleTypeDef htimer32_channel;
|
static TIMER32_CHANNEL_HandleTypeDef htimer32_channel;
|
||||||
static uint32_t WriteValMax = WRITE_VAL_MAX_DEFAULT;
|
static uint32_t WriteValMax = WRITE_VAL_MAX_DEFAULT;
|
||||||
static uint32_t pwmTopVal = PWM_TOP_VAL_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:
|
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.PWM_Invert = TIMER32_CHANNEL_NON_INVERTED_PWM;
|
||||||
htimer32_channel.Mode = TIMER32_CHANNEL_MODE_PWM;
|
htimer32_channel.Mode = TIMER32_CHANNEL_MODE_PWM;
|
||||||
htimer32_channel.CaptureEdge = TIMER32_CHANNEL_CAPTUREEDGE_RISING;
|
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.OCR = (uint32_t) (((uint64_t)pwmTopVal * writeVal) / WriteValMax);
|
||||||
htimer32_channel.Noise = TIMER32_CHANNEL_FILTER_OFF;
|
htimer32_channel.Noise = TIMER32_CHANNEL_FILTER_OFF;
|
||||||
Timer32_Channel_Init(&htimer32_channel);
|
HAL_Timer32_Channel_Init(&htimer32_channel);
|
||||||
|
|
||||||
// start timer with initialized channel
|
// start timer with initialized channel
|
||||||
HAL_Timer32_Channel_Enable(&htimer32_channel);
|
HAL_Timer32_Channel_Enable(&htimer32_channel);
|
||||||
HAL_Timer32_Value_Clear(&htimer32);
|
HAL_Timer32_Value_Clear(&htimer32);
|
||||||
HAL_Timer32_Start(&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
|
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");
|
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)
|
void analogWriteStop(uint32_t PinNumber)
|
||||||
{
|
{
|
||||||
if (pwmIsInited)
|
if ((pwmIsInited > 0) && (digitalPinPwmIsOn(PinNumber)))
|
||||||
{
|
{
|
||||||
// load the timer address and channel number corresponding to the specified pin
|
// load the timer address and channel number corresponding to the specified pin
|
||||||
htimer32.Instance = pwmPinToTimer(PinNumber);
|
htimer32.Instance = pwmPinToTimer(PinNumber);
|
||||||
htimer32_channel.TimerInstance = htimer32.Instance;
|
htimer32_channel.TimerInstance = htimer32.Instance;
|
||||||
htimer32_channel.ChannelIndex = pwmPinToTimerChannel(PinNumber);
|
htimer32_channel.ChannelIndex = pwmPinToTimerChannel(PinNumber);
|
||||||
// in the initChannel function they do it inside, but in deinit they don't. We do it outside
|
// deinit channel
|
||||||
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);
|
|
||||||
HAL_Timer32_Channel_DeInit(&htimer32_channel);
|
HAL_Timer32_Channel_DeInit(&htimer32_channel);
|
||||||
HAL_Timer32_Stop(&htimer32);
|
pwmIsInited--; // decrease inited channels qty
|
||||||
pwmIsInited = false;
|
|
||||||
|
// 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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -16,6 +16,13 @@ extern "C" {
|
|||||||
*/
|
*/
|
||||||
uint32_t analogRead(uint32_t PinNumber);
|
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.
|
* \brief Writes an analog value (PWM wave) to a pin.
|
||||||
*
|
*
|
||||||
|
|||||||
@ -24,8 +24,6 @@
|
|||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
extern void ErrorMsgHandler(const char * msg);
|
|
||||||
|
|
||||||
// initialization
|
// initialization
|
||||||
void pinMode(uint32_t PinNumber, uint32_t PinMode)
|
void pinMode(uint32_t PinNumber, uint32_t PinMode)
|
||||||
{
|
{
|
||||||
|
|||||||
@ -39,6 +39,11 @@ void SysTick_Init(void)
|
|||||||
HAL_SCR1_Timer_Init(&hscr1_timer); // Ticks are 32 MHz
|
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
|
// number of microseconds since start of the program
|
||||||
uint32_t micros(void)
|
uint32_t micros(void)
|
||||||
{
|
{
|
||||||
|
|||||||
@ -24,12 +24,22 @@
|
|||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define clockCyclesPerMicrosecond() (F_CPU / 1000000L)
|
||||||
|
#define clockCyclesToMicroseconds(a) ((a) / clockCyclesPerMicrosecond())
|
||||||
|
#define microsecondsToClockCycles(a) ((a) * clockCyclesPerMicrosecond())
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Initialize timer for creating delays
|
* \brief Initialize timer for creating delays
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
void SysTick_Init(void);
|
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.
|
* \brief Returns the number of milliseconds since the Arduino board began running the current program.
|
||||||
|
|||||||
BIN
docs/pinout.PNG
Normal file
BIN
docs/pinout.PNG
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 233 KiB |
2
libraries/EEPROM/.gitignore
vendored
Normal file
2
libraries/EEPROM/.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
installed.json
|
||||||
|
.vscode/
|
||||||
139
libraries/EEPROM/README.md
Normal file
139
libraries/EEPROM/README.md
Normal 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.
|
||||||
32
libraries/EEPROM/examples/eeprom_clear/eeprom_clear.ino
Normal file
32
libraries/EEPROM/examples/eeprom_clear/eeprom_clear.ino
Normal 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. **/
|
||||||
|
}
|
||||||
51
libraries/EEPROM/examples/eeprom_crc/eeprom_crc.ino
Normal file
51
libraries/EEPROM/examples/eeprom_crc/eeprom_crc.ino
Normal 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;
|
||||||
|
}
|
||||||
66
libraries/EEPROM/examples/eeprom_get/eeprom_get.ino
Normal file
66
libraries/EEPROM/examples/eeprom_get/eeprom_get.ino
Normal 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 */
|
||||||
|
}
|
||||||
@ -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() {}
|
||||||
56
libraries/EEPROM/examples/eeprom_put/eeprom_put.ino
Normal file
56
libraries/EEPROM/examples/eeprom_put/eeprom_put.ino
Normal 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 */
|
||||||
|
}
|
||||||
38
libraries/EEPROM/examples/eeprom_read/eeprom_read.ino
Normal file
38
libraries/EEPROM/examples/eeprom_read/eeprom_read.ino
Normal 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);
|
||||||
|
}
|
||||||
50
libraries/EEPROM/examples/eeprom_update/eeprom_update.ino
Normal file
50
libraries/EEPROM/examples/eeprom_update/eeprom_update.ino
Normal 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);
|
||||||
|
}
|
||||||
41
libraries/EEPROM/examples/eeprom_write/eeprom_write.ino
Normal file
41
libraries/EEPROM/examples/eeprom_write/eeprom_write.ino
Normal 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);
|
||||||
|
}
|
||||||
22
libraries/EEPROM/keywords.txt
Normal file
22
libraries/EEPROM/keywords.txt
Normal 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)
|
||||||
|
#######################################
|
||||||
|
|
||||||
10
libraries/EEPROM/library.properties
Normal file
10
libraries/EEPROM/library.properties
Normal 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
|
||||||
|
|
||||||
119
libraries/EEPROM/src/EEPROM.cpp
Normal file
119
libraries/EEPROM/src/EEPROM.cpp
Normal 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);
|
||||||
|
}
|
||||||
250
libraries/EEPROM/src/EEPROM.h
Normal file
250
libraries/EEPROM/src/EEPROM.h
Normal 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
|
||||||
392
libraries/MFRC522/README.rst
Normal file
392
libraries/MFRC522/README.rst
Normal 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
|
||||||
24
libraries/MFRC522/UNLICENSE
Normal file
24
libraries/MFRC522/UNLICENSE
Normal 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/>
|
||||||
199
libraries/MFRC522/changes.txt
Normal file
199
libraries/MFRC522/changes.txt
Normal 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.
|
||||||
67
libraries/MFRC522/doc/PICCMemoryLayout.md
Normal file
67
libraries/MFRC522/doc/PICCMemoryLayout.md
Normal 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.
Binary file not shown.
|
After Width: | Height: | Size: 343 KiB |
BIN
libraries/MFRC522/doc/fritzing/RFID-RC522 - Pin Layout.png
Normal file
BIN
libraries/MFRC522/doc/fritzing/RFID-RC522 - Pin Layout.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 162 KiB |
BIN
libraries/MFRC522/doc/fritzing/RFID-RC522-v2.fzpz
Normal file
BIN
libraries/MFRC522/doc/fritzing/RFID-RC522-v2.fzpz
Normal file
Binary file not shown.
BIN
libraries/MFRC522/doc/fritzing/RFID-RC522-v2.png
Normal file
BIN
libraries/MFRC522/doc/fritzing/RFID-RC522-v2.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 29 KiB |
BIN
libraries/MFRC522/doc/fritzing/RFID-RC522-v3.fzpz
Normal file
BIN
libraries/MFRC522/doc/fritzing/RFID-RC522-v3.fzpz
Normal file
Binary file not shown.
BIN
libraries/MFRC522/doc/fritzing/RFID-RC522-v3.png
Normal file
BIN
libraries/MFRC522/doc/fritzing/RFID-RC522-v3.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 17 KiB |
BIN
libraries/MFRC522/doc/rfidmifare.doc
Normal file
BIN
libraries/MFRC522/doc/rfidmifare.doc
Normal file
Binary file not shown.
BIN
libraries/MFRC522/doc/rfidmifare.pdf
Normal file
BIN
libraries/MFRC522/doc/rfidmifare.pdf
Normal file
Binary file not shown.
112
libraries/MFRC522/examples/ChangeUID/ChangeUID.ino
Normal file
112
libraries/MFRC522/examples/ChangeUID/ChangeUID.ino
Normal 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);
|
||||||
|
}
|
||||||
69
libraries/MFRC522/examples/DumpInfo/DumpInfo.ino
Normal file
69
libraries/MFRC522/examples/DumpInfo/DumpInfo.ino
Normal 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));
|
||||||
|
}
|
||||||
55
libraries/MFRC522/examples/FixBrickedUID/FixBrickedUID.ino
Normal file
55
libraries/MFRC522/examples/FixBrickedUID/FixBrickedUID.ino
Normal 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);
|
||||||
|
}
|
||||||
@ -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));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
139
libraries/MFRC522/examples/MinimalInterrupt/MinimalInterrupt.ino
Normal file
139
libraries/MFRC522/examples/MinimalInterrupt/MinimalInterrupt.ino
Normal 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);
|
||||||
|
}
|
||||||
|
|
||||||
62
libraries/MFRC522/examples/Ntag216_AUTH/Ntag216_AUTH.ino
Normal file
62
libraries/MFRC522/examples/Ntag216_AUTH/Ntag216_AUTH.ino
Normal 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);
|
||||||
|
}
|
||||||
314
libraries/MFRC522/examples/RFID-Cloner/RFID-Cloner.ino
Normal file
314
libraries/MFRC522/examples/RFID-Cloner/RFID-Cloner.ino
Normal 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
202
libraries/MFRC522/examples/ReadAndWrite/ReadAndWrite.ino
Normal file
202
libraries/MFRC522/examples/ReadAndWrite/ReadAndWrite.ino
Normal 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
129
libraries/MFRC522/examples/ReadNUID/ReadNUID.ino
Normal file
129
libraries/MFRC522/examples/ReadNUID/ReadNUID.ino
Normal 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
63
libraries/MFRC522/examples/firmware_check/firmware_check.ino
Normal file
63
libraries/MFRC522/examples/firmware_check/firmware_check.ino
Normal 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
|
||||||
@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -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();
|
||||||
|
}
|
||||||
|
//*****************************************************************************************//
|
||||||
@ -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
|
||||||
|
|
||||||
|
}
|
||||||
223
libraries/MFRC522/keywords.txt
Normal file
223
libraries/MFRC522/keywords.txt
Normal 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
|
||||||
15
libraries/MFRC522/library.json
Normal file
15
libraries/MFRC522/library.json
Normal 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"]
|
||||||
|
}
|
||||||
9
libraries/MFRC522/library.properties
Normal file
9
libraries/MFRC522/library.properties
Normal 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
|
||||||
1950
libraries/MFRC522/src/MFRC522.cpp
Normal file
1950
libraries/MFRC522/src/MFRC522.cpp
Normal file
File diff suppressed because it is too large
Load Diff
375
libraries/MFRC522/src/MFRC522.h
Normal file
375
libraries/MFRC522/src/MFRC522.h
Normal 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
|
||||||
1160
libraries/MFRC522/src/MFRC522Extended.cpp
Normal file
1160
libraries/MFRC522/src/MFRC522Extended.cpp
Normal file
File diff suppressed because it is too large
Load Diff
120
libraries/MFRC522/src/MFRC522Extended.h
Normal file
120
libraries/MFRC522/src/MFRC522Extended.h
Normal file
@ -0,0 +1,120 @@
|
|||||||
|
/**
|
||||||
|
* Library extends MFRC522.h to support RATS for ISO-14443-4 PICC.
|
||||||
|
* RATS - Request for Answer To Select.
|
||||||
|
* @author JPG-Consulting
|
||||||
|
*/
|
||||||
|
#ifndef MFRC522Extended_h
|
||||||
|
#define MFRC522Extended_h
|
||||||
|
|
||||||
|
#include <Arduino.h>
|
||||||
|
#include "MFRC522.h"
|
||||||
|
|
||||||
|
class MFRC522Extended : public MFRC522 {
|
||||||
|
|
||||||
|
public:
|
||||||
|
// ISO/IEC 14443-4 bit rates
|
||||||
|
enum TagBitRates : byte {
|
||||||
|
BITRATE_106KBITS = 0x00,
|
||||||
|
BITRATE_212KBITS = 0x01,
|
||||||
|
BITRATE_424KBITS = 0x02,
|
||||||
|
BITRATE_848KBITS = 0x03
|
||||||
|
};
|
||||||
|
|
||||||
|
// Structure to store ISO/IEC 14443-4 ATS
|
||||||
|
typedef struct {
|
||||||
|
byte size;
|
||||||
|
byte fsc; // Frame size for proximity card
|
||||||
|
|
||||||
|
struct {
|
||||||
|
bool transmitted;
|
||||||
|
bool sameD; // Only the same D for both directions supported
|
||||||
|
TagBitRates ds; // Send D
|
||||||
|
TagBitRates dr; // Receive D
|
||||||
|
} ta1;
|
||||||
|
|
||||||
|
struct {
|
||||||
|
bool transmitted;
|
||||||
|
byte fwi; // Frame waiting time integer
|
||||||
|
byte sfgi; // Start-up frame guard time integer
|
||||||
|
} tb1;
|
||||||
|
|
||||||
|
struct {
|
||||||
|
bool transmitted;
|
||||||
|
bool supportsCID;
|
||||||
|
bool supportsNAD;
|
||||||
|
} tc1;
|
||||||
|
|
||||||
|
// Raw data from ATS
|
||||||
|
byte data[FIFO_SIZE - 2]; // ATS cannot be bigger than FSD - 2 bytes (CRC), according to ISO 14443-4 5.2.2
|
||||||
|
} Ats;
|
||||||
|
|
||||||
|
// A struct used for passing the PICC information
|
||||||
|
typedef struct {
|
||||||
|
uint16_t atqa;
|
||||||
|
Uid uid;
|
||||||
|
Ats ats;
|
||||||
|
|
||||||
|
// For Block PCB
|
||||||
|
bool blockNumber;
|
||||||
|
} TagInfo;
|
||||||
|
|
||||||
|
// A struct used for passing PCB Block
|
||||||
|
typedef struct {
|
||||||
|
struct {
|
||||||
|
byte pcb;
|
||||||
|
byte cid;
|
||||||
|
byte nad;
|
||||||
|
} prologue;
|
||||||
|
struct {
|
||||||
|
byte size;
|
||||||
|
byte *data;
|
||||||
|
} inf;
|
||||||
|
} PcbBlock;
|
||||||
|
|
||||||
|
// Member variables
|
||||||
|
TagInfo tag;
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Contructors
|
||||||
|
/////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
MFRC522Extended() : MFRC522() {};
|
||||||
|
MFRC522Extended(uint8_t rst) : MFRC522(rst) {};
|
||||||
|
MFRC522Extended(uint8_t ss, uint8_t rst) : MFRC522(ss, rst) {};
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Functions for communicating with PICCs
|
||||||
|
/////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
StatusCode PICC_Select(Uid *uid, byte validBits = 0) override; // overrride
|
||||||
|
StatusCode PICC_RequestATS(Ats *ats);
|
||||||
|
StatusCode PICC_PPS(); // PPS command without bitrate parameter
|
||||||
|
StatusCode PICC_PPS(TagBitRates sendBitRate, TagBitRates receiveBitRate); // Different D values
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Functions for communicating with ISO/IEC 14433-4 cards
|
||||||
|
/////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
StatusCode TCL_Transceive(PcbBlock *send, PcbBlock *back);
|
||||||
|
StatusCode TCL_Transceive(TagInfo * tag, byte *sendData, byte sendLen, byte *backData = NULL, byte *backLen = NULL);
|
||||||
|
StatusCode TCL_TransceiveRBlock(TagInfo *tag, bool ack, byte *backData = NULL, byte *backLen = NULL);
|
||||||
|
StatusCode TCL_Deselect(TagInfo *tag);
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Support functions
|
||||||
|
/////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
static PICC_Type PICC_GetType(TagInfo *tag);
|
||||||
|
using MFRC522::PICC_GetType;// // make old PICC_GetType(byte sak) available, otherwise would be hidden by PICC_GetType(TagInfo *tag)
|
||||||
|
|
||||||
|
// Support functions for debuging
|
||||||
|
void PICC_DumpToSerial(TagInfo *tag);
|
||||||
|
using MFRC522::PICC_DumpToSerial; // make old PICC_DumpToSerial(Uid *uid) available, otherwise would be hidden by PICC_DumpToSerial(TagInfo *tag)
|
||||||
|
void PICC_DumpDetailsToSerial(TagInfo *tag);
|
||||||
|
using MFRC522::PICC_DumpDetailsToSerial; // make old PICC_DumpDetailsToSerial(Uid *uid) available, otherwise would be hidden by PICC_DumpDetailsToSerial(TagInfo *tag)
|
||||||
|
void PICC_DumpISO14443_4(TagInfo *tag);
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Convenience functions - does not add extra functionality
|
||||||
|
/////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
bool PICC_IsNewCardPresent() override; // overrride
|
||||||
|
bool PICC_ReadCardSerial() override; // overrride
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
20
libraries/MFRC522/src/deprecated.h
Normal file
20
libraries/MFRC522/src/deprecated.h
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2016 by Ludwig Grill (www.rotzbua.de)
|
||||||
|
* Simple deprecated workaround for Arduino IDE
|
||||||
|
* IDE 1.6.8 use gcc 4.8 which do not support c++14 [[deprecated]]
|
||||||
|
* Later versions should support c++14, then use c++14 syntax
|
||||||
|
*/
|
||||||
|
#ifndef DEPRECATED_H
|
||||||
|
#define DEPRECATED_H
|
||||||
|
|
||||||
|
#ifdef __has_cpp_attribute
|
||||||
|
#if __has_cpp_attribute(deprecated)
|
||||||
|
#define DEPRECATED [[deprecated]]
|
||||||
|
#define DEPRECATED_MSG(msg) [[deprecated(msg)]]
|
||||||
|
#endif // __has_cpp_attribute(deprecated)
|
||||||
|
#else
|
||||||
|
#define DEPRECATED __attribute__((deprecated))
|
||||||
|
#define DEPRECATED_MSG(msg) __attribute__((deprecated(msg)))
|
||||||
|
#endif // __has_cpp_attribute
|
||||||
|
|
||||||
|
#endif // DEPRECATED_H
|
||||||
12
libraries/MFRC522/src/require_cpp11.h
Normal file
12
libraries/MFRC522/src/require_cpp11.h
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2016 by Ludwig Grill (www.rotzbua.de)
|
||||||
|
* Throws error if c++11 is not supported
|
||||||
|
*/
|
||||||
|
#ifndef REQUIRE_CPP11_H
|
||||||
|
#define REQUIRE_CPP11_H
|
||||||
|
|
||||||
|
#if __cplusplus < 201103L
|
||||||
|
#error "This library needs at least a C++11 compliant compiler, maybe compiler argument for C++11 support is missing or if you use Arduino IDE upgrade to version >=1.6.6"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif // REQUIRE_CPP11_H
|
||||||
165
libraries/NeoPixel/LICENSE.txt
Normal file
165
libraries/NeoPixel/LICENSE.txt
Normal file
@ -0,0 +1,165 @@
|
|||||||
|
GNU LESSER GENERAL PUBLIC LICENSE
|
||||||
|
Version 3, 29 June 2007
|
||||||
|
|
||||||
|
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
|
||||||
|
Everyone is permitted to copy and distribute verbatim copies
|
||||||
|
of this license document, but changing it is not allowed.
|
||||||
|
|
||||||
|
|
||||||
|
This version of the GNU Lesser General Public License incorporates
|
||||||
|
the terms and conditions of version 3 of the GNU General Public
|
||||||
|
License, supplemented by the additional permissions listed below.
|
||||||
|
|
||||||
|
0. Additional Definitions.
|
||||||
|
|
||||||
|
As used herein, "this License" refers to version 3 of the GNU Lesser
|
||||||
|
General Public License, and the "GNU GPL" refers to version 3 of the GNU
|
||||||
|
General Public License.
|
||||||
|
|
||||||
|
"The Library" refers to a covered work governed by this License,
|
||||||
|
other than an Application or a Combined Work as defined below.
|
||||||
|
|
||||||
|
An "Application" is any work that makes use of an interface provided
|
||||||
|
by the Library, but which is not otherwise based on the Library.
|
||||||
|
Defining a subclass of a class defined by the Library is deemed a mode
|
||||||
|
of using an interface provided by the Library.
|
||||||
|
|
||||||
|
A "Combined Work" is a work produced by combining or linking an
|
||||||
|
Application with the Library. The particular version of the Library
|
||||||
|
with which the Combined Work was made is also called the "Linked
|
||||||
|
Version".
|
||||||
|
|
||||||
|
The "Minimal Corresponding Source" for a Combined Work means the
|
||||||
|
Corresponding Source for the Combined Work, excluding any source code
|
||||||
|
for portions of the Combined Work that, considered in isolation, are
|
||||||
|
based on the Application, and not on the Linked Version.
|
||||||
|
|
||||||
|
The "Corresponding Application Code" for a Combined Work means the
|
||||||
|
object code and/or source code for the Application, including any data
|
||||||
|
and utility programs needed for reproducing the Combined Work from the
|
||||||
|
Application, but excluding the System Libraries of the Combined Work.
|
||||||
|
|
||||||
|
1. Exception to Section 3 of the GNU GPL.
|
||||||
|
|
||||||
|
You may convey a covered work under sections 3 and 4 of this License
|
||||||
|
without being bound by section 3 of the GNU GPL.
|
||||||
|
|
||||||
|
2. Conveying Modified Versions.
|
||||||
|
|
||||||
|
If you modify a copy of the Library, and, in your modifications, a
|
||||||
|
facility refers to a function or data to be supplied by an Application
|
||||||
|
that uses the facility (other than as an argument passed when the
|
||||||
|
facility is invoked), then you may convey a copy of the modified
|
||||||
|
version:
|
||||||
|
|
||||||
|
a) under this License, provided that you make a good faith effort to
|
||||||
|
ensure that, in the event an Application does not supply the
|
||||||
|
function or data, the facility still operates, and performs
|
||||||
|
whatever part of its purpose remains meaningful, or
|
||||||
|
|
||||||
|
b) under the GNU GPL, with none of the additional permissions of
|
||||||
|
this License applicable to that copy.
|
||||||
|
|
||||||
|
3. Object Code Incorporating Material from Library Header Files.
|
||||||
|
|
||||||
|
The object code form of an Application may incorporate material from
|
||||||
|
a header file that is part of the Library. You may convey such object
|
||||||
|
code under terms of your choice, provided that, if the incorporated
|
||||||
|
material is not limited to numerical parameters, data structure
|
||||||
|
layouts and accessors, or small macros, inline functions and templates
|
||||||
|
(ten or fewer lines in length), you do both of the following:
|
||||||
|
|
||||||
|
a) Give prominent notice with each copy of the object code that the
|
||||||
|
Library is used in it and that the Library and its use are
|
||||||
|
covered by this License.
|
||||||
|
|
||||||
|
b) Accompany the object code with a copy of the GNU GPL and this license
|
||||||
|
document.
|
||||||
|
|
||||||
|
4. Combined Works.
|
||||||
|
|
||||||
|
You may convey a Combined Work under terms of your choice that,
|
||||||
|
taken together, effectively do not restrict modification of the
|
||||||
|
portions of the Library contained in the Combined Work and reverse
|
||||||
|
engineering for debugging such modifications, if you also do each of
|
||||||
|
the following:
|
||||||
|
|
||||||
|
a) Give prominent notice with each copy of the Combined Work that
|
||||||
|
the Library is used in it and that the Library and its use are
|
||||||
|
covered by this License.
|
||||||
|
|
||||||
|
b) Accompany the Combined Work with a copy of the GNU GPL and this license
|
||||||
|
document.
|
||||||
|
|
||||||
|
c) For a Combined Work that displays copyright notices during
|
||||||
|
execution, include the copyright notice for the Library among
|
||||||
|
these notices, as well as a reference directing the user to the
|
||||||
|
copies of the GNU GPL and this license document.
|
||||||
|
|
||||||
|
d) Do one of the following:
|
||||||
|
|
||||||
|
0) Convey the Minimal Corresponding Source under the terms of this
|
||||||
|
License, and the Corresponding Application Code in a form
|
||||||
|
suitable for, and under terms that permit, the user to
|
||||||
|
recombine or relink the Application with a modified version of
|
||||||
|
the Linked Version to produce a modified Combined Work, in the
|
||||||
|
manner specified by section 6 of the GNU GPL for conveying
|
||||||
|
Corresponding Source.
|
||||||
|
|
||||||
|
1) Use a suitable shared library mechanism for linking with the
|
||||||
|
Library. A suitable mechanism is one that (a) uses at run time
|
||||||
|
a copy of the Library already present on the user's computer
|
||||||
|
system, and (b) will operate properly with a modified version
|
||||||
|
of the Library that is interface-compatible with the Linked
|
||||||
|
Version.
|
||||||
|
|
||||||
|
e) Provide Installation Information, but only if you would otherwise
|
||||||
|
be required to provide such information under section 6 of the
|
||||||
|
GNU GPL, and only to the extent that such information is
|
||||||
|
necessary to install and execute a modified version of the
|
||||||
|
Combined Work produced by recombining or relinking the
|
||||||
|
Application with a modified version of the Linked Version. (If
|
||||||
|
you use option 4d0, the Installation Information must accompany
|
||||||
|
the Minimal Corresponding Source and Corresponding Application
|
||||||
|
Code. If you use option 4d1, you must provide the Installation
|
||||||
|
Information in the manner specified by section 6 of the GNU GPL
|
||||||
|
for conveying Corresponding Source.)
|
||||||
|
|
||||||
|
5. Combined Libraries.
|
||||||
|
|
||||||
|
You may place library facilities that are a work based on the
|
||||||
|
Library side by side in a single library together with other library
|
||||||
|
facilities that are not Applications and are not covered by this
|
||||||
|
License, and convey such a combined library under terms of your
|
||||||
|
choice, if you do both of the following:
|
||||||
|
|
||||||
|
a) Accompany the combined library with a copy of the same work based
|
||||||
|
on the Library, uncombined with any other library facilities,
|
||||||
|
conveyed under the terms of this License.
|
||||||
|
|
||||||
|
b) Give prominent notice with the combined library that part of it
|
||||||
|
is a work based on the Library, and explaining where to find the
|
||||||
|
accompanying uncombined form of the same work.
|
||||||
|
|
||||||
|
6. Revised Versions of the GNU Lesser General Public License.
|
||||||
|
|
||||||
|
The Free Software Foundation may publish revised and/or new versions
|
||||||
|
of the GNU Lesser General Public License from time to time. Such new
|
||||||
|
versions will be similar in spirit to the present version, but may
|
||||||
|
differ in detail to address new problems or concerns.
|
||||||
|
|
||||||
|
Each version is given a distinguishing version number. If the
|
||||||
|
Library as you received it specifies that a certain numbered version
|
||||||
|
of the GNU Lesser General Public License "or any later version"
|
||||||
|
applies to it, you have the option of following the terms and
|
||||||
|
conditions either of that published version or of any later version
|
||||||
|
published by the Free Software Foundation. If the Library as you
|
||||||
|
received it does not specify a version number of the GNU Lesser
|
||||||
|
General Public License, you may choose any version of the GNU Lesser
|
||||||
|
General Public License ever published by the Free Software Foundation.
|
||||||
|
|
||||||
|
If the Library as you received it specifies that a proxy can decide
|
||||||
|
whether future versions of the GNU Lesser General Public License shall
|
||||||
|
apply, that proxy's public statement of acceptance of any version is
|
||||||
|
permanent authorization for you to choose that version for the
|
||||||
|
Library.
|
||||||
2
libraries/NeoPixel/README.md
Normal file
2
libraries/NeoPixel/README.md
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
|
||||||
|
## NeoPixel - это библиотека адресного светодиода WS2812 для Амура (МК от Микрон) в ArduinoIDE
|
||||||
42
libraries/NeoPixel/examples/simple/simple.ino
Normal file
42
libraries/NeoPixel/examples/simple/simple.ino
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
#include <NeoPixel.h>
|
||||||
|
|
||||||
|
#define PIN 2
|
||||||
|
#define NUMPIXELS 8
|
||||||
|
|
||||||
|
NeoPixel pixels(NUMPIXELS, PIN);
|
||||||
|
|
||||||
|
uint8_t red = 0xff;
|
||||||
|
uint8_t green = 0x00;
|
||||||
|
uint8_t blue = 0x00;
|
||||||
|
uint8_t white = 0x00;
|
||||||
|
|
||||||
|
void setup() {
|
||||||
|
// init pin for led control
|
||||||
|
pixels.begin();
|
||||||
|
}
|
||||||
|
|
||||||
|
void loop() {
|
||||||
|
// clear pixels colors
|
||||||
|
pixels.clear();
|
||||||
|
|
||||||
|
// set new color and show it
|
||||||
|
for(int i=0; i<NUMPIXELS; i++) {
|
||||||
|
pixels.setPixelColor(i, pixels.Color(red, green, blue));
|
||||||
|
pixels.show();
|
||||||
|
}
|
||||||
|
delay(1000);
|
||||||
|
// update color to set
|
||||||
|
if (white == 0xff) {
|
||||||
|
red = 0xff;
|
||||||
|
green = blue = white = 0x00;
|
||||||
|
}else if (red == 0xff) {
|
||||||
|
green = 0xff;
|
||||||
|
red = blue = 0x00;
|
||||||
|
}else if (green == 0xff) {
|
||||||
|
blue = 0xff;
|
||||||
|
red = green = 0x00;
|
||||||
|
}else if (blue == 0xff) {
|
||||||
|
white = 0xff;
|
||||||
|
red = green = blue = 0xff;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,57 @@
|
|||||||
|
#include <NeoPixel.h>
|
||||||
|
|
||||||
|
#define PIN 2
|
||||||
|
#define NUMPIXELS 8
|
||||||
|
|
||||||
|
NeoPixel pixels(NUMPIXELS, PIN);
|
||||||
|
|
||||||
|
void setup() {
|
||||||
|
// init Serial and pin for led control
|
||||||
|
Serial.begin(9600);
|
||||||
|
pixels.begin();
|
||||||
|
Serial.println("pixels.begin");
|
||||||
|
delay(1000);
|
||||||
|
// clear pixels and show
|
||||||
|
pixels.clear();
|
||||||
|
pixels.show();
|
||||||
|
Serial.println("pixels.clear");
|
||||||
|
delay(1000);
|
||||||
|
}
|
||||||
|
|
||||||
|
void loop() {
|
||||||
|
// sequentially set a new pixel color and show it
|
||||||
|
for(int i=0; i<NUMPIXELS; i++) {
|
||||||
|
pixels.setPixelColor(i, pixels.Color(0xff, 0x00, 0x00));
|
||||||
|
pixels.show();
|
||||||
|
}
|
||||||
|
Serial.println("pixels.Color red");
|
||||||
|
delay(1000);
|
||||||
|
|
||||||
|
for(int i=0; i<NUMPIXELS; i++) {
|
||||||
|
pixels.setPixelColor(i, pixels.Color(0x00, 0xff, 0x00));
|
||||||
|
pixels.show();
|
||||||
|
}
|
||||||
|
Serial.println("pixels.Color green");
|
||||||
|
delay(1000);
|
||||||
|
|
||||||
|
for(int i=0; i<NUMPIXELS; i++) {
|
||||||
|
pixels.setPixelColor(i, pixels.Color(0x00, 0x00, 0xff));
|
||||||
|
pixels.show();
|
||||||
|
}
|
||||||
|
Serial.println("pixels.Color blue");
|
||||||
|
delay(1000);
|
||||||
|
|
||||||
|
for(int i=0; i<NUMPIXELS; i++) {
|
||||||
|
pixels.setPixelColor(i, pixels.Color(0xff, 0xff, 0xff));
|
||||||
|
pixels.show();
|
||||||
|
}
|
||||||
|
Serial.println("pixels.Color white");
|
||||||
|
delay(1000);
|
||||||
|
|
||||||
|
// clear leds
|
||||||
|
pixels.clear();
|
||||||
|
pixels.show();
|
||||||
|
Serial.println("pixels.clear");
|
||||||
|
delay(1000);
|
||||||
|
}
|
||||||
|
|
||||||
72
libraries/NeoPixel/keywords.txt
Normal file
72
libraries/NeoPixel/keywords.txt
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
#######################################
|
||||||
|
# Syntax Coloring Map For NeoPixel
|
||||||
|
#######################################
|
||||||
|
# Class
|
||||||
|
#######################################
|
||||||
|
|
||||||
|
NeoPixel KEYWORD1
|
||||||
|
|
||||||
|
#######################################
|
||||||
|
# Methods and Functions
|
||||||
|
#######################################
|
||||||
|
|
||||||
|
begin KEYWORD2
|
||||||
|
show KEYWORD2
|
||||||
|
setPin KEYWORD2
|
||||||
|
setPixelColor KEYWORD2
|
||||||
|
fill KEYWORD2
|
||||||
|
setBrightness KEYWORD2
|
||||||
|
clear KEYWORD2
|
||||||
|
updateLength KEYWORD2
|
||||||
|
updateType KEYWORD2
|
||||||
|
canShow KEYWORD2
|
||||||
|
getPixels KEYWORD2
|
||||||
|
getBrightness KEYWORD2
|
||||||
|
getPin KEYWORD2
|
||||||
|
numPixels KEYWORD2
|
||||||
|
getPixelColor KEYWORD2
|
||||||
|
sine8 KEYWORD2
|
||||||
|
gamma8 KEYWORD2
|
||||||
|
Color KEYWORD2
|
||||||
|
ColorHSV KEYWORD2
|
||||||
|
gamma32 KEYWORD2
|
||||||
|
|
||||||
|
#######################################
|
||||||
|
# Constants
|
||||||
|
#######################################
|
||||||
|
|
||||||
|
NEO_COLMASK LITERAL1
|
||||||
|
NEO_SPDMASK LITERAL1
|
||||||
|
NEO_KHZ800 LITERAL1
|
||||||
|
NEO_KHZ400 LITERAL1
|
||||||
|
NEO_RGB LITERAL1
|
||||||
|
NEO_RBG LITERAL1
|
||||||
|
NEO_GRB LITERAL1
|
||||||
|
NEO_GBR LITERAL1
|
||||||
|
NEO_BRG LITERAL1
|
||||||
|
NEO_BGR LITERAL1
|
||||||
|
NEO_WRGB LITERAL1
|
||||||
|
NEO_WRBG LITERAL1
|
||||||
|
NEO_WGRB LITERAL1
|
||||||
|
NEO_WGBR LITERAL1
|
||||||
|
NEO_WBRG LITERAL1
|
||||||
|
NEO_WBGR LITERAL1
|
||||||
|
NEO_RWGB LITERAL1
|
||||||
|
NEO_RWBG LITERAL1
|
||||||
|
NEO_RGWB LITERAL1
|
||||||
|
NEO_RGBW LITERAL1
|
||||||
|
NEO_RBWG LITERAL1
|
||||||
|
NEO_RBGW LITERAL1
|
||||||
|
NEO_GWRB LITERAL1
|
||||||
|
NEO_GWBR LITERAL1
|
||||||
|
NEO_GRWB LITERAL1
|
||||||
|
NEO_GRBW LITERAL1
|
||||||
|
NEO_GBWR LITERAL1
|
||||||
|
NEO_GBRW LITERAL1
|
||||||
|
NEO_BWRG LITERAL1
|
||||||
|
NEO_BWGR LITERAL1
|
||||||
|
NEO_BRWG LITERAL1
|
||||||
|
NEO_BRGW LITERAL1
|
||||||
|
NEO_BGWR LITERAL1
|
||||||
|
NEO_BGRW LITERAL1
|
||||||
|
|
||||||
9
libraries/NeoPixel/library.properties
Normal file
9
libraries/NeoPixel/library.properties
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
name=NeoPixel
|
||||||
|
version=0.0.1
|
||||||
|
author=Adafruit
|
||||||
|
maintainer=Ogneyar <ogneyar@hutoryanin.ru>
|
||||||
|
sentence=Arduino library for controlling single-wire-based LED pixels and strip.
|
||||||
|
paragraph=This library can manage tapes with WS2812 address LEDs - up to 60 pieces.
|
||||||
|
category=Display
|
||||||
|
url=https://gitflic.ru/project/ogneyar/neopixel_amura
|
||||||
|
architectures=MIK32_Amur
|
||||||
366
libraries/NeoPixel/src/NeoPixel.cpp
Normal file
366
libraries/NeoPixel/src/NeoPixel.cpp
Normal file
@ -0,0 +1,366 @@
|
|||||||
|
#include "NeoPixel.h"
|
||||||
|
|
||||||
|
NeoPixel::NeoPixel(uint16_t n, int16_t p, neoPixelType t)
|
||||||
|
: begun(false), brightness(0), pixels(NULL), endTime(0) {
|
||||||
|
updateType(t);
|
||||||
|
updateLength(n);
|
||||||
|
setPin(p);
|
||||||
|
}
|
||||||
|
|
||||||
|
NeoPixel::NeoPixel()
|
||||||
|
: is800KHz(true), begun(false), numLEDs(0), numBytes(0), pin(-1), brightness(0),
|
||||||
|
pixels(NULL), rOffset(1), gOffset(0), bOffset(2), wOffset(1), endTime(0) {
|
||||||
|
}
|
||||||
|
|
||||||
|
NeoPixel::~NeoPixel() {
|
||||||
|
free(pixels);
|
||||||
|
if (pin >= 0)
|
||||||
|
pinMode(pin, INPUT);
|
||||||
|
}
|
||||||
|
|
||||||
|
void NeoPixel::begin(void) {
|
||||||
|
if (pin >= 0) {
|
||||||
|
pinMode(pin, OUTPUT);
|
||||||
|
digitalWrite(pin, LOW);
|
||||||
|
}
|
||||||
|
begun = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void NeoPixel::updateLength(uint16_t n) {
|
||||||
|
free(pixels); // Free existing data (if any)
|
||||||
|
|
||||||
|
// Allocate new data -- note: ALL PIXELS ARE CLEARED
|
||||||
|
numBytes = n * ((wOffset == rOffset) ? 3 : 4);
|
||||||
|
if ((pixels = (uint8_t *)malloc(numBytes))) {
|
||||||
|
memset(pixels, 0, numBytes);
|
||||||
|
numLEDs = n;
|
||||||
|
} else {
|
||||||
|
numLEDs = numBytes = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void NeoPixel::updateType(neoPixelType t) {
|
||||||
|
bool oldThreeBytesPerPixel = (wOffset == rOffset); // false if RGBW
|
||||||
|
|
||||||
|
wOffset = (t >> 6) & 0b11; // See notes in header file
|
||||||
|
rOffset = (t >> 4) & 0b11; // regarding R/G/B/W offsets
|
||||||
|
gOffset = (t >> 2) & 0b11;
|
||||||
|
bOffset = t & 0b11;
|
||||||
|
is800KHz = (t < 256); // 400 KHz flag is 1<<8
|
||||||
|
|
||||||
|
if (pixels) {
|
||||||
|
bool newThreeBytesPerPixel = (wOffset == rOffset);
|
||||||
|
if (newThreeBytesPerPixel != oldThreeBytesPerPixel)
|
||||||
|
updateLength(numLEDs);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void __attribute__((noinline, section(".ram_text"))) mik32Show(GPIO_TypeDef* m_port, uint32_t m_pin, uint8_t* pixels, uint32_t numBytes, bool is800KHz) {
|
||||||
|
// not support 400khz
|
||||||
|
if (!is800KHz) return;
|
||||||
|
|
||||||
|
volatile uint32_t* set = &m_port->SET;
|
||||||
|
volatile uint32_t* clr = &m_port->CLEAR;
|
||||||
|
|
||||||
|
uint8_t* ptr = pixels;
|
||||||
|
uint8_t* end = ptr + numBytes;
|
||||||
|
uint8_t p = *ptr++;
|
||||||
|
uint8_t bitMask = 0x80;
|
||||||
|
|
||||||
|
noInterrupts();
|
||||||
|
|
||||||
|
while (1) {
|
||||||
|
if (p & bitMask) { // ONE
|
||||||
|
// High 800ns - 25,6 tick
|
||||||
|
*set = m_pin;
|
||||||
|
__asm volatile (
|
||||||
|
"nop; nop; nop; nop; nop; nop; nop; nop;"
|
||||||
|
"nop; nop; nop; nop; nop; nop; nop; nop;"
|
||||||
|
"nop; nop; nop; nop;"
|
||||||
|
);
|
||||||
|
|
||||||
|
// Low 450ns - 14,4 tick
|
||||||
|
*clr = m_pin;
|
||||||
|
__asm volatile (
|
||||||
|
"nop; nop; nop; nop; nop;"
|
||||||
|
);
|
||||||
|
} else { // ZERO
|
||||||
|
// High 400ns - 12,8 tick
|
||||||
|
*set = m_pin;
|
||||||
|
__asm volatile (
|
||||||
|
"nop; nop; nop; nop; nop; nop;"
|
||||||
|
);
|
||||||
|
|
||||||
|
// Low 850ns - 27,2 tick
|
||||||
|
*clr = m_pin;
|
||||||
|
__asm volatile (
|
||||||
|
"nop; nop; nop; nop; nop; nop; nop; nop;"
|
||||||
|
"nop; nop; nop;"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bitMask >>= 1) {
|
||||||
|
// Move on to the next pixel
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (ptr >= end) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
p = *ptr++;
|
||||||
|
bitMask = 0x80;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
interrupts();
|
||||||
|
}
|
||||||
|
|
||||||
|
void NeoPixel::show(void) {
|
||||||
|
|
||||||
|
if (!pixels)
|
||||||
|
return;
|
||||||
|
|
||||||
|
while (!canShow())
|
||||||
|
;
|
||||||
|
mik32Show(gpioPort, gpioPin, pixels, numBytes, is800KHz);
|
||||||
|
endTime = micros(); // Save EOD time for latch on next call
|
||||||
|
}
|
||||||
|
|
||||||
|
void NeoPixel::setPin(int16_t p) {
|
||||||
|
if (begun && (pin >= 0))
|
||||||
|
pinMode(pin, INPUT); // Disable existing out pin
|
||||||
|
pin = p;
|
||||||
|
if (begun) {
|
||||||
|
pinMode(p, OUTPUT);
|
||||||
|
digitalWrite(p, LOW);
|
||||||
|
}
|
||||||
|
|
||||||
|
gpioPort = digitalPinToPort(pin);
|
||||||
|
gpioPin = digitalPinToBitMask(pin);
|
||||||
|
}
|
||||||
|
|
||||||
|
void NeoPixel::setPixelColor(uint16_t n, uint8_t r, uint8_t g,
|
||||||
|
uint8_t b) {
|
||||||
|
if (n < numLEDs) {
|
||||||
|
if (brightness) { // See notes in setBrightness()
|
||||||
|
r = (r * brightness) >> 8;
|
||||||
|
g = (g * brightness) >> 8;
|
||||||
|
b = (b * brightness) >> 8;
|
||||||
|
}
|
||||||
|
uint8_t *p;
|
||||||
|
if (wOffset == rOffset) { // Is an RGB-type strip
|
||||||
|
p = &pixels[n * 3]; // 3 bytes per pixel
|
||||||
|
} else { // Is a WRGB-type strip
|
||||||
|
p = &pixels[n * 4]; // 4 bytes per pixel
|
||||||
|
p[wOffset] = 0; // But only R,G,B passed -- set W to 0
|
||||||
|
}
|
||||||
|
p[rOffset] = r; // R,G,B always stored
|
||||||
|
p[gOffset] = g;
|
||||||
|
p[bOffset] = b;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void NeoPixel::setPixelColor(uint16_t n, uint8_t r, uint8_t g,
|
||||||
|
uint8_t b, uint8_t w) {
|
||||||
|
|
||||||
|
if (n < numLEDs) {
|
||||||
|
if (brightness) { // See notes in setBrightness()
|
||||||
|
r = (r * brightness) >> 8;
|
||||||
|
g = (g * brightness) >> 8;
|
||||||
|
b = (b * brightness) >> 8;
|
||||||
|
w = (w * brightness) >> 8;
|
||||||
|
}
|
||||||
|
uint8_t *p;
|
||||||
|
if (wOffset == rOffset) { // Is an RGB-type strip
|
||||||
|
p = &pixels[n * 3]; // 3 bytes per pixel (ignore W)
|
||||||
|
} else { // Is a WRGB-type strip
|
||||||
|
p = &pixels[n * 4]; // 4 bytes per pixel
|
||||||
|
p[wOffset] = w; // Store W
|
||||||
|
}
|
||||||
|
p[rOffset] = r; // Store R,G,B
|
||||||
|
p[gOffset] = g;
|
||||||
|
p[bOffset] = b;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void NeoPixel::setPixelColor(uint16_t n, uint32_t c) {
|
||||||
|
if (n < numLEDs) {
|
||||||
|
uint8_t *p, r = (uint8_t)(c >> 16), g = (uint8_t)(c >> 8), b = (uint8_t)c;
|
||||||
|
if (brightness) { // See notes in setBrightness()
|
||||||
|
r = (r * brightness) >> 8;
|
||||||
|
g = (g * brightness) >> 8;
|
||||||
|
b = (b * brightness) >> 8;
|
||||||
|
}
|
||||||
|
if (wOffset == rOffset) {
|
||||||
|
p = &pixels[n * 3];
|
||||||
|
} else {
|
||||||
|
p = &pixels[n * 4];
|
||||||
|
uint8_t w = (uint8_t)(c >> 24);
|
||||||
|
p[wOffset] = brightness ? ((w * brightness) >> 8) : w;
|
||||||
|
}
|
||||||
|
p[rOffset] = r;
|
||||||
|
p[gOffset] = g;
|
||||||
|
p[bOffset] = b;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void NeoPixel::fill(uint32_t c, uint16_t first, uint16_t count) {
|
||||||
|
uint16_t i, end;
|
||||||
|
|
||||||
|
if (first >= numLEDs) {
|
||||||
|
return; // If first LED is past end of strip, nothing to do
|
||||||
|
}
|
||||||
|
|
||||||
|
// Calculate the index ONE AFTER the last pixel to fill
|
||||||
|
if (count == 0) {
|
||||||
|
// Fill to end of strip
|
||||||
|
end = numLEDs;
|
||||||
|
} else {
|
||||||
|
// Ensure that the loop won't go past the last pixel
|
||||||
|
end = first + count;
|
||||||
|
if (end > numLEDs)
|
||||||
|
end = numLEDs;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = first; i < end; i++) {
|
||||||
|
this->setPixelColor(i, c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t NeoPixel::ColorHSV(uint16_t hue, uint8_t sat, uint8_t val) {
|
||||||
|
|
||||||
|
uint8_t r, g, b;
|
||||||
|
|
||||||
|
hue = (hue * 1530L + 32768) / 65536;
|
||||||
|
|
||||||
|
if (hue < 510) { // Red to Green-1
|
||||||
|
b = 0;
|
||||||
|
if (hue < 255) { // Red to Yellow-1
|
||||||
|
r = 255;
|
||||||
|
g = hue; // g = 0 to 254
|
||||||
|
} else { // Yellow to Green-1
|
||||||
|
r = 510 - hue; // r = 255 to 1
|
||||||
|
g = 255;
|
||||||
|
}
|
||||||
|
} else if (hue < 1020) { // Green to Blue-1
|
||||||
|
r = 0;
|
||||||
|
if (hue < 765) { // Green to Cyan-1
|
||||||
|
g = 255;
|
||||||
|
b = hue - 510; // b = 0 to 254
|
||||||
|
} else { // Cyan to Blue-1
|
||||||
|
g = 1020 - hue; // g = 255 to 1
|
||||||
|
b = 255;
|
||||||
|
}
|
||||||
|
} else if (hue < 1530) { // Blue to Red-1
|
||||||
|
g = 0;
|
||||||
|
if (hue < 1275) { // Blue to Magenta-1
|
||||||
|
r = hue - 1020; // r = 0 to 254
|
||||||
|
b = 255;
|
||||||
|
} else { // Magenta to Red-1
|
||||||
|
r = 255;
|
||||||
|
b = 1530 - hue; // b = 255 to 1
|
||||||
|
}
|
||||||
|
} else { // Last 0.5 Red (quicker than % operator)
|
||||||
|
r = 255;
|
||||||
|
g = b = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Apply saturation and value to R,G,B, pack into 32-bit result:
|
||||||
|
uint32_t v1 = 1 + val; // 1 to 256; allows >>8 instead of /255
|
||||||
|
uint16_t s1 = 1 + sat; // 1 to 256; same reason
|
||||||
|
uint8_t s2 = 255 - sat; // 255 to 0
|
||||||
|
return ((((((r * s1) >> 8) + s2) * v1) & 0xff00) << 8) |
|
||||||
|
(((((g * s1) >> 8) + s2) * v1) & 0xff00) |
|
||||||
|
(((((b * s1) >> 8) + s2) * v1) >> 8);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
uint32_t NeoPixel::getPixelColor(uint16_t n) const {
|
||||||
|
if (n >= numLEDs)
|
||||||
|
return 0; // Out of bounds, return no color.
|
||||||
|
|
||||||
|
uint8_t *p;
|
||||||
|
|
||||||
|
if (wOffset == rOffset) { // Is RGB-type device
|
||||||
|
p = &pixels[n * 3];
|
||||||
|
if (brightness) {
|
||||||
|
|
||||||
|
return (((uint32_t)(p[rOffset] << 8) / brightness) << 16) |
|
||||||
|
(((uint32_t)(p[gOffset] << 8) / brightness) << 8) |
|
||||||
|
((uint32_t)(p[bOffset] << 8) / brightness);
|
||||||
|
} else {
|
||||||
|
// No brightness adjustment has been made -- return 'raw' color
|
||||||
|
return ((uint32_t)p[rOffset] << 16) | ((uint32_t)p[gOffset] << 8) |
|
||||||
|
(uint32_t)p[bOffset];
|
||||||
|
}
|
||||||
|
} else { // Is RGBW-type device
|
||||||
|
p = &pixels[n * 4];
|
||||||
|
if (brightness) { // Return scaled color
|
||||||
|
return (((uint32_t)(p[wOffset] << 8) / brightness) << 24) |
|
||||||
|
(((uint32_t)(p[rOffset] << 8) / brightness) << 16) |
|
||||||
|
(((uint32_t)(p[gOffset] << 8) / brightness) << 8) |
|
||||||
|
((uint32_t)(p[bOffset] << 8) / brightness);
|
||||||
|
} else { // Return raw color
|
||||||
|
return ((uint32_t)p[wOffset] << 24) | ((uint32_t)p[rOffset] << 16) |
|
||||||
|
((uint32_t)p[gOffset] << 8) | (uint32_t)p[bOffset];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void NeoPixel::setBrightness(uint8_t b) {
|
||||||
|
|
||||||
|
uint8_t newBrightness = b + 1;
|
||||||
|
if (newBrightness != brightness) {
|
||||||
|
|
||||||
|
uint8_t c, *ptr = pixels,
|
||||||
|
oldBrightness = brightness - 1; // De-wrap old brightness value
|
||||||
|
uint16_t scale;
|
||||||
|
if (oldBrightness == 0)
|
||||||
|
scale = 0; // Avoid /0
|
||||||
|
else if (b == 255)
|
||||||
|
scale = 65535 / oldBrightness;
|
||||||
|
else
|
||||||
|
scale = (((uint16_t)newBrightness << 8) - 1) / oldBrightness;
|
||||||
|
for (uint16_t i = 0; i < numBytes; i++) {
|
||||||
|
c = *ptr;
|
||||||
|
*ptr++ = (c * scale) >> 8;
|
||||||
|
}
|
||||||
|
brightness = newBrightness;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t NeoPixel::getBrightness(void) const { return brightness - 1; }
|
||||||
|
|
||||||
|
void NeoPixel::clear(void) { memset(pixels, 0, numBytes); }
|
||||||
|
|
||||||
|
uint32_t NeoPixel::gamma32(uint32_t x) {
|
||||||
|
uint8_t *y = (uint8_t *)&x;
|
||||||
|
|
||||||
|
for (uint8_t i = 0; i < 4; i++)
|
||||||
|
y[i] = gamma8(y[i]);
|
||||||
|
return x; // Packed 32-bit return
|
||||||
|
}
|
||||||
|
|
||||||
|
void NeoPixel::rainbow(uint16_t first_hue, int8_t reps,
|
||||||
|
uint8_t saturation, uint8_t brightness, bool gammify) {
|
||||||
|
for (uint16_t i=0; i<numLEDs; i++) {
|
||||||
|
uint16_t hue = first_hue + (i * reps * 65536) / numLEDs;
|
||||||
|
uint32_t color = ColorHSV(hue, saturation, brightness);
|
||||||
|
if (gammify) color = gamma32(color);
|
||||||
|
setPixelColor(i, color);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
neoPixelType NeoPixel::str2order(const char *v) {
|
||||||
|
int8_t r = 0, g = 0, b = 0, w = -1;
|
||||||
|
if (v) {
|
||||||
|
char c;
|
||||||
|
for (uint8_t i=0; ((c = tolower(v[i]))); i++) {
|
||||||
|
if (c == 'r') r = i;
|
||||||
|
else if (c == 'g') g = i;
|
||||||
|
else if (c == 'b') b = i;
|
||||||
|
else if (c == 'w') w = i;
|
||||||
|
}
|
||||||
|
r &= 3;
|
||||||
|
}
|
||||||
|
if (w < 0) w = r; // If 'w' not specified, duplicate r bits
|
||||||
|
return (w << 6) | (r << 4) | ((g & 3) << 2) | (b & 3);
|
||||||
|
}
|
||||||
177
libraries/NeoPixel/src/NeoPixel.h
Normal file
177
libraries/NeoPixel/src/NeoPixel.h
Normal file
@ -0,0 +1,177 @@
|
|||||||
|
|
||||||
|
#ifndef NEOPIXEL_H
|
||||||
|
#define NEOPIXEL_H
|
||||||
|
|
||||||
|
#include <Arduino.h>
|
||||||
|
|
||||||
|
// RGB NeoPixel permutations; white and red offsets are always same
|
||||||
|
// Offset: W R G B
|
||||||
|
#define NEO_RGB ((0 << 6) | (0 << 4) | (1 << 2) | (2)) ///< Transmit as R,G,B
|
||||||
|
#define NEO_RBG ((0 << 6) | (0 << 4) | (2 << 2) | (1)) ///< Transmit as R,B,G
|
||||||
|
#define NEO_GRB ((1 << 6) | (1 << 4) | (0 << 2) | (2)) ///< Transmit as G,R,B
|
||||||
|
#define NEO_GBR ((2 << 6) | (2 << 4) | (0 << 2) | (1)) ///< Transmit as G,B,R
|
||||||
|
#define NEO_BRG ((1 << 6) | (1 << 4) | (2 << 2) | (0)) ///< Transmit as B,R,G
|
||||||
|
#define NEO_BGR ((2 << 6) | (2 << 4) | (1 << 2) | (0)) ///< Transmit as B,G,R
|
||||||
|
|
||||||
|
// RGBW NeoPixel permutations; all 4 offsets are distinct
|
||||||
|
// Offset: W R G B
|
||||||
|
#define NEO_WRGB ((0 << 6) | (1 << 4) | (2 << 2) | (3)) ///< Transmit as W,R,G,B
|
||||||
|
#define NEO_WRBG ((0 << 6) | (1 << 4) | (3 << 2) | (2)) ///< Transmit as W,R,B,G
|
||||||
|
#define NEO_WGRB ((0 << 6) | (2 << 4) | (1 << 2) | (3)) ///< Transmit as W,G,R,B
|
||||||
|
#define NEO_WGBR ((0 << 6) | (3 << 4) | (1 << 2) | (2)) ///< Transmit as W,G,B,R
|
||||||
|
#define NEO_WBRG ((0 << 6) | (2 << 4) | (3 << 2) | (1)) ///< Transmit as W,B,R,G
|
||||||
|
#define NEO_WBGR ((0 << 6) | (3 << 4) | (2 << 2) | (1)) ///< Transmit as W,B,G,R
|
||||||
|
|
||||||
|
#define NEO_RWGB ((1 << 6) | (0 << 4) | (2 << 2) | (3)) ///< Transmit as R,W,G,B
|
||||||
|
#define NEO_RWBG ((1 << 6) | (0 << 4) | (3 << 2) | (2)) ///< Transmit as R,W,B,G
|
||||||
|
#define NEO_RGWB ((2 << 6) | (0 << 4) | (1 << 2) | (3)) ///< Transmit as R,G,W,B
|
||||||
|
#define NEO_RGBW ((3 << 6) | (0 << 4) | (1 << 2) | (2)) ///< Transmit as R,G,B,W
|
||||||
|
#define NEO_RBWG ((2 << 6) | (0 << 4) | (3 << 2) | (1)) ///< Transmit as R,B,W,G
|
||||||
|
#define NEO_RBGW ((3 << 6) | (0 << 4) | (2 << 2) | (1)) ///< Transmit as R,B,G,W
|
||||||
|
|
||||||
|
#define NEO_GWRB ((1 << 6) | (2 << 4) | (0 << 2) | (3)) ///< Transmit as G,W,R,B
|
||||||
|
#define NEO_GWBR ((1 << 6) | (3 << 4) | (0 << 2) | (2)) ///< Transmit as G,W,B,R
|
||||||
|
#define NEO_GRWB ((2 << 6) | (1 << 4) | (0 << 2) | (3)) ///< Transmit as G,R,W,B
|
||||||
|
#define NEO_GRBW ((3 << 6) | (1 << 4) | (0 << 2) | (2)) ///< Transmit as G,R,B,W
|
||||||
|
#define NEO_GBWR ((2 << 6) | (3 << 4) | (0 << 2) | (1)) ///< Transmit as G,B,W,R
|
||||||
|
#define NEO_GBRW ((3 << 6) | (2 << 4) | (0 << 2) | (1)) ///< Transmit as G,B,R,W
|
||||||
|
|
||||||
|
#define NEO_BWRG ((1 << 6) | (2 << 4) | (3 << 2) | (0)) ///< Transmit as B,W,R,G
|
||||||
|
#define NEO_BWGR ((1 << 6) | (3 << 4) | (2 << 2) | (0)) ///< Transmit as B,W,G,R
|
||||||
|
#define NEO_BRWG ((2 << 6) | (1 << 4) | (3 << 2) | (0)) ///< Transmit as B,R,W,G
|
||||||
|
#define NEO_BRGW ((3 << 6) | (1 << 4) | (2 << 2) | (0)) ///< Transmit as B,R,G,W
|
||||||
|
#define NEO_BGWR ((2 << 6) | (3 << 4) | (1 << 2) | (0)) ///< Transmit as B,G,W,R
|
||||||
|
#define NEO_BGRW ((3 << 6) | (2 << 4) | (1 << 2) | (0)) ///< Transmit as B,G,R,W
|
||||||
|
|
||||||
|
|
||||||
|
#define NEO_KHZ400 0x0100 ///< 400 KHz data transmission
|
||||||
|
#define NEO_KHZ800 0x0000 ///< 800 KHz data transmission
|
||||||
|
|
||||||
|
|
||||||
|
typedef uint16_t neoPixelType; ///< 3rd arg to NeoPixel constructor
|
||||||
|
|
||||||
|
|
||||||
|
static const uint8_t PROGMEM _NeoPixelSineTable[256] = {
|
||||||
|
128, 131, 134, 137, 140, 143, 146, 149, 152, 155, 158, 162, 165, 167, 170,
|
||||||
|
173, 176, 179, 182, 185, 188, 190, 193, 196, 198, 201, 203, 206, 208, 211,
|
||||||
|
213, 215, 218, 220, 222, 224, 226, 228, 230, 232, 234, 235, 237, 238, 240,
|
||||||
|
241, 243, 244, 245, 246, 248, 249, 250, 250, 251, 252, 253, 253, 254, 254,
|
||||||
|
254, 255, 255, 255, 255, 255, 255, 255, 254, 254, 254, 253, 253, 252, 251,
|
||||||
|
250, 250, 249, 248, 246, 245, 244, 243, 241, 240, 238, 237, 235, 234, 232,
|
||||||
|
230, 228, 226, 224, 222, 220, 218, 215, 213, 211, 208, 206, 203, 201, 198,
|
||||||
|
196, 193, 190, 188, 185, 182, 179, 176, 173, 170, 167, 165, 162, 158, 155,
|
||||||
|
152, 149, 146, 143, 140, 137, 134, 131, 128, 124, 121, 118, 115, 112, 109,
|
||||||
|
106, 103, 100, 97, 93, 90, 88, 85, 82, 79, 76, 73, 70, 67, 65,
|
||||||
|
62, 59, 57, 54, 52, 49, 47, 44, 42, 40, 37, 35, 33, 31, 29,
|
||||||
|
27, 25, 23, 21, 20, 18, 17, 15, 14, 12, 11, 10, 9, 7, 6,
|
||||||
|
5, 5, 4, 3, 2, 2, 1, 1, 1, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 1, 1, 1, 2, 2, 3, 4, 5, 5, 6, 7, 9, 10, 11,
|
||||||
|
12, 14, 15, 17, 18, 20, 21, 23, 25, 27, 29, 31, 33, 35, 37,
|
||||||
|
40, 42, 44, 47, 49, 52, 54, 57, 59, 62, 65, 67, 70, 73, 76,
|
||||||
|
79, 82, 85, 88, 90, 93, 97, 100, 103, 106, 109, 112, 115, 118, 121,
|
||||||
|
124};
|
||||||
|
|
||||||
|
|
||||||
|
static const uint8_t PROGMEM _NeoPixelGammaTable[256] = {
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1,
|
||||||
|
1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 3,
|
||||||
|
3, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 5, 6,
|
||||||
|
6, 6, 6, 7, 7, 7, 8, 8, 8, 9, 9, 9, 10, 10, 10,
|
||||||
|
11, 11, 11, 12, 12, 13, 13, 13, 14, 14, 15, 15, 16, 16, 17,
|
||||||
|
17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22, 23, 24, 24, 25,
|
||||||
|
25, 26, 27, 27, 28, 29, 29, 30, 31, 31, 32, 33, 34, 34, 35,
|
||||||
|
36, 37, 38, 38, 39, 40, 41, 42, 42, 43, 44, 45, 46, 47, 48,
|
||||||
|
49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
|
||||||
|
64, 65, 66, 68, 69, 70, 71, 72, 73, 75, 76, 77, 78, 80, 81,
|
||||||
|
82, 84, 85, 86, 88, 89, 90, 92, 93, 94, 96, 97, 99, 100, 102,
|
||||||
|
103, 105, 106, 108, 109, 111, 112, 114, 115, 117, 119, 120, 122, 124, 125,
|
||||||
|
127, 129, 130, 132, 134, 136, 137, 139, 141, 143, 145, 146, 148, 150, 152,
|
||||||
|
154, 156, 158, 160, 162, 164, 166, 168, 170, 172, 174, 176, 178, 180, 182,
|
||||||
|
184, 186, 188, 191, 193, 195, 197, 199, 202, 204, 206, 209, 211, 213, 215,
|
||||||
|
218, 220, 223, 225, 227, 230, 232, 235, 237, 240, 242, 245, 247, 250, 252,
|
||||||
|
255};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class NeoPixel {
|
||||||
|
|
||||||
|
public:
|
||||||
|
// Constructor: number of LEDs, pin number, LED type
|
||||||
|
NeoPixel(uint16_t n, int16_t pin = 6,
|
||||||
|
neoPixelType type = NEO_GRB + NEO_KHZ800);
|
||||||
|
NeoPixel(void);
|
||||||
|
~NeoPixel();
|
||||||
|
|
||||||
|
void begin(void);
|
||||||
|
void show(void);
|
||||||
|
void setPin(int16_t p);
|
||||||
|
void setPixelColor(uint16_t n, uint8_t r, uint8_t g, uint8_t b);
|
||||||
|
void setPixelColor(uint16_t n, uint8_t r, uint8_t g, uint8_t b, uint8_t w);
|
||||||
|
void setPixelColor(uint16_t n, uint32_t c);
|
||||||
|
void fill(uint32_t c = 0, uint16_t first = 0, uint16_t count = 0);
|
||||||
|
void setBrightness(uint8_t);
|
||||||
|
void clear(void);
|
||||||
|
void updateLength(uint16_t n);
|
||||||
|
void updateType(neoPixelType t);
|
||||||
|
|
||||||
|
bool canShow(void) {
|
||||||
|
uint32_t now = micros();
|
||||||
|
if (endTime > now) {
|
||||||
|
endTime = now;
|
||||||
|
}
|
||||||
|
return (now - endTime) >= 300L;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t *getPixels(void) const { return pixels; };
|
||||||
|
uint8_t getBrightness(void) const;
|
||||||
|
|
||||||
|
int16_t getPin(void) const { return pin; };
|
||||||
|
|
||||||
|
uint16_t numPixels(void) const { return numLEDs; }
|
||||||
|
uint32_t getPixelColor(uint16_t n) const;
|
||||||
|
|
||||||
|
static uint8_t sine8(uint8_t x) {
|
||||||
|
return pgm_read_byte(&_NeoPixelSineTable[x]); // 0-255 in, 0-255 out
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint8_t gamma8(uint8_t x) {
|
||||||
|
return pgm_read_byte(&_NeoPixelGammaTable[x]); // 0-255 in, 0-255 out
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint32_t Color(uint8_t r, uint8_t g, uint8_t b) {
|
||||||
|
return ((uint32_t)r << 16) | ((uint32_t)g << 8) | b;
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint32_t Color(uint8_t r, uint8_t g, uint8_t b, uint8_t w) {
|
||||||
|
return ((uint32_t)w << 24) | ((uint32_t)r << 16) | ((uint32_t)g << 8) | b;
|
||||||
|
}
|
||||||
|
static uint32_t ColorHSV(uint16_t hue, uint8_t sat = 255, uint8_t val = 255);
|
||||||
|
|
||||||
|
static uint32_t gamma32(uint32_t x);
|
||||||
|
|
||||||
|
void rainbow(uint16_t first_hue = 0, int8_t reps = 1,
|
||||||
|
uint8_t saturation = 255, uint8_t brightness = 255,
|
||||||
|
bool gammify = true);
|
||||||
|
|
||||||
|
static neoPixelType str2order(const char *v);
|
||||||
|
|
||||||
|
|
||||||
|
protected:
|
||||||
|
bool is800KHz; ///< true if 800 KHz pixels
|
||||||
|
bool begun; ///< true if begin() previously called
|
||||||
|
uint16_t numLEDs; ///< Number of RGB LEDs in strip
|
||||||
|
uint16_t numBytes; ///< Size of 'pixels' buffer below
|
||||||
|
int16_t pin; ///< Output pin number (-1 if not yet set)
|
||||||
|
uint8_t brightness; ///< Strip brightness 0-255 (stored as +1)
|
||||||
|
uint8_t *pixels; ///< Holds LED color values (3 or 4 bytes each)
|
||||||
|
uint8_t rOffset; ///< Red index within each 3- or 4-byte pixel
|
||||||
|
uint8_t gOffset; ///< Index of green byte
|
||||||
|
uint8_t bOffset; ///< Index of blue byte
|
||||||
|
uint8_t wOffset; ///< Index of white (==rOffset if no white)
|
||||||
|
uint32_t endTime; ///< Latch timing reference
|
||||||
|
GPIO_TypeDef *gpioPort; ///< Output GPIO PORT
|
||||||
|
uint32_t gpioPin; ///< Output GPIO PIN
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // NEOPIXEL_H
|
||||||
@ -2,10 +2,11 @@
|
|||||||
#include "mik32_hal_spi.h"
|
#include "mik32_hal_spi.h"
|
||||||
|
|
||||||
SPI_HandleTypeDef hspi;
|
SPI_HandleTypeDef hspi;
|
||||||
|
|
||||||
bool newConfig = false;
|
bool newConfig = false;
|
||||||
bool isInited = false;
|
bool isInited = false;
|
||||||
uint32_t currentSpeed = 0;
|
uint32_t currentSpeed = 0;
|
||||||
int8_t currentDataOrder = -1;
|
int8_t currentDataOrder = MSBFIRST;
|
||||||
int8_t currentDataMode = -1;
|
int8_t currentDataMode = -1;
|
||||||
static uint8_t reverse_bits(uint8_t byte);
|
static uint8_t reverse_bits(uint8_t byte);
|
||||||
|
|
||||||
@ -31,16 +32,10 @@ void SPISettings::spiUpdateSettings(uint32_t speedMaximum, uint8_t dataOrder, ui
|
|||||||
}
|
}
|
||||||
// if break didn't call in cycle, it will be the greatest divRegVal (and divider)
|
// if break didn't call in cycle, it will be the greatest divRegVal (and divider)
|
||||||
|
|
||||||
// update config
|
// update params in struct
|
||||||
hspi.Instance = SPI_1;
|
|
||||||
hspi.Init.SPI_Mode = HAL_SPI_MODE_MASTER; // only master mode
|
|
||||||
hspi.Init.CLKPhase = dataMode & 0b00000001;
|
hspi.Init.CLKPhase = dataMode & 0b00000001;
|
||||||
hspi.Init.CLKPolarity = (dataMode & 0b00000010)>>1;
|
hspi.Init.CLKPolarity = (dataMode & 0b00000010)>>1;
|
||||||
hspi.Init.ThresholdTX = 4;
|
|
||||||
hspi.Init.BaudRateDiv = divRegVal;
|
hspi.Init.BaudRateDiv = divRegVal;
|
||||||
hspi.Init.Decoder = SPI_DECODER_NONE;
|
|
||||||
hspi.Init.ManualCS = SPI_MANUALCS_ON;
|
|
||||||
hspi.Init.ChipSelect = SPI_CS_NONE;
|
|
||||||
|
|
||||||
currentSpeed = speedMaximum;
|
currentSpeed = speedMaximum;
|
||||||
currentDataOrder = dataOrder;
|
currentDataOrder = dataOrder;
|
||||||
@ -50,9 +45,6 @@ void SPISettings::spiUpdateSettings(uint32_t speedMaximum, uint8_t dataOrder, ui
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------ //
|
// ------------------------------------------------------------------ //
|
||||||
// pins shift in gpio register
|
|
||||||
#define PIN_1_3_GPIO_S 3
|
|
||||||
#define PIN_1_4_GPIO_S 4
|
|
||||||
|
|
||||||
SPIClass SPI;
|
SPIClass SPI;
|
||||||
bool SPIClass::spiInUse = false;
|
bool SPIClass::spiInUse = false;
|
||||||
@ -61,42 +53,19 @@ uint8_t SPIClass::interruptMask = 0;
|
|||||||
|
|
||||||
void SPIClass::begin()
|
void SPIClass::begin()
|
||||||
{
|
{
|
||||||
// there is a seller on pin 1.6 which replace D10 from spi NSS pin 1.3 to pin 1.4,
|
spi_onBegin();
|
||||||
// because spi needs pin 1.3 for correct work
|
|
||||||
|
|
||||||
// replace config from 1.3 to 1.4
|
// set constant parameters in spi struct
|
||||||
uint8_t config = ((PAD_CONFIG->PORT_1_CFG) & (0b11<<(2*PIN_1_3_GPIO_S))) >> (2*PIN_1_3_GPIO_S);
|
hspi.Instance = SPI_1;
|
||||||
if (config == 0) // common gpio
|
hspi.Init.SPI_Mode = HAL_SPI_MODE_MASTER; // only master mode used
|
||||||
{
|
hspi.Init.ThresholdTX = 4;
|
||||||
// pin direction
|
hspi.Init.Decoder = SPI_DECODER_NONE;
|
||||||
uint8_t direction = ((GPIO_1->DIRECTION_IN) & (1<<PIN_1_3_GPIO_S)) >> PIN_1_3_GPIO_S;
|
hspi.Init.ManualCS = SPI_MANUALCS_ON;
|
||||||
if (direction == 1) // input
|
hspi.Init.ChipSelect = SPI_CS_NONE;
|
||||||
GPIO_1->DIRECTION_IN |= (1<<PIN_1_4_GPIO_S);
|
// adjustable parameters default values as in SPISettings()
|
||||||
else // output
|
hspi.Init.BaudRateDiv = SPI_CLOCK_DIV8;
|
||||||
GPIO_1->DIRECTION_OUT |= (1<<PIN_1_4_GPIO_S);
|
hspi.Init.CLKPhase = SPI_MODE0 & 0b00000001;
|
||||||
|
hspi.Init.CLKPolarity = (SPI_MODE0 & 0b00000010)>>1;
|
||||||
// pull up/down
|
|
||||||
uint8_t pupd_1_3 = ((PAD_CONFIG ->PORT_1_PUPD) & (0b11<<(2*PIN_1_3_GPIO_S))) >> (2*PIN_1_3_GPIO_S);
|
|
||||||
PAD_CONFIG ->PORT_1_PUPD &= (~(0b11<<(2*PIN_1_4_GPIO_S))); // clear
|
|
||||||
PAD_CONFIG ->PORT_1_PUPD |= ((pupd_1_3&0b11)<<(2*PIN_1_4_GPIO_S)); // set new
|
|
||||||
|
|
||||||
//current state
|
|
||||||
uint8_t state1_3 = ((GPIO_1->OUTPUT_) & (1<<PIN_1_3_GPIO_S)) >> PIN_1_3_GPIO_S;
|
|
||||||
GPIO_1->OUTPUT_ &= (~(0b1<<PIN_1_4_GPIO_S)); // clear
|
|
||||||
GPIO_1->OUTPUT_ |= ((state1_3&0b1)<<PIN_1_4_GPIO_S); // set new
|
|
||||||
}
|
|
||||||
else if(config == 2) // timer for pwm
|
|
||||||
{
|
|
||||||
// if D10 (spi NSS pin) was used as pwm, we need to stop timer,
|
|
||||||
// because 1.4 don't support timer
|
|
||||||
analogWriteStop(10);
|
|
||||||
ErrorMsgHandler("analogWrite(): D10 cannot be used as PWM pin while SPI is running");
|
|
||||||
}
|
|
||||||
|
|
||||||
// switch seller to pin 1.4
|
|
||||||
HAL_GPIO_PinConfig(GPIO_1, GPIO_PIN_6, HAL_GPIO_MODE_GPIO_OUTPUT, HAL_GPIO_PULL_NONE, HAL_GPIO_DS_2MA);
|
|
||||||
HAL_GPIO_WritePin(GPIO_1, GPIO_PIN_6, GPIO_PIN_HIGH);
|
|
||||||
blockSpiPin();
|
|
||||||
|
|
||||||
spiInUse = true;
|
spiInUse = true;
|
||||||
}
|
}
|
||||||
@ -115,29 +84,7 @@ void SPIClass::end()
|
|||||||
HAL_GPIO_MODE_GPIO_INPUT, HAL_GPIO_PULL_NONE, HAL_GPIO_DS_2MA);
|
HAL_GPIO_MODE_GPIO_INPUT, HAL_GPIO_PULL_NONE, HAL_GPIO_DS_2MA);
|
||||||
}
|
}
|
||||||
|
|
||||||
// return D10 with common gpio config to pin 1.3
|
spi_onEnd();
|
||||||
PAD_CONFIG->PORT_1_CFG &= (~(0b11<<(2*PIN_1_3_GPIO_S))); // set config to 0 - common gpio mode
|
|
||||||
|
|
||||||
// pin direction
|
|
||||||
uint8_t direction = ((GPIO_1->DIRECTION_IN) & (1<<PIN_1_4_GPIO_S)) >> PIN_1_4_GPIO_S;
|
|
||||||
if (direction == 1) // input
|
|
||||||
GPIO_1->DIRECTION_IN |= (1<<PIN_1_3_GPIO_S);
|
|
||||||
else // output
|
|
||||||
GPIO_1->DIRECTION_OUT |= (1<<PIN_1_3_GPIO_S);
|
|
||||||
|
|
||||||
// pull up/down
|
|
||||||
uint8_t pupd_1_4 = ((PAD_CONFIG ->PORT_1_PUPD) & (0b11<<(2*PIN_1_4_GPIO_S))) >> (2*PIN_1_4_GPIO_S);
|
|
||||||
PAD_CONFIG ->PORT_1_PUPD &= (~(0b11<<(2*PIN_1_3_GPIO_S))); // clear
|
|
||||||
PAD_CONFIG ->PORT_1_PUPD |= ((pupd_1_4&0b11)<<(2*PIN_1_3_GPIO_S)); // set new
|
|
||||||
|
|
||||||
// current state
|
|
||||||
uint8_t state1_4 = ((GPIO_1->OUTPUT_) & (1<<PIN_1_4_GPIO_S)) >> PIN_1_4_GPIO_S;
|
|
||||||
GPIO_1->OUTPUT_ &= (~(0b1<<PIN_1_3_GPIO_S)); // clear
|
|
||||||
GPIO_1->OUTPUT_ |= ((state1_4&0b1)<<PIN_1_3_GPIO_S); // set new
|
|
||||||
|
|
||||||
// switch seller back to pin 1.3
|
|
||||||
HAL_GPIO_WritePin(GPIO_1, GPIO_PIN_6, GPIO_PIN_LOW);
|
|
||||||
unblockSpiPin();
|
|
||||||
|
|
||||||
spiInUse = false;
|
spiInUse = false;
|
||||||
isInited = false;
|
isInited = false;
|
||||||
@ -299,35 +246,44 @@ void SPIClass::endTransaction(void)
|
|||||||
// ------------------------------------ //
|
// ------------------------------------ //
|
||||||
void SPIClass::setBitOrder(uint8_t bitOrder)
|
void SPIClass::setBitOrder(uint8_t bitOrder)
|
||||||
{
|
{
|
||||||
currentDataOrder = bitOrder;
|
if (spiInUse)
|
||||||
|
currentDataOrder = bitOrder;
|
||||||
|
else
|
||||||
|
ErrorMsgHandler("SPI.setBitOrder():SPI.begin() need to be called first");
|
||||||
}
|
}
|
||||||
|
|
||||||
void SPIClass::setDataMode(uint8_t dataMode)
|
void SPIClass::setDataMode(uint8_t dataMode)
|
||||||
{
|
{
|
||||||
uint32_t config = hspi.Instance->CONFIG;
|
if (spiInUse)
|
||||||
HAL_SPI_Disable(&hspi);
|
{
|
||||||
hspi.Init.CLKPhase = dataMode & 0b00000001;
|
hspi.Init.CLKPhase = (dataMode&0b00000001);
|
||||||
hspi.Init.CLKPolarity = (dataMode & 0b00000010)>>1;
|
hspi.Init.CLKPolarity = (dataMode&0b00000010)>>1;
|
||||||
config &= ~((1 << SPI_CONFIG_CLK_PH_S) | (1 << SPI_CONFIG_CLK_POL_S)); // clear
|
HAL_SPI_Set_Clock_Mode(&hspi);
|
||||||
config |= ((hspi.Init.CLKPhase << SPI_CONFIG_CLK_PH_S) |
|
currentDataMode = dataMode;
|
||||||
(hspi.Init.CLKPolarity << SPI_CONFIG_CLK_POL_S)); // set new
|
}
|
||||||
hspi.Instance->CONFIG = config;
|
else
|
||||||
HAL_SPI_Enable(&hspi);
|
ErrorMsgHandler("SPI.setDataMode():SPI.begin() need to be called first");
|
||||||
}
|
}
|
||||||
|
|
||||||
void SPIClass::setClockDivider(uint8_t clockDiv)
|
void SPIClass::setClockDivider(uint8_t clockDiv)
|
||||||
{
|
{
|
||||||
// if divider is in valid range
|
if (spiInUse)
|
||||||
if ((clockDiv >= SPI_CLOCK_DIV4) && (clockDiv <= SPI_CLOCK_DIV256))
|
|
||||||
{
|
{
|
||||||
uint32_t config = hspi.Instance->CONFIG;
|
// if divider is valid
|
||||||
HAL_SPI_Disable(&hspi);
|
if ((clockDiv == SPI_CLOCK_DIV4) || (clockDiv == SPI_CLOCK_DIV8) ||
|
||||||
hspi.Init.BaudRateDiv = clockDiv;
|
(clockDiv == SPI_CLOCK_DIV16) || (clockDiv == SPI_CLOCK_DIV32) ||
|
||||||
config &= ~(0b111 << SPI_CONFIG_BAUD_RATE_DIV_S); // clear
|
(clockDiv == SPI_CLOCK_DIV64) || (clockDiv == SPI_CLOCK_DIV128) ||
|
||||||
config |= (hspi.Init.BaudRateDiv << SPI_CONFIG_BAUD_RATE_DIV_S); // set new
|
(clockDiv == SPI_CLOCK_DIV256))
|
||||||
hspi.Instance->CONFIG = config;
|
{
|
||||||
HAL_SPI_Enable(&hspi);
|
hspi.Init.BaudRateDiv = clockDiv;
|
||||||
|
currentSpeed = F_CPU >> (clockDiv+1);
|
||||||
|
HAL_SPI_Set_Clock_Divider(&hspi);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
ErrorMsgHandler("SPI.setClockDivider(): Invalid clock devider");
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
ErrorMsgHandler("SPI.setClockDivider():SPI.begin() need to be called first");
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint8_t reverse_bits(uint8_t byte)
|
static uint8_t reverse_bits(uint8_t byte)
|
||||||
|
|||||||
504
libraries/Servo/LICENSE.txt
Normal file
504
libraries/Servo/LICENSE.txt
Normal file
@ -0,0 +1,504 @@
|
|||||||
|
GNU LESSER GENERAL PUBLIC LICENSE
|
||||||
|
Version 2.1, February 1999
|
||||||
|
|
||||||
|
Copyright (C) 1991, 1999 Free Software Foundation, Inc.
|
||||||
|
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
Everyone is permitted to copy and distribute verbatim copies
|
||||||
|
of this license document, but changing it is not allowed.
|
||||||
|
|
||||||
|
[This is the first released version of the Lesser GPL. It also counts
|
||||||
|
as the successor of the GNU Library Public License, version 2, hence
|
||||||
|
the version number 2.1.]
|
||||||
|
|
||||||
|
Preamble
|
||||||
|
|
||||||
|
The licenses for most software are designed to take away your
|
||||||
|
freedom to share and change it. By contrast, the GNU General Public
|
||||||
|
Licenses are intended to guarantee your freedom to share and change
|
||||||
|
free software--to make sure the software is free for all its users.
|
||||||
|
|
||||||
|
This license, the Lesser General Public License, applies to some
|
||||||
|
specially designated software packages--typically libraries--of the
|
||||||
|
Free Software Foundation and other authors who decide to use it. You
|
||||||
|
can use it too, but we suggest you first think carefully about whether
|
||||||
|
this license or the ordinary General Public License is the better
|
||||||
|
strategy to use in any particular case, based on the explanations below.
|
||||||
|
|
||||||
|
When we speak of free software, we are referring to freedom of use,
|
||||||
|
not price. Our General Public Licenses are designed to make sure that
|
||||||
|
you have the freedom to distribute copies of free software (and charge
|
||||||
|
for this service if you wish); that you receive source code or can get
|
||||||
|
it if you want it; that you can change the software and use pieces of
|
||||||
|
it in new free programs; and that you are informed that you can do
|
||||||
|
these things.
|
||||||
|
|
||||||
|
To protect your rights, we need to make restrictions that forbid
|
||||||
|
distributors to deny you these rights or to ask you to surrender these
|
||||||
|
rights. These restrictions translate to certain responsibilities for
|
||||||
|
you if you distribute copies of the library or if you modify it.
|
||||||
|
|
||||||
|
For example, if you distribute copies of the library, whether gratis
|
||||||
|
or for a fee, you must give the recipients all the rights that we gave
|
||||||
|
you. You must make sure that they, too, receive or can get the source
|
||||||
|
code. If you link other code with the library, you must provide
|
||||||
|
complete object files to the recipients, so that they can relink them
|
||||||
|
with the library after making changes to the library and recompiling
|
||||||
|
it. And you must show them these terms so they know their rights.
|
||||||
|
|
||||||
|
We protect your rights with a two-step method: (1) we copyright the
|
||||||
|
library, and (2) we offer you this license, which gives you legal
|
||||||
|
permission to copy, distribute and/or modify the library.
|
||||||
|
|
||||||
|
To protect each distributor, we want to make it very clear that
|
||||||
|
there is no warranty for the free library. Also, if the library is
|
||||||
|
modified by someone else and passed on, the recipients should know
|
||||||
|
that what they have is not the original version, so that the original
|
||||||
|
author's reputation will not be affected by problems that might be
|
||||||
|
introduced by others.
|
||||||
|
|
||||||
|
Finally, software patents pose a constant threat to the existence of
|
||||||
|
any free program. We wish to make sure that a company cannot
|
||||||
|
effectively restrict the users of a free program by obtaining a
|
||||||
|
restrictive license from a patent holder. Therefore, we insist that
|
||||||
|
any patent license obtained for a version of the library must be
|
||||||
|
consistent with the full freedom of use specified in this license.
|
||||||
|
|
||||||
|
Most GNU software, including some libraries, is covered by the
|
||||||
|
ordinary GNU General Public License. This license, the GNU Lesser
|
||||||
|
General Public License, applies to certain designated libraries, and
|
||||||
|
is quite different from the ordinary General Public License. We use
|
||||||
|
this license for certain libraries in order to permit linking those
|
||||||
|
libraries into non-free programs.
|
||||||
|
|
||||||
|
When a program is linked with a library, whether statically or using
|
||||||
|
a shared library, the combination of the two is legally speaking a
|
||||||
|
combined work, a derivative of the original library. The ordinary
|
||||||
|
General Public License therefore permits such linking only if the
|
||||||
|
entire combination fits its criteria of freedom. The Lesser General
|
||||||
|
Public License permits more lax criteria for linking other code with
|
||||||
|
the library.
|
||||||
|
|
||||||
|
We call this license the "Lesser" General Public License because it
|
||||||
|
does Less to protect the user's freedom than the ordinary General
|
||||||
|
Public License. It also provides other free software developers Less
|
||||||
|
of an advantage over competing non-free programs. These disadvantages
|
||||||
|
are the reason we use the ordinary General Public License for many
|
||||||
|
libraries. However, the Lesser license provides advantages in certain
|
||||||
|
special circumstances.
|
||||||
|
|
||||||
|
For example, on rare occasions, there may be a special need to
|
||||||
|
encourage the widest possible use of a certain library, so that it becomes
|
||||||
|
a de-facto standard. To achieve this, non-free programs must be
|
||||||
|
allowed to use the library. A more frequent case is that a free
|
||||||
|
library does the same job as widely used non-free libraries. In this
|
||||||
|
case, there is little to gain by limiting the free library to free
|
||||||
|
software only, so we use the Lesser General Public License.
|
||||||
|
|
||||||
|
In other cases, permission to use a particular library in non-free
|
||||||
|
programs enables a greater number of people to use a large body of
|
||||||
|
free software. For example, permission to use the GNU C Library in
|
||||||
|
non-free programs enables many more people to use the whole GNU
|
||||||
|
operating system, as well as its variant, the GNU/Linux operating
|
||||||
|
system.
|
||||||
|
|
||||||
|
Although the Lesser General Public License is Less protective of the
|
||||||
|
users' freedom, it does ensure that the user of a program that is
|
||||||
|
linked with the Library has the freedom and the wherewithal to run
|
||||||
|
that program using a modified version of the Library.
|
||||||
|
|
||||||
|
The precise terms and conditions for copying, distribution and
|
||||||
|
modification follow. Pay close attention to the difference between a
|
||||||
|
"work based on the library" and a "work that uses the library". The
|
||||||
|
former contains code derived from the library, whereas the latter must
|
||||||
|
be combined with the library in order to run.
|
||||||
|
|
||||||
|
GNU LESSER GENERAL PUBLIC LICENSE
|
||||||
|
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||||
|
|
||||||
|
0. This License Agreement applies to any software library or other
|
||||||
|
program which contains a notice placed by the copyright holder or
|
||||||
|
other authorized party saying it may be distributed under the terms of
|
||||||
|
this Lesser General Public License (also called "this License").
|
||||||
|
Each licensee is addressed as "you".
|
||||||
|
|
||||||
|
A "library" means a collection of software functions and/or data
|
||||||
|
prepared so as to be conveniently linked with application programs
|
||||||
|
(which use some of those functions and data) to form executables.
|
||||||
|
|
||||||
|
The "Library", below, refers to any such software library or work
|
||||||
|
which has been distributed under these terms. A "work based on the
|
||||||
|
Library" means either the Library or any derivative work under
|
||||||
|
copyright law: that is to say, a work containing the Library or a
|
||||||
|
portion of it, either verbatim or with modifications and/or translated
|
||||||
|
straightforwardly into another language. (Hereinafter, translation is
|
||||||
|
included without limitation in the term "modification".)
|
||||||
|
|
||||||
|
"Source code" for a work means the preferred form of the work for
|
||||||
|
making modifications to it. For a library, complete source code means
|
||||||
|
all the source code for all modules it contains, plus any associated
|
||||||
|
interface definition files, plus the scripts used to control compilation
|
||||||
|
and installation of the library.
|
||||||
|
|
||||||
|
Activities other than copying, distribution and modification are not
|
||||||
|
covered by this License; they are outside its scope. The act of
|
||||||
|
running a program using the Library is not restricted, and output from
|
||||||
|
such a program is covered only if its contents constitute a work based
|
||||||
|
on the Library (independent of the use of the Library in a tool for
|
||||||
|
writing it). Whether that is true depends on what the Library does
|
||||||
|
and what the program that uses the Library does.
|
||||||
|
|
||||||
|
1. You may copy and distribute verbatim copies of the Library's
|
||||||
|
complete source code as you receive it, in any medium, provided that
|
||||||
|
you conspicuously and appropriately publish on each copy an
|
||||||
|
appropriate copyright notice and disclaimer of warranty; keep intact
|
||||||
|
all the notices that refer to this License and to the absence of any
|
||||||
|
warranty; and distribute a copy of this License along with the
|
||||||
|
Library.
|
||||||
|
|
||||||
|
You may charge a fee for the physical act of transferring a copy,
|
||||||
|
and you may at your option offer warranty protection in exchange for a
|
||||||
|
fee.
|
||||||
|
|
||||||
|
2. You may modify your copy or copies of the Library or any portion
|
||||||
|
of it, thus forming a work based on the Library, and copy and
|
||||||
|
distribute such modifications or work under the terms of Section 1
|
||||||
|
above, provided that you also meet all of these conditions:
|
||||||
|
|
||||||
|
a) The modified work must itself be a software library.
|
||||||
|
|
||||||
|
b) You must cause the files modified to carry prominent notices
|
||||||
|
stating that you changed the files and the date of any change.
|
||||||
|
|
||||||
|
c) You must cause the whole of the work to be licensed at no
|
||||||
|
charge to all third parties under the terms of this License.
|
||||||
|
|
||||||
|
d) If a facility in the modified Library refers to a function or a
|
||||||
|
table of data to be supplied by an application program that uses
|
||||||
|
the facility, other than as an argument passed when the facility
|
||||||
|
is invoked, then you must make a good faith effort to ensure that,
|
||||||
|
in the event an application does not supply such function or
|
||||||
|
table, the facility still operates, and performs whatever part of
|
||||||
|
its purpose remains meaningful.
|
||||||
|
|
||||||
|
(For example, a function in a library to compute square roots has
|
||||||
|
a purpose that is entirely well-defined independent of the
|
||||||
|
application. Therefore, Subsection 2d requires that any
|
||||||
|
application-supplied function or table used by this function must
|
||||||
|
be optional: if the application does not supply it, the square
|
||||||
|
root function must still compute square roots.)
|
||||||
|
|
||||||
|
These requirements apply to the modified work as a whole. If
|
||||||
|
identifiable sections of that work are not derived from the Library,
|
||||||
|
and can be reasonably considered independent and separate works in
|
||||||
|
themselves, then this License, and its terms, do not apply to those
|
||||||
|
sections when you distribute them as separate works. But when you
|
||||||
|
distribute the same sections as part of a whole which is a work based
|
||||||
|
on the Library, the distribution of the whole must be on the terms of
|
||||||
|
this License, whose permissions for other licensees extend to the
|
||||||
|
entire whole, and thus to each and every part regardless of who wrote
|
||||||
|
it.
|
||||||
|
|
||||||
|
Thus, it is not the intent of this section to claim rights or contest
|
||||||
|
your rights to work written entirely by you; rather, the intent is to
|
||||||
|
exercise the right to control the distribution of derivative or
|
||||||
|
collective works based on the Library.
|
||||||
|
|
||||||
|
In addition, mere aggregation of another work not based on the Library
|
||||||
|
with the Library (or with a work based on the Library) on a volume of
|
||||||
|
a storage or distribution medium does not bring the other work under
|
||||||
|
the scope of this License.
|
||||||
|
|
||||||
|
3. You may opt to apply the terms of the ordinary GNU General Public
|
||||||
|
License instead of this License to a given copy of the Library. To do
|
||||||
|
this, you must alter all the notices that refer to this License, so
|
||||||
|
that they refer to the ordinary GNU General Public License, version 2,
|
||||||
|
instead of to this License. (If a newer version than version 2 of the
|
||||||
|
ordinary GNU General Public License has appeared, then you can specify
|
||||||
|
that version instead if you wish.) Do not make any other change in
|
||||||
|
these notices.
|
||||||
|
|
||||||
|
Once this change is made in a given copy, it is irreversible for
|
||||||
|
that copy, so the ordinary GNU General Public License applies to all
|
||||||
|
subsequent copies and derivative works made from that copy.
|
||||||
|
|
||||||
|
This option is useful when you wish to copy part of the code of
|
||||||
|
the Library into a program that is not a library.
|
||||||
|
|
||||||
|
4. You may copy and distribute the Library (or a portion or
|
||||||
|
derivative of it, under Section 2) in object code or executable form
|
||||||
|
under the terms of Sections 1 and 2 above provided that you accompany
|
||||||
|
it with the complete corresponding machine-readable source code, which
|
||||||
|
must be distributed under the terms of Sections 1 and 2 above on a
|
||||||
|
medium customarily used for software interchange.
|
||||||
|
|
||||||
|
If distribution of object code is made by offering access to copy
|
||||||
|
from a designated place, then offering equivalent access to copy the
|
||||||
|
source code from the same place satisfies the requirement to
|
||||||
|
distribute the source code, even though third parties are not
|
||||||
|
compelled to copy the source along with the object code.
|
||||||
|
|
||||||
|
5. A program that contains no derivative of any portion of the
|
||||||
|
Library, but is designed to work with the Library by being compiled or
|
||||||
|
linked with it, is called a "work that uses the Library". Such a
|
||||||
|
work, in isolation, is not a derivative work of the Library, and
|
||||||
|
therefore falls outside the scope of this License.
|
||||||
|
|
||||||
|
However, linking a "work that uses the Library" with the Library
|
||||||
|
creates an executable that is a derivative of the Library (because it
|
||||||
|
contains portions of the Library), rather than a "work that uses the
|
||||||
|
library". The executable is therefore covered by this License.
|
||||||
|
Section 6 states terms for distribution of such executables.
|
||||||
|
|
||||||
|
When a "work that uses the Library" uses material from a header file
|
||||||
|
that is part of the Library, the object code for the work may be a
|
||||||
|
derivative work of the Library even though the source code is not.
|
||||||
|
Whether this is true is especially significant if the work can be
|
||||||
|
linked without the Library, or if the work is itself a library. The
|
||||||
|
threshold for this to be true is not precisely defined by law.
|
||||||
|
|
||||||
|
If such an object file uses only numerical parameters, data
|
||||||
|
structure layouts and accessors, and small macros and small inline
|
||||||
|
functions (ten lines or less in length), then the use of the object
|
||||||
|
file is unrestricted, regardless of whether it is legally a derivative
|
||||||
|
work. (Executables containing this object code plus portions of the
|
||||||
|
Library will still fall under Section 6.)
|
||||||
|
|
||||||
|
Otherwise, if the work is a derivative of the Library, you may
|
||||||
|
distribute the object code for the work under the terms of Section 6.
|
||||||
|
Any executables containing that work also fall under Section 6,
|
||||||
|
whether or not they are linked directly with the Library itself.
|
||||||
|
|
||||||
|
6. As an exception to the Sections above, you may also combine or
|
||||||
|
link a "work that uses the Library" with the Library to produce a
|
||||||
|
work containing portions of the Library, and distribute that work
|
||||||
|
under terms of your choice, provided that the terms permit
|
||||||
|
modification of the work for the customer's own use and reverse
|
||||||
|
engineering for debugging such modifications.
|
||||||
|
|
||||||
|
You must give prominent notice with each copy of the work that the
|
||||||
|
Library is used in it and that the Library and its use are covered by
|
||||||
|
this License. You must supply a copy of this License. If the work
|
||||||
|
during execution displays copyright notices, you must include the
|
||||||
|
copyright notice for the Library among them, as well as a reference
|
||||||
|
directing the user to the copy of this License. Also, you must do one
|
||||||
|
of these things:
|
||||||
|
|
||||||
|
a) Accompany the work with the complete corresponding
|
||||||
|
machine-readable source code for the Library including whatever
|
||||||
|
changes were used in the work (which must be distributed under
|
||||||
|
Sections 1 and 2 above); and, if the work is an executable linked
|
||||||
|
with the Library, with the complete machine-readable "work that
|
||||||
|
uses the Library", as object code and/or source code, so that the
|
||||||
|
user can modify the Library and then relink to produce a modified
|
||||||
|
executable containing the modified Library. (It is understood
|
||||||
|
that the user who changes the contents of definitions files in the
|
||||||
|
Library will not necessarily be able to recompile the application
|
||||||
|
to use the modified definitions.)
|
||||||
|
|
||||||
|
b) Use a suitable shared library mechanism for linking with the
|
||||||
|
Library. A suitable mechanism is one that (1) uses at run time a
|
||||||
|
copy of the library already present on the user's computer system,
|
||||||
|
rather than copying library functions into the executable, and (2)
|
||||||
|
will operate properly with a modified version of the library, if
|
||||||
|
the user installs one, as long as the modified version is
|
||||||
|
interface-compatible with the version that the work was made with.
|
||||||
|
|
||||||
|
c) Accompany the work with a written offer, valid for at
|
||||||
|
least three years, to give the same user the materials
|
||||||
|
specified in Subsection 6a, above, for a charge no more
|
||||||
|
than the cost of performing this distribution.
|
||||||
|
|
||||||
|
d) If distribution of the work is made by offering access to copy
|
||||||
|
from a designated place, offer equivalent access to copy the above
|
||||||
|
specified materials from the same place.
|
||||||
|
|
||||||
|
e) Verify that the user has already received a copy of these
|
||||||
|
materials or that you have already sent this user a copy.
|
||||||
|
|
||||||
|
For an executable, the required form of the "work that uses the
|
||||||
|
Library" must include any data and utility programs needed for
|
||||||
|
reproducing the executable from it. However, as a special exception,
|
||||||
|
the materials to be distributed need not include anything that is
|
||||||
|
normally distributed (in either source or binary form) with the major
|
||||||
|
components (compiler, kernel, and so on) of the operating system on
|
||||||
|
which the executable runs, unless that component itself accompanies
|
||||||
|
the executable.
|
||||||
|
|
||||||
|
It may happen that this requirement contradicts the license
|
||||||
|
restrictions of other proprietary libraries that do not normally
|
||||||
|
accompany the operating system. Such a contradiction means you cannot
|
||||||
|
use both them and the Library together in an executable that you
|
||||||
|
distribute.
|
||||||
|
|
||||||
|
7. You may place library facilities that are a work based on the
|
||||||
|
Library side-by-side in a single library together with other library
|
||||||
|
facilities not covered by this License, and distribute such a combined
|
||||||
|
library, provided that the separate distribution of the work based on
|
||||||
|
the Library and of the other library facilities is otherwise
|
||||||
|
permitted, and provided that you do these two things:
|
||||||
|
|
||||||
|
a) Accompany the combined library with a copy of the same work
|
||||||
|
based on the Library, uncombined with any other library
|
||||||
|
facilities. This must be distributed under the terms of the
|
||||||
|
Sections above.
|
||||||
|
|
||||||
|
b) Give prominent notice with the combined library of the fact
|
||||||
|
that part of it is a work based on the Library, and explaining
|
||||||
|
where to find the accompanying uncombined form of the same work.
|
||||||
|
|
||||||
|
8. You may not copy, modify, sublicense, link with, or distribute
|
||||||
|
the Library except as expressly provided under this License. Any
|
||||||
|
attempt otherwise to copy, modify, sublicense, link with, or
|
||||||
|
distribute the Library is void, and will automatically terminate your
|
||||||
|
rights under this License. However, parties who have received copies,
|
||||||
|
or rights, from you under this License will not have their licenses
|
||||||
|
terminated so long as such parties remain in full compliance.
|
||||||
|
|
||||||
|
9. You are not required to accept this License, since you have not
|
||||||
|
signed it. However, nothing else grants you permission to modify or
|
||||||
|
distribute the Library or its derivative works. These actions are
|
||||||
|
prohibited by law if you do not accept this License. Therefore, by
|
||||||
|
modifying or distributing the Library (or any work based on the
|
||||||
|
Library), you indicate your acceptance of this License to do so, and
|
||||||
|
all its terms and conditions for copying, distributing or modifying
|
||||||
|
the Library or works based on it.
|
||||||
|
|
||||||
|
10. Each time you redistribute the Library (or any work based on the
|
||||||
|
Library), the recipient automatically receives a license from the
|
||||||
|
original licensor to copy, distribute, link with or modify the Library
|
||||||
|
subject to these terms and conditions. You may not impose any further
|
||||||
|
restrictions on the recipients' exercise of the rights granted herein.
|
||||||
|
You are not responsible for enforcing compliance by third parties with
|
||||||
|
this License.
|
||||||
|
|
||||||
|
11. If, as a consequence of a court judgment or allegation of patent
|
||||||
|
infringement or for any other reason (not limited to patent issues),
|
||||||
|
conditions are imposed on you (whether by court order, agreement or
|
||||||
|
otherwise) that contradict the conditions of this License, they do not
|
||||||
|
excuse you from the conditions of this License. If you cannot
|
||||||
|
distribute so as to satisfy simultaneously your obligations under this
|
||||||
|
License and any other pertinent obligations, then as a consequence you
|
||||||
|
may not distribute the Library at all. For example, if a patent
|
||||||
|
license would not permit royalty-free redistribution of the Library by
|
||||||
|
all those who receive copies directly or indirectly through you, then
|
||||||
|
the only way you could satisfy both it and this License would be to
|
||||||
|
refrain entirely from distribution of the Library.
|
||||||
|
|
||||||
|
If any portion of this section is held invalid or unenforceable under any
|
||||||
|
particular circumstance, the balance of the section is intended to apply,
|
||||||
|
and the section as a whole is intended to apply in other circumstances.
|
||||||
|
|
||||||
|
It is not the purpose of this section to induce you to infringe any
|
||||||
|
patents or other property right claims or to contest validity of any
|
||||||
|
such claims; this section has the sole purpose of protecting the
|
||||||
|
integrity of the free software distribution system which is
|
||||||
|
implemented by public license practices. Many people have made
|
||||||
|
generous contributions to the wide range of software distributed
|
||||||
|
through that system in reliance on consistent application of that
|
||||||
|
system; it is up to the author/donor to decide if he or she is willing
|
||||||
|
to distribute software through any other system and a licensee cannot
|
||||||
|
impose that choice.
|
||||||
|
|
||||||
|
This section is intended to make thoroughly clear what is believed to
|
||||||
|
be a consequence of the rest of this License.
|
||||||
|
|
||||||
|
12. If the distribution and/or use of the Library is restricted in
|
||||||
|
certain countries either by patents or by copyrighted interfaces, the
|
||||||
|
original copyright holder who places the Library under this License may add
|
||||||
|
an explicit geographical distribution limitation excluding those countries,
|
||||||
|
so that distribution is permitted only in or among countries not thus
|
||||||
|
excluded. In such case, this License incorporates the limitation as if
|
||||||
|
written in the body of this License.
|
||||||
|
|
||||||
|
13. The Free Software Foundation may publish revised and/or new
|
||||||
|
versions of the Lesser General Public License from time to time.
|
||||||
|
Such new versions will be similar in spirit to the present version,
|
||||||
|
but may differ in detail to address new problems or concerns.
|
||||||
|
|
||||||
|
Each version is given a distinguishing version number. If the Library
|
||||||
|
specifies a version number of this License which applies to it and
|
||||||
|
"any later version", you have the option of following the terms and
|
||||||
|
conditions either of that version or of any later version published by
|
||||||
|
the Free Software Foundation. If the Library does not specify a
|
||||||
|
license version number, you may choose any version ever published by
|
||||||
|
the Free Software Foundation.
|
||||||
|
|
||||||
|
14. If you wish to incorporate parts of the Library into other free
|
||||||
|
programs whose distribution conditions are incompatible with these,
|
||||||
|
write to the author to ask for permission. For software which is
|
||||||
|
copyrighted by the Free Software Foundation, write to the Free
|
||||||
|
Software Foundation; we sometimes make exceptions for this. Our
|
||||||
|
decision will be guided by the two goals of preserving the free status
|
||||||
|
of all derivatives of our free software and of promoting the sharing
|
||||||
|
and reuse of software generally.
|
||||||
|
|
||||||
|
NO WARRANTY
|
||||||
|
|
||||||
|
15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
|
||||||
|
WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
|
||||||
|
EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
|
||||||
|
OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
|
||||||
|
KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||||
|
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
|
||||||
|
LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
|
||||||
|
THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||||
|
|
||||||
|
16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
|
||||||
|
WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
|
||||||
|
AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
|
||||||
|
FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
|
||||||
|
CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
|
||||||
|
LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
|
||||||
|
RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
|
||||||
|
FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
|
||||||
|
SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
|
||||||
|
DAMAGES.
|
||||||
|
|
||||||
|
END OF TERMS AND CONDITIONS
|
||||||
|
|
||||||
|
How to Apply These Terms to Your New Libraries
|
||||||
|
|
||||||
|
If you develop a new library, and you want it to be of the greatest
|
||||||
|
possible use to the public, we recommend making it free software that
|
||||||
|
everyone can redistribute and change. You can do so by permitting
|
||||||
|
redistribution under these terms (or, alternatively, under the terms of the
|
||||||
|
ordinary General Public License).
|
||||||
|
|
||||||
|
To apply these terms, attach the following notices to the library. It is
|
||||||
|
safest to attach them to the start of each source file to most effectively
|
||||||
|
convey the exclusion of warranty; and each file should have at least the
|
||||||
|
"copyright" line and a pointer to where the full notice is found.
|
||||||
|
|
||||||
|
<one line to give the library's name and a brief idea of what it does.>
|
||||||
|
Copyright (C) <year> <name of author>
|
||||||
|
|
||||||
|
This library is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU Lesser General Public
|
||||||
|
License as published by the Free Software Foundation; either
|
||||||
|
version 2.1 of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
This library is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
Lesser General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Lesser General Public
|
||||||
|
License along with this library; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
|
||||||
|
USA
|
||||||
|
|
||||||
|
Also add information on how to contact you by electronic and paper mail.
|
||||||
|
|
||||||
|
You should also get your employer (if you work as a programmer) or your
|
||||||
|
school, if any, to sign a "copyright disclaimer" for the library, if
|
||||||
|
necessary. Here is a sample; alter the names:
|
||||||
|
|
||||||
|
Yoyodyne, Inc., hereby disclaims all copyright interest in the
|
||||||
|
library `Frob' (a library for tweaking knobs) written by James Random
|
||||||
|
Hacker.
|
||||||
|
|
||||||
|
<signature of Ty Coon>, 1 April 1990
|
||||||
|
Ty Coon, President of Vice
|
||||||
|
|
||||||
|
That's all there is to it!
|
||||||
2
libraries/Servo/README.md
Normal file
2
libraries/Servo/README.md
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
|
||||||
|
## Servo - это библиотека Servo для Амура (МК от Микрон) в ArduinoIDE
|
||||||
27
libraries/Servo/examples/Broom/Broom.ino
Normal file
27
libraries/Servo/examples/Broom/Broom.ino
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
|
||||||
|
/*
|
||||||
|
"Broom" Servo
|
||||||
|
This example demonstrates the servo drive movement
|
||||||
|
with a smooth stop in both directions
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <Servo.h>
|
||||||
|
|
||||||
|
Servo servo; // create an Servo class instance to control the servo
|
||||||
|
|
||||||
|
int pos = 0; // variable for storing servo position
|
||||||
|
|
||||||
|
void setup() {
|
||||||
|
servo.attach(8); // connecting the servo drive to digital pin 8 (D8)
|
||||||
|
}
|
||||||
|
|
||||||
|
void loop() {
|
||||||
|
for (pos = 0; pos <= 180; pos += 1) { // change degrees from 0 to 180
|
||||||
|
servo.write(pos); // command to servo drive - go to position of variable "pos"
|
||||||
|
delay(15); // waiting for the servo to get there
|
||||||
|
}
|
||||||
|
for (pos = 180; pos >= 0; pos -= 1) { // change degrees from 180 to 0
|
||||||
|
servo.write(pos); // command to servo drive - go to position of variable "pos"
|
||||||
|
delay(15); // waiting for the servo to get there
|
||||||
|
}
|
||||||
|
}
|
||||||
25
libraries/Servo/examples/Jerks/Jerks.ino
Normal file
25
libraries/Servo/examples/Jerks/Jerks.ino
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
|
||||||
|
/*
|
||||||
|
"Jerks"
|
||||||
|
This example demonstrates the servo drive movement
|
||||||
|
with a sharp stop in both directions
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <Servo.h>
|
||||||
|
|
||||||
|
Servo servo; // create an Servo class instance to control the servo
|
||||||
|
|
||||||
|
void setup() {
|
||||||
|
servo.attach(8); // connecting the servo drive to digital pin 8 (D8)
|
||||||
|
}
|
||||||
|
|
||||||
|
void loop() {
|
||||||
|
servo.write(0); // command to the servo drive - go to the 0 degree position (clockwise movement)
|
||||||
|
delay(1000); // wait
|
||||||
|
servo.write(90); // stop movement
|
||||||
|
delay(1000); // wait
|
||||||
|
servo.write(180); // command to the servo drive - move to the 180 degree position (counterclockwise movement)
|
||||||
|
delay(1000); // wait
|
||||||
|
servo.write(90); // stop movement
|
||||||
|
delay(1000); // wait
|
||||||
|
}
|
||||||
24
libraries/Servo/examples/Resist/Resist.ino
Normal file
24
libraries/Servo/examples/Resist/Resist.ino
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
|
||||||
|
/*
|
||||||
|
"Resist"
|
||||||
|
This example demonstrates the servo drive movement
|
||||||
|
depending on the value on the potentiometer
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <Servo.h>
|
||||||
|
|
||||||
|
Servo servo; // create an Servo class instance to control the servo
|
||||||
|
|
||||||
|
int potpin = A0; // analog pin used to connect a potentiometer
|
||||||
|
int val; // variable for reading the analog output value
|
||||||
|
|
||||||
|
void setup() {
|
||||||
|
servo.attach(8); // connecting the servo drive to digital pin 8 (D8)
|
||||||
|
}
|
||||||
|
|
||||||
|
void loop() {
|
||||||
|
val = analogRead(potpin); // reading the potentiometer value (value from 0 to 4096)
|
||||||
|
val = map(val, 0, 4096, 0, 180); // change scale for use with servo (value from 0 to 180)
|
||||||
|
servo.write(val); // setting the servo position according to the value
|
||||||
|
delay(15); // waiting for the servo to get there
|
||||||
|
}
|
||||||
23
libraries/Servo/keywords.txt
Normal file
23
libraries/Servo/keywords.txt
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
#######################################
|
||||||
|
# Syntax Coloring Map Servo
|
||||||
|
#######################################
|
||||||
|
|
||||||
|
#######################################
|
||||||
|
# Datatypes (KEYWORD1)
|
||||||
|
#######################################
|
||||||
|
|
||||||
|
Servo KEYWORD1 Servo
|
||||||
|
|
||||||
|
#######################################
|
||||||
|
# Methods and Functions (KEYWORD2)
|
||||||
|
#######################################
|
||||||
|
attach KEYWORD2
|
||||||
|
detach KEYWORD2
|
||||||
|
write KEYWORD2
|
||||||
|
read KEYWORD2
|
||||||
|
writeMicroseconds KEYWORD2
|
||||||
|
readMicroseconds KEYWORD2
|
||||||
|
|
||||||
|
#######################################
|
||||||
|
# Constants (LITERAL1)
|
||||||
|
#######################################
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user