UI options: backlight auto-off, splash screen toggle

This commit is contained in:
furrtek 2016-01-07 14:17:39 +01:00
parent d1e9bf33ec
commit 1e71a10346
13 changed files with 311 additions and 74 deletions

View File

@ -156,6 +156,7 @@ CPPSRC = main.cpp \
ui_focus.cpp \ ui_focus.cpp \
ui_navigation.cpp \ ui_navigation.cpp \
ui_menu.cpp \ ui_menu.cpp \
ui_about.cpp \
ui_rssi.cpp \ ui_rssi.cpp \
ui_channel.cpp \ ui_channel.cpp \
ui_audio.cpp \ ui_audio.cpp \

View File

@ -52,7 +52,8 @@ void m4_init(const portapack::spi_flash::region_t from, const portapack::memory:
} }
int m4_load_image(void) { int m4_load_image(void) {
uint32_t mod_size; const char magic[6] = {'P', 'P', 'M', ' ', 0x01, 0x00};
//uint32_t mod_size;
UINT bw; UINT bw;
uint8_t i; uint8_t i;
uint16_t cnt; uint16_t cnt;
@ -62,28 +63,36 @@ int m4_load_image(void) {
DIR rootdir; DIR rootdir;
FRESULT res; FRESULT res;
// Scan SD card root directory for files with the right md5 fingerprint at the right location // Scan SD card root directory for files with the right MD5 fingerprint at the right location
f_opendir(&rootdir, "/"); f_opendir(&rootdir, "/");
for (;;) { for (;;) {
res = f_readdir(&rootdir, &modinfo); res = f_readdir(&rootdir, &modinfo);
if (res != FR_OK || modinfo.fname[0] == 0) break; if (res != FR_OK || modinfo.fname[0] == 0) break; // Reached last file, abort
if (!(modinfo.fattrib & AM_DIR)) { // Only care about files with .bin extension
if ((!(modinfo.fattrib & AM_DIR)) && (modinfo.fname[9] == 'B') && (modinfo.fname[10] == 'I') && (modinfo.fname[11] == 'N')) {
f_open(&modfile, modinfo.fname, FA_OPEN_EXISTING | FA_READ); f_open(&modfile, modinfo.fname, FA_OPEN_EXISTING | FA_READ);
f_lseek(&modfile, 26); // Magic bytes and version check
f_read(&modfile, &md5sum, 16, &bw); f_read(&modfile, &md5sum, 6, &bw);
for (i = 0; i < 16; i++) { for (i = 0; i < 6; i++) {
if (md5sum[i] != modhash[i]) break; if (md5sum[i] != magic[i]) break;
} }
if (i == 16) { if (i == 6) {
f_lseek(&modfile, 6); f_lseek(&modfile, 26);
f_read(&modfile, &mod_size, 4, &bw); f_read(&modfile, &md5sum, 16, &bw);
f_lseek(&modfile, 256); for (i = 0; i < 16; i++) {
// For some reason, f_read > 512 bytes at once crashes everything... :/ if (md5sum[i] != modhash[i]) break;
for (cnt=0;cnt<256;cnt++) }
f_read(&modfile, reinterpret_cast<void*>(portapack::memory::map::m4_code.base()+(cnt*256)), 256, &bw); if (i == 16) {
f_close(&modfile); //f_lseek(&modfile, 6);
LPC_RGU->RESET_CTRL[0] = (1 << 13); //f_read(&modfile, &mod_size, 4, &bw);
return 1; f_lseek(&modfile, 256);
// For some reason, f_read > 512 bytes at once crashes everything... :/
for (cnt=0;cnt<256;cnt++)
f_read(&modfile, reinterpret_cast<void*>(portapack::memory::map::m4_code.base()+(cnt*256)), 256, &bw);
f_close(&modfile);
LPC_RGU->RESET_CTRL[0] = (1 << 13);
return 1;
}
} }
f_close(&modfile); f_close(&modfile);
} }
@ -95,7 +104,7 @@ int m4_load_image(void) {
void m4_switch(const char * hash) { void m4_switch(const char * hash) {
modhash = const_cast<char*>(hash); modhash = const_cast<char*>(hash);
// Ask M4 to enter loop in RAM // Ask M4 to enter wait loop in RAM
BasebandConfiguration baseband_switch { BasebandConfiguration baseband_switch {
.mode = SWITCH, .mode = SWITCH,
.sampling_rate = 0, .sampling_rate = 0,

View File

@ -19,11 +19,13 @@
* Boston, MA 02110-1301, USA. * Boston, MA 02110-1301, USA.
*/ */
//TODO: Enum modulation modes (baseband) //TODO: Playdead amnesia and login
//TODO: Touch screen calibration
//TODO: Display module info (name, desc) somewhere
//TODO: Show MD5 mismatches for modules not found, etc...
//TODO: More gfx, cute icons :) //TODO: More gfx, cute icons :)
//TODO: check jammer bandwidths //TODO: check jammer bandwidths
//TODO: GSM channel detector //TODO: GSM channel detector
//TODO: wait_for_switch() in baseband-tx !
//TODO: AFSK receiver //TODO: AFSK receiver
//TODO: SIGFOX RX/TX //TODO: SIGFOX RX/TX
//TODO: Reset baseband if module not found (instead of lockup in RAM loop) //TODO: Reset baseband if module not found (instead of lockup in RAM loop)
@ -32,7 +34,6 @@
//TODO: BUG: Crash after TX stop (unregister message !) //TODO: BUG: Crash after TX stop (unregister message !)
//TODO: Check bw setting in LCR TX //TODO: Check bw setting in LCR TX
//TODO: BUG: Crash after PSN entry in RDS TX //TODO: BUG: Crash after PSN entry in RDS TX
//TODO: Dynamically load baseband code depending on mode (disable M4 & interrupts, load, reset)
//TODO: Bodet :) //TODO: Bodet :)
//TODO: Whistler //TODO: Whistler
//TODO: Setup: Play dead by default ? Enable/disable ? //TODO: Setup: Play dead by default ? Enable/disable ?
@ -51,7 +52,10 @@
using namespace lpc43xx; using namespace lpc43xx;
#include "portapack.hpp" #include "portapack.hpp"
#include "portapack_io.hpp"
#include "portapack_shared_memory.hpp" #include "portapack_shared_memory.hpp"
#include "portapack_persistent_memory.hpp"
using namespace portapack;
#include "cpld_update.hpp" #include "cpld_update.hpp"
@ -160,7 +164,17 @@ private:
} }
void handle_rtc_tick() { void handle_rtc_tick() {
uint16_t bloff_time;
const auto sd_card_present_now = sdc_lld_is_card_inserted(&SDCD1); const auto sd_card_present_now = sdc_lld_is_card_inserted(&SDCD1);
bloff_time = portapack::persistent_memory::ui_config_bloff();
if (bloff_time) {
if (portapack::bl_tick_counter >= bloff_time)
io.lcd_backlight(0);
else
portapack::bl_tick_counter++;
}
if( sd_card_present_now != sd_card_present ) { if( sd_card_present_now != sd_card_present ) {
sd_card_present = sd_card_present_now; sd_card_present = sd_card_present_now;
@ -234,6 +248,10 @@ private:
void handle_switches() { void handle_switches() {
const auto switches_state = get_switches_state(); const auto switches_state = get_switches_state();
io.lcd_backlight(1);
portapack::bl_tick_counter = 0;
for(size_t i=0; i<switches_state.size(); i++) { for(size_t i=0; i<switches_state.size(); i++) {
// TODO: Ignore multiple keys at the same time? // TODO: Ignore multiple keys at the same time?
if( switches_state[i] ) { if( switches_state[i] ) {
@ -248,6 +266,10 @@ private:
void handle_encoder() { void handle_encoder() {
const uint32_t encoder_now = get_encoder_position(); const uint32_t encoder_now = get_encoder_position();
const int32_t delta = static_cast<int32_t>(encoder_now - encoder_last); const int32_t delta = static_cast<int32_t>(encoder_now - encoder_last);
io.lcd_backlight(1);
portapack::bl_tick_counter = 0;
encoder_last = encoder_now; encoder_last = encoder_now;
const auto event = static_cast<ui::EncoderEvent>(delta); const auto event = static_cast<ui::EncoderEvent>(delta);
event_bubble_encoder(event); event_bubble_encoder(event);

View File

@ -70,6 +70,8 @@ TransmitterModel transmitter_model {
clock_manager clock_manager
}; };
uint8_t bl_tick_counter = 0;
class Power { class Power {
public: public:
void init() { void init() {

View File

@ -44,6 +44,8 @@ extern wolfson::wm8731::WM8731 audio_codec;
extern ReceiverModel receiver_model; extern ReceiverModel receiver_model;
extern TransmitterModel transmitter_model; extern TransmitterModel transmitter_model;
extern uint8_t bl_tick_counter;
void init(); void init();
void shutdown(); void shutdown();

View File

@ -0,0 +1,71 @@
/*
* Copyright (C) 2015 Jared Boone, ShareBrained Technology, Inc.
*
* This file is part of PortaPack.
*
* This program 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 2, or (at your option)
* any later version.
*
* 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.
*
* You should have received a copy of the GNU General Public License
* along with this program; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street,
* Boston, MA 02110-1301, USA.
*/
#include "ui_about.hpp"
#include "touch.hpp"
#include "portapack_persistent_memory.hpp"
#include "lpc43xx_cpp.hpp"
#include <math.h>
#include <cstring>
using namespace lpc43xx;
using namespace portapack;
namespace ui {
/*static AboutView::update() {
uint8_t c;
uint16_t raster_color;
for (c=0; c<=200; c++) {
raster_color = copper_buffer[c];
if (raster_color) painter.fill_rectangle({ { 0, (c+32) }, { 240, 1 } }, { (raster_color >> 4) & 0xF0, raster_color & 0xF0, (raster_color << 4) & 0xF0 });
}
for (c=0; c<=200; c++)
copper_buffer[c] = 0;
for (c=0; c<=200; c++) {
copper_buffer[c] = (c | (c << 4)) + phase;
}
phase++;
}*/
AboutView::AboutView(NavigationView& nav) {
add_children({ {
&text_title,
&text_firmware,
&text_cpld_hackrf,
&text_cpld_portapack,
&button_ok,
} });
button_ok.on_select = [this,&nav](Button&){ nav.pop(); };
}
void AboutView::focus() {
button_ok.focus();
}
} /* namespace ui */

View File

@ -0,0 +1,72 @@
/*
* Copyright (C) 2015 Jared Boone, ShareBrained Technology, Inc.
*
* This file is part of PortaPack.
*
* This program 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 2, or (at your option)
* any later version.
*
* 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.
*
* You should have received a copy of the GNU General Public License
* along with this program; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street,
* Boston, MA 02110-1301, USA.
*/
#ifndef __UI_ABOUT_H__
#define __UI_ABOUT_H__
#include "ui_widget.hpp"
#include "ui_menu.hpp"
#include "ui_navigation.hpp"
#include <cstdint>
namespace ui {
class AboutView : public View {
public:
AboutView(NavigationView& nav);
void focus() override;
private:
/*bool drawn;
uint16_t phase = 0;
uint16_t copper_buffer[256];
void update(void);*/
Text text_title {
{ 100, 96, 40, 16 },
"About",
};
Text text_firmware {
{ 0, 128, 240, 16 },
"Git Commit hash " GIT_REVISION,
};
Text text_cpld_hackrf {
{ 0, 144, 240, 16 },
"HackRF CPLD CRC 0x????????",
};
Text text_cpld_portapack {
{ 0, 160, 240, 16 },
"PortaPack CPLD CRC 0x????????",
};
Button button_ok {
{ 72, 192, 96, 24 },
"OK"
};
};
} /* namespace ui */
#endif/*__UI_ABOUT_H__*/

View File

@ -28,6 +28,7 @@
#include "splash.hpp" #include "splash.hpp"
#include "ui_about.hpp"
#include "ui_setup.hpp" #include "ui_setup.hpp"
#include "ui_debug.hpp" #include "ui_debug.hpp"
#include "ui_receiver.hpp" #include "ui_receiver.hpp"
@ -169,7 +170,10 @@ SystemView::SystemView(
//else //else
// navigation_view.push(new BMPView { navigation_view }); // navigation_view.push(new BMPView { navigation_view });
if (portapack::persistent_memory::ui_config() & 1)
navigation_view.push(new BMPView { navigation_view }); navigation_view.push(new BMPView { navigation_view });
else
navigation_view.push(new SystemMenuView { navigation_view });
} }
Context& SystemView::context() const { Context& SystemView::context() const {

View File

@ -147,22 +147,6 @@ SetFrequencyCorrectionModel SetFrequencyCorrectionView::form_collect() {
}; };
} }
AboutView::AboutView(NavigationView& nav) {
add_children({ {
&text_title,
&text_firmware,
&text_cpld_hackrf,
&text_cpld_portapack,
&button_ok,
} });
button_ok.on_select = [&nav](Button&){ nav.pop(); };
}
void AboutView::focus() {
button_ok.focus();
}
SetTouchCalibView::SetTouchCalibView(NavigationView& nav) { SetTouchCalibView::SetTouchCalibView(NavigationView& nav) {
add_children({{ add_children({{
&text_title, &text_title,
@ -230,12 +214,45 @@ void SetPlayDeadView::focus() {
button_enter.focus(); button_enter.focus();
} }
SetUIView::SetUIView(NavigationView& nav) {
uint32_t ui_config;
add_children({{
&checkbox_showsplash,
&checkbox_bloff,
&options_bloff,
&button_ok
}});
ui_config = portapack::persistent_memory::ui_config();
if (ui_config & 1) checkbox_showsplash.set_value(true);
if (ui_config & 2) checkbox_bloff.set_value(true);
options_bloff.set_selected_index((ui_config >> 5) & 7);
button_ok.on_select = [&nav,this](Button&){
uint32_t ui_config = 0;
if (checkbox_showsplash.value() == true) ui_config |= 1;
if (checkbox_bloff.value() == true) ui_config |= 2;
ui_config |= (options_bloff.selected_index() << 5);
portapack::persistent_memory::set_ui_config(ui_config);
nav.pop();
};
}
void SetUIView::focus() {
button_ok.focus();
}
SetupMenuView::SetupMenuView(NavigationView& nav) { SetupMenuView::SetupMenuView(NavigationView& nav) {
add_items<4>({ { add_items<5>({ {
{ "Date/Time", ui::Color::white(), [&nav](){ nav.push(new SetDateTimeView { nav }); } }, { "Date/Time", ui::Color::white(), [&nav](){ nav.push(new SetDateTimeView { nav }); } },
{ "Frequency correction", ui::Color::white(), [&nav](){ nav.push(new SetFrequencyCorrectionView { nav }); } }, { "Frequency correction", ui::Color::white(), [&nav](){ nav.push(new SetFrequencyCorrectionView { nav }); } },
{ "Touch", ui::Color::white(), [&nav](){ nav.push(new SetTouchCalibView { nav }); } }, { "Touch screen", ui::Color::white(), [&nav](){ nav.push(new SetTouchCalibView { nav }); } },
{ "Play dead", ui::Color::white(), [&nav](){ nav.push(new SetPlayDeadView { nav }); } }, { "Play dead", ui::Color::red(), [&nav](){ nav.push(new SetPlayDeadView { nav }); } },
{ "UI", ui::Color::white(), [&nav](){ nav.push(new SetUIView { nav }); } },
} }); } });
on_left = [&nav](){ nav.pop(); }; on_left = [&nav](){ nav.pop(); };
} }

View File

@ -176,44 +176,12 @@ private:
SetFrequencyCorrectionModel form_collect(); SetFrequencyCorrectionModel form_collect();
}; };
class AboutView : public View {
public:
AboutView(NavigationView& nav);
void focus() override;
private:
Text text_title {
{ 100, 96, 40, 16 },
"About",
};
Text text_firmware {
{ 0, 128, 240, 16 },
"Git Commit Hash " GIT_REVISION,
};
Text text_cpld_hackrf {
{ 0, 144, 240, 16 },
"HackRF CPLD CRC 0x????????",
};
Text text_cpld_portapack {
{ 0, 160, 240, 16 },
"PortaPack CPLD CRC 0x????????",
};
Button button_ok {
{ 72, 192, 96, 24 },
"OK"
};
};
class SetTouchCalibView : public View { class SetTouchCalibView : public View {
public: public:
SetTouchCalibView(NavigationView& nav); SetTouchCalibView(NavigationView& nav);
void focus() override; void focus() override;
bool on_touch(const TouchEvent event) override; bool on_touch(const TouchEvent event) override;
private: private:
Text text_title { Text text_title {
@ -237,6 +205,40 @@ private:
}; };
}; };
class SetUIView : public View {
public:
SetUIView(NavigationView& nav);
void focus() override;
private:
Checkbox checkbox_showsplash {
{ 3 * 8, 2 * 16},
"Show splash"
};
Checkbox checkbox_bloff {
{ 3 * 8, 4 * 16},
"Backlight off after:"
};
OptionsField options_bloff {
{ 10 * 8, 5 * 16 + 4 },
5,
{
{ "5 seconds ", 0 },
{ "15 seconds", 1 },
{ "1 minute ", 2 },
{ "5 minutes ", 3 },
{ "10 minutes", 4 }
}
};
Button button_ok {
{ 4 * 8, 272, 64, 24 },
"Ok"
};
};
class SetPlayDeadView : public View { class SetPlayDeadView : public View {
public: public:
SetPlayDeadView(NavigationView& nav); SetPlayDeadView(NavigationView& nav);

View File

@ -84,6 +84,8 @@ struct data_t {
// Play dead unlock // Play dead unlock
uint32_t playing_dead; uint32_t playing_dead;
uint32_t playdead_sequence; uint32_t playdead_sequence;
int32_t ui_config;
}; };
static_assert(sizeof(data_t) <= 0x100, "Persistent memory structure too large for VBAT-maintained region"); static_assert(sizeof(data_t) <= 0x100, "Persistent memory structure too large for VBAT-maintained region");
@ -168,5 +170,34 @@ void set_playdead_sequence(const uint32_t new_value) {
data->playdead_sequence = new_value; data->playdead_sequence = new_value;
} }
uint32_t ui_config() {
uint8_t bloff_value;
// Cap value
bloff_value = (data->ui_config >> 5) & 7;
if (bloff_value > 4) bloff_value = 1;
data->ui_config = (data->ui_config & 0x1F) | (bloff_value << 5);
return data->ui_config;
}
uint16_t ui_config_bloff() {
uint8_t bloff_value;
uint16_t bloff_seconds[5] = { 5, 15, 60, 300, 600 };
if (!(data->ui_config & 2)) return 0;
// Cap value
bloff_value = (data->ui_config >> 5) & 7;
if (bloff_value > 4) bloff_value = 1;
return bloff_seconds[bloff_value];
}
void set_ui_config(const uint32_t new_value) {
data->ui_config = new_value;
}
} /* namespace persistent_memory */ } /* namespace persistent_memory */
} /* namespace portapack */ } /* namespace portapack */

View File

@ -58,6 +58,10 @@ void set_playing_dead(const uint32_t new_value);
uint32_t playdead_sequence(); uint32_t playdead_sequence();
void set_playdead_sequence(const uint32_t new_value); void set_playdead_sequence(const uint32_t new_value);
uint32_t ui_config();
void set_ui_config(const uint32_t new_value);
uint16_t ui_config_bloff();
} /* namespace persistent_memory */ } /* namespace persistent_memory */
} /* namespace portapack */ } /* namespace portapack */

Binary file not shown.