QuatCore

Так ли страшно 0,99969 вместо 1?

В размышлениях о DMA, о возможных последствиях "смешивания" старых и новых значений при выдаче целевой информации, опять выполз вопрос:

насколько это плохо/некрасиво, если мы вместо кватерниона малого поворота 1+(φx/2)i+(φy/2)j+(φz/2)k возьмём 0,999969+(φx/2)i+(φy/2)j+(φz/2)k? То есть, вместо 1 будет 1-2-15, максимальное число, которое можно представить в формате Q1.15 (в целых числах это 32767).

И внезапно прихожу к выводу: Ещё лучше взять 0,9999084 (в целых числах 32765)

Collapse )


Убедил? :)

Poll #2112344 Кватернион малого поворота

Какое приближение вы бы взяли?

1+(a/2)i+(b/2)j+(c/2)k
1(33.3%)
-1-(a/2)i-(b/2)j-(c/2)k
0(0.0%)
32767/32768+(a/2)i+(b/2)j+(c/2)k
2(66.7%)
32765/32768+(a/2)i+(b/2)j+(c/2)k
0(0.0%)


PS. Впрочем, почти завершив это "исследование", я вспомнил, почему в своё время так настаивал на -1 вместо 0,99969, но это заслуживает ещё одной небольшой главки в "ликбезе по кватернионам"...
doomguy

Как продлить агонию велотрансмиссии на 1500+ км

Последний раз о велосипедных делах отчитывался в середине мая, когда прошёл год "велопробегом по коронавирусу".

Уже тогда я "жаловался", что кассета (набор задних звёздочек) основательно изношена, работают только передачи 1,2,7,8, т.е "края", которыми я толком не пользовался. На той же неделе я уже купил себе новую трансмиссию: кассету, 3 цепи и даже, на всякий случай, большую переднюю звёздочку, после чего "с чистой совестью" (зная, что если что-то пойдёт не так - поставлю всё новенькое) немножко доработал старую кассету напильником, благодаря чему все скорости худо-бедно работают ещё спустя 1500 км пробега! Если точнее, я на пути домой сегодня должен "отметить" 1600 км, на старой кассете (пробег OVER 9000 км) и старой цепи (на троих пробег тот же), при том что и то и другое "бюджетные" Shimano HG40.

IMG20210518120208.jpg

Расскажу про этот способ, его достоинства и недостатки, и ещё об эпопее с фарами для динамки, всякими ловушками на дорогах, ну и бонусная Марта.

Collapse )
QuatCore

DMA для QuatCore

Вот фрагмент схемы нашего "процессорного ядра" QuatCore:


Справа сверху "притаилась" оперативная память. На той ПЛИС, что у меня есть сейчас (5576ХС4Т) и той, что хотел бы применить в лётном изделии (5576ХС6Т) полноценной двухпортовой памяти нет. Максимум - можно одновременно осуществлять чтение на один адрес и запись на другой адрес, при условии, что адреса не совпадают (если совпадают, то на выход пойдёт только что записанное значение, конкретно в этих ПЛИС, если они ведут себя аналогично Flex10k до последних мелочей). Но я пока и эту возможность не использовал из-за своей исключительной жадности: это бы потребовало два отдельных формирователя эффективного адреса, а они довольно толстые (выбрать базовый регистр, выбрать первый индексный, второй индексный регистры - и всё сложить).

Впрочем, эта жадность могла мне выйти боком: один формирователь, что у меня, должен "работать за двоих", т.е на его входе стоит мультиплексор, выбирающий, из какой половины команды взять биты, из SrcAddr или из DestAddr.

Сейчас адрес используется ровно один. Кроме него, на оперативную память поступают 16 бит для записи, напрямую из шины данных, сигнал WREN (WRite ENable), а выход отправляется в модуль QuatCoreMem, где стоит мультиплексор, срабатывающий на "квадратные скобки" в мнемонике команды. Если они стоят - значит нам нужно значение из памяти, коммутируем его. Если нет - значение одного из регистров (X,Y,Z,SP), выдадим его.

Теперь бы как-нибудь к этой же памяти подключить "провода" D,Q, MemWrReq, MemRdReq и MemReady из протокольного контроллера МКО, желательно малой кровью... Обеспечить ему пресловутый Прямой Доступ к Памяти, или Direct Memory Access (DMA)...

Collapse )

Схема "верхнего уровня":


Барабанная дробь... Синтезируется в 1704 ЛЭ (перед фиттером), 1732 ЛЭ (после фиттера). Timing Analyzer: все требования выполнены, предельная частота 26,04 МГц!

Как-то слишком просто... Я ожидал, что будет эдак 20 МГц, и ещё неделю-другую надо будет "конвейер перебирать", чтобы вернуться к родным 25 МГц. Какая-то жуткая подлянка затаилась и ждёт своего часу.

Ну ладно, с завтрашнего дня начинаю отладку. Разрозненные части, наконец-то, собираются в целое.
QuatCore

"МКО через UART" в железе - 2

Продолжим проверять этот модулёк.


Collapse )

Выглядит неплохо! Есть, что улучшить:
- пусть и на индивидуальную команду "Синхронизация (с СД)" отвечает правильно, подтверждая, что команда пришла,
- если "пообещать" длинное сообщение (например, 32 слова), но не передать его целиком - контроллер будет до посинения ждать, пока нужное число слов данных будет передано, здесь никакого таймаута пока не предусмотрено. Когда "ручками" с ним общаешься - неприятно, что-то немного не то вбил - и вдруг ни ответа ни привета, и поди разберись, что с ним. На деле, не так уж это и страшно, пошлёшь запрос повторно, он "доберёт" сколько надо слов, уйдёт в sIdle по несовпадению CRC, и дело с концом. Но вообще с таймаутом правильнее, ГОСТ предписывает проверять временнЫе параметры и при отступлении от норм тихо ругаться.
- у меня были предусмотрены команды "дамп памяти" и "передать изображение", там маленькими кусочками передаётся содержимое памяти, "внутренней" и "внешней" соответственно. Можно было бы это дело на контроллер "взвалить", чтоб делал без участия процессора. Но пока было лень...

А сейчас, пожалуй, надо взяться за DMA.
QuatCore

"МКО через UART" в железе

Долго мучали эту штуковину на симуляции, пора уже в макет это прошить и посмотреть, как оно себя поведёт.

Оставлю "основную схему" (процессор, SPI, контроллер ЖК-экранчика, видеообработчик, детектор и селектор синхроимпульсов), но "отниму" у неё RS485 и "отдам" его новой схеме, этому самому "МКО". Позже они должны будут получить общий доступ к памяти, но давайте сначала обособленно его проверим.

Окинем прощальным взором львиную долю "схемы" TopLevel:


Collapse )



Что-то есть. Первое сообщение "начинаем работу" - это от старой прошивки. При подаче питания срабатывает она, потом я по JTAG "запихиваю" в ПЛИС текущий проект. Это показывает, что по крайней мере "железо" рабочее.

Далее даю командное слово: адрес 6, подадрес 110002, передача ОУ-КШ, передать одно слово данных. Байты переставлены местами, потому как у меня приёмник и передатчик передают по 16 бит за раз, от младшего бита к старшему, а на компьютере передаётся по байту, от младшего бита к старшему, из-за чего "endian" меняется.

В ответ получаю ответное слово 0x3000 (адрес 6, все флажки сброшены, "всё в порядке") и одно слово данных: 0000. Да: по нашей логике последнее слово это всегда CRC, даже если оно по совместительству первое :) Вот это оно и есть, CRC от пустого сообщения!

Потом посылаю командные слова на "чужой" адрес 0, и никакого ответа не получаю. Всё верно.

В следующий раз заказал по тому же адресу и подадресу ("телеметрия") 2 слова данных - и получил заголовок массива телеметрии, 0xFF00, а затем CRC от него. Тот же CRC можно получить на crccalc.com, если ввести 00FF, и в строке CRC16/KERMIT в результате 0x0F78 переставить местами байты.

Потом ещё попробовал 3 слова данных, 4, 5, 6, 7. Результат: ответное слово, за ним заголовок массива, за ним сплошные нули (ну да, здесь я в память никаких "интересных" значений не клал), и CRC. Во всех случаях корректный.

И ещё "заказал" 0 слов данных, только этот ноль в МКО (ГОСТ Р 52070-2003, Mil-Std 1553) интерпретируется как 32 слова, что нужно было также прописать в коде. Что ж, эта часть также работает, выдаётся ответное слово и ещё 32 слова данных, последнее из которых: CRC.

Продолжение следует...
QuatCore

"Ошибка на единицу" при передаче CRC

В прошлый раз обнаружили нехорошую вещь: при передаче данных от нашего устройства, CRC начинает работать одним словом раньше, чем надо, и результат своей работы отсылает одним словом раньше.

Пора уже это исправить, чего-то задолбался я немного.

Collapse )
Действительно обошлись "малой кровью", не добавив ни одного ЛЭ.

Вот, кажется, и всё, протокол информационного обмена исполнен в полном объёме, на "жёсткой логике", без обращения к процессору.

Осталось всё это "в железе" посмотреть, заодно написав "программу рабочего места". Потом, если всё нормально, написать примитивный DMA. Дальше ожидаю раунд борьбы с фиттером, который может завалить трассировку всего проекта целиком, и второй раунд, когда в кои-то веки придётся все части программы свести в единое целое, так что и ROM и RAM подрастут, и ширина адресных шин вместе с ними.

Тяжело идёт, и уже как-то "через силу". Кажется, что всё творческое уже позади, а сейчас надо просто стиснуть зубы и довести хреновину до кондиции...
QuatCore

"МКО" с CRC, работа над ошибками

В кои-то веки всё соединили вместе, начали тестировать и обнаружили две проблемы:

- не обеспечивается паузы между принятым сообщением и передаваемым. Доходит до того, что отвечать начинаем ещё до того, как передатчик окончит стоповый бит!
- нарушена логика обнаружения ошибки в сообщении: ещё во время приёма командного слова "зажигается" CRCerror и не "гаснет" вовремя.

Прежде чем двигаться дальше, надо это дело исправить, по возможности малой кровью.

Collapse )

Ладно, эти две проблемы устранили, потом обнаружили ещё одну, при передаче данных (CRC сбивается на 1 слово), её сейчас тоже обмозгуем. Должно быть решение, простое до безобразия, главное, его найти...
QuatCore

Тестируем "МКО" с CRC

Вроде как написали самую полную версию "протокольного контроллера МКО" (хоть и вместо настоящего МКО он пока использует UART), а ещё полудуплексный 16-битный приёмопередатчик с модулем CRC. Пора бы посмотреть, что они между собой дружат.

Для начала на симуляции. Но для этого нужно в ПЛИС "подружить" два приёмопередатчика между собой, чтобы они думали, что посередине линия передачи RS485. Т.е с одной стороны в этот модулёк будут поступать провода rxd (выход данных с приёмника), txd (вход данных на передатчик) и RW (0, если нужно принимать данные, 1, если нужно передавать). И с другой стороны то же самое. Причём rxd - двунаправленная линия, при RW=1 приёмник должен перевести свой выход на rxd в Z-состояние (высокое выходное сопротивление).

Как-то так:
module RS485dummyLine (input RW0, txd0, inout rxd0,
			input RW1, txd1, inout rxd1);
					
assign rxd0 = RW0? 1'bz : txd1;
assign rxd1 = RW1? 1'bz : txd0;					
									
endmodule


Фактически, передатчик одного модуля соединяется с приёмником соседнего (и наоборот), но приёмник "слепнет" во время работы собственного передатчика, тем самым моделируя полудуплекс.

И ещё "нарисуем" схему всего модуля информационного обмена (протокольный контроллер + память + часы реального времени + приёмопередатчик + CRC) в сборе:


Большинство выводов этой схемы - отладочные, посмотреть "что там творится". А по сути, "наружу" выходят:
- txd, rxd и RW - интерфейс с "физическим уровнем" приёмопередатчика,
- Mark - сигнал скорее всего от процессора (назначим ему отдельный адрес и декодер), что половина экспозиции кадра завершена. Устанавливает на выход часов реального времени метку, когда это произошло.

Весь остальной обмен должен будет идти через "общую" память, это сделаем, как только хреновину отладим. Хотя, также в отладочных целях, я наверное введу ещё остановку процессора в ожидании прихода "Синхронизация (с СД)", не готов я к тому, что процессор будет жить своей жизнью, перемалывая по 25 кадров в секунду, а мы будем получать данные "с какого повезёт".

Синтезируется такая схема в 240 ЛЭ, предельная частота 52,91 МГц. Злой рок: первое число неумолимо растёт, второе столь же неумолимо падает!

Впрочем, ещё одну вещь мы позабыли: контроллеру нужно как-то отличать между собой слова данных и командные слова! Он ожидает, что ему это сообщат прямым текстом, по проводу RXisData, руководствуясь полярностью синхроимпульса в МКО (Mil-Std 1553). Но в UART у нас нет полярности синхроимпульса, надо придумать костыль.

Collapse )

С нахрапу "прикрутить" CRC не получилось, немножко не рассчитал. И ещё всплыл старый должок с обеспечением паузы между приёмом и передачей ответного слова. Что ж, завтра будем исправлять.
slow loris

Dragostea din tei

Есть такая молдавская группа O-Zone, со страшно популярной песней Dragostea din tei, более известной как Numa Numa:



Не так давно эту песню стали использовать в рекламе одного популярного интернет-магазина. Догадаетесь с одного раза, что же за магазин такой взял композицию от O-Zone?

Collapse )
Sidious

Физика жаркой электрички

Ехал сегодня на электричке от платформы Яуза до Сергиев Посада, практически со всеми остановками. К счастью, под вечер было хоть чуточку прохладнее, чем посреди дня, но в тамбуре (с великом) всё равно жарища.

Хорошо ещё, половинка двери в салон может фиксироваться в открытом положении:
IMG20210716211509.jpg

И ещё двери между вагонами раскрыл
IMG20210716212330.jpg

Как видно, в обоих вагонах практически все форточки открыты настежь. Тем не менее, пока электричка едет с постоянной скоростью (даже если она высока), в тамбуре ни ветерка.

Зато, когда электричка разгоняется с характерным жужжанием, или когда тормозит, начинается очень приличный сквозняк! Совершенно чётко: при разгоне начинает дуть от головы в хвост состава, а при торможении - из хвоста в голову!

Физика процесса мне не очень ясна...

Collapse )

Странно только, что я никогда раньше не замечал так чётко возникающего ветерка. Может, ровно сейчас случайно вышли самые подходящие условия: безветренная погода и глухо закрытый сегмент (два тамбура), разделяющий собой два вагона с открытыми форточками. Не знаю.

В общем, если нечем будет заняться в общественном транспорте - присоединяйтесь к весёлым экспериментам.