Эмулятор карт EM Marine
Наверняка каждому из нас, кто хоть раз бывал в обычных офисах, было интересно, как же функционируют эти бесконтактные пропуска. В данной статье мы разберёмся с принципом работы бесконтактных карт и сделаем эмулятор буквально из трёх радиодеталей.
Технология RFID
Внешний вид RFID-меток
RFID (англ. Radio Frequency IDentification, радиочастотная идентификация) — имеет достаточно широкий частотный диапазон и достаточно большое количество различных стандартов, которые так или иначе применимы к данной технологии. Для справки: используются частоты: 125-135кГц, 400 кГц, 6.78МГц, 13.56МГц (карты метро и банковские карты), 27.125МГц, 40.68 МГц, 433.29 МГц, 869 МГц, 915 МГц, 2.45 ГГц, 5.8 ГГц и 24.125ГГц. Как видно частотный диапазон очень широкий.
Мы же будем говорить о самых распространённых и наименее защищённых картах частотного диапазона 125 кГц. Я разберу стандарт EM Marine 4102, так как именно с ним лучше всего знаком. Однако код эмулятора позволяет работать и с другими стандартами, работающими на частоте 125 кГц.
Чтобы мы могли дальше углубиться в теорию, следует рассказать пару слов о принципе работы RFID. Далее в тексте будет приводиться информация, относящаяся к стандарту 125 кГц EM Marine, прочие RFID решения устроены подобным образом.
Считыватель, кроме информационного обмена осуществляет подачу питания. Метка из себя представляет ПЗУ, которое питается от электромагнитного поля, и после подачи питания просто отдаёт записанную информацию.
Из этой схемы хорошо видно, как устроен передатчик и приёмник. Оба колебательных контура настроены в резонанс и используются для передачи данных и передачи энергии, для питания пассивной метки, в роли которой выступает наша карта.
Более детально о принципе работы можно прочитать в [1]
Внутренности разобранной карты
Если разобрать карту, то можно увидеть антенну в виде катушки и чип залитый компаундом, в котором находится ПЗУ и конденсатор ёмкостью 75 пФ.
Описание протокола EM4102
Прежде, чем мы пойдём дальше, давайте разберёмся со стандартом EM4102, который мы будем эмулировать. EM4102 совместимая RFID-метка содержит 64 бита памяти только для чтения. По сути — это и есть ПЗУ, то есть информация может быть считана из неё, но не может быть изменена либо записана, проще говоря этот чип единожды прошивается на заводе. Структуру памяти метки можно посмотреть на рисунке ниже.
Когда метка попадает в электромагнитное поле, излучаемое считывателем RFID, она получает энергию от поля (питание) и начинает передачу данных. Первые 9 битов – это логическая единица. Эти биты используются как последовательность маркеров для обозначения начала передачи. Поскольку во всех остальных данных используется контроль чётности, эта девятибитная последовательность единиц больше не встретится ни в каком другом месте. Далее идут 10 групп по 4 бита данных и 1 бит чётности на каждую группу. Наконец, есть 4 бита контрольной суммы и последний стоповый бит, который всегда равен нулю.
Метка повторяет цикл передачи данных, пока на неё приходит питание. Поэтому мы на ридере наблюдаем постоянное считывание метки.
Приведу пример данных, которые передаёт метка с номером: 0x06 — номер версии, и 0x001259E3 — данные.
Кстати, номер, напечатанный на карте можно перевести в hex-номер, который получит считыватель. Например, на карте записан номер: 116,23152
- 116 в десятичной системе счисления – это 0x74 в шестадцатиричной;
- 23152 в десятичной – это 0x5A70 в шестнадцатиричной;
Комбинируя их, мы получаем серийный номер карты, который нам даст считыватель: 0x00745A70.
Модуляция сигнала
Передача данных от метки до считывателя осуществляется с помощью модуляции несущего сигнала считывателя (в нашем случае несущей частоты 125 кГц). Обратите внимание, что от этой несущей частоты идёт и питание и ей же осуществляется модуляция сигнала. Для начала рассмотрим упрощённую схему взаимодействия считывателя и метки. Запомните эту картинку, мы ещё будем к ней обращаться.
Как видно у метки есть колебательный контур LC, диод, служащий для выпрямления переменного тока, конденсатор для сглаживания пульсаций (это часть питания метки), и транзистор, управляя которым мы можем модулировать сигнал. На считывателе это будет отражаться в изменении тока протекающего в катушке. Проще говоря, при попадании в поле считывателя, метка потребляет электрический ток (примерно постоянно), при передаче информации она транзистором изменяет значение потребляемого тока и таким образом считыватель может получить сигнал, измеряя потребляемую мощность.
Считыватель генерирует магнитное поле, с помощью модулятора и катушки и снимает промодулированный сигнал, затем декодирует его.
Пример модуляции несущего сигнала
Если я вас окончательно не запутал, то едем дальше. Для того чтобы передать данные, нам необходимо модулировать сигнал. То есть на несущую частоту наложит биты передаваемой информации.
По стандарту RFID есть три популярных схемы модуляции:
- Манчестер код
- Двухфазный манчестер код
- Кодирование фазовым сдвигом
Поскольку в стандарте EM4102 используется схема Манчестерского кодирования, то её и рассмотрим. При модуляции для EM4102 протокола время передачи одного бита может составлять 64, 32 или 16 периодов несущей частоты (125 кГц).
При таком кодировании метка изменяет уровень передачи сигнала строго в середине периода передачи одного бита. Переход от низкого к высокому уровню в эти моменты означает состояние логической «1», а переход от высокого уровня к низкому, представляет состояние логического «0».
Реальный промодулированный сигнал, снятый на катушке считывателя.
Делаем RFID-эмулятор
Ну что же, если вы ещё здесь и голова не опухла, от таких выкладок, то пришла пора делать RFID-эмулятор, всего из двух деталей. В этой простоте кроется гениальность. Устройство я собрал, позаимствовав идею и код у Micah Dowty, фотографии мои.
Вот такой миниатюрный таракан, вполне может эмулировать метку
Сайт проекта . Код очень интересен, можно сказать гениален и лаконичен (используется ассемблер). Остановимся на нём подробно. Его мы и разберём. Ознакомиться с кодом можно вот тут.
Для начала разберёмся, как же эта штука вообще функционирует, хотя по определению работать не должна, так как противоречит привычной схеме подключения микроконтроллера. Схема устройства взята из исходного кода.
Катушка индуктивности около 1 мкГн и микроконтроллер ATtiny85
Вот это дамы и господа и есть настоящее Хакерство, когда уровень понимания особенностей работы оборудования позволяет создавать технические решения, выходящие за рамки, обозначенные производителем! И это работает, проверено лично. Вот истинное значение слова «хакер», это не про взлом и воровство.
Забегая вперёд скажу, что данной катушки для нормальной работы недостаточно, и всё же пришлось cделать нормальную антенну, повесить конденсаторы по питанию, резонансный конденсатор. Но вот для демонстрации принципов работы вполне подойдёт.
Как же это работает:
Прежде чем мы пойдём разбирать код данного эмулятора давайте сделаем ему нормальную антенну. Мои эксперименты с текущей схемотехникой выявили крайнюю нестабильность её работы. Она работает только совсем рядом со считывателем и то не всегда. Поэтому сначала я припаял конденсатор 0,1 мкФ на ножки питания контроллера, а потом решил сделать настоящий большой колебательный контур, как в настоящей метке.
- Катушка фактически питает микроконтроллер AVR через контакты ввода/вывода. Каждый такой контроллер имеет диоды на портах ввода/вывода, которые предотвращает повышение напряжения на этом выводе выше напряжения питания микросхемы или опускание уровня сигнала ниже уровня земли. Они используются так же для предотвращения статического пробоя, который приводит к выходу из строя микросхемы. При поднесении катушки к считывателю, в ней наводится ЭДС равная нескольким вольтам. Когда напряжение на катушке превышает напряжение питания контроллера, то часть этой энергии через эти ограничивающие диоды передаются к шине питания микросхемы. В результате получается, что микроконтроллер получает питание. А верх и низ синусоидальной волны усекается, и сигнал становится более похож на прямоугольный меандр.
- Фильтрация питания с использованием ёмкости кристалла AVR. Обычно, когда ставят микросхему, то ставят конденсаторы по питанию, для фильтрации помех (обычно 0,1 мкФ керамику и электролит параллельно). В данном решении фильтрация осуществляется только внутренней ёмкостью шин питания в кремниевом кристалле микроконтроллера AVR. Она небольшая, но даже её достаточно для стабильного питания и работы, при питании от импульсов с частотой 125кГц!
- Работа осуществляется при очень низком напряжении. Микроконтроллер ATtiny85 предназначен для работы при напряжении всего 2,5 В. Существует версия с расширенным диапазоном напряжений до 1,8 В. При этих напряжениях обычные тактовые генераторы AVR не работают, но этого можно избежать применив следующий хак...
- Катушка индуктивности применяется не только для питания микросхемы, но ещё и для тактирования микроконтроллера! Выше мы говорили, что получаем прямоугольную волну, которая остаётся после того как ограничивающие диоды забрали немного энергии. Эта форма волны является входом Clock нашего микроконтроллера! И весь код работает на частоте 125 кГц, синхронно с несущей частотой считывателя RFID. Это гениально, ребята!
- Прошивка? На таких низких скоростях микропрограммное обеспечение микросхемы больше похоже на последовательность операций ввода-вывода, выполняемых синхронно с каждым тактовым циклом несущей. Но остается много лишних циклов. В протоколе EM4102 вы потенциально можете выполнить некоторую полезную работу с 32 тактовыми циклами между каждым битом. Однако с протоколом HID вам необходимо выводить фронт FSK каждые 4 тактовых цикла. В результате прошивка на RFID-метке крайне тупая. «Исходный код» на самом деле представляет собой просто набор причудливых макросов ассемблера, которые преобразуют код метки RFID в длинную последовательность инструкций ввода-вывода.
Первая модификация — конденсатор 0,1 мкФ по питанию
Создание антенны
Никаких хитростей в создании катушечной антенны нет, но всё же необходимо ознакомиться с документацией и понимать физику процесса… Это не сложно, и справится даже школьник, требуется только немного терпения и усидчивости.
Собрать и настроить антенну очень просто, прямо как в картинке из [1].
Для расчёта антенны надо вспомнить немного теории. Нам необходимо сделать колебательный контур, который будет настроен на частоту 125 кГц. Откроем курс Теоретических Основ Электротехники и прочитаем, что же такое колебательный контур:
Колебательный контур, электрическая цепь, содержащая катушку индуктивности и конденсатор, в которой могут возбуждаться электрические колебания.
Параллельный колебательный контур
Если оставить всю математику и перейти к сути, у колебательного контура есть такой параметр, как резонансная частота, которая определяется по формуле.
Где f — частота колебаний, L — индуктивность катушки, C — ёмкость конденсатора.
В данном случае у нас есть фиксированный параметр — частота, а с ёмкостью и индуктивностью мы можем играться. Для того чтобы рассчитать катушку, воспользуемся документом [2]. Все кто хоть как-то собираются делать антенны для RFID меток (любых частот), обязаны с ним ознакомиться!
Многие умельцы, как для ридеров, так и для эмуляторов (суть не важна) делают круглые катушки. Их проще считать и изготавливать, но они имеют существенный недостаток — их линейные размеры больше карточки. Я хочу изготовить катушку индуктивности в форме прямоугольника, с линейными размерами меньше размеров стандартной карты и, чтобы результирующее устройство было размером со стандартную карту RFID. В результате выбираю размер будущей катушки индуктивности практически такой же, как стоит в настоящей метке, то есть примерно 70х40 мм. Если конденсатор выбрать 10 нФ, то индуктивность катушки (из формулы выше), должна составлять у нас 162 мкГн. Теперь смотрим в документацию по расчёту прямоугольной катушки. Для намотки катушки выбрал провод сечением 0,2 мм. В результате открываем соответствующий раздел документации, и нашему взору представляется следующая славная формула.
Как видим параметры толщины и ширины катушки у нас неизвестные и изменяемые (упираются в толщину провода 0,2 мм), но общие прикидки мне дали цифру в 42 витка. Можно было бы сделать несколько итераций, и сделать прям точный-точный расчёт, но в нашем штучном случае, и так сойдёт.
После чего, необходимо изготовить каркас 70х40 мм для намотки катушки. Его я изготовил из текстолита и на него намотал катушку.
Каркас из текстолита
Намотка и готовая катушка
К сожалению, измерителя индуктивности у меня нет, поэтому пришлось действовать далее методом научного тыка. Поскольку я наверняка ошибся в расчётах, и в количестве витков, когда наматывал катушку, так как делал их приблизительно и на глаз, то я решил подобрать резонансную ёмкость вручную. Для этого закрепил катушку на картридере, воткнул её концы в макетную плату (“матрац с дырками”), затем начал поочерёдно подключать ёмкости, при этом регистрируя сигнал на осциллографе.
Начнём подбор резонансного конденсатора
Сначала я проверил конденсатор емкостью 10 нФ, который должен быть резонансным. Но амплитуда сигнала сразу просела, по сравнению с пустой катушкой. Тогда я взял конденсатор меньшего номинала. И так перебирал конденсаторы, пока не поймал резонанс. Таким образом резонансная ёмкость конденсатора составила 3,2 нФ.
Сигнал без конденсатора, пустая катушка
Сигнал 10 нФ
1 нФ, 2 нФ
3 нФ, 4 нФ, 2,2 нФ
3,2 нФ
Видно, что пробовал разные варианты, и было ясно что максимум лежит где-то между 3 и 4 нФ и результатом стал конденсатор 3,2 нФ (состоящий из двух конденсаторов в параллели). Всё, наша катушка готова к дальнейшим опытам.
Вообще, хочу заметить, что катушку можно сделать вообще в виде дорожек на печатной плате, и при небольшой серии изделий так и стоит делать. Вот, пример такой платы, именно на 125 кГц от Alexander Guthmann. К сожалению, сайт практически умер, а автор давно не выходит на связь, так что довольствуемся только моими фото. Если кто поможет его найти, буду признателен! Не знаю что с ним случилось.
Таким образом, делать эмулятор сразу в виде печатной платы — нет никаких проблем. Думаю имея руководство [2], сможете рассчитать такое самостоятельно, раз это смог сделать четырнадцатилетний немецкий школьник.
Пробежимся по коду
Давайте кратенько пробежимся по коду, который можно посмотреть вот тут. Там пример эмуляции двух типов карт, я разберу только EM4102.
Перво-наперво, как гласит код, нам при прошивке микроконтроллера надо прошить fuse-биты в значение lfuse to 0xC0: таким образом, чтобы контроллер тактировался от внешнего генератора. Обращаю внимание, что любая перепрошивка контроллера будет сопряжена с тем, что его надо будет тактировать от внешнего источника, так как мы устанавливаем fuse биты с генерацией от внешнего генератора!
Весь код основан на макросах. Напомню, что такое макросы — это программа, которая подготавливает код к компиляции. Наша программа состоит всего из нескольких ассемблеровских инструкций: rjmp, call (2 такта), nop, ldi, out и ret (все по 1 такту)! Всё, весь остальной код формируется макросами в зависимости от макроса серийного номера (дефайна). Особенность работы в том, что у нас достаточно мало тактов для нормальной работы. Попробуй успей за 32 такта сделать что-то, учитывая что инструкции перехода в контроллере AVR занимают 2 такта. Поэтому весь код генерируют макросы в зависимости от ID-карты.
#define FORMAT_IS_EM4102
#define EM4102_MFR_ID 0x12
#define EM4102_UNIQUE_ID 0x3456789A
Дефайнами задаём какой тип карты мы эмулируем и задаём ID-карты. Это главный макрос, на основании которого и формируется остальной код. И, тадам, его величество макросы.
.macro delay cycles
.if \cycles > 1
rjmp .+0
delay (\cycles - 2)
.elseif \cycles > 0
nop
delay (\cycles - 1)
.endif
.endm
Макрос задержки, принимает на вход количество тактов задержки. Достаточно очевидный рекурсивный макрос, осуществляет задержку с помощью команды nop (нет операции, 1 такт) и команды rjmp .+0 (перейти на следующую строку, 2 такта). Комбинируя эти команды между собой, можно сделать задержку нужной длинны в тактах. По сути код ничего не делает, только тратит машинное время.
Если вы ещё соображаете, то дальше я вам совсем изнасилую мозг, но код так гениален что вам придётся потерпеть.
Рекурсивный макрос кодирования манчестер-кодом.
.macro manchester bit, count=1
.if \count
manchester (\bit >> 1), (\count - 1)
.if \bit & 1
baseband_1
baseband_0
.else
baseband_0
baseband_1
.endif
.endif
.endm
.macro stop_bit
baseband_0
baseband_1_last
.endm
Собственно тут и осуществляется вся логика. Принимает на вход битовую маску и счётчик битов. Если счётчик не нуль, то вызываем ещё раз сами себя, декрементируя счётчик (рекурсивный макрос, ага). Далее в самом теле идут вызовы макросов baseband_0, baseband_1 и baseband_1_last. В зависимости от того, какой бит у нас “1” или “0”, мы модулируем сигнал манчестер кода с нуля на единицу или с единицы на нуль.
Помните выше я приводил таблицу в статье, как идёт кодирование содержимого карты, где идут биты чётности, и стоп биты в конце. Так вот, наша задача теперь ID-метки закодировать этим методом, для этого у нас существуют два макроса.
#define ROW_PARITY(n) ( (((n) & 0xF) << 1) | (((n) ^ ((n) >> 1) ^ ((n) >> 2) ^ ((n) >> 3)) & 1) )
#define COLUMN_PARITY ( (EM4102_MFR_ID >> 4) ^ (EM4102_MFR_ID) ^ (EM4102_UNIQUE_ID >> 28) ^ (EM4102_UNIQUE_ID >> 24) ^ (EM4102_UNIQUE_ID >> 20) ^ (EM4102_UNIQUE_ID >> 16) ^ (EM4102_UNIQUE_ID >> 12) ^ (EM4102_UNIQUE_ID >> 8) ^ (EM4102_UNIQUE_ID >> 4) ^ (EM4102_UNIQUE_ID) )
ROW_PARITY — расчёт бита чётности в строке из четырёх бит, COLUMN_PARITY — расчёт контрольной суммы всей посылки.
Вся логика работы у нас описывается в макросе в .main
header
manchester ROW_PARITY(EM4102_MFR_ID >> 4), 5
manchester ROW_PARITY(EM4102_MFR_ID >> 0), 5
manchester ROW_PARITY(EM4102_UNIQUE_ID >> 28), 5
manchester ROW_PARITY(EM4102_UNIQUE_ID >> 24), 5
manchester ROW_PARITY(EM4102_UNIQUE_ID >> 20), 5
manchester ROW_PARITY(EM4102_UNIQUE_ID >> 16), 5
manchester ROW_PARITY(EM4102_UNIQUE_ID >> 12), 5
manchester ROW_PARITY(EM4102_UNIQUE_ID >> 8), 5
manchester ROW_PARITY(EM4102_UNIQUE_ID >> 4), 5
manchester ROW_PARITY(EM4102_UNIQUE_ID >> 0), 5
manchester COLUMN_PARITY, 4
stop_bit
Ну то есть, так же точно передаём заголовочные 9 бит, потом манчестер кодинг, высчитывая бит чётности для каждых 4-х бит, в конце контрольная сумма и стоп бит.
Осталось разобраться, что же такое baseband. Для этого у нас служат ещё одни макросы обёртки (да сколько можно-то, а?).
.macro baseband_0
rcall baseband30_0
rjmp .+0
.endm
.macro baseband_1
rcall baseband30_1
rjmp .+0
.endm
.macro baseband_1_last
rcall baseband30_1
rjmp main
.endm
.macro header
manchester 0x1FF, 9
.endm
Макросы baseband* — выполняют ассемблеровский код: вызывают соответствующие функции, и потом делают переход на другую команду. Макрос baseband_1_last — аналогична макросу baseband_1, кроме того что делает безусловный переход не на команду ниже, а в начало функции main. Макрос header — служит для вывода заголовка из девяти однотипных бит равных единице, и вызывает макрос манчестера с передачей числа и количества передаваемых бит.
Последнее, что осталось разобрать — это функции baseband30_0 и baseband30_1. Они описываются следующим кодом.
baseband30_0:
ldi r16, OUT_PINS // 1
rjmp baseband30 // 2
/*
* Emit a 1 at the baseband layer.
* Takes a total of 30 clock cycles, including call overhead.
*/
baseband30_1:
ldi r16, 0 // 1
rjmp baseband30 // 2
/*
* Internal routine for baseband32_0 and _1. Must use
* a total of 24 clock cycles. (32 - 1 ldi - 2 rjmp - 3 rcall)
*/
baseband30:
out _SFR_IO_ADDR(DDRB), r16 // 1
delay 19 // 19
ret // 4
В зависимости от того, какая функция вызывается baseband30_0 или baseband30_1 в регистр r16 записывается значение того что должно быть на пине ввода/вывода: 1 или 0. После этого идёт безусловный переход на baseband30 осуществляется вывод и задержка на 19 тактов, после чего идёт возврат.
Самая большая магия этого кода, что он просчитан точно до каждого такта, каждый такт передачи манчестерского кода занимает ровно столько периодов, сколько допустимо стандартом, а именно 32 такта процессора! Это фантастически гениально, надо помнить сколько тактов занимает каждая команда.
Давайте его скорее скомпилируем и посмотрим как он выглядит, как развернутся все эти макросы. Компилируем командой make (предварительно установив avr-gcc) и дизассемблируем получившийся elf-файл
00000000 __vectors:
0: 0e c0 rjmp .+28 ; 0x1e __ctors_end
2: 15 c0 rjmp .+42 ; 0x2e __bad_interrupt
...
Вначале у нас вектора прерываний, но нас интересует только первый jump. Так как остальные вектора никуда не ведут.
0000001e __ctors_end:
1e: 11 24 eor r1, r1
20: 1f be out 0x3f, r1 ; 63
22: cf e5 ldi r28, 0x5F ; 95
24: d2 e0 ldi r29, 0x02 ; 2
26: de bf out 0x3e, r29 ; 62
28: cd bf out 0x3d, r28 ; 61
2a: 02 d0 rcall .+4 ; 0x30 main
2c: 11 c1 rjmp .+546 ; 0x250 _exit
Здесь мы настраиваем порты ввода/вывода, и вызываем функцию main. A main состоит из безумного количества вызовов функций baseband30* и jump (так развернулся наша адский цирк макросов).
00000030 main:
30: 01 d1 rcall .+514 ; 0x234 baseband30_1
32: 00 c0 rjmp .+0 ; 0x34 main+0x4
34: fd d0 rcall .+506 ; 0x230 baseband30_0
36: 00 c0 rjmp .+0 ; 0x38 main+0x8
38: fd d0 rcall .+506 ; 0x234 baseband30_1
3a: 00 c0 rjmp .+0 ; 0x3c main+0xc
3c: f9 d0 rcall .+498 ; 0x230 baseband30_0
3e: 00 c0 rjmp .+0 ; 0x40 main+0x10
40: f9 d0 rcall .+498 ; 0x234 baseband30_1
42: 00 c0 rjmp .+0 ; 0x44 main+0x14
44: f5 d0 rcall .+490 ; 0x230 baseband30_0
46: 00 c0 rjmp .+0 ; 0x48 main+0x18
48: f5 d0 rcall .+490 ; 0x234 baseband30_1
4a: 00 c0 rjmp .+0 ; 0x4c main+0x1c
4c: f1 d0 rcall .+482 ; 0x230 baseband30_0
...
22e: 00 cf rjmp .-512 ; 0x30 main
И так далее… пока не джампнемся снова на main
Ну и глянем как же выглядит наш baseband модуль.
00000230 baseband30_0:
230: 08 e1 ldi r16, 0x18 ; 24
232: 02 c0 rjmp .+4 ; 0x238 baseband30
00000234 baseband30_1:
234: 00 e0 ldi r16, 0x00 ; 0
236: 00 c0 rjmp .+0 ; 0x238 baseband30
00000238 baseband30:
238: 07 bb out 0x17, r16 ; 23
23a: 00 c0 rjmp .+0 ; 0x23c baseband30+0x4
23c: 00 c0 rjmp .+0 ; 0x23e baseband30+0x6
23e: 00 c0 rjmp .+0 ; 0x240 baseband30+0x8
240: 00 c0 rjmp .+0 ; 0x242 baseband30+0xa
242: 00 c0 rjmp .+0 ; 0x244 baseband30+0xc
244: 00 c0 rjmp .+0 ; 0x246 baseband30+0xe
246: 00 c0 rjmp .+0 ; 0x248 baseband30+0x10
248: 00 c0 rjmp .+0 ; 0x24a baseband30+0x12
24a: 00 c0 rjmp .+0 ; 0x24c baseband30+0x14
24c: 00 00 nop
24e: 08 95 ret
В конце видно как delay развернулся в список jump и nop для задержки. Вот такая красивая магия.
Ну что же, с кодом разобрались. Соберите вытекший мозг с ушей, переходим к испытаниям.
Испытания
Применим все полученные знания и проведём испытания. Компилируем прошивку, прошиваем контроллер, не забывая правильно выставить Fuse-биты.
Платка для прошивки
Подключаем наш колебательный контур и тестируем на настоящем промышленном считывателе, никаких полумер, честные боевые условия.
Испытательный стенд
И, о чудо! Оно работает, корректно считывается и в цикле даёт корректный ID! Без внешнего питания, с работой только от поля. Осталось всё это привести в порядок и сделать настоящую RFID-метку.
Окончательный “заламинированный” вариант метки
Итого
Могу честно признаться, что до конца не верил, что это заработает. Питание от поля, нестандартные режимы работы контроллера, работа строго по тактам, самодельная катушка индуктивности. Плюс ещё работа самого RFID. И вот, вроде плёвая поделка растекается на пару месяцев чтения документации и разбора полётов. Но это работает, и эта штука по-настоящему гениальна. Так что ребята, вот такие штуки и есть настоящее хакерство. Дерзайте!
Домашнее задание
Раз вы всё-таки прочитали эту крутую статью, я её писал, старался, делал, теперь пора и вам что-то попробовать сделать. В коде эмулятора есть раздел, который эмулирует карты стандарта HID Proximity, с кодированием фазовым сдвигом. Вам в качестве развлечения и лучшего усвоения материала следует разобраться со стандартом HID и этим кодированием. Решение присылайте в комментарии. Удачи.
Список литературы
- AppNote 411 RFID Made Easy
- AN710 Antenna Circuit Design for RFID Applications
- При подготовке статьи использованы материалы сайта priority1design.com
SubSerman
Классная статья, очень интересно было читать
dlinyj Автор
Спасибо, очень приятно!