diff --git a/CHANGELOG.txt b/CHANGELOG.txt index 852a59b..46cc941 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -1,3 +1,35 @@ +----Version 12.0.0---- ++FPGA: Попытка устранить периодические проблемы с фантомными сигналами (пока только 22к версия, временно будет работать и 11.1.0 в случае проблем) ++FPGA: В System Info теперь отображаются MIN/MAX значения на входе ЦАП во время передачи, Tnx R6DLC ++STM32: Добавлена экспериментальная поддержка внешнего интерфейсного устройства на базе ESP32, программируемого под нужды пользователя (см папку Stuff для информации) ++STM32: При отключенном Autogainer отображается уровень сигнала на входе АЦП (CN темы), Tnx Dire Wolf ++STM32: Улучшение алгоритма импорта настроек, Tnx SP7MFR ++STM32: Увеличен порядок фильтров IQ потока для 384кГц обзора, Tnx SP7MFR ++STM32: Добавлен DC-фильтр для SAM демодулятора, Tnx Jaz ++STM32: Доработки FM демодулятора "Diff" типа ++STM32: Wolf-1: В настраиваемые функциональные кнопки добавлена функция "TX", Tnx UT8EU ++STM32: Перемещена кнопка "EQ" на главной панели, Tnx ats52 ++STM32: Улучшена работа CW макросов при задержке передачи, Tnx SP7MFR ++STM32: Wolf-Lite: Остановлено развитие кодовой базы из-за закончившейся ROM, далее только выпуск баг-фиксов к стабильному релизу ++STM32: Новый алгоритм шумоподавления DNR, в настройках задаются 2 порога срабатывания под предпочтения пользователя для быстрого переключения между режимами ++STM32: Экранные диапазонные кнопки в CN темах теперь работают аналогично аппаратным (короткое нажатие прыгает по ячейкам памяти, долгое - записывает в память), Tnx RT3W ++STM32: Ячейки памяти диапазонов сохраняют не только частоту, но и моду, Tnx UT8EU ++STM32: Добавлены предзаписанные пары ячеек памяти для основных диапазонов (SSB+CW) ++STM32: Wolf-Mini: Удалена опция "FUNC" с вторичного энкодера, Tnx R7KBI ++STM32: Wolf-Mini: Во время регулировки SSB HPF вторичным энкодером отображается текущее значение полосы фильтра, Tnx R7KBI ++STM32: Wolf-Mini: Улучшена система синхронизации параметров кодека NAU8822 по I2C, Tnx R7KBI ++STM32: Улучшен механизм определения перегрузки АЦП ++STM32: Усилена вычисляемая контрольная сумма, которая защищает настройки и калибровки от случайного повреждения ++STM32: Добавлена поддержка формата моно-16 бит для USB аудио-устройства, Tnx RN3KK, R3TLI ++STM32: Улучшение поддержки части CAT-команд, Tnx RN3KK ++STM32: В списке WiFi сетей выводится RSSI сигнала каждой из точек доступа, Tnx R7KBI ++STM32: Реализована поддержка удалёнки через Bi4Remote, https://t.me/bi4remote_team https://habr.com/ru/articles/797625/ , Tnx RN3KK, R3TLI ++STM32: Улучшена работа TOT в CW, Tnx SP7MFR ++STM32: Макросы выделены в отдельное меню ++STM32: Долгое нажатие на макрос в нижнем меню открывает страницу его редактирования ++STM32: Добавлено 5 макросов SSB, активируется на те же кнопки, что и макросы CW но в голосовых модах, им можно прописать свои имена на кнопках, Tnx RT3W ++STM32: Увеличено ускорение перестройки частоты при быстром вращении энкодера и активной настройке "TRX Settings -> Encoder Accelerate" (само ускорение настраивается в калибровках под энкодер), Tnx ats52 + ----Version 11.5.0---- +STM32: Улучшение работы связки CAT+CW+Секвенсор +STM32: Улучшение работы CW самоконтроля, Tnx UT8EU diff --git a/README.md b/README.md index a4f3dae..789a3f5 100644 --- a/README.md +++ b/README.md @@ -168,7 +168,7 @@ WiFi module ESP-01 must have fresh firmware with SDK 3.0.4 and higher, and AT co * **Transverter XXcm** - Enable external ham band transverter support * **URSI Code** - Ionogram URSI Code https://digisonde.com/index.html#stationmap-section * **Tropo Region** - Region for tropospheric forecast https://www.dxinfocentre.com/tropo.html -* **Wolf Cluster** - Display Wolf TRX users on spectrum and send self data +* **Wolf Interface I2C** - Connect TRX to external I2C interface device (See STUFF folder for example) ### FILTERS Settings @@ -327,6 +327,7 @@ WiFi module ESP-01 must have fresh firmware with SDK 3.0.4 and higher, and AT co * **Show Sec VFO** - Show secondary VFO position on spectrum * **WTF Color** - Waterfall colors: 1(blue -> yellow -> red), 2(black -> yellow -> red), 3(black -> yellow -> green), 4(black -> red), 5(black -> green), 6(black -> blue), 7(black -> white) * **WTF Moving** - Mowe waterfall with frequency changing +* **Wolf Cluster** - Display Wolf TRX users on spectrum and send self data ### Decoders * **CW Decoder** - Software CW receive decoder diff --git a/README.ru-RU.md b/README.ru-RU.md index 40fb5e5..2b9aca0 100644 --- a/README.ru-RU.md +++ b/README.ru-RU.md @@ -167,7 +167,7 @@ WiFi модуль ESP-01 должен иметь свежую прошивку * **Transverter XXcm** - Поддержка внешнего трансвертера для радиолюбительских бэндов * **URSI Code** - URSI код для вывода ионограмм https://digisonde.com/index.html#stationmap-section * **Tropo Region** - Регион для прогноза тропо https://www.dxinfocentre.com/tropo.html -* **Wolf Cluster** - Отображать других пользователей трансивера Волк на спектре и передавать свои данные +* **Wolf Interface I2C** - Подключение трансивера к внешнему I2C интерфейсному устройству, см папку STUFF для получения примера ### FILTERS Settings @@ -326,6 +326,7 @@ WiFi модуль ESP-01 должен иметь свежую прошивку * **Show Sec VFO** - Отображать положение второго VFO на спектре * **WTF Color** - Цвета водопада: 1(синий -> желтый -> красный), 2(чёрный -> желтый -> красный), 3(чёрный -> желтый -> зеленый), 4(чёрный -> красный), 5(чёрный -> зеленый), 6(чёрный -> синий), 7(чёрный -> белый) * **WTF Moving** - Смещение водопада вместе с изменением частоты +* **Wolf Cluster** - Отображать других пользователей трансивера Волк на спектре и передавать свои данные ### Decoders diff --git a/Stuff/Wolf-Interface/Info.txt b/Stuff/Wolf-Interface/Info.txt new file mode 100644 index 0000000..a9d6647 --- /dev/null +++ b/Stuff/Wolf-Interface/Info.txt @@ -0,0 +1,8 @@ +Интерфейс предназначен для создания пользовательских устройств, + имеющих высокую степень интеграции с трансивером "Волк" Интерфейс подключается к общей I2C шине трансивера.В данном примере используется плата ESP32, + подсоединенная к 21 ноге(сигнал SDA) и 22(сигнал SCK) + + Со стороны трансивера требуется включение опции Menu->TRX Settings->Wolf Interface I2C + + В данный момент поддерживается : 1. Синхронизация основных параметров трансивера(частота, мода, TX / RX) 2. Выполнение и получение ответа по любой поддерживаемой CAT комманде + 3. Вывод сообщения на экран трансивера diff --git a/Stuff/Wolf-Interface/Wolf-Interface.ino b/Stuff/Wolf-Interface/Wolf-Interface.ino new file mode 100644 index 0000000..05c6d18 --- /dev/null +++ b/Stuff/Wolf-Interface/Wolf-Interface.ino @@ -0,0 +1,38 @@ +/* + Wolf Interface Example Project + + This sketch demonstrates basic functionality for develop user-space devices, which communicates with TRX Wolf + + https://github.com/XGudron/UA3REO-DDC-Transceiver +*/ + +#include "Wolf.h" + +// the setup function runs once when you press reset or power the board +void setup() { + Serial.begin(115200); // enable serial port for debugging + + WOLF_init(); // init TRX Wolf communication +} + +// the loop function runs over and over again forever +void loop() { + Serial.println("TRX Info:"); + Serial.println("Current VFO: " + String(TRX_WOLF.CurrentVFO == TRX_SELECTED_VFO_A ? "A" : "B")); + Serial.println("VFO A Frequency: " + String(TRX_WOLF.VFO_A_Frequency)); + Serial.println("VFO A Mode: " + WOLF_modeToString(TRX_WOLF.VFO_A_Mode)); + Serial.println("VFO A Mode is CW? " + String(TRX_WOLF.VFO_A_Mode == TRX_MODE_CW ? "Yes" : "No")); + Serial.println("VFO B Frequency: " + String(TRX_WOLF.VFO_B_Frequency)); + Serial.println("VFO B Mode: " + WOLF_modeToString(TRX_WOLF.VFO_B_Mode)); + Serial.println("In TX? " + String(TRX_WOLF.TX ? "Yes" : "No")); + Serial.println("In Tune? " + String(TRX_WOLF.Tune ? "Yes" : "No")); + + String CAT_Answer = WOLF_catCommand("SM2"); // run CAT command and get answer + Serial.println("CAT Answer (S-Meter dBm RX1): " + CAT_Answer); + + WOLF_setMessage("Hello World! " + String(millis())); // set message over FFT, may be disabled if not set + + Serial.println("---"); + + delay(1000); +} diff --git a/Stuff/Wolf-Interface/Wolf.h b/Stuff/Wolf-Interface/Wolf.h new file mode 100644 index 0000000..6498841 --- /dev/null +++ b/Stuff/Wolf-Interface/Wolf.h @@ -0,0 +1,51 @@ +#ifndef WOLF_h +#define WOLF_h + +typedef enum { + TRX_MODE_LSB, + TRX_MODE_USB, + TRX_MODE_CW, + TRX_MODE_NFM, + TRX_MODE_WFM, + TRX_MODE_AM, + TRX_MODE_SAM_STEREO, + TRX_MODE_SAM_LSB, + TRX_MODE_SAM_USB, + TRX_MODE_DIGI_L, + TRX_MODE_DIGI_U, + TRX_MODE_IQ, + TRX_MODE_LOOPBACK, + TRX_MODE_RTTY, + TRX_MODE_DSB, +} TRX_MODE; + +typedef enum { + TRX_SELECTED_VFO_A, + TRX_SELECTED_VFO_B, +} TRX_SELECTED_VFO; + +typedef struct { // TRX information structure + uint8_t CurrentVFO; + uint64_t VFO_A_Frequency; + uint64_t VFO_B_Frequency; + uint8_t VFO_A_Mode; + uint8_t VFO_B_Mode; + char CAT_Answer[64]; + bool TX; + bool Tune; +} tWOLF; + +typedef struct { // Interface information structure + bool hasDataChanges; + char Message[64]; + char CAT_Command[64]; +} tWOLFInterface; + +extern tWOLF TRX_WOLF; + +extern void WOLF_init(void); +extern String WOLF_modeToString(uint8_t mode); +extern void WOLF_setMessage(String message); +extern String WOLF_catCommand(String command); + +#endif diff --git a/Stuff/Wolf-Interface/Wolf.ino b/Stuff/Wolf-Interface/Wolf.ino new file mode 100644 index 0000000..88c3f7b --- /dev/null +++ b/Stuff/Wolf-Interface/Wolf.ino @@ -0,0 +1,129 @@ +#include "Wolf.h" +#include "driver/i2c.h" +#include "freertos/FreeRTOS.h" + +#define WOLF_I2C_SLAVE_SDA_IO GPIO_NUM_21 +#define WOLF_I2C_SLAVE_SCL_IO GPIO_NUM_22 +#define WOLF_I2C_SLAVE_NUM I2C_NUM_0 +#define WOLF_I2C_ADDR 0b1110110 // without RW bit +#define WOLF_BUF_LEN 256 + +tWOLF TRX_WOLF; +tWOLFInterface TRX_INTERFACE; + +static uint8_t WOLF_inBuff[WOLF_BUF_LEN]; +static uint8_t WOLF_outBuff[WOLF_BUF_LEN]; + +static esp_err_t WOLF_i2c_slave_init() { + i2c_config_t conf_slave; + conf_slave.sda_io_num = WOLF_I2C_SLAVE_SDA_IO; + conf_slave.sda_pullup_en = GPIO_PULLUP_ENABLE; + conf_slave.scl_io_num = WOLF_I2C_SLAVE_SCL_IO; + conf_slave.scl_pullup_en = GPIO_PULLUP_ENABLE; + conf_slave.mode = I2C_MODE_SLAVE; + conf_slave.slave.addr_10bit_en = 0; + conf_slave.slave.slave_addr = WOLF_I2C_ADDR; + conf_slave.slave.maximum_speed = 300000; + conf_slave.clk_flags = 0; + i2c_param_config(WOLF_I2C_SLAVE_NUM, &conf_slave); + return i2c_driver_install(WOLF_I2C_SLAVE_NUM, conf_slave.mode, WOLF_BUF_LEN, WOLF_BUF_LEN, 0); +} + +static void WOLF_i2c_background_task(void *arg) { + while (1) { + size_t size = i2c_slave_read_buffer(WOLF_I2C_SLAVE_NUM, WOLF_inBuff, 1, 1000 / portTICK_RATE_MS); + if (size != 1) { + continue; + } + + if (WOLF_inBuff[0] == 0x10) // write structure command + { + size = i2c_slave_read_buffer(WOLF_I2C_SLAVE_NUM, WOLF_inBuff, 1, 1000 / portTICK_RATE_MS); + if (size != 1) { + continue; + } + + if (WOLF_inBuff[0] == 0x01) { + i2c_slave_read_buffer(WOLF_I2C_SLAVE_NUM, (uint8_t *)&TRX_WOLF.CurrentVFO, sizeof(TRX_WOLF.CurrentVFO), 1000 / portTICK_RATE_MS); + } + if (WOLF_inBuff[0] == 0x02) { + i2c_slave_read_buffer(WOLF_I2C_SLAVE_NUM, (uint8_t *)&TRX_WOLF.VFO_A_Frequency, sizeof(TRX_WOLF.VFO_A_Frequency), 1000 / portTICK_RATE_MS); + } + if (WOLF_inBuff[0] == 0x03) { + i2c_slave_read_buffer(WOLF_I2C_SLAVE_NUM, (uint8_t *)&TRX_WOLF.VFO_B_Frequency, sizeof(TRX_WOLF.VFO_B_Frequency), 1000 / portTICK_RATE_MS); + } + if (WOLF_inBuff[0] == 0x04) { + i2c_slave_read_buffer(WOLF_I2C_SLAVE_NUM, (uint8_t *)&TRX_WOLF.VFO_A_Mode, sizeof(TRX_WOLF.VFO_A_Mode), 1000 / portTICK_RATE_MS); + } + if (WOLF_inBuff[0] == 0x05) { + i2c_slave_read_buffer(WOLF_I2C_SLAVE_NUM, (uint8_t *)&TRX_WOLF.VFO_B_Mode, sizeof(TRX_WOLF.VFO_B_Mode), 1000 / portTICK_RATE_MS); + } + if (WOLF_inBuff[0] == 0x06) { + i2c_slave_read_buffer(WOLF_I2C_SLAVE_NUM, (uint8_t *)&TRX_WOLF.CAT_Answer, sizeof(TRX_WOLF.CAT_Answer), 1000 / portTICK_RATE_MS); + } + if (WOLF_inBuff[0] == 0x07) { + i2c_slave_read_buffer(WOLF_I2C_SLAVE_NUM, (uint8_t *)&TRX_WOLF.TX, sizeof(TRX_WOLF.TX), 1000 / portTICK_RATE_MS); + } + if (WOLF_inBuff[0] == 0x08) { + i2c_slave_read_buffer(WOLF_I2C_SLAVE_NUM, (uint8_t *)&TRX_WOLF.Tune, sizeof(TRX_WOLF.Tune), 1000 / portTICK_RATE_MS); + } + } + + if (WOLF_inBuff[0] == 0x20) // read has changes? command + { + WOLF_outBuff[0] = TRX_INTERFACE.hasDataChanges ? 0x01 : 0x00; + i2c_reset_tx_fifo(WOLF_I2C_SLAVE_NUM); + i2c_slave_write_buffer(WOLF_I2C_SLAVE_NUM, WOLF_outBuff, 1, 1000 / portTICK_RATE_MS); + } + + if (WOLF_inBuff[0] == 0x30) // read data from interface command + { + size = i2c_slave_read_buffer(WOLF_I2C_SLAVE_NUM, WOLF_inBuff, 1, 1000 / portTICK_RATE_MS); + if (size != 1) { + continue; + } + + i2c_reset_tx_fifo(WOLF_I2C_SLAVE_NUM); + + if (WOLF_inBuff[0] == 0x01) { + i2c_slave_write_buffer(WOLF_I2C_SLAVE_NUM, (uint8_t *)TRX_INTERFACE.Message, sizeof(TRX_INTERFACE.Message), 1000 / portTICK_RATE_MS); + } + if (WOLF_inBuff[0] == 0x02) { + i2c_slave_write_buffer(WOLF_I2C_SLAVE_NUM, (uint8_t *)TRX_INTERFACE.CAT_Command, sizeof(TRX_INTERFACE.CAT_Command), 1000 / portTICK_RATE_MS); + memset(TRX_INTERFACE.CAT_Command, 0x00, sizeof(TRX_INTERFACE.CAT_Command)); + } + + TRX_INTERFACE.hasDataChanges = false; + } + } +} + +void WOLF_init(void) { + ESP_ERROR_CHECK(WOLF_i2c_slave_init()); + xTaskCreate(WOLF_i2c_background_task, "wolf-task", 1024 * 2, (void *)1, 10, NULL); +} + +String WOLF_modeToString(uint8_t mode) { + const char *MODE_DESCR[] = {"LSB", "USB", "CW", "NFM", "WFM", "AM", "SAM", "AM-L", "AM-U", "DIGL", "DIGU", "IQ", "LOOP", "RTTY", "DSB"}; + return String(MODE_DESCR[mode]); +} + +void WOLF_setMessage(String message) { + message.toCharArray(TRX_INTERFACE.Message, sizeof(TRX_INTERFACE.Message)); + TRX_INTERFACE.hasDataChanges = true; +} + +String WOLF_catCommand(String command) { + memset(TRX_WOLF.CAT_Answer, 0x00, sizeof(TRX_WOLF.CAT_Answer)); + command.toCharArray(TRX_INTERFACE.CAT_Command, sizeof(TRX_INTERFACE.CAT_Command)); + TRX_INTERFACE.hasDataChanges = true; + + uint32_t startMs = esp_timer_get_time() / 1000; + while ((esp_timer_get_time() / 1000) - startMs < 2000) { // CAT Timeout + if (strlen(TRX_WOLF.CAT_Answer) > 0) { + return String(TRX_WOLF.CAT_Answer); + } + } + + return ""; +}