117 lines
5.0 KiB
C
117 lines
5.0 KiB
C
/**
|
||
* common.c — Реализация общих функций для приёмника и передатчика
|
||
*/
|
||
|
||
#include "common.h"
|
||
|
||
// Глобальный флаг завершения (используется обоими модулями)
|
||
volatile sig_atomic_t stop = 0;
|
||
|
||
/**
|
||
* Обработчик сигналов завершения
|
||
*/
|
||
static void sigint_handler(int s) {
|
||
(void)s;
|
||
stop = 1;
|
||
}
|
||
|
||
void setup_signal_handlers(void) {
|
||
signal(SIGINT, sigint_handler);
|
||
signal(SIGTERM, sigint_handler);
|
||
signal(SIGPIPE, SIG_IGN);
|
||
}
|
||
|
||
void print_usage(const char *prog_name, const char *mode) {
|
||
fprintf(stderr, "═══════════════════════════════════════════════════\n");
|
||
fprintf(stderr, "OFDM %s — PlutoSDR Radio Link\n", mode);
|
||
fprintf(stderr, "═══════════════════════════════════════════════════\n");
|
||
fprintf(stderr, "Использование: %s [ОПЦИИ]\n\n", prog_name);
|
||
fprintf(stderr, "ОБЩИЕ ОПЦИИ:\n");
|
||
fprintf(stderr, " -f ЧАСТОТА Частота несущей в Гц (по умолчанию: %.0f)\n",
|
||
(double)DEFAULT_FREQ);
|
||
fprintf(stderr, " -r СКОРОСТЬ Частота дискретизации (по умолчанию: %.0f)\n",
|
||
(double)DEFAULT_RATE);
|
||
fprintf(stderr, " -b ПОЛОСА Полоса пропускания (по умолчанию: %.0f)\n",
|
||
(double)DEFAULT_BW);
|
||
fprintf(stderr, " -u URI URI PlutoSDR\n");
|
||
fprintf(stderr, " -c РЕЖИМ FEC: rs8 или none (по умолчанию: rs8)\n");
|
||
fprintf(stderr, " -h Показать эту справку\n");
|
||
}
|
||
|
||
void print_config(const char *mode, long long freq, long long rate,
|
||
long long bw, int fec_on) {
|
||
fprintf(stderr, "═══════════════════════════════════════════════════\n");
|
||
fprintf(stderr, "КОНФИГУРАЦИЯ %s\n", mode);
|
||
fprintf(stderr, "Частота: %.1f МГц\n", freq / 1e6);
|
||
fprintf(stderr, "Дискрет.: %.2f МГц\n", rate / 1e6);
|
||
fprintf(stderr, "Полоса: %.2f МГц\n", bw / 1e6);
|
||
fprintf(stderr, "OFDM: M=%d, CP=%d, Taper=%d\n",
|
||
OFDM_M, OFDM_CP, OFDM_TAPER);
|
||
fprintf(stderr, "FEC: %s\n", fec_on ? "RS(255,223)" : "ОТКЛЮЧЕН");
|
||
}
|
||
|
||
int pluto_init(const char *uri, struct iio_context **ctx,
|
||
struct iio_device **phy, struct iio_device **dev, int is_tx) {
|
||
// Создание контекста
|
||
*ctx = iio_create_context_from_uri(uri);
|
||
if (!*ctx) {
|
||
LOG_ERROR("Не удалось подключиться к PlutoSDR по адресу %s", uri);
|
||
return -1;
|
||
}
|
||
|
||
// Поиск устройств
|
||
*phy = iio_context_find_device(*ctx, "ad9361-phy");
|
||
*dev = iio_context_find_device(*ctx,
|
||
is_tx ? "cf-ad9361-dds-core-lpc" : "cf-ad9361-lpc");
|
||
|
||
if (!*phy || !*dev) {
|
||
LOG_ERROR("Радиоустройства не найдены в контексте");
|
||
iio_context_destroy(*ctx);
|
||
return -1;
|
||
}
|
||
|
||
return 0;
|
||
}
|
||
|
||
void pluto_configure(struct iio_device *phy, long long freq, long long rate,
|
||
long long bw, double gain, int is_tx) {
|
||
const char *voltage_ch = is_tx ? "voltage0" : "voltage0";
|
||
const char *altvoltage_ch = is_tx ? "altvoltage1" : "altvoltage0";
|
||
bool output = is_tx ? true : false;
|
||
|
||
// Установка частоты несущей
|
||
iio_channel_attr_write_longlong(
|
||
iio_device_find_channel(phy, altvoltage_ch, output),
|
||
"frequency", freq);
|
||
|
||
// Установка частоты дискретизации
|
||
iio_channel_attr_write_longlong(
|
||
iio_device_find_channel(phy, voltage_ch, output),
|
||
"sampling_frequency", rate);
|
||
|
||
// Установка полосы пропускания
|
||
iio_channel_attr_write_longlong(
|
||
iio_device_find_channel(phy, voltage_ch, output),
|
||
"rf_bandwidth", bw);
|
||
|
||
if (is_tx) {
|
||
// Настройки передатчика
|
||
iio_channel_attr_write(
|
||
iio_device_find_channel(phy, voltage_ch, output),
|
||
"rf_port_select", "A");
|
||
iio_channel_attr_write_double(
|
||
iio_device_find_channel(phy, voltage_ch, output),
|
||
"hardwaregain", gain);
|
||
} else {
|
||
// Настройки приёмника
|
||
iio_channel_attr_write(
|
||
iio_device_find_channel(phy, voltage_ch, output),
|
||
"gain_control_mode", "manual");
|
||
iio_channel_attr_write_double(
|
||
iio_device_find_channel(phy, voltage_ch, output),
|
||
"hardwaregain", gain);
|
||
iio_channel_attr_write(
|
||
iio_device_find_channel(phy, voltage_ch, output),
|
||
"rf_port_select", "A_BALANCED");
|
||
}
|
||
} |