mirror of
https://github.com/opentx/opentx.git
synced 2025-07-21 15:25:17 +03:00
[X10 Express] Spectrum analyser, first version
This commit is contained in:
parent
01c88fbba8
commit
ffb731dc30
11 changed files with 281 additions and 140 deletions
|
@ -419,7 +419,6 @@ if(NOT MSVC)
|
||||||
set(OPT s)
|
set(OPT s)
|
||||||
|
|
||||||
if(ARCH STREQUAL ARM)
|
if(ARCH STREQUAL ARM)
|
||||||
|
|
||||||
enable_language(ASM)
|
enable_language(ASM)
|
||||||
set(CMAKE_C_COMPILER arm-none-eabi-gcc)
|
set(CMAKE_C_COMPILER arm-none-eabi-gcc)
|
||||||
set(CMAKE_CXX_COMPILER arm-none-eabi-g++)
|
set(CMAKE_CXX_COMPILER arm-none-eabi-g++)
|
||||||
|
|
172
radio/src/gui/480x272/radio_spectrum_analyser.cpp
Normal file
172
radio/src/gui/480x272/radio_spectrum_analyser.cpp
Normal file
|
@ -0,0 +1,172 @@
|
||||||
|
/*
|
||||||
|
* 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"
|
||||||
|
|
||||||
|
extern uint8_t g_moduleIdx;
|
||||||
|
|
||||||
|
enum SpectrumFields {
|
||||||
|
SPECTRUM_FREQUENCY,
|
||||||
|
SPECTRUM_SPAN,
|
||||||
|
SPECTRUM_FIELDS_MAX
|
||||||
|
};
|
||||||
|
|
||||||
|
bool menuRadioSpectrumAnalyser(event_t event)
|
||||||
|
{
|
||||||
|
SUBMENU(STR_MENU_SPECTRUM_ANALYSER, ICON_RADIO, 1, {1});
|
||||||
|
|
||||||
|
if (menuEvent) {
|
||||||
|
lcdDrawCenteredText(LCD_H/2, STR_STOPPING);
|
||||||
|
lcdRefresh();
|
||||||
|
moduleState[g_moduleIdx].readModuleInformation(&reusableBuffer.moduleSetup.pxx2.moduleInformation, PXX2_HW_INFO_TX_ID, PXX2_HW_INFO_TX_ID);
|
||||||
|
/* wait 1s to resume normal operation before leaving */
|
||||||
|
watchdogSuspend(1000);
|
||||||
|
RTOS_WAIT_MS(1000);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (moduleState[g_moduleIdx].mode != MODULE_MODE_SPECTRUM_ANALYSER) {
|
||||||
|
if (TELEMETRY_STREAMING()) {
|
||||||
|
lcdDrawCenteredText(LCD_H/2, STR_TURN_OFF_RECEIVER);
|
||||||
|
if (event == EVT_KEY_FIRST(KEY_EXIT)) {
|
||||||
|
killEvents(event);
|
||||||
|
popMenu();
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
memclear(&reusableBuffer.spectrumAnalyser, sizeof(reusableBuffer.spectrumAnalyser));
|
||||||
|
|
||||||
|
if (isModuleR9MAccess(g_moduleIdx)) {
|
||||||
|
reusableBuffer.spectrumAnalyser.spanDefault = 20;
|
||||||
|
reusableBuffer.spectrumAnalyser.spanMax = 40;
|
||||||
|
reusableBuffer.spectrumAnalyser.freqDefault = 890;
|
||||||
|
reusableBuffer.spectrumAnalyser.freqMin = 850;
|
||||||
|
reusableBuffer.spectrumAnalyser.freqMax = 930;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
reusableBuffer.spectrumAnalyser.spanDefault = 40; // 40MHz
|
||||||
|
reusableBuffer.spectrumAnalyser.spanMax = 80;
|
||||||
|
reusableBuffer.spectrumAnalyser.freqDefault = 2440; // 2440MHz
|
||||||
|
reusableBuffer.spectrumAnalyser.freqMin = 2400;
|
||||||
|
reusableBuffer.spectrumAnalyser.freqMax = 2485;
|
||||||
|
}
|
||||||
|
|
||||||
|
reusableBuffer.spectrumAnalyser.span = reusableBuffer.spectrumAnalyser.spanDefault * 1000000;
|
||||||
|
reusableBuffer.spectrumAnalyser.freq = reusableBuffer.spectrumAnalyser.freqDefault * 1000000;
|
||||||
|
reusableBuffer.spectrumAnalyser.step = reusableBuffer.spectrumAnalyser.span / LCD_W;
|
||||||
|
reusableBuffer.spectrumAnalyser.dirty = true;
|
||||||
|
moduleState[g_moduleIdx].mode = MODULE_MODE_SPECTRUM_ANALYSER;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (uint8_t i=0; i<SPECTRUM_FIELDS_MAX; i++) {
|
||||||
|
LcdFlags attr = (menuHorizontalPosition == i ? (s_editMode>0 ? INVERS|BLINK : INVERS) : 0);
|
||||||
|
|
||||||
|
switch (i) {
|
||||||
|
case SPECTRUM_FREQUENCY: {
|
||||||
|
uint16_t frequency = reusableBuffer.spectrumAnalyser.freq / 1000000;
|
||||||
|
lcdDrawText(MENUS_MARGIN_LEFT, MENU_FOOTER_TOP, "F:", TEXT_INVERTED_COLOR);
|
||||||
|
lcdDrawNumber(lcdNextPos + 2, MENU_FOOTER_TOP, frequency, attr | TEXT_INVERTED_COLOR);
|
||||||
|
lcdDrawText(lcdNextPos + 2, MENU_FOOTER_TOP, "MHz", TEXT_INVERTED_COLOR);
|
||||||
|
if (attr) {
|
||||||
|
reusableBuffer.spectrumAnalyser.freq = uint32_t(checkIncDec(event, frequency, reusableBuffer.spectrumAnalyser.freqMin, reusableBuffer.spectrumAnalyser.freqMax, 0)) * 1000000;
|
||||||
|
if (checkIncDec_Ret) {
|
||||||
|
reusableBuffer.spectrumAnalyser.dirty = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case SPECTRUM_SPAN:
|
||||||
|
uint8_t span = reusableBuffer.spectrumAnalyser.span / 1000000;
|
||||||
|
lcdDrawText(MENUS_MARGIN_LEFT + 100, MENU_FOOTER_TOP, "S:", TEXT_INVERTED_COLOR);
|
||||||
|
lcdDrawNumber(lcdNextPos + 2, MENU_FOOTER_TOP, reusableBuffer.spectrumAnalyser.span/1000000, attr | TEXT_INVERTED_COLOR);
|
||||||
|
lcdDrawText(lcdNextPos + 2, MENU_FOOTER_TOP, "MHz", TEXT_INVERTED_COLOR);
|
||||||
|
if (attr) {
|
||||||
|
reusableBuffer.spectrumAnalyser.span = checkIncDec(event, span, 1, reusableBuffer.spectrumAnalyser.spanMax, 0) * 1000000;
|
||||||
|
if (checkIncDec_Ret) {
|
||||||
|
reusableBuffer.spectrumAnalyser.step = reusableBuffer.spectrumAnalyser.span / LCD_W;
|
||||||
|
reusableBuffer.spectrumAnalyser.dirty = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (uint32_t frequency = ((reusableBuffer.spectrumAnalyser.freq - reusableBuffer.spectrumAnalyser.span / 2) / 10000000) * 10000000; frequency < reusableBuffer.spectrumAnalyser.freq + reusableBuffer.spectrumAnalyser.span / 2; frequency += 10000000) {
|
||||||
|
int32_t offset = frequency - (reusableBuffer.spectrumAnalyser.freq - reusableBuffer.spectrumAnalyser.span / 2);
|
||||||
|
uint32_t x = offset / reusableBuffer.spectrumAnalyser.step;
|
||||||
|
if (x > 0 && x < LCD_W - 1)
|
||||||
|
lcdDrawVerticalLine(x, MENU_HEADER_HEIGHT, LCD_H - MENU_HEADER_HEIGHT - MENU_FOOTER_HEIGHT, STASHED, CURVE_AXIS_COLOR);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (coord_t y = MENU_HEADER_HEIGHT + (MENU_FOOTER_TOP - MENU_HEADER_HEIGHT) / 8; y < MENU_FOOTER_TOP; y += (MENU_FOOTER_TOP - MENU_HEADER_HEIGHT) / 8) {
|
||||||
|
lcdDrawHorizontalLine(0, y, LCD_W, STASHED, CURVE_AXIS_COLOR);
|
||||||
|
}
|
||||||
|
|
||||||
|
coord_t peak_y = LCD_H;
|
||||||
|
coord_t peak_x = 0;
|
||||||
|
|
||||||
|
coord_t prev_yv = (coord_t)-1;
|
||||||
|
for (coord_t xv=0; xv<LCD_W; xv++) {
|
||||||
|
coord_t yv = MENU_FOOTER_TOP - limit<int>(0, reusableBuffer.spectrumAnalyser.bars[xv] << 1, LCD_H - MENU_HEADER_HEIGHT - MENU_FOOTER_HEIGHT);
|
||||||
|
if (prev_yv != (coord_t)-1) {
|
||||||
|
if (yv < peak_y) {
|
||||||
|
peak_x = xv;
|
||||||
|
peak_y = yv;
|
||||||
|
}
|
||||||
|
if (prev_yv < yv) {
|
||||||
|
for (int y=prev_yv; y<=yv; y+=1) {
|
||||||
|
lcdDrawPoint(xv, y, TEXT_COLOR);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
for (int y=yv; y<=prev_yv; y+=1) {
|
||||||
|
lcdDrawPoint(xv, y, TEXT_COLOR);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
prev_yv = yv;
|
||||||
|
}
|
||||||
|
|
||||||
|
prev_yv = (coord_t)-1;
|
||||||
|
for (coord_t xv=0; xv<LCD_W; xv++) {
|
||||||
|
coord_t yv = MENU_FOOTER_TOP - limit<int>(0, reusableBuffer.spectrumAnalyser.max[xv] << 1, LCD_H - MENU_HEADER_HEIGHT - MENU_FOOTER_HEIGHT);
|
||||||
|
if (prev_yv != (coord_t)-1) {
|
||||||
|
if (prev_yv < yv) {
|
||||||
|
for (int y=prev_yv; y<=yv; y+=1) {
|
||||||
|
lcdDrawPoint(xv, y, TEXT_INVERTED_BGCOLOR);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
for (int y=yv; y<=prev_yv; y+=1) {
|
||||||
|
lcdDrawPoint(xv, y, TEXT_INVERTED_BGCOLOR);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
prev_yv = yv;
|
||||||
|
}
|
||||||
|
|
||||||
|
coord_t y = max<coord_t>(MENU_HEADER_HEIGHT + 1, peak_y - FH);
|
||||||
|
lcdDrawNumber(limit<coord_t>(20, peak_x, LCD_W - 20), y, ((reusableBuffer.spectrumAnalyser.freq - reusableBuffer.spectrumAnalyser.span / 2) + peak_x * (reusableBuffer.spectrumAnalyser.span / LCD_W)) / 1000000, TINSIZE | CENTERED);
|
||||||
|
lcdDrawText(lcdNextPos, y, "M", TINSIZE);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
|
@ -27,9 +27,9 @@ bool addRadioTool(uint8_t index, const char * label)
|
||||||
{
|
{
|
||||||
int8_t sub = menuVerticalPosition - HEADER_LINE;
|
int8_t sub = menuVerticalPosition - HEADER_LINE;
|
||||||
LcdFlags attr = (sub == index ? INVERS : 0);
|
LcdFlags attr = (sub == index ? INVERS : 0);
|
||||||
coord_t y = MENU_HEADER_HEIGHT + 1 + index * FH;
|
coord_t y = MENU_CONTENT_TOP + index * FH;
|
||||||
lcdDrawNumber(3, y, index + 1, LEADING0|LEFT, 2);
|
lcdDrawNumber(MENUS_MARGIN_LEFT, y, index + 1, LEADING0|LEFT, 2);
|
||||||
// BSS lcdDrawText(3*FW, y, label, (sub == index ? INVERS : 0));
|
lcdDrawText(30, y, label, (sub == index ? INVERS : 0));
|
||||||
if (attr && s_editMode > 0) {
|
if (attr && s_editMode > 0) {
|
||||||
s_editMode = 0;
|
s_editMode = 0;
|
||||||
killAllEvents();
|
killAllEvents();
|
||||||
|
@ -46,52 +46,13 @@ void addRadioModuleTool(uint8_t index, const char * label, bool (* tool)(event_t
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#define TOOL_NAME_MAXLEN 16
|
|
||||||
|
|
||||||
#if defined(LUA)
|
#if defined(LUA)
|
||||||
bool readToolName(const char * filename, char * name)
|
|
||||||
{
|
|
||||||
FIL file;
|
|
||||||
char buffer[1024];
|
|
||||||
UINT count;
|
|
||||||
|
|
||||||
if (f_open(&file, filename, FA_READ) != FR_OK) {
|
|
||||||
return "Error opening file";
|
|
||||||
}
|
|
||||||
|
|
||||||
if (f_read(&file, &buffer, sizeof(buffer), &count) != FR_OK) {
|
|
||||||
f_close(&file);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
const char * tns = "TNS|";
|
|
||||||
auto * start = std::search(buffer, buffer + sizeof(buffer), tns, tns + 4);
|
|
||||||
if (start >= buffer + sizeof(buffer))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
start += 4;
|
|
||||||
|
|
||||||
const char * tne = "|TNE";
|
|
||||||
auto * end = std::search(buffer, buffer + sizeof(buffer), tne, tne + 4);
|
|
||||||
if (end >= buffer + sizeof(buffer) || end <= start)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
uint8_t len = end - start;
|
|
||||||
if (len > TOOL_NAME_MAXLEN)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
strncpy(name, start, len);
|
|
||||||
memclear(name + len, TOOL_NAME_MAXLEN + 1 - len);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void addRadioScriptTool(uint8_t index, const char * path)
|
void addRadioScriptTool(uint8_t index, const char * path)
|
||||||
{
|
{
|
||||||
char toolName[TOOL_NAME_MAXLEN + 1];
|
char toolName[TOOL_NAME_MAXLEN + 1];
|
||||||
const char * label;
|
const char * label;
|
||||||
char * ext = (char *)getFileExtension(path);
|
char * ext = (char *)getFileExtension(path);
|
||||||
if (readToolName(path, toolName)) {
|
if (readToolName(toolName, path)) {
|
||||||
label = toolName;
|
label = toolName;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -105,12 +66,6 @@ void addRadioScriptTool(uint8_t index, const char * path)
|
||||||
luaExec(path);
|
luaExec(path);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool isRadioScriptTool(const char * filename)
|
|
||||||
{
|
|
||||||
const char * ext = getFileExtension(filename);
|
|
||||||
return ext && !strcasecmp(ext, SCRIPT_EXT);
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
bool menuRadioTools(event_t event)
|
bool menuRadioTools(event_t event)
|
||||||
|
@ -130,18 +85,18 @@ bool menuRadioTools(event_t event)
|
||||||
|
|
||||||
uint8_t index = 0;
|
uint8_t index = 0;
|
||||||
|
|
||||||
#if 0 // TODO BSS defined(PXX2)
|
#if defined(PXX2)
|
||||||
if (isPXX2ModuleOptionAvailable(reusableBuffer.hardwareAndSettings.modules[INTERNAL_MODULE].information.modelID, MODULE_OPTION_SPECTRUM_ANALYSER))
|
if (isPXX2ModuleOptionAvailable(reusableBuffer.hardwareAndSettings.modules[INTERNAL_MODULE].information.modelID, MODULE_OPTION_SPECTRUM_ANALYSER))
|
||||||
addRadioModuleTool(index++, STR_SPECTRUM_ANALYSER_INT, menuRadioSpectrumAnalyser, INTERNAL_MODULE);
|
addRadioModuleTool(index++, STR_SPECTRUM_ANALYSER_INT, menuRadioSpectrumAnalyser, INTERNAL_MODULE);
|
||||||
|
|
||||||
if (isPXX2ModuleOptionAvailable(reusableBuffer.hardwareAndSettings.modules[INTERNAL_MODULE].information.modelID, MODULE_OPTION_POWER_METER))
|
// if (isPXX2ModuleOptionAvailable(reusableBuffer.hardwareAndSettings.modules[INTERNAL_MODULE].information.modelID, MODULE_OPTION_POWER_METER))
|
||||||
addRadioModuleTool(index++, STR_POWER_METER_INT, menuRadioPowerMeter, INTERNAL_MODULE);
|
// addRadioModuleTool(index++, STR_POWER_METER_INT, menuRadioPowerMeter, INTERNAL_MODULE);
|
||||||
|
|
||||||
if (isPXX2ModuleOptionAvailable(reusableBuffer.hardwareAndSettings.modules[EXTERNAL_MODULE].information.modelID, MODULE_OPTION_SPECTRUM_ANALYSER))
|
if (isPXX2ModuleOptionAvailable(reusableBuffer.hardwareAndSettings.modules[EXTERNAL_MODULE].information.modelID, MODULE_OPTION_SPECTRUM_ANALYSER))
|
||||||
addRadioModuleTool(index++, STR_SPECTRUM_ANALYSER_EXT, menuRadioSpectrumAnalyser, EXTERNAL_MODULE);
|
addRadioModuleTool(index++, STR_SPECTRUM_ANALYSER_EXT, menuRadioSpectrumAnalyser, EXTERNAL_MODULE);
|
||||||
|
|
||||||
if (isPXX2ModuleOptionAvailable(reusableBuffer.hardwareAndSettings.modules[EXTERNAL_MODULE].information.modelID, MODULE_OPTION_POWER_METER))
|
// if (isPXX2ModuleOptionAvailable(reusableBuffer.hardwareAndSettings.modules[EXTERNAL_MODULE].information.modelID, MODULE_OPTION_POWER_METER))
|
||||||
addRadioModuleTool(index++, STR_POWER_METER_EXT, menuRadioPowerMeter, EXTERNAL_MODULE);
|
// addRadioModuleTool(index++, STR_POWER_METER_EXT, menuRadioPowerMeter, EXTERNAL_MODULE);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(LUA)
|
#if defined(LUA)
|
||||||
|
|
|
@ -32,15 +32,6 @@ void menuRadioSpectrumAnalyser(event_t event)
|
||||||
{
|
{
|
||||||
SUBMENU(STR_MENU_SPECTRUM_ANALYSER, 1, {1});
|
SUBMENU(STR_MENU_SPECTRUM_ANALYSER, 1, {1});
|
||||||
|
|
||||||
if (TELEMETRY_STREAMING()) {
|
|
||||||
lcdDrawCenteredText(LCD_H/2, STR_TURN_OFF_RECEIVER);
|
|
||||||
if (event == EVT_KEY_FIRST(KEY_EXIT)) {
|
|
||||||
killEvents(event);
|
|
||||||
popMenu();
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (menuEvent) {
|
if (menuEvent) {
|
||||||
lcdDrawCenteredText(LCD_H/2, STR_STOPPING);
|
lcdDrawCenteredText(LCD_H/2, STR_STOPPING);
|
||||||
lcdRefresh();
|
lcdRefresh();
|
||||||
|
@ -51,6 +42,18 @@ void menuRadioSpectrumAnalyser(event_t event)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (moduleState[g_moduleIdx].mode != MODULE_MODE_SPECTRUM_ANALYSER) {
|
||||||
|
if (TELEMETRY_STREAMING()) {
|
||||||
|
lcdDrawCenteredText(LCD_H/2, STR_TURN_OFF_RECEIVER);
|
||||||
|
if (event == EVT_KEY_FIRST(KEY_EXIT)) {
|
||||||
|
killEvents(event);
|
||||||
|
popMenu();
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
memclear(reusableBuffer.spectrumAnalyser.bars, sizeof(reusableBuffer.spectrumAnalyser.bars));
|
||||||
|
|
||||||
if (isModuleR9MAccess(g_moduleIdx)) {
|
if (isModuleR9MAccess(g_moduleIdx)) {
|
||||||
reusableBuffer.spectrumAnalyser.spanDefault = 20;
|
reusableBuffer.spectrumAnalyser.spanDefault = 20;
|
||||||
reusableBuffer.spectrumAnalyser.spanMax = 40;
|
reusableBuffer.spectrumAnalyser.spanMax = 40;
|
||||||
|
@ -66,8 +69,6 @@ void menuRadioSpectrumAnalyser(event_t event)
|
||||||
reusableBuffer.spectrumAnalyser.freqMax = 2485;
|
reusableBuffer.spectrumAnalyser.freqMax = 2485;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (moduleState[g_moduleIdx].mode != MODULE_MODE_SPECTRUM_ANALYSER) {
|
|
||||||
memclear(reusableBuffer.spectrumAnalyser.bars, sizeof(reusableBuffer.spectrumAnalyser.bars));
|
|
||||||
reusableBuffer.spectrumAnalyser.span = reusableBuffer.spectrumAnalyser.spanDefault * 1000000;
|
reusableBuffer.spectrumAnalyser.span = reusableBuffer.spectrumAnalyser.spanDefault * 1000000;
|
||||||
reusableBuffer.spectrumAnalyser.freq = reusableBuffer.spectrumAnalyser.freqDefault * 1000000;
|
reusableBuffer.spectrumAnalyser.freq = reusableBuffer.spectrumAnalyser.freqDefault * 1000000;
|
||||||
reusableBuffer.spectrumAnalyser.step = reusableBuffer.spectrumAnalyser.span / LCD_W;
|
reusableBuffer.spectrumAnalyser.step = reusableBuffer.spectrumAnalyser.span / LCD_W;
|
||||||
|
|
|
@ -49,48 +49,11 @@ void addRadioModuleTool(uint8_t index, const char * label, void (* tool)(event_t
|
||||||
#define TOOL_NAME_MAXLEN 16
|
#define TOOL_NAME_MAXLEN 16
|
||||||
|
|
||||||
#if defined(LUA)
|
#if defined(LUA)
|
||||||
bool readToolName(const char * filename, char * name)
|
|
||||||
{
|
|
||||||
FIL file;
|
|
||||||
char buffer[1024];
|
|
||||||
UINT count;
|
|
||||||
|
|
||||||
if (f_open(&file, filename, FA_READ) != FR_OK) {
|
|
||||||
return "Error opening file";
|
|
||||||
}
|
|
||||||
|
|
||||||
if (f_read(&file, &buffer, sizeof(buffer), &count) != FR_OK) {
|
|
||||||
f_close(&file);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
const char * tns = "TNS|";
|
|
||||||
auto * start = std::search(buffer, buffer + sizeof(buffer), tns, tns + 4);
|
|
||||||
if (start >= buffer + sizeof(buffer))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
start += 4;
|
|
||||||
|
|
||||||
const char * tne = "|TNE";
|
|
||||||
auto * end = std::search(buffer, buffer + sizeof(buffer), tne, tne + 4);
|
|
||||||
if (end >= buffer + sizeof(buffer) || end <= start)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
uint8_t len = end - start;
|
|
||||||
if (len > TOOL_NAME_MAXLEN)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
strncpy(name, start, len);
|
|
||||||
memclear(name + len, TOOL_NAME_MAXLEN + 1 - len);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void addRadioScriptTool(uint8_t index, const char * path)
|
void addRadioScriptTool(uint8_t index, const char * path)
|
||||||
{
|
{
|
||||||
char toolName[TOOL_NAME_MAXLEN + 1];
|
char toolName[TOOL_NAME_MAXLEN + 1];
|
||||||
|
|
||||||
if (!readToolName(path, toolName)) {
|
if (!readToolName(toolName, path)) {
|
||||||
strAppendFilename(toolName, getBasename(path), TOOL_NAME_MAXLEN);
|
strAppendFilename(toolName, getBasename(path), TOOL_NAME_MAXLEN);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -102,12 +65,6 @@ void addRadioScriptTool(uint8_t index, const char * path)
|
||||||
luaExec(path);
|
luaExec(path);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool isRadioScriptTool(const char * filename)
|
|
||||||
{
|
|
||||||
const char * ext = getFileExtension(filename);
|
|
||||||
return ext && !strcasecmp(ext, SCRIPT_EXT);
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void menuRadioTools(event_t event)
|
void menuRadioTools(event_t event)
|
||||||
|
|
|
@ -22,6 +22,7 @@
|
||||||
|
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <algorithm>
|
||||||
#include "opentx.h"
|
#include "opentx.h"
|
||||||
#include "bin_allocator.h"
|
#include "bin_allocator.h"
|
||||||
#include "lua_api.h"
|
#include "lua_api.h"
|
||||||
|
@ -1073,7 +1074,6 @@ uint32_t luaGetMemUsed(lua_State * L)
|
||||||
return L ? (lua_gc(L, LUA_GCCOUNT, 0) << 10) + lua_gc(L, LUA_GCCOUNTB, 0) : 0;
|
return L ? (lua_gc(L, LUA_GCCOUNT, 0) << 10) + lua_gc(L, LUA_GCCOUNTB, 0) : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void luaInit()
|
void luaInit()
|
||||||
{
|
{
|
||||||
TRACE("luaInit");
|
TRACE("luaInit");
|
||||||
|
@ -1116,3 +1116,46 @@ void luaInit()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool readToolName(char * toolName, const char * filename)
|
||||||
|
{
|
||||||
|
FIL file;
|
||||||
|
char buffer[1024];
|
||||||
|
UINT count;
|
||||||
|
|
||||||
|
if (f_open(&file, filename, FA_READ) != FR_OK) {
|
||||||
|
return "Error opening file";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (f_read(&file, &buffer, sizeof(buffer), &count) != FR_OK) {
|
||||||
|
f_close(&file);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char * tns = "TNS|";
|
||||||
|
auto * start = std::search(buffer, buffer + sizeof(buffer), tns, tns + 4);
|
||||||
|
if (start >= buffer + sizeof(buffer))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
start += 4;
|
||||||
|
|
||||||
|
const char * tne = "|TNE";
|
||||||
|
auto * end = std::search(buffer, buffer + sizeof(buffer), tne, tne + 4);
|
||||||
|
if (end >= buffer + sizeof(buffer) || end <= start)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
uint8_t len = end - start;
|
||||||
|
if (len > TOOL_NAME_MAXLEN)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
strncpy(toolName, start, len);
|
||||||
|
memclear(toolName + len, TOOL_NAME_MAXLEN + 1 - len);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isRadioScriptTool(const char * filename)
|
||||||
|
{
|
||||||
|
const char * ext = getFileExtension(filename);
|
||||||
|
return ext && !strcasecmp(ext, SCRIPT_EXT);
|
||||||
|
}
|
||||||
|
|
|
@ -171,6 +171,10 @@ void registerBitmapClass(lua_State * L);
|
||||||
void luaSetInstructionsLimit(lua_State* L, int count);
|
void luaSetInstructionsLimit(lua_State* L, int count);
|
||||||
int luaLoadScriptFileToState(lua_State * L, const char * filename, const char * mode);
|
int luaLoadScriptFileToState(lua_State * L, const char * filename, const char * mode);
|
||||||
|
|
||||||
|
#define TOOL_NAME_MAXLEN 16
|
||||||
|
bool readToolName(char * toolName, const char * filename);
|
||||||
|
bool isRadioScriptTool(const char * filename);
|
||||||
|
|
||||||
struct LuaMemTracer {
|
struct LuaMemTracer {
|
||||||
const char * script;
|
const char * script;
|
||||||
int lineno;
|
int lineno;
|
||||||
|
|
|
@ -1187,6 +1187,9 @@ union ReusableBuffer
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
uint8_t bars[LCD_W];
|
uint8_t bars[LCD_W];
|
||||||
|
#if defined(COLORLCD)
|
||||||
|
uint8_t max[LCD_W];
|
||||||
|
#endif
|
||||||
uint32_t freq;
|
uint32_t freq;
|
||||||
uint32_t span;
|
uint32_t span;
|
||||||
uint32_t step;
|
uint32_t step;
|
||||||
|
|
|
@ -301,6 +301,9 @@ void Pxx2Pulses::setupSpectrumAnalyser(uint8_t module)
|
||||||
{
|
{
|
||||||
if (reusableBuffer.spectrumAnalyser.dirty) {
|
if (reusableBuffer.spectrumAnalyser.dirty) {
|
||||||
reusableBuffer.spectrumAnalyser.dirty = false;
|
reusableBuffer.spectrumAnalyser.dirty = false;
|
||||||
|
#if defined(PCBHORUS)
|
||||||
|
memclear(&reusableBuffer.spectrumAnalyser.max, sizeof(reusableBuffer.spectrumAnalyser.max));
|
||||||
|
#endif
|
||||||
addFrameType(PXX2_TYPE_C_POWER_METER, PXX2_TYPE_ID_SPECTRUM);
|
addFrameType(PXX2_TYPE_C_POWER_METER, PXX2_TYPE_ID_SPECTRUM);
|
||||||
Pxx2Transport::addByte(0x00);
|
Pxx2Transport::addByte(0x00);
|
||||||
Pxx2Transport::addWord(reusableBuffer.spectrumAnalyser.freq);
|
Pxx2Transport::addWord(reusableBuffer.spectrumAnalyser.freq);
|
||||||
|
|
|
@ -88,6 +88,15 @@ if(NOT UNEXPECTED_SHUTDOWN)
|
||||||
add_definitions(-DNO_UNEXPECTED_SHUTDOWN)
|
add_definitions(-DNO_UNEXPECTED_SHUTDOWN)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
if(INTERNAL_MODULE_PXX1)
|
||||||
|
add_definitions(-DINTERNAL_MODULE_PXX1)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(INTERNAL_MODULE_PXX2)
|
||||||
|
set(PXX2 ON)
|
||||||
|
add_definitions(-DINTERNAL_MODULE_PXX2)
|
||||||
|
endif()
|
||||||
|
|
||||||
include_directories(${RADIO_SRC_DIRECTORY}/fonts/480x272 gui/${GUI_DIR} gui/${GUI_DIR}/layouts)
|
include_directories(${RADIO_SRC_DIRECTORY}/fonts/480x272 gui/${GUI_DIR} gui/${GUI_DIR}/layouts)
|
||||||
|
|
||||||
file(GLOB THEMES_SRC RELATIVE ${RADIO_SRC_DIRECTORY}/gui/480x272 ${RADIO_SRC_DIRECTORY}/gui/480x272/themes/*.cpp)
|
file(GLOB THEMES_SRC RELATIVE ${RADIO_SRC_DIRECTORY}/gui/480x272 ${RADIO_SRC_DIRECTORY}/gui/480x272/themes/*.cpp)
|
||||||
|
@ -123,13 +132,13 @@ if(PXX2 OR LUA)
|
||||||
set(GUI_SRC ${GUI_SRC} radio_tools.cpp)
|
set(GUI_SRC ${GUI_SRC} radio_tools.cpp)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
#if(PXX2)
|
if(PXX2)
|
||||||
# set(GUI_SRC
|
set(GUI_SRC
|
||||||
# ${GUI_SRC}
|
${GUI_SRC}
|
||||||
# ../common/stdlcd/radio_spectrum_analyser.cpp
|
radio_spectrum_analyser.cpp
|
||||||
# ../common/stdlcd/radio_power_meter.cpp
|
# radio_power_meter.cpp
|
||||||
# )
|
)
|
||||||
#endif()
|
endif()
|
||||||
|
|
||||||
if(DISK_CACHE)
|
if(DISK_CACHE)
|
||||||
set(SRC ${SRC} disk_cache.cpp)
|
set(SRC ${SRC} disk_cache.cpp)
|
||||||
|
@ -191,12 +200,3 @@ if(PYTHONINTERP_FOUND)
|
||||||
DEPENDS ${RADIO_DIRECTORY}/src/datastructs.h ${RADIO_DIRECTORY}/util/generate_datacopy.py
|
DEPENDS ${RADIO_DIRECTORY}/src/datastructs.h ${RADIO_DIRECTORY}/util/generate_datacopy.py
|
||||||
)
|
)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(INTERNAL_MODULE_PXX1)
|
|
||||||
add_definitions(-DINTERNAL_MODULE_PXX1)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if(INTERNAL_MODULE_PXX2)
|
|
||||||
set(PXX2 ON)
|
|
||||||
add_definitions(-DINTERNAL_MODULE_PXX2)
|
|
||||||
endif()
|
|
|
@ -238,6 +238,10 @@ void processSpectrumAnalyserFrame(uint8_t module, uint8_t * frame)
|
||||||
uint32_t x = offset / reusableBuffer.spectrumAnalyser.step;
|
uint32_t x = offset / reusableBuffer.spectrumAnalyser.step;
|
||||||
if (x < LCD_W) {
|
if (x < LCD_W) {
|
||||||
reusableBuffer.spectrumAnalyser.bars[x] = 0x80 + power;
|
reusableBuffer.spectrumAnalyser.bars[x] = 0x80 + power;
|
||||||
|
#if defined(COLORLCD)
|
||||||
|
if (reusableBuffer.spectrumAnalyser.bars[x] > reusableBuffer.spectrumAnalyser.max[x])
|
||||||
|
reusableBuffer.spectrumAnalyser.max[x] = reusableBuffer.spectrumAnalyser.bars[x];
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue