В прошлый раз мы рассмотрели аппаратную часть нашей побрякушки, настало время написать прошивку.
Работа 1-Wire
В первой части почти ничего не было сказано о специфике работы 1-wire. Аппаратная часть протокола очень проста: один сигнальный проводник, подтянутый к плюсу питания через резистор. Все, что могут устройства, это замыкать сигнальную линию на землю на то или иное время. Как же организована передача данных?
Каждый акт взаимодействия по 1-wire начинается со сброса.
Ведущее устройство выдает импульс низкого уровня длительностью от 480 мкс до бесконечности. Таким образом, включение питания тоже рассматривается как сброс. После этого ведущий отпускает линию и через 200 мкс проверяет напряжение на ней. Любое ведомое устройство, если оно есть на шине, в это время должно дать ответный импульс, называемый Presence (присутствие). Если Presence принят, можно считать, что ведомые устройства обнаружены и готовы к принятию команд.
Передача данных разбита по времени на тайм-слоты, длительностью от 67 мкс. В пределах одного тайм-слота передается один бит, таким образом скорость передачи может достигать 14,9 кбит/с. Некоторые микросхемы поддерживают еще режим Overdrive, в котором слоты укорачиваются до 10 мкс, а скорость возрастает до 100 кбит/с, но мы этот режим рассматривать не будем, стандартной скорости более чем хватает.
Для передачи единицы ведущий выдает короткий импульс (5 мкс) и до конца тайм-слота отпускает линию. Для передачи ноля импульс длиннее — 60 мкс.
Прием данных от ведомых устройств также синхронизируется ведущим. В начале тайм-слота он дает импульс длительностью 5 мкс. Если ведомое устройство передает единицу, оно не вмешивается в процесс. Если передает ноль — удерживает линию на низком уровне в течение 20 мкс. От ведущего требуется проверить уровень напряжения через некоторое время после подачи импульса.
Обратите внимание! Некоторые временные параметры передачи для микросхемы DS2413 отличаются от стандартных, в datasheet'е они выделены желтым.
Адресация
Каждое ведомое устройство должно иметь свой уникальный адрес. В микросхемы, предназначенные для работы с 1-wire адреса прошиваются в процессе производства. Адрес состоит из 64 бит (8 байт), причем младший байт представляет собой код семейства микросхем (для DS2413 — 0x3A), а старший — контрольную сумму. После выбора устройства по адресу все остальные устройства не реагируют на команды до следующего сброса.
Команды
Устройства 1-wire управляются однобайтными командами. Существуют команды общие для всех, а также специфичные для определенных микросхем.
Общие команды:
- 0x33 — Read ROM. После этой команды могут быть приняты 64 бита адреса устройства. Команда работает, только если устройство на шине одно.
- 0x55 — Match ROM. После команды требуется передать адрес. Устройство, чей адрес совпал с переданным, продолжает отвечать на команды, остальные молчат.
- 0xF0 — Search ROM. Позволяет узнать адреса всех устройств на шине. Алгоритм поиска довольно сложный, желающие могут ознакомиться здесь
- 0xCC — Skip ROM. Выбирает все устройства на шине.
- 0xA5 — Resume. Выбирает устройство, выбранное в прошлый раз. Полезно при многократных обращениях к одному устройству.
Команды, специфичные для DS2413, их всего две:
- 0x5A — PIO Write. Управление ключами. После команды должен быть передан байт, в котором младшие два бита отвечают за состояние двух каналов. Например, 0x01 — включить первый канал, 0x02 — второй, 0x00 — все выключить. Затем нужно передать тот же байт, но в инвертированном виде (было 0x02 — стало 0xFE) для защиты от ошибок.
- 0xF5 — PIO Read. DS2413 может не только управлять выходными портами, но и считывать с них значения. Подробности — в документации, мы эту команду использовать не будем.
Определение адресов микросхем
Как было упомянуто в первой части статьи, перед сборкой не худо считать адреса, зашитые в купленных микросхемах, иначе мы не сможем ими управлять. Для этого предназначена специальная прошивка-считыватель. Она позволяет прочитать адрес DS2413 и записать в EEPROM контроллера, откуда его можно достать программатором.
К великому сожалению, считыватель был написан немного под другой контроллер (ATTiny12) и на ассемблере. В архиве в конце статьи будет исходник этой прошивки, желающие могут попытаться портировать ее под Tiny13. Также можно воспользоваться готовыми функциями приема и передачи 1-wire из основной прошивки и написать свой считыватель.
Наконец, можно взять адаптер 1-wire/COM (например, такой) и считать микросхемы на компьютере.
Элементы программы
Генератор псевдослучайных чисел
Однообразно мигающее украшение очень быстро надоест, поэтому нужно воспроизводить случайные световые эффекты через случайные промежутки времени. В качестве генератора псевдослучайных чисел выбран сдвиговой регистр с обратными связями (Linear feedback shift register) как наиболее просто реализующийся на AVR. Алгоритм не содержит операций умножения, только XOR и сдвиги. Регистр разрядности 15 бит обеспечивает 32767 состояний, чего хватит на час неповторяющейся работы устройства.
Но это еще не все, для инициализации ГСЧ нужен источник энтропии, иначе при каждом включении будет генерироваться одна и та же последовательность. В качестве такого источника может выступать:
- АЦП. Можно оцифровать напряжение питания и взять несколько младших бит.
- RC-цепь. С большой дискретностью измеряется время заряда/разряда конденсатора, берутся младшие биты.
- Два несинхронизированных таймера. Вычисляется отношение периодов.
В данной конструкции применен третий способ: подсчет числа тактовых импульсов за один период сторожевого таймера. Сторожевой таймер в Tiny13 тактируется от своего собственного осциллятора, частота которого довольно нестабильна.
Каждые 2 секунды генерируется 2 8-битных псевдослучайных числа, биты которых используются следующим образом:
4 старших бита первого числа — выбор текущего эффекта. Это может быть:
- «Бегущий огонь» в одном из двух направлений. Вероятность 2/16.
- Вспышка одного, двух или трех светодиодов. Вероятности — по 1/16.
- Отсутствие эффекта. С вероятностью 11/16 в данный момент ничего не загорится.
Старший бит второго числа — цвет (зеленый или оранжевый).
Оставшиеся биты кодируют номера первого, второго и третьего светодиода для одиночных вспышек (группами по 3 бита). Так как 3 бита кодируют номера от 0 до 7, а всего звеньев 10, для второй вспышки номер увеличивается на 1, для третьей — на 2. Таким образом охватывается весь диапазон, и это проще, чем брать четырехбитные номера и контролировать границы.
Тактирование
Контроллер Tiny13 имеет два встроенных источника тактового сигнала — 9,6 и 4,8 МГц, кроме того, можно включить делитель тактовой частоты. Чем частота ниже, тем ниже энергопотребление контроллера. С другой стороны, слишком низкая частота не позволит задать временные интервалы для протокола 1-wire. При написании прошивки на ассемблере удалось добиться работы на частоте 1,2 МГц, при этом самый короткий отмеряемый интервал составил всего три такта. Для прошивки на C такого быстродействия достичь не получилось, минимальная тактовая частота — 4,8 МГц.
Большую часть времени контроллер находится в режиме PowerDown, при этом работает только сторожевой таймер, который вызывает прерывание каждые 2 секунды.
Fuse-биты
Для конфигурирования контроллера служит набор так называемых fuse-битов (фьюзов). Их значения нужно установить один раз перед прошивкой. Значения фьюзов для данного проекта (значения, отличные от заводских, выделены):
SELFPRGEN = 1 // самопрограммирование запрещено
DWEN = 1 // debugWire отключен
BODLEVEL1:0 = 10 //brown-out detector настроен на 1,8 В.
RSTDISBL = 1 // вывод RESET не отключен
SPIEN = 0 // SPI разрешен
EESAVE = 1 // защита EEPROM отключена
WDTON = 1 // отключение сторожевого таймера разрешено
CKDIV8 = 1 // делитель тактовой частоты на 8 отключен
SUT1:0 = 00 // время старта 64 clk
CKSEL1:0 = 01 // тактовая частота 4,8 МГц
Прошивать контроллер нужно до установки на плату, подключив его непосредственно к программатору. Если нет панельки для SOIC-корпусов, можно аккуратно подключить проводами. После прошивки и проверки работоспособности контроллер можно распаивать окончательно.
Полные исходники основной прошивки:
pastebin.com/CEKvhYVt
Прошивка для считывателя адресов 1-wire:
pastebin.com/tQ7AqmfN
Видео, показывающее работу прошивки:
Заключение
На данный момент занято чуть больше половины памяти контроллера, так что есть огромный простор для фантазии. Можно реализовать новые эффекты, можно слегка доработать схему устройства и добавить датчик температуры, освещенности, акселлерометр, микрофон, детектор НЛО или ИК-приемник. Можно организовать загрузку новой прошивки, скажем, через последовательный интерфейс (Tiny13 поддерживает самопрограммирование). Естественно, для всех возможностей одновременно не хватит ни ног, ни памяти контроллера, но одну-две фичи добавить можно.
Поздравляю прекрасную половину хабрачеловечества с наступающим 8 марта!
Автор: Ocelot