SportIduino и активный чип. Часть 1. Посетила меня идея…

Как-то практически случайно на сайте известного производителя полупроводниковых компонентов nxp.com наткнулся на страницу с описанием микросхемы  NTAG I2C plus (далее «микросхема»). Заинтересовался ей. Эта маленькая микросхема (в корпусе с 8-ю выводами) содержит пассивную RFID-метку наподобие NTAG 216, только без антенны, и интерфейс для коммуникации с управляющим микроконтроллером (далее «MCU») по шине I2C. При этом пассивная метка способна выполнять свои функции без подачи питающего напряжения на интерфейсную часть, ей достаточно энергии электромагнитного поля от считывателя (базовой станции Sportiduino), как и любой другой пассивной RFID-метки. А вот для нормальной работы интерфейсной части и небольшой статической памяти (SRAM размером 64 байта) уже необходимо подавать внешнее питание на вывод VDD этой микросхемы. На рис.1 я привожу картинку из описания микросхемы со своими комментариями:

Рис.1
Взаимодействие внешнего RFID-считывателя с микросхемой в связке с MCU.

На этом рисунке микросхема показана очень обобщенно в виде 2-х блоков SRAM и EEPROM (Electrically Erasable Programmable Read-Only Memory — электрически стираемое перепрограммируемое ПЗУ, энергонезависимая память) и шины I2C для обмена данными между микросхемой и MCU.

Организация энергонезависимой памяти EEPROM этой микросхемы (я сейчас рассматриваю только вариант микросхемы с 1 килобайтом EEPROM, есть вариант микросхемы и с 2KB EEPROM, но этот объем для электронной отметки я уже считаю избыточным) очень напоминает пассивную метку NTAG 216, которая используется в SportIduino. Немного про структуру памяти меток NTAG можно прочитать здесь, я же отмечу, что EEPROM этих меток имеет страничную организацию. Размер каждой страницы составляет 4 байта, в метке NTAG 216 для пользовательских данных остается доступным 222 страницы, из них 216 страниц можно отвести для хранения в метке отметок на базовых станциях. Каждая отметка занимает ровно одну страницу, в которой 1-й байт содержит номер станции, а следующие 3 байта – младшие 3 байта времени отметки (в формате unixtime). Считыватель с меткой может обмениваться только страницами. Нельзя прочитать или записать на метку отдельный байт, можно только страницу целиком. Процесс чтения одной страницы занимает минимум 2 миллисекунды, записи – минимум 5 миллисекунд. Но прежде чем считыватель начнет чтение/запись страниц метки, он должен сначала выбрать метку, так как есть вероятность, что в зоне действия электромагнитного поля считывателя может находиться сразу несколько меток.

Опишу упрощенно алгоритм отметки меткой NTAG в базовой станции SprotIduino (далее «Станция»):

  1. Станция периодически (каждые 250 миллисекунд) включает свой RFID-считыватель, в результате чего станцией создается электромагнитное поле на частоте 13.56 мегагерц. Это не просто радиоизлучение, оно еще содержит модулированные цифровые данные, которыми могут обмениваться RFID-считыватель и находящиеся рядом метки (их может быть сразу несколько). Сначала станция посылает запрос всем меткам (типа, «эй, кто тут есть, отзовитесь»), на этот запрос должна ответить только одна метка (энергию для своей работы метки берут из электромагнитного поля, созданного считывателем), остальные метки больше не отвечают до следующего такого запроса. Если на запрос не отозвалась ни одна метка, то станция «засыпает» на 250 миллисекунд, чтобы затем начать этот шаг сначала;
  2. Если метка отозвалась, то станция начинает с ней сеанс отметки;
  3. Считывается страница номер 4 метки (напомню, что организация памяти метки для SportIduino описана здесь), в которой хранится номер чипа (первые 2 байта), тип метки (3-й байт) и байт с номером версии программного обеспечения SportIduino. Здесь нам интересен номер чипа и тип чипа. Для метки NTAG 216 тип чипа определен как 6 (0x06H);
  4. Далее станция начинает поиск свободной страницы в памяти метки для записи в нее текущей отметки. Задача – найти в памяти страницу с последней отметкой. Напомню, что SportIduino для меток NTAG 216 отводит 216 страниц для записи в них отметок на базовых станциях (КП), начиная с 9-й страницы. Для отметки стартовой станции выделена фиксированная страница номер 8. Свободная страница ищется методом «половинного деления». Текущий диапазон (изначально это 216 страниц) делится пополам. То есть, сначала считывается страница с условным номером 108, полученным как 216/2 (на самом деле будет считана страница с номером 116, так как первые 8 страниц метки не используются для записи отметки). Если считанная страница пустая (содержимое всех байтов нулевое), то следующим шагом считывается страница из середины «левого» поддиапазона 1 – 108 (до страницы 108), то есть страница с условным номером 54 (а если бы страница с условным номером 108 была бы непустая, тогда следующим шагом считывалась бы страница из середины «правого» поддиапазона 108-216). И так далее, пока не будет найден условный номер страницы с последней отметкой (или ноль, если в метке не найдено ни одной отметки). Для метки NTAG 216 для записи в нее первой отметки сначала будет сделано 8 считываний! Это страницы с условными номерами 108, 54, 27, 14, 7, 4, 2, 1. Потом, по мере заполнения памяти метки отметками, количество считываний будет постепенно уменьшаться (до заполнения половины памяти метки), а затем снова начнет увеличиваться.
  5. К условному номеру найденной страницы с последней отметкой прибавляется единица (это будет условный номер первой свободной отметки), и, если результат не превышает максимальное возможное количество отметок, то станция записывает в страницу с первой свободной отметкой следующие данные: номер станции (первый байт) и младшие 3 байта времени отметки (в формате unixtime). После чего станция подает световой и звуковой сигнал, подтверждающий сделанную отметку, и «засыпает» на 250мс. Далее все начинается по новой (с шага 1).

Получается, что время записи первых отметок в память метки NTAG 216 будет состоять из больших десятков (возможно, и сотен) миллисекунд. И при этом в случае одновременного поднесения к станции нескольких меток непонятно, в какую именно метку станция сделала запись. Метки то ведь пассивные…

Это было длинное (лирическое) отступление. Теперь я возвращаюсь к микросхеме. Её прелесть (на мой взгляд) заключается в наличии у нее SRAM, способной работать в одном из двух следующих режимов:

  • SRAM buffer mirroring – зеркальное отображение SRAM на страницы EEPROM. В регистрах микросхемы можно указать стартовый номер страницы памяти EEPROM микросхемы, начиная с которого при обращении RFID-считывателя к этой (и последующим 15 страницам EEPROM) на самом деле будет происходить обращение к ячейкам SRAM. Это относится как к операциям чтения таких страниц, так и к операциям записи. Обращаться к содержимому SRAM может также и MCU, подключенный к микросхеме по шине I2C. В этом случае в микросхеме реализован арбитраж памяти, который «разруливает» (не допускает) одновременные обращения к памяти (EEPROM и SRAM) со стороны MCU и RFID-считывателя. Если RFID-считыватель выполнил операцию записи в такую страницу, то, во-первых, ее содержимое из SRAM может прочитать MCU (как впрочем и записать в SRAM), а во-вторых (зеркалируемая) страница EEPROM при этом не перезаписывается;
  • Pass-through mode – это особый режим передачи данных (между микросхемой и RFID-считывателем), при котором ячейки SRAM для rfid-считывателя выглядят как дополнительные 16 страниц памяти EEPROM микросхемы с номерами 240-255. В этом режиме задается направление передачи (от rfid-считывателя к MCU или наоборот), при этом микросхема автоматически переключает направление передачи в случае записи в последнюю страницу 255 со стороны rfid-считывателя (если задано направление передачи «от rfid-считывателя к MCU») или записи со стороны MCU в последние 4 байта памяти со стороны MCU по шине I2C (если задано направление передачи «от MCU к rfid-считывателю»). При этом не важно, с какой страницы была начата запись в область SRAM. Таким образом, можно организовать обмен информацией (через SRAM) между rfid-считывателем и MCU порциями от 4 (если использовать только страницу 255) до 64 байт (если использовать все страницы SRAM 240-255). Более подробно про такой обмен почитать можно здесь. Надо отметить, что у микросхемы есть особый вывод «FD» (Field detection), который можно запрограммировать на разные варианты. Например, активизировать этот вывод в случае, когда микросхема обнаружила внешнее электромагнитное поле или в случае, когда микросхема обнаружила окончание записи в страницу 255. И далее активный сигнал на выводе «FD» может обрабатываться MCU как внешнее прерывание.

А теперь вернусь к самому началу — заголовку «SportIduino и активный чип». Чтобы для SportIduino добавить возможность использования активной метки. Со своим автономным питанием, MCU и светодиодом, сигнализирующим, что отметка произведена именно в этот чип. Для этого на маленькой плате необходимо разместить микросхему (8 ножек, работает до напряжения 1.8 вольта питания на VDD) плюс MCU (например, микроконтроллер STM32L011D4P6 в корпусе с 14-ю ножками и также работает до 1.8V), литиевую батарейку на 2.5-3V, светодиод и антенну. Почему именно STM32L011D4P6, а не, например, ATTiny45V? Да потому, что этот микроконтроллер заточен под ультранизкое энергопотребление и имеет (при той же цене) характеристики куда лучше. Например, объем оперативной памяти 2 килобайта в STM32 серии L против 128 байт ATTiny45V. И так во всем. А самое главное, что ATTiny45V может пробуждаться только по сигналу с одного вывода и этот же вывод задействован для шины I2C, а STM32 пробуждается по сигналу с любого вывода. Вот набросал «на коленке» прототип схемы активного чипа (см.рис.2):

Рис.2
Прототип схемы активного чипа (ver.2 от 21.09.2020)

Идея следующая: микросхема конфигурируется (прошивкой в MCU) на режим работы «Pass-through mode», при этом на странице 4 памяти EEPROM микросхемы в 3-м байте указывается особый тип чипа. Например, 7 – активный чип. Необходимо еще модифицировать прошивку базовой станции SportIduino, чтобы (после установления сеанса между rfid-считывателем и микросхемой) станция определяла, что это активный чип (по типу чипу из 4-й страницы памяти EEPROM микросхемы), и тогда далее она (вместо поиска методом «половинного деления» первой свободной страницы в памяти EEPROM микросхемы) должна произвести считывание страницы 255 микросхемы. Если считывание страницы завершилось ошибкой – значит, скорее всего батарейка активного чипа уже «сдохла» и тогда поиск первой свободной страницы делается стандартным алгоритмом (методом «половинного деления»). А если считывание прошло успешно – значит, чип в активном режиме и тогда эта страница (как вариант) может содержать информацию о последней сделанной в микросхеме отметке – в 1-м байте содержится номер станции, а в последующих 3-х байтах – последние 3 байта времени последней отметки (в формате unixtime). Если все байты этой страницы равны 0 – значит, в микросхеме еще нет ни одной отметки. А если номер станции равен 255 – значит, все страницы микросхемы уже заполнены и записать текущую отметку некуда (в этом случае станция издает особый сигнал ошибки). В любом случае станция в ответ должна записать в страницу 255 активного чипа ответную информацию – уже о текущей отметке, где 1-й байт должен содержать номер станции, а следующие 3 байта — последние 3 байта времени текущей отметки (в формате unixtime). Эта запись вызовет формирование микросхемой сигнала на выводе «FD» для MCU активного чипа, который должен прочитать (по шине I2C) содержимое этой страницы и поместить эту информацию в нужную страницу памяти EEPROM микросхемы. И затем сформировать сигнал на светодиоде (активного чипа), подтверждающий запись отметки в активный чип. То есть, задача поиска свободной страницы в памяти микросхемы выполняется силами MCU активного чипа, а не станцией. Станция по сути выполняет только чтение страницы 4 (с номером чипа и типом чипа) и затем страницы 255 (с данными о последней отметке чипа). После чего станция выполняет запись в страницу 255 активного чипа (которая длится всего 0.8мс вместо 4.8мс в случае записи в EEPROM) и, если запись завершена успешно (операция записи страницы 255 получила подтверждение ACK), то на этом все! Сеанс беспроводного обмена данными между станцией и микросхемой на этом закончен. Далее станция (действуя по стандартному алгортиму) запишет в свою память EEPROM факт отметки на станции чипа (по номеру чипа), а MCU активного чипа переписывает содержимое страницы номер 255 микросхемы в первую свободную страницу памяти EEPROM микросхемы. Если в памяти микросхемы больше нет свободных страниц, то MCU должен записать в 1-й байт страницы 255 микросхемы (где хранится номер станции) число 255 – признак того, что в микросхеме больше нет свободных страниц. Все остальное время MCU может находиться в режиме «глубокого сна», когда отключены почти все блоки MCU (периферия, арифметико-логическое устройство и т.п.). Пробуждаться MCU будет по сигналу с вывода «FD» (или с выхода Vout — тогда MCU может уходить в режим «Standby»). Когда MCU находится в «отключке» (в режиме «Stop» или «Standby»), ток потребления составляет менее 1-го микроампера (при температуре до 25°C).

Возможно также задействовать MCU активного чипа при очистке чипа, когда стирать страницы памяти для отметки будет не станция очистки, а MCU. Например, при записи rfid-считывателем в страницу 255 активного чипа отметки с номером станции 249 и 3-мя нулевыми байтами. Такой номер в SportIduino имеет станция очистки (другие особые номера станций: 240 – стартовая, 245 – финишная, 248 — проверки). Это будет для MCU командой очистить EEPROM микросхемы и очистка силами MCU будет выполнена быстрее и еще позволит сэкономить батарейки станции очистки. Возможно (учитывая длительность операции очистки и энергию батарейки активного чипа, затраченную на очистку 216-ти страниц памяти EEPROM микросхемы) надо будет добавить в прошивку станции SportIduino еще и ожидание от активного чипа подтверждения успешного завершения очистки. Например, записью MCU активного чипа в страницу 255 в 1-й байт значения 249 (номер станции очистки) и особыми ненулевыми байтами в последующих 3-х байтах. И выдавать (световой и звуковой) сигнал станция очистки будет только после получения этого подтверждения (при этом активный чип также должен просигнализировать успешную очистку своим светодиодом). Если же от активного чипа не получено успешное подтверждение очистки (например, разрядилась батарейка), то станция переходит к стандартному алгоритму очистки (пассивного) чипа.

Учитывая, что MCU STM32L011D4P6 содержит аналогово-цифровой преобразователь (далее «АЦП»), то этот АЦП можно использовать для контроля напряжения батарейки активного чипа. Для этого АЦП необходимо сконфигурировать на разрешение в 10 бит, на вход АЦП подать напряжения с источника опорного напряжения 1.2V, встроенного в STM32L011D4P6. Поскольку АЦП получает питание от батарейки, то полученный на выходе АЦП результат преобразования будет обратно пропорционален напряжению батарейки. Вот формула:

 VALUEацп = (1200 / Vbat) * 1023 , где:

VALUEацп – результат преобразования на выходе АЦП (целое число от 0 до 1023);
1200 – опорное напряжение 1.2 вольта (в милливольтах), подаваемое на вход АЦП;
Vbat – измеряемое напряжение батарейки, в милливольтах;
1023 – максимально возможное значение на выходе 10-ти битного АЦП.

Из нее можно легко получить напряжение батарейки Vbat в милливольтах (вычисление в милливольтах позволяет оставаться в рамках целочисленной арифметики и не связываться с арифметикой с плавающей точкой):

Vbat = (1200 / VALUEацп) * 1023 = 1227600 / VALUEацп

Таким образом можно контролировать напряжение батарейки активного чипа (на стадии очистки чипа и можно еще на стадии проверки) и формировать положительный результат (окончания операции очистки или проверки) только в случае, когда измеренное напряжение батарейки будет выше определенного минимального порога (например, выше 2000 милливольт). И также можно запоминать измеренное напряжение в оперативной памяти MCU (даже можно запоминать в особых регистрах RTC Backup и переводить MCU в режим «Standby», при котором оперативная память отключается), чтобы затем программно отключать функции активного чипа, если напряжение батарейки ниже минимального порога, но при этом MCU активного чипа продолжает нормально работать (по заложенной в него программе). Потому что это уже рискованно —  в любой момент нормальная работа может прекратиться. Трагедии в этом случае не произойдет – просто активный чип перестанет быть активным и станет по сути пассивной меткой NTAG 216.

По логике проверку напряжения батарейки активного чипа необходимо делать еще до старта, например, на станции проверки. Для этого также надо будет модернизировать прошивку станции SportIduino. Например, станция проверки записывает в страницу 255 активного чипа 4 байта: 1-й байт — номер станции 248 (этот номер зарезервирован для станции проверки) и затем 3 нулевых байта. Если запись страницы прошла успешно, то станция ждет, чтобы прочитать страницу 255. MCU активного чипа, прочитав байты этой страницы, выполняет стандартный алгоритм проверки чипа (проверяет, чтобы все 216 страниц памяти EEPROM микросхемы, отведенные для отметки, были очищены) и также измеряет напряжение батарейки. Если все страницы очищены и напряжение батарейки превышает минимально допустимое (например, 2V), то MCU записывает в страницу 255 микросхемы в байты 2-4 ненулевые данные (например, измеренное напряжение батарейки в милливольтах), которые затем должна прочитать станция проверки и подать сигнал, что проверка успешно пройдена (и активный чип также должен просигнализировать своим светодиодом).

Если же MCU обнаружил пониженное напряжение батарейки или неочищенные страницы отметки в памяти EEPROM микросхемы, то содержимое страницы 255 микросхемы MCU не меняет и активный чип ничего не сигнализирует. Станция проверки, прочитав страницу 255 и обнаружив там, что байты 2-4 остались нулевыми, понимает, что проверка (силами MCU активного чипа) не пройдена и тогда проводит процедуру проверки стандартным алгоритмом (как для пассивного чипа). Это позволит использовать активный чип и при разряженной батарейке, но только уже как обычный (пассивный) чип.

Вот такая идея посетила мою (больную) голову. Вот какие цены сейчас в магазине ЧипДип:

Цены в этом магазине не самые низкие, особенно когда заказывается малое количество, но я их привел для грубой прикидки. Плата и корпус активного чипа – это надо считать отдельно. Но грубо при заказе от 100 штук стоимость комплектующих для одного активного чипа будет в районе 350-400 рублей.

Вот наступит зима и появится у меня гораздо больше свободного времени – тогда пожалуй сделаю несколько прототипов активного чипа…