[recovery mode] Самосинхронизирующиеся коды для связи через SPI интерфейс

2b8fab63a8a1612cda18d43b2892b8fb.png

Проблемы с покупкой микроконтроллеров в России, плюс моя любовь к минимализму и желание заказчика сделать стоимость изделия минимальной, привели к разработке показанного на блок схеме устройства.

5b47f94b5d60f961400b2167f2609950.png

Спустя короткий промежуток времени, была поставлена задача — малой кровью сделать управление по линии связи устройством (назовем его «Блок управлением светом») на микроконтроллере PIC10F322, где большая часть из 512 программных слов уже было занято управлением светодиодами. Причем у PIC10F322 свободным для связи оставался только один вывод да и то, тот который может работать только в режиме входа.

e2916449737d9eb0012ef56b3406b854.png

Сложность еще заключалась в том, что у микроконтроллера в блоке управления единственный UART был занят связью с панелью управления, поэтому замена в блоке управления светом микроконтроллера на более мощный с аппаратным UART, требовала так же замены микроконтроллера на более мощный с двумя UART в блоке управления. Захотелось найти более простое решение, не требующее замены микроконтроллеров, тем более заказчик утверждал, что дальнейшее увеличение функционала не предвидится.

Так как PIC10F322 управлял светодиодами через три сдвиговых регистра 74HC595, то каждые 320 мкс он выдавал три пачки по восемь импульсов тактового сигнала и появилась идея организовать удаленный SPI интерфейс через микросхемы драйверов RS485.

63482b2369485f295159b0d6357e0550.png

PIC10F322 работает в режиме мастера, выдавая тактовый сигнал в линию, а базовый блок работает как подчиненный передатчик, выдавая обратно битовый поток команды. Так как между блоком управления и блоком света нет синхронизации, то PIC10F322 должен как-то понять где начало байта. Контроль ошибок делается за счет избыточности, если полученные три байта одинаковые, то значит ошибки нет. Так как битовый поток идет постоянно, то можно смело отбрасывать ошибочные кадры.

Стоит заметить, что блок управления управляет двухтактным преобразователем напряжения и ШИМ формирователем усилителя класса D, формируя звуковые сигналы оповещения, а также аналого-цифровое преобразование и простейшую обработку сигнала с микрофона. Поэтому времени у него просто в обрез и работать на прерываниях по SPI, где промежуток между байтами в кадре 10 мкс не представляется возможным.

Хотелось бы найти решение, в котором записал байт в буфер и забыл. Так как синхронизация между блоками отсутствует, то базовый блок может начать передачу в произвольный момент времени. Вот так я пришел к тому, что нужны коды, которые при сдвиге не пересекаются с другими кодами.

Идея в следующем — если байт 0×01 циклически сдвигать по кругу, то его никогда не перепутаешь с так же циклически сдвинутым байтом 0×03 или 0×05 или 0×07.

1ba60af092ee40bce610b005a9af2abd.png

Стало интересно, а сколько всего таких кодов в восьми битах? Оказалось таких кодов — 34, причем 16 из них идут подряд (0×80–0×8F), поэтому декодировать их очень легко.

В связи с тем, что мне нужно всего лишь 16 команд, программа получилась очень простая. Формирую тактовый сигнал, по заднему фронту считываю состояние входа и записываю в регистр. Полученный байт сохраняю в буфер. После заполнения буфера сравниваю значения элементов буфера, если одинаковые, то проверяю на попадание в диапазон 0×80 — 0×8F, если не попали, то сдвигаю два соседних байта в буфере и снова сравниваю, и так до семи раз. В случае любой ошибки пакет отбрасывается. Затем просто обнуляю старший бит и команда получена.

Полный список кодов которые, при сдвиге не принимают значение другого кода:

от 0×80 до 0×8F, 0×92, 0×93, 0×95, 0×96, 0×97, 0×99, 0×9A, 0×9B, 0×9D, 0×9E, 0×9F, 0xAA, 0xAB, 0xAD, 0xAF, 0xB7, 0xBB, 0xBF.

На КДПВ одинаковым цветом отмечены варианты сдвинутого числа, числа в рамочке, те которые я выбрал как «родителей» последовательности вариантов.

Вполне возможно, что такое давным давно придумали еще во времена Чарлза Бэббиджа, но беглый поиск по «самосинхронизирующиеся коды» интересующего меня результата не дал.

© Habrahabr.ru