nabbla (nabbla1) wrote,
nabbla
nabbla1

Category:

Аффинный алгоритм+информационный обмен, начало отладки

Каждый раз волнительно возвращаться к "железу" после долгого перерыва. У меня оно ещё и от "повербанки" работало, которая мне прям очень понадобилась на прошлой неделе, поэтому её оттуда вытаскивал, а сегодня припаивал на место. Ну ничего, признаки жизни подало - экранчик засветился, выдал там "ЛОИ ВИПС" ещё по старой прошивке, нормально.

Потом традиционно квартус "потерял" USB Blaster, а когда я его выткнул и заново воткнул - намертво завис. Ну это нормальная история, квартус штука глючная, к сожалению.

Наконец, "залил" новую прошивку, не во Flash-конфигуратор, просто в саму ПЛИС, т.е до отключения питания. Попробовал отправить что-то осмысленное:



И да, что-то осмысленное получил в ответ!


Сообщение "начинаем работу" отправляется старой прошивкой, при подаче питания. Когда загружаешь в ПЛИС новую конфигурацию с компьютера, она "молчит". Даже этот несчастный "нолик" не посылает в самом начале. То был глюк QuatCore: он в начале работы успевает по ошибке выдать команду 00 00, то означает "OUT 0", причём устройством по умолчанию оказывается UART. Квартус как-то "спустя рукава" относится к инициализации регистров: иногда инициализирует как просили, а иногда запихает нули и ни слова не скажет по этому поводу!

Первый наш запрос, 0x0137. Чтобы понять, что это, меняем местами старший и младший байт, выходит 0x3701. И выписываем в двоичной форме, отделяя первые 5 бит, затем 1, и ещё 2 раза по 5 бит:
0x3701 = 0011 0111 0000 0001 = 00110 1 11000 00001 = (6, 1, 24, 1)

Адрес 6 (это наш), передача от ОУ к КШ, т.е мы запросили данные. Подадрес 24, "выдать телеметрию". Количество слов: 1.

Нам пришло ответное слово 0x0030, т.е "всё в порядке" и одно слово данных, 0x0000. Это по сути CRC от пустого сообщения, 0.

Следующий запрос, 0x0037 - снова запрос телеметрии, только на этот раз целых 32 слова (00000 в поле количества слов интерпретируется именно так). Первым пришёл заголовок массива, затем сплошные нули (мы пока ничего шибко умного в память не занесли в этом месте), и под конец CRC от сообщения.

Для выдачи этого сообщения процессор не требовался в принципе, зато мы увидели нормальную работу через DMA!

И дальше мне хочется проверить информационный обмен более обстоятельно. Начнём с передачи данных с компьютера на приборчик (КШ-ОУ):


Сейчас мой "протокольный контроллер" так устроен, что сообщение длиной в 1 слово данных забракует ЗАВЕДОМО, т.к он сравнит это единственное слово с заголовком массива, но под конец ещё и проверит совпадение CRC, поэтому уж или одна проверка провалится, или другая!

Поэтому шлю 2 слова данных: заголовок + CRC. Для некорректных подадресов беру в качестве заголовка то значение, за которым протокольный контроллер "полезет в память", чтобы убедиться: эти сообщения были забракованы не потому, что неправильный заголовок или неправильный CRC, а именно потому что по этим подадресам либо запрещено работать В ЦЕЛОМ, либо запрещено принимать данные (так сказать Read-Only). Всего 2 слова взял, чтобы окончательно не сбрендить, пока всё это буду вводить. Что ж, полный успех:


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

Теперь будем запрашивать информацию с прибора (ОУ-КШ):


А ну-ка...


Ну шикарно же! Из 30 подадресов (команды управления пока не рассматриваем), по правильным 5 получили ответное слово + 32 слова данных (первое - заголовок массива, последнее - CRC, посередине данные). По неправильным (в принципе неправильным либо тем, что только для записи) получили только ответное слово с признаком "ошибка в сообщении".

Пока слова данных преимущественно нулевые, потому как мы никаких значений "по умолчанию" в память и не заносили. Хотя "сырые данные для соседа" мы-таки предоставили зачем-то, всё те же 4 обнаруженные точки, на которых тренировались! То есть, сначала заголовок массива, потом "циклический счётчик", равный -1 ("это левое сообщение, которое лежало по умолчанию в оперативной памяти"), потом количество найденных точек, 4 (как водится, нужно старший и младший байт местами переставлять), ну и затем координаты этих точек. Для всех остальных координаты приведены 0 и -32768.

Целевая информация пока что нулевая вообще вся! Это означает, что процессор пока что алгоритм не выполнил. Так оно и должно быть по идее, он должен застрять на команде "IN". И на выходе RTC должно по умолчанию остаться нулевое значение, поэтому метка времени также нулевая.

Ну и пора, наконец, послать команду управления "Синхронизация (с СД)"!

Дадим её индивидуально нашему прибору, т.е адрес 6, а не широковещательный 31. Подадрес 0, количество СД/код КУ 17, т.е 100012. Получается командное слово 0x3011, но в терминале надо ввести 0x1130, Endianness пресловутый... И ещё слово данных одно нужно присовокупить.

Попробуем:


Что-то определённо происходит!

Ответное слово 0x3400 ("ошибка в сообщении") на команду управления - это ожидаемо. Я пока не стал усложнять логику проверки сообщений, поэтому и в этом единственном слове пытается одновременно сравнить его с заголовком массива из памяти, но в то же самое время проверить CRC, т.к это слово одновременно и первое, и последнее, и какую-то проверку он не проходит. Так-то это должна быть групповая команда, на которую отвечать не надо, и специально всех опрашивать "вы её получили?" тоже никто не собирается.

Далее я запрашиваю целевую информацию - и получаю отнюдь не нули, как в прошлый раз! Чтобы разобраться в данных, возьму "раскладку" оперативной памяти из ассемблерного файла:

;подадрес 0x06 (адреса 0xC0..0xDF) - целевая информация
ORG	0xC0
DA_header	dw	0x3C3C	;заголовок массива
DA_flags	dw	?		;всевозможные флажки
;0:1 - Mode (00-поиск, 01-захват, 10-сопровождение, 11-не используется)
;2   - Stereo (1-стереорежим активен)
;3   - DistOK, признак достоверности выдаваемой дистанции, активных углов и крена, (1-достоверны)
;4   - VelOK, признак достоверности выдаваемой скорости, (1-достоверна)
;5   - QuatOK, признак достоверности выдаваемого кватерниона (1-кватернион достоверен)
;6   - CovarN, какая часть ковариационной матрицы шума измерений передаётся в этом сообщении.
;              (0 - первые 11 значений, 1 - последнии 10 значений)
;7:15 - reserved (не используются)
DA_PRF_NO	dw	0xFFFF	;метка времени (правильные значения от 0 до 0xC800, сейчас у нас "вне времени")
DA_vel		Int16	?		;скорость сближения, диапазон -2..+2 м/с

DA_Vexp:	;при UseCartes=1: 
DA_dist		dw	?		;При UseCartes=0 (по умолчанию): дальность, диапазон 0..512 метра 
DA_Vx:	;При UseCartes=1:
DA_yaw		Int16	?		;При UseCartes=0 (по умолчанию): угол активного курса, диапазон -4..+4 радиан
DA_Vy:	;При UseCartes=1:
DA_pitch	Int16	?		;При UseCartes=0 (по умолчанию): угол активного тангажа, диапазон -4..+4 радиан
DA_Vz:	;При UseCartes=1:
DA_roll		Int16	?		;При UseCartes=0 (по умолчанию): угол взаимного крена, диапазон -4..+4 радиан
DA_Quat0	Int16	?	;кватернион взаимной ориентации, скалярная часть
DA_QuatX	Int16	?	;диапазон -1..+1 для каждой компоненты
DA_QuatY	Int16	?
DA_QuatZ	Int16	?


Первым ожидаемо приходит ответное слово, 0x3000, т.е "всё в порядке".
Затем заголовок массива, 0x3C3C.
Флаги 0x0001, что означает "режим захвата", достоверность данных отсутствует (она появится при переходе на режим сопровождения), стереорежим отключён.

Это уже поработал процессор - ранее тут лежал "нолик". Мало того, был выполнен один из двух алгоритмов захвата.

Далее идёт метка времени. Заметим, что в памяти изначально лежало 0xFFFF, только вот ни первый раз, ни сейчас оно на выход не попало - взамен мы получили метку из часов реального времени. Когда мы отправили нулевое слово данных для синхронизации, получили нулевую метку времени. Цена младшего разряда составляет 195,3125 мкс (100 мс / 512). Получается, все вычисления заняли меньше времени. Возможно, с обнулением делителя частоты я ошибся малость, а может, так оно и есть, после всех улучшений алгоритма и процессора. Когда я испытывал новое АЛУ, целиком алгоритм завершился за 208 микросекунд. Правда, потом перемножение матриц надо было переделать, чтобы оно работало и на дальней дистанции (3х4 на 4х2), так и на ближней (3х6 на 6х2). Но чего-то не припомню, чтобы там случилось ускорение - не с чего! В общем, пока загадка.

Во второй раз я "наобум" послал слово данных 0x8000, напрочь позабыв, что по нашему протоколу там на самом деле должны быть целые значения от 0 до 99. А потому в RTC в действительности идут только младшие 7 бит, а старшие "висят в воздухе". Поэтому неудивительно, что и здесь метка времени оказалась нулевой.

В третий раз я послал слово данных 0x0050 = 8010, что должно было означать "8 секунд" (цена младшего разряда в слове данных: 100 мс). В итоге получил метку времени 0xA000. Опять же, по протоколу информационного обмена, младшие 7 бит должны были "перекочевать" в старшие 7 бит, чтобы можно было указать сколько-нибудь точно, когда мы получили данные. ВСЁ ВЕРНО! Вся эпопея с часами реального времени, их синхронизацией и фиксированием конкретного момента, оно работает. Разве что насчёт 195 мкс не уверен, самый первый импульс мог удлиниться из-за кривого сброса.

Следующее слово: скорость сближения. Пока мы вообще этим не занимались, поэтому там гордо сидит нолик, всё верно.

Далее, идёт вектор параллельного переноса, пока что в декартовом виде (в дальнейшем можно будет выбрать и сферические координаты). Первой идёт "общая экспонента", число 9. ДА: поскольку нам нужно мерять дальности от 0,5 до 300 метров, было решено ввести "смещение -1" для экспоненты, т.е 0 означает 20-1 = 0,5 метра, на которые домножаются "мантиссы". А значит, число 9 даёт дальность в диапазоне от 256 до 512 метров, всё верно.

Следующее слово: мантисса для координаты X ("дальность"), 0x9591 = 38289. В формате UQ15.1 это означает 1,168488. Помножим на 256 и получаем 299,13 метра. В модели было 300 метров, но внесены всевозможные "мешающие факторы". Да, как-то так и выходило.

Следующее слово: мантисса для координаты Y ("смещение по горизонтали"), 0x0D95 = 3477. Это отличается от посчитанного в прошлый раз на симуляции. Число 0x9591 там было, а вот смещения совсем другие. Надо проверить исходные данные, может где-то накосячил с матрицами. Та же история с координатой Z ("смещение по вертикали"), 0x80DC = -32548, это вообще какая-то жесть, почти "на упоры встали".

Кватернион тоже чего-то кривоват: скалярная (действительная) часть 0x7FE7 = 32743, что в формате Q1.15 означает 0,999237. Остальные компоненты нулевые. Они и на симуляции были все нулевые, но вот нормировалось оно насколько возможно, то скалярной части 0x7FFF = 32767 = 1 - 2-15. Так что и здесь какой-то криминал творится...

Далее у нас идёт ковариационная матрица шума измерений, но пока что это пространство использовалось для промежуточных вычислений. Имеем значения 0x0002, 0x0002, 0x0001, 0x01B7, 0x002A и 0xFE7E. Пока "без комментариев".

И наконец, дальше вообще сплошные нули и напоследок CRC.


Очень неплохо! Как будто бы информационный обмен работает правильно, память они делят между собой как надо. Дальность находит правильно, метку времени вставляет, правда, в синхронизации мог ещё накосячить немного. Кватернион до конца не отнормировался, и смещения криво посчитались. Пока что думаю, что с программой накосячил, когда память переразмечал, но первое впечатление бывает ошибочным.

Завтра (в смысле, сегодня, после сна) продолжим...
Tags: ПЛИС, программки, работа, странные девайсы
Subscribe

Recent Posts from This Journal

  • Тестируем atan1 на QuatCore

    Пора уже перебираться на "железо" потихоньку. Решил начать с самого первого алгоритма, поскольку он уже был написан на ассемблере. В программу внёс…

  • Формулы приведения, что б их... (и atan на ТРЁХ умножениях)

    Формулу арктангенса на 4 умножениях ещё немножко оптимизировал с помощью алгоритма Ремеза: Ошибка уменьшилась с 4,9 до 4,65 угловой секунды, и…

  • Алгоритм Ремеза в экселе

    Вот и до него руки дошли, причина станет ясна в следующем посте. Изучать чужие библиотеки было лениво (в том же BOOSTе сам чёрт ногу сломит), писать…

  • Post a new comment

    Error

    Anonymous comments are disabled in this journal

    default userpic

    Your IP address will be recorded 

  • 0 comments