32 KiB
Electrical tests
These procedures verify the Phase 7A OLED and buttons, MAX3243 breakout, UART1 data path, hardware flow control, and session broker. They are manual tests: the firmware never starts one automatically.
Safety: With power removed, install only the wiring required by the selected test. DE-9 pins 3 (
TX), 4 (DTR), and 7 (RTS) are driven outputs. Never connect one of these outputs to another driven output. Keep temporary Dupont wiring short and secure. Power the OLED only from 3.3 V because module-mounted I²C pull-ups may connect SDA and SCL to the OLEDVCCrail.
Phase 7 OLED and button bring-up
Use the exact OLED and button connections in Hardware wiring. Display diagnostics initially operate I²C at 100 kHz and probe the standard 7-bit 0x3c and 0x3d addresses. The connected test module acknowledges at 0x3c, whose 8-bit write/read forms are 0x78 and 0x79. A missing or unresponsive display is nonfatal: diagnostics should report it without disrupting UART0 or the serial services.
1. Power-off wiring checks
Disconnect both USB connectors and every other power source before checking or changing wiring.
- Confirm OLED
VCCgoes only to3V3, OLEDGNDgoes toGND, SDA goes to GPIO11, and SCL goes to GPIO12. - Check for an unintended short between
3V3andGND, and verify ground continuity between the OLED and ESP32 board. - Determine whether the OLED module has SDA/SCL pull-ups and verify that any module-mounted or external pull-ups terminate at 3.3 V, never 5 V. Add suitable external pull-ups to
3V3only if the module does not provide them; account for parallel resistance if more than one set is fitted. - Confirm each button is wired between its input and
GND: previous/back GPIO10, select/confirm GPIO13, and next GPIO14. With a meter, each button should be open when released and near zero ohms toGNDwhen pressed. - Check that no button shorts two GPIOs together and that SDA and SCL are not swapped or shorted.
2. Powered idle checks and address probe
Apply power, but do not initialize the OLED yet.
- Measure OLED
VCCrelative toGND; it should be approximately 3.3 V. - Measure idle SDA on GPIO11 and idle SCL on GPIO12. Both should be near 3.3 V. Power down immediately if either bus line rises toward 5 V; correct the OLED supply or pull-up wiring before continuing.
- Run
debug display statusand record the diagnostic state. - Run
debug display probe. Confirm that it tests only 7-bit0x3cand0x3dat the initial 100 kHz bus rate. The tested module should acknowledge at0x3c(8-bit0x78write /0x79read).
If the expected address does not respond, treat the result as a nonfatal hardware finding. On this dedicated local-UI bus, debug display scan --force may identify an unexpected address before further investigation. Otherwise leave the serial core running, power down, and recheck 3.3 V power, common ground, SDA/SCL order, solder joints, and pull-ups. Do not scan a bus shared with unrelated I²C devices.
3. Initialization and display patterns
Initialize the address observed during the scan. The tested module uses 7-bit 0x3c, equivalently 8-bit 0x78 (write) and 0x79 (read):
debug display init 0x3c
Then run:
debug display pattern clear
debug display pattern fill
debug display pattern checker
debug display pattern grid
debug display pattern corners
Confirm that clear and fill affect the full 128×64 area, checker and grid have regular spacing without shifted or wrapped columns, and all four corner markers are visible in the correct locations. Display diagnostics pause the periodic status UI for 30 seconds so the selected pattern remains observable. Record any unexpected mirroring, rotation, clipping, or column offset for correction.
4. Rendered status/content layout
Run the Phase 7B panel-layout pattern:
debug display pattern layout
Confirm that the status text is entirely in the yellow 128×16 panel (rows 0–15), content text is entirely in the blue 128×48 panel (rows 16–63), and the physical black divider between them remains visible. Record any text crossing the divider, clipping, incorrect panel color, or divider obscuration.
5. Row 15/16 color-boundary test
Clear the display, illuminate row 15, and record its physical color and position:
debug display pattern clear
debug display row 15
Repeat for row 16:
debug display pattern clear
debug display row 16
Verified result: row 15 is the last yellow addressable row and row 16 is the first blue addressable row. The two colored areas are separated by a narrow physical black divider, so later UI rendering must treat the 128×16 yellow and 128×48 blue regions as separate panels rather than one visually continuous canvas. Also test another endpoint row if needed with debug display row <0..63> to confirm row addressing and orientation.
6. Contrast, inversion, and display-off checks
With a visible pattern loaded, exercise the bounded contrast range and confirm that brightness changes without bus errors. On the validated module, the useful visible brightness range begins at 1 and extends through 255:
debug display contrast 0
debug display contrast 64
debug display contrast 128
debug display contrast 255
Then verify inversion toggles all displayed pixels and can be restored:
debug display invert on
debug display invert off
Finally run debug display off and confirm the panel turns off cleanly. Use debug display status, then debug display init 0x3c (or equivalently 0x78 or 0x79) before further display tests.
7. Button checks
With all buttons released, run debug buttons status. Confirm previous/back GPIO10, select/confirm GPIO13, and next GPIO14 report released/high due to their internal pull-ups; each should report pressed/low while held to GND.
Run debug buttons test for the default 10-second interval. During the test, press and release each button separately with a deliberate short press, then repeat with a sustained long press. Confirm that the correct button and short/long classification are reported exactly once per intended action.
Repeat with an explicit duration, for example:
debug buttons test 30
Use the longer run to check:
- Debounce: press with normal switch bounce and make several deliberately quick taps; one physical press must not produce a burst of duplicate press/release or short/long events.
- Long press: hold each button long enough for the diagnostic to classify it as long, then release it; it must not also create an unintended short-press action.
- Stuck button: hold one button before starting the test and keep it held. The input must remain identified as pressed/stuck without blocking checks of the other buttons, and the bounded diagnostic must still exit after the selected duration.
- Recovery: release the held button and confirm
debug buttons statusreturns to released/high without a reboot.
debug buttons test [seconds] accepts 1 through 30 seconds and defaults to 10 seconds when omitted. Record unexpected event duplication, missed transitions, incorrect GPIO mapping, false long presses, or a test that fails to terminate.
8. Read-only status UI (Phase 7C)
After boot, the OLED starts on the OVERVIEW page. A short previous/back press on GPIO10 and a short next press on GPIO14 must wrap through these read-only pages:
- OVERVIEW — serial, broker, USB, HTTPS/WebSocket, SSH, and Wi-Fi summary.
- RS232 MODEM — framing, modem inputs, byte counters, queue depth, drops, and faults.
- BROKER — connected clients, current writer marker, pending output, and drop/event counters.
- NETWORK SERVICES — Wi-Fi state/RSSI/IP/AP state and HTTPS, WebSocket, and SSH service state.
Confirm that each page remains entirely within the blue content panel. The yellow panel must retain the same fixed icon positions while pages change: serial, segmented Wi-Fi strength, USB, WebSocket, SSH, broker clients, and alert. Active icons are solid with a value below; inactive icon slots remain completely blank and omit their value. Confirm that page text uses readable upper/lowercase, separates items and values with colons, and displays the active station SSID or AP SSID with its channel on the Overview and Network pages.
The UI refreshes at 4 Hz maximum and is read-only: select (GPIO13) must not change a service, acquire/release a writer, inject serial data, or expose passwords, credentials, tickets, or key material. With UART0, USB CDC, WebSocket, and SSH active, navigate pages and confirm that the display continues to update without disrupting serial traffic or UART0 recovery.
For the OLED-aging policy, leave all three buttons untouched and verify:
- At five minutes, display contrast drops to
1while the contents remain present. - At ten minutes, the OLED switches off.
- The first debounced press of any button wakes the OLED at contrast
127without changing the current page. - A subsequent previous/next press navigates normally and restarts the inactivity timers.
debug display status may verify an individual transition in a separate timing run. Every display diagnostic counts as activity and holds normal UI rendering for 30 seconds, so do not invoke it between the five- and ten-minute observations of one continuous run. Record a missing, stale, clipped, or implausible status value or incorrect dim/off/wake transition before Phase 7C is marked complete.
9. Local controls (Phase 7D)
From a status page, use a short Select press to open Controls. Previous/next selects an item; Select activates it. The menu includes serial start/stop, Wi-Fi start/stop/reconnect/next-profile, HTTPS start/stop, SSH start/stop, writer revocation, display off, and reboot. WiFi:next profile requests the enabled station profile after the active one in priority order and wraps safely; it must never show or change credentials, Wi-Fi profile configuration, serial framing, TLS/SSH keys, or I²C scan controls.
Stopping a service, Wi-Fi reconnect, Wi-Fi next-profile, writer revocation, and reboot open a confirmation page. Verify that:
- Previous/back cancels the confirmation without changing the selected service or writer.
- A short Select press does not execute the action.
- Only one continuous two-second Select hold executes the action once; releasing it does not repeat the action.
- Any simultaneous button chord is ignored and cannot confirm an action.
- An untouched confirmation expires to the menu after 30 seconds.
- A dimmed/off OLED consumes the first button press for wake only; its later release and hold must not navigate or confirm an action.
For Wi-Fi lifecycle calls, confirm the immediate result says Requested, then use the status pages to observe the asynchronous state change. For WiFi:next profile, configure at least two enabled station profiles, cancel once with Previous/back, then hold Select for two seconds; verify the current station disconnects, the next enabled profile is attempted, and the Overview/Network WiFi:<SSID> Ch:<channel> value (or wifi status) changes. Repeat until the selection wraps to the first profile. HTTPS and SSH starts must fail cleanly when neither station nor AP networking is available. Writer revocation must only release the current writer—never assign a replacement—and the UI must never appear as a broker client. For reboot, observe Restarting..., then verify all normal boot services and UART0 recovery return.
Run these checks with UART0 available. Repeat appropriate stop/revoke cases with USB CDC, WebSocket, and SSH clients connected; verify the intended session/service is interrupted, unrelated recovery paths remain responsive, and no action injects serial data.
10. Phase 7E boot animation, persistence, and fault recovery
On each normal boot with an initialized OLED, first verify the bounded five-second identity animation: the full ESP32 SERIAL SWISS ARMY KNIFE name scrolls across the yellow panel; the blue panel shows the compact right-oriented monochrome logo with an upright >_ prompt and serial/USB cable ends entering from the left. Wi-Fi activity and the cursor blink at the 4 Hz animation cadence. A missing OLED must skip the animation without preventing normal UART0 recovery.
Then shorten the delays for a bounded aging-policy test:
display status
display set dim-seconds 5
display set off-seconds 10
display save
reboot
After reboot, display status must report the stored 5/10-second values. Verify dim at five seconds, off at ten seconds, and one consumed wake press. Run display load, then test display defaults without saving and confirm 300/600 seconds are restored only in RAM. Run display reset, reboot, and confirm the defaults persisted. Verify invalid combinations such as dim 10 with off 5 are rejected without changing the working values. Set either timeout to 0, save/reboot, and confirm that transition is disabled; finish with display reset.
Exercise the following fault matrix while keeping UART0 available:
| Fault/stress | Procedure | Required result |
|---|---|---|
| OLED absent at boot | Power down, remove the OLED, then boot. | UART0, serial, USB, Wi-Fi, HTTPS/WebSocket, and SSH startup remain independent; no reset or probe loop occurs. |
| Reattach | Power down before reconnecting loose wiring, boot, and press one button. If using a connector explicitly suitable for live removal, avoid shorts and reconnect before pressing. | One bounded reprobe initializes the panel; the wake press does not navigate or execute an action. |
| NACK/timeout | With safe test wiring, interrupt the display during refresh or hold one bus line low briefly, then release it. | One bounded frame fails and marks the OLED unavailable; no watchdog reset, repeated log flood, serial loss, or broker ownership change occurs. A later new press can recover after the bus is healthy. |
| Stuck button | Hold each button continuously for at least ten seconds, then operate each of the other buttons. | The held input is quarantined, the other controls remain usable, and no action repeats. Release and debounce the held input; it must rearm without rebooting. |
| Real chord | Press two healthy buttons together before either is quarantined. | The chord is ignored and cannot confirm an action. |
| Repeated actions | Re-enter Controls and repeat start/stop, reconnect, next-profile, writer-revoke, and display-off requests during transitions. | Each confirmation hold executes once; stale state produces an error rather than the opposite action; queue saturation, if reached, reports an error and leaves the Wi-Fi alert/counter visible. |
For the final concurrency regression, connect USB CDC, one WebSocket terminal, and one SSH terminal while UART1 carries sustained bidirectional traffic. Navigate the UI, run the persistence checks, exercise service stop/start and writer revocation, and inject the display/stuck-button faults above. Confirm UART0 remains responsive, the UI never appears as a broker client or injects serial bytes, writer ownership is always the expected client or none, and serial/broker drop counters do not increase unexpectedly. Record memory, transport counters, wifi counters, and debug display status before and after the run.
Phase 8A role-based user database and UART0 administration
Keep UART0 physically attached throughout these tests. Phase 8A deliberately does not change HTTPS or SSH authentication: existing network sessions still use the legacy shared credential, while the new database and public keys are prepared for the Phase 8B cutover. Do not include generated or entered passwords in test logs.
1. First-boot migration and persistence
Upgrade a device that already has working HTTPS/SSH credentials and no user_db blob. After boot:
- Run
user statusanduser show admin. - Confirm exactly one
admin-named account exists with roleuser,bootstrapped=no, no displayed password/salt/verifier, and no public keys. - Confirm the pre-upgrade credential still authenticates to HTTPS and SSH and that serial terminal behavior is unchanged.
- Reboot and confirm
user statusreports the same account ID and authentication generation. - Confirm routine boot logs,
status,web status, andssh statuscontain no user password, verifier, salt, or raw public-key blob.
A transient failure reading the legacy web credential must not create or commit an empty user database. If a valid user_db blob already exists, it must still load without the legacy credential being readable.
2. Administrator bootstrap
Run user bootstrap, verify that typed password characters are not echoed, enter a 12–64 character printable password twice, and confirm user show admin now reports role admin and a higher authentication generation. Reboot and confirm bootstrapped=yes and one administrator persist. On a separate resettable test image, exercise user bootstrap --generate; record the generated password securely for the test, verify it is displayed once, then clear the terminal scrollback after use.
During Phase 8A, verify the newly bootstrapped password does not replace the legacy HTTPS/SSH login yet and the existing network credential continues to work. This separation is intentional until Phase 8B. A second user bootstrap must be rejected without changing the account.
3. Account CRUD, capacity, and invariants
Use generated test passwords where practical:
user add operator user --generate
user add maint admin --generate
user list
user show operator
user role operator admin --force
user role operator user --force
user password operator --generate
Confirm unique valid usernames are accepted; uppercase, empty, oversized, or punctuation-invalid usernames are rejected. Confirm duplicate users are rejected. Fill all eight slots and verify a ninth account is rejected without altering existing records; delete a non-final account and confirm its slot can be reused with a new account ID.
With two administrators, demote or delete one and confirm the operation persists. Then attempt both deletion and demotion of the final administrator and confirm both are rejected. Before bootstrap on a separate migration run, verify user delete admin --force is rejected so legacy synchronization remains recoverable. Ctrl-C during either hidden password prompt must cancel without changing the account or leaving stale input in the next console command.
4. SSH public-key import and fingerprints
Generate disposable Ed25519 and ECDSA P-256 OpenSSH keys on a trusted host. For each supported type, run user key add <username>, paste the single .pub line, and confirm user show <username> reports the type, stable slot index, and expected SHA256: fingerprint without displaying the Base64 blob or comment.
Verify all of the following fail without changing the account generation or key list:
- Unsupported RSA, certificate, or unknown key types.
- Truncated/invalid Base64, mismatched outer and embedded types, trailing blob data, malformed Ed25519 lengths, and an invalid/off-curve ECDSA point.
- Adding the same key again to the same account or assigning it to a different account.
- Adding a fourth key to an account that already has three.
- Deleting an empty/out-of-range slot.
Then exercise user key delete <username> <index> --force and user key clear <username> --force, reboot, and confirm the exact remaining fingerprints persist. Phase 8A stores these keys but does not yet accept SSH key login.
5. Legacy credential rotation boundary and reboot reconciliation
Before administrator bootstrap on a resettable test image:
- Run
web credentials rotate --force. - Confirm the console reports that the pre-bootstrap migrated verifier was synchronized.
- Verify the new legacy credential works for HTTPS and SSH, reboot, and confirm
user show adminretains the synchronized authentication generation. - Where NVS fault injection or controlled power interruption is available, interrupt after the web credential commits but before the user blob commits. On the next boot, confirm reconciliation updates the migrated verifier rather than committing an empty database or losing network recovery.
After bootstrap, rotate the legacy credential again. Confirm the console explicitly says it remains separate from user passwords, existing network sessions are revoked, the new legacy credential works, and the bootstrapped administrator generation/password are not silently replaced. Apply the same checks to web reset --force, additionally confirming HTTPS certificate recovery/restart behavior remains intact.
6. Explicit database recovery and storage failures
Using a disposable device or test NVS image, inject a wrong-size/version or malformed user_db blob and reboot. Confirm normal database initialization fails without erasing shared NVS, but the user command is still registered. user status must report the database unavailable. Run:
user recover --force
user status
user bootstrap --generate
Confirm recovery explicitly replaces only user_db, imports the current legacy credential as role user, and leaves serial, Wi-Fi, HTTPS identity, SSH host key, and legacy network login intact. Confirm recovery is rejected while a valid database is initialized. Simulate NVS write/commit exhaustion or failure during create, password, role, key, and recovery operations; after reboot, each operation must expose either the complete old blob or complete new blob, never a partially live mutation.
Because NVS is not yet encrypted, this test validates logical verifier storage rather than resistance to physical extraction. PBKDF2 verifiers remain susceptible to offline guessing, and append-oriented NVS may retain historical plaintext legacy credentials until a full partition/flash erase.
7. Phase 8A regression
With the maximum supported mix of USB CDC, WebSocket, and SSH serial clients active, repeat user list/show and several UART0 mutations. Confirm password prompts remain physical-UART-only, no user operation acquires a broker client or writer lease, existing Phase 8A network authentication and revocation behavior remains functional, and serial/broker counters show no unexplained loss. Record memory, web counters, and ssh counters before and after the run.
Phase 8B role-aware HTTPS and SSH authentication
Complete the Phase 8A bootstrap first and retain two disposable accounts, one user and one admin. Phase 8B gives both roles the existing serial/status interface; the administrative SSH shell is not expected until Phase 8C.
1. HTTPS passwords and fail-closed behavior
For both roles, authenticate to /, /api/status, and the browser terminal with the account password. Confirm the full 16-character username and a 64-character password work, while absent, malformed, oversized, wrong-user, and wrong-password Basic headers fail without exposing which component was wrong. After bootstrap, confirm the value from web credentials show no longer authenticates unless it independently equals a current user password.
On a disposable malformed-database image, confirm HTTPS returns authentication-service unavailable and never falls back to the legacy credential. Recover through physical UART0 only. Verify web status reports user-database authentication and active WebSocket sessions show account, user role, and password method without secrets.
2. SSH password and public-key login
For both user and admin, verify password SSH login reaches the same broker-backed serial stream as before. Confirm ssh sessions shows the account, user role, password method, and writer/observer role. An administrator must not receive UART0 commands yet.
Import one Ed25519 key and one ECDSA P-256 key through user key add, then verify each matching private key authenticates without a password and ssh sessions reports public-key. Confirm an unregistered key, wrong username, unsupported RSA key, certificate key, and three failed completed attempts are rejected. Normal client probe-then-sign behavior must consume one completed attempt, not two; unsigned probes alone must never create an authenticated session or broker client.
3. WebSocket ticket binding
Authenticate separately as two users and request tickets. Confirm each ticket is accepted exactly once, expires after 30 seconds, and cannot be reused or altered. Change one account after ticket issuance but before WebSocket connection; its ticket must fail closed without creating a broker client, while the other account's ticket still works. Repeat with delete followed by recreation of the same username and confirm the old ticket remains invalid.
4. Targeted session revocation
Connect simultaneous WebSocket and SSH sessions for two different users and place one affected session in writer state. One mutation at a time, exercise password change, role change, SSH-key add/delete/clear, and account deletion. Required results:
- Outstanding tickets and active sessions for the changed username are revoked promptly and any writer lease is released.
- The stale session cannot inject additional serial bytes or reacquire writer ownership.
- The unrelated user's WebSocket/SSH sessions remain connected and retain their expected broker roles.
- New authentication succeeds only with the updated password/key/role state.
- Deleting and recreating the same username does not revive old tickets or sessions.
Run web status, ssh sessions, web counters, ssh counters, and broker clients around each mutation. Also rotate web credentials rotate --force after administrator bootstrap and confirm it changes only recovery material: role-based HTTPS/SSH sessions remain connected and user passwords are unchanged. web reset --force restarts HTTPS because the TLS identity changes, but must not revoke unrelated SSH sessions.
5. Concurrency regression
With USB CDC, two role-based network users, one WebSocket terminal, one SSH terminal, and UART1 traffic active, alternate writer ownership and mutate one account. Confirm binary transparency, observer isolation, bounded authentication/handshake behavior, UART0 responsiveness, and no unexpected disconnect of the unaffected user. Record memory, broker, web, SSH, and serial counters before and after. Repeat after reboot to verify passwords, roles, keys, and authentication methods persist.
Configuration A: data and handshake pairs
Connect the following pairs:
| Driven output | Receiver input | Expected ESP32 logic |
|---|---|---|
DE-9 pin 3, TX |
DE-9 pin 2, RX |
RX == TX |
DE-9 pin 4, DTR |
DE-9 pin 6, DSR |
DSR == DTR |
DE-9 pin 7, RTS |
DE-9 pin 8, CTS |
CTS == RTS |
DE-9 pin 3 TX ─────> pin 2 RX
DE-9 pin 4 DTR ─────> pin 6 DSR
DE-9 pin 7 RTS ─────> pin 8 CTS
Run debug loopback-a. The test cycles all TX/DTR/RTS states and verifies the three receivers and VLD. Driver and receiver inversions cancel, so the resulting ESP32 logic levels must match.
This configuration also supports debug valid-test, debug uart-loopback <baud> [format] [bytes], and debug uart-suite; the UART commands need only the pin 3-to-2 connection.
Configuration B: remaining receivers
Remove every configuration A jumper, then connect:
| Driven output | Receiver input | Expected ESP32 logic |
|---|---|---|
DE-9 pin 3, TX |
DE-9 pin 1, DCD |
DCD == TX |
DE-9 pin 4, DTR |
DE-9 pin 9, RI |
RI == DTR |
DE-9 pin 7, RTS |
DE-9 pin 2, RX |
RX == RTS |
DE-9 pin 3 TX ─────> pin 1 DCD
DE-9 pin 4 DTR ─────> pin 9 RI
DE-9 pin 7 RTS ─────> pin 2 RX
Run debug loopback-b. Configurations A and B together exercise all three drivers and five receivers.
CTS transmit gating
Disconnect all external DE-9 equipment, power down, and remove previous jumpers. Install only:
| Driven output | Receiver input | Purpose |
|---|---|---|
DE-9 pin 3, TX |
DE-9 pin 2, RX |
Return UART1 data for comparison |
DE-9 pin 4, DTR |
DE-9 pin 8, CTS |
Present inactive and active CTS states |
DE-9 pin 3 TX ─────> pin 2 RX
DE-9 pin 4 DTR ─────> pin 8 CTS
Run debug cts-flow-test. At 115200 baud with hardware CTS enabled, the firmware first queues 512 bytes while CTS is inactive and confirms that no data is sent for 250 ms. It then activates CTS and verifies automatic, exact transmission and reception of all bytes.
RTS receive backpressure
Disconnect all external DE-9 equipment, power down, and remove previous jumpers. Install only:
| Driven output | Receiver input | Purpose |
|---|---|---|
DE-9 pin 4, DTR |
DE-9 pin 2, RX |
Carry UART2-generated data to UART1 RX |
DE-9 pin 7, RTS |
DE-9 pin 1, DCD |
Return UART1 RTS to UART2 CTS |
UART2 TX / DE-9 pin 4 DTR ─────> pin 2 RX / UART1 RX
UART1 RTS / DE-9 pin 7 RTS ─────> pin 1 DCD / UART2 CTS
Run debug rts-flow-test. UART2 queues 4096 bytes while UART1 is initially unread. Once UART1 reaches its receive threshold, it deasserts RTS and stops UART2 through CTS. Draining UART1 must reassert RTS and let UART2 finish. UART_BUFFER_FULL is expected; FIFO overflows, framing/parity errors, breaks, or any data mismatch are failures.
Voltage and polarity checks
With no DE-9 loopback jumpers installed, measure pins 3, 4, and 7 relative to DE-9 pin 5 (GND):
debug drivers 0 0 0
Each output should be at a positive RS-232 voltage. Then run:
debug drivers 1 1 1
Each output should be negative. Exact voltages depend on supply, load, meter, and charge-pump behavior; polarity is the important result.
Recommended order
- With no DE-9 jumpers, run
status. - Measure output polarity with
debug drivers 0 0 0anddebug drivers 1 1 1. - Power down, install configuration A, power up, and run
debug loopback-a. - Run
debug valid-testwith configuration A still installed. - Keep only pin 3-to-2 and run
debug uart-loopback 9600 8N1 256, thendebug uart-suite. - Power down, install configuration B, power up, and run
debug loopback-b. - Power down, install CTS wiring, power up, and run
debug cts-flow-test. - Power down, install RTS wiring, power up, and run
debug rts-flow-test.
RTS and CTS remain GPIO signals during static and basic UART tests. Only the flow-control tests assign them to UART peripherals. The firmware shuts down the MAX3243 while changing GPIO-matrix routing and restores outputs to static logic 1 after each test.
Session-broker loopback
This test verifies broker fan-out and writer ownership independently of the diagnostics. Disconnect external peers, power down, remove previous jumpers, and connect only DE-9 pin 3 (TX) to pin 2 (RX). Power up and run:
serial start
broker connect writer
broker connect observer
broker clients
Use the client IDs printed by the device:
broker request-writer <writer-id>
broker send-hex <writer-id> 0055aaff1b5b33316d
broker read <writer-id> 64
broker read <observer-id> 64
Both clients should receive 0055aaff1b5b33316d. A read may return zero if UART1 has not returned the bytes yet; repeat it shortly afterward.
Verify writer exclusion and administrative reassignment:
broker request-writer <observer-id>
broker send-hex <observer-id> dead
broker force-writer <observer-id>
broker send-hex <observer-id> 112233
broker read <writer-id> 64
broker read <observer-id> 64
broker events <writer-id>
broker events <observer-id>
The competing request and its initial send should fail. After reassignment, both clients should receive 112233; events should show denial, revocation, and grant. Clean up:
broker disconnect <observer-id>
broker disconnect <writer-id>
serial stop
Remove the loopback jumper with power off before connecting an external serial device.