Skip to content

Machine autonomy: clock, wake schedule, sleep timeout, cup warmer - #4

Open
ChampionDesigns wants to merge 1 commit into
ben/detect-protocolfrom
ben/machine-autonomy
Open

ChampionDesigns wants to merge 1 commit into
ben/detect-protocolfrom
ben/machine-autonomy

Conversation

@ChampionDesigns

Copy link
Copy Markdown
Owner

Filed inside the fork so the diff shows only this PR's own changes.
It will be re-filed against decentespresso/de1app once its base has merged there.

merges. 400 insertions, 5 files.

Summary

The machine only wakes, sleeps and pre-warms while the tablet app is running and connected.
A Bengle can do all of it itself. This gives the firmware what it needs, and adds the cup
warmer page.

register address encoding
CupWarmerMode 0x008038AC 0/1, RAM only on the firmware side
MatHeaterDrivePct 0x008038B4 0–100, read-only
MatTempFault 0x008038B8 0 ok, 1 open/short, 2 runaway, read-only
InactivitySleepTimeout 0x008038BC minutes, 0–240
SetLocalTimeOfWeek 0x008038C0 seconds since Sunday, 0–604800
ScheduleEntry 0x008038C4 (dow<<22)|(start<<11)|end, 32 max
ScheduleControl 0x008038C8 0 clear+disable, 1 enable
MatPreheatEnable 0x008038D0 0/1, persisted
MatPreheatLeadMin 0x008038D4 minutes, 0–120, persisted

Every address, clamp and the schedule packing match decentespresso/decaid.

The clock

There is no battery-backed RTC. The firmware keeps a software wall clock, seeded on connect
and re-sent every 30 minutes. A power cut loses it and the next connection re-seeds it;
until then only the inactivity timer runs, so the machine can still sleep itself but cannot
wake on schedule.

Where the schedule comes from

The D_Scheduler plugin's per-weekday wake times become one-minute windows, and the
built-in scheduler's keep-warm window is sent for all seven days when scheduler_enable is
set. They cannot double up: the plugin clears that flag. The sleep timeout reuses the
existing screen_saver_delay rather than adding a setting.

Pre-warm is the firmware's job

With MatPreheatEnable set, the firmware runs the mat from MatPreheatLeadMin minutes
before a scheduled wake, with no tablet connected. Both registers are flash-persisted,
so the app sends them on connect and when the user changes the setting.

Write order matters and follows decaid: enabling sends the lead first so the firmware never
acts on a stale one; disabling clears the enable first.

An earlier draft did pre-warm with a Tcl after alarm, which only fired while the app was
running — defeating the point of the PR. That alarm is gone.

Cup warmer mode

CupWarmerMode is not persisted by the firmware, so it is re-sent on every connect. The
app deliberately sends 0: the warmer turns on only when the user asks or the pre-warm
fires. A machine does not start heating by itself after a blackout. utils.tcl resets the
flag at app start for the same reason.

Changes

de1_comms.tclset_cupwarmer_mode, set_cupwarmer_preheat,
set_sleep_timeout_minutes, set_machine_clock, machine_clock_resync,
set_wake_schedule, get_cupwarmer_status.

bluetooth.tcl — the connect-time pushes, and the decode branches for
CupWarmerMode, MatHeaterDrivePct and MatTempFault. Those decodes must be here:
de1_event_handler in de1_comms.tcl begins with an unconditional error and is dead
code, so a decode placed only there never runs.

machine.tcl, utils.tcl — three settings and the app-start reset.

skins/default/de1_skin_settings.tcl — the cupwarmer page as page 4 of the
calibration flow: target-temperature slider, on/off toggle, live status from
MatHeaterDrivePct and MatTempFault, pre-warm toggle, 0–120 minute lead slider, and a
preview of when the heater will come on. Both pre-warm controls commit through one
debounced path.

Also corrects four addresses in that page's header comment, each of which named the
register one slot below the real one.

Known issues, not fixed here

Raised by a review of the series, recorded rather than fixed. Not reproduced on hardware.

  • The connect-time writes are gated on is_bengle_model, which depends on an MMR read
    that may not have returned yet.
    later_new_de1_connection_setup fires on the Version
    reply. If the model read is still outstanding, the sleep timeout, clock, schedule and
    pre-warm writes silently no-op with no retry. This is the most likely reason a first-ever
    connect would not take the settings.
  • is_bengle_model is also evaluated at skin-load time, so the cupwarmer page may not
    be registered on a first connect, while show_page_calibrate_3_next still navigates to
    it. Same root cause; one fix probably covers both, and it affects the LED and calibration
    PRs too.

Naming

decaid calls this hardware the "mat" — matSetPoint, matPreheat*. This repo already
calls the same register at 0x00803874 set_cupwarmer_temperature. The register names
here follow the firmware's MMR.def; the app-side procs keep this repo's wording. Happy to
align either way.

Impact on a DE1

Every write proc tests is_bengle_model and returns early. The cupwarmer page is
reachable only from the Bengle flow. The new settings are inert.

Test plan

  • Connect a DE1. Confirm no schedule, clock or cup-warmer MMR writes in the log.
  • TODO (Ben): set a wake time on a Bengle, close the app, confirm it wakes on schedule
    with no tablet connected.
  • TODO (Ben): enable pre-warm with a lead, close the app, confirm the mat starts early.
  • TODO (Ben): confirm the settings take on a first-ever connect — this is the known
    issue above.
  • TODO (Ben): pull mains power, restore, reconnect; confirm the clock re-seeds.
  • TODO (Ben): disconnect the mat NTC; confirm the page shows the fault warning.

Testing

Manual verification only. There is no automated test coverage for these Tcl paths in the
repo.

The machine only wakes, sleeps and pre-warms while the tablet app is
running and connected. A Bengle can do all of it itself. This gives the
firmware what it needs.

  CupWarmerMode          0x008038AC  RAM only, re-sent every connect
  MatHeaterDrivePct      0x008038B4  read-only
  MatTempFault           0x008038B8  read-only
  InactivitySleepTimeout 0x008038BC  minutes, 0-240
  SetLocalTimeOfWeek     0x008038C0  seconds since Sunday, 0-604800
  ScheduleEntry          0x008038C4  packed (dow<<22)|(start<<11)|end
  ScheduleControl        0x008038C8  0 clear+disable, 1 enable
  MatPreheatEnable       0x008038D0  persisted
  MatPreheatLeadMin      0x008038D4  persisted, 0-120

Every address, clamp and the schedule packing match decentespresso/decaid.

There is no battery-backed RTC. The firmware keeps a software wall clock,
seeded on connect and re-sent every 30 minutes. A power cut loses it and
the next connection re-seeds it; until then only the inactivity timer
runs, so the machine can still sleep itself but cannot wake on schedule.

Schedule sources are the D_Scheduler plugin's per-weekday wake times and
the built-in scheduler's keep-warm window. They cannot double up: the
plugin clears scheduler_enable.

Pre-warm is the firmware's job. With MatPreheatEnable set it runs the mat
from MatPreheatLeadMin minutes before a scheduled wake with no tablet
connected. Write order follows decaid: enabling sends the lead first so
the firmware never acts on a stale one; disabling clears the enable first.

CupWarmerMode is deliberately sent as 0 on every connect. The warmer turns
on only when the user asks or the pre-warm fires -- a machine does not
start heating by itself after a blackout. utils.tcl resets the flag at app
start for the same reason.

Adds the cup warmer page as page 4 of the calibration flow, with live
status from MatHeaterDrivePct and MatTempFault. Nothing requested those
two reads before, so that status could never update; get_cupwarmer_status
now asks for them on connect.

Corrects four addresses in the page's header comment, each of which named
the register one slot below the real one.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants