Взял себе плату BeagleBone с процессором AM335x. У него на борту есть два реал-тайм ядра PRU (PRU0 и PRU1). Хочу через GPIO научить их обмениваться данными. Данный кодируются в манчестерском коде. У прушек свой компилятор - pasm. Частота работы ядер 200 МГц
Проблема:
Понятно, что алгоритм передачи написать не так сложно: сначала переводит байт в МК(манчестерский код), потом передаем бит за битом. С приемом, естественно, немного сложнее, но идея проста: принимаем стартовую последовательность, а далее делаем некоторое количество отсчетов за 1/3 периода. Записываем значение счетчика и сравниваем с следующим отсчетом.
В коде я сделал немного иначе и вместо 1/3 взял чуть меньше 1/2. Вот пример кода:
Код
LISEN: // прослушка линии
QBEQ START, r9, 15 // если принято 16 бит, то выход
MOV r2, 0 // обнуляем счетчик длительности
QBBC CLR0, IN // проверка на 0-ь.
QBBS SET1, IN // проверка на 1-цу
CLR0: // метка установки 0
ADD r2, r2, 1 // счетчик длительности
QBBC CLR0, IN // проверяет текущий уровень
QBGE CLR10, r2, 50 // считаем, что половина периода - 150 нс. Тогда переход на CLR10, если 0 длится больше 150
CLR r5.t16 // устанавливаем 0
LSR r5, r5, 1 // сдвигаем
ADD r9, r9, 1 // счетчик принятых бит
QBA LISEN // возвращаемся на прослушку
CLR10: // пришло два нуля
CLR r5.t16 // устанавливаем и сдвигаем
LSR r5, r5, 1
CLR r5.t16
LSR r5, r5, 1
ADD r9, r9, 2 // принято 2 бита
QBA LISEN // возврат на прослушку
//--------------------------------------------------------------------------
SET1: // метка установки 1
ADD r2, r2, 1 // счетчик длительности
QBBS SET1, IN // проверяет текущий уровень
QBGE SET01, r2, 50 // считаем, что период 150 нс.
SET r5.t16 // устанавливаем 1
LSR r5, r5, 1 // сдвигаем
ADD r9, r9, 1 // счетчик принятых бит
QBA LISEN // возвращаемся на прослушку
SET01: // пришло две 1-ы
SET r5.t16 // устанавливаем и сдвигаем
LSR r5, r5, 1
SET r5.t16
LSR r5, r5, 1
ADD r9, r9, 2 // принято 2 бита
QBA LISEN // возврат на прослушку
QBEQ START, r9, 15 // если принято 16 бит, то выход
MOV r2, 0 // обнуляем счетчик длительности
QBBC CLR0, IN // проверка на 0-ь.
QBBS SET1, IN // проверка на 1-цу
CLR0: // метка установки 0
ADD r2, r2, 1 // счетчик длительности
QBBC CLR0, IN // проверяет текущий уровень
QBGE CLR10, r2, 50 // считаем, что половина периода - 150 нс. Тогда переход на CLR10, если 0 длится больше 150
CLR r5.t16 // устанавливаем 0
LSR r5, r5, 1 // сдвигаем
ADD r9, r9, 1 // счетчик принятых бит
QBA LISEN // возвращаемся на прослушку
CLR10: // пришло два нуля
CLR r5.t16 // устанавливаем и сдвигаем
LSR r5, r5, 1
CLR r5.t16
LSR r5, r5, 1
ADD r9, r9, 2 // принято 2 бита
QBA LISEN // возврат на прослушку
//--------------------------------------------------------------------------
SET1: // метка установки 1
ADD r2, r2, 1 // счетчик длительности
QBBS SET1, IN // проверяет текущий уровень
QBGE SET01, r2, 50 // считаем, что период 150 нс.
SET r5.t16 // устанавливаем 1
LSR r5, r5, 1 // сдвигаем
ADD r9, r9, 1 // счетчик принятых бит
QBA LISEN // возвращаемся на прослушку
SET01: // пришло две 1-ы
SET r5.t16 // устанавливаем и сдвигаем
LSR r5, r5, 1
SET r5.t16
LSR r5, r5, 1
ADD r9, r9, 2 // принято 2 бита
QBA LISEN // возврат на прослушку
Код, естественно, работает не совсем корректно, поэтому для теста я написал тестовую программку для 4-ех бит, а именно ситуаций, когда в линии 0011, 1100, 1001, 0110. Мне думается, что весь мой косяк в том, что я не правильно произвожу выборку.
Глоссарии:
SBCO - команда записи данных в память
QBBS, QBBC - команды перехода на метку, если 1 или 0
QBNE - переход на метку, пока не ровно.
QBGE - переход на метку, если больше.
Недочеты кода:
переход на метки SET01 и CLR10 происходит в тот момент, когда переход от 1 к 0, тогда в линии у нас 1001, либо от 0 к 1, тогда 0110. . Как только условия соблюдены, у нас происходит ещё 9 тактов - это доп. смещение, которое ломает общий алгоритм. Либо нужно увеличивать длительность сигнала, либо придумать компенсацию. А может я ошибаюсь..
UPD: перед входом к метке LISEN стоит команда WBS IN. Вход в метку будет в тот момент, когда по линии придет единица. Если смогу принять одни байт информации, то можно будет уже перейти на пакеты.