Compare commits

..

7 Commits

Author SHA1 Message Date
sommermoregentraum c36fe78bd5 pacman: cheat lifes and cheat skip level (#1821)
cheat lives and cheat skip level and fixed review issue. Thanks @NotherNgineer
2024-01-29 00:54:13 +08:00
Mark Thompson bd8385464e Tuner code readability (no functional change) (#1820) 2024-01-28 10:02:11 -06:00
Totoo 8c996b5bc6 Embedded friendly usb (#1817) 2024-01-27 19:33:08 +01:00
Mark Thompson d1901939e1 Fix tuning of 2170-2300 and 2700-2740 MHz (#1819) 2024-01-27 13:30:32 +01:00
Mark Thompson 41ec11fb66 Check app checksums during untar (#1815) 2024-01-27 13:29:24 +01:00
Mark Thompson df47490d85 Allow 3 boot failures before Config Mode starts (#1816)
* Allow 3 boot attempts before Config Mode starts

* Add files via upload
2024-01-26 21:02:52 +13:00
Totoo a2f6d14b15 ISS for aprs, for the request #1810 (#1814) 2024-01-25 21:10:43 +01:00
14 changed files with 158 additions and 67 deletions
+2
View File
@@ -101,6 +101,8 @@ APRSRxView::APRSRxView(NavigationView& nav, Rect parent_rect)
field_frequency.set_value(145175000);
} else if (i == 3) {
field_frequency.set_value(144575000);
} else if (i == 4) {
field_frequency.set_value(145825000);
}
};
+2 -1
View File
@@ -221,7 +221,8 @@ class APRSRxView : public View {
{{"NA ", 0},
{"EUR", 1},
{"AUS", 2},
{"NZ ", 3}}};
{"NZ ", 3},
{"ISS", 4}}};
RxFrequencyField field_frequency{
{3 * 8, 0 * 16},
+10 -10
View File
@@ -21,6 +21,7 @@
*/
#include "ui_flash_utility.hpp"
#include "ui_styles.hpp"
#include "portapack_shared_memory.hpp"
namespace ui {
@@ -33,13 +34,13 @@ static constexpr size_t max_filename_length = 26;
bool valid_firmware_file(std::filesystem::path::string_type path) {
File firmware_file;
uint32_t read_buffer[128];
uint32_t checksum{1};
uint32_t checksum{(uint32_t)~FLASH_EXPECTED_CHECKSUM}; // initializing to invalid checksum in case file can't be read
// test read of the whole file just to validate checksum (baseband flash code will re-read when flashing)
auto result = firmware_file.open(path.c_str());
if (!result.is_valid()) {
checksum = 0;
for (uint32_t i = FLASH_STARTING_ADDRESS; i < FLASH_ROM_SIZE / sizeof(read_buffer); i++) {
for (uint32_t i = 0; i < FLASH_ROM_SIZE / sizeof(read_buffer); i++) {
auto readResult = firmware_file.read(&read_buffer, sizeof(read_buffer));
// if file is smaller than 1MB, assume it's a downgrade to an old FW version and ignore the checksum
@@ -122,12 +123,6 @@ std::filesystem::path FlashUtilityView::extract_tar(std::filesystem::path::strin
painter.fill_rectangle({0, 50, portapack::display.width(), 90}, ui::Color::black());
painter.draw_string({0, 60}, this->nav_.style(), fileName);
});
if (res.string().empty()) {
ui::Painter painter;
painter.fill_rectangle({0, 50, portapack::display.width(), 90}, ui::Color::black());
painter.draw_string({0, 60}, this->nav_.style(), "BAD TAR FILE");
chThdSleepMilliseconds(5000);
}
return res;
}
@@ -137,8 +132,13 @@ void FlashUtilityView::flash_firmware(std::filesystem::path::string_type path) {
path = extract_tar(u'/' + path).native();
}
if (path.empty() || !valid_firmware_file(path.c_str()))
return; // bad firmware image - just returning back to the file list
if (path.empty() || !valid_firmware_file(path.c_str())) {
ui::Painter painter;
painter.fill_rectangle({0, 50, portapack::display.width(), 90}, ui::Color::black());
painter.draw_string({0, 60}, Styles::red, "BAD FIRMWARE FILE");
chThdSleepMilliseconds(5000);
return;
}
ui::Painter painter;
painter.fill_rectangle(
+7 -2
View File
@@ -27,14 +27,19 @@
void config_mode_blink_until_dfu();
void config_mode_set() {
portapack::persistent_memory::set_config_mode_storage_direct(CONFIG_MODE_GUARD_VALUE);
uint32_t cms = portapack::persistent_memory::config_mode_storage_direct();
if ((cms >= CONFIG_MODE_GUARD_VALUE) && (cms < CONFIG_MODE_LIMIT_VALUE))
cms += 1;
else
cms = CONFIG_MODE_GUARD_VALUE;
portapack::persistent_memory::set_config_mode_storage_direct(cms);
}
bool config_mode_should_enter() {
if (portapack::persistent_memory::config_disable_config_mode_direct())
return false;
else
return portapack::persistent_memory::config_mode_storage_direct() == CONFIG_MODE_GUARD_VALUE;
return portapack::persistent_memory::config_mode_storage_direct() == CONFIG_MODE_LIMIT_VALUE;
}
void config_mode_clear() {
+7
View File
@@ -28,6 +28,13 @@
#include "portapack_shared_memory.hpp"
#include "portapack_persistent_memory.hpp"
// number of boot failures before entering config menu mode
#define BOOT_FAILURES_BEFORE_CONFIG_MODE 3
#define CONFIG_MODE_GUARD_VALUE 0xbadb0000
#define CONFIG_MODE_LIMIT_VALUE (CONFIG_MODE_GUARD_VALUE + BOOT_FAILURES_BEFORE_CONFIG_MODE - 1)
#define CONFIG_MODE_NORMAL_VALUE 0x000007cf
void config_mode_set();
bool config_mode_should_enter();
void config_mode_clear();
+60 -15
View File
@@ -13,8 +13,8 @@ typedef uint8_t byte;
typedef uint32_t word;
byte SPEED = 2;
byte MAXLIFES = 5;
byte LIFES = START_LIFES;
byte MAXLIFES = 20;
size_t LIFES = START_LIFES;
byte GAMEWIN = 0;
byte GAMEOVER = 0;
byte DEMO = 1;
@@ -25,6 +25,9 @@ byte GAMEPAUSED = 0;
byte PACMANFALLBACK = 0;
bool cheat_level = false;
bool cheat_lifes = false;
#include "DrawIndexedMap.h"
/******************************************************************************/
@@ -901,14 +904,15 @@ class Playfield {
void PackmanDied() { // Noooo... PACMAN DIED :(
if (LIFES <= 0) {
if (LIFES <= 0 && !cheat_lifes) {
GAMEOVER = 1;
LEVEL = START_LEVEL;
LIFES = START_LIFES;
DEMO = 1;
Init();
} else {
LIFES--;
if (!cheat_lifes)
LIFES--;
_inited = true;
_state = ReadyState;
@@ -934,8 +938,14 @@ class Playfield {
_icons[13 - i] = BONUSICON + i;
}
for (byte i = 0; i < LIFES; i++) {
_icons[0 + i] = PACMANICON;
if (!cheat_lifes) {
for (byte i = 0; i < LIFES; i++) {
_icons[0 + i] = PACMANICON;
}
} else {
for (byte i = 0; i < 14; i++) {
_icons[0 + i] = PACMANICON;
}
}
// Draw LIFE and BONUS Icons
@@ -1177,8 +1187,13 @@ class Playfield {
if (GAMEWIN == 1) {
GAMEWIN = 0;
} else {
LEVEL = START_LEVEL;
LIFES = START_LIFES;
if (!cheat_level) {
LEVEL = START_LEVEL;
}
if (!cheat_lifes) {
LIFES = START_LIFES;
}
ACTUALBONUS = 0; // actual bonus icon
ACTIVEBONUS = 0; // status of bonus
@@ -1215,8 +1230,14 @@ class Playfield {
}
// SET Lifes icons
for (byte i = 0; i < LIFES; i++) {
_icons[0 + i] = PACMANICON;
if (cheat_lifes) {
for (byte i = 0; i < 14; i++) { // cuz 14 lives full fills PP's screen
_icons[0 + i] = PACMANICON;
}
} else {
for (byte i = 0; i < LIFES; i++) {
_icons[0 + i] = PACMANICON;
}
}
// Draw LIFE and BONUS Icons
@@ -1243,21 +1264,45 @@ class Playfield {
}
void Step() {
int16_t keys = 0;
if (GAMEWIN == 1) {
cheat_level = false;
cheat_lifes = false;
LEVEL++;
Init();
}
// Start GAME
if (but_A && DEMO == 1 && GAMEPAUSED == 0) {
if (but_A && DEMO == 1 && GAMEPAUSED == 0) { // start
but_A = false;
DEMO = 0;
Init();
} else if (but_A && DEMO == 0 && GAMEPAUSED == 0) { // Or PAUSE GAME
DEMO = 0;
} else if (but_A && DEMO == 0 && GAMEPAUSED == 0) { // pause
but_A = false;
GAMEPAUSED = 1;
} else if (but_LEFT && DEMO == 1 && GAMEPAUSED == 0) { // -level
cheat_level = true;
but_LEFT = false;
if (LEVEL > 1) {
LEVEL--;
}
Init();
} else if (but_RIGHT && DEMO == 1 && GAMEPAUSED == 0) { // +level
cheat_level = true;
but_RIGHT = false;
if (LEVEL < 255) {
LEVEL++;
}
Init();
} else if (but_UP && DEMO == 1 && GAMEPAUSED == 0) { // full of lifes
cheat_lifes = true;
but_UP = false;
Init();
} else if (but_DOWN && DEMO == 1 && GAMEPAUSED == 0) { // reset
cheat_level = false;
cheat_lifes = false;
but_DOWN = false;
LIFES = START_LIFES;
Init();
}
if (GAMEPAUSED && but_A && DEMO == 0) {
+2 -7
View File
@@ -33,10 +33,10 @@ namespace max283x {
namespace lo {
constexpr std::array<rf::FrequencyRange, 4> band{{
{2300000000, 2400000000},
{2170000000, 2400000000},
{2400000000, 2500000000},
{2500000000, 2600000000},
{2600000000, 2700000000},
{2600000000, 2740000000},
}};
} /* namespace lo */
@@ -48,11 +48,6 @@ namespace lna {
constexpr range_t<int8_t> gain_db_range{0, 40};
constexpr int8_t gain_db_step = 8;
constexpr std::array<rf::FrequencyRange, 2> band{{
{2300000000, 2500000000},
{2500000000, 2700000000},
}};
} /* namespace lna */
/*************************************************************************/
+2
View File
@@ -184,11 +184,13 @@ bool set_tuning_frequency(const rf::Frequency frequency) {
if (tuning_config.is_valid()) {
first_if.disable();
// Program first local oscillator frequency (if there is one) into RFFC507x
if (tuning_config.first_lo_frequency) {
first_if.set_frequency(tuning_config.first_lo_frequency);
first_if.enable();
}
// Program second local oscillator frequency into MAX283x
const auto result_second_if = second_if->set_frequency(tuning_config.second_lo_frequency);
rf_path.set_band(tuning_config.rf_path_band);
+2 -2
View File
@@ -39,8 +39,8 @@ enum class Direction {
namespace path {
constexpr FrequencyRange band_low{0, 2170000000};
constexpr FrequencyRange band_high{2740000000, 7250000000};
constexpr FrequencyRange band_low{0, 2170'000'000};
constexpr FrequencyRange band_high{2740'000'000, 7250'000'000};
constexpr FrequencyRange band_mid{band_low.maximum, band_high.minimum};
enum class Band {
+21 -22
View File
@@ -26,44 +26,43 @@
namespace tuning {
namespace config {
namespace {
// Low band <2170 Mhz:
constexpr rf::Frequency low_band_second_lo_frequency(const rf::Frequency target_frequency) {
return 2650000000 - (target_frequency / 7);
}
constexpr rf::Frequency high_band_second_lo_regions_2_and_3(const rf::Frequency target_frequency) {
return (target_frequency < 5100000000)
? (2350000000 + ((target_frequency - 3600000000) / 5))
: (2500000000 + ((target_frequency - 5100000000) / 9));
}
constexpr rf::Frequency high_band_second_lo_frequency(const rf::Frequency target_frequency) {
return (target_frequency < 3600000000)
? (2170000000 + (((target_frequency - 2740000000) * 57) / 86))
: high_band_second_lo_regions_2_and_3(target_frequency);
return 2650'000'000 - (target_frequency / 7);
}
Config low_band(const rf::Frequency target_frequency) {
const rf::Frequency first_lo_frequency = target_frequency + low_band_second_lo_frequency(target_frequency);
const rf::Frequency second_lo_frequency = first_lo_frequency - target_frequency;
const rf::Frequency second_lo_frequency = low_band_second_lo_frequency(target_frequency);
const rf::Frequency first_lo_frequency = target_frequency + second_lo_frequency;
const bool mixer_invert = true;
return {first_lo_frequency, second_lo_frequency, rf::path::Band::Low, mixer_invert};
}
// Mid band 2170-2740 Mhz:
Config mid_band(const rf::Frequency target_frequency) {
return {0, target_frequency, rf::path::Band::Mid, false};
const rf::Frequency second_lo_frequency = target_frequency;
const rf::Frequency first_lo_frequency = 0;
const bool mixer_invert = false;
return {first_lo_frequency, second_lo_frequency, rf::path::Band::Mid, mixer_invert};
}
// High band >2740 Mhz:
constexpr rf::Frequency high_band_second_lo_frequency(const rf::Frequency target_frequency) {
if (target_frequency < 3600'000'000)
return (2170'000'000 + (((target_frequency - 2740'000'000) * 57) / 86));
else if (target_frequency < 5100'000'000)
return (2350'000'000 + ((target_frequency - 3600'000'000) / 5));
else
return (2500'000'000 + ((target_frequency - 5100'000'000) / 9));
}
Config high_band(const rf::Frequency target_frequency) {
const rf::Frequency first_lo_frequency = target_frequency - high_band_second_lo_frequency(target_frequency);
const rf::Frequency second_lo_frequency = target_frequency - first_lo_frequency;
const rf::Frequency second_lo_frequency = high_band_second_lo_frequency(target_frequency);
const rf::Frequency first_lo_frequency = target_frequency - second_lo_frequency;
const bool mixer_invert = false;
return {first_lo_frequency, second_lo_frequency, rf::path::Band::High, mixer_invert};
}
} /* namespace */
Config create(const rf::Frequency target_frequency) {
/* TODO: This is some lame code. */
if (rf::path::band_low.contains(target_frequency)) {
+2 -2
View File
@@ -118,7 +118,7 @@ uint8_t usb_descriptor_configuration_full_speed[] = {
USB_INT_IN_EP_ADDR, // bEndpointAddress
0x03, // bmAttributes: BULK
USB_WORD(16), // wMaxPacketSize
0xFF, // bInterval: no NAK
0x20, // bInterval: no NAK
9, // bLength
USB_DESCRIPTOR_TYPE_INTERFACE, // bDescriptorType
@@ -203,7 +203,7 @@ uint8_t usb_descriptor_configuration_high_speed[] = {
USB_INT_IN_EP_ADDR, // bEndpointAddress
0x03, // bmAttributes: BULK
USB_WORD(16), // wMaxPacketSize
0xFF, // bInterval: no NAK
0x20, // bInterval: no NAK
9, // bLength
USB_DESCRIPTOR_TYPE_INTERFACE, // bDescriptorType
+2 -1
View File
@@ -26,7 +26,8 @@
#include "ui_navigation.hpp"
#include "spi_image.hpp"
#define CURRENT_HEADER_VERSION 0x00000001
#define CURRENT_HEADER_VERSION 0x00000002
#define MIN_HEADER_VERSION_FOR_CHECKSUM 0x00000002
typedef void (*externalAppEntry_t)(ui::NavigationView& nav);
@@ -32,6 +32,7 @@
#include "modems.hpp"
#include "serializer.hpp"
#include "volume.hpp"
#include "config_mode.hpp"
// persistent memory from/to sdcard flag file
#define PMEM_FILEFLAG u"/SETTINGS/PMEM_FILEFLAG"
@@ -242,8 +243,6 @@ void set_disable_touchscreen(bool v);
uint8_t config_encoder_dial_sensitivity();
void set_encoder_dial_sensitivity(uint8_t v);
#define CONFIG_MODE_GUARD_VALUE 0x000007d1
#define CONFIG_MODE_NORMAL_VALUE 0x000007cf
uint32_t config_mode_storage_direct();
void set_config_mode_storage_direct(uint32_t v);
bool config_disable_config_mode_direct();
+38 -3
View File
@@ -6,6 +6,8 @@
#include <string.h>
#include "string_format.hpp"
#include "file.hpp"
#include "utility.hpp"
#include "ui_external_items_menu_loader.hpp"
class UnTar {
public:
@@ -86,6 +88,10 @@ class UnTar {
std::string binfile = "";
std::string fn = "";
int filesize;
uint32_t app_checksum;
bool app_file;
bool first_read;
bool corrupt_file{false};
for (;;) {
auto readres = a->read(buff, 512);
if (!readres.is_ok()) return "";
@@ -132,20 +138,49 @@ class UnTar {
delete_file(fn);
auto fres = f.open(fn, false, true);
if (!fres.value().ok()) return "";
app_file = (fn.substr(fn.size() - 5) == ".ppma");
first_read = true;
app_checksum = 0;
corrupt_file = false;
}
while (filesize > 0) {
readres = a->read(buff, 512);
if (!readres.is_ok()) return "";
if (!readres.is_ok()) {
corrupt_file = true;
break;
}
bytes_read = readres.value();
if (bytes_read < 512) {
return "";
corrupt_file = true;
break;
}
if (filesize < 512)
bytes_read = filesize;
if (app_file && first_read) {
// Check app file header for min version for checksum support
struct application_information_t* app_info = (struct application_information_t*)buff;
if (app_info->header_version < MIN_HEADER_VERSION_FOR_CHECKSUM)
app_file = false;
first_read = false;
}
if (app_file) {
app_checksum += simple_checksum((uint32_t)buff, bytes_read);
}
auto fwres = f.write(buff, bytes_read);
if (!fwres.is_ok()) return "";
if (!fwres.is_ok()) {
corrupt_file = true;
break;
}
filesize -= bytes_read;
f.sync();
if ((filesize == 0) && app_file && (app_checksum != EXT_APP_EXPECTED_CHECKSUM)) {
corrupt_file = true;
break;
}
}
if (corrupt_file) {
delete_file(fn);
return "";
}
}
return binfile;