mirror of
https://github.com/liquidraver/ZephCore.git
synced 2026-09-01 21:08:19 +00:00
gps fixes
This commit is contained in:
@@ -1491,6 +1491,16 @@ void gps_enable(bool enable)
|
||||
gps_current_state = GPS_STATE_OFF;
|
||||
consecutive_good_fixes = 0;
|
||||
|
||||
/* Zero the stale satellite count so a re-enable doesn't briefly
|
||||
* report a live fix (e.g. joystick UI showing "3D FIX") off old
|
||||
* data before any new NMEA sentence arrives. lat/lon/valid are
|
||||
* deliberately left alone — telemetry/UI "last known position"
|
||||
* reads (gps_get_position/gps_load_position) intentionally survive
|
||||
* an on/off toggle; only the live fix-quality indicator resets. */
|
||||
k_mutex_lock(&gps_mutex, K_FOREVER);
|
||||
current_pos.satellites = 0;
|
||||
k_mutex_unlock(&gps_mutex);
|
||||
|
||||
/* Clear first-fix flags so the next enable gets a fresh long
|
||||
* first-acquisition window again — the user explicitly toggled GPS
|
||||
* expecting it to try hard for a fix. */
|
||||
|
||||
@@ -916,6 +916,30 @@ void JoystickUITask::toggleGPS()
|
||||
mesh_gps_set_enabled(!gps_is_enabled());
|
||||
}
|
||||
|
||||
uint32_t JoystickUITask::getGpsDutySec() const
|
||||
{
|
||||
return gps_get_poll_interval_sec();
|
||||
}
|
||||
|
||||
void JoystickUITask::adjustGpsDuty(int step)
|
||||
{
|
||||
static const uint32_t kPresets[] = {
|
||||
0, 10, 30, 60, 120, 300, 600, 900, 1800, 3600,
|
||||
7200, 21600, 43200, 86400, 172800, 604800
|
||||
};
|
||||
const int kCount = (int)(sizeof(kPresets) / sizeof(kPresets[0]));
|
||||
|
||||
uint32_t cur = gps_get_poll_interval_sec();
|
||||
int idx = kCount - 1;
|
||||
for (int i = 0; i < kCount; i++) {
|
||||
if (kPresets[i] >= cur) { idx = i; break; }
|
||||
}
|
||||
idx += step;
|
||||
if (idx < 0) idx = 0;
|
||||
if (idx >= kCount) idx = kCount - 1;
|
||||
mesh_save_gps_duty_sec(kPresets[idx]);
|
||||
}
|
||||
|
||||
void JoystickUITask::playCountdownAlarm()
|
||||
{
|
||||
#ifdef CONFIG_ZEPHCORE_UI_BUZZER
|
||||
|
||||
@@ -104,6 +104,12 @@ public:
|
||||
bool isGPSAvailable() const;
|
||||
bool getGPSState() const;
|
||||
void toggleGPS();
|
||||
/* GPS duty-cycle interval, seconds (0 = always on). Steps through a fixed
|
||||
* preset ladder (step = +1/-1) rather than raw seconds, since the valid
|
||||
* range spans 0..604800 — a linear per-press delta would be unusable at
|
||||
* either end. Applied live + persists to prefs. */
|
||||
uint32_t getGpsDutySec() const;
|
||||
void adjustGpsDuty(int step);
|
||||
bool isSerialEnabled() const { return _ble_enabled; }
|
||||
void disableSerial();
|
||||
void enableSerial();
|
||||
|
||||
@@ -722,13 +722,24 @@ int GPSSettingsScreen::render(JoystickDisplay &display)
|
||||
|
||||
bool gps_enabled = _task->getGPSState();
|
||||
|
||||
char gps_state_line[24];
|
||||
char top_line[24];
|
||||
char satellites_line[32];
|
||||
char lat_lon_line[40];
|
||||
char speed_line[32];
|
||||
|
||||
snprintf(gps_state_line, sizeof(gps_state_line), "GPS: %s",
|
||||
gps_enabled ? "ON" : "OFF");
|
||||
/* Line 0 doubles as the GPS on/off toggle and the duty-cycle setting —
|
||||
* the display only has room for 4 lines total (64px OLED), so rather
|
||||
* than add a 5th line, _selected swaps what line 0 shows/does. */
|
||||
if (_selected == 0) {
|
||||
snprintf(top_line, sizeof(top_line), "GPS: %s", gps_enabled ? "ON" : "OFF");
|
||||
} else {
|
||||
uint32_t duty = _task->getGpsDutySec();
|
||||
if (duty == 0) {
|
||||
snprintf(top_line, sizeof(top_line), "Duty: Always on");
|
||||
} else {
|
||||
snprintf(top_line, sizeof(top_line), "Duty: %us", (unsigned)duty);
|
||||
}
|
||||
}
|
||||
|
||||
bool has_fix = false;
|
||||
|
||||
@@ -787,9 +798,9 @@ int GPSSettingsScreen::render(JoystickDisplay &display)
|
||||
}
|
||||
}
|
||||
|
||||
const char *lines[4] = { gps_state_line, satellites_line, lat_lon_line, speed_line };
|
||||
const char *lines[4] = { top_line, satellites_line, lat_lon_line, speed_line };
|
||||
|
||||
renderScreenHeader(display, "GPS", 0, 1);
|
||||
renderScreenHeader(display, "GPS", _selected, 2);
|
||||
display.setTextSize(1);
|
||||
|
||||
int y = kContentY + 2;
|
||||
@@ -803,9 +814,21 @@ int GPSSettingsScreen::render(JoystickDisplay &display)
|
||||
|
||||
bool GPSSettingsScreen::handleInput(char key)
|
||||
{
|
||||
if (handleCommonListNavigation(key, _selected, 2)) return true;
|
||||
if (key == KEY_LEFT || key == KEY_RIGHT) {
|
||||
if (_selected == 1) {
|
||||
_task->adjustGpsDuty(key == KEY_RIGHT ? 1 : -1);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
if (key == KEY_ENTER) {
|
||||
_task->toggleGPS();
|
||||
_task->showAlert(_task->getGPSState() ? "GPS enabled" : "GPS disabled", 1000);
|
||||
if (_selected == 0) {
|
||||
_task->toggleGPS();
|
||||
_task->showAlert(_task->getGPSState() ? "GPS enabled" : "GPS disabled", 1000);
|
||||
} else {
|
||||
_task->adjustGpsDuty(1);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
if (key == KEY_CANCEL || key == KEY_HOME) { _task->gotoHomeScreen(); return true; }
|
||||
|
||||
@@ -43,6 +43,7 @@ LOG_MODULE_REGISTER(zephcore_ui_actions, CONFIG_ZEPHCORE_UI_ACTIONS_LOG_LEVEL);
|
||||
#define UI_ACTION_WAKE_ON_MSG_SAVE BIT(9)
|
||||
#define UI_ACTION_SCREEN_OFF_SAVE BIT(10)
|
||||
#define UI_ACTION_PATH_HASH_MODE_SAVE BIT(11)
|
||||
#define UI_ACTION_GPS_DUTY_SAVE BIT(12)
|
||||
|
||||
/* Module-local pointers, set by init */
|
||||
static CompanionMesh *s_mesh;
|
||||
@@ -68,6 +69,7 @@ static atomic_t pending_brightness;
|
||||
static atomic_t pending_wake_on_msg;
|
||||
static atomic_t pending_screen_off_secs;
|
||||
static atomic_t pending_path_hash_mode;
|
||||
static atomic_t pending_gps_duty_sec;
|
||||
|
||||
extern "C" void ui_mesh_actions_init(struct k_event *mesh_events,
|
||||
uint32_t mesh_event_ui_action,
|
||||
@@ -151,6 +153,17 @@ extern "C" void mesh_save_path_hash_mode(uint8_t mode)
|
||||
k_event_post(s_mesh_events, s_mesh_event_ui_action);
|
||||
}
|
||||
|
||||
extern "C" void mesh_save_gps_duty_sec(uint32_t sec)
|
||||
{
|
||||
/* Apply immediately (lightweight, no flash) — same split as mesh_gps_set_enabled. */
|
||||
gps_set_poll_interval_sec(sec);
|
||||
|
||||
/* Defer the flash write (savePrefs) to mesh thread */
|
||||
atomic_set(&pending_gps_duty_sec, (atomic_val_t)sec);
|
||||
atomic_or(&pending_ui_actions, UI_ACTION_GPS_DUTY_SAVE);
|
||||
k_event_post(s_mesh_events, s_mesh_event_ui_action);
|
||||
}
|
||||
|
||||
extern "C" void mesh_set_buzzer_quiet(bool quiet)
|
||||
{
|
||||
/* Defer the flash write (savePrefs) to mesh thread */
|
||||
@@ -289,6 +302,12 @@ extern "C" void mesh_handle_ui_actions(void)
|
||||
need_save = true;
|
||||
}
|
||||
|
||||
if (actions & UI_ACTION_GPS_DUTY_SAVE) {
|
||||
s_mesh->prefs.gps_interval = (uint32_t)atomic_get(&pending_gps_duty_sec);
|
||||
LOG_INF("gps_interval=%u (button)", s_mesh->prefs.gps_interval);
|
||||
need_save = true;
|
||||
}
|
||||
|
||||
if (need_save || (actions & UI_ACTION_SAVE_RESTART)) {
|
||||
s_data_store->savePrefs(s_mesh->prefs);
|
||||
LOG_INF("prefs saved (button action)");
|
||||
|
||||
@@ -66,6 +66,9 @@ void mesh_set_wake_on_msg(bool enabled);
|
||||
void mesh_save_screen_off_secs(uint16_t secs);
|
||||
/* path_hash_mode: 0/1/2 → 1/2/3 bytes per hop appended to outbound flood path */
|
||||
void mesh_save_path_hash_mode(uint8_t mode);
|
||||
/* GPS duty-cycle interval in seconds (0 = always on). Applied live immediately
|
||||
* (lightweight); the flash write is deferred to the mesh thread. */
|
||||
void mesh_save_gps_duty_sec(uint32_t sec);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user