Changelog
v3.4.6
Changes
- Devices now sleep and wake with the PC correctly
- Device STALLs now pass through to the PC correctly
- Devices with lots of interfaces, endpoints or alternate settings no longer require IMPERFECT
- Devices now connect ~200ms faster
- Improvements to query latency (status queries are now on-par with stock firmware)
- Improvements to native report latency (~0.05ms)
- More memory headroom on models without PSRAM
- Added a full comparison against the MAKCU stock firmware to the website
- Overhauled the website, with a new landing page, guide and help section
- Added search across the whole website
- Added link previews for pages, help answers, releases and devices
- Added copy-link buttons across the website and dashboard
- Added an Options guide explaining what every option does
- Added a Flash page to the dashboard (releases, files and MAKCU stock firmware, over USB2 or ROM download)
- The dashboard now offers the fix a connected device needs (ie, IMPERFECT, the Logitech fix)
- Boxes on older firmware (v3.2.0 to v3.4.1) can now use the Options tab in the dashboard
- Connection errors in the dashboard now say why, and Retry no longer needs the port picked again
- Added firmware updates to the C/C++ and Python bindings
- Streams can now be closed from another thread in the library and bindings (ie, to stop a thread waiting on input)
- The C ABI (medius-capi) is now published on crates.io, for Rust projects that offer a C API built on Medius
- Fixed an issue where typing a long string could drop characters
- Fixed an issue where a fast burst of commands could be lost (and leave a key held down)
- Fixed an issue where commands could be lost while a device was being plugged in or unplugged
- Fixed an issue where rendered movement may not add up to what was sent while the mouse was moving
- Fixed an issue where quick back-and-forth rendered movement could lose a few counts
- Fixed an issue where a CLIP's first click after a pause could land a frame late
- Fixed an issue where a 1khz keyboard could run at half rate beside slower endpoints (ie, Wooting keyboards)
- Fixed an issue where movement could arrive 1ms late under heavy load
- Fixed an issue where a single late report could leave a device a poll behind for up to 3 seconds
- Fixed an issue where IMPERFECT devices could lose bulk packets
- Fixed an issue where HEALTH could report the rate as confident with no mouse bound
- Fixed an issue where closing a device or stream in Python while another thread was using it could crash
- Several other smaller improvements to stability and performance
Notes
Devices now go to sleep with the PC like they would plugged in directly, and only wake the PC the way they normally would (ie, a mouse that only wakes on click won't wake it on movement anymore)
The website also got a massive overhaul this update, including a full side-by-side comparison against the stock firmware: https://medius.k4tech.net/comparison
The C/C++ bindings have a new ABI version (10), so rebuild against the new header if you use them
Show commits
Firmware
- docs: a stock defect worded so site search still puts Help's answer first for a mouse that won't move
07d5c95 - ci: the firmware zip goes on the GitHub release as well as the Discord post
87db760 - docs: release notes for 3.4.6
d6171e2 - tools: gate docs, rig notes and test comments read on first pass
24db7a5 - firmware: comments read on first pass
c349253 - docs: the spec, write-ups and comparison read on first pass, with symbols for counts and limits
d89e5ac - tools: gate docstrings, rig notes and test comments in the project's words
77de5dd - firmware: comments in the project's words, and the ones that had the code wrong
86e8c59 - docs: the protocol spec, architecture and comparison write-ups in the project's words, and the facts they had wrong
3ada641 - docs: the suppression gate needs a device that sends nothing unprompted
ed20cb8 - docs: the protocol doc, README, PSRAM page and detection notes follow 3.4.6
cdfd496 - docs: comparison rerun on the final build, with report latency, the lead and bulk data on Medius brought up to date
b6695e9 - docs: the design record, release notes and gate list follow the bulk data fix
9daf47e - firmware: a device's bulk data reaches the PC whole, however late or slowly the PC reads it
7457c41 - docs: the Discord foundation's rules post ends on rule 5
3b5f48e - docs: the Discord rework's embeds and panels in the site's blue, and the comparison's benchmarks
9193c6d - tools: the release post's embed is in the site's blue, its title linking the release
97475a5 - docs: the Discord rework's embeds follow the bot's look
bc4e32a - tools: the release post's text is its pings, the notes an embed titled with the release
967f32b - docs: the Discord rework's bot posts are embeds
503f9f0 - tools: the release's Discord post is an embed, with the ping and the credits' thanks in its text
2b78491 - docs: the design record, release notes and bench notes follow the 400 ยตs lead and the shorter wait after a late report
a302c08 - firmware: every report the box relays is readied ahead of its other work, not only the mouse's
173dc14 - docs: the Discord rework adds a comparison channel holding the site's summary
3bde844 - firmware: one late report no longer leaves the reports after it a poll late for seconds
fdcab3f - firmware: the mouse's reports keep their poll under heavy load, and reach the PC 50 ยตs sooner
5044c5d - docs: comparison has no pending tests left; the three that need Windows are listed as not covered
47ca3c9 - docs: comparison counts reports carrying only injected motion beside a varying mouse, and shows each clone's endpoint 0 reply time
df7ed4e - docs: comparison lists stock's 1 ms mouse interval as a defect on every row it wins
02a91e7 - tools: comparison checks take a defect on every row it decides, and the device matrix has 2 ms and 4 ms mice
263e809 - docs: comparison report latency rerun, p99 in place of the slowest report
f3746bc - tools: report latency script places the emulator's clock per window and follows its held-back intervals
5953efb - docs: comparison report latency on both boxes at 125 Hz to 1 kHz
4163514 - tools: comparison script timing every native report from the emulator to the PC, on both boxes
401aab8 - docs: comparison click timing rerun on the clip fix
0b2d552 - firmware: a clip's clicks and keys reach the PC as far apart as they were played, the first after a pause included
328db02 - docs: comparison rebuilt on one hub with Medius 3.4.6 final, the pending tests measured on both boxes
7751eb7 - tools: comparison scripts give Medius the same fast and back-to-back legs as stock, and keep a clone that reconnects
eb32686 - firmware: every interface number, setting and endpoint a device has is driven, and a stream polled every frame keeps its rate beside a slower one
43f9538 - tools: comparison scripts for interface data, intake limits, typing, sleep and timing legs; same-hub evidence and its manifest
8ddbc03 - docs: v3.4.6 sleep, halt, render debt and link fixes in the design record, protocol and release notes
2f353a4 - tools: gates find this box's clone by its USB port as well as its ID, and the suspend and halt gates check more
1c7907a - firmware: the PC's sleep and a device's halts pass through, rendered debts are delivered, and a device change loses no link frame
aa833ee - docs: v3.4.6 faithfulness fixes design record and release notes
0d37dfd - tools: a clone lookup never takes another box's clone
25c7c2b - firmware: an endpoint the mouse stops reaches the PC, and the device chip keeps one snapshot
825a402 - firmware: rendered moves deliver exactly what was sent, with no count against them
49edc1d - docs: comparison results rebuilt as direct like-for-like rows, with defects and pending tests
d03373e - docs: comparison results: relay reruns, Equal by overlapping ranges, defects that reproduce, pending tests for readers
8b70cef - docs: comparison smoothing group described in fewer words
b288474 - docs: comparison results format: unmeasured chart points, defects on rows of results, stricter checks; seed refreshed
da7b336 - docs: comparison results in one checked file, for the site
1b87cad - docs: comparison section design
dbdc893 - docs: dashboard controls design record
f7f2945 - docs: v3.4.6 render totals and query replies
36d86fc - tools: wire-level timing for the comparison, and the transform gate reads a reader overflow as blocked
8cb9f99 - firmware: the control port answers queries sooner
a381d09 - firmware: rendered motion keeps its totals with every report the model's
375710d - release v3.4.6
0e0175b - docs: v3.4.6 design record, release tables and protocol change log
8ac0726 - tools: the transform gate reads its own box's clone
ed59ffc - firmware: devices enumerate on the USB specification's reset timings
b93a834 - firmware: typed strings arrive whole, and bursts of commands are kept
de854a4 - firmware: rendered moves add up while the mouse moves
2cd6524 - docs: comparison wording
4229ddc - docs: comparison refusals with the mouse moving, readers in their own processes, hub timing
c65622c - docs: comparison move sizes, text clumps and the reworked lock check on stock
b728b24 - docs: comparison move acceptance by form and pacing, lock checks, native rate triggers
c055649 - docs: comparison stock re-runs after power cycles, native rate while injecting, parser trigger
6875489 - docs: comparison second review: trigger order, interval rule, render evidence, imperfect coverage
f0f1ff8 - docs: comparison data path checks
fad19f0 - docs: comparison report descriptor limits and endpoint 0 shapes
4a6c80c - docs: comparison corrections, Medius fastest-settings and cold-start runs, stock re-run script
ea6672b - docs: the stock firmware comparison: rig, measurements and research
bff4704 - tools: quiet_clone and clone_guard cover two clones on one PC
9ee97ab - docs: the dashboard's Flash page and one-count flash meter
b6d4856 - docs: the ROM client spec's erase before the write and its smaller blocks
970fa9c - docs: the device feed's first post and the changelog's history in the Discord design
e2c8c4e - docs: the ROM client spec's stock done screen, one line
ba5c3ae - release notes: a refused Discord post prints Discord's answer
0c4a7a2 - docs: the dashboard's boot ROM client, spec and plan
b4a289d - docs: release posts by Clanker and the device feed in the Discord design
79bd102 - release notes: the Discord post comes from the server's bot, not a webhook
60fb701 - docs: the honeypot and bot settings in the Discord spec
8562eb9 - docs: Home under Support in the Discord layout
e87073b - docs: the Server Tag in the Discord checklist
36866d9 - docs: what the Discord spec holds now
08f9cad - docs: the Discord Apply checklist
3507bba - docs: options spec, the stock erase in regions
ffb0cfd - release notes: ping a release role in place of @everyone when one is set
414f00b - docs: Discord onboarding beside the captcha
d29730d - docs: place addresses spec and plan, as built
91c0a9c - docs: Discord layout after the second review
ddca522 - docs: Discord rework after review
5a7d5c7 - docs: options spec, project terms
fc385e5 - docs: Discord rework design
0623ddf - docs: options spec, details as tables
31b5023 - docs: rule 2 is the rule as written
2299430 - docs: options spec, every option a section
6a04047 - docs: options spec, links both ways and plain sections
ec9691d - docs: Discord foundation spec as built
b1d3e86 - docs: options page and dashboard fixes spec and plan, as built
5b95e15 - docs: Discord foundation spec, build changes
075af56 - docs: Discord foundation plan; spec binds by name
1b9bfe9 - docs: Discord foundation spec
7296017 - docs: deferred minors spec and plan, as built
0de35d1 - docs: copy link spec as built
1ae6b55 - docs: copy link spec and plan
6431caa - release notes: no preview for any other link in the post
f2e8b1a - release notes: link the release's page, so its card shows
d349667 - docs: plan wording
ef24270 - docs: link preview plan; theme-color set before first paint
95bfe26 - docs: link preview spec and the approved cards
975886b - docs: site loading spec as built; search spec follows it
5127cd9 - docs: site search spec as built
049759f - docs: site search spec and plan
be54efa - docs: site surfaces implementation plan
ac49efd - docs: surfaces mockup, approved version
5a77bb8 - docs: surfaces mockup, eighth version
4f21c4e - docs: surfaces mockup, seventh version
da90739 - docs: surfaces mockup uses the full page width
0910fcc - docs: surfaces mockup, fifth version
cad1657 - docs: surfaces mockup, fourth version
7a3f54c - docs: surfaces mockup, third version
21fe54e - docs: design mockup for the site's remaining surfaces
9951773 - tools: closer injection bursts in the site feed capture, and no capture date
eb72838 - tools: site capture rigs read the run exactly and restore every option they change
fc314f6 - tools: descriptor and report capture for the docs site
d01f12c - docs: plan wording
0a95b59 - docs: site theme and user pages plan
8c13329 - docs: site theme and user pages spec
c4a6fe7 - docs: the approved site design mockup
c213605 - docs: every dashboard page is indexed
8edef13 - docs: the search foundation spec as built
35d4814 - tools: release notes refuse unknown sections and stray mentions; long posts split cleanly
42821b3 - docs: wording in the search foundation spec and plan
371a670 - docs: release notes for v2.2.1 to v3.4.5
d8ea65d - tools, ci: release notes written once, posted to GitHub and Discord
a572a8e - docs: plan for the docs site's search foundation
304274c - docs: design for the docs site's search foundation
6b7013f
Library
- docs: doc comments, the C header and Python docs read on first pass
c8dc355 - docs: doc comments, the C header and the Python docstrings in the project's words, and the facts they had wrong
88f2073 - library 3.4.6: close a stream from another thread, the C ABI on crates.io, and docs that match the code
5260727 - docs: the library follows firmware 3.4.6: what relay_drops counts, sleep, STALLs, typing capacity and the RAW IN queue
042a40c - library: mock refuses an activate or reboots after one, tests for the abort and the confirm retry
390deeb - python: Device and ClipHandle close safe across threads
13e2dd3 - python, capi: closer to the crate, safe stream close across threads, firmware update and confirm through the crate
881a342 - capi: MediusDevice::into_raw, a handle over a Device that's already open
0d7e773
Docs
- comparison: data synced; search for a mouse that won't move finds Help's answer again
017498a - comparison: a count out of a total reads 6/10
a109fb7 - site: every page reads on first pass, with symbols for counts and limits
30cfe39 - docs: comparison wording synced from the firmware repo: native rate, emitted reports, relaying
6335da1 - docs: every page and the dashboard in the project's words, and the facts they had wrong
d72fe58 - docs: library 3.4.6: closing a stream from another thread, firmware update and confirm in every language, and the mock's update knobs
cf7e706 - docs: the site follows firmware 3.4.6: sleep, STALLs, typing capacity, what relay_drops counts and when a transfer gets no answer
ec1cbbc - test: the stats page's dates are checked in the locale the tests run under
2df307e - docs: the comparison follows the final firmware build, and the RAW page describes how bulk IN fills its queue
066ed8b - feat: the comparison JSON carries a few benchmarks with both boxes' values, and every area's page
f8a3694 - feat: the comparison JSON counts the results each box is ahead in, by area
487b38a - fix: the comparison JSON is built once per deploy
dba8df8 - feat: the comparison's Overview as JSON, for the Discord bot
ae4be1a - comparison: the Method page drops its pending tests section
e4f07d6 - comparison: injected-only reports beside a varying mouse, and endpoint 0 reply times
cdbcf84 - site: links land clear of the bar and light the place they go to, and the settings table's headers wrap over their columns
0c03139 - comparison: a defect marks every row it decides and links to its own place in the list
b521746 - comparison: report latency rerun
ac08092 - comparison: report latency section, led on the Overview
6c7aca3 - comparison: click timing on the clip fix
86c7316 - comparison: results from the one-hub final pass, the pending tests added, and the rig described as one hub
9fb2033 - docs: comparison pages rebuilt as direct like-for-like results; headings and in-page links fixed
682bbeb - docs: comparison results refreshed; Method states the Equal rule and what interval sd measures
4412cf5 - feat: a Comparison section: MAKCU's stock firmware against Medius, area by area
7c3acdc - docs: the privacy page carries what the law asks for, in the site's voice
5169636 - fix: rate limits drop an address when its window ends, and count each visitor rather than the proxy
fbba2e2 - feat: a Flash page that writes either chip through its ROM, older releases, and dashboard controls that match the site
d539a57 - docs: update firmware version strings to 3.4.6
5a216b0 - test: comment wording in the Devices JSON test
405f9d9 - test: each device's address in the Devices JSON is its own row's card
a0aabd5 - fix: the privacy page dates a scam signature from the last scam post that added it
30c425e - feat: each device in the Devices JSON carries its card's address
c1dca68 - feat: the Devices list as JSON, for the Discord bot
21eb8fa - fix: the privacy page keeps scam signatures for a year, as the bot does
161c3f2 - fix: the privacy page names scam signatures as the bot keeps them
50b709d - feat: a copy of a box's stats on request; the privacy page covers copies, verifications, signatures and DMed transcripts
875c68e - fix: the stock firmware relay follows MAKCU's toolkit 1.15.20
b9fe229 - fix: the stock source reads as the release does, plainer fix offers, a stock erase as MAKCU's toolkit does it, and a fuller privacy page
4fdc7ba - feat: privacy page, a footer link to it, and a stats delete command
ed419c8 - feat: an address and a link card for every section, tab and panel
c210347 - docs: emit, ride and relay in place of paraphrases across the site
e28100b - docs: option details as tables with measured delays, not prose
da96a00 - docs: Rendered motion and Wire rate as sections of the Options guide
2ebbb90 - docs: plain option explanations with links back to the dashboard, and noun headings across the reference
13ba603 - docs: plainer wording across the reference pages, comments and test names
24c9f54 - fix: review findings for the Options page, the fix offers and the stock firmware relay and flash
d65f947 - docs: Help sends owners to the dashboard for older boxes and MAKCU's stock firmware
63903b1 - feat: Update's Manual tab can put MAKCU's stock firmware back on either chip
a08c74d - feat: the server relays MAKCU's signed stock firmware, checked as MAKCU's toolkit checks it
d3287ee - feat: the dashboard offers the fix a connected device needs, in place
bef0948 - feat: boxes on firmware from v3.2.0 get the options their firmware has
b83f9fe - feat: an Options page in the Guide, linked from each option on the dashboard
864ed80 - fix: review findings: a poll that stalls after a flash, the Devices twin's links, tab spacing per strip, and the feed on browsers that round
97be654 - fix: no page scrolls sideways at 320 px, tab strips fit before they scroll, and Copied stays clear of tabs
8c92a13 - fix: the landing's feed and descriptor are right before the app runs, pause under the pointer, and take the keyboard
2aa8ac3 - fix: a link to an option says how to reach it before a box is connected
0de7f3c - test: crawlcheck fails a doubled or missing link-preview tag, and one naming another page
c7b11a7 - fix: link cards draw every Latin letter off the main thread, item pages carry their own data, and drafts stay off the changelog
33762e7 - fix: an unplugged box waits for its port without timers, and Reconnecting reads as a status
af7a5ea - fix: link icons take no room until shown, keep headings' names, and Copied never widens the page
b921cb9 - docs: the link icon and Anchor in CLAUDE.md
e068230 - fix: the open tab's Copied stays inside the tab bar
d50cf64 - test: the build fails on a place search can land on with no link icon
a2880ea - feat: copy the link to the open dashboard tab
fc844d6 - feat: copy the link to a Help answer, device or release
4d5c7ba - feat: a copy link icon on every section, panel and marked block
aa606cd - fix: one release date for every reader, page and card
d884d2a - docs: Pulsar ZywOo The Chosen Mouse reported working
675f071 - docs: six more devices reported working, four confirmed on v3.4.5
85a9319 - fix: link cards kept by what they show, unknown items stay a 404, release lookups answer within 5 s
513e5fb - test: crawl every link card and item address
0cfbc07 - fix: fill the changelog and stats blocks as the prerender now captures them
683aef8 - feat: serve link cards and item addresses
c596cf4 - feat: link card tags on every page, and addresses for one Help answer, release or device
6ab40f3 - feat: draw link cards as PNGs on the server
bc87a87 - feat: what each link card says, and addresses for single items
71ff1ec - feat: link card fonts and text layout
798032a - fix: one top bar and grid for the site, scroll kept per page, motion that never plays twice
da5197e - perf: split the site's code per page and fetch search on use
2653d39 - feat: site search built from the pages themselves
514fb1c - feat: rebuilt site search
1b90eb8 - fix: the box diagram matches the board
a298aa7 - fix: the safety clear's caption is one short line
1845204 - feat: one motion for every page
0fb5d52 - fix: the dashboard's rare states, each rendered and measured
07ef510 - fix: the 404's description names the links it carries
df1517d - fix: the 404 page prerenders again
237b076 - fix: dashboard controls as designed: sliders, steppers, buttons and links
aace53a - fix: review findings across the dashboard and the Guide
432b849 - docs: pages open on their title and first paragraph, with no subtitle
465420c - feat: the 404 names the address asked for and where to go instead
55e44e2 - feat: the Guide in three pages: Start here, Devices and Help
e2ceb4c - feat: Changelog with each version beside its notes, and commits grouped by repo
418a637 - feat: Stats on tabs, with charts that read out the column or row under the pointer
bade974 - feat: Control on tabs, Update with a manual flash tab, and Set up as one flow
c05ee44 - feat: the Device page on tabs: overview, options and a log to copy or save
8211222 - feat: the box drawn from its board, for wiring and install steps
07b0009 - feat: segmented choices, a filterable dropdown and a log for the dashboard
dd94a12 - feat: page tabs and panels for the dashboard, and pages that use the full width
f035a3b - chore: a box that answers without hardware on the dev server
25bcb11 - feat: the landing feed shows a burst of injected motion every few seconds, and no capture date
6a26bc8 - feat: the landing feed recaptured with exact injected-byte marks
9278d64 - fix: the landing intro carries on when the app takes over, and descriptor panel fixes
a6f6ce7 - fix: landing and changelog answer within seconds while GitHub or Discord hang
0130bec - fix: plainer Troubleshooting lead and search description
a3fe643 - fix: the custom scrollbar shows in Chrome, square and blue on hover
ba7b2c6 - fix: the landing feed keeps every byte of a long report on screen at any width
bfec47c - test: crawlcheck holds every page to one h1 and a footer, and no hidden reveals
1fa1d71 - feat: landing page
3967f7d - feat: captured descriptor and report samples for the landing page
4e62486 - fix: phone panels, scrolling, prerendered reveals, contrast and search anchors
85f94ad - fix: phone page panel closes on a box pick or search, and dashboard tools get the full width
9765e4a - fix: guide corrections, and page leads without trailing periods
c1c3e36 - fix: compatibility rows stay apart per device, and the Discord count retries after a failure
94c9e64 - fix: prerender waits for the 404 page's header
3568738 - docs: project notes for the new shell
f4613ce - feat: not-found page on the new shell
d049c04 - feat: landing page blocks
1e3d911 - feat: live figures on the landing and compatibility pages
d54320d - feat: guide pages for box owners
c6a3a05 - feat: compatibility data
1d3f078 - feat: FAQ data and structured data
95b7570 - feat: docs content in the site theme
df74a74 - feat: frame diagrams as byte strips
19b6a89 - refactor: docs pages use page headers and sections
5f893f5 - feat: dashboard in the site theme
6f16d46 - feat: docs pages on the new shell
20b6382 - feat: page header, sections and on-this-page rail
df5300b - feat: docs sidebar
1bdd0e5 - feat: site nav and footer
4c7d086 - feat: guide section routes
99dc575 - feat: scroll reveal helpers
f5e97d9 - feat: site theme tokens, fonts and base styles
f59b667 - feat: the Control and Advanced control pages are indexed
b1a7aa7 - fix: the server's shared modules ship in the image; live pages answer 503, not a placeholder
3050201 - chore: wording in comments, a description and a test name
0a59366 - feat: bold and code in release notes; crawl check typechecks
4905b9e - docs: the route registry, sidebar links and 404 in CLAUDE.md
d490c73 - ci: sitemap dates from each page's last commit
0df48e2 - feat: release notes on the changelog, commits behind Show commits, filled in for crawlers
02a5489 - test: drop the removed unsupported-browser cards from the search exemptions
9e34f4e - feat: dashboard pages keep their content in a browser without Web Serial
b8349a0 - feat: breadcrumbs and a site footer
452aeae - feat: a sidebar of real links
9598337 - feat: a 404 page
67d43ae - feat: 301 to the canonical URL and a real 404 for unknown paths
d1e876d - feat: page head and structured data from the registry
ff7fb51 - feat: prerender every route, the dashboard included, from the registry
6ab9ba9 - feat: one route registry for page titles, descriptions and navigation
13c9fe7
v3.4.5
Changes
- Fixed an issue where certain models without PSRAM would fail to update
- Fixed an issue where certain models without PSRAM could get stuck when attempting to start
- Improved EP0 round-trip timing (~-30% reduction in EP0 latency)
- Improved timing stability for certain EP0 commands
Notes
Sorry to those affected, this hotfix should address the issues you had with updating. Should be fully fixed now.
Show commits
Firmware
- docs, tools: v3.4.5's control request timing and RAM figures
6ad9805 - firmware: control requests are answered from RAM
bf6e62f - docs: v3.4.5 in the release table and protocol change log
2dcc498 - release v3.4.5
95a4d53 - docs: internal RAM on a box without PSRAM, and how the update gate checks it
977e03e - tools: the update gate runs the device image as a box without PSRAM does
2339868 - firmware: the clone starts on a box without PSRAM
e8c1e2f - docs: the usage stats design and plan reach the page from the Stats tab alone
c2a431d
Docs
- docs: update firmware version strings to 3.4.5
116031c - dashboard: fewer words on the Update, Advanced and Device pages
8b0a097 - dashboard: the connect card without the stats line
45c272b
v3.4.4
Changes
- Over-capacity IMPERFECT device's extra endpoints will now function correctly (ie, Wooting keyboards)
- Added support for multiple boxes in the dashboard
- Added flashing over USB2 from the Advanced page
- Boxes on newer firmware than the dashboard supports will now be able to connect (to upgrade/rollback)
- Added a public usage stats page
- Updates now catch a chip which fell back to its previous firmware during the process
- Fixed an issue where locks could take up-to 50ms to engage/disengage (now <2ms)
- Fixed an issue where some over-capacity devices would constantly re-enumerate on Windows
- Fixed an issue where devices with several interfaces could send reports in uneven gaps
- Fixed an issue where a 500hz device could read as 1khz if some reports arrived late
- Fixed an issue where the box could ignore a program's first commands if the previous was disconnected mid-command
- Fixed several issues when a cable is pulled mid-flash
- Fixed an issue where the dashboard couldn't read the box after a program had been using it
- Fixed an issue where the dropdowns could continue using the CPU after being closed (on the dashboard)
- Numerous other small improvements to performance and stability
Notes
The over-capacity IMPERFECT changes allow devices which originally had dead endpoints to now function fully. It still requires IMPERFECT to be enabled, but DRAMATICALLY improves device-support and security in IMPERFECT mode. (IMO, there is almost no difference in security between a perfect and imperfect clone now)
The public usage stats page can be found here: https://medius.k4tech.net/dashboard/stats
Show commits
Firmware
- docs: the usage stats design's result names and totals
4020244 - docs: the usage stats page down to its numbers
5fb9415 - docs: the usage stats page is reached from the dashboard alone
14867a0 - docs: the usage stats design's limits, active boxes and shared devices
7c2b211 - docs: the public usage stats design and plan
628d511 - docs, tools: plainer wording in the protocol doc, designs and gate notes
3dc6e29 - tools: leave the control port readable by the browser dashboard
390ca7d - firmware: the control port drops a frame its sender abandoned
83fbd1b - docs: the USB2 flash design's rare paths and what they changed
4a65e0d - docs, tests: the stable update path names its resync, waits and the messages between the chips
8183489 - docs: the USB2 flash design as built, and its hardware run
19410d8 - docs: name the stable update path section, and plain punctuation in the plan
8df2fee - docs, tests: the update path keeps its shape from protocol 5 on
9d7e587 - docs: plan for flashing over USB2 from the dashboard's Advanced page
dd5c6ce - docs: design for flashing over USB2 from the dashboard's Advanced page
d543602 - docs: USB device box icon, and dropdown menus idle once closed
be31119 - docs: box icons in the multi-box dashboard design
6dd0725 - docs: multi-box dashboard design, Add box tab and card wording
aa5f821 - docs: the multi-box dashboard design as built
dfe9a8c - docs: design and plan for managing several boxes from the dashboard
a7b7de2 - firmware, tests, tools, docs: an imperfect clone keeps every IN endpoint live
d4eb9ec - firmware, tools, docs: a lock is in force before any command sent after it
ea2e07a - docs: v3.4.4 in the protocol change log
4d8f564 - tools: the Logitech fix runs on Linux and Windows with nothing to install
c6d64e1 - docs: v3.4.4 in the release tables
d2f2839 - firmware, tools, docs: an endpoint polled every frame keeps one place in it beside slower ones
ff60509 - firmware, tests, tools, docs: the native rate reads true through reports a poll late
74558cf - release v3.4.4
c2417ef
Library
- library: over_capacity says what it counts, now that the box serves every IN endpoint
610a5fe
Docs
- dashboard: Waiting for injection and Move the mouse to start as neutral chips
292d018 - dashboard: stats bar labels wide enough for the longest route
c56d2ae - dashboard: stats totals as tiles, Unconfirmed as a flash result, a nameless device named by its kind
d397ef4 - dashboard: the stats page down to its numbers
c40b38f - dashboard: the stats page is reached from the dashboard alone
535fdf2 - dashboard: the dev server refuses to serve the stats database
550b9c7 - dashboard: the stats page says when it can't load, wraps long names, and tells flash results apart
5a33b27 - dashboard: stats rate limits, a box active only when it connects, a device listed once two boxes share it
aeea4d5 - dashboard: stats headings named as nouns, a peak on each chart, and New this week among the totals
848103a - dashboard: a volume for the usage stats database
f870b69 - dashboard: a public stats page, and a note on the connect card that boxes are counted
926b4be - dashboard: report each ROM download flash to the public stats
1228dcc - dashboard: report each box, its cloned device and each update to the public stats
72686a7 - dashboard: a usage stats sink, and the totals read for the page
d0c9d29 - dashboard: an event route and a totals route for the usage stats
04f1ad4 - dashboard: usage counts in SQLite, a box known only by a keyed hash of its MAC
add952c - dashboard: the stats server checks each reported event, field by field
653dde4 - dashboard: name ROM download on Advanced, and plainer copy for the fixed update path
d4a5e73 - dashboard: a box the browser can't read says to replug USB2, instead of an empty list
e6413eb - dashboard: say which firmware needs the resync before a handshake
77af84e - dashboard: a flash retried after a pulled cable clears what the box still held, and the box's busy is no longer worded as a held port
81471f1 - dashboard: a box unplugged mid-flash reconnects when it comes back, and says the flash didn't finish
57d455e - dashboard: a newer box is named as newer on every page, and Update leaves Advanced's result alone
46e20f8 - dashboard: Advanced keeps a flash set up when a box comes or goes, and spaces its fields like the other cards
3f6a169 - dashboard: one update at a time, and a newer box found after an install is connected
cb6c47d - tests: pin this page's half of the stable update path
d25cd11 - docs, dashboard: name the stable update path, and tighten two comments
1372324 - dashboard: a refused file names no version to come, and Flash anyway has its own row
3078029 - docs: the update path keeps its shape, and Advanced's search words
9aee6d0 - dashboard: flash either chip or both over USB2 from Advanced
c563c96 - dashboard: an update records which slot each chip came back on
f07950b - dashboard: say when a box is newer than the page, and where it can still be flashed
cfd434a - dashboard: a box on another protocol is kept connected without asking it for health
5713f0a - dashboard: a box on a newer protocol connects, for updating
bda9d27 - dashboard: read a firmware file's chip and version before flashing it
0e44693 - dashboard: a USB device icon for a box
64ffd79 - dashboard: dropdowns no longer keep working in the background after they close
2c3bca1 - dashboard: pick an icon for each box in the sidebar
3e36c5b - dashboard: long box names end in an ellipsis, and no Boxes section without Web Serial
130805b - dashboard: Add box as the last box tab, and box card wording to match its siblings
a5285c6 - dashboard: box list as sidebar tabs, Identify on the box card
4c0664d - dashboard: one opener per port, and a box is held by one tab
b3f5522 - dashboard: every box on the PC, listed and held at once
cc61111 - docs: an imperfect clone serves every IN endpoint
2a7fdfd - docs: a lock is in force before anything sent after it
f4d5828 - docs: update firmware version strings to 3.4.4
0381ea2
v3.4.3
Changes
- Improved support for many more device types (devices with no HID interface, alternate settings, ect)
- Endpoint halts now pass in both directions correctly
- Improvements to native report latency (packets emit 1-tick after arrival instead of 2)
- Updated to ABCurves v2.0
- Added support for high-dpi while using rendering
- CATCH now reports zero-length packets correctly
- Improvements to latency for library replies on Windows
- Fixed an issue where writing to a device's OUT endpoints was capped at ~1 packet/ms
- Fixed an issue where reports could be lost when the PC paused reading the stream
- Fixed an issue where reports could be lost when a device switched settings
- Fixed an issue where zero-length packets from a device wouldn't be passed to the PC
- Fixed an issue where devices with a small control endpoint could take several seconds to connect
- Fixed an issue where some some strings and descriptors weren't cloned exactly as the device sent them
- Fixed an issue where a low-speed device's first report after a pause could land a frame late
- Fixed an issue where a CLIP could play 2 entries in 1 report
- Fixed an issue where MOVEs at poll rate could merge
- Several other smaller improvements to stability and performance
Notes
This update should provide numerous improvements to stability, latency, and device support
I have some other changes in the works too, but I want to get this stuff out first
Show commits
Firmware
- firmware, tools, docs: relayed reports reach the PC on the poll after they arrive, and none are lost across setting switches
8ab665e - firmware, docs: a clip plays one entry to a report, every time
2974980 - docs: v3.4.3 in the release tables
dae9d77 - firmware, tests, docs: a low-speed device's first report after a pause keeps its place
557253f - firmware, tools, docs: a PC that stops reading a stream loses nothing, and reads it current after
d8f701e - firmware, tools, docs: zero-length packets on interrupt endpoints reach the PC as the device sends them
1f918af - firmware, tools, docs: relayed endpoints keep every packet through halts, resets and setting changes
ebe9ed7 - firmware, tools, docs: reports reach the PC sooner, and slower endpoints wait on its polls
65aca8b - docs: the device shapes v3.4.3 clones, the OUT relay, endpoint halts and alternate settings
08376dd - firmware: HID interfaces with alternate settings are cloned, and a switch loses no report
7649b8a - firmware: an endpoint halt passes both ways between the PC and the device
e6d0427 - firmware: every packet the PC writes to an OUT endpoint reaches the device, at the PC's rate
41fdcee - firmware: IN endpoints numbered 5 and 6 are cloned
72aaa87 - firmware: a control request for more than 2048 bytes reaches the device as the PC wrote it
f1d0046 - firmware: a patched string is readable on a device that lists no language
bb769ca - firmware: the device qualifier and other-speed configuration are cloned
7e160c8 - firmware: a device with a small endpoint 0 enumerates at once
8f6a057 - firmware: strings are cloned as the device answers them, in every language it lists
a1bf68b - firmware: a device with no HID interface is cloned
7b63fb9 - firmware, docs: remove the unused capture-owner hooks
256946b - firmware: class and vendor requests to any interface reach the device
45efb0e - firmware: vendor relay buffers are sized to the endpoints that can be live at once
fadb88b - firmware: a device past the host's descriptor tables clones what fits and says what did not
e3fa3d0 - firmware: a device that refuses its own report descriptor is cloned refusing it
cb82a3b - firmware: a slow report descriptor fetch is waited for, not left out of the clone
3144bee - firmware: a HID descriptor after the endpoints, or listing another descriptor first, no longer loses its interface
d154a9f - firmware: devices whose interface numbers skip a value or start at 1 are cloned
4f0ce37 - firmware: an EP0 answer is relayed whole or refused
4511feb - firmware: tell an interrupt transfer a zero-length packet ended
abea180 - firmware: count the IN endpoints a configuration can have live at once
2ef987d - firmware: name the host limit a configuration exceeds
f963527 - firmware: one device is cloned from behind a hub, the first to configure
50d7fb7 - firmware: OUT credit that lets a clone hold the PC the way a busy device does
82f7856 - firmware: the report descriptor store keeps a device's refusal as an entry
1a9a03b - firmware: vendor endpoint buffers are sized to what can be live at once
93a9591 - firmware: a table of string descriptors keyed by index and language
41193f0 - firmware: find a HID interface's report descriptor wherever its HID descriptor sits
10e6ee1 - tools: a descriptor gate and shared sim shape builders
08d473b - docs: design and plan for faithful clones of more device shapes
45a09a0 - firmware, tools, docs: the box's reports reach the PC at one place in its frame
fad5327 - firmware: moves at the poll rate stay one to a report beside a slower mouse
cffba9b - tools: the relay gate checks a feature report's bytes reach the device
8d8aff7 - firmware, tools, docs: a HID interface without an interrupt IN is cloned
d88cfc3 - firmware: rendered motion keeps pace with a flick (ABCurves 2.0)
5c24af8 - release v3.4.3
15efeb3 - firmware: the host chip logs lost reports, not a heartbeat every 5 s
3c69470
Library
- capi: format a test
31fd6ba - library, capi, python: relay_drops as the firmware counts it now that the box polls only as the PC reads
47f1aff - library, capi, python: the zero-length packet flag on every relayed traffic class
6516ce7 - library, capi, python: relay_drops, RAW OUT and the device kind as the firmware has them
e861041 - library, capi, python: a clone is up once its identity says so, and the counters and kinds read as the firmware has them
8d9ceb2 - library, capi, python: a clone with no HID interface counts as cloned
47df70c - library, capi, python: 3.4.3
d3f2e13 - examples: inject_latency also times a query's round trip
4ce1787 - library: a Windows read wakes on the box's reply, not on a 2 ms poll
466412c
Docs
- docs: relay drops, and the room RAW reports have in an interrupt IN queue
15f09d3 - dashboard, docs: zero-length packets on interrupt endpoints and the CATCH flag that marks them
5f69d13 - docs: relay drops, RAW OUT waiting, the requests CATCH sees on EP0, the product string and the device kind
eb4619f - dashboard, docs: an attached device the box did not clone, relay drops, the IN endpoints a clone serves and the requests it passes on
361a7a8 - docs: the native requests page on a clone with no HID interface, and which long requests the box refuses
9b2a754 - dashboard, docs: a clone with no HID interface reads as cloned, and the IN endpoints a clone serves at once
ca384a0 - docs: when a native report keeps its own poll beside an injection
c721340 - docs: a rendered report is bounded by the mouse's own field, not 127 counts
b699bcf - docs: the library's unsafe code is its Windows comm-event wait
8e996ba - docs: update firmware and crate version strings to 3.4.3
65632ec
v3.4.2
Changes
- Moved all motion processing to the host chip (rendering, riding, spreading, locks, ect)
- Added factory reset
- The library now restores locks, rules, subscriptions, ect after a box restart
- Injection now wakes a sleeping PC (where applicable)
- Fixed an issue where using CATCH could cause the devices movement to be dropped
- Fixed an issue where the library could bluescreen Windows PCs using the WCH CH343 driver
- Fixed an issue where a descriptor patch that failed a check could still override the device
- Fixed an issue where a device with reports larger than one packet would stop after its first report
- Fixed an issue where OUT reporting could be merged and lost on certain devices
- Fixed an issue where back-to-back injected clicks could be lost
- Fixed an issue where injected reports could delay a native report
- Fixed an issue where a devices reports could drop during an update
- Clearing descriptor patches no longer requires a reboot
- Several other smaller improvements to stability and performance
Notes
With the motion processing being done on the host chip, it should eliminate any slowdown that occurred on certain devices whilst using Full Rendering and other high-intensity features
Overall, we are looking at a roughly 40% decrease in render latency across a number of different measurements. This also means native reports are delivered more consistently
Show commits
Firmware
- firmware: a render comment keeps the reason one report is outstanding
1517fe2 - firmware, tools, docs: fewer words in every comment and doc, and the claims the pass found wrong
11752c1 - docs: a flagged MOVE skips spreading and rendering with riding off
e8dd0ca - docs: the protocol reference and architecture match the corrected behaviour
f08625b - tools: gates for the advanced control fixes, session releases and OUT relay, all sim-driven
68b5ebd - firmware: advanced control corrections, OUT relay fixes and report scheduling
aafaf4f - docs: the version table names the flag RESET grew
2e623a4 - tools: the client's opcode list says what RESET carries
f3ad3a6 - firmware: RESET requires its flags byte, like every other command
c7a4dd2 - firmware: RESET can take the box's stored settings with it
d69e608 - firmware: a suspended PC is woken for injection, and hears it when it wakes
10f89dd - tools: the render gate reads a property the paced fill cannot have
1389ff4 - firmware: the health bit answers for the control PC's motion, not the device's own
b39b53f - firmware, tools: comments say the one thing that is not obvious, in two lines
8895c70 - firmware: injected commands cross the link a whole frame at a time
47cf5e8 - tools: the wedge gate walks past an identity it has already spent
3a4943b - firmware: an abort that worked no longer leaves the session open behind it
ca82234 - tools: three cadence checks now read the value their property is about
297b43d - firmware: what a departed control PC left behind is released whether or not a device is attached
8aefc06 - tools: the wedge gate stops spending a device identity it cannot get back
91a3285 - tools: a cadence gate was grading its own sender, not the box
4298d03 - firmware: an update no longer loses its answer to the link's own recovery
3e1e82f - firmware: a relayed update says what happened to it
b567d1a - firmware: an OUT report lost on the link is the relay shedding, not input the game missed
fb52822 - tools: the reference client's stats reply length follows the field it grew
9e4111d - firmware: a drop counter says which fault it is, or it says nothing useful
2af524b - tools: what a scale does to physical input no longer needs a hand
2fca234 - firmware: injected motion leaves on arrival, not on a clock of its own
0ce9edb - tools: the transform gate measures the weigh and the transform together
4960cd1 - firmware: nothing that carries motion blocks on the link, and the host watches its own work
fe925ec - firmware: the authority's answer crosses as the weigh and the release, apart
4f02b05 - firmware: the box reports what the links dropped
c4bfad1 - firmware: the motion authority releases the lock it takes
abe6356 - firmware: the motion authority moves to the host chip
87f59c6 - firmware: one weighing unit, on the delta rather than the report
efa315b - firmware: the motion primitives move to common
dea849e - docs: the motion authority moves to the host chip
9038058 - release v3.4.2
6cdbbfe - tools: the conservation arm puts the sim back when it is done
0154163 - tools: the catch rig asks whether observing cost the player any movement
ac495eb - firmware: observing the traffic no longer costs the device's reports
ff0c296
Library
- library, capi, python: fewer words in every doc, and the claims the pass found wrong
45468f3 - library: a non-blocking control-port read avoids a WCH serial-driver crash on Windows
5b60d0b - library, capi, python: the library restores its state after a box restart or session release
37fdd95 - library: RESET carries its flags byte on both paths
460c51c - library, capi, python: the box can be asked to erase what it keeps across a reboot
e84f1b3 - library, capi, python: comments say the one thing that is not obvious, in two lines
6fc9f65 - library, capi, python: back-pressure on a relayed stream is its own counter
b5782b0 - library, capi, python: control protocol 9 and the box's link drop counters
57a56fd
Docs
- dashboard: values that stand alone start with a capital
47cdd60 - dashboard: DTR and RTS reset neither chip, measured
28c624a - docs, dashboard: fewer words on every page, and the wrong claims the pass turned up
60d5c89 - dashboard: shorter performance row labels
33442a7 - dashboard: the performance card shows every counter's count
a196c66 - dashboard: the relayed-streams chip stands on its own
f862c43 - dashboard: decode protocol 9 catch flags and stats, and show patch and rewrite state as reported
da3a75a - docs: the library and bindings pages cover session recovery and the corrected advanced control
bbd45cf - docs: native pages for RAW, TRANSFER, REWRITE and PATCH, and a sidebar that fits its pane
f9c68d5 - docs, dashboard: RESET carries its flags byte on every frame
d678a45 - docs, dashboard: RESET's erase-and-reboot flag
f231ce8 - docs, dashboard: comments say the one thing that is not obvious, in two lines
b648d75 - docs, dashboard: the stats counters tell lost input from relayed back-pressure
1cf6f21 - docs: the stats offsets are what-inclusive, and the samples speak protocol 9
6bbb5f7 - docs, dashboard: control protocol 9 and the inter-chip link counters
37a8d9c
v3.4.1
Changes
- Added packet-based triggers to the CLIP system
- Added AC pan, raw reports and control transfers to CLIP system
- CLIPs now function correctly on all device types, not just mice
- Fixed an issue where injecting at the devices native report rate could blend moves together
- Fixed an issue where a descriptor patch wouldn't apply to a device without a mouse interface
- Fixed an issue where rewrite rules weren't cleared when the control link went silent
- Fixed an issue where rewrite rules on a vendor interface's OUT wouldn't match
- Improvements to latency when injecting RAW packets via the library
- Several other smaller improvements to stability and performance
Notes
Packet triggers let a CLIP fire directly from the device's traffic. This allows for specific behaviour when a flag is seen (ie, conduct macro when DPI button is pressed): https://medius.k4tech.net/library/clip#packet-triggers
The protocol and ABI version has changed to 8, so devs with their own libs will need to update accordingly
Show commits
Firmware
- docs: what protocol 8 changes, and the README's command reference
f9bea34 - firmware: control protocol 8
6388acc - docs: a packet trigger's read-back has its present bit clear
3fd6757 - docs: clip packet triggers
44c550a - tools: the clip gate proves packet triggers on every surface
f219f0b - firmware: a matched packet is a clip trigger
9ea7e94 - docs: whole commands at the report rate
14e9bf1 - tools: the spread gate measures a report-rate loop, and a tool keeps the clone off the desktop
d5c7ed6 - firmware: a command loop at the report rate lands one command on each report
807593e - docs: clip entries for pan, raw reports and transfers, and the clip transfer class
d35751d - tools: the catch gate presents its own streaming mouse for the clock-offset leg
9a73e43 - tools: the reference client builds the new clip entries, and a clip gate proves them on the sim
9bfa856 - firmware: clips carry pan, raw reports and control transfers
f2e6caf - release v3.4.1
c09fa89 - tools: the clone-policy gate waits out a multi-configuration capture
45dd27e - tools: the descriptor-patch gate covers a device the box finds no mouse in
66280e5 - firmware: a descriptor patch is stored against the device, not the mouse in it
d4aef98
Library
- library: the C header names its ABI, and a reconnect refuses a box on another protocol
a0740f2 - library: control protocol 8 and C ABI 8
dac754e - library: packet triggers follow the box through the opt-in, and the mock refuses as the box does
8208e81 - capi, python: clip packet triggers
eb0a3a7 - library: a matched packet is a clip trigger
7a93a44 - docs: set_spread says what a loop at the report rate gets
a006979 - examples: the hardware suite proves clip entries and a clip across a reconnect
901a1ec - library, capi, python: clip frames carry pan, raw reports and control transfers
1a54225 - ci: the crate, the C ABI and the Python binding must carry one version
c066099 - library, capi, python: the bindings reach the transfer timeout the crate has
9454600 - release: bump the crate, C ABI, and Python binding to 3.4.1
cecf373 - library: raw sends without a round trip for the opt-in
50a4f8d
Docs
- docs, dashboard: what protocol 8 changes, the C ABI constant, and a reconnect across protocols
f85d02b - docs, dashboard: control protocol 8 and C ABI 8
9a0bf86 - dashboard: number fields take whole numbers
07ae27d - docs: packet trigger ordering, placement, timing and the mock
b0b2f26 - dashboard: the Clip card says when the box does not take a trigger
439682f - docs, dashboard: clip packet triggers
6bf5ab2 - docs: what a loop at the native report rate gets from spreading
3e4bb4e - dashboard: clips build pan, raw report and control transfer ticks
8ac29c2 - docs: clip frames with pan, raw reports and control transfers, and the clip transfer class
52dce04 - docs: the C and Python transfer timeout calls
31a433c - docs: update crate version strings to 3.4.1
0a96dd5 - docs: update firmware version strings to 3.4.1
d8d5931 - docs: a patch's cfg is a configuration index, and raw does not read the opt-in
a0e2823
v3.4.0
Changes
- Added an advanced control layer (raw report injection, traffic rewrite rules, descriptor patches, ect)
- Added AC pan as first-class axis
- Added support for buttons above 5 (up to whatever the device declares)
- Added transform system: swap axis' and remap buttons with first-class support
- Fixed an issue where CLIP motion wouldn't be processed by the renderer
- Fixed an issue where CLIP + rendering may not advance at the correct rate for slower-reporting devices
- Fixed an issue where rendered motion may not be delivered in full on large movements
- Major improvements to injection throughput and reductions in latency
- Fixed an issue where a device may stop working after a host-pc restart
- Fixed an issue where a device may read as not connected when it just takes a while to connect
- Fixed an issue where an update may fail whilst the other chip was still erasing
- Several other smaller improvements to stability and performance
Notes
The advanced control layer gives you low-level control over the device itself. Emit bytes on any endpoint, control transfers though to the real device, rules that can rewrite traffic in-flight, and patches to the descriptors being sent to the host device
It requires Imperfect Clone to be enabled, and can be found here: https://medius.k4tech.net/library/advanced/raw
The protocol version has changed, so for those with their own libs, you will need to update accordingly. The control port has also moved from 4MBaud to 6MBaud, so you will need to update your port-opening accordingly
Show commits
Firmware
- docs: the transform section says how the two commands compose, not what one lacks
4279cd1 - firmware: a lock bites the field the device drove, and every one-bit class refuses a reversal
5641e52 - firmware: the two comments that still described the old pass order
de0c479 - docs, tools: the lock scale is signed, and a transform only moves a field
dcfd81f - firmware: weighing a field belongs to LOCK, and a transform only moves it
7af85dd - firmware: the field-transform pass is the first thing the renderer does, not the second
5a28e90 - firmware: a scaled swap banks each direction, and a remapped key is one a keyboard reports
78b5873 - firmware: the one injection path that reads the report map checks it is bound
ae091fd - tools: the transform gate reads the wire the game PC sees
2322322 - tools, protocol: the reference client and the byte reference cover transforms
f90d0e7 - firmware: a narrower configuration can still release what a wider one held
2685068 - firmware: transforms hold their own arithmetic, and a remapped key follows the button
73941a4 - firmware: shorter clip rendering notes and comments
67f58ba - firmware: clips play through the renderer at their own pace, and rendered motion arrives whole
74a6c6a - firmware: the mouse keeps working after the game PC restarts
99e546d - firmware: the tools open the port at the rate the box answers on
0bb18b2 - firmware: a completed transmission is no longer thrown away before it is seen
cdcf9e0 - firmware: a host image confirms itself only on a link that works
4247979 - firmware: the link's rate recovery starts where the image expects it
52594cc - firmware: the inter-chip link runs at 20 Mbaud
b7a799e - firmware: revert the short frame form and CTRL_MOVE8
39d5644 - protocol: one version bump for the release, not two
e802ed3 - firmware: the control link runs its own UART interrupt, and the link watchdog tolerates an erase
9fab234 - tools: the recovery flash script takes the control rate from the client, not a literal
ac67ce4 - firmware: the inter-chip link runs its own UART interrupt instead of IDF's driver
95d8c53 - firmware: link frames go straight into the TX FIFO instead of through the driver's ring
299a0a4 - firmware: the snapshot retry budget is spent only on attempts the link could carry
1bf86fd - protocol: the short frame form is v8, and the reference spells it out
4d14a07 - tools: a control-rate rig, and the client stops charging the port timeout to every reply
1c5e7e6 - firmware: the inter-chip link runs at 12 Mbaud and stops waiting out its receive timeout
ab9f62b - firmware: a shorter hot-path frame, and injection stops paying for a refused emit
b325bf4 - firmware: the frame CRC reads a table instead of shifting eight times a byte
bc14de0 - firmware: hold 32 rewrite rules, and count the matches the reply reports
5e96c48 - tools: bearing and lock take the AC-Pan axis in their motion callback
f45dfef - firmware: descriptor-patch consistency read the wrong bytes, and a refusal stranded the clone
f7426a3 - firmware: rename the developer layer to the advanced control layer
2e5b4a6 - tools: catch subscribes to endpoints by number, and a raw injection gate
ecfc977 - tools: reference client and protocol reference name an endpoint by number and direction
e9e99bf - firmware: name a cloned endpoint by number and direction, not a packed byte
51f0e97 - firmware: transforms apply on a secondary mouse, and a cross-class remap releases its key on removal
3f136c8 - tests: gate the field transforms and their compositions
1481d38 - firmware: field transforms (invert, scale, swap, remap)
9c3a259 - tools: reference client mirrors the widened input core (AC Pan, buttons past five)
27cab02 - firmware: correct AC Pan's clip scope and the reported button count
f6741da - tests: gate AC Pan, buttons past five, and the spread/ride drain
7052133 - firmware: widen the input core to AC Pan and buttons past five
5efc74d - firmware: the rewrite table's generation counter stays monotonic across a clear
855f239 - firmware: set the milestone version to 3.4.0
617997d - firmware: skip an unchanged patch-set write, and correct a transfer status comment
e4dc8dc - tools: reference client and protocol reference track the patch-length widening
2740192 - firmware: correctness fixes to the developer layer's emit, observation, transfer and patch paths
163e0f4 - firmware: a table overwrite that will not fit keeps the existing entry
7ee87de - docs: control-protocol reference for the developer layer (proto 7)
8f0d7cf - tools: reference client for the raw, transfer, rewrite and patch verbs (proto 7)
21817e3 - firmware: dispatch the raw, transfer, rewrite and patch commands
6d91f35 - firmware: persisted descriptor patches, applied under the clone-refusal ladder
50c48c2 - firmware: health carries the rewrite state (health is now 16 bits)
389aa18 - firmware: an on-box rule table that rewrites traffic at every surface
41e2c40 - firmware: run a control transfer against the device on the control PC's behalf
d17be06 - firmware: raw report injection on any cloned endpoint
ba45759 - firmware: control-protocol wire for raw injection, transfers, rewrites and patches (proto 7)
dbd264f - firmware: a per-device descriptor-patch set with consistency checks
fc0a70f - firmware: a pure rule table for rewriting traffic in flight
8e3e1cf - docs: implementation plan for the generic control layer
d38d73c - docs: v3.4.0 design specs (generic control, widened input, transforms)
ebaf3ff
Library
- library, capi, python: docs say where to go, not what the API lacks
a6f2520 - library, capi, python: pin the signed scale's guards, and rank a block above a reversal
e2cbfde - library, capi, python: weighing a field is the lock's, and the percent is signed
8856654 - library, capi, python: the C transform op byte, and the tests that never compiled
ee62bcd - library, capi, python: a transform table replays in the order it was built
8281209 - library, capi: the clip ride readback fields keep their original wording
837c25a - library, capi, python: clip riding reaches only the wheel while rendering takes the cursor
d37c615 - library: say what actually confirms a firmware image
7bfa7f4 - library: the control link opens at 6 Mbaud
6abe68c - library, capi: the rewrite table holds 32 rules
38ca523 - python: finish the advanced control layer rename in a test section header
35160bd - library, capi, python: rename the developer layer to the advanced control layer
2fa56be - library, capi, python: name a cloned endpoint by number and direction, not a packed byte
42510de - capi, python: AC Pan and first-class transforms
45d730e - library: field transforms (invert/scale/swap/remap)
c085db7 - library: a button blanket re-asserts every declared button after a reconnect
7c4cebe - library: AC Pan axis and buttons past five in the input core
a76de9a - library: C API and Python bindings for the developer layer
0740836 - library: serialize the developer-layer session state and harden its tests
ad99e91 - library: cover the developer layer in tests and the hardware example
ab33cce - library: raw injection, control transfers, rewrite rules and descriptor patches
b492584
Docs
- docs: a conformance gate, so shape drift is caught by the build and not by the reader
e7bf915 - docs: an enum is documented on the enum page, not carded again on the method page
67936ae - docs: pages point somewhere, instead of naming calls that were never there
0bf11aa - docs, dashboard: the opcode table reaches 0x1E, and a block outranks a reversal
2dcbfb2 - docs, dashboard: the lock scale is signed, and a transform only moves a field
412ff1d - docs: correct what the transform pages claim, and finish moving the types
0fa563c - docs, dashboard: the v3.4.0 types live on the type pages, and transforms match the wire
b822eb2 - dashboard: the update choices are the ones they were
da23a7b - dashboard: reach a box on older firmware, and see its update through
a949be4 - docs: shorter clip rendering copy
152ef34 - docs: clips are rendered like live motion
0c594e1 - docs: the pages that tell you which baud to open still said the old one
66182d3 - docs: the control link is 6 Mbaud and the inter-chip link 20
9650135 - docs: the rewrite table holds 32 rules
02023b5 - docs: rebuild the advanced control tab on the pattern the other tabs use
12b760d - docs: gate the rewrite remove/clear buttons on the imperfect opt-in
4fb4b97 - docs: the advanced control dashboard tab is no longer blank without a device
d968e0e - docs: finish the advanced control layer rename (tab variable, a test comment)
20213f3 - docs: rename the developer layer to the advanced control layer
cc5d672 - docs: fix the dashboard RAW comments left on the old packed wire
ffa5a43 - docs: name a cloned endpoint by number and direction, not a packed byte
b6988c9 - docs: complete and de-slop the v3.4.0 reference
7fbc25b - docs: AC Pan and buttons past five as first-class input
22254a4 - docs: widen the native HEALTH reference to the 16-bit word
da8f6eb - docs: developer layer reference and the 3.4.0 version bump
9be03ac - docs: firmware 3.4.0, protocol 7 on the native pages
f70735d - dashboard: add a Developer tab to edit rewrite rules and descriptor patches
aec3079 - dashboard: mirror the developer layer on the control link (proto 7)
a4f09ec
v3.3.4
Changes
- Fixed an issue where the box could reboot while under heavy load
- Fixed an issue where data sent from the control pc could be silently dropped
- Fixed a rare crash on startup
- More small improvements to stability and crash reporting
Notes
I've got a couple more features I want to do, but I have a TON of stuff coming up with work soon so just be aware of that
And just FYI, Unless a developer approaches me with the stuff to add proper console support (ie, the decryption process for PS5), it is unlikely that controller/console support will be implemented
This is simply because I do not have the hardware to test it on (A PS5 is >$1000 in Australia ๐ธ)
Show commits
Firmware
- firmware: claim a deferred write before making it, not after
f4c4623 - firmware: make a bulk sequence increment atomic now that it crosses cores
ea3e711 - host: a control job refused rather than asserted before its queue exists
7cbd464 - firmware: move the two starved tasks instead of working around them
e3be0b7 - firmware: the record keeps the names worth reading, and a refused write is its own
80566b6 - firmware: watch fewer tasks, and say which one stopped
e89e759 - firmware: a busy box stays up, and a wedged one still names what stopped
9aa62e8 - release v3.3.4
87e90bf - firmware: a busy box no longer reboots itself under a heavy observation load
16459f3 - docs: what a watchdog record says, and the boot line as it is actually emitted
6f56497 - firmware: a task watchdog now says what was running when it fired
698b263
Docs
- docs: tx_drops counts both directions, not just the report path
7318cb8 - docs: update firmware version strings to 3.3.4
ae7a32a
v3.3.3
Firmware
- release v3.3.3
4d5ad7f - firmware: act on the review of the PSRAM fix
2a0448a - docs: the two PSRAM variants of the board and what differs on each
17f749d - firmware: a box whose S3 has no PSRAM stops reverting its update
c01a089
Docs
- docs: update firmware version strings to 3.3.3, and record that clip capacity varies
ea25c2a
v3.3.2
Changes
- Fixed an issue where PSRAM may not initiate correctly causing the update to fail
Show commits
Firmware
- firmware: ask for PSRAM a second time before giving up on it
d69deec - firmware: boot a box whose PSRAM does not answer, and say what it found
c2a6425
Docs
- docs: the firmware is on 3.3.2
6e79184
v3.3.1
Changes
- Added emission rendering, injected movement is pushed via a fitted model of your device
- Added "Full Rendering" where native movement ALSO passes through the model
- Added injection spreading to spread out added movement from sub-native injection rates
- Fixed an issue where after a pause, injected movement would wait an extra milisecond
- Fixed an issue where a device could get out-of-sync with its emitted state
- More improvements to stability and performance
Notes
Rendering is probably the most important feature ever released. Injected movement now carries the texture of the device connected, not just a fixed, flat pattern
https://medius.k4tech.net/library/options#set-render
The protocol version has changed, so for those with their own libs, you will need to update accordingly.
Show commits
Firmware
- tools: let the relay arm allow an accumulation, and only an accumulation
881c34b - tools: let the mirror gate run itself
bcc50b7 - firmware: keep the motion mirror true through a coalesced report
52dec74 - tools: three gate defects, one of which inverted what a gate measured
d1e6c1b - firmware: hold the smoother's rounding order
f61dfd9 - firmware: deposit a rendered report from the clock that emits it
9bcaf95 - firmware: take a sixth off the model step and the observation pass
c52d7ef - firmware: learn the command period from the bucket's low edge
42c5811 - firmware: cover a command rate that varies continuously, not in steps
ec76b3c - firmware: name the subject in three comments that opened on a pronoun
b2407d1 - firmware: name what is being released instead of writing it
ee78ecd - firmware: keep the anchor a deposit has already earned
da65db8 - firmware: drop the commentary the composing change made pointless
22c6678 - tools: wait for the clone's event node instead of guessing one
a9d52c4 - firmware: compose the release interval with movement riding
4f77770 - spec: record where the build differs from the design
53697c9 - firmware: fix the defects an adversarial audit of the release interval found
4f52577 - tools: gate the release interval on density and magnitude, not the total
7b07f3c - firmware: spread an injected delta across the host's command interval
5d8a740 - firmware: release an injected pot across an interval rather than on one drain
0eb0ee9 - plan: the release-interval implementation
7f03864 - spec: spread injected motion across the learnt command interval
bc5d559 - tools: three gate defects the hardware run exposed
a31c648 - firmware: say native for the operator's motion too, and drop two metaphors
9f1de70 - firmware: say native in the host tests too
0f4bc36 - firmware: say native
9577f8e - firmware: fix the defects an adversarial audit of the render change found
cb5107c - docs: name the box state a faithfulness capture requires
dab36b4 - docs: mark the superseded render design records
1f57ef0 - docs: correct the plan steps that contradicted their own constraints
1ea2e65 - tools: have the client's selftest read every option back
125f3f1 - firmware: dispatch and pack the box options in id order
e6588b4 - tools: correct which personality the full-rendering gate runs on
5e6c796 - docs: record the rendered texture in the detection register
6655022 - tools: order the client's options by id, and name the bearing rather than the aim
dfd08d2 - docs: say rendering adds latency, and stop there
250873a - firmware: credit ABCurves, and ship its licence with the images
395771e - docs: cut the render prose back to what the surrounding pages carry
f3b8c7e - docs: use the vocabulary and voice the rest of the stack already uses
684f625 - firmware: keep the wire version this branch already introduced
fb83667 - docs: record the soak result and what still needs a hand
ba47579 - docs: record what the acceptance run measured and what it did not
a23b22e - device: keep the operator's motion out of every path that drops the host's
3169ec7 - docs: describe the texture as its own setting, and what full renders
a74ee47 - tools: address the texture settings on their own command
19da53d - device: render the attached device's motion with the same model
483084c - docs: plan the work for rendering native motion
7af1de1 - docs: settle how native motion joins the model's stream
a4cc658 - docs: the constraint set and open decisions for rendering native motion
58ad3d3 - docs: design for spreading owed injection across the learnt command interval
61bfe18 - tools: measure what a host commanding slower than the device costs the wire
f8fa8ec - docs: describe the kernel the box ships and the clock the model steps on
5ea77cd - docs: record every departure from the upstream render runtime and its measured cost
5f5d897 - tools: verify the profile armed before the texture page claims a mode
6635fda - tools: apply the comparison kernels causally, at their own lag
bcc39ba - tools: resolve the clone's input node instead of assuming its index
6b571ae - firmware: begin a render phase on the tick it steps on, and hand back what it still owes
78545fa - firmware: render the intent in single precision, on a kernel that answers sooner
c0c16c4 - tools: ignore the texture rig's output
cc46e41 - tools: measure the render model against injection shapes a host actually sends
b2165e2 - tools: score injected texture against the attached mouse
9a513ab - firmware: render on the same clock reports leave on
95e6e95 - docs: record the measured result and why the render path deposits again
a43c4a8 - tests: bound the assertions that passed on a dead pipeline
6925be7 - firmware: drop the smoother's dead branches and answer flush misuse
78419a3 - firmware: keep the device stack on its own core, and let the pace clock catch up
ed1d30b - docs: correct the renderer state size after the smoother change
4ee0cab - docs: what the render model reproduces, and why it paces off a timer
8286116 - tools: gate the renderer on its texture and on whole delivery, not on idle fraction
f978169 - firmware: stop the render pace clock on a clear, and only yield when a tick is already owed
43978f4 - docs: record the measured injected-emit latency
41ee33c - tools: measure injected-emit latency per render mode
f3e1a14 - firmware: the renderer keeps to its millisecond grid and starts a phase without folding the profile
94efd3c - firmware: injected motion emits as soon as its rate gate allows
8fb49d3 - firmware: one place that builds a synthetic injected frame
ac55a88 - tests: assert the render pipeline's latency without hardware
9eed0f9 - firmware: the de-spiked smoother no longer drops the motion it starts with
383cbb2 - docs: implementation plan for the injected-emit latency work
f0cb115 - docs: design for cutting injected-emit latency
6d03dae - docs: use one spelling for the words that had two
b700ceb - firmware: apply a render mode change at the next phase, not mid-phase
03afab9 - docs: correct stale protocol facts and tighten the writing
07fdee7 - docs: split the render section and drop the em dashes
75735d7 - docs: correct the protocol version and the emit section
df9d435 - tools: assert the render profile is armed, and leave the box as found
6212b28 - firmware: render only once the device has been seen to move
fcfbef5 - firmware: render injected motion by default
092b7f7 - firmware: give the render mode its own field in the emit option
ef63132 - tools: show every render mode in the texture page and fix its idle metric
2ad2995 - firmware: stock / de-spiked / off modes for the injected-motion smoother
2b5bfd2 - firmware: no first-tick spike from the injected-motion smoother
e0fc07a - tools: ignore the generated render_viz.html
c3bffde - tools: visualise paced vs rendered injection
fd2550d - firmware: drop the stale mode-3 name from the render header
ab2e69c - firmware: make rendered a texture flag that composes with the pace
55622e2 - firmware: vendor the ABCurves MIT license
2b8f7a4 - firmware: cut comment noise in the render path
0f30828 - release v3.3.1
edcb98f - docs: list the rendered emit gate among the validators
3561e40 - firmware: measure the rendered emit gate in isolation, off kernel time
482d940 - firmware: harden the rendered emit path found by review
d6837e4 - firmware: point the render gate at the trace mouse's own product id
fdbb35f - firmware: conformance gate for the rendered emit mode
7fa49cc - firmware: keep the rendered tick on-chip (IRAM code, internal-RAM tables)
183370b - firmware: rendered emit mode drives injected motion
36ec37a - firmware: move the clip ring to PSRAM to free internal RAM
70cec1c - firmware: 1ms grid reconstruction for the emit observer
a5c2961 - firmware: bit-exact render runtime with SIMD-optimised tick and host gate
f9a10b3 - docs: implementation plan for rendered emit mode
bbd6c1d - docs: design for rendered emit mode
e9407bb
Library
- library: name what is being released instead of writing it
2cfd1df - library: say native for the report rate in set_spread's docs
4f86ba2 - library: regenerate the C header, and widen two boundary tests past a byte
c8e0104 - library: expose the release interval on the library and both bindings
ef0d6e6 - library: say native
e047fee - library: cover the render option's async and C-ABI paths, and match the mock to the box
8a74375 - library: expose the box options in id order across the library and both bindings
feadf82 - docs: say rendering adds latency, and stop there
b76c1d0 - docs: name the model the box renders with
bad84cd - docs: tighten the render option's doc comment
e64ec71 - docs: use the vocabulary and voice the rest of the stack already uses
788be0b - library: keep the wire version this branch already introduced
b1b27dc - library: make the mock answer the pace the way an unarmed box does
11f7b86 - library: address the texture settings on their own command
5f31ad4 - library: one spelling in the Cargo.toml comment
6b1f0b5 - library: take the render mode across the C ABI as a byte
e3a04f2 - library: correct stale doc comments and tighten the writing
e2ff4f9 - library: bump the C ABI, and require an explicit render mode
f997d6c - library: the render mode is its own emit field, and de-spiked is the default
860905c - library: a RenderMode of off / stock / de-spiked / unsmoothed
4fcb605 - library: trim the emit-pace doc comments to one-liners
1971cf3 - library: rendered is a composing flag, not a pace variant
9787636 - release: bump the crate, C ABI, and Python binding to 3.3.1
5dbfc7d - library: assert the rendered pace resolves to 1 kHz, and document it
59965e5 - library: rendered emit pace across the crate, C API and Python
e5014c9
Docs
- docs: name what is being released instead of writing it
23ad387 - docs: drop the riding paragraphs the composing change made pointless
ce9cc43 - docs: say that the release interval composes with movement riding
bc1453c - docs: correct what the release interval does, and say native
02d005b - docs: document the release interval and add its control
1dfa40e - dashboard: say what two more controls are, in fewer words
50db963 - dashboard: say native for the wire rate too
b531d09 - docs: say native
068eab6 - dashboard: name the render setting, not what it does to the mouse
64cc05c - docs: fix the docs defects an adversarial audit found
611014b - dashboard: order the option code paths by id too
82b1bec - docs: list the box options in id order on every page
3bf7bb0 - docs: put the option cards back in the order the other pages use
bcc5402 - docs: say rendering adds latency, and stop there
e7b78ef - docs: credit ABCurves where the render option is described
861e177 - docs: bring the render copy back to the shape of the cards around it
e57335d - docs: put the render option back with the other options
d24381c - docs: use the vocabulary and voice the rest of the stack already uses
8f43a93 - docs: give the texture its own page instead of a footnote in the options list
9c60f5f - docs: keep the wire version this branch already introduced
53210af - docs: correct the texture's own cost and what it renders when it is off
5732204 - docs: give the texture settings their own command and page
8145b5c - docs: shorten the labels that had grown into sentences
76b9167 - dashboard: give every card a search anchor and every state its own card
6cffdd2 - docs: correct stale references and tighten the writing
945600a - docs: cut the emit card down and stop tables repeating their own label
17cb075 - dashboard: say what to do, not what the protocol is
b0b2132 - dashboard: give the older-protocol state a card, not a loose callout
285ddfe - dashboard: connect a box a protocol version behind so it can be updated
491ed70 - docs: correct the protocol version and the binding references
5051cc4 - docs: rebuild the emit option page around its four fields
bbaa865 - dashboard: four render modes in the selector; drop the Render Lab
7a483cf - dashboard: hint when rendered emits nothing on an unprofiled device
bc163c1 - dashboard: a Render Lab to visualise rendered vs paced injection
a712679 - docs: fix the rendered control's label case and reactive blurb
5317a5c - docs: strip the rendered prose to the terse house style
b5cb437 - docs: match the bindings set_emit_pace signature and status field
dd7db68 - docs: rendered is a composing flag, and credit ABCurves
34932ad - docs: order the option sections by id
8b77755 - docs: tighten the rendered emit prose
3a70975 - docs: rendered emit mode, and the 3.3.1 firmware version
a090bcc
v3.2.1
Changes
- Fixed an issue where a mouse would stop responding despite still showing as connected
Show commits
Firmware
- release v3.2.1
c024681 - docs: what the box does when a mouse stops answering, and what the delivery count means
c2c87e3 - firmware: count a delivery stall only on an endpoint the PC reads
8c48083 - firmware: bring a stream back when the mouse stops answering its own endpoint
aa409d1
Docs
- docs: update firmware version strings to 3.2.1
7e3ae55
v3.2.0
Changes
- Added firmware updating via USB2, both chips with no buttons or recabling
- LOCK is now a scale, you can keep a fraction of an input instead of only blocking it
- Added injection-based aim bearing, so LOCKs can apply with or against the direction of injection
- Added forcing of the rate the clone advertises
- Improved dashboard onboarding and update workflow
- Connection errors in dashboard now actually explain what is wrong
- Fixed some devices going unresponsive when the box attempts to seed certain information
- Fixed some wireless receivers reporting as a keyboard instead of a mouse
- Fixed clearing an aim bearing not actually fully clearing it
- Fixed a button LOCK reading back as the wrong thing
- Fixed SCALE affecting reports it shouldnt
Notes
Updating is a big theme this release. Both chips can now take firmware over the control cable instead of performing the dance previously required. If an image won't run, the box will return to the previously working firmware automatically
However, you need to get TO v3.2.0 first though to enjoy this benefit. So follow the new setup page and that should hopefully be the last manual flash you'll need to do
https://medius.k4tech.net/dashboard/setup
LOCK got a big overhaul, it's a scale now instead of a binary on or off. 0 blocks everything, 100 allows everything through untouched. Above 100 amplifies the movement as well. Combined with the new aim bearing system and you can weigh native input by whether it's with or against the injection
Superstrike users, I will make a guide shortly on how to fix your device so it works correctly with this latest update. It will be found in #guides on the Discord
Keep it coming lads ๐ซก
Show commits
Firmware
- docs: correct the setup design to what the board and the reviews showed
8ff0f49 - docs: the build order for getting a box set up the first time
05e0635 - docs: the design for getting a box set up the first time
29e6813 - tools: guard each restore, hand the sim back, and name the verb that exists
bd6bbde - docs: correct the forced-rate entry to what the wire actually does
16645c1 - firmware: build the forced rate the way the files around it are built
346c220 - firmware: say the poll interval changed only when it did
f4b8491 - tools: run the rate gate against a real attached device, forcing away from what it declares
696c824 - tools: let the riding gate run without a hand when the sim owns the only node
45e3456 - tools: build the gate's mouse from the rig's own, and find its input node
77e7a57 - firmware: what the review found in the forced-rate path
48d477d - tools: a gate for a clone running at a rate the device did not declare
25ff60e - docs: how a box is told to run at a rate the device did not declare
afbb2a0 - tools: set and read the forced rate from the reference client
0527fda - firmware: ask the device for reports as often as the clone says it will be asked
94fe1f7 - firmware: let a box advertise a rate the device did not declare
c99497e - firmware: carry a forced rate and what the clone advertises on the pacing option
ba558cc - firmware: work out the poll interval a forced rate needs, and write it into a descriptor
4c97cb3 - docs: keep the dash sweep out of the file it sweeps
a9d859e - docs: the build order for a clone that runs at a forced rate
e9b5d91 - docs: the design for running a clone at a rate the device does not declare
068a5a2 - gate: hold each chip to the window it advertises
43ecf6e - firmware: let the mouse-side chip restart the way it always did
d36c59b - firmware: put the mouse-side USB controller down before that chip restarts
6165e95 - firmware: ask for only as much as the chip can actually hold
8f1efa9 - firmware: hold the whole window the box says it will take
c9e5a55 - docs: say that abandoning a commit disarms both chips
4965827 - firmware: abandoning one commit abandons both, and the client could not clear either
493bb1a - firmware: tell the other chip too, and settle before erasing
ce01bc4 - firmware: only abandon an update while there is still something to abandon
898ff28 - firmware: what the third review found in the second round of fixes
a1a3075 - firmware: what the second review found in the first round of fixes
0bba54a - firmware: anchor every timer to the clock, not to zero
6f6728b - docs: match the renamed client call
c08bba0 - firmware: read every elapsed-time check as signed
c07b370 - tools: what the review found in the reference client
d03ca93 - firmware: what the review found in the update path
ac065b0 - tools: one command to push firmware to a connected box
211c39f - docs: how an image reaches each chip now
4711a91 - tools: prove a broken image does not stick
20965e3 - tools: a gate for taking an image over the control port
a9f26b8 - firmware: ask the far chip for its version until it answers
1da1093 - docs: record what the hardware corrected in the update design
9dbabfc - firmware: keep the clone down while the box rewrites itself
20a4807 - firmware: serve an update on the control port and pass one along
0a1d078 - firmware: let the mouse-side chip take an image over the internal link
a37c3b2 - firmware: put the box down cleanly before it rewrites itself
161bbce - firmware: write a staged image to the spare slot
1f31d89 - firmware: the chunk sequencing behind a staged image, with its tests
a139518 - firmware: the wire shape for taking an image over the control port
1afe07e - firmware: give both chips a second app slot
a22f3c1 - docs: the host chip gets one rom flash, and it has to be the right one
e14b65a - docs: the work order for updating over the control port
de9c107 - docs: the design for updating both chips over the control port
edbd2ef - docs: the G502 answer is not random, it is before-first-motion
8944b4c - docs: point the work order at what actually shipped
b36bd88 - docs: record what the review corrected in the at-rest rule
88c9289 - docs: say which fields the spec pins and which only look pinned
cb4cd80 - firmware: trust only what the descriptor pins, and ask once at a device that answers
bc6d4ee - docs: where an at-rest report comes from, in order of preference
80bef6d - firmware: ask a device once, and bring it back if the question stops it answering
e694922 - tools: a gate for a device that stops answering when asked
fe39acb - firmware: reuse a report the box already has before asking for one
7f8e023 - firmware: do not ask a device for a report its descriptor already spells out
f92d3b6 - firmware: work out from the descriptor what a report reads at rest
a3c6f8e - docs: the build order for deciding when a device needs asking
d88e6e5 - docs: decide from the descriptor whether a device needs asking at all
e0b4c26 - docs: why a receiver falls into its bootloader behind the box
6cfccd4 - fix: a full key bitmap made a receiver's paired mouse report as a keyboard
03f5d3e - docs: name the mechanism in the protocol reference and the comments
5fc4378 - docs: correct what a discard, a refusal and a saturating gain actually do
ccf4f60 - tools: validate the motion flags, and pin what the last round fixed
282386b - tools: stop a mutating verb defaulting to the destructive value
6ea1bb0 - firmware: make a bearing clear actually clear, and keep the aim's angle
0e59085 - docs: write down what the box applies, not what it was told
85adde4 - tools: make a bearing gate that a plain sign lock cannot pass
252e352 - tests: pin the weighing rules a mutation can still break
32603dc - firmware: weigh a report only when the scale actually changes it
13d1106 - tools: stop the puller before closing the port it writes to
698a65f - tools: measure what the bearing does to a hand, not what it reports
125d7c2 - firmware: let a button store the block it renders, not the number sent
0895364 - firmware: re-read the version header when it changes, not once per build tree
6c56608 - tools: validate a scale by hand, not only a lock
9a15813 - firmware: let a lock keep a fraction of an input instead of all or none
19606fe
Library
- ci: check the features this crate actually has, and do not ship wheels for a crate that did not publish
5ed374b - library: mirror the interval the box now advertises, and format
66f588e - library: what the review found in the forced-rate surfaces
ee75bd6 - library: check the forced rate round-trips on a real box
06b2435 - bindings: carry the forced rate through the C and Python surfaces
d31e06b - library: set and read the rate a box advertises
94d2cec - library: shorter refusal text
bc78c27 - library: say what a refused update means and what to do about it
5cb91b6 - library: derive the result-name guard instead of listing it
cdca871 - library: clear what a refused commit left armed
0a6dc24 - library: drop a reply the box has moved on from
74b6e09 - library: look for a parked reply on every wake
5606b85 - library: park a reply for the caller it belongs to
cc701a1 - library: put back a reply that answers another caller
2df1b87 - library: what the review found in the update client
0b7cafd - library: formatting
ee4567d - library: update box firmware over the control port
b2b43f6 - docs: name the mechanism in the public API surface
f1fdc4b - capi: refuse a byte no constant names, everywhere one crosses
34747d2 - hw_full: assert what only the firmware can satisfy
cb8f075 - bindings(python): check a scalar before ctypes truncates it
8826d5a - capi: take a byte where the boundary cannot trust an enum
d80ce4b - crate: model the box's lock table so a reapply rebuilds what it found
2c98fac - crate: say what the scale readback actually promises
d2574c3 - hw_full: prove the scale round trip and the bearing option on a box
78db22f - v3.2.0
da8d355 - bindings(python): follow the C ABI to the scale system
8bb2c5b - capi: carry the scale and the bearing across the C boundary
ed65e1d - crate: let a lock keep a fraction of an input instead of all or none
e179bcb
Docs
- dashboard: let the manual flasher be manual, and size the secondary buttons like the rest
e643106 - dashboard: keep the step chip, and stop the diagram forcing the gap above it
54d3a70 - dashboard: put the step in the header instead of a row of its own
041af30 - dashboard: even the gap either side of the step counter
c769401 - dashboard: let the card header own the step counter's spacing
0a21b47 - dashboard: give the step chip its own gap, and say the reason once
f8851e0 - dashboard: set the device port apart from the two computers
86fa2a2 - dashboard: one diagram per action, and cut the filler
4ed10e7 - dashboard: judge each chip on its own version, and tests that can actually fail
324cc80 - dashboard: a finish screen that could not finish, and the update path nothing tested
7996f79 - dashboard: stop claiming a check that never ran, and cover the page that had no tests
5a29691 - dashboard: two fixes that cancelled each other, and four more blind tests
1c4c470 - dashboard: the wrong chip named, the slow read, and three blind tests
397baba - dashboard: the button beside the socket, and what round four found
d224f71 - dashboard: the page freezes and the skipped gate that round three found
c0ec1ef - dashboard: what reviewing the fixes found in them
ce8f568 - dashboard: what three reviews found in the setup path
de0efd7 - dashboard: a guided first install, and a connect that says what is wrong
9992bc6 - dashboard: turn a failed connect into one answer, and say which firmware gave it
0c952e7 - dashboard: name the wire rate in the card's own heading style
cac69b8 - dashboard: build the wire rate the way every other control on the card is built
c078168 - dashboard: give the wire rate the card's own spacing, and name the two rate fields apart
260a4e9 - dashboard: apply the forced rate the user actually asked for
55b2243 - docs: the rate a box advertises is now something you set
fbfe5de - dashboard: refusal text that reads like the rest of the UI
a53ca34 - dashboard: errors that say what to do
f40db50 - dashboard: adopt a port that is already open, and say the window is not fixed
e108e85 - docs: write the update pages the way every other page is written
7d6fd66 - docs: put the update feature where the rest of the docs keep things
42efafd - docs: say that abandoning a commit disarms both chips
86c2a10 - dashboard: make the typecheck gate able to fail
88f8787 - docs: list the new result where the results are listed
8a7bb6c - dashboard: typecheck what the bundler never looked at
c835fea - dashboard: clear what a failed update left behind
aa668f7 - dashboard: keep the real cause when a port goes away
24c8e42 - dashboard: do not consume a reply from an abandoned transfer
a2f10f8 - dashboard: do not lose an update reply that arrives early
b9d383a - docs: say which flashing path is the normal one now
009a9a4 - docs: the library calls for updating a box
2209088 - docs: a page for updating a box over the control port
b410928 - dashboard: update both chips over the port you are already connected to
9cfdd68 - dashboard: speak the firmware-update protocol
2f2deb1 - docs: say where a lock readback can disagree with what the axis does
e30951b - dashboard: keep a readout's rows together
64f7075 - dashboard: give the riding checkbox the margin its siblings have
33ccc30 - Revert "dashboard: let the container own vertical rhythm, not the child"
ed9526e - dashboard: let the container own vertical rhythm, not the child
99c812d - dashboard: stop restating the reference in the control panel
2361d38 - dashboard: pin that the release-on-silence fact is stated once
629aeba - dashboard: one sentence per control on the control page too
9ecc171 - dashboard: put the bearing Turn off button back
d67a9e1 - dashboard: one sentence per option, and one shape for every control
58977c9 - dashboard: say why a connect failed on the control page
3690611 - docs: name the mechanism, not the picture it makes
c5bfc00 - docs: hold the rest of the reference to the bar the lock page set
dc0016f - docs: rebuild the lock page in the shape the rest of the reference uses
5a46100 - docs: correct what a saturating gain does, and make the client claims true
bc998d7 - docs: split the lock page, and say what the bearing actually does
660454e - docs: say each thing once, where the reader is looking for it
2aa0d86 - docs: carry the scale, the aim and the version the pages describe
45169ab - dashboard: drop a lock entry the box would never have named
7ef46d8 - docs: correct what Both does, and warn where the version cannot
ef59816 - docs: document the scale and the bearing across every page they reach
fbf8811 - dashboard: put the scale and the aim bearing on the control page
80bbf96 - dashboard: follow the lock wire from a state to a scale
3bf110d
v3.1.0
Changes
- CATCH now observed every class of traffic, not just input
- Catch events carry the timestamp the report actually arrived
- Vendor specific interfaces are now relayed correctly, instead of being presented dead
- Alternate settings are now followed all the way to the real device
- Devices with multiple configurations are correctly described and can be switched to
- Added support for control endpoints above 0
- HID interfaces that declare extra endpoints are now driven (instead of being refused)
- Extra-large report descriptors are now correctly carried, via any interface
- Added a per-command movement riding override
- Fixed low-speed device support
- Fixed keyboards that split their keys across several reports
- Fixed key reports corrupting on an endpoint shared with a mouse report
- Fixed control frames being silently dropped whilst the box was emitting
- Fixed blanket lock axis doing nothing
- Fixed some devices reporting as the wrong KIND
Notes
Security got a HUGE improvement this update, IMO this is pretty close to the limit of security for this hardware. Additionally, many more devices are now supported due to massive improvements in what can be cloned faithfully
CATCH is the other big one this release, it has received a massive overhaul, and now supports a wide range of functionality
https://medius.k4tech.net/library/catch
Keep the feedback coming lads ๐ซก
Show commits
Firmware
- docs: the design behind the per-command riding override
4aa8246 - tools: a gate for what riding delivers, and what it holds back
4598c8b - tools: two tools had been sending move frames the box throws away
269decb - firmware: let one move say whether it waits for the user to move
d9da046 - docs: say when a clip trigger takes its input lock, and when it does not
e3790a7 - firmware: lock every axis when the blanket asks for it
c8598cd - docs: write the catch design doc without the dashes
3ce7a00 - docs: the design behind the catch API rework
5b82fe9 - firmware: charge a lost event to every subscription it belonged to
f691b7b - tools: leave the rig on a device the other gates can actually exercise
54750b7 - firmware: make a snapshot say which class and which edge produced it
c2f4760 - firmware: hold back only what can flood the link, and let the waits be short enough to matter
375267f - firmware: make the clock estimate say what it actually knows, and the tests able to tell
003518e - docs: say what the counter orders and what actually holds input early
e791ae4 - firmware: keep the observation stream from making an input report late
f5ab3a7 - tools: a conformance gate for the observation surface
6eee30a - firmware: keep the busiest observation work off the core the USB stack needs
1877297 - firmware: carry the crash record's caller chain, and keep the rig off the desktop cursor
52c70ad - firmware: wake the drain directly instead of through a shared counter
bcdea80 - firmware: read the observation table without locking the paths that read it most
cce63f1 - firmware: pace the event stream to the link instead of spinning on it
8219d3d - firmware: keep the event stream from stalling the link it shares
255569e - docs: document what can be observed and which clock stamped it
0f132a6 - tools: prove observing the traffic does not disturb it
39fb9c0 - firmware: observe every class of traffic the box carries
bfbed83 - firmware: hold the observation subscription as a table, and rank its event stream
cb46f50 - firmware: stamp bulk where it arrives, like every other inbound stream
7c8ca4b - firmware: a four-stamp exchange so the two chips' clocks can be compared
619e26f - tools: teach the reference client the new observation surface
9694782 - firmware: measure the two chips' clock difference instead of assuming it
380864b - firmware: address what to observe the way locks are addressed
c7c200c - docs: the implementation plan for observing everything the box carries
52d3182 - docs: tap emitted reports where they complete, not where they are staged
59c8542 - docs: a design for observing everything the box carries, not only physical input
96ee0f4 - docs: a top-level guide so the repo carries its own bring-up knowledge
6bb87dc - tools: prove the descriptor half of the configuration cost, on hardware
11b67c1 - firmware: cost the configurations the clone is not in, not just the one it is
b23f831 - firmware: the faults only repeated switching could reach
bc626ca - firmware: rebind the roles a configuration switch moves, and hold every configuration's descriptors
8092fd6 - firmware: a configuration switch rebuilds what it changes
3d72c39 - firmware: the rest of what the reviews found
e346dc6 - firmware: a marker that is a prefix of another could never be seen missing
3c5215e - firmware: defects a review found, including two the previous round introduced
368fb59 - firmware: carry the report descriptors a configuration switch needs, with the switch
76e3a12 - firmware: enter any configuration a device offers, not only the one it came up in
b262349 - firmware: carry a control data stage larger than one link frame
62b41b1 - tools: count the bytes on every endpoint a shape exists to exercise
7a7c042 - tools: make the hardware oracles able to fail
2853b1d - firmware: defects found reviewing the rest of the interface-coverage work
fcfbd14 - firmware: defects found reviewing the control-endpoint work
7050f85 - firmware: carry a control endpoint a device declares beyond the first
df18d25 - firmware: name the control endpoint above zero, and teach the port to hear it
a1c527d - firmware: describe every configuration a device has, not just the one it is in
cccaa2d - firmware: follow the alternate setting a host selects, all the way to the device
51bb6d0 - docs: why the alt-setting relay is asynchronous
cd6ed02 - firmware: drive the endpoints a HID interface declares and its driver ignores
f8a0d11 - firmware: carry a report descriptor the device actually has, from an interface of any class
ab95091 - docs: design for retiring every refusal the hardware does not force
b29edaa - firmware: a control transfer too big to buffer hung the clone instead of failing it
66580fc - firmware: the two chips disagreed about which interfaces they serve
eba56a3 - tools: the refusal ladder had no test that ran it
c9f688a - firmware: an audio device cloned in silence, minus the half that mattered
ae6014e - firmware: a HID interface could declare an endpoint the clone never feeds
866ff13 - firmware: a clone answered questions about configurations it does not have
90e3d13 - docs: the vendor bulk ceiling is measured now, not estimated
7814fb3 - docs: the vendor-interface pass-through design
0494a35 - firmware: vendor-specific interfaces were declared to the PC but carried nothing
446b93f - firmware: a rejected hunk could still report itself applied
9ece3cc - firmware: defects found reviewing this branch
d0a5751 - docs: the low-speed frame-interval fault, and finish a truncated sentence
5584bbe - firmware: low-speed devices were told the bus was idle on every frame
6d28b89 - firmware: one keypress read as three on a keyboard that splits its keys across reports
c3c4aa3 - firmware: the previous commit changed no behaviour; say so
82d9c02 - firmware: log which firmware image is actually running
e5add6f - fix: device kind was decided by interface order, not by what the device sends
b91235b - fix: queue overflow dropped the newest report on one of two paths
5459acc - fix: report-ID budget counted Feature reports it never needed
a38482c - Revert "surface reports cut short mid-transfer"
bedda73 - fix: key reports corrupted on an endpoint shared with a mouse report
cf55d44 - docs: low-speed clones now match native bus speed
2d0077f - tools: screen HID devices for multi-packet reports
b0e1a84 - fix: low-speed device support on both chips
ac5a647 - docs: compress the protocol timestamp note
4195634 - docs: spec matches the wire-width crate surface
7224a5d - docs: usage-event timestamp capture from the bench
694a185 - tools: revive the lock validator and poll for ROM download
20f668d - docs: native jitter baseline for the timestamp accuracy oracle
3f73ce6 - docs: record the bench device's measured report families
3d31dbb - firmware: catch events carry the report's arrival timestamp
0722057 - docs: timestamped catch events design spec
644ea05 - revert: drop the QUERY(LINK) selector
283e47c - fix: defects found reviewing the control-link work
4a2962f - firmware: drop the emit-path blocking histogram from RESP(LINK)
6307db2 - firmware: RESP(LINK) reports only the window it can measure exactly
8974cf2 - v3.1.0
0b4e07e - tools: control-link loss rig, scripted host flash
5e0cc83 - firmware: control frames survive a busy emit path
3a1a72b
Library
- bindings: carry the move override through C and Python
e0975ce - crate: let one move say whether it waits for the user to move
35034c2 - docs: strip the dashes and the padding out of the reference
ecfab01 - crate: address an input the way a lock does, and hand back the edges
c6f5ca0 - crate: refuse a subscription the box cannot hold, and send only what changed
b341abf - hw_full: measure the sustained rate, and drive the traffic a still device will not
39cc619 - crate: route a held-usage snapshot as the class state it is, and mirror it in C and Python
ce3a72e - crate: expose the protocol version, and stop asserting quiet on a streaming clone
8ee86f3 - hw_full: check the per-id observation path on hardware, not only the blankets
344230a - crate: route each observed input event by the address it actually carries
3cfb471 - crate: give each observer only the traffic it asked for
c6ea88c - bindings(python): follow the C ABI to version 4
6bbe0cf - capi: carry the observation surface across the C boundary
911eb2f - crate: observe every traffic class, not only physical input
cd50aca - capi: hold the ABI version at 3
7ce742b - v3.1.0
956d9c1 - refactor: hand the catch timestamp over at its wire width
8b642b5 - refactor: match the crate's idiom in the catch clock widener
72e76b1 - feat: catch events carry the report's arrival timestamp
81118e6 - v3.0.1
f6b4dd1 - fix: stop Windows injection queueing behind the reader thread
7ba7c4c
Docs
- docs: check the rest of the pages this feature touched the same way
6f6d350 - docs+dashboard: follow the patterns the reference already has, on the pages this feature touched
fdc3b21 - docs: document what a move can say about waiting
9bb4f27 - dashboard: drive the riding override from the control page
a3e52c4 - docs: index the names the catch rework introduced
3e2ed8b - docs: index the dashboard cards search could not reach
737249f - dashboard: name the clip trigger flag in full on the checkbox
a59bf55 - dashboard: call the clip trigger flag what the protocol calls it
a60a88e - dashboard: open the clip trigger picker on the class its own list leads with
96b1eca - docs: describe a clip trigger's input lock by what it does
5f03e36 - dashboard: rebuild the control page around what the box can do
08e613c - docs: cut the documentation down to what it actually says
f4d9e68 - docs: stop the reference justifying what the table just defined
b7a1698 - docs: stop the tables saying their own column headings
2753832 - docs+dashboard: document the catch surface as it is, not as it was
f43090c - docs: a table that is full, and who a lost event is charged to
a1a4b14 - docs+dashboard: say which edge produced a snapshot, and how to route one
8f9f0e0 - docs: document the protocol version a build speaks
5ee0d93 - docs+dashboard: say which class a snapshot names, and what an unfitted drift rate means
ee104d3 - docs: correct what the event counter means and how the stream is ranked
d43d7bb - docs+dashboard: document and display every traffic class the box can observe
1bad5f4 - docs: repoint two search entries at the anchors that exist
e3b9ca8 - docs: ABI displays back to 3
81c9e65 - docs: crate and ABI displays for v3.1.0
55387ed - docs: firmware displays to 3.1.0
4ef0046 - dashboard: decode the catch timestamp instead of reading it as motion
90cc283 - docs: ts_us belongs on the frame that carries it
37146b0 - docs: trim the timestamp cards to reference-only
3026e95 - docs: rebuild the timestamp cards as diagrams and tables
da0dc25 - docs: correct the mock inbound-traffic card subtitle
1b2c016 - docs: catch events carry the report's arrival timestamp
bd40044 - docs: crate version displays to v3.0.1
981a99e
v3.0.1
Changes
- Fixed a bug with the lock system where events could report through a lock if other conditions were met
Notes
Keep it coming
Show commits
Firmware
- firmware: classify falls open on report shapes it can't model
73d0dbd - firmware: a locked input emits nothing instead of an empty report (v3.0.1)
7abc2a8
Docs
- docs: firmware version displays to v3.0.1
9f6257b
v3.0.0
Changes
- Unified mouse buttons, keyboard keys, and media into a single input model
- Added buffered clip playback
- Added on-device clip triggers
- Added retained clips with looping replay
- Added per-clip auto-lock
- Clip triggers can be consumed to never reach the target pc
- Added persistent box names
- Added AI support for documentation
Notes
Buffered clips and the on-device trigger system is documented here: https://medius.k4tech.net/library/clip
Buttons, keys and media are now a unified "Usage" across the whole api, you will need to update your code if you are using any of the libraries
Keep the suggestions coming
Show commits
Firmware
- docs: update README control-surface to proto 3 (MOTION_EVENT/USAGE_EVENT, CLIP_SET/CLIP_TRIGGER, 10 query selectors)
d495261 - ci: split the Discord release changelog across messages over the embed limit
b26bdea - docs: control-protocol clip trigger set + config + RESP(CLIP) rewrite
8d02390 - tools: refclient clip trigger set + config, new RESP(CLIP) decode
3d2ca96 - firmware: clip trigger set, retain/rewind engine, and queryable config
feefbe2 - docs: clip trigger + config redesign spec and plan
c872c0c - cleanup: strip comments and AI-slop from host firmware, common, and docs
4bde84e - cleanup: strip AI-slop and comments (tools, host tests, protocol doc)
26a0a08 - cleanup: strip firmware comments and AI-slop
9eaea0b - medius.py: one usage vocabulary for inject and lock
8027a85 - docs+comments: proto 3 wire spec, RESP(CATCH) media bit, stale event-name comments
5f1f6dc - v3.0.0
e939e75 - medius.py: decode the clip held-usage snapshot in RESP(CLIP)
b1b60ca - firmware: report clip held state as one usage snapshot, not a button bitmask
0321ece - firmware: one catch event shape for every input class
9b79c45 - firmware: uniform LOCK addressing and a full lock-state readback (proto v3)
d3d536b - firmware: one inject verb and one synthetic-emit path for every class
093d3f8 - firmware: unify the HID injection core on one momentary-usage model
30e27fd - docs: input-taxonomy unification design
8dc8f7d - firmware: field-generic clip control with an autolock scope
f977fb5 - firmware: clip STOP releases held input; auto-lock owns locks per direction
f76849e - firmware: clip auto-lock locks all input, drop the lock-mask
3ad676c - firmware: buffered clip playback drives keyboard and media, not just the mouse
255ebd3 - docs: note buffered clip playback in README, ARCHITECTURE, tools
2c2a9c7 - docs: correct clip overrun semantics + crate API reference
979db9b - firmware: harden buffered clip playback (adversarial review)
e8909fd - firmware: clip reference client + protocol doc
752fc28 - firmware: clip playback engine + command dispatch
92fb50f - firmware: CLIP protocol constants + status packer
c99630c - firmware: clip SPSC byte ring (host-tested)
39d2651 - firmware: clip entry codec (host-tested)
252df80 - docs: buffered clip playback implementation plan
3e29317 - docs: buffered clip playback design spec
17f8cd0 - firmware: persistent, host-settable box name
671afbe
Library
- docs: fix README to the v3 unified-usage API
0a34b65 - fix: repair crate CI for v3
9eaed71 - hw_full: correct stale proto assertion and grab all composite clone nodes
e724e36 - python: clip trigger set + queryable config bindings
59b2682 - capi: clip trigger set + queryable config C ABI
0663193 - clip: trigger set, retain/rewind, and queryable config surface
89c5521 - cleanup: strip AI-slop from README and a stray doc-comment
5f5b08e - cleanup: strip unnecessary comments and AI-slop (crate, capi, python)
db05194 - finish the builder unification + align the usage id field
dc0b940 - bindings: rename MediusInput to MediusUsage (one Usage vocabulary)
9c9bbd7 - review: LockScope sum type, shared usage codec, safer conversions
7657b2b - v3.0.0
b2f684c - hw_full: v3 handshake + correct the clip/lock/name checks
65ec4a7 - host: clip held state is a usage snapshot across crate, C ABI, and Python
cf2befe - python: unify bindings on the Input usage taxonomy (ABI v3)
b8eaab3 - capi: unify the C ABI on the Usage taxonomy (ABI v3)
3659dee - crate: unify the input API on Usage and Axis (proto v3)
0676994 - clip: ClipConfig options type + field-generic control API
6ac4187 - clip: held is a per-button bitmask; enforce the edge cap; validate C edge actions
c47cfb1 - crate + C ABI + Python: field-generic clip reuses existing types
a7158f3 - docs: buffered clip playback section in the crate README
5a5f16f - crate + C ABI + Python: buffered clip playback
05728aa - crate + C ABI + Python: box name
19c9f17
Docs
- docs: update README to the v3 API (opcode range 0x15, all 5 sections, input-passthrough, drop dead MidnightUI link)
7339e79 - chore: shorten server.json description to the registry 100-char limit
8474b06 - chore: MCP registry manifest (server.json) + publishing guide
3b74cc5 - docs: demonstrate a move and an edge on one clip frame, all four surfaces
e9d7574 - docs: move AI page to its own /ai section, add dropdown link
12a3ef9 - docs: fix clip reconnect claim and clip-query section polish
bfc3014 - docs: lay out the clip streaming/retained and trigger sections visually
42973bd - docs: add the AI & LLM access page
6ec7aea - feat: advertise MCP, cache headers, rel=alternate, prerender Home
b8c01e5 - feat: ChatGPT-compatible search/fetch MCP tools
6600245 - docs: fix the AI-actions menu button font
49f6ff3 - fix: review findings (head defaults, search cap, route decode)
275e7f4 - feat: serve the agent surface under vite dev and preview
fa14b49 - ci: prerender stage in Docker, tests in CI, prerender scripts
8044820 - feat: move AI-actions to a titlebar dropdown (portaled)
8fd103e - feat: per-route head + AI-actions row + SSG double-mount fix
b4a4dc7 - fix: harden markdown extractor (review findings)
4b3e76d - feat: remote MCP docs server on /mcp
2db15e8 - feat: agent content-negotiation in the Bun server
c58e47f - feat: build-time prerender + markdown extraction pipeline and agent artifacts
0e254db - docs: link the clip queries from the Clip page, like Lock and Catch
cdd428d - docs: agent-accessible docs design spec
3b67739 - docs: move the clip queries onto the Requests page with the others
205b7de - docs: full page-by-page consistency pass across all 78 pages
79f41fc - docs: fix broken binding anchors + em-dash labels, mirror c/python clip API
5294fa5 - docs: tighten the clip page to the sibling norm
82db2b0 - docs: fix clip content + anchors from the migration review
9ecaf50 - docs: clip trigger set + queryable config across the SPA
86a81be - docs: add the missing CLIP entry to feature-index enumerations
950e079 - cleanup: strip AI-slop and narrating comments from the docs-SPA components
2a82ba0 - docs: dashboard UI copy pass (terminology, labels, one diagram prop)
9555b82 - docs: page-by-page quality pass (dedup, links, diagram redraws)
18fee2f - docs: finish the builder + field-rename propagation, ClipState meaning tables, reconnect badge
265cdff - docs: apply deep-review findings + propagate the Usage rename
52ab2c5 - docs: v3.0.0 / proto 3 version references
6db69c3 - docs: unify the input taxonomy across the reference and dashboard
39b49e5 - docs: field-generic clip control and ClipConfig
89ae248 - docs: correct clip status held (button bitmask) and ticks (content-only)
373f8f8 - docs: rebuild the clip pages to match the rest of the docs, diagram-first
831879d - docs: rewrite the clip pages, field-generic and terse
be75744 - docs: buffered clip playback
ea11667 - docs + dashboard: box name
1ed73a2
v2.3.2
Changes
- Fixed an inconsistency in the locking behaviour
Show commits
Firmware
- firmware: soft-release clears a force-release, not just a press (v2.3.2)
da24f52
Docs
- docs: soft-release defers to physical from any state; version strings to 2.3.2
5e2d10a
v2.3.1
Changes
- Fixed lock and catch occasionally binding to the wrong interface on certain mice
- Lock and catch logic now applies across ALL applicable interfaces, not just the first
- Injection now prefers the boot interface for certain mice
Notes
These changes should hopefully fix some inconsistencies some people were having with the injection/lock/catch logic
It may also improve device support for certain devices
Please keep the bug reports coming, I'm committed to fixing as much as a physically can
Show commits
Firmware
- firmware: catch and lock cover multi-interface mouse dongles (v2.3.1)
8a3c63f
Docs
- docs: update firmware version strings to 2.3.1
3d77801 - docs: correct the stale crate version (2.0.0 -> 2.3.0)
1886e43 - docs: bare-symbol card titles for discovery + a few consistency fixes
8c88a19
v2.3.0
Changes
- Added emission rate control (Learnt rate (default), Interval (bInterval based), Fixed)
- Improved HID capture on erratic enumeration
- Clone is now only emit after full enumeration (or timeout)
- Multi-box support, more detailed box descriptors
- Device info now carries more information about the connected device
Notes
Emission pacing control can be found in the documentation: https://medius.k4tech.net/library/options#set-emit-pace
Discover by device type and similar multi-box steps can be found here: https://medius.k4tech.net/library/discovery
Show commits
Firmware
- firmware: self-heal a control decoder wedged by an abandoned partial frame
abb0c95 - docs: sync the control-protocol reference + READMEs to the DEVICE_INFO rename (kind, product, box MAC)
64dd946 - firmware: name the DEVICE_INFO product-tail cap (127) so host string buffers keep NUL room
dc36571 - tools: multi-box discovery (list / open-by-id) + generic device_info in the reference client
bd283dd - firmware: VERSION carries the box MAC; MOUSE_INFO -> generic DEVICE_INFO (+kind, +product)
691aadb - docs: plan multi-box + generic device-info
80a07bd - docs: spec multi-box management + generic device-info
406a80a - host: robust HID report-descriptor fetch (blind-fetch + retry, verbatim)
1158d0a - host: emit the clone snapshot once all HID interfaces are captured
f2642eb - host: count HID interfaces in a config descriptor (for capture completion)
35ba281 - docs: plan the capture-robustness implementation
065ba8d - docs: spec capture robustness for slow composite HID devices
7c1237b - Bump version to v2.3.0
307c21e - tools: harden the emit-rate test + validation rig
998cd72 - firmware: reset the interval emit-rate when the device detaches
faa0ee0 - tools: emit-rate HW validation rig
02da0af - tools: emit-rate option in the reference client
8c3ed75 - firmware: wire the emit-rate option command + query
fbda1e0 - firmware: emit-rate pacing override (state + gate)
7351086 - firmware: add the emit-rate option to the control protocol
7fcdb74 - docs: plan the emit-rate option implementation
b5151ce - docs: spec a selectable emit-rate option
d347419
Library
- style: cargo fmt
345ad1e - crate: discover example (enumerate boxes + open by kind/id); gate open_transport to the mock build
abcfe0e - capi + python: device_info (+kind +product) + multi-box discovery (list/open_by_id/find_*_box) + version MAC
f642a95 - crate: multi-box discovery (list/open_by_id/find_*_box) + reconnect by identity; device_info replaces mouse_info
8480595 - Bump version to 2.3.0
d2f3a86 - mock: match the firmware's emit-rate snapping
1eb5851 - emit-rate pacing: C ABI + Python bindings
6d9ab05 - emit-rate pacing API
93b19fc - bindings(python): add a README and use it as the PyPI long description
d304bea
Docs
- docs: update example version strings from 2.2.1 to 2.3.0
9eeb739 - docs: bump docs site to v2.3.0
97a25f3 - dashboard: flush a wedged box decoder before retrying the handshake
7529503 - dashboard: capitalize the device-kind chip, make the emit-rate radio vertical to match the others, and group Box id with the identity rows
95124f5 - docs: add the mac field to mock Version examples; correct is_composite to n_hid>1
c61e317 - document multi-box discovery + generic device-info (kind, product, box MAC)
72f81a7 - docs: rewrite the native Options page table-first
f78e1e5 - document the emit-rate option
218cf4e - dashboard: add the emit-rate option control
39146b2
v2.2.1
Changes
- Added C/C++ bindings
- Added Python bindings
- Hardening of release binary
- Improvements to documentation
Notes
Documentation for the new bindings can be found here: https://medius.k4tech.net/bindings
This was a required step so other developers can start utilising Medius, now I can start implementing more features/functionality
Make sure to keep the suggestions coming
Show commits
Firmware
- firmware: binary hardening (v2.2.1)
da48813 - release: drop the parenthetical from the Library changelog header
50d2233 - release: combine the 3-repo changelog and attach a bin zip to Discord
9157dd8
Library
- bindings(python): add a README and use it as the PyPI long description
d304bea - ci: drop sccache (measured ~no gain) + the redundant host rust reinstall
47ab1dc - ci: cache the wheel Rust builds with sccache (GHA backend)
e1ad8b3 - ci: aggressive caching to cut CI time
32fa151 - ci: attach only wheels to the release, not the sdist
dc1fdde - ci: export MACOSX_DEPLOYMENT_TARGET=11.0 to cibuildwheel so delocate accepts the macOS wheels
772f1ce - ci: pin macOS deployment target so the x86_64 wheel passes delocate
6de7f4c - ci: wheels match the C tarball platforms (drop i686, add macOS x86_64)
5bab67e - ci: skip-existing on PyPI publish so a re-dispatch is idempotent
ff4fa90 - ci: fix the crates.io version check (User-Agent) + attach wheels to the release
8940488 - ci: build all 5 C ABI tarballs + add a manual backfill path
cc0dcac - ci: merge the C ABI + Python checks into ci.yml; gate the release on them
fc94810 - ci: drop the unavailable macos-13 wheel runner
146fc21 - release: bump the crate, C ABI, and Python binding to 2.2.1
17f04ba - bindings: drop the C++ wrapper; the C header serves C and C++
336b4d4 - test: cut drift โ src/tests covers only what hw_full can't reach
ab361dd - Drop the docs/ directory โ docs live in the medius-docs repo
1c3d127 - review: cut slop and dedupe across the bindings
1d2cd64 - docs(bindings): drop DIFFERENCES.md for a short README section; trim prose
079731d - bindings: drop the Conan recipe / vcpkg plan
04e8cf8 - ci: fold the bindings release into the crate publish flow
4ff3da7 - ci(wheels): install libudev in the manylinux container; skip musllinux/win32
5b6c99f - bindings: deviation doc + publishing (PyPI, C/C++ release assets, Conan)
eedbae9 - bindings: restore the Clone capability (Device/streams/MockBox)
c78696e - docs: bindings README + main README pointer to the C/C++/Python bindings
d044b5f - ci: build/test/lint the C ABI + bindings; fix the publish version check
6a21cf9 - bindings(python): self-contained sdist, py3-none wheel, API fixes
20beb94 - bindings(python): ctypes package over the C ABI + wheel packaging
d3a652e - bindings(cpp): header-only RAII C++ wrapper over the C ABI
00b5c36 - capi: cap catch-event key count at u8::MAX so it can never wrap
95f8113 - capi: C ABI crate (medius-capi) covering the full medius surface
2eeadb8 - docs: design spec for the C ABI + C++/Python bindings
cb6919b
Docs
- docs: de-AI the binding prose and set version strings to 2.2.1
478e9ec - docs: syntax-highlight code blocks with Prism
e009fb4 - docs: bindings section for C/C++ and Python
49fede4 - dashboard: render the grouped per-repo changelog headers
9123bc2 - docs: add a Discord link (top-bar button + search)
52cfbc9
v2.2.0
- firmware: enforce the no-radio guarantee with a build guard + document
1483d70 - Bump version to v2.2.0
22b2ced
v2.1.0
- Feat/options movement riding (#13)
e657212 - research: note report-density is sensitivity-dependent (no absolute human threshold)
0b4d928 - research: movement-injection detectability rig + findings
781ff2d - Revert "ci: cache the esp-idf docker image"
2982ef5 - ci: cache the esp-idf docker image
31ef02e - ci: cache ccache across firmware builds
de14333
v2.0.1
- Gate verbose diagnostics behind the dev build flag (v2.0.1)
f4f6074
v2.0.0
- Unified HID-input core (inject/move/lock/rate, faithful EP0 proxying) (#12)
da90ef9 - Keyboard support P1 โ injection state into a per-target table (#8)
70bbdd3 - Keyboard support P0 โ parser learns keyboard fields (#7)
9f949cf - fix(keyboard): follow the active interface for catch + inject
cb89c70 - docs(protocol): keyboard + media (KEY/CONSUMER/KB_EVENT/CONS_EVENT, KBD_CAPS, KEYS catch)
fca4e0f - Make the mouse protocol names explicit, matching KBD_CAPS / KB_EVENT
dee2484 - P5: note the variable-bitmap Consumer form is passthrough-only (review nit)
546ee25 - P5: media (Consumer) key inject + catch
3bf90ba - P5: parse the Consumer (media-key) collection
a1ee76a - P5: bind the richest keyboard interface, not the boot 6KRO
96ccf5a - P4: review nits โ widen NKRO run counter, fix stale catch comments
7f47dd9 - P4: keyboard catch โ generalize the catch pipeline in place
15c359a - P2: review hardening โ reserved keycodes, bind alias, suspend-safe release
992b1e6 - spec: drop send_text โ library stays semantic, no keystroke automation
f54ff65 - test: cover the keyboard control-protocol additions
3ff5aa9 - P2: wire keyboard inject into usbdev + control dispatch + medius client
6bae488 - P2 (wip): keyboard render core + protocol (host-tested)
57bfd90 - P1: injection state into a per-target table (mouse byte-identical)
4a605f9 - P0: keyboard field parsing (modifier / array / NKRO bitmap)
a0c24b4 - Add keyboard support design spec (v1.7.0)
61b0773
v1.6.0
- CATCH โ physical-input event stream (v1.6.0) (#6)
42bf371
v1.5.0
- LOCK โ block physical input selectively (v1.5.0) (#4)
801b1ea - Post the release changelog to Discord (#5)
1a32ae0
v1.4.1
- LED control (v1.4.1) (#3)
b85bb5b
v1.4.0
- feat: device-info requests (MOUSE_INFO/CAPS/RATE/STATS + RATE_CONFIDENT) (#2)
01207b2
v1.3.1
- rate: log/persist the realised emit rate, not the raw bucket centre
1c72990 - docs: sync reference docs with v1.3.0 (link watchdog/safety machine, drop dead PONG)
455f837
v1.3.0
- release v1.3.0
94ccf57 - docs: record the inter-chip link watchdog + safety machine (HW-validated)
2e6f224 - tools: link-watchdog HW validation script (idle stability, no-false-trip, strand-trip)
57ad484 - docs: sync link-watchdog spec/plan with review fixes
8f71df4 - fw: adversarial-review fixes โ dedicated lossy heartbeat task, drop dead PONG
dbd5303 - docs: link-watchdog safety design + implementation plan
d9b9d0e - host: ~100ms inter-chip heartbeat so idle links stay warm
ea44acc - device: inter-chip link-loss watchdog, safety clear on loss/detach
4c07124 - usbdev: unify the atomic clear as usbdev_safety_clear()
e9ef4fb - link: pure link-liveness watch helper + host test
920e674 - docs: bring DETECTION-RESISTANCE + ARCHITECTURE up to v1.2.0
6c2e39c
v1.2.0
- release v1.2.0
b73ae80 - fw: strip comment slop from the Tier-2 detection-resistance work
7f342c3 - tools: fix flash_device.sh for esptool v5 + target the device's 303a download port
3ea000d - fw: adversarial-review fixes (patch-harness silent-unpatched + ctrl-chunk race + drop-on-full)
d3dbbb2 - fw: B6 โ clone non-ASCII (raw UTF-16) string descriptors byte-true
e2fa27f - fw: interrupt-OUT endpoint forwarding
70a3804 - fw: B8 โ chunk proxied control transfers with a data stage >504 B
e96759f - fw: build-time CherryUSB patch harness + 3 core conformance fixes + host limits
f5ae094 - fw: iConfiguration/iInterface caching, snapshot forward-compat, multi-IN guard
40ce42d - fw: enum-safe empty-string fallback + wIndex check + audit doc updates
36dd316 - fw: EP0 device-feature conformance + capture stale-tail/empty-string fixes
a3a192f - docs: drop the "risky" framing from the host-chip flash
f5ffa35 - docs: reflect v1.1.0 native-rate injection pacing
6803c0a
v1.1.0
- fw: pace pure injection to the mouse's live report rate
44d26a8
v1.0.2
- fw: clone the BOS descriptor for USB 2.01+ mice
8159f29
v1.0.1
- release v1.0.1
8f1bc9b - fw: robustness fixes โ stream re-arm, snapshot re-send, enum recovery
dd34ba4 - ci: release notes are a commit list, not GitHub PR notes
46d613a
v0.1.0
Initial release of the Medius firmware.