/** * 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 ЧАСТОТА Частота несущей в Гц (по умолчанию: %lld)\n", DEFAULT_FREQ); fprintf(stderr, " -r СКОРОСТЬ Частота дискретизации (по умолчанию: %lld)\n", DEFAULT_RATE); fprintf(stderr, " -b ПОЛОСА Полоса пропускания (по умолчанию: %lld)\n", 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) { if (is_tx) { // Настройка передатчика iio_channel_attr_write_longlong( iio_device_find_channel(phy, "altvoltage1", true), "frequency", freq); iio_channel_attr_write_longlong( iio_device_find_channel(phy, "voltage0", true), "sampling_frequency", rate); iio_channel_attr_write_longlong( iio_device_find_channel(phy, "voltage0", true), "rf_bandwidth", bw); iio_channel_attr_write( iio_device_find_channel(phy, "voltage0", true), "rf_port_select", "A"); iio_channel_attr_write_double( iio_device_find_channel(phy, "voltage0", true), "hardwaregain", gain); } else { // Настройка приёмника iio_channel_attr_write_longlong( iio_device_find_channel(phy, "altvoltage0", true), "frequency", freq); iio_channel_attr_write_longlong( iio_device_find_channel(phy, "voltage0", false), "sampling_frequency", rate); iio_channel_attr_write_longlong( iio_device_find_channel(phy, "voltage0", false), "rf_bandwidth", bw); iio_channel_attr_write( iio_device_find_channel(phy, "voltage0", false), "gain_control_mode", "manual"); iio_channel_attr_write_double( iio_device_find_channel(phy, "voltage0", false), "hardwaregain", gain); iio_channel_attr_write( iio_device_find_channel(phy, "voltage0", false), "rf_port_select", "A_BALANCED"); } }