Перейти к содержанию
    

kowapuk

Участник
  • Постов

    7
  • Зарегистрирован

  • Посещение

Репутация

0 Обычный
  1. Для того объекта, с которым будет вестись обмен, не предусмотрен UART для обмена данными. Для этого бы приходилось влазить в "ту" систему. А это, пока что, исключено.
  2. Передатчик можно написать, исходя из кода приемника. Это не самое трудное. Далее, нужно добавить пару строчек перевода кода манчестера в классический. // приемник для передачи сигнала со скоростью 2 мегабита .origin 0 .entrypoint PRE #include "GPIOCTR.hp" #include "TRSBNI.hp" #define USR0 21 // led 0 #define USR1 22 // led 1 #define USR2 23 // led 2 #define USR3 24 // led 3 #define GPIO1 0x4804C000 // адресс регистров GPIO1 #define PRU1_ARM_INT 20 // значение прерывания от PRU1 to ARM #define RAM0 C24 // Локальная память PRU1 #define RAM1 C25 // Локальная память PRU0 #define IN r31.t6 // входной GPIO //Определим основные регистры #define REQ r1 // в этот регистр будет помещаться информация от PRU0 #define COUNT r2 // считает колличество принятых байт #define VALUE r3 //Приветствуем в программа приемника кода на PRU PRE: MOV R4, 2 INIT: MOV REQ, 0 MOV COUNT, 8 MOV VALUE, 0 LBCO REQ, RAM0, 0, 1 // выход из программы. QBEQ EXIT, REQ, 0 START: // Знаем, что в линии, если ничего не приходит идет сигнал низкого уровня // Длительность задержки 45 нс. Проверяющий сигнал между байтами равен 9 мкс // Или 4.5 HIGH и 4.5 LOW. Для начала будем ждать сигнал от PRU0, что он начал передачу LBCO REQ, RAM0, 1, 1 // сюда помещаем разрешающее значения QBNE START, REQ, 0 // Пока не будет установлен 0, будет прыгать на старт. // в начале посылки каждого байта будем получать переход из 1 в 0. Задержка кажого сигнала 4.5 мкс WBS IN // ждем 4.5 мкс WBC IN // после этого нужно поставить задержку, равную 100 CDELAY 101 // компенсация задержки хоста 100+1. CDELAY 1 - 45 нс. POOL: REC9 IN, VALUE, COUNT //макрос приемника SBCO VALUE, RAM0, R4, 1 // запись в память ADD R4, R4, 1 // добавляем 1 в счетчик бит QBEQ EXIT, R4, 35 QBA INIT // Дальше начинают приходить биты с длительностью от 480 до 500 нс (-45 нс) EXIT: // Ждем прерывания от хоста и выключаем PRU MOV r31.b0, 20+16 HALT Синтаксис макроса REC9 (REC9 - это приемник с задержкой 9): .macro REC9 // Макрос приема данных с задержкой 9 .mparam IN, OUT, COUNT // входные параметры: IN - вход GPIO; OUT - выходной регистр; // COUNT - регистр, содержащий в себе число бит. RECIVE: QBBS SET1X, IN // проверяем 1 сейчас. Если нет, то сразу переход на 0 QBEQ BACK, COUNT, 0 SET0X: WBC IN // проверям, точно ли 0. CDELAY 9 // ждем 405 НС. До смены остается ещё 30 НС WBC IN // вторая проверка. Debbug точка CDELAY 1 // после неё станет ясно, что пришло. Сигнал уже как 20 нс новый. QBBC SET00, IN // пришел 0? Если нет, значит 1-ца. -25 нс. SET01: // ЗАписываем переход из 0 в 1 CLR OUT.t1 // Записываем 01 SET OUT.t0 LSL OUT, OUT, 2 //смещаем. -45нс. CDELAY 9 // Сигналу осталось минимум 30 нс. -405-40+480 SUB COUNT, COUNT, 2 // принято 2-а байта. 25 нс. CDELAY 1 // -20 нс нового сигнала QBA RECIVE // возвращаемся на прием. -25 SET00: //записываем переход из 0 в 0 CLR OUT.t1 CLR OUT.t0 LSL OUT, OUT, 2 CDELAY 9 SUB COUNT, COUNT, 2 CDELAY 1 QBA RECIVE // возвращаемся на прием -25 SET1X: // для установки 1-ы и.... WBS IN // аналогично с нулем CDELAY 9 WBS IN CDELAY 1 QBBS SET11, IN SET10: SET OUT.t1 CLR OUT.t0 LSL OUT, OUT, 2 CDELAY 9 SUB COUNT, COUNT, 2 CDELAY 1 QBA RECIVE // переход на прием SET11: SET OUT.t1 SET OUT.t0 LSL OUT, OUT, 2 CDELAY 9 SUB COUNT, COUNT, 2 CDELAY 1 QBA RECIVE // переход на прием BACK: // метка записи значения LSR OUT, OUT, 2 // когда приходят последний 2 бита, то он сдвигаются влево. Это необходимо учесть .endm Тему можно закрывать.
  3. Введение: Взял себе плату 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 // возврат на прослушку Код, естественно, работает не совсем корректно, поэтому для теста я написал тестовую программку для 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. Вход в метку будет в тот момент, когда по линии придет единица. Если смогу принять одни байт информации, то можно будет уже перейти на пакеты.
  4. Благодарю за ответ! Я тут уже нашел пару вариантов реализации декодера для других ядер. Попробую их адаптировать, либо допилю свой. Наверное, больше меня волнует алгоритм с уклоном на ассемблер. А таки да, обращусь к тем ребятам, спасибо)
  5. Note: Ядра работают на частотах 200 МГц (такт 5 нс или меня обманули). Нашел ошибку в коде: переход на метки SET01 и CLR10 происходит в тот момент, когда в линии меняется фронт (с 0 в 1 или с 1 в 0) и если длительность присутствия одного уровня превышает половину периода. Как только условия соблюдены, у нас происходит ещё 9 тактов - это доп. смещение, которое ломает общий алгоритм. Возможно, правильнее использовать команды: WBS и WBC ( ждать, пока не придет 1, и 0 соответственно).
  6. Введение: Взял себе плату BeagleBone с процессором AM335x. У него на борту есть два реал-тайм ядра PRU (PRU0 и PRU1). Хочу через GPIO научить их обмениваться данными. Данный кодируются в манчестерском коде. У прушек свой компилятор - pasm. Проблема: Понятно, что алгоритм передачи написать не так сложно: сначала переводит байт в МК(манчестерский код), потом передаем бит за битом. Проблема в двух вещах: приеме и синхронизации. Бог с ней, с синхронизацией, её я домучаю позже. У меня замылились глаза на приеме. Вот код: 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 // возврат на прослушку Приходит конечно не то, что нужно. Возможно я написал неправильный алгоритм посылки, но вроде проверял осцилографом (но там он показывает выборку в случайном месте). Глоссарии: SBCO - команда записи данных в память QBBS, QBBC - команды перехода на метку, если 1 или 0 QBNE - переход на метку, пока не ровно. QBGE - переход на метку, если больше.
×
×
  • Создать...