Compare commits

...

10 Commits

Author SHA1 Message Date
gullradriel fd7637187a updated version number (#2855)
Co-authored-by: gullradriel <gullradriel@no-mail.com>
2025-11-07 20:52:28 +01:00
Totoo 674b865ec0 Refactor OnTouchEvent functions to return boolean values for better event handling (#2854) 2025-11-05 20:53:23 +01:00
Totoo 00c9c6b40e Fix shift key position (#2850) 2025-10-31 18:25:23 +01:00
RocketGod 113cbc42c9 Add sound effects (#2849)
* Add sound effects

Adding sound effects and volume adjuster in start menu. Sounds are a little clicky but I tinkered a long time and couldn't solve that. Maybe someone else wants to tinker a bit with me.

* Format code
2025-10-30 07:38:45 +01:00
RocketGod 454b8776b6 Refactor gfxEQView UI layout for consistency (#2848)
* Refactor gfxEQView UI layout for consistency

Updated control and graph positioning in gfxEQView to use a standard layout approach, aligning with other applications. Screen dimensions are now used for dynamic placement, and hardcoded values have been replaced for improved maintainability and consistency.

Basically, centered for smaller and larger screens with other visual improvements.

* Fixed screen to Macros - looks good now

Better methods for dynamic screen size
2025-10-30 07:33:38 +01:00
Matej Sochan efdf043d62 fix typo: wps -> wpm in morse_tx (#2847) 2025-10-28 20:55:21 +01:00
gullradriel 0f9d9e589d Revert "Additional debounce control parameters for rotary encoder settings (f…" (#2846)
This reverts commit bf18851b6b.
2025-10-28 22:34:14 +13:00
Totoo 3b57672dda sht4x support,, typo fix (#2843) 2025-10-28 10:14:11 +08:00
Totoo b739dd883c Free up some fw space (#2844) 2025-10-28 08:10:09 +08:00
rmckay bf18851b6b Additional debounce control parameters for rotary encoder settings (for bad/noisy encoders) (#2841)
* Added debounce control options for rotary encoder settings

* ran format-code.sh to adjust whitespace

---------

Co-authored-by: Robert McKay <robert.mckay@ubermorgen.land>
2025-10-27 23:56:27 +01:00
37 changed files with 594 additions and 157 deletions
+1 -1
View File
@@ -1 +1 @@
v2.1.0
v2.2.0
+1 -1
View File
@@ -1 +1 @@
v2.2.0
v2.3.0
-2
View File
@@ -192,7 +192,6 @@ set(CPPSRC
core_control.cpp
database.cpp
gradient.cpp
rfm69.cpp
event_m0.cpp
file_reader.cpp
file.cpp
@@ -261,7 +260,6 @@ set(CPPSRC
ui/ui_receiver.cpp
ui/ui_rssi.cpp
ui/ui_freqlist.cpp
ui/ui_tv.cpp
ui/ui_spectrum.cpp
ui/ui_tabview.cpp
ui/ui_textentry.cpp
+1 -1
View File
@@ -171,7 +171,7 @@ void IQTrimView::update_range_controls(iq::TrimRange trim_range) {
}
void IQTrimView::profile_capture() {
power_buckets_ = {};
power_buckets_.clear();
iq::PowerBuckets buckets{
.p = power_buckets_.data(),
.size = power_buckets_.size()};
@@ -285,9 +285,9 @@ bool StandaloneView::on_encoder(const EncoderEvent event) {
bool StandaloneView::on_touch(const TouchEvent event) {
if (get_application_information()->header_version > 1) {
get_application_information()->OnTouchEvent(event.point.x(), event.point.y(), (uint32_t)event.type);
return get_application_information()->OnTouchEvent(event.point.x(), event.point.y(), (uint32_t)event.type);
}
return true;
return false;
}
bool StandaloneView::on_keyboard(const KeyboardEvent event) {
+1 -1
View File
@@ -339,7 +339,7 @@ void SubGhzDRecentEntryDetailView::parseProtocol() {
if (entry_.sensorType == FPS_CAMEATOMO) {
entry_.data ^= 0xFFFFFFFFFFFFFFFF;
entry_.data <<= 4;
uint8_t pack[8] = {};
uint8_t pack[8];
pack[0] = (entry_.data >> 56);
pack[1] = ((entry_.data >> 48) & 0xFF);
pack[2] = ((entry_.data >> 40) & 0xFF);
+1 -1
View File
@@ -612,7 +612,7 @@ void TextEditorView::open_file(const fs::path& path) {
viewer.clear_file();
delete_temp_file(path_);
path_ = {};
path_ = "";
file_dirty_ = false;
has_temp_file_ = false;
auto result = FileWrapper::open(
@@ -34,7 +34,7 @@ using namespace portapack;
#include <cmath>
#include <array>
namespace ui {
namespace ui::external_app::analogtv {
namespace tv {
/* TimeScopeView******************************************************/
@@ -235,4 +235,4 @@ void TVWidget::on_audio_spectrum() {
}
} /* namespace tv */
} /* namespace ui */
} // namespace ui::external_app::analogtv
@@ -33,7 +33,7 @@
#include <cstdint>
#include <cstddef>
namespace ui {
namespace ui::external_app::analogtv {
namespace tv {
class TimeScopeView : public View {
@@ -167,6 +167,6 @@ class TVWidget : public View {
};
} /* namespace tv */
} /* namespace ui */
} // namespace ui::external_app::analogtv
#endif /*__UI_TV_H__*/
-1
View File
@@ -21,7 +21,6 @@
*/
#include "bht.hpp"
#include "portapack_persistent_memory.hpp"
namespace ui::external_app::bht_tx {
+1 -1
View File
@@ -207,7 +207,7 @@ class BHTView : public View {
"Scan"};
Checkbox checkbox_flashing{
{16 * 8, 25 * 8},
{UI_POS_X(16), 25 * 8},
8,
"Flashing"};
NumberField field_speed{
+12 -12
View File
@@ -20,13 +20,13 @@ void initialize_app(ui::NavigationView& nav) {
extern "C" {
__attribute__((section(".external_app.app_breakout.application_information"), used)) application_information_t _application_information_breakout = {
(uint8_t*)0x00000000,
ui::external_app::breakout::initialize_app,
CURRENT_HEADER_VERSION,
VERSION_MD5,
/*.memory_location = */ (uint8_t*)0x00000000,
/*.externalAppEntry = */ ui::external_app::breakout::initialize_app,
/*.header_version = */ CURRENT_HEADER_VERSION,
/*.app_version = */ VERSION_MD5,
"Breakout",
{
/*.app_name = */ "Breakout",
/*.bitmap_data = */ {
0x00,
0x00,
0x7F,
@@ -60,11 +60,11 @@ __attribute__((section(".external_app.app_breakout.application_information"), us
0xF7,
0xF7,
},
ui::Color::green().v,
app_location_t::GAMES,
-1,
/*.icon_color = */ ui::Color::green().v,
/*.menu_location = */ app_location_t::GAMES,
/*.desired_menu_position = */ -1,
{0, 0, 0, 0},
0x00000000,
/*.m4_app_tag = */ {'P', 'A', 'B', 'P'}, // This is the audio beep baseband tag!
/*.m4_app_offset = */ 0x00000000, // will be filled at compile time
};
} // namespace ui::external_app::breakout
}
+279 -10
View File
@@ -7,6 +7,12 @@
*/
#include "ui_breakout.hpp"
#include "baseband_api.hpp"
#include "audio.hpp"
#include "portapack.hpp"
#include "portapack_persistent_memory.hpp"
using namespace portapack;
namespace ui::external_app::breakout {
@@ -92,6 +98,37 @@ void BreakoutView::init_game() {
game_state = STATE_MENU;
menu_blink_state = true;
menu_blink_counter = 0;
// Play startup sound
if (sound_enabled) {
baseband::request_audio_beep(262, 24000, 150); // C4 -
chThdSleepMilliseconds(200);
baseband::request_audio_beep(262, 24000, 150); // C4
chThdSleepMilliseconds(200);
baseband::request_audio_beep(392, 24000, 150); // G4
chThdSleepMilliseconds(200);
baseband::request_audio_beep(392, 24000, 150); // G4
chThdSleepMilliseconds(200);
baseband::request_audio_beep(440, 24000, 150); // A4
chThdSleepMilliseconds(200);
baseband::request_audio_beep(440, 24000, 150); // A4
chThdSleepMilliseconds(200);
baseband::request_audio_beep(392, 24000, 300); // G4
chThdSleepMilliseconds(350);
baseband::request_audio_beep(349, 24000, 150); // F4
chThdSleepMilliseconds(200);
baseband::request_audio_beep(349, 24000, 150); // F4
chThdSleepMilliseconds(200);
baseband::request_audio_beep(330, 24000, 150); // E4
chThdSleepMilliseconds(200);
baseband::request_audio_beep(330, 24000, 150); // E4
chThdSleepMilliseconds(200);
baseband::request_audio_beep(294, 24000, 150); // D4
chThdSleepMilliseconds(200);
baseband::request_audio_beep(294, 24000, 150); // D4
chThdSleepMilliseconds(200);
baseband::request_audio_beep(262, 24000, 400); // C4
}
}
void BreakoutView::init_level() {
@@ -126,6 +163,34 @@ void BreakoutView::draw_screen() {
draw_level();
}
void BreakoutView::draw_menu_volume_bar() {
// Clear the entire volume area first to handle bar shrinking
painter.fill_rectangle({40, 259, 220, 40}, Color::black());
// Draw volume label
auto style = *ui::Theme::getInstance()->fg_light;
painter.draw_string({40, 260}, style, "Volume:");
// Draw volume bar background
painter.draw_rectangle({100, 259, 102, 10}, Color::grey());
// Draw volume level
int bar_width = (volume_level * 100) / 99;
if (bar_width > 0) {
painter.fill_rectangle({101, 260, bar_width, 8}, Color::green());
}
// Draw percentage
painter.draw_string({210, 260}, style, std::to_string(volume_level) + "%");
// Draw sound status
if (sound_enabled) {
painter.draw_string({UI_POS_X_CENTER(11), 280}, *ui::Theme::getInstance()->fg_green, "Sound: ON");
} else {
painter.draw_string({UI_POS_X_CENTER(11), 280}, *ui::Theme::getInstance()->fg_red, "Sound: OFF");
}
}
void BreakoutView::draw_borders() {
rect(0, GAME_AREA_TOP - 1, SCREEN_WIDTH, GAME_AREA_TOP, COLOR_BORDER);
}
@@ -166,6 +231,22 @@ void BreakoutView::draw_level() {
painter.draw_string({80, 30}, style, "Level: " + std::to_string(level));
}
void BreakoutView::adjust_volume(int delta) {
volume_level += delta;
if (volume_level < 0) volume_level = 0;
if (volume_level > 99) volume_level = 99;
// Update the actual audio volume using decibel conversion
// Map 0-99 to roughly -60dB to 0dB range
int db = (volume_level - 99) * 60 / 99; // Maps 0->-60dB, 99->0dB
audio::headphone::set_volume(volume_t::decibel(db));
// If we're in the menu, redraw the volume bar
if (game_state == STATE_MENU) {
draw_menu_volume_bar();
}
}
void BreakoutView::move_paddle_left() {
if (paddle_x > 0) {
fillrect(paddle_x, PADDLE_Y, paddle_x + PADDLE_WIDTH, PADDLE_Y + PADDLE_HEIGHT, COLOR_BACKGROUND);
@@ -231,19 +312,23 @@ void BreakoutView::update_game() {
if (ball_x < 0) {
ball_x = 0;
ball_dx = -ball_dx;
play_wall_hit();
} else if (ball_x > SCREEN_WIDTH - BALL_SIZE) {
ball_x = SCREEN_WIDTH - BALL_SIZE;
ball_dx = -ball_dx;
play_wall_hit();
}
if (ball_y < GAME_AREA_TOP) {
ball_y = GAME_AREA_TOP;
ball_dy = -ball_dy;
play_wall_hit();
}
// Bottom edge - lose life
if (ball_y > GAME_AREA_BOTTOM) {
lives--;
play_death_sound(); // Play death sound
draw_lives();
if (lives <= 0) {
handle_game_over();
@@ -262,6 +347,8 @@ void BreakoutView::update_game() {
ball_y = PADDLE_Y - BALL_SIZE;
ball_dy = -ball_dy;
play_paddle_hit();
// Add some angle based on hit position
float hit_position = (ball_x + (BALL_SIZE / 2)) - paddle_x;
float angle = (hit_position / PADDLE_WIDTH) - 0.5f;
@@ -301,6 +388,8 @@ bool BreakoutView::check_brick_collision(int row, int col) {
score += (5 - row) * 10;
draw_score();
play_brick_hit();
ball_dy = -ball_dy;
return true;
}
@@ -314,6 +403,8 @@ bool BreakoutView::check_level_complete() {
void BreakoutView::next_level() {
level++;
play_level_complete();
chThdSleepMilliseconds(500); // Give time for sound to play
init_level();
draw_screen();
}
@@ -322,9 +413,11 @@ void BreakoutView::handle_game_over() {
game_state = STATE_GAME_OVER;
gameover_blink_state = true;
gameover_blink_counter = 0;
play_game_over();
}
void BreakoutView::show_menu() {
// Only draw the static parts once
if (menu_blink_counter == 0) {
cls();
background(COLOR_BACKGROUND);
@@ -338,23 +431,30 @@ void BreakoutView::show_menu() {
painter.draw_string({UI_POS_X_CENTER(20), 130}, style_cyan, "ROTARY: MOVE PADDLE");
painter.draw_string({UI_POS_X_CENTER(21), 160}, style_cyan, "SELECT: START/LAUNCH");
painter.draw_string({UI_POS_X_CENTER(25), 190}, style_blue, "========================");
// Volume adjustment instructions
painter.draw_string({UI_POS_X_CENTER(24), 220}, style_cyan, "Press UP/DOWN for Volume");
// Draw volume control at bottom
draw_menu_volume_bar();
}
auto style_red = *ui::Theme::getInstance()->fg_red;
// Only flash the "PRESS SELECT" text
if (++menu_blink_counter >= 30) {
menu_blink_counter = 0;
menu_blink_counter = 1; // Keep it at 1 so we don't redraw everything
menu_blink_state = !menu_blink_state;
painter.fill_rectangle({UI_POS_X_CENTER(17), 228, 128, 20}, Color::black());
auto style_red = *ui::Theme::getInstance()->fg_red;
painter.fill_rectangle({UI_POS_X_CENTER(17), 238, 128, 20}, Color::black());
if (menu_blink_state) {
painter.draw_string({UI_POS_X_CENTER(17), 230}, style_red, "* PRESS SELECT *");
painter.draw_string({UI_POS_X_CENTER(17), 240}, style_red, "* PRESS SELECT *");
}
}
}
void BreakoutView::show_game_over() {
// Only draw the static parts once
if (gameover_blink_counter == 0) {
cls();
background(COLOR_BACKGROUND);
@@ -366,12 +466,12 @@ void BreakoutView::show_game_over() {
painter.draw_string({UI_POS_X_CENTER(11), 150}, style_yellow, "SCORE: " + std::to_string(score));
}
auto style_green = *ui::Theme::getInstance()->fg_green;
// Only flash the "PRESS SELECT" text
if (++gameover_blink_counter >= 30) {
gameover_blink_counter = 0;
gameover_blink_counter = 1; // Keep it at 1 so we don't redraw everything
gameover_blink_state = !gameover_blink_state;
auto style_green = *ui::Theme::getInstance()->fg_green;
painter.fill_rectangle({UI_POS_X_CENTER(13), 198, 96, 20}, Color::black());
if (gameover_blink_state) {
@@ -385,17 +485,169 @@ void BreakoutView::reset_game() {
score = 0;
lives = 3;
game_state = STATE_PLAYING;
dummy.focus();
init_level();
draw_screen();
}
// Sound effect implementations with timing control
void BreakoutView::play_paddle_hit() {
if (sound_enabled) {
uint32_t current_time = chTimeNow();
if (current_time - last_sound_time >= min_sound_interval) {
baseband::request_beep_stop(); // Stop any previous sound
chThdSleepMilliseconds(5); // Small delay
baseband::request_audio_beep(440, 24000, 40); // 440Hz A4, 40ms
last_sound_time = current_time;
}
}
}
void BreakoutView::play_brick_hit() {
if (sound_enabled) {
uint32_t current_time = chTimeNow();
if (current_time - last_sound_time >= min_sound_interval) {
baseband::request_beep_stop(); // Stop any previous sound
chThdSleepMilliseconds(5); // Small delay
// Higher pitch that varies with remaining bricks
uint32_t freq = 880 + ((25 - brick_count) * 20); // Gets higher as bricks are destroyed
baseband::request_audio_beep(freq, 24000, 30);
last_sound_time = current_time;
}
}
}
void BreakoutView::play_wall_hit() {
if (sound_enabled) {
uint32_t current_time = chTimeNow();
if (current_time - last_sound_time >= min_sound_interval) {
baseband::request_beep_stop(); // Stop any previous sound
chThdSleepMilliseconds(5); // Small delay
baseband::request_audio_beep(220, 24000, 120); // 220Hz A3, 120ms
last_sound_time = current_time;
}
}
}
void BreakoutView::play_death_sound() {
if (sound_enabled) {
baseband::request_audio_beep(493, 24000, 150); // B4
chThdSleepMilliseconds(180);
baseband::request_audio_beep(466, 24000, 150); // Bb4
chThdSleepMilliseconds(180);
baseband::request_audio_beep(440, 24000, 150); // A4
chThdSleepMilliseconds(180);
baseband::request_audio_beep(415, 24000, 150); // Ab4
chThdSleepMilliseconds(180);
baseband::request_audio_beep(392, 24000, 150); // G4
chThdSleepMilliseconds(180);
baseband::request_audio_beep(369, 24000, 150); // Gb4
chThdSleepMilliseconds(180);
baseband::request_audio_beep(349, 24000, 150); // F4
chThdSleepMilliseconds(180);
baseband::request_audio_beep(329, 24000, 150); // E4
chThdSleepMilliseconds(180);
baseband::request_audio_beep(293, 24000, 150); // D4
chThdSleepMilliseconds(180);
baseband::request_audio_beep(261, 24000, 150); // C4
chThdSleepMilliseconds(180);
baseband::request_audio_beep(196, 24000, 200); // G3
chThdSleepMilliseconds(230);
baseband::request_audio_beep(130, 24000, 300); // C3
}
}
void BreakoutView::play_game_over() {
if (sound_enabled) {
// First phrase
baseband::request_audio_beep(392, 24000, 300); // G4
chThdSleepMilliseconds(350);
baseband::request_audio_beep(392, 24000, 150); // G4
chThdSleepMilliseconds(200);
baseband::request_audio_beep(392, 24000, 150); // G4
chThdSleepMilliseconds(200);
baseband::request_audio_beep(311, 24000, 500); // Eb4 - long
chThdSleepMilliseconds(600);
// Second phrase
baseband::request_audio_beep(349, 24000, 300); // F4
chThdSleepMilliseconds(350);
baseband::request_audio_beep(349, 24000, 150); // F4
chThdSleepMilliseconds(200);
baseband::request_audio_beep(349, 24000, 150); // F4
chThdSleepMilliseconds(200);
baseband::request_audio_beep(294, 24000, 500); // D4 - long
chThdSleepMilliseconds(600);
// Final phrase - slower and more dramatic
baseband::request_audio_beep(262, 24000, 200); // C4
chThdSleepMilliseconds(250);
baseband::request_audio_beep(247, 24000, 200); // B3
chThdSleepMilliseconds(250);
baseband::request_audio_beep(233, 24000, 200); // Bb3
chThdSleepMilliseconds(250);
baseband::request_audio_beep(220, 24000, 200); // A3
chThdSleepMilliseconds(250);
baseband::request_audio_beep(196, 24000, 200); // G3
chThdSleepMilliseconds(250);
baseband::request_audio_beep(175, 24000, 200); // F3
chThdSleepMilliseconds(250);
baseband::request_audio_beep(131, 24000, 600); // C3
}
}
void BreakoutView::play_level_complete() {
if (sound_enabled) {
baseband::request_beep_stop(); // Stop any previous sound
chThdSleepMilliseconds(10);
baseband::request_audio_beep(1047, 24000, 300); // 1047Hz C6, 300ms
}
}
BreakoutView::BreakoutView(NavigationView& nav)
: nav_{nav}, bricks{} { // Add bricks{} here
: nav_{nav}, bricks{} {
// Initialize audio system for beeps FIRST
baseband::run_prepared_image(portapack::memory::map::m4_code.base()); // Load the audio beep baseband
add_children({&dummy});
// Initialize audio
audio::set_rate(audio::Rate::Hz_24000);
audio::output::start();
// Set initial volume to 80% and ensure sound is ON
volume_level = 80;
sound_enabled = true; // Make sure this is explicitly set to ON
// Set the actual volume
int db = (volume_level - 99) * 60 / 99; // Maps to roughly -12dB for 80%
audio::headphone::set_volume(volume_t::decibel(db));
attach(1.0 / 60.0);
}
BreakoutView::~BreakoutView() {
// Clean shutdown
baseband::request_beep_stop();
receiver_model.disable();
baseband::shutdown();
audio::output::stop();
}
void BreakoutView::on_show() {
// Nothing needed here, initialization done in constructor
}
void BreakoutView::on_hide() {
// Additional cleanup
baseband::request_beep_stop();
audio::output::stop();
}
void BreakoutView::focus() {
dummy.focus();
}
void BreakoutView::paint(Painter& painter) {
@@ -433,16 +685,33 @@ bool BreakoutView::on_key(const KeyEvent key) {
} else if (game_state == STATE_PLAYING && ball_attached) {
launch_ball();
} else if (game_state == STATE_GAME_OVER) {
reset_game();
// Return to menu after game over
game_state = STATE_MENU;
menu_blink_counter = 0;
init_game();
}
} else if (key == KeyEvent::Left && game_state == STATE_PLAYING) {
move_paddle_left();
} else if (key == KeyEvent::Right && game_state == STATE_PLAYING) {
move_paddle_right();
} else if (key == KeyEvent::Up && game_state == STATE_MENU) {
// Only adjust volume in menu
adjust_volume(5);
if (!sound_enabled) sound_enabled = true;
set_dirty();
} else if (key == KeyEvent::Down && game_state == STATE_MENU) {
// Only adjust volume in menu
adjust_volume(-5);
set_dirty();
}
set_dirty();
return true;
}
bool BreakoutView::on_touch(const TouchEvent event) {
(void)event; // Intentionally unused - touch disabled to avoid nav bar issues
return true;
}
} // namespace ui::external_app::breakout
+21 -1
View File
@@ -11,6 +11,7 @@
#include "ui.hpp"
#include "ui_navigation.hpp"
#include "ui_receiver.hpp"
#include "event_m0.hpp"
#include "message.hpp"
#include "irq_controls.hpp"
@@ -56,15 +57,18 @@ enum {
class BreakoutView : public View {
public:
BreakoutView(NavigationView& nav);
~BreakoutView();
void on_show() override;
void on_hide() override;
std::string title() const override { return "Breakout"; }
void focus() override { dummy.focus(); }
void focus() override;
void paint(Painter& painter) override;
void frame_sync();
bool on_encoder(const EncoderEvent event) override;
bool on_key(KeyEvent key) override;
bool on_touch(const TouchEvent event) override;
void cls();
void background(int color);
@@ -81,6 +85,7 @@ class BreakoutView : public View {
void draw_lives();
void draw_level();
void draw_borders();
void draw_menu_volume_bar();
void move_paddle_left();
void move_paddle_right();
void launch_ball();
@@ -96,6 +101,15 @@ class BreakoutView : public View {
void check_game_timer();
void attach(double delay_sec);
void detach();
void adjust_volume(int delta);
// Sound effect methods
void play_paddle_hit();
void play_brick_hit();
void play_wall_hit();
void play_death_sound();
void play_game_over();
void play_level_complete();
private:
const Color pp_colors[9] = {
@@ -147,6 +161,12 @@ class BreakoutView : public View {
double game_update_timeout = 0;
uint32_t game_update_counter = 0;
// Audio control
bool sound_enabled = true;
int volume_level = 80; // 0-99
uint32_t last_sound_time = 0;
uint32_t min_sound_interval = 20; // Minimum ms between sounds
Button dummy{
{screen_width, 0, 0, 0},
""};
+75 -73
View File
@@ -1,265 +1,267 @@
set(EXTCPPSRC
#afsk_rx
#afsk_rx 16 byte
external/afsk_rx/main.cpp
external/afsk_rx/ui_afsk_rx.cpp
#calculator
#calculator 632 bytes
external/calculator/main.cpp
external/calculator/ui_calculator.cpp
#font_viewer
#font_viewer 8 byte?!
external/font_viewer/main.cpp
external/font_viewer/ui_font_viewer.cpp
#blespam
#blespam 336 bytes - array initializers?
external/blespam/main.cpp
external/blespam/ui_blespam.cpp
#analogtv
#analogtv 552 bytes
external/analogtv/main.cpp
external/analogtv/analog_tv_app.cpp
external/analogtv/ui_tv.cpp
#nrf_rx
#nrf_rx 40 byte
external/nrf_rx/main.cpp
external/nrf_rx/ui_nrf_rx.cpp
#coasterp
#coasterp 0 byte
external/coasterp/main.cpp
external/coasterp/ui_coasterp.cpp
#lge
#lge 120 byte
external/lge/main.cpp
external/lge/lge_app.cpp
external/lge/rfm69.cpp
#lcr
#lcr - 460 byte flash
external/lcr/main.cpp
external/lcr/ui_lcr.cpp
#jammer
#jammer 144 byte
external/jammer/main.cpp
external/jammer/ui_jammer.cpp
#gpssim
#gpssim 160 byte
external/gpssim/main.cpp
external/gpssim/gps_sim_app.cpp
#spainter
#spainter 464 byte
external/spainter/main.cpp
external/spainter/ui_spectrum_painter.cpp
external/spainter/ui_spectrum_painter_text.cpp
external/spainter/ui_spectrum_painter_image.cpp
#keyfob
#keyfob 216 byte
external/keyfob/main.cpp
external/keyfob/ui_keyfob.cpp
external/keyfob/ui_keyfob.hpp
#tetris
#tetris 88 byte
external/tetris/main.cpp
external/tetris/ui_tetris.cpp
#extsensors
#extsensors 192 byte
external/extsensors/main.cpp
external/extsensors/ui_extsensors.cpp
external/extsensors/ui_extsensors.hpp
#foxhunt
#foxhunt 0
external/foxhunt/main.cpp
external/foxhunt/ui_foxhunt_rx.cpp
external/foxhunt/ui_foxhunt_rx.hpp
#audio_test
#audio_test 192 byte
external/audio_test/main.cpp
external/audio_test/ui_audio_test.cpp
#wardrivemap
#wardrivemap 64 byte
external/wardrivemap/main.cpp
external/wardrivemap/ui_wardrivemap.cpp
#tpmsrx
#tpmsrx 920 byte- possible shared part with baseband
external/tpmsrx/main.cpp
external/tpmsrx/tpms_app.cpp
#protoview
#protoview 8 byte
external/protoview/main.cpp
external/protoview/ui_protoview.cpp
#adsbtx
#adsbtx 3544 byte - adsb shared part
external/adsbtx/main.cpp
external/adsbtx/ui_adsb_tx.cpp
#morse_tx
#morse_tx 768 bytes
external/morse_tx/main.cpp
external/morse_tx/ui_morse.cpp
#sstvtx
#sstvtx 456 bytes
external/sstvtx/main.cpp
external/sstvtx/ui_sstvtx.cpp
#random
#random 464 bytes.
external/random_password/main.cpp
external/random_password/ui_random_password.cpp
external/random_password/sha512.cpp
external/random_password/sha512.h
#acars
external/acars_rx/main.cpp
external/acars_rx/acars_app.cpp
#external/acars_rx/main.cpp
#external/acars_rx/acars_app.cpp
#wefax_rx
#wefax_rx 192 bytes
external/wefax_rx/main.cpp
external/wefax_rx/ui_wefax_rx.cpp
#noaaapt_rx
#noaaapt_rx 72 bytes
external/noaaapt_rx/main.cpp
external/noaaapt_rx/ui_noaaapt_rx.cpp
#shoppingcart_lock
#shoppingcart_lock 272 bytes
external/shoppingcart_lock/main.cpp
external/shoppingcart_lock/shoppingcart_lock.cpp
#ookbrute
#ookbrute 80 byte
external/ookbrute/main.cpp
external/ookbrute/ui_ookbrute.cpp
#ook_editor
#ook_editor 1808 bytes
external/ook_editor/main.cpp
external/ook_editor/ui_ook_editor.cpp
#cvs_spam
#cvs_spam 24 byte
external/cvs_spam/main.cpp
external/cvs_spam/cvs_spam.cpp
#flippertx
#flippertx 712 bytes
external/flippertx/main.cpp
external/flippertx/ui_flippertx.cpp
#remote
#remote 1664 bytes
external/remote/main.cpp
external/remote/ui_remote.cpp
#mcu_temperature
#mcu_temperature 112
external/mcu_temperature/main.cpp
external/mcu_temperature/mcu_temperature.cpp
#fmradio
#fmradio 640
external/fmradio/main.cpp
external/fmradio/ui_fmradio.cpp
#tuner
#tuner 384
external/tuner/main.cpp
external/tuner/ui_tuner.cpp
#metronome
#metronome 696 bytes
external/metronome/main.cpp
external/metronome/ui_metronome.cpp
#app_manager
#app_manager 40 bytes
external/app_manager/main.cpp
external/app_manager/ui_app_manager.cpp
#hopper
#hopper 472 bytes
external/hopper/main.cpp
external/hopper/ui_hopper.cpp
# whip calculator
# whip calculator 48 bytes
external/antenna_length/main.cpp
external/antenna_length/ui_whipcalc.cpp
# wav viewer
# wav viewer 1232 bytes
external/wav_view/main.cpp
external/wav_view/ui_view_wav.cpp
# wipe sdcard
# wipe sdcard 16 byte
external/sd_wipe/main.cpp
external/sd_wipe/ui_sd_wipe.cpp
# playlist editor
# playlist editor 232 bytes
external/playlist_editor/main.cpp
external/playlist_editor/ui_playlist_editor.cpp
#snake
#snake 240 bytes
external/snake/main.cpp
external/snake/ui_snake.cpp
#stopwatch
#stopwatch 0
external/stopwatch/main.cpp
external/stopwatch/ui_stopwatch.cpp
#breakout
#breakout 1144 bytes
external/breakout/main.cpp
external/breakout/ui_breakout.cpp
#dinogame
#dinogame 0
external/dinogame/main.cpp
external/dinogame/ui_dinogame.cpp
#doom
#doom 224
external/doom/main.cpp
external/doom/ui_doom.cpp
#debug_pmem
#debug_pmem 944 byte
external/debug_pmem/main.cpp
external/debug_pmem/ui_debug_pmem.cpp
#scanner
#scanner 520 byte
external/scanner/main.cpp
external/scanner/ui_scanner.cpp
#level
#level 24 byte
external/level/main.cpp
external/level/ui_level.cpp
#gfxEQ
#gfxEQ 80 byte
external/gfxeq/main.cpp
external/gfxeq/ui_gfxeq.cpp
#detector_rx
#detector_rx 168 byte
external/detector_rx/main.cpp
external/detector_rx/ui_detector_rx.cpp
#space_invaders
#space_invaders 0 byte
external/spaceinv/main.cpp
external/spaceinv/ui_spaceinv.cpp
#blackjack
#blackjack 24 byte
external/blackjack/main.cpp
external/blackjack/ui_blackjack.cpp
#battleship
#battleship 256 byte
external/battleship/main.cpp
external/battleship/ui_battleship.cpp
#ert
#ert 3040 bytes - has common with baseband, could be renamed the namespace, so both could have it, but not kept in fw.
external/ert/main.cpp
external/ert/ert_app.cpp
#epirb_rx
#epirb_rx 168 byte flash
external/epirb_rx/main.cpp
external/epirb_rx/ui_epirb_rx.cpp
#soundboard
#soundboard 272byte - 1236 bytes
external/soundboard/main.cpp
external/soundboard/soundboard_app.cpp
#game2048
#game2048 - 168 byte flash
external/game2048/main.cpp
external/game2048/ui_game2048.cpp
#bht_tx
#bht_tx - 3920 byte flash, unknown
external/bht_tx/main.cpp
external/bht_tx/ui_bht_tx.cpp
external/bht_tx/bht.cpp
#morse_practice
#morse_practice - 80 byte flash - bc of array initializers
external/morse_practice/main.cpp
external/morse_practice/ui_morse_practice.cpp
#adult_toys_controller
#adult_toys_controller 144 bytes
external/adult_toys_controller/main.cpp
external/adult_toys_controller/ui_adult_toys_controller.cpp
)
@@ -269,8 +271,8 @@ set(EXTAPPLIST
calculator
font_viewer
blespam
nrf_rx
analogtv
nrf_rx
coasterp
lge
lcr
@@ -283,19 +285,19 @@ set(EXTAPPLIST
foxhunt_rx
audio_test
wardrivemap
cvs_spam
tpmsrx
protoview
adsbtx
morse_tx
sstvtx
random_password
# acars_rx
ookbrute
ook_editor
# acars_rx --not working
wefax_rx
noaaapt_rx
shoppingcart_lock
ookbrute
ook_editor
cvs_spam
flippertx
remote
mcu_temperature
+1 -1
View File
@@ -79,7 +79,7 @@ class FlipperTxView : public View {
void on_tx_progress(const bool done);
bool on_file_changed(std::filesystem::path new_file_path);
std::filesystem::path filename = {};
std::filesystem::path filename = "";
FlipperProto proto = FLIPPER_PROTO_UNSUPPORTED;
FlipperPreset preset = FLIPPER_PRESET_UNK;
uint16_t te = 0; // for binraw
-1
View File
@@ -41,7 +41,6 @@ gfxEQView::gfxEQView(NavigationView& nav)
audio::set_rate(audio::Rate::Hz_48000);
audio::output::start();
receiver_model.set_headphone_volume(receiver_model.headphone_volume()); // WM8731 hack
//
receiver_model.enable();
receiver_model.set_target_frequency(frequency_value); // Retune to actual freq
+9 -7
View File
@@ -46,6 +46,7 @@ class gfxEQView : public View {
NavigationView& nav_;
uint32_t current_theme{0};
const std::array<ColorTheme, 20> themes{
ColorTheme{Color(255, 0, 255), Color(255, 255, 255)},
ColorTheme{Color(0, 255, 0), Color(255, 0, 0)},
@@ -68,13 +69,14 @@ class gfxEQView : public View {
ColorTheme{Color(64, 64, 64), Color(255, 0, 0)},
ColorTheme{Color(255, 192, 0), Color(0, 64, 128)}};
ButtonWithEncoder button_frequency{{UI_POS_X(0), UI_POS_Y(0) + 4, 11 * 8, 1 * 8}, ""};
RFAmpField field_rf_amp{{13 * 8, UI_POS_Y(0)}};
LNAGainField field_lna{{15 * 8, UI_POS_Y(0)}};
VGAGainField field_vga{{18 * 8, UI_POS_Y(0)}};
Button button_mood{{21 * 8, 0, 6 * 8, 16}, "MOOD"};
AudioVolumeField field_volume{{screen_width - 2 * 8, UI_POS_Y(0)}};
GraphEq gr{{2, UI_POS_DEFAULT_HEIGHT, UI_POS_MAXWIDTH - 4, UI_POS_HEIGHT_REMAINING(2)}, false};
// Widgets with positions using UI_POS macros
ButtonWithEncoder button_frequency{{UI_POS_X(0), UI_POS_Y(0) + 4, UI_POS_WIDTH(11), UI_POS_HEIGHT(1)}, ""};
RFAmpField field_rf_amp{{UI_POS_X(12), UI_POS_Y(0) + 4}};
LNAGainField field_lna{{UI_POS_X(14), UI_POS_Y(0) + 4}};
VGAGainField field_vga{{UI_POS_X(17), UI_POS_Y(0) + 4}};
Button button_mood{{UI_POS_X(21), UI_POS_Y(0) + 4, UI_POS_WIDTH(4), UI_POS_HEIGHT(1)}, "MOOD"};
AudioVolumeField field_volume{{UI_POS_X_RIGHT(2), UI_POS_Y(0) + 4}};
GraphEq gr{{2, UI_POS_Y(1) + 8, UI_POS_MAXWIDTH, UI_POS_Y_BOTTOM(1) - 28}, false};
rf::Frequency frequency_value{93100000};
@@ -24,6 +24,8 @@
#include "crc.hpp"
#include "portapack_shared_memory.hpp"
namespace ui::external_app::lge {
uint32_t RFM69::gen_frame(std::vector<uint8_t>& payload) {
CRC<16> crc{0x1021, 0x1D0F, 0xFFFF};
std::vector<uint8_t> frame{};
@@ -74,3 +76,5 @@ uint32_t RFM69::gen_frame(std::vector<uint8_t>& payload) {
// Copy for baseband
return frame.size();
}
} /* namespace ui::external_app::lge */
@@ -28,6 +28,8 @@
#include "utility.hpp"
namespace ui::external_app::lge {
class RFM69 {
public:
RFM69(const uint8_t num_preamble, const uint16_t sync_word, const bool CRC, const bool manchester)
@@ -54,4 +56,6 @@ class RFM69 {
bool manchester_{false};
};
} /* namespace ui::external_app::lge */
#endif /*__RFM69_H__*/
+1 -1
View File
@@ -110,7 +110,7 @@ class MorseView : public View {
bool run{false};
Labels labels{
{{4 * 8, 6 * 8}, "Speed: wps", Theme::getInstance()->fg_light->foreground},
{{4 * 8, 6 * 8}, "Speed: wpm", Theme::getInstance()->fg_light->foreground},
{{4 * 8, 8 * 8}, "Tone: Hz", Theme::getInstance()->fg_light->foreground},
{{4 * 8, 10 * 8}, "Modulation:", Theme::getInstance()->fg_light->foreground},
{{4 * 8, 12 * 8}, "Loop:", Theme::getInstance()->fg_light->foreground},
@@ -231,7 +231,7 @@ void RandomPasswordView::on_data(uint32_t value, bool is_data) {
}
void RandomPasswordView::clean_buffer() {
seeds_deque = {};
seeds_deque.clear();
}
void RandomPasswordView::on_freqchg(int64_t freq) {
@@ -247,6 +247,18 @@ void RandomPasswordView::set_random_freq() {
field_frequency.set_value(random_freq);
}
bool RandomPasswordView::islower(char c) {
return (c >= 'a' && c <= 'z');
}
bool RandomPasswordView::isupper(char c) {
return (c >= 'A' && c <= 'Z');
}
bool RandomPasswordView::isdigit(char c) {
return (c >= '0' && c <= '9');
}
void RandomPasswordView::new_password() {
if (seeds_deque.size() < MAX_DIGITS * 2) {
seeds_buffer_not_full = true;
@@ -261,21 +273,21 @@ void RandomPasswordView::new_password() {
int password_length = field_digits.value();
/// charset worker
if (check_digits.value())
charset += "0123456789";
if (check_latin_lower.value())
charset += "abcdefghijklmnopqrstuvwxyz";
if (check_latin_upper.value())
charset += "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
if (check_digits.value()) {
charset += "23456789";
if (check_allow_confusable_chars.value()) charset += "01";
}
if (check_latin_lower.value()) {
charset += "abcdefghijkmnpqrstuvwxyz";
if (check_allow_confusable_chars.value()) charset += "ol";
}
if (check_latin_upper.value()) {
charset += "ABCDEFGHIJKLMNPQRSTUVWXYZ";
if (check_allow_confusable_chars.value()) charset += "O";
}
if (check_punctuation.value())
charset += ".,-!?";
if (!check_allow_confusable_chars.value()) {
charset.erase(std::remove_if(charset.begin(), charset.end(),
[](char c) { return c == '0' || c == 'O' || c == 'o' || c == '1' || c == 'l'; }),
charset.end());
}
if (charset.empty()) {
text_generated_passwd.set("generate failed,");
text_char_type_hints.set("select at least 1 type");
@@ -306,11 +318,11 @@ void RandomPasswordView::new_password() {
/// hint text worker
for (char c : password_chars) {
password += c;
if (std::isdigit(c)) {
if (isdigit(c)) {
char_type_hints += "1";
} else if (std::islower(c)) {
} else if (islower(c)) {
char_type_hints += "a";
} else if (std::isupper(c)) {
} else if (isupper(c)) {
char_type_hints += "A";
} else {
char_type_hints += ",";
@@ -360,11 +372,11 @@ void RandomPasswordView::paint_password_hints() {
for (size_t i = 0; i < password.length(); i++) {
char c = password[i];
Color color;
if (std::isdigit(c)) {
if (isdigit(c)) {
color = Color::red();
} else if (std::islower(c)) {
} else if (islower(c)) {
color = Color::green();
} else if (std::isupper(c)) {
} else if (isupper(c)) {
color = Color::blue();
} else {
color = Color::white();
@@ -379,8 +391,8 @@ void RandomPasswordView::paint_password_hints() {
std::string RandomPasswordView::generate_log_line() {
std::string seeds_set = "";
for (auto seed : seeds_deque) {
seeds_set += std::to_string(seed);
for (unsigned int seed : seeds_deque) {
seeds_set += to_string_dec_uint(seed);
seeds_set += " ";
}
std::string line = "\npassword=" + password +
@@ -92,6 +92,10 @@ class RandomPasswordView : public View {
std::string generate_log_line();
void paint_password_hints();
bool islower(char c);
bool isupper(char c);
bool isdigit(char c);
NavigationView& nav_;
RxRadioState radio_state_{};
app_settings::SettingsManager settings_{
+1 -1
View File
@@ -114,7 +114,7 @@ Optional<capture_metadata> read_metadata_file(const fs::path& path) {
}
bool parse_float_meta(std::string_view str, float& out_val) {
out_val = {};
out_val = 0.0f;
if (str.size() > max_parse_int_length)
return false;
+1 -1
View File
@@ -81,7 +81,7 @@ class AlphanumView : public TextEntryView {
std::array<Button, 29> buttons{};
NewButton button_shift{
{192, 214, screen_width / 5, 38},
{screen_width - screen_width / 5, 214, screen_width / 5, 38},
{},
&bitmap_icon_shift,
Theme::getInstance()->bg_dark->background,
+3 -4
View File
@@ -769,9 +769,9 @@ void add_apps(NavigationView& nav, BtnGridView& grid, app_location_t loc) {
}
// clang-format off
void add_external_items(NavigationView& nav, app_location_t location, BtnGridView& grid, uint8_t error_tile_pos) {
void add_external_items(NavigationView& nav, app_location_t location, BtnGridView& grid, uint8_t error_tile_pos, bool show_error_tile ) {
auto externalItems = ExternalItemsMenuLoader::load_external_items(location, nav);
if (externalItems.empty()) {
if (externalItems.empty() && show_error_tile) {
grid.insert_item({"ExtAppErr",
Theme::getInstance()->error_dark->foreground,
nullptr,
@@ -848,8 +848,7 @@ void TranceiversMenuView::on_populate() {
add_items({{"..", Theme::getInstance()->fg_light->foreground, &bitmap_icon_previous, [this]() { nav_.pop(); }}});
}
add_apps(nav_, *this, TRX);
// add_external_items(nav_, app_location_t::TRX, *this, return_icon ? 1 : 0);
// this folder doesn't have external apps, comment to prevent pop the err msg.
add_external_items(nav_, app_location_t::TRX, *this, return_icon ? 1 : 0, false); // this folder doesn't have external apps, so don't show error for it.
// NB: when has external app someday, uncomment this.
}
+1 -1
View File
@@ -61,7 +61,7 @@ using namespace sd_card;
namespace ui {
void add_apps(NavigationView& nav, BtnGridView& grid, app_location_t loc);
void add_external_items(NavigationView& nav, app_location_t location, BtnGridView& grid, uint8_t error_tile_pos);
void add_external_items(NavigationView& nav, app_location_t location, BtnGridView& grid, uint8_t error_tile_pos, bool show_error_tile = true);
bool verify_sdcard_format();
enum modal_t {
+2 -2
View File
@@ -175,7 +175,7 @@ void RecordView::start() {
text_record_filename.set("");
text_record_dropped.set("");
trim_path = {};
trim_path = "";
if (sampling_rate == 0) {
return;
@@ -348,7 +348,7 @@ void RecordView::trim_capture() {
trim_ui.clear();
}
trim_path = {};
trim_path = "";
}
void RecordView::on_gps(const GPSPosDataMessage* msg) {
+1 -1
View File
@@ -32,7 +32,7 @@ namespace i2cdev {
bool I2cDev_BH1750::init(uint8_t addr_) {
if (addr_ != I2CDEV_BH1750_ADDR_1) return false;
addr = addr_;
model = I2CDECMDL_BH1750;
model = I2CDEVMDL_BH1750;
query_interval = 3;
// power up
+61
View File
@@ -0,0 +1,61 @@
/*
* Copyright (C) 2024 HTotoo.
*
* 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 "i2cdev_sht4x.hpp"
namespace i2cdev {
bool I2cDev_SHT4x::init(uint8_t addr_) {
if (addr_ != I2CDEV_SHT4X_ADDR_1 && addr_ != I2CDEV_SHT4X_ADDR_2) return false;
addr = addr_; // store the addr
model = I2C_DEVMDL::I2CDEVMDL_SHT4X; // set the device model!!!!!!!!!!!!!!!!!!
query_interval = 10; // set update interval in sec
chThdSleepMilliseconds(50);
uint8_t tmp[1]; // command buffer
uint8_t rx[6]; // response buffer
tmp[0] = SHT4X_SERIAL_NUMBER_CMD_ID;
if (!i2c_write(nullptr, 0, tmp, 1)) return false; // get serial number
chThdSleepMilliseconds(10);
if (!i2c_read(nullptr, 0, rx, 6)) return false; // read serial number
return true;
}
void I2cDev_SHT4x::update() {
float temp = 0;
float hum = 0;
uint8_t cmd[1];
cmd[0] = SHT4X_MEASURE_MEDIUM_PRECISION_TICKS_CMD_ID;
uint8_t res[6];
if (!i2c_write(nullptr, 0, cmd, 1)) return;
chThdSleepMilliseconds(5); // wait for measurement, 10 for high precision, 5 for medium, 2 for low
if (!i2c_read(nullptr, 0, res, 6)) return;
uint16_t temptick = (uint16_t)res[0] << 8 | (uint16_t)res[1];
uint16_t humtick = (uint16_t)res[3] << 8 | (uint16_t)res[4];
temp = -45 + (((float)temptick * 175.0) / 65535.0);
hum = -6 + 125.0 * (float)humtick / 65535.0;
if (hum < 0) hum = 0;
if (hum > 100) hum = 100;
EnvironmentDataMessage msg{temp, hum}; // create the system message
EventDispatcher::send_message(msg); // and send it
}
} // namespace i2cdev
+53
View File
@@ -0,0 +1,53 @@
/*
* Copyright (C) 2025 HTotoo.
*
* 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 __I2CDEV_SHT4X_H__
#define __I2CDEV_SHT4X_H__
#include "i2cdevmanager.hpp"
namespace i2cdev {
class I2cDev_SHT4x : public I2cDev {
public:
typedef enum {
SHT4X_MEASURE_HIGH_PRECISION_TICKS_CMD_ID = 0xfd,
SHT4X_MEASURE_MEDIUM_PRECISION_TICKS_CMD_ID = 0xf6,
SHT4X_MEASURE_LOWEST_PRECISION_TICKS_CMD_ID = 0xe0,
SHT4X_ACTIVATE_HIGHEST_HEATER_POWER_LONG_TICKS_CMD_ID = 0x39,
SHT4X_ACTIVATE_HIGHEST_HEATER_POWER_SHORT_TICKS_CMD_ID = 0x32,
SHT4X_ACTIVATE_MEDIUM_HEATER_POWER_LONG_TICKS_CMD_ID = 0x2f,
SHT4X_ACTIVATE_MEDIUM_HEATER_POWER_SHORT_TICKS_CMD_ID = 0x24,
SHT4X_ACTIVATE_LOWEST_HEATER_POWER_LONG_TICKS_CMD_ID = 0x1e,
SHT4X_ACTIVATE_LOWEST_HEATER_POWER_SHORT_TICKS_CMD_ID = 0x15,
SHT4X_SERIAL_NUMBER_CMD_ID = 0x89,
SHT4X_SOFT_RESET_CMD_ID = 0x94,
} SHT4xCmdId;
bool init(uint8_t addr_) override; // sets the addr to our local variable, set the model, try to init the module, and only return true if it is really that module, and inited ok
void update() override; // query the module for recent data, and send it to the system via the corresponding Message
private:
float read_temperature();
float read_humidity();
};
} // namespace i2cdev
#endif
+5 -1
View File
@@ -34,14 +34,18 @@ enum I2C_DEVMDL {
I2CDEVMDL_SHT3X,
I2CDEVMDL_BMP280,
I2CDEVMDL_BME280,
I2CDECMDL_BH1750,
I2CDEVMDL_BH1750,
I2CDECMDL_PPMOD,
I2CDEVMDL_SHT4X,
};
#define I2CDEV_BMX280_ADDR_1 0x76
#define I2CDEV_BMX280_ADDR_2 0x77
#define I2CDEV_SHT3X_ADDR_1 0x44
#define I2CDEV_SHT3X_ADDR_2 0x45
// sadly sht4x uses the same addr as sht3x, but the init script can decide which is which
#define I2CDEV_SHT4X_ADDR_1 0x44
#define I2CDEV_SHT4X_ADDR_2 0x45
#define I2CDEV_MAX17055_ADDR_1 0x36
#define I2CDEV_ADS1110_ADDR_1 0x48
+6
View File
@@ -32,6 +32,7 @@
#include "i2cdev_ads1110.hpp"
#include "i2cdev_bh1750.hpp"
#include "i2cdev_ppmod.hpp"
#include "i2cdev_sht4x.hpp"
namespace i2cdev {
@@ -73,6 +74,11 @@ bool I2CDevManager::found(uint8_t addr) {
if (!item.dev->init(addr)) item.dev = nullptr;
}
if (!item.dev && (addr == I2CDEV_SHT4X_ADDR_1 || addr == I2CDEV_SHT4X_ADDR_2)) {
item.dev = std::make_unique<I2cDev_SHT4x>();
if (!item.dev->init(addr)) item.dev = nullptr;
}
if (!item.dev && (addr == I2CDEV_MAX17055_ADDR_1)) {
item.dev = std::make_unique<I2cDev_MAX17055>();
if (!item.dev->init(addr)) item.dev = nullptr;
+1 -1
View File
@@ -148,7 +148,7 @@ struct standalone_application_information_t {
void (*shutdown)();
void (*PaintViewMirror)();
void (*OnTouchEvent)(int x, int y, uint32_t type);
bool (*OnTouchEvent)(int x, int y, uint32_t type);
void (*OnFocus)();
bool (*OnKeyEvent)(uint8_t key);
bool (*OnEncoder)(int32_t delta);
@@ -77,7 +77,7 @@ ui::Widget* touch_widget(ui::Widget* const w, ui::TouchEvent event) {
ui::Widget* captured_widget{nullptr};
void OnTouchEvent(int, int, uint32_t) {
bool OnTouchEvent(int, int, uint32_t) {
if (standaloneViewMirror) {
_api->exit_app();
/* //left here for example, but not used in digital rain
@@ -96,6 +96,7 @@ void OnTouchEvent(int, int, uint32_t) {
captured_widget->on_touch(event);
*/
}
return false;
}
void OnFocus() {
@@ -40,7 +40,7 @@ void shutdown();
void OnFocus();
bool OnKeyEvent(uint8_t);
bool OnEncoder(int32_t);
void OnTouchEvent(int, int, uint32_t);
bool OnTouchEvent(int, int, uint32_t);
bool OnKeyboad(uint8_t);
void PaintViewMirror();
+1 -1
View File
@@ -23,7 +23,7 @@
#include "pacman.hpp"
#include <memory>
void notouch(int, int, uint32_t) {
bool notouch(int, int, uint32_t) {
// do nothing
}
void nothing() {