some more cleanup, slightly simpler screens configuration, additional screen layouts for ILI9225

This commit is contained in:
Hansi, dl9rdz 2019-10-18 23:29:43 +02:00
parent 22bf0f8c21
commit 3ebdab2676
7 changed files with 187 additions and 101 deletions

View File

@ -387,15 +387,23 @@ struct st_configitems config_list[] = {
{"wifi", "Wifi mode (0/1/2/3)", 0, &sonde.config.wifi},
{"debug", "Debug mode (0/1)", 0, &sonde.config.debug},
{"maxsonde", "Maxsonde", 0, &sonde.config.maxsonde},
{"display", "Display mode (1/2/3)", 0, &sonde.config.display},
{"display", "Display screens (scan,default,...)", -6, sonde.config.display},
/* Spectrum display settings */
{"spectrum", "Show spectrum (-1=no, 0=forever, >0=seconds)", 0, &sonde.config.spectrum},
{"startfreq", "Startfreq (MHz)", 0, &sonde.config.startfreq},
{"channelbw", "Bandwidth (kHz)", 0, &sonde.config.channelbw},
{"marker", "Spectrum MHz marker", 0, &sonde.config.marker},
{"noisefloor", "Sepctrum noisefloor", 0, &sonde.config.noisefloor},
/* decoder settings */
{"", "Receiver configuration", -5, NULL},
{"showafc", "Show AFC value", 0, &sonde.config.showafc},
{"freqofs", "RX frequency offset (Hz)", 0, &sonde.config.freqofs},
{"rs41.agcbw", "RS41 AGC bandwidth", 0, &sonde.config.rs41.agcbw},
{"rs41.rxbw", "RS41 RX bandwidth", 0, &sonde.config.rs41.rxbw},
{"rs92.rxbw", "RS92 RX (and AGC) bandwidth", 0, &sonde.config.rs92.rxbw},
{"rs92.alt2d", "RS92 2D fix default altitude", 0, &sonde.config.rs92.alt2d},
{"dfm.agcbw", "DFM6/9 AGC bandwidth", 0, &sonde.config.dfm.agcbw},
{"dfm.rxbw", "DFM6/9 RX bandwidth", 0, &sonde.config.dfm.rxbw},
{"", "Data feed configuration", -5, NULL},
/* APRS settings */
{"call", "Call", 8, sonde.config.call},
@ -415,14 +423,6 @@ struct st_configitems config_list[] = {
{"tcp.port", "APRS TCP Port", 0, &sonde.config.tcpfeed.port},
{"tcp.idformat", "DFM ID Format", -2, &sonde.config.tcpfeed.idformat},
{"tcp.highrate", "Rate limit", 0, &sonde.config.tcpfeed.highrate},
/* decoder settings */
{"", "Receiver configuration", -5, NULL},
{"rs41.agcbw", "RS41 AGC bandwidth", 0, &sonde.config.rs41.agcbw},
{"rs41.rxbw", "RS41 RX bandwidth", 0, &sonde.config.rs41.rxbw},
{"rs92.rxbw", "RS92 RX (and AGC) bandwidth", 0, &sonde.config.rs92.rxbw},
{"rs92.alt2d", "RS92 2D fix default altitude", 0, &sonde.config.rs92.alt2d},
{"dfm.agcbw", "DFM6/9 AGC bandwidth", 0, &sonde.config.dfm.agcbw},
{"dfm.rxbw", "DFM6/9 RX bandwidth", 0, &sonde.config.dfm.rxbw},
/* Hardware dependeing settings */
{"", "Hardware configuration (requires reboot)", -5, NULL},
{"disptype", "Display type (0=OLED/SSD1306, 1=TFT/ILI9225, 2=OLED/SH1106)", 0, &sonde.config.disptype},
@ -468,6 +468,25 @@ void addConfigHeading(char *ptr, const char *label) {
strcat(ptr, label);
strcat(ptr, "</th></tr>\n");
}
void addConfigInt8List(char *ptr, int idx, const char *label, int8_t *list) {
sprintf(ptr + strlen(ptr), "<tr><td>%s", label);
for (int i = 0; i < disp.nLayouts; i++) {
sprintf(ptr + strlen(ptr), "<br>%d=%s", i, disp.layouts[i].label);
}
sprintf(ptr + strlen(ptr), "</td><td><input name=\"CFG%d\" type=\"text\" value=\"", idx);
if (*list == -1) {
strcat(ptr, "0");
}
else {
sprintf(ptr + strlen(ptr), "%d", list[0]);
list++;
}
while (*list != -1) {
sprintf(ptr + strlen(ptr), ",%d", *list);
list++;
}
strcat(ptr, "\"/></td></tr>\n");
}
const char *createConfigForm() {
char *ptr = message;
@ -476,6 +495,10 @@ const char *createConfigForm() {
switch (config_list[i].type) {
case -5: // Heading
addConfigHeading(ptr, config_list[i].label);
break;
case -6: // List of int8 values
addConfigInt8List(ptr, i, config_list[i].label, (int8_t *)config_list[i].data);
break;
case -3: // in/offt
addConfigOnOffEntry(ptr, i, config_list[i].label, (int *)config_list[i].data);
break;
@ -1112,7 +1135,6 @@ int scanI2Cdevice(void)
}
extern int initlevels[40];
extern DispInfo *layouts;
bool pmu_irq = false;
@ -1228,10 +1250,10 @@ void setup()
sonde.clearDisplay();
setupWifiList();
Serial.printf("before disp.initFromFile... layouts is %p", layouts);
Serial.printf("before disp.initFromFile... layouts is %p", disp.layouts);
disp.initFromFile();
Serial.printf("disp.initFromFile... layouts is %p", layouts);
Serial.printf("disp.initFromFile... layouts is %p", disp.layouts);
// == show initial values from config.txt ========================= //
@ -1453,6 +1475,10 @@ void loopDecoder() {
Serial.println("updateDisplay done");
}
void setCurrentDisplay(int value) {
Serial.printf("setCurrentDisplay: setting index %d, entry %d\b", value, sonde.config.display[value]);
currentDisplay = sonde.config.display[value];
}
void loopSpectrum() {
int marker = 0;
@ -1469,7 +1495,7 @@ void loopSpectrum() {
enterMode(ST_WIFISCAN);
return;
case KP_DOUBLE:
currentDisplay = 0;
setCurrentDisplay(0);
enterMode(ST_DECODER);
return;
default: break;
@ -1494,7 +1520,7 @@ void loopSpectrum() {
disp.rdis->drawString(0, 1 + marker, buf);
disp.rdis->drawString(2, 1 + marker, "Sec.");
if (remaining <= 0) {
currentDisplay = 0;
setCurrentDisplay(0);
enterMode(ST_DECODER);
}
}
@ -1533,7 +1559,9 @@ void enableNetwork(bool enable) {
SetupAsyncServer();
udp.begin(WiFi.localIP(), LOCALUDPPORT);
MDNS.addService("http", "tcp", 80);
if(sonde.config.kisstnc.active) { tncserver.begin(); }
if (sonde.config.kisstnc.active) {
tncserver.begin();
}
connected = true;
} else {
MDNS.end();
@ -1744,7 +1772,7 @@ void initialMode() {
if (sonde.config.spectrum != -1) { // enable Spectrum in config.txt: spectrum=number_of_seconds
startSpectrumDisplay();
} else {
currentDisplay = 0;
setCurrentDisplay(0);
enterMode(ST_DECODER);
}
}
@ -1861,15 +1889,6 @@ void loopWifiScan() {
}
enableNetwork(true);
initialMode();
#if 0
// done already in initialMode
if (sonde.config.spectrum != -1) { // enable Spectrum in config.txt: spectrum=number_of_seconds (0=forever)
enterMode(ST_SPECTRUM);
} else {
currentDisplay = 0;
enterMode(ST_DECODER);
}
#endif
}

View File

@ -35,15 +35,17 @@ wifi=3
# TCP/IP KISS TNC in port 14590 for APRSdroid (0=disabled, 1=enabled)
kisstnc.active = 1
# display mode: 1=standard 2=fieldmode 3=field w/sondetype
display=1
# display configuration. List of "displays"
# first entry: "Scanner" display
# second entry: default "Receiver" display
# additional entries: alternative receiver display, activated by button
display=0,1,2,3,4
#-------------------------------#
# Spectrum display settings
#-------------------------------#
startfreq=400
channelbw=10
spectrum=10
timer=1
noisefloor=-125
marker=1
#-------------------------------#

View File

@ -90,7 +90,7 @@
# => Button press activates default receiver view, double press does nothing
# Mid press activates Spectrum display, long press activates Wifi scan
# - key2 has no function
@Scanner:5
@Scanner
timer=-1,0,0
key1action=D,#,F,W
key2action=#,#,#,#
@ -113,7 +113,7 @@ timeaction=#,D,+
# - timer actions: #,#,0
# (norx timer: if no signal for >20 seconds: go back to scanner mode)
#
@Legacy:11
@Legacy
timer=-1,-1,20000
key1action=+,0,F,W
key2action=2,#,#,#
@ -133,7 +133,7 @@ timeaction=#,#,0
############
# Configuratoon for "Field" display (display 2)
# similar to @Legacy, but no norx timer, and Key2 goes to display 4
@Field:7
@Field
timer=-1,-1,-1
key1action=+,0,F,W
key2action=3,#,#,#
@ -149,7 +149,7 @@ timeaction=#,#,#
############
# Configuration for "Field2" display (display 3)
# similar to @Field
@Field2:9
@Field2
timer=-1,-1,-1
key1action=+,0,F,W
key2action=4,#,#,#
@ -167,7 +167,7 @@ timeaction=#,#,#
#############
# Configuration for "GPS" display
# not yet the final version, just for testing
@GPSDIST:14
@GPSDIST
timer=-1,-1,-1
key1action=+,0,F,W
key2action=1,#,#,#
@ -187,3 +187,45 @@ timeaction=#,#,#
7,2=xd=
7,4=gD
7,12=gI°
############
# Scan display for large 2" TFT dispaly
@ScannerTFT
timer=-1,0,0
key1action=D,#,F,W
key2action=#,#,#,#
timeaction=#,D,+
font=5,6
0,0=XScan:
0,8=T
3,0=F MHz
5,0=S
7,5=n
############
@MainTFT
timer=-1,-1,20000
key1action=+,0,F,W
key2action=2,#,#,#
timeaction=#,#,0
color=FFD700
0,0=Is
color=0000FF
0,9,-7=f
1,1,6=c
1,12,-4=t
color=00ff00
2,0=L
4,0=O
color=FFA500
2,9,-7=A
3,9,-7=vm/s
color=AA5522
4,9,-7=hkkm/h
color=FFFFFF
6,2=r
7,0=xd=
7,2,6=gD
7,12=gI

View File

@ -163,13 +163,12 @@ uint8_t gpsActions[] = {
ACT_NONE, ACT_NONE, ACT_NONE};
DispInfo staticLayouts[5] = {
{ searchLayout, searchActions, searchTimeouts },
{ legacyLayout, legacyActions, legacyTimeouts },
{ fieldLayout, fieldActions, fieldTimeouts },
{ field2Layout, field2Actions, fieldTimeouts },
{ gpsLayout, gpsActions, fieldTimeouts } };
{ searchLayout, searchActions, searchTimeouts, "StaticSearch" },
{ legacyLayout, legacyActions, legacyTimeouts, "StaticLegacy" },
{ fieldLayout, fieldActions, fieldTimeouts, "StaticField1" },
{ field2Layout, field2Actions, fieldTimeouts, "StaticFiel2" },
{ gpsLayout, gpsActions, fieldTimeouts, "StaticGPS" } };
DispInfo *layouts = staticLayouts;
/////////////// Wrapper code for various display
@ -413,7 +412,7 @@ void ILI9225Display::drawBitmap(uint16_t x1, uint16_t y1, const uint16_t* bitmap
void ILI9225Display::welcome() {
tft->clear();
setFont(6);
drawString(0, 0*22, version_name, WIDTH_AUTO, 0xff77);
drawString(0, 0*22, version_name, WIDTH_AUTO, 0xff00);
setFont(5);
drawString(0, 1*22, "RS41,RS92,DFM6/9");
drawString(0, 3*22, version_id);
@ -503,10 +502,11 @@ void Display::init() {
Display::Display() {
layouts = staticLayouts;
setLayout(0);
}
#define MAXSCREENS 10
#define MAXSCREENS 20
#define DISP_ACTIONS_N 12
#define DISP_TIMEOUTS_N 3
@ -522,7 +522,7 @@ void Display::freeLayouts() {
free(old);
}
int Display::allocDispInfo(int entries, DispInfo *d)
int Display::allocDispInfo(int entries, DispInfo *d, char *label)
{
int totalsize = (entries+1)*sizeof(DispEntry) + DISP_ACTIONS_N*sizeof(uint8_t) + DISP_TIMEOUTS_N * sizeof(int16_t);
char *mem = (char *)malloc(totalsize);
@ -537,6 +537,8 @@ int Display::allocDispInfo(int entries, DispInfo *d)
d->actions[0] = ACT_NONE;
d->timeouts = (int16_t *)mem;
d->label = label;
Serial.printf("allocated %d bytes (%d entries) for %p (addr=%p)\n", totalsize, entries, d, d->de);
return 0;
}
@ -632,17 +634,35 @@ static uint8_t ACTION(char c) {
return ACT_NONE;
}
int Display::countEntries(File f) {
int pos = f.position();
int n = 0;
while(1) {
String line = f.readStringUntil('\n');
line.trim();
const char *c=line.c_str();
if(*c=='#') continue;
if(*c>='0'&&*c<='9') n++;
if(strchr(c,'=')) continue;
break;
}
f.seek(pos, SeekSet);
Serial.printf("Counted %d entries\n", n);
return n;
}
void Display::initFromFile() {
File d = SPIFFS.open("/screens.txt", "r");
if(!d) return;
freeLayouts();
DispInfo *layouts = (DispInfo *)malloc(MAXSCREENS * sizeof(DispInfo));
if(!layouts) {
DispInfo *newlayouts = (DispInfo *)malloc(MAXSCREENS * sizeof(DispInfo));
if(!newlayouts) {
Serial.println("Init from file: FAILED, using static layouts");
layouts = staticLayouts;
return;
}
memset(layouts, 0, MAXSCREENS * sizeof(DispInfo));
memset(newlayouts, 0, MAXSCREENS * sizeof(DispInfo));
// default color
colfg = 0xffff; // white; only used for ILI9225
@ -665,15 +685,11 @@ void Display::initFromFile() {
Serial.printf("Illegal start of screen: %s\n", s);
continue;
}
char *num = strchr(s, ':');
if(!num) {
Serial.println("Line missing size length indication");
continue;
}
entrysize = atoi(num+1);
entrysize = countEntries(d);
Serial.printf("Reading entry with %d elements\n", entrysize);
idx++;
int res = allocDispInfo(entrysize, &layouts[idx]);
int res = allocDispInfo(entrysize, &newlayouts[idx], strdup(s+1));
Serial.printf("allocDispInfo: idx %d: label is %p - %s\n",idx,newlayouts[idx].label, newlayouts[idx].label);
if(res<0) {
Serial.println("Error allocating memory for disp info");
continue;
@ -683,29 +699,29 @@ void Display::initFromFile() {
break;
default: // parse content... (additional data or line `what`)
if(strncmp(s,"timer=",6)==0) { // timer values
sscanf(s+6, "%hd,%hd,%hd", layouts[idx].timeouts, layouts[idx].timeouts+1, layouts[idx].timeouts+2);
Serial.printf("timer values: %d, %d, %d\n", layouts[idx].timeouts[0], layouts[idx].timeouts[1], layouts[idx].timeouts[2]);
sscanf(s+6, "%hd,%hd,%hd", newlayouts[idx].timeouts, newlayouts[idx].timeouts+1, newlayouts[idx].timeouts+2);
Serial.printf("timer values: %d, %d, %d\n", newlayouts[idx].timeouts[0], newlayouts[idx].timeouts[1], newlayouts[idx].timeouts[2]);
} else if(strncmp(s, "key1action=",11)==0) { // key 1 actions
char c1,c2,c3,c4;
sscanf(s+11, "%c,%c,%c,%c", &c1, &c2, &c3, &c4);
layouts[idx].actions[1] = ACTION(c1);
layouts[idx].actions[2] = ACTION(c2);
layouts[idx].actions[3] = ACTION(c3);
layouts[idx].actions[4] = ACTION(c4);
newlayouts[idx].actions[1] = ACTION(c1);
newlayouts[idx].actions[2] = ACTION(c2);
newlayouts[idx].actions[3] = ACTION(c3);
newlayouts[idx].actions[4] = ACTION(c4);
} else if(strncmp(s, "key2action=",11)==0) { // key 2 actions
char c1,c2,c3,c4;
sscanf(s+11, "%c,%c,%c,%c", &c1, &c2, &c3, &c4);
layouts[idx].actions[5] = ACTION(c1);
layouts[idx].actions[6] = ACTION(c2);
layouts[idx].actions[7] = ACTION(c3);
layouts[idx].actions[8] = ACTION(c4);
newlayouts[idx].actions[5] = ACTION(c1);
newlayouts[idx].actions[6] = ACTION(c2);
newlayouts[idx].actions[7] = ACTION(c3);
newlayouts[idx].actions[8] = ACTION(c4);
Serial.printf("parsing key2action: %c %c %c %c\n", c1, c2, c3, c4);
} else if(strncmp(s, "timeaction=",11)==0) { // timer actions
char c1,c2,c3;
sscanf(s+11, "%c,%c,%c", &c1, &c2, &c3);
layouts[idx].actions[9] = ACTION(c1);
layouts[idx].actions[10] = ACTION(c2);
layouts[idx].actions[11] = ACTION(c3);
newlayouts[idx].actions[9] = ACTION(c1);
newlayouts[idx].actions[10] = ACTION(c2);
newlayouts[idx].actions[11] = ACTION(c3);
} else if(strncmp(s, "fonts=",6)==0) { // change font
sscanf(s+6, "%d,%d", &fontsma, &fontlar);
} else if(strncmp(s, "scale=",6)==0) { // change line->pixel scaling for ILI9225 display
@ -724,24 +740,25 @@ void Display::initFromFile() {
n=sscanf(s, "%d,%d,%d", &y, &x, &w);
sscanf(ptr+1, "%30[^\r\n]", text);
if(sonde.config.disptype==1) { x*=xscale; y*=yscale; w*=xscale; }
layouts[idx].de[what].x = x;
layouts[idx].de[what].y = y;
layouts[idx].de[what].width = n>2 ? w : WIDTH_AUTO;
parseDispElement(text, layouts[idx].de+what);
Serial.printf("entry at %d,%d width=%d font %d, color=%x,%x\n", x, y, layouts[idx].de[what].width, layouts[idx].de[what].fmt,
layouts[idx].de[what].fg, layouts[idx].de[what].bg);
newlayouts[idx].de[what].x = x;
newlayouts[idx].de[what].y = y;
newlayouts[idx].de[what].width = n>2 ? w : WIDTH_AUTO;
parseDispElement(text, newlayouts[idx].de+what);
Serial.printf("entry at %d,%d width=%d font %d, color=%x,%x\n", x, y, newlayouts[idx].de[what].width, newlayouts[idx].de[what].fmt,
newlayouts[idx].de[what].fg, newlayouts[idx].de[what].bg);
what++;
layouts[idx].de[what].func = NULL;
newlayouts[idx].de[what].func = NULL;
} else {
for(int i=0; i<12; i++) {
Serial.printf("action %d: %d\n", i, (int)layouts[idx].actions[i]);
Serial.printf("action %d: %d\n", i, (int)newlayouts[idx].actions[i]);
}
what=-1;
}
break;
}
}
::layouts = layouts;
layouts = newlayouts;
nLayouts = idx+1;
setLayout(0);
}
@ -782,6 +799,8 @@ void Display::circ(uint16_t *bm, int16_t size, int16_t x0, int16_t y0, int16_t r
void Display::setLayout(int layoutIdx) {
Serial.printf("setLayout: %d (max is %d)\n", layoutIdx, nLayouts);
if(layoutIdx>=nLayouts) layoutIdx = 0;
layout = &layouts[layoutIdx];
}

View File

@ -62,13 +62,6 @@ void Scanner::plotResult()
void Scanner::scan()
{
#if 0
// Test only
for(int i=0; i<PLOT_N; i++) {
scandisp[i] = 30*sin(2*3.1415*i/50)-180;
}
return;
#endif
// Configure
sx1278.writeRegister(REG_PLL_HOP, 0x80); // FastHopOn
sx1278.setRxBandwidth(CHANBW*1000);

View File

@ -144,7 +144,9 @@ void Sonde::defaultConfig() {
config.debug=0;
config.wifi=1;
config.wifiap=1;
config.display=1;
config.display[0]=0;
config.display[1]=1;
config.display[2]=-1;
config.startfreq=400;
config.channelbw=10;
config.spectrum=10;
@ -225,8 +227,16 @@ void Sonde::setConfig(const char *cfg) {
} else if(strcmp(cfg,"wifiap")==0) {
config.wifiap = atoi(val);
} else if(strcmp(cfg,"display")==0) {
config.display = atoi(val);
disp.setLayout(config.display);
int i = 0;
char *ptr;
while(val) {
ptr = strchr(val,',');
if(ptr) *ptr = 0;
config.display[i++] = atoi(val);
val = ptr?ptr+1:NULL;
Serial.printf("appending value %d next is %s\n", config.display[i-1], val?val:"");
}
config.display[i] = -1;
} else if(strcmp(cfg,"startfreq")==0) {
config.startfreq = atoi(val);
} else if(strcmp(cfg,"channelbw")==0) {
@ -496,9 +506,9 @@ uint8_t Sonde::updateState(uint8_t event) {
}
int n = event;
if(event==ACT_DISPLAY_DEFAULT) {
n = config.display;
n = config.display[1];
}
if(n>=0&&n<5) {
if(n>=0&&n<disp.nLayouts) {
Serial.printf("Setting display mode %d\n", n);
disp.setLayout(n);
sonde.clearDisplay();
@ -554,9 +564,9 @@ void Sonde::updateDisplayIP() {
}
void Sonde::updateDisplayScanner() {
disp.setLayout(0);
disp.setLayout(config.display[0]);
disp.updateDisplay();
disp.setLayout(config.display);
disp.setLayout(config.display[1]);
}
void Sonde::updateDisplay()

View File

@ -33,6 +33,7 @@ extern const char *RXstr[];
//int8_t actions[EVT_MAX];
#define ACT_NONE 255
#define ACT_DISPLAY(n) (n)
#define ACT_DISPLAY_NEXT 64
#define ACT_DISPLAY_DEFAULT 63
#define ACT_DISPLAY_SPECTRUM 62
#define ACT_DISPLAY_WIFI 61
@ -99,7 +100,7 @@ typedef struct st_rdzconfig {
int debug; // show port and config options after reboot
int wifi; // connect to known WLAN 0=skip
int wifiap; // enable/disable WiFi AccessPoint mode 0=disable
int display; // select display mode (0=default, 1=default, 2=fieldmode)
int8_t display[30]; // list of display mode (0:scanner, 1:default, 2,... additional modes)
int startfreq; // spectrum display start freq (400, 401, ...)
int channelbw; // spectrum channel bandwidth (valid: 5, 10, 20, 25, 50, 100 kHz)
int spectrum; // show freq spectrum for n seconds -1=disable; 0=forever