Skip to content

Fix/spec overflow - #1

Open
Ludo-lab wants to merge 46 commits into
hjc2023:mainfrom
Jan-IngenHousz-Institute:fix/spec_overflow
Open

Fix/spec overflow#1
Ludo-lab wants to merge 46 commits into
hjc2023:mainfrom
Jan-IngenHousz-Institute:fix/spec_overflow

Conversation

@Ludo-lab

Copy link
Copy Markdown

Added the COMMAND 35, that estimate spectra according AS7341 AN000633, and adjusted way of getting PAR (non negative visible channels).

Ludo-lab and others added 30 commits June 17, 2026 14:29
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Merge the ambyte/cloud build variants into one image. First-byte router in
loop(): >127 -> frozen binary FSM, '{'/'[' -> openJII JSON envelope, other
printable -> legacy text console (what the openJII app driver and Calibratron
parse). Sticky host latch keeps light sleep for the ambyte and disables it for
non-retrying text/JSON hosts. Version is build-injected (tools/version.py) and
now reported identically by cmd 33/2, hello (FW:<semver>), and the JSON
identity; hw_rev claims a byte of the reserved cmd 33/2 slot.
PR titles (Conventional Commits, squash model) drive semantic-release. pr.yml
validates the title, builds with the previewed version injected, verifies the
version string is embedded, and uploads the artifact; release.yml publishes
the same bits as a GitHub release with a flash manifest (names, offsets,
sha256) so downstream flashers never hardcode the layout.
…-firmware

feat(fw): single-image firmware with runtime host routing and release automation
The v1.1.0 release failed because the subject regex only matched a squash
merge's "(#N)"; PR #1 landed as a merge commit ("Merge pull request #1"),
so no artifact could be located. Ask the API which merged PR contains each
of the last 20 commits instead, newest first, which also covers a direct
push to main following a release.
busy() treated any buffered byte as mid-frame. A client that terminates an
envelope with a newline (the openJII driver probes with
'{"command":"INFO"}\n') completes the JSON, resets, then has its trailing
\n appended in UNKNOWN mode: whitespace locks no mode, so rx stayed non-empty
with busy() true and the idle timeout - which only covered Mode::JSON - could
never clear it. loop() then early-returned forever and the device answered
neither dialect until power-cycled.

- busy() now means "a mode is locked"; with no mode locked the buffer can only
  hold whitespace.
- poll() no longer buffers a leading newline, and abandons a locked frame when a
  >0x7F byte arrives, so an ambyte wake burst is handed back to the binary
  router instead of being absorbed (each absorbed byte refreshed the idle timer,
  outliving the companion's ~1.25 s retry window).
- the idle timeout now covers any locked mode; LINE had none.

Also claim CONNECTION_TYPE=COMPUTER when routing to the text console: every
binary command latches AMBYTE and nothing cleared it, so plain `arrun` from a
text host ran with the ambyte sink still selected.
setup()'s esp_log_level_set("*", ESP_LOG_NONE) only gags IDF logging; the
Arduino ESP_LOGx macros compile to Serial.printf. Bench proof: a stray frame
byte made the router answer a host with
"[E][ambit-1.ino:215] loop(): [INO] Unknown cmd 171" instead of protocol
bytes, which is exactly the ASCII-before-a-binary-frame hazard AGENTS.md
forbids. CORE_DEBUG_LEVEL=0 removes the format strings entirely (verified
absent from the image) and drops flash 418 KB -> 397 KB.
This reverts commit fda6d46b3780392f13e9e9d2139405cc789be331.
This reverts commit 4c9b90fce36a6a1ed786e5b8c7baa5bef18e1dbd.
…r-stall

fix(router): never let a finished envelope stall the first-byte router
…cleanroom-rc4

chore(migration): import JII AMBIT continuation
…r-stall

chore(adpd): replace vendor SDK with JII clean-room driver
The public code tree was previously imported as a clean snapshot. This merge
joins the sanitized 24-commit JII development line solely to restore attribution
and topology. The histories began independently; this merge does not claim
earlier ancestry. Existing public source/build content and tags remain unchanged
except migration and audit documentation.
…on-candidate

chore(history): restore attributed private development record
…-readme-v2

docs(readme): document firmware operation and integration
dominikvrbic and others added 16 commits August 6, 2026 20:24
…pplication-v1.1.4

fix(calibration): apply persisted coefficients and baselines
…-asset-url

chore(release): validate draft asset namespaces
get_PAR() assigned `counts * Spec_COE_n` into a uint16, which wrapped rather
than saturated. Full scale is (ATIME+1)*(ASTEP+1) = 50000 counts, but the
weights (12,10,11,10,10,9,7,4,1,1) push the reported word past 65535 from
~11% of that -- F1 wraps above 5461 counts. A bright reading therefore came
back looking like a dark one, and since PAR was summed from those same wrapped
words, PAR collapsed with them: at F1 = 5462 counts the old code reported
word 8 and PAR 0.19 where the true values are 65535 (pegged) and 1573.

- Compute PAR in get_PAR_raw() from the unclamped counts in a uint32
  accumulator. Coefficients and operation order are otherwise untouched, so
  the result is bit-identical to the old one whenever nothing overflowed
  (checked over 100k non-overflowing vectors against the previous algorithm).
- Saturate the ten 16-bit channel words at 65535 instead of wrapping. A pegged
  value is monotonic and obviously at the rail; a wrapped one is silently
  wrong. Framing and the 24-byte length of cmd 31 are unchanged -- only values
  differ, and only under light that used to wrap.
- Add binary cmd 35 get_spec_raw: 0xA1 + 32 B + 0xF0 carrying the unscaled
  counts plus format/atime/astep/gain_low/gain_high/flags, so a host can
  normalise across exposures and detect saturation. Byte-explicit and
  naturally aligned, so it avoids the ESP32-default-alignment coupling that
  froze the cmd 33 structs. Additive: cmd 31 is untouched and pre-v1.2.0
  images are unaffected. Hosts gate on cmd 33/2, since an unknown opcode hits
  `default:` and draws no reply at all.
- Guard spec_meas.h, which was unguarded while it held only idempotent
  declarations and now defines a type.

The ambyte side is deliberately not updated yet; cmd 31 still answers exactly
as before, so deployed loggers keep working untouched.

Re-runs plans/HW_CONFORMANCE.md (logged in section 7, layout in section 6).

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants