diff --git a/src/pages/128x64x1/guiobj.h b/src/pages/128x64x1/guiobj.h index e2e4bd468c..773f6ff5ad 100644 --- a/src/pages/128x64x1/guiobj.h +++ b/src/pages/128x64x1/guiobj.h @@ -120,6 +120,12 @@ struct reorder_obj { guiScrollable_t scrollable; }; +struct scanner_obj { + guiButton_t enable; + guiButton_t scan_mode; + guiButton_t attenuator; +}; + struct telemcfg_obj { guiLabel_t msg; guiLabel_t idx[7]; @@ -367,6 +373,9 @@ struct _gui_objs { struct modelload_obj modelload; struct modelpage_obj modelpage; struct reorder_obj reorder; +#if HAS_SCANNER + struct scanner_obj scanner; +#endif struct telemcfg_obj telemcfg; struct telemtest_obj telemtest1; struct timer_obj timer; diff --git a/src/pages/128x64x1/pagelist.h b/src/pages/128x64x1/pagelist.h index c0a523be74..3770c875fa 100644 --- a/src/pages/128x64x1/pagelist.h +++ b/src/pages/128x64x1/pagelist.h @@ -75,6 +75,9 @@ PAGEDEF(PAGEID_CHANMON, PAGE_ChantestInit, PAGE_ChantestEvent, PAGE_Chant PAGEDEF(PAGEID_TELEMMON, PAGE_TelemtestInit, PAGE_TelemtestEvent, NULL, TX_MENU, _tr_noop("Telemetry monitor")) #endif PAGEDEF(PAGEID_RANGE, PAGE_RangeInit, NULL, PAGE_RangeExit, TX_MENU, _tr_noop("Range Test")) +#if HAS_SCANNER +PAGEDEF(PAGEID_SCANNER, PAGE_ScannerInit, PAGE_ScannerEvent, PAGE_ScannerExit, TX_MENU, _tr_noop("Scanner")) +#endif //------------------- // Pages menu diff --git a/src/pages/128x64x1/pages.h b/src/pages/128x64x1/pages.h index 5d379c1614..2ccc9c0dd3 100644 --- a/src/pages/128x64x1/pages.h +++ b/src/pages/128x64x1/pages.h @@ -14,7 +14,9 @@ struct pagemem { struct timer_page timer_page; struct chantest_page chantest_page; struct range_page range_page; - //struct scanner_page scanner_page; +#if HAS_SCANNER + struct scanner_page scanner_page; +#endif #if HAS_MUSIC_CONFIG struct voiceconfig_page voiceconfig_page; #endif diff --git a/src/pages/128x64x1/scanner_page.c b/src/pages/128x64x1/scanner_page.c new file mode 100644 index 0000000000..fb800295f6 --- /dev/null +++ b/src/pages/128x64x1/scanner_page.c @@ -0,0 +1,66 @@ +/* + This project is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Deviation 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. + + You should have received a copy of the GNU General Public License + along with Deviation. If not, see . + */ + +#include "common.h" +#include "protocol/interface.h" +#include "pages.h" +#include "config/model.h" + +#if HAS_SCANNER +#include "../common/_scanner_page.c" + +static struct scanner_obj * const gui = &gui_objs.u.scanner; +static const char *enablestr_cb(guiObject_t *obj, const void *data) +{ + (void)obj; + (void)data; + return sp->enable ? _tr("On") : _tr("Off"); +} + +static const char *modestr_cb(guiObject_t *obj, const void *data) +{ + (void)obj; + (void)data; + return sp->scan_mode ? _tr("Average") : _tr("Peak"); +} + +static const char *attstr_cb(guiObject_t *obj, const void *data) +{ + (void)obj; + (void)data; + return sp->attenuator ? _tr("-20dB") : _tr("0dB"); +} + +void _draw_page(u8 enable) +{ + (void)enable; + PAGE_ShowHeader(PAGE_GetName(PAGEID_SCANNER)); + GUI_CreateButtonPlateText(&gui->enable, 0, HEADER_HEIGHT, 40, LINE_HEIGHT, &BUTTON_FONT, enablestr_cb, press_enable_cb, NULL); + GUI_CreateButtonPlateText(&gui->scan_mode, LCD_WIDTH/2 - 20, HEADER_HEIGHT, 40, LINE_HEIGHT, &BUTTON_FONT, modestr_cb, press_mode_cb, NULL); + GUI_CreateButtonPlateText(&gui->attenuator, LCD_WIDTH - 40, HEADER_HEIGHT, 40, LINE_HEIGHT, &BUTTON_FONT, attstr_cb, press_attenuator_cb, NULL); +} + +void _draw_channels() +{ + const unsigned offset = HEADER_HEIGHT + LINE_HEIGHT; + // draw a line + int col = (LCD_WIDTH - (MAX_RADIOCHANNEL - MIN_RADIOCHANNEL)) / 2 + sp->channel; + int height = sp->channelnoise[sp->channel] * (LCD_HEIGHT - offset) / 0x1F; + + LCD_DrawFastVLine(col, offset, LCD_HEIGHT - height, 0); + LCD_DrawFastVLine(col, LCD_HEIGHT - height, LCD_HEIGHT, Display.xygraph.grid_color); +} + +#endif //HAS_SCANNER diff --git a/src/pages/320x240x16/pages.h b/src/pages/320x240x16/pages.h index 488897ffbc..e1bf70b6ac 100644 --- a/src/pages/320x240x16/pages.h +++ b/src/pages/320x240x16/pages.h @@ -2,7 +2,6 @@ #define _PAGES_H_ #include "../common/_pages.h" -#include "scanner_page.h" #include "icons.h" #include "guiobj.h" diff --git a/src/pages/320x240x16/scanner_page.c b/src/pages/320x240x16/scanner_page.c index 71a66f2e22..d4763c3726 100644 --- a/src/pages/320x240x16/scanner_page.c +++ b/src/pages/320x240x16/scanner_page.c @@ -18,51 +18,10 @@ #include "pages.h" #include "config/model.h" + #if HAS_SCANNER -static struct scanner_page * const sp = &pagemem.u.scanner_page; +#include "../common/_scanner_page.c" static struct scanner_obj * const gui = &gui_objs.u.scanner; -static u8 scanState = 0; - -u16 scan_cb() -{ - int delay; - - if(scanState == 0) { - if(sp->time_to_scan == 0) { - CYRF_ConfigRFChannel(sp->channel + MIN_RADIOCHANNEL); - if(sp->attenuator) { - CYRF_WriteRegister(CYRF_06_RX_CFG, 0x0A); - } else { - CYRF_WriteRegister(CYRF_06_RX_CFG, 0x4A); - } - sp->time_to_scan = 1; - } - scanState = 1; - delay = 300; //slow channel require 270usec for synthesizer to settle - } else { - if ( !(CYRF_ReadRegister(CYRF_05_RX_CTRL) & 0x80)) { - CYRF_WriteRegister(CYRF_05_RX_CTRL, 0x80); //Prepare to receive - Delay(10); - CYRF_ReadRegister(CYRF_13_RSSI); //dummy read - Delay(15); - } - int rssi = CYRF_ReadRegister(CYRF_13_RSSI) & 0x1F; - if(sp->scan_mode) { - sp->channelnoise[sp->channel] = (sp->channelnoise[sp->channel] + rssi) / 2; - } else { - if(rssi > sp->channelnoise[sp->channel]) - sp->channelnoise[sp->channel] = rssi; - } - scanState++; - delay = 300; - if(scanState == 5) { - scanState = 0; - delay = 50; - } - } - return delay; -} - static s32 show_bar_cb(void *data) { long ch = (long)data; @@ -90,44 +49,7 @@ static const char *attstr_cb(guiObject_t *obj, const void *data) return sp->attenuator ? _tr("Att.: -20dB") : _tr("Att.: 0dB"); } -static void press_enable_cb(guiObject_t *obj, const void *data) -{ - (void)data; -#ifndef ENABLE_MODULAR - sp->enable ^= 1; - if (sp->enable) { - PROTOCOL_DeInit(); - DEVO_Cmds(0); //Switch to DEVO configuration - PROTOCOL_SetBindState(0); //Disable binding message - CLOCK_StopTimer(); - CYRF_SetTxRxMode(RX_EN); //Receive mode - CLOCK_StartTimer(1250, scan_cb); - } else { - PROTOCOL_Init(0); - } -#endif - GUI_Redraw(obj); -} - -static void press_mode_cb(guiObject_t *obj, const void *data) -{ - (void)data; -#ifndef ENABLE_MODULAR - sp->scan_mode ^= 1; -#endif - GUI_Redraw(obj); -} - -static void press_attenuator_cb(guiObject_t *obj, const void *data) -{ - (void)data; -#ifndef ENABLE_MODULAR - sp->attenuator ^= 1; -#endif - GUI_Redraw(obj); -} - -void PAGE_ScannerInit(int page) +void _draw_page(u8 enable) { enum { SCANBARWIDTH = (LCD_WIDTH / (MAX_RADIOCHANNEL - MIN_RADIOCHANNEL + 1)), @@ -135,44 +57,19 @@ void PAGE_ScannerInit(int page) SCANBARHEIGHT = (LCD_HEIGHT - 78), }; u8 i; - (void)page; - PAGE_SetModal(0); + (void)enable; PAGE_ShowHeader(PAGE_GetName(PAGEID_SCANNER)); - sp->enable = 0; GUI_CreateButton(&gui->enable, LCD_WIDTH/2 - 152, 40, BUTTON_96, enablestr_cb, press_enable_cb, NULL); - sp->scan_mode = 0; GUI_CreateButton(&gui->scan_mode, LCD_WIDTH/2 - 48, 40, BUTTON_96, modestr_cb, press_mode_cb, NULL); - sp->attenuator = 0; - GUI_CreateButton(&gui->attenuator, LCD_WIDTH/2 + 56, 40, BUTTON_96, attstr_cb, press_attenuator_cb, NULL); - sp->channel = 0; - sp->time_to_scan = 0; + GUI_CreateButton(&gui->attenuator, LCD_WIDTH/2 + 56, 40, BUTTON_96, attstr_cb, press_attenuator_cb, NULL); for(i = 0; i < (MAX_RADIOCHANNEL - MIN_RADIOCHANNEL + 1); i++) { GUI_CreateBarGraph(&gui->bar[i], SCANBARXOFFSET + i * SCANBARWIDTH, 70, SCANBARWIDTH, SCANBARHEIGHT, 2, 31, BAR_VERTICAL, show_bar_cb, (void *)((long)i)); - sp->channelnoise[i] = 0; } } -void PAGE_ScannerEvent() +void _draw_channels() { -#ifndef ENABLE_MODULAR - if(! sp->enable) - return; GUI_Redraw(&gui->bar[sp->channel]); - //printf("%02X : %d\n",sp->channel,sp->channelnoise[sp->channel]); - sp->channel++; - if(sp->channel == (MAX_RADIOCHANNEL - MIN_RADIOCHANNEL + 1)) - sp->channel = 0; - sp->channelnoise[sp->channel] = 0; - sp->time_to_scan = 0; -#endif -} - -void PAGE_ScannerExit() -{ -#ifndef ENABLE_MODULAR - if(sp->enable) - PROTOCOL_Init(0); -#endif } #endif //HAS_SCANNER diff --git a/src/pages/480x272x16/scanner_page.h b/src/pages/480x272x16/scanner_page.h deleted file mode 100644 index 635ff6a493..0000000000 --- a/src/pages/480x272x16/scanner_page.h +++ /dev/null @@ -1 +0,0 @@ -#include "../320x240x16/scanner_page.h" diff --git a/src/pages/common/_pages.h b/src/pages/common/_pages.h index b7f2d63c65..4f3351b0b6 100644 --- a/src/pages/common/_pages.h +++ b/src/pages/common/_pages.h @@ -23,6 +23,7 @@ #include "config/display.h" #include "rtc_config.h" #include "voiceconfig_page.h" +#include "scanner_page.h" #define PAGE_NAME_MAX 10 diff --git a/src/pages/common/_scanner_page.c b/src/pages/common/_scanner_page.c new file mode 100644 index 0000000000..f94b8b1b59 --- /dev/null +++ b/src/pages/common/_scanner_page.c @@ -0,0 +1,143 @@ +/* + This project is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Deviation 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. + + You should have received a copy of the GNU General Public License + along with Deviation. If not, see . + */ + +static struct scanner_page * const sp = &pagemem.u.scanner_page; + +static void _draw_page(u8 enable); +static void _draw_channels(void); +static u16 scan_cb(); + +#ifdef ENABLE_MODULAR +#error "Not supported in MODULAR build" +#endif + +// The high level interface to do the scan +static void _scan_enable(int enable) +{ + if (enable) { + PROTOCOL_DeInit(); + DEVO_Cmds(0); //Switch to DEVO configuration + PROTOCOL_SetBindState(0); //Disable binding message + CLOCK_StopTimer(); + CYRF_SetTxRxMode(RX_EN); //Receive mode + CLOCK_StartTimer(1250, scan_cb); + } else { + PROTOCOL_Init(0); + } +} + +static void _scan_next() +{ + CYRF_ConfigRFChannel(sp->channel + MIN_RADIOCHANNEL); + if(sp->attenuator) { + CYRF_WriteRegister(CYRF_06_RX_CFG, 0x0A); + } else { + CYRF_WriteRegister(CYRF_06_RX_CFG, 0x4A); + } +} + +static int _scan_rssi() +{ + if ( !(CYRF_ReadRegister(CYRF_05_RX_CTRL) & 0x80)) { + CYRF_WriteRegister(CYRF_05_RX_CTRL, 0x80); //Prepare to receive + Delay(10); + CYRF_ReadRegister(CYRF_13_RSSI); //dummy read + Delay(15); + } +#ifdef EMULATOR + return rand32() % 0x1F; +#else + return CYRF_ReadRegister(CYRF_13_RSSI) & 0x1F; +#endif +} + +u16 scan_cb() +{ + int delay; + if(sp->scanState == 0) { + if(sp->time_to_scan == 0) { + _scan_next(); + sp->time_to_scan = 1; + } + sp->scanState = 1; + delay = 300; //slow channel require 270usec for synthesizer to settle + } else { + int rssi = _scan_rssi(); + if(sp->scan_mode) { + sp->channelnoise[sp->channel] = (sp->channelnoise[sp->channel] + rssi) / 2; + } else { + if(rssi > sp->channelnoise[sp->channel]) + sp->channelnoise[sp->channel] = rssi; + } + sp->scanState++; + delay = 300; + if(sp->scanState == 5) { + sp->scanState = 0; + delay = 50; + } + } + return delay; +} + +static void press_enable_cb(guiObject_t *obj, const void *data) +{ + (void)data; + sp->enable ^= 1; + _scan_enable(sp->enable); + GUI_Redraw(obj); +} + +static void press_mode_cb(guiObject_t *obj, const void *data) +{ + (void)data; + sp->scan_mode ^= 1; + GUI_Redraw(obj); +} + +static void press_attenuator_cb(guiObject_t *obj, const void *data) +{ + (void)data; + sp->attenuator ^= 1; + GUI_Redraw(obj); +} + +void PAGE_ScannerInit(int page) +{ + (void)page; + memset(sp, 0, sizeof(struct scanner_page)); + + PAGE_SetModal(0); + _draw_page(1); +} + +void PAGE_ScannerEvent() +{ + if(! sp->enable) + return; + + // draw the channels + _draw_channels(); + + sp->channel++; + if(sp->channel == (MAX_RADIOCHANNEL - MIN_RADIOCHANNEL + 1)) + sp->channel = 0; + sp->channelnoise[sp->channel] = 0; + sp->time_to_scan = 0; +} + +void PAGE_ScannerExit() +{ + _scan_enable(0); +} diff --git a/src/pages/320x240x16/scanner_page.h b/src/pages/common/scanner_page.h similarity index 94% rename from src/pages/320x240x16/scanner_page.h rename to src/pages/common/scanner_page.h index 7714b3df21..36e27668fd 100644 --- a/src/pages/320x240x16/scanner_page.h +++ b/src/pages/common/scanner_page.h @@ -7,6 +7,7 @@ struct scanner_page { u8 channelnoise[MAX_RADIOCHANNEL - MIN_RADIOCHANNEL + 1]; u8 channel; + u8 scanState; u8 time_to_scan; u8 enable; u8 scan_mode; diff --git a/src/target/devo10/target_defs.h b/src/target/devo10/target_defs.h index 3af5f3a111..14b35bb36b 100644 --- a/src/target/devo10/target_defs.h +++ b/src/target/devo10/target_defs.h @@ -18,7 +18,7 @@ #define HAS_VIBRATINGMOTOR 1 #define HAS_DATALOG 1 #define HAS_LAYOUT_EDITOR 1 -#define HAS_SCANNER 0 +#define HAS_SCANNER 1 #define HAS_EXTRA_SWITCHES 0 #define HAS_EXTRA_BUTTONS 0 #define HAS_MULTIMOD_SUPPORT 1 diff --git a/src/target/devo12e/target_defs.h b/src/target/devo12e/target_defs.h index 91f845a840..e93c06719c 100644 --- a/src/target/devo12e/target_defs.h +++ b/src/target/devo12e/target_defs.h @@ -18,7 +18,7 @@ #define HAS_VIBRATINGMOTOR 1 #define HAS_DATALOG 1 #define HAS_LAYOUT_EDITOR 1 -#define HAS_SCANNER 0 +#define HAS_SCANNER 1 #define HAS_EXTRA_SWITCHES 0 #define HAS_EXTRA_BUTTONS 0 #define HAS_MULTIMOD_SUPPORT 1 diff --git a/src/target/devo7e-256/target_defs.h b/src/target/devo7e-256/target_defs.h index 12710e8d7c..bcb4c8048a 100644 --- a/src/target/devo7e-256/target_defs.h +++ b/src/target/devo7e-256/target_defs.h @@ -17,7 +17,7 @@ #define HAS_RTC 0 #define HAS_VIBRATINGMOTOR 1 #define HAS_DATALOG 1 -#define HAS_SCANNER 0 +#define HAS_SCANNER 1 #define HAS_LAYOUT_EDITOR 1 #define HAS_EXTRA_SWITCHES OPTIONAL #define HAS_SWITCHES_NOSTOCK 1 diff --git a/src/target/ir8m/target_defs.h b/src/target/ir8m/target_defs.h index 171dfd4ccc..293686449f 100644 --- a/src/target/ir8m/target_defs.h +++ b/src/target/ir8m/target_defs.h @@ -17,7 +17,7 @@ #define HAS_RTC 0 #define HAS_VIBRATINGMOTOR 1 #define HAS_DATALOG 1 -#define HAS_SCANNER 0 +#define HAS_SCANNER 1 #define HAS_LAYOUT_EDITOR 1 #define HAS_EXTRA_SWITCHES OPTIONAL #define HAS_SWITCHES_NOSTOCK 1 diff --git a/src/target/t8sg/target_defs.h b/src/target/t8sg/target_defs.h index 340b61e6de..86d280ff0e 100644 --- a/src/target/t8sg/target_defs.h +++ b/src/target/t8sg/target_defs.h @@ -17,7 +17,7 @@ #define HAS_RTC 0 #define HAS_VIBRATINGMOTOR 1 #define HAS_DATALOG 1 -#define HAS_SCANNER 0 +#define HAS_SCANNER 1 #define HAS_LAYOUT_EDITOR 1 #define HAS_EXTRA_SWITCHES OPTIONAL #define HAS_SWITCHES_NOSTOCK 1 diff --git a/src/target/t8sg_v2/target_defs.h b/src/target/t8sg_v2/target_defs.h index 106460a122..6b767a4947 100644 --- a/src/target/t8sg_v2/target_defs.h +++ b/src/target/t8sg_v2/target_defs.h @@ -17,7 +17,7 @@ #define HAS_RTC 0 #define HAS_VIBRATINGMOTOR 1 #define HAS_DATALOG 1 -#define HAS_SCANNER 0 +#define HAS_SCANNER 1 #define HAS_LAYOUT_EDITOR 1 #define HAS_EXTRA_SWITCHES OPTIONAL #define HAS_SWITCHES_NOSTOCK 1 diff --git a/src/target/t8sg_v2_plus/target_defs.h b/src/target/t8sg_v2_plus/target_defs.h index a2c23aa3e7..da476dee82 100644 --- a/src/target/t8sg_v2_plus/target_defs.h +++ b/src/target/t8sg_v2_plus/target_defs.h @@ -17,7 +17,7 @@ #define HAS_RTC 0 #define HAS_VIBRATINGMOTOR 1 #define HAS_DATALOG 1 -#define HAS_SCANNER 0 +#define HAS_SCANNER 1 #define HAS_LAYOUT_EDITOR 1 #define HAS_EXTRA_SWITCHES OPTIONAL #define HAS_SWITCHES_NOSTOCK 1