В продолжение предыдущей статьи об SDR радиоприемнике на основе платы Марсоход2.
Принцип SDR радио — как можно больше обработки производить в программном обеспечении. По этому собственно оно так и называется Software Defined Radio. Устройство приема делает какую-то начальную обработку и передает сырые данные в компьютер, где специальная программа знает, что с ними делать, как декодировать и как воспроизводить.
В нашем SDR радио прием и первичная обработка происходят в плате Марсоход2. Однако потом все накопленные данные нужно передать программе SDR радио. Я использую программу HDSDR из http://www.hdsdr.de/index.html
Чтобы программа HDSDR могла взаимодействовать с нашей платой нужно написать специальную DLL, которая будет экспортировать функции согласно спецификации Winrad API, http://www.winrad.org/bin/Winrad_Extio.pdf. Чтобы понять какие данные нужно передавать, как передавать, как часто передавать — придется изучить эту спецификацию Winrad да и вообще нужно основательно погрузиться в тему цифрового радио.
В своей работе я значительно опирался на статью на хабре "Простой SDR приёмник на ПЛИС".
Из изученного стало понятно, что:
- данные пересылаемые по направлению от HDSDR к плате редки и малы — это всего лишь целое число, определяющее частоту тюнера. Может быть 32-х битным числом.
- данные от платы к компьютеру, к программе HDSDR – это поток, например, 50000 выборок в секунду. Каждая выборка — это пара чисел, так называемые I / Q каналы. Числа могут быть целые знаковые 16-ти битные, 24-х битные, 32-х битные или даже 32-х битные числа с плавающей точкой.
Есть несколько способов передавать данные из платы Марсоход2 в компьютер:
- поставить Ethernet шилд и передавать данные по сети, хоть UDP пакетами
- передавать через последовательный порт, на плате стоит USB-FTDI чип и у него скорость последовательного порта до 12 Мбит/сек. Вероятно этого хватит?
- можно еще передавать через тот же USB-FTDI в режиме MPSSE, тогда скорость передачи будет еще больше.
Из всех способов передачи самый простой — это последовательный порт. Давайте попробуем посчитать, хватит ли его пропускной способности.
Одна из проблем последовательного порта — в нем байты идут один за другим единым потоком. Если передавать пары выборок, например, поочередно, то как на стороне приема определить где какая выборка, где четная и где нечетная? Или еще вопрос: если передается, например, 4-х байтное слово, то как выбрать из потока именно нужные четыре байта?
Один из способов решения этой проблемы — организация последовательных данных в пакеты. Предлагаю такой способ передачи, как на рисунке выше, в самом начале статьи.
Данные передаются в обе стороны в виде 5-ти байтных пакетов. Байт с установленным в единицу старшим битом является заголовком пакета. Он идет в потоке первым, потом идут четыре байта данных пакета. Байты данных в пакете имеют старшим битом ноль. Однако, чтобы не терять эти старшие биты они будут передаваться в заголовке, в младшей тетраде. Таким образом я смогу закодировать 5-ю байтами четыре, и при этом на стороне приема смогу легко синхронизироваться по пакету, смогу отделять целые 32-х битные числа из потока данных из последовательного порта.
При последовательной передаче за один байт уходят как минимум 10 бит: старт бит (ноль), восемь бит данных, стоп бит (единица). Ну пусть 12 бит, добавлю еще парочку стоп битов на всякий случай. 12 бит * 5 байт * 2 канала ( пары I / Q) * 50000 выборок/секунду = 6000000 бит в секунду требуется пропускной способности. А последовательный порт FTDI на плате Марсоход2 может 12Мбит/сек. То есть вполне все успевает передаваться с двукратным запасом.
Значит так и делаем.
Итак.
Передача частоты для тюнера в плату Марсоход2 делается одним 5ти байтным пакетом и при этом передается 32-х битное число.
Передача из платы Марсоход2 в библиотеку DLL для программы HDSDR выполнятся похожим образом, двумя 5-ти байтными пакетами. Первый пакет несет 32-х битное число канала I, второй пакет несет 32-х битное число канала Q. Вот только у второго пакета пожалуй не буду передавать «1» в старшем бите заголовка — это чтобы отличать каналы.
Нужно заметить, что в статье на хабрахабре «Простой SDR приемник на ПЛИС» ведется передача только 16-ти битных данных. На мой взгляд это не очень хорошо, так как при этом существенно обрезается сигнал — нужно передавать слова с выходов FIR фильтров, а там выходы многоразрядные. Как многоразрядное число, скажем 40-50 бит впихнуть в 16-ти разрядное не очень понятно. Думаю позже напишу еще про эту проблему. Думаю, что передача 32-х битных чисел гораздо лучше, чем 16-ти битных.
Подробнее...