Files
desklock/firmware/main/desklock.h
T
jpmschweitzerandClaude Fable 5 5c6a6eba36
Test, Build and Push / test-gateway (push) Successful in 10s
Test, Build and Push / release (push) Skipped
Test, Build and Push / build-gateway (push) Skipped
Fix touch crash + make rain a reachability signal + calm the alarm churn
TOUCH CRASH (the blue screen): app_on_touch ran a blocking WebSocket
send (up to 5s) directly in the LVGL touch callback, stalling the
MIPI-DSI flush into a garbage/blue frame + task-watchdog reboot on
every tap. Now touch_cb only gives a semaphore; a dedicated app_task
does the blocking sends, audio, and face changes off the render
thread. WS send timeout cut 5s to 1.5s as belt-and-braces.

RAIN = REACHABILITY (user request): rain now falls only while the
gateway WebSocket is live (gated on gw_connected in rain_tick). It
drains gracefully on disconnect, resumes on reconnect, a genuine
glanceable reachable signal. Idle density bumped 2 to 4 so
connected-idle reads distinctly from disconnected-black.

CALM THE WEDGE CHURN (user request): transient wifi/WS drops no longer
slam to the x_x error face or a CONNECTING banner. Boot goes straight
to the calm idle face (dry until connected). Only a sustained 30s+
outage escalates to x_x (clock_cb); the ~15s wedge-recovery just shows
a brief rain pause.

Two fixes from adversarial concurrency review before flashing:
- persistent single capture task (was xTaskCreate per utterance; a
  rapid re-tap or WS-stop-vs-app-start race could put two readers on
  one mic/I2S handle and corrupt the codec)
- reset s_talking on disconnect (app_on_disconnect) so the first tap
  after a mid-utterance drop starts fresh, not the stop branch

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-15 09:04:57 +02:00

55 lines
1.5 KiB
C

/* Shared app types and cross-module hooks. */
#pragma once
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
typedef enum {
FACE_BOOT, /* connecting — idle glyphs + status tag */
FACE_IDLE, /* clock, rare drips */
FACE_LISTENING, /* mic hot */
FACE_PENSIVE, /* transcribing / short waits */
FACE_EFFORT, /* Tatlock working: max rain + orbit + elapsed */
FACE_SPEAKING, /* mouth sync */
FACE_RAGE, /* request failed: table flip, auto-returns to idle */
FACE_ERROR, /* gateway unreachable */
} face_state_t;
/* face.c */
void face_init(void);
void face_set(face_state_t state); /* safe from any task */
face_state_t face_get(void);
void face_activity(void);
void face_status(const char *text); /* bottom status line (diag/boot) */ /* reset the power ladder to active */
/* audio.c */
void audio_init(void);
void audio_play_gong(void);
void audio_capture_start(void);
void audio_capture_stop(void);
void audio_playback_begin(void);
void audio_playback_feed(const uint8_t *data, size_t len);
void audio_playback_end(void);
bool audio_is_playing(void);
/* net.c */
void net_start(void);
/* gw_client.c */
void gw_start(void);
bool gw_connected(void);
void gw_send_text(const char *json);
void gw_send_bin(const uint8_t *data, size_t len);
/* wifi_diag.c */
void wifi_diag_start(void);
/* c6_ota.c */
void c6_ota_start(void);
/* desklock_main.c */
void app_on_touch(void);
void app_on_disconnect(void);
void app_on_playback_done(void);