Декодирование двухпроводного последовательного протокола в стиле SPI

Я работаю над проектом, в котором используется оптический датчик от мыши. У меня есть оригинальная управляющая печатная плата (все еще заполненная, за исключением самого оптического датчика), и у меня есть оптический датчик на моей специальной печатной плате, которая должна управляться nrf51822. Я подключил контакты часов + данных (это двухпроводной интерфейс) к обеим платам, управляемые оригинальной платой управления (я установил контакты часов и данных в качестве входов без подтягивающих резисторов).

Я пытаюсь перехватить трафик, чтобы определить, какие сигналы отправляются, но мне не очень повезло - я подозреваю, что моя тактовая частота слишком низкая. Как можно быстрее (только в while trueцикле) я сканирую свой вывод часов и вывод данных, а затем вывожу их оба на выход моей консоли через UART со скоростью 1 Мбод. Запуск этого цикла пустым в течение 5 секунд приводит к ~ 4000 циклам, что означает, что я получаю время выполнения> 1 мс для каждого цикла, что я считаю своей основной проблемой.

Как бы то ни было, я фиксирую (примерно за 700 сканирований) 100 групп чередующихся «часы 1 и данные 1» и «часы 0 и данные 0» — каждая группа состоит из 4–9 элементов (то есть 4–9 «1» на оба, а затем 4-9 «0» на обоих). Затем, примерно через 400 сканирований (~ 0,5 секунды), я получаю то же самое, но 54 группы. В этот момент я прекратил сканирование.

Есть ли способ: A) Ускорить мой цикл сканирования, чтобы я мог более точно фиксировать трафик? или Б) Расшифровать то, что у меня уже есть (сомнительно)?

Нужно ли мне рассматривать альтернативный маршрут? Я не нашел доступа к осциллографу, что... жаль.

Буду признателен за любой совет. Спасибо.

Какой MCU или процессор вы используете для чтения псевдо-SPI CLK и DATA? Вы действительно работаете вслепую без осциллографа. USB-оскопы стали довольно дешевыми и могут быть в вашем ценовом диапазоне (например, Digilent Analog Discovery 2, двухканальный, 100 Msps, 159 долларов США со скидкой для студентов). Это не рекомендательный сайт, так что просто погуглите USB-осциллограф, и вы найдете массу. Если вам все же нужно немного разбить этот протокол, вам лучше всего использовать выделенный микроконтроллер, работающий на «голом железе» (C или ассемблер). Возможно, даже придется прервать на границе CLK, сохранить состояние ДАННЫХ и выполнить последующую обработку.
Для этого вам не нужен осциллограф, вам, вероятно, понадобится логический анализатор. Те, что на чипах USB fifo, стоят достаточно дешево, и могут скормить для анализа что-то вроде сигрока. Но также учтите, что вы, вероятно, смотрите на протокол мыши ps/2 , который хорошо документирован и не нуждается в обратном проектировании.
Спасибо за комментарии, ребята! Я использую Nordic nrf51822, который работает на частоте 16 МГц, поэтому я должен иметь точность до ~ 62,5 нс, хотя только в том случае, если то, что я пытаюсь сделать, может быть выполнено в 1 инструкции (какое чтение... может быть в состоянии ?) Я настрою прерывание и попробую обработать позже, чтобы цикл не замедлялся отправкой сообщения UART. Я также посмотрю, есть ли какие-нибудь местные хакерские пространства или что-то, что может иметь осциллограф...
@ChrisStratton, я еще могу попробовать логический анализатор, но я достаточно уверен, что протокол, используемый на этом чипе, является проприетарным. Посмотрев на спецификацию PS/2, я не ДУМАЮ, что это будет реализовано на этом чипе - он был скопирован с беспроводной мыши, а беспроводной модуль в мыши позаботился о связи с хост-компьютером. Распиновка похожа на ADNS2620, но я посмотрю спецификацию PS/2 и посмотрю, возможно ли это.
На самом деле было бы вполне логично, если бы беспроводная мышь была внутри PS/2. Это позволяет им использовать обычную микросхему проводной мыши и отдельную микросхему радио/микроконтроллера, при этом ни одна из частей не должна быть нестандартной или специфичной для этой цели, что может помочь снизить затраты.
@Полезно - на самом деле купите любой дешевый анализатор входа в систему, например этот ebay.com/itm/… , и он вам очень поможет.
@PeterJ, честно говоря, меня это очень соблазняет - доставка меня отталкивает, хотя к тому времени я буду очень занят в школе. :/ Я ценю совет!

Ответы (2)

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

Есть два варианта:

Вариант 1.
Запуск в узком цикле, опрашивающий выводы и записывающий метку времени в буфер при изменении их состояния. Если значение не изменилось, ничего не делайте.
Как только буфер заполнится, выведите время, записанное по последовательному каналу.

Вариант 2:
Используйте последовательные и тактовые линейные входы в качестве прерываний. Когда выводы меняются, в буфер записывается временная метка перехода и новое состояние вывода.
Сделайте так, чтобы фоновый цикл отправлял зарегистрированные данные на последовательный порт, не отставая от данных, насколько это возможно, указывая, не переполнился ли буфер.

Оба они решают большую проблему, с которой вы столкнулись: вы пытаетесь вывести последовательные данные из критически важного по времени фрагмента кода, printf работает медленно, а последовательные порты работают в ледяном темпе, никогда не выполняйте их в нужном вам разделе кода. быстро бежать. Вариант 1 проще и, вероятно, справится с немного более высокими частотами, но будет записывать только до тех пор, пока у вас есть место для буферизации, и, возможно, может сообщать о двух очень близких друг к другу фронтах как о неправильном порядке. Вариант 2 выводит во время работы, поэтому он должен работать дольше (будь то на 1 фронт больше или сохраняется и работает неопределенно, зависит от скорости фронтов и последовательного порта), но из-за накладных расходов на прерывания будет иметь более низкий верх скорость и сложнее кодировать.

Другое очевидное решение — одолжить/арендовать у кого-нибудь осциллограф или логический анализатор.

Я отмечаю это как принятый ответ, поскольку это имеет смысл - я как бы подозревал, что отладка UART длилась вечность. Как вы думаете, будет ли массив достаточно быстрым буфером, или я должен просто использовать некоторые побитовые операторы с uint64_t или что-то в этом роде?
Массив uint32_t должен подойти. Вы можете использовать таймер, чтобы дать вам текущее время в виде 32-битного значения, которое должно быть довольно быстрым для чтения. В зависимости от используемого временного разрешения вы можете использовать верхний бит 32-битного значения для представления направления.
Подумайте об этом, если вы знаете полярность часов, вы можете установить прерывание для чтения данных на соответствующем фронте часов и записать только это. Это не даст вам времени, но даст вам данные, отправленные в очень компактной форме. И никогда не используйте 64-битные значения в 32-битном процессоре, если в этом нет крайней необходимости.

NRF51822 использует ARM Cortex M0, который кажется совершенно неподходящим для вашей задачи захвата. Cortex M0 использует от 1 до 4 циклов для основных инструкций и намного дольше, если вы используете такие вещи, как умножение. Процессор не может быть прерван во время декодирования базовой инструкции.

Если вы хотите захватить данные, было бы намного лучше с небольшим 8-битным процессором с 1 циклом на команду, таким как ATMega328. Вы должны быть в состоянии подключить Arduino Nano за 3 доллара для сериализации данных и вывода через последовательный порт.

Поскольку протокол является синхронным, вы должны иметь возможность использовать SPI в режиме Slave для получения данных. Вы должны прочитать отличный обзор SPI Ника Гэммонса , чтобы начать.

Если вы используете ведомое устройство SPI, вам фактически придется вставлять 8 бит в очередь UART каждые 8 ​​тактов вашего устройства. Просто помните, что этот метод захвата не будет захватывать пробелы (без тактов), поэтому вы получите плотный дамп (без пробелов) данных.

Чтобы понять, почему ARM Cortex M0 плохо справляется со скоростью прерывания или битовыми портами, прочитайте это и это .

Это очень вводящий в заблуждение совет. ЦП должен быть достаточно быстрым, если код написан разумно, проблема в том, что постер пытается генерировать вывод для печати в режиме реального времени - это и поддерживающий его USB ограничивают частоту дискретизации порядка тысячи в секунду. С небольшой осторожностью, вероятно, достижимо увеличение скорости в 100 раз без замены аппаратного обеспечения. Тем не менее, если работает программное устройство BLE или его эквивалент, или любой другой планировщик или прерывания, они будут вызывать паузы в выборке.
@Крис Стрэттон. Я добавил кое-что к своему ответу, но я придерживаюсь того факта, что M0 не является хорошим процессором для того, что хочет сделать оператор. Мы также понятия не имеем, что если NordicSemi изменили или модифицировали что-либо при использовании M0 IP. Использовали ли они запечатанную реализацию или у них была полная лицензия и накатывались собственные дополнения?
Если бы постер подчеркивал разницу между 100 KSPS и 1 MSPS, вы могли бы быть правы, но проблема 1 KSPS заключается не в выборе чипа, а в плохо разработанной программе и схеме отчетности. Это действительно плохой программист, который настаивает на новом оборудовании, чтобы исправить вопиющую ошибку проектирования программного обеспечения.
@Крис Стрэттон. Поскольку ОП не предоставил ни одной строки кода, трудно судить о его программных возможностях. Однако любой приличный инженер-железо знает, что M0 — плохой выбор для такого типа задач. .... Если вы пытаетесь испытать МОЮ способность программировать, то это другое дело. Я бы начал с понимания как программных, так и аппаратных ограничений процессора, который я хочу использовать. Но, возможно, вы другой человек и никогда бы не подумали об аппаратных ограничениях.......
M0 должен быть способен на что-то порядка 100 раз больше, чем производительность, достигнутая плакатом. Общая форма причины, которая не реализуется, очевидна в вопросе, и то, что я уже указывал: попытка генерировать последовательный вывод, по-видимому, в удобочитаемой форме, для каждого образца во время взятия образцов. То, что они должны делать, — это короткий быстрый захват в буфер памяти, чтобы получить представление о времени, а затем использовать это понимание для тактирования слов, выбранных на правильном фронте предоставленных тактовых импульсов.
Это помогло мне понять некоторые ограничения скорости, поэтому я ценю совет — я искоренил, хотя выбрал другой ответ в качестве принятого. Спасибо вам за ваши предложения!