Не так давно импульсивно купил симпатичный SDR трансивер для детей и юношества – ADALM PLUTO. К моему сожалению он работает с кучей софта под LINUX, а вот мой любимый HDSDR его не поддерживает. Недолго думая стал разбираться с этой проблемой и вот что из этого получилось:

Analog Devices адресует свой PLUTO студентам. Весь софт для PLUTO открытый и находится в свободном доступе. На сайте компании есть страничка, на которой можно найти почти всю необходимую информацию о функционировании PLUTO. Большая часть софта написана под Linux и студентам рекомендуют пользоваться GNU Radio, MATLAB и т.п.

У меня же чисто радиолюбительский интерес к PLUTO. SDR с диапазоном от 70МГц до 6ГГц (после раскрытия) всего за 150 американских денег — это чудо. Сколько всяких экспериментов можно провести! Посмотрите как много там всего интегрировано:



По всей видимости AD считает, что радиолюбители сами должны писать драйвера для популярных программ, поэтому до недавнего времени даже SDR# не поддерживался. Но меня SDR# не устраивает, поскольку мне нужна хорошая поддержка CAT в программе для синхронизации частоты с трансивером. HDSDR же хочется попробовать использовать в качестве панорамного приёмника, подключив его к первой промежуточной частоте трансивера. Итак, выход один – интегрировать HDSDR и PLUTO самому.

С помощью гугла я довольно быстро выяснил, что для решения моей задачи нужно создать специальную ExtIO_.dll библиотеку в формате Winrad. Эта библиотека служит программным мостом между HDSDR и желаемым SDR приёмником. К счастью, интерфейс библиотеки неплохо документирован. Кроме того, на github довольно много готовых реализаций библиотек для различных приёмников: RTL_SDR, LimeSDR и пр. Было где подсмотреть как надо писать код. Сама же библиотека совсем олдскульная, никаких новых технологий, чистый C89, как писали лет 20 лет назад. По крайней мере не надо учить новый язык программирования, что уже вселяло надежду на успех.

По сути в ExtIO_.dll нужно реализовать с десяток функций, которые позволяют инициализировать оборудование SDR, запускать и останавливать приём сигнала, сохранять и восстанавливать заданные настройки. Для меня самым непонятным моментом явился формат обмена потоковыми данными между приёмником и HDSDR, но об этом чуть ниже.

Теперь возник вопрос как управлять PLUTO программным способом. На самом деле есть несколько вариантов управления. Я нашёл минимум два: напрямую чипом через библиотеку libad9361.dll, либо через библиотеку IIO. Последний вариант мне показался более простым и хорошо описанным, поэтому остановился на нём. В этой библиотеке все настройки оборудования доступны в виде какого-то подобия XML структуры, обращение к отдельному элементу идёт по текстовому названию свойства, что довольно удобно. Подробнее описание библиотеки можно посмотреть здесь. Огромным преимуществом библиотеки является то, что она поставляется с утилитами командной строки, с помощью которых всегда можно быстро поменять нужную настройку приёмника. Таким образом, не нужно реализовывать все настройки SDR в интерфейсе HDSDR, можно обойтись необходимым минимумом. А загрузку какого-нибудь экзотического FIR фильтра можно сделать из командной строки, если вообще когда-нибудь такая необходимость появится. Потоки данных в IIO:



Программно научиться управлять PLUTO из HDSDR получилось довольно быстро и просто. Несколько сложнее было получить удовлетворительный результат по передаче потоковых данных, тем более ранее опыта работы с SDR у меня не было. Тут надо понимать, что данные поступают из SDR приёмника в виде потока I/Q/I/Q … I /Q сэмплов. Каждый сэмпл это без знаковое 16 битное целое число, из которого только 12 младших бит имеют значение. В то же время у HDSDR есть с десяток вариантов принимаемых потоков данных. Какой из них удобнее и лучше не совсем мне понятно. В результате я остановился на варианте, который в ExtIO называется exthwUSBdata16, т.е. фактически один в один как отдаёт данные библиотека IIO.
Следующей проблемой стала передача данных между буферами приёма IIO и HDSDR. Последний принимает данные блоками, кратными 512 байтам, а IIO в таком формате выдавать данные не может. Пришлось сделать промежуточный буфер и передавать поток через него. Код передачи показан ниже.

DWORD WINAPI GeneratorThreadProc( __in  LPVOID lpParameter )
{
	int16_t	iqbuf[EXT_BLOCKLEN * 2];
	ssize_t	nbytes_rx;
	char	*p_dat, *p_end;
	ptrdiff_t	p_inc;

	int	iqcnt = 0; // pointer to sample in iqbuf
	
	while ( !gbExitThread )
	{
		nbytes_rx = iio_buffer_refill(rxbuf);
		p_inc = iio_buffer_step(rxbuf);
		p_end = (char *)iio_buffer_end(rxbuf);
		for (p_dat = (char *)iio_buffer_first(rxbuf, rx0_i); p_dat < p_end; p_dat += p_inc) {

			iqbuf[iqcnt++] = ((int16_t*)p_dat)[0];
			iqbuf[iqcnt++] = ((int16_t*)p_dat)[1];

			if (iqcnt == EXT_BLOCKLEN * 2) { // buffer full
				iqcnt = 0;
				pfnCallback(EXT_BLOCKLEN, 0, 0.0F, &iqbuf[0]);
			}
		}
	}
	gbExitThread = false;
	gbThreadRunning = false;
	return 0;
}

Используя указанный цикл удалось достичь передачи потока в 4 MS/s, выше этого значения данные не успевают передаваться и приём сигнала идёт с заиканиями, хотя железо вроде способно отдавать и 20 MS/s и даже выше. Увеличил приоритет потока, в котором крутится цикл до THREAD_PRIORITY_TIME_CRITICAL, увеличивал размер буферов. Без результата. Причём при увеличении буфера до 1 МБ, нормальный приём был невозможен и на минимальной скорости потока. Больше тут не значит лучше. Если есть идеи как повысить скорость, прошу поделиться в комментариях.

Надо сказать, что 4 MS/s для моих целей вполне достаточно, полоса с лихвой перекрывает любой радиолюбительский КВ диапазон. Да и на УКВ и СВЧ полосы хватит для большинства задач. В результате библиотека написана, окно HDSDR с включенным на приём PLUTO выглядит примерно так:



Весь код библиотеки доступен на github здесь. Можете смело использовать его для своих экспериментов с ADALM PLUTO.

73 de R2AJP

Комментарии (10)


  1. yakorev
    26.02.2019 01:11

    У самого 2 PlutoSDR и приходилось с SDRSharp их использовать. По мне так HDSDR удобнее и ждал когда же разработчик библиотеку выпустит. Думаю после такой прекрасной работы и авторы HDSDR подтянутся)


  1. vitmeat
    26.02.2019 13:02

    Нафига в репу тащить сто пицот бинарников и 'добра' которое нагенерировала студия? Я негодуэ )))

    Так же я не очень понял как у вас по usb данные передаются?
    Там поднят RNDIS и по виртуальной сетевой карте?
    Или собственный драйвер usb? Или еще какой то usb профиль?
    Если верить вики, то

    Хотя теоретическая максимальная пропускная способность USB 2.0 составляет 480 Мбит/с (60 МБ/с), на практике обеспечить пропускную способность, близкую к пиковой, не удаётся (макс. 45 МБ/с[50], чаще до 30 МБ/с).

    Получается в 'прыжке' при 60 МБ/с — можно передать полосу в 15MSPS (4 байта на IQ)
    А при реальных 30 МБ/с это всего 7.5 MSPS =(
    Сама АДэшка может вплоть до 61.44 MSPS отдавать (а это 245.76 МБ/с !!!)
    Туда бы usb3.0 =)


    1. lesha108 Автор
      26.02.2019 17:12

      IIO драйвера сами организуют канал и по NDIS и по USB. Всё естественно идет через USB2.0 Видимо в этом основная проблема. Где-то прочел, что при одновременном включении и передачи и приёма общая скорость двух потоков должна быть меньше 6 MS/s. Похоже, что большие потоки надо обрабатывать на внутреннем процессоре PLUTO. Там двухъядерный ARM есть, на котором крутится Linux.


  1. vau
    26.02.2019 20:46
    +1

    А где и как вы купили эту прелесть?


    1. lesha108 Автор
      26.02.2019 21:22
      +1

      На Алиэкспрессе обычным образом. А так многие поставщики продукции Analog Devices в РФ возят под заказ. С Али быстрее получилось, за 2 недели привезли. Ищите AD EV8634 EBZ AD9363 ZYNQ7010 SDR ADALM PLUTO


      1. evkup
        27.02.2019 14:11

        Это была акция? Сейчас находятся только варианты $180-190


        1. lesha108 Автор
          27.02.2019 14:13

          Не знаю даже. Там всё время какие то скидки дают. Видимо, сейчас цена подросла на Али


  1. evkup
    27.02.2019 16:20

    Вы не сравнивали сабж с HackRF One? По характеристикам не хуже, цена меньше, сообщество очень большое. С HDSDR давно подружили.


    1. evkup
      27.02.2019 16:20

      Хотя...«импульсивно купил». Наверное это объясняет :)


    1. lesha108 Автор
      27.02.2019 17:35

      «Не хуже» это не очень мне понятно. PLUTO полнодуплексный трансивер, да еще 12 битный, частота семплирования выше (правда доступна только на внутреннем линуксе). Беда его в отсутсnвии хорошего TXCO и экранирования.