mirror of
https://github.com/eried/portapack-mayhem.git
synced 2024-12-24 14:59:24 -05:00
UI options: backlight auto-off, splash screen toggle
This commit is contained in:
parent
d1e9bf33ec
commit
1e71a10346
@ -156,6 +156,7 @@ CPPSRC = main.cpp \
|
||||
ui_focus.cpp \
|
||||
ui_navigation.cpp \
|
||||
ui_menu.cpp \
|
||||
ui_about.cpp \
|
||||
ui_rssi.cpp \
|
||||
ui_channel.cpp \
|
||||
ui_audio.cpp \
|
||||
|
@ -52,7 +52,8 @@ void m4_init(const portapack::spi_flash::region_t from, const portapack::memory:
|
||||
}
|
||||
|
||||
int m4_load_image(void) {
|
||||
uint32_t mod_size;
|
||||
const char magic[6] = {'P', 'P', 'M', ' ', 0x01, 0x00};
|
||||
//uint32_t mod_size;
|
||||
UINT bw;
|
||||
uint8_t i;
|
||||
uint16_t cnt;
|
||||
@ -62,28 +63,36 @@ int m4_load_image(void) {
|
||||
DIR rootdir;
|
||||
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, "/");
|
||||
for (;;) {
|
||||
res = f_readdir(&rootdir, &modinfo);
|
||||
if (res != FR_OK || modinfo.fname[0] == 0) break;
|
||||
if (!(modinfo.fattrib & AM_DIR)) {
|
||||
if (res != FR_OK || modinfo.fname[0] == 0) break; // Reached last file, abort
|
||||
// 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_lseek(&modfile, 26);
|
||||
f_read(&modfile, &md5sum, 16, &bw);
|
||||
for (i = 0; i < 16; i++) {
|
||||
if (md5sum[i] != modhash[i]) break;
|
||||
// Magic bytes and version check
|
||||
f_read(&modfile, &md5sum, 6, &bw);
|
||||
for (i = 0; i < 6; i++) {
|
||||
if (md5sum[i] != magic[i]) break;
|
||||
}
|
||||
if (i == 16) {
|
||||
f_lseek(&modfile, 6);
|
||||
f_read(&modfile, &mod_size, 4, &bw);
|
||||
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;
|
||||
if (i == 6) {
|
||||
f_lseek(&modfile, 26);
|
||||
f_read(&modfile, &md5sum, 16, &bw);
|
||||
for (i = 0; i < 16; i++) {
|
||||
if (md5sum[i] != modhash[i]) break;
|
||||
}
|
||||
if (i == 16) {
|
||||
//f_lseek(&modfile, 6);
|
||||
//f_read(&modfile, &mod_size, 4, &bw);
|
||||
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);
|
||||
}
|
||||
@ -95,7 +104,7 @@ int m4_load_image(void) {
|
||||
void m4_switch(const 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 {
|
||||
.mode = SWITCH,
|
||||
.sampling_rate = 0,
|
||||
|
@ -19,11 +19,13 @@
|
||||
* 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: check jammer bandwidths
|
||||
//TODO: GSM channel detector
|
||||
//TODO: wait_for_switch() in baseband-tx !
|
||||
//TODO: AFSK receiver
|
||||
//TODO: SIGFOX RX/TX
|
||||
//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: Check bw setting in LCR 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: Whistler
|
||||
//TODO: Setup: Play dead by default ? Enable/disable ?
|
||||
@ -51,7 +52,10 @@
|
||||
using namespace lpc43xx;
|
||||
|
||||
#include "portapack.hpp"
|
||||
#include "portapack_io.hpp"
|
||||
#include "portapack_shared_memory.hpp"
|
||||
#include "portapack_persistent_memory.hpp"
|
||||
using namespace portapack;
|
||||
|
||||
#include "cpld_update.hpp"
|
||||
|
||||
@ -160,7 +164,17 @@ private:
|
||||
}
|
||||
|
||||
void handle_rtc_tick() {
|
||||
uint16_t bloff_time;
|
||||
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 ) {
|
||||
sd_card_present = sd_card_present_now;
|
||||
|
||||
@ -234,6 +248,10 @@ private:
|
||||
|
||||
void handle_switches() {
|
||||
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++) {
|
||||
// TODO: Ignore multiple keys at the same time?
|
||||
if( switches_state[i] ) {
|
||||
@ -248,6 +266,10 @@ private:
|
||||
void handle_encoder() {
|
||||
const uint32_t encoder_now = get_encoder_position();
|
||||
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;
|
||||
const auto event = static_cast<ui::EncoderEvent>(delta);
|
||||
event_bubble_encoder(event);
|
||||
|
@ -70,6 +70,8 @@ TransmitterModel transmitter_model {
|
||||
clock_manager
|
||||
};
|
||||
|
||||
uint8_t bl_tick_counter = 0;
|
||||
|
||||
class Power {
|
||||
public:
|
||||
void init() {
|
||||
|
@ -44,6 +44,8 @@ extern wolfson::wm8731::WM8731 audio_codec;
|
||||
extern ReceiverModel receiver_model;
|
||||
extern TransmitterModel transmitter_model;
|
||||
|
||||
extern uint8_t bl_tick_counter;
|
||||
|
||||
void init();
|
||||
void shutdown();
|
||||
|
||||
|
71
firmware/application/ui_about.cpp
Normal file
71
firmware/application/ui_about.cpp
Normal 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 */
|
72
firmware/application/ui_about.hpp
Normal file
72
firmware/application/ui_about.hpp
Normal 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__*/
|
@ -28,6 +28,7 @@
|
||||
|
||||
#include "splash.hpp"
|
||||
|
||||
#include "ui_about.hpp"
|
||||
#include "ui_setup.hpp"
|
||||
#include "ui_debug.hpp"
|
||||
#include "ui_receiver.hpp"
|
||||
@ -169,7 +170,10 @@ SystemView::SystemView(
|
||||
//else
|
||||
// navigation_view.push(new BMPView { navigation_view });
|
||||
|
||||
if (portapack::persistent_memory::ui_config() & 1)
|
||||
navigation_view.push(new BMPView { navigation_view });
|
||||
else
|
||||
navigation_view.push(new SystemMenuView { navigation_view });
|
||||
}
|
||||
|
||||
Context& SystemView::context() const {
|
||||
|
@ -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) {
|
||||
add_children({{
|
||||
&text_title,
|
||||
@ -230,12 +214,45 @@ void SetPlayDeadView::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) {
|
||||
add_items<4>({ {
|
||||
add_items<5>({ {
|
||||
{ "Date/Time", ui::Color::white(), [&nav](){ nav.push(new SetDateTimeView { nav }); } },
|
||||
{ "Frequency correction", ui::Color::white(), [&nav](){ nav.push(new SetFrequencyCorrectionView { nav }); } },
|
||||
{ "Touch", ui::Color::white(), [&nav](){ nav.push(new SetTouchCalibView { nav }); } },
|
||||
{ "Play dead", ui::Color::white(), [&nav](){ nav.push(new SetPlayDeadView { nav }); } },
|
||||
{ "Touch screen", ui::Color::white(), [&nav](){ nav.push(new SetTouchCalibView { 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(); };
|
||||
}
|
||||
|
@ -176,44 +176,12 @@ private:
|
||||
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 {
|
||||
public:
|
||||
SetTouchCalibView(NavigationView& nav);
|
||||
void focus() override;
|
||||
bool on_touch(const TouchEvent event) override;
|
||||
|
||||
private:
|
||||
|
||||
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 {
|
||||
public:
|
||||
SetPlayDeadView(NavigationView& nav);
|
||||
|
@ -84,6 +84,8 @@ struct data_t {
|
||||
// Play dead unlock
|
||||
uint32_t playing_dead;
|
||||
uint32_t playdead_sequence;
|
||||
|
||||
int32_t ui_config;
|
||||
};
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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 portapack */
|
||||
|
@ -58,6 +58,10 @@ void set_playing_dead(const uint32_t new_value);
|
||||
uint32_t playdead_sequence();
|
||||
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 portapack */
|
||||
|
||||
|
Binary file not shown.
Loading…
Reference in New Issue
Block a user