1
0
Fork 0
mirror of https://github.com/opentx/opentx.git synced 2025-07-23 16:25:16 +03:00

In progress ...

This commit is contained in:
Bertrand Songis 2019-02-06 19:12:20 +01:00
parent 8f9fcca0c4
commit dfd12ff978
9 changed files with 155 additions and 17 deletions

View file

@ -79,6 +79,7 @@ enum MenuRadioIndexes
MENU_RADIO_SWITCHES_TEST,
MENU_RADIO_ANALOGS_TEST,
MENU_RADIO_HARDWARE,
MENU_RADIO_SPECTRUM,
MENU_RADIO_CALIBRATION,
MENU_RADIO_PAGES_COUNT
};
@ -91,6 +92,7 @@ void menuRadioVersion(event_t event);
void menuRadioDiagKeys(event_t event);
void menuRadioDiagAnalogs(event_t event);
void menuRadioHardware(event_t event);
void menuRadioSpectrum(event_t event);
void menuRadioCalibration(event_t event);
static const MenuHandlerFunc menuTabGeneral[] = {
@ -102,6 +104,7 @@ static const MenuHandlerFunc menuTabGeneral[] = {
menuRadioDiagKeys,
menuRadioDiagAnalogs,
menuRadioHardware,
menuRadioSpectrum,
menuRadioCalibration
};

View 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);
}

View file

@ -1158,6 +1158,11 @@ union ReusableBuffer
uint8_t stickMode;
} generalSettings;
struct
{
uint8_t bars[128];
} spectrum;
#if defined(STM32)
// 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];

View file

@ -139,9 +139,10 @@ void setupPulsesPXX(uint8_t port)
void setupPulsesPXX2(uint8_t module)
{
if (module == INTERNAL_MODULE) {
modulePulsesData[module].pxx2.setupFrame(module);
if (modulePulsesData[module].pxx2.setupFrame(module)) {
intmoduleSendNextFrame();
}
}
#if 0
// here we have to wait that telemetryInit() is called, hence this test
@ -292,7 +293,7 @@ void sendPulses(uint8_t port, uint8_t protocol)
case PROTOCOL_CHANNELS_PXX2:
setupPulsesPXX2(port);
scheduleNextMixerCalculation(port, PXX2_PERIOD);
scheduleNextMixerCalculation(port, moduleSettings[port].mode == MODULE_MODE_SPECTRUM ? 1 : PXX2_PERIOD);
break;
#if defined(MULTIMODULE)

View file

@ -73,13 +73,14 @@ enum ModuleSettingsMode
MODULE_MODE_NORMAL,
MODULE_MODE_RANGECHECK,
MODULE_MODE_BIND,
MODULE_MODE_REGISTER
MODULE_MODE_REGISTER,
MODULE_MODE_SPECTRUM,
};
PACK(struct ModuleSettings {
uint8_t protocol:5;
uint8_t protocol:4;
uint8_t paused:1;
uint8_t mode:2;
uint8_t mode:3;
uint16_t counter;
});

View file

@ -55,7 +55,7 @@ void Pxx2Pulses::setupChannelsFrame(uint8_t module)
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);
@ -68,9 +68,11 @@ void Pxx2Pulses::setupRegisterFrame(uint8_t module)
else {
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);
@ -87,18 +89,56 @@ void Pxx2Pulses::setupBindFrame(uint8_t module)
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();
bool result = true;
uint8_t mode = moduleSettings[module].mode;
if (mode == MODULE_MODE_REGISTER)
setupRegisterFrame(module);
result = setupRegisterFrame(module);
else if (mode == MODULE_MODE_BIND)
setupBindFrame(module);
result = setupBindFrame(module);
else if (mode == MODULE_MODE_SPECTRUM)
result = setupSpectrumAnalyser(module);
else
setupChannelsFrame(module);
@ -116,4 +156,6 @@ void Pxx2Pulses::setupFrame(uint8_t module)
#endif
endFrame();
return result;
}

View file

@ -31,6 +31,8 @@
#define PXX2_TYPE_ID_SPORT 0xFE
#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
@ -123,15 +125,17 @@ class Pxx2Transport: public DataBuffer<uint8_t, 64>, public PxxCrcMixin {
class Pxx2Pulses: public PxxPulses<Pxx2Transport> {
public:
void setupFrame(uint8_t module);
bool setupFrame(uint8_t module);
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);
bool setupSpectrumAnalyser(uint8_t module);
void addHead()
{
// send 7E, do not CRC

View file

@ -175,6 +175,7 @@ set(GUI_SRC ${GUI_SRC}
radio_diagkeys.cpp
radio_diaganas.cpp
radio_hardware.cpp
radio_spectrum.cpp
view_channels.cpp
view_telemetry.cpp
view_about.cpp

View file

@ -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)
{
if (moduleSettings[module].mode != MODULE_MODE_BIND) {
@ -100,13 +102,13 @@ void processBindFrame(uint8_t module, uint8_t * frame)
if (frame[3] == 0x00) {
bool found = false;
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;
break;
}
}
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];
for (uint8_t i=0; i<PXX2_LEN_RX_ID; i++) {
uint8_t byte = frame[4 + i];
@ -122,13 +124,35 @@ void processBindFrame(uint8_t module, uint8_t * frame)
}
}
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;
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)
{
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)
{
switch (frame[1]) {
@ -149,6 +186,10 @@ void processModuleFrame(uint8_t module, uint8_t * frame)
processRadioFrame(module, frame);
break;
case PXX2_TYPE_C_POWER_METER:
processPowerMeterFrame(module, frame);
break;
default:
break;
}