mirror of
https://github.com/opentx/opentx.git
synced 2025-07-23 16:25:16 +03:00
In progress ...
This commit is contained in:
parent
8f9fcca0c4
commit
dfd12ff978
9 changed files with 155 additions and 17 deletions
|
@ -79,6 +79,7 @@ enum MenuRadioIndexes
|
||||||
MENU_RADIO_SWITCHES_TEST,
|
MENU_RADIO_SWITCHES_TEST,
|
||||||
MENU_RADIO_ANALOGS_TEST,
|
MENU_RADIO_ANALOGS_TEST,
|
||||||
MENU_RADIO_HARDWARE,
|
MENU_RADIO_HARDWARE,
|
||||||
|
MENU_RADIO_SPECTRUM,
|
||||||
MENU_RADIO_CALIBRATION,
|
MENU_RADIO_CALIBRATION,
|
||||||
MENU_RADIO_PAGES_COUNT
|
MENU_RADIO_PAGES_COUNT
|
||||||
};
|
};
|
||||||
|
@ -91,6 +92,7 @@ void menuRadioVersion(event_t event);
|
||||||
void menuRadioDiagKeys(event_t event);
|
void menuRadioDiagKeys(event_t event);
|
||||||
void menuRadioDiagAnalogs(event_t event);
|
void menuRadioDiagAnalogs(event_t event);
|
||||||
void menuRadioHardware(event_t event);
|
void menuRadioHardware(event_t event);
|
||||||
|
void menuRadioSpectrum(event_t event);
|
||||||
void menuRadioCalibration(event_t event);
|
void menuRadioCalibration(event_t event);
|
||||||
|
|
||||||
static const MenuHandlerFunc menuTabGeneral[] = {
|
static const MenuHandlerFunc menuTabGeneral[] = {
|
||||||
|
@ -102,6 +104,7 @@ static const MenuHandlerFunc menuTabGeneral[] = {
|
||||||
menuRadioDiagKeys,
|
menuRadioDiagKeys,
|
||||||
menuRadioDiagAnalogs,
|
menuRadioDiagAnalogs,
|
||||||
menuRadioHardware,
|
menuRadioHardware,
|
||||||
|
menuRadioSpectrum,
|
||||||
menuRadioCalibration
|
menuRadioCalibration
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
40
radio/src/gui/128x64/radio_spectrum.cpp
Normal file
40
radio/src/gui/128x64/radio_spectrum.cpp
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) OpenTX
|
||||||
|
*
|
||||||
|
* Based on code named
|
||||||
|
* th9x - http://code.google.com/p/th9x
|
||||||
|
* er9x - http://code.google.com/p/er9x
|
||||||
|
* gruvin9x - http://code.google.com/p/gruvin9x
|
||||||
|
*
|
||||||
|
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License version 2 as
|
||||||
|
* published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "opentx.h"
|
||||||
|
|
||||||
|
void menuRadioSpectrum(event_t event)
|
||||||
|
{
|
||||||
|
MENU("SPECTRUM", menuTabGeneral, MENU_RADIO_SPECTRUM, HEADER_LINE, { HEADER_LINE_COLUMNS });
|
||||||
|
|
||||||
|
if (event == EVT_ENTRY) {
|
||||||
|
memclear(reusableBuffer.spectrum.bars, sizeof(reusableBuffer.spectrum.bars));
|
||||||
|
moduleSettings[INTERNAL_MODULE].mode = MODULE_MODE_SPECTRUM;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (uint8_t i=0; i<LCD_W; i++) {
|
||||||
|
uint8_t h = reusableBuffer.spectrum.bars[i] >> 2;
|
||||||
|
lcdDrawSolidVerticalLine(i, LCD_H - h, h);
|
||||||
|
}
|
||||||
|
extern uint32_t FREQUENCY;
|
||||||
|
extern uint8_t POWER;
|
||||||
|
lcdDrawNumber(64, 32, FREQUENCY);
|
||||||
|
lcdDrawNumber(64, 40, POWER);
|
||||||
|
}
|
|
@ -1158,6 +1158,11 @@ union ReusableBuffer
|
||||||
uint8_t stickMode;
|
uint8_t stickMode;
|
||||||
} generalSettings;
|
} generalSettings;
|
||||||
|
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
uint8_t bars[128];
|
||||||
|
} spectrum;
|
||||||
|
|
||||||
#if defined(STM32)
|
#if defined(STM32)
|
||||||
// Data for the USB mass storage driver. If USB mass storage runs no menu is not allowed to be displayed
|
// Data for the USB mass storage driver. If USB mass storage runs no menu is not allowed to be displayed
|
||||||
uint8_t MSC_BOT_Data[MSC_MEDIA_PACKET];
|
uint8_t MSC_BOT_Data[MSC_MEDIA_PACKET];
|
||||||
|
|
|
@ -139,8 +139,9 @@ void setupPulsesPXX(uint8_t port)
|
||||||
void setupPulsesPXX2(uint8_t module)
|
void setupPulsesPXX2(uint8_t module)
|
||||||
{
|
{
|
||||||
if (module == INTERNAL_MODULE) {
|
if (module == INTERNAL_MODULE) {
|
||||||
modulePulsesData[module].pxx2.setupFrame(module);
|
if (modulePulsesData[module].pxx2.setupFrame(module)) {
|
||||||
intmoduleSendNextFrame();
|
intmoduleSendNextFrame();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
|
@ -292,7 +293,7 @@ void sendPulses(uint8_t port, uint8_t protocol)
|
||||||
|
|
||||||
case PROTOCOL_CHANNELS_PXX2:
|
case PROTOCOL_CHANNELS_PXX2:
|
||||||
setupPulsesPXX2(port);
|
setupPulsesPXX2(port);
|
||||||
scheduleNextMixerCalculation(port, PXX2_PERIOD);
|
scheduleNextMixerCalculation(port, moduleSettings[port].mode == MODULE_MODE_SPECTRUM ? 1 : PXX2_PERIOD);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
#if defined(MULTIMODULE)
|
#if defined(MULTIMODULE)
|
||||||
|
|
|
@ -73,13 +73,14 @@ enum ModuleSettingsMode
|
||||||
MODULE_MODE_NORMAL,
|
MODULE_MODE_NORMAL,
|
||||||
MODULE_MODE_RANGECHECK,
|
MODULE_MODE_RANGECHECK,
|
||||||
MODULE_MODE_BIND,
|
MODULE_MODE_BIND,
|
||||||
MODULE_MODE_REGISTER
|
MODULE_MODE_REGISTER,
|
||||||
|
MODULE_MODE_SPECTRUM,
|
||||||
};
|
};
|
||||||
|
|
||||||
PACK(struct ModuleSettings {
|
PACK(struct ModuleSettings {
|
||||||
uint8_t protocol:5;
|
uint8_t protocol:4;
|
||||||
uint8_t paused:1;
|
uint8_t paused:1;
|
||||||
uint8_t mode:2;
|
uint8_t mode:3;
|
||||||
uint16_t counter;
|
uint16_t counter;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -55,7 +55,7 @@ void Pxx2Pulses::setupChannelsFrame(uint8_t module)
|
||||||
addChannels(module, flag0 & PXX2_FLAG0_FAILSAFE, 1);
|
addChannels(module, flag0 & PXX2_FLAG0_FAILSAFE, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Pxx2Pulses::setupRegisterFrame(uint8_t module)
|
bool Pxx2Pulses::setupRegisterFrame(uint8_t module)
|
||||||
{
|
{
|
||||||
addFrameType(PXX2_TYPE_C_MODULE, PXX2_TYPE_ID_REGISTER);
|
addFrameType(PXX2_TYPE_C_MODULE, PXX2_TYPE_ID_REGISTER);
|
||||||
|
|
||||||
|
@ -68,9 +68,11 @@ void Pxx2Pulses::setupRegisterFrame(uint8_t module)
|
||||||
else {
|
else {
|
||||||
Pxx2Transport::addByte(0);
|
Pxx2Transport::addByte(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return true; // TODO not always
|
||||||
}
|
}
|
||||||
|
|
||||||
void Pxx2Pulses::setupBindFrame(uint8_t module)
|
bool Pxx2Pulses::setupBindFrame(uint8_t module)
|
||||||
{
|
{
|
||||||
addFrameType(PXX2_TYPE_C_MODULE, PXX2_TYPE_ID_BIND);
|
addFrameType(PXX2_TYPE_C_MODULE, PXX2_TYPE_ID_BIND);
|
||||||
|
|
||||||
|
@ -87,18 +89,56 @@ void Pxx2Pulses::setupBindFrame(uint8_t module)
|
||||||
Pxx2Transport::addByte(g_model.modelRegistrationID[i]);
|
Pxx2Transport::addByte(g_model.modelRegistrationID[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return true; // TODO not always
|
||||||
}
|
}
|
||||||
|
|
||||||
void Pxx2Pulses::setupFrame(uint8_t module)
|
bool Pxx2Pulses::setupSpectrumAnalyser(uint8_t module)
|
||||||
|
{
|
||||||
|
addFrameType(PXX2_TYPE_C_POWER_METER, PXX2_TYPE_ID_SPECTRUM);
|
||||||
|
Pxx2Transport::addByte(0x00);
|
||||||
|
|
||||||
|
uint32_t fq = 2500000000;
|
||||||
|
Pxx2Transport::addByte(fq);
|
||||||
|
Pxx2Transport::addByte(fq >> 8);
|
||||||
|
Pxx2Transport::addByte(fq >> 16);
|
||||||
|
Pxx2Transport::addByte(fq >> 24);
|
||||||
|
|
||||||
|
uint32_t span = 10000;
|
||||||
|
Pxx2Transport::addByte(span);
|
||||||
|
Pxx2Transport::addByte(span >> 8);
|
||||||
|
Pxx2Transport::addByte(span >> 16);
|
||||||
|
Pxx2Transport::addByte(span >> 24);
|
||||||
|
|
||||||
|
uint32_t bandwidth = 10000;
|
||||||
|
Pxx2Transport::addByte(bandwidth);
|
||||||
|
Pxx2Transport::addByte(bandwidth >> 8);
|
||||||
|
Pxx2Transport::addByte(bandwidth >> 16);
|
||||||
|
Pxx2Transport::addByte(bandwidth >> 24);
|
||||||
|
|
||||||
|
static bool done = false;
|
||||||
|
|
||||||
|
if (done)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
done = true;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Pxx2Pulses::setupFrame(uint8_t module)
|
||||||
{
|
{
|
||||||
initFrame();
|
initFrame();
|
||||||
|
|
||||||
|
bool result = true;
|
||||||
uint8_t mode = moduleSettings[module].mode;
|
uint8_t mode = moduleSettings[module].mode;
|
||||||
|
|
||||||
if (mode == MODULE_MODE_REGISTER)
|
if (mode == MODULE_MODE_REGISTER)
|
||||||
setupRegisterFrame(module);
|
result = setupRegisterFrame(module);
|
||||||
else if (mode == MODULE_MODE_BIND)
|
else if (mode == MODULE_MODE_BIND)
|
||||||
setupBindFrame(module);
|
result = setupBindFrame(module);
|
||||||
|
else if (mode == MODULE_MODE_SPECTRUM)
|
||||||
|
result = setupSpectrumAnalyser(module);
|
||||||
else
|
else
|
||||||
setupChannelsFrame(module);
|
setupChannelsFrame(module);
|
||||||
|
|
||||||
|
@ -116,4 +156,6 @@ void Pxx2Pulses::setupFrame(uint8_t module)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
endFrame();
|
endFrame();
|
||||||
|
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,6 +31,8 @@
|
||||||
#define PXX2_TYPE_ID_SPORT 0xFE
|
#define PXX2_TYPE_ID_SPORT 0xFE
|
||||||
|
|
||||||
#define PXX2_TYPE_C_POWER_METER 0x02
|
#define PXX2_TYPE_C_POWER_METER 0x02
|
||||||
|
#define PXX2_TYPE_ID_POWER_METER 0x01
|
||||||
|
#define PXX2_TYPE_ID_SPECTRUM 0x02
|
||||||
|
|
||||||
#define PXX2_TYPE_C_OTA 0xFE
|
#define PXX2_TYPE_C_OTA 0xFE
|
||||||
|
|
||||||
|
@ -123,15 +125,17 @@ class Pxx2Transport: public DataBuffer<uint8_t, 64>, public PxxCrcMixin {
|
||||||
|
|
||||||
class Pxx2Pulses: public PxxPulses<Pxx2Transport> {
|
class Pxx2Pulses: public PxxPulses<Pxx2Transport> {
|
||||||
public:
|
public:
|
||||||
void setupFrame(uint8_t module);
|
bool setupFrame(uint8_t module);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void setupRegisterFrame(uint8_t module);
|
bool setupRegisterFrame(uint8_t module);
|
||||||
|
|
||||||
void setupBindFrame(uint8_t module);
|
bool setupBindFrame(uint8_t module);
|
||||||
|
|
||||||
void setupChannelsFrame(uint8_t module);
|
void setupChannelsFrame(uint8_t module);
|
||||||
|
|
||||||
|
bool setupSpectrumAnalyser(uint8_t module);
|
||||||
|
|
||||||
void addHead()
|
void addHead()
|
||||||
{
|
{
|
||||||
// send 7E, do not CRC
|
// send 7E, do not CRC
|
||||||
|
|
|
@ -175,6 +175,7 @@ set(GUI_SRC ${GUI_SRC}
|
||||||
radio_diagkeys.cpp
|
radio_diagkeys.cpp
|
||||||
radio_diaganas.cpp
|
radio_diaganas.cpp
|
||||||
radio_hardware.cpp
|
radio_hardware.cpp
|
||||||
|
radio_spectrum.cpp
|
||||||
view_channels.cpp
|
view_channels.cpp
|
||||||
view_telemetry.cpp
|
view_telemetry.cpp
|
||||||
view_about.cpp
|
view_about.cpp
|
||||||
|
|
|
@ -91,6 +91,8 @@ void processRegisterFrame(uint8_t module, uint8_t * frame)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const uint8_t MY_RX_ID[] = { 0x46, 0x17, 0x32, 0x85 };
|
||||||
|
|
||||||
void processBindFrame(uint8_t module, uint8_t * frame)
|
void processBindFrame(uint8_t module, uint8_t * frame)
|
||||||
{
|
{
|
||||||
if (moduleSettings[module].mode != MODULE_MODE_BIND) {
|
if (moduleSettings[module].mode != MODULE_MODE_BIND) {
|
||||||
|
@ -100,13 +102,13 @@ void processBindFrame(uint8_t module, uint8_t * frame)
|
||||||
if (frame[3] == 0x00) {
|
if (frame[3] == 0x00) {
|
||||||
bool found = false;
|
bool found = false;
|
||||||
for (uint8_t i=0; i<reusableBuffer.modelsetup.pxx2_bind_candidate_receivers_count; i++) {
|
for (uint8_t i=0; i<reusableBuffer.modelsetup.pxx2_bind_candidate_receivers_count; i++) {
|
||||||
if (memcmp(reusableBuffer.modelsetup.pxx2_bind_candidate_receivers_ids[i], &frame[4], PXX2_LEN_RX_ID) == 0) {
|
if (memcmp(reusableBuffer.modelsetup.pxx2_bind_candidate_receivers_ids[i], MY_RX_ID /*TODO &frame[4]*/, PXX2_LEN_RX_ID) == 0) {
|
||||||
found = true;
|
found = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!found && reusableBuffer.modelsetup.pxx2_bind_candidate_receivers_count < PXX2_MAX_RECEIVERS_PER_MODULE) {
|
if (!found && reusableBuffer.modelsetup.pxx2_bind_candidate_receivers_count < PXX2_MAX_RECEIVERS_PER_MODULE) {
|
||||||
memcpy(reusableBuffer.modelsetup.pxx2_bind_candidate_receivers_ids[reusableBuffer.modelsetup.pxx2_bind_candidate_receivers_count], &frame[4], PXX2_LEN_RX_ID);
|
memcpy(reusableBuffer.modelsetup.pxx2_bind_candidate_receivers_ids[reusableBuffer.modelsetup.pxx2_bind_candidate_receivers_count], MY_RX_ID /*TODO &frame[4]*/, PXX2_LEN_RX_ID);
|
||||||
char * c = reusableBuffer.modelsetup.pxx2_bind_candidate_receivers_names[reusableBuffer.modelsetup.pxx2_bind_candidate_receivers_count];
|
char * c = reusableBuffer.modelsetup.pxx2_bind_candidate_receivers_names[reusableBuffer.modelsetup.pxx2_bind_candidate_receivers_count];
|
||||||
for (uint8_t i=0; i<PXX2_LEN_RX_ID; i++) {
|
for (uint8_t i=0; i<PXX2_LEN_RX_ID; i++) {
|
||||||
uint8_t byte = frame[4 + i];
|
uint8_t byte = frame[4 + i];
|
||||||
|
@ -122,13 +124,35 @@ void processBindFrame(uint8_t module, uint8_t * frame)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (frame[3] == 0x01) {
|
else if (frame[3] == 0x01) {
|
||||||
if (memcmp(reusableBuffer.modelsetup.pxx2_bind_candidate_receivers_ids[reusableBuffer.modelsetup.pxx2_bind_selected_receiver_index], &frame[4], PXX2_LEN_RX_ID) == 0) {
|
if (memcmp(reusableBuffer.modelsetup.pxx2_bind_candidate_receivers_ids[reusableBuffer.modelsetup.pxx2_bind_selected_receiver_index], MY_RX_ID /*TODO &frame[4]*/, PXX2_LEN_RX_ID) == 0) {
|
||||||
reusableBuffer.modelsetup.pxx2_register_or_bind_step = BIND_OK;
|
reusableBuffer.modelsetup.pxx2_register_or_bind_step = BIND_OK;
|
||||||
moduleSettings[module].mode = MODULE_MODE_NORMAL;
|
moduleSettings[module].mode = MODULE_MODE_NORMAL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint32_t FREQUENCY;
|
||||||
|
uint8_t POWER;
|
||||||
|
void processSpectrumFrame(uint8_t module, uint8_t * frame)
|
||||||
|
{
|
||||||
|
if (moduleSettings[module].mode != MODULE_MODE_SPECTRUM) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t * frequency = (uint32_t *)&frame[4];
|
||||||
|
int8_t * power = (int8_t *)&frame[8];
|
||||||
|
|
||||||
|
// center = 2500000000
|
||||||
|
// left = 2500000000 - 5000
|
||||||
|
// span = 10000
|
||||||
|
|
||||||
|
FREQUENCY = *frequency;
|
||||||
|
POWER = *power;
|
||||||
|
|
||||||
|
|
||||||
|
// reusableBuffer.spectrum.bars[(*frequency - (2500000000 - 5000)) * 128 / 10000] = 127 + *power;
|
||||||
|
}
|
||||||
|
|
||||||
void processRadioFrame(uint8_t module, uint8_t * frame)
|
void processRadioFrame(uint8_t module, uint8_t * frame)
|
||||||
{
|
{
|
||||||
switch (frame[2]) {
|
switch (frame[2]) {
|
||||||
|
@ -142,6 +166,19 @@ void processRadioFrame(uint8_t module, uint8_t * frame)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void processPowerMeterFrame(uint8_t module, uint8_t * frame)
|
||||||
|
{
|
||||||
|
switch (frame[2]) {
|
||||||
|
case PXX2_TYPE_ID_POWER_METER:
|
||||||
|
// TODO
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PXX2_TYPE_ID_SPECTRUM:
|
||||||
|
processSpectrumFrame(module, frame);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void processModuleFrame(uint8_t module, uint8_t * frame)
|
void processModuleFrame(uint8_t module, uint8_t * frame)
|
||||||
{
|
{
|
||||||
switch (frame[1]) {
|
switch (frame[1]) {
|
||||||
|
@ -149,6 +186,10 @@ void processModuleFrame(uint8_t module, uint8_t * frame)
|
||||||
processRadioFrame(module, frame);
|
processRadioFrame(module, frame);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case PXX2_TYPE_C_POWER_METER:
|
||||||
|
processPowerMeterFrame(module, frame);
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue