# HPT USB SDRAM buffer and USBHS tuning acceptance

Status: complete
Type: evidence
Updated: 2026-07-26
Next Action: retain the selected image for the remaining HPT release gates

Parent:
`work/wp/completed/wp-move-hpt-usb-buffer-to-sdram-and-tune-usbhs-throughput.md`
Predecessor: `work/evidence/hpt-usb-csv-buffer-window-tuning-20260726.md`
Canonical Truth: `docs/sd-card-operation-and-recovery.md`

## Result

The HPT CSV aggregation window was moved from internal SRAM to a dedicated
external-SDRAM linker section, increased from `32 KiB` to `128 KiB`, and
qualified with the SSP-supported maximum `2 KiB` USBHS FIFO, a `128 KiB`
USBX Bulk-Only-Transport phase, and an `8 KiB` FileX media buffer.

The same exact image passed Controller B twice and Controller A once. All
three real retained-range exports completed the temporary-file, staged-count,
completion-trailer, close, first media flush, rename, and final media-flush
sequence. Each export used one complete-row buffered write with zero
snapshot/requested-range gaps, HPT errors, USB errors, bulk fallbacks, lost
records, or dropped logs.

| Metric | B first / cold media | B repeat | A |
| --- | ---: | ---: | ---: |
| Records scanned / selected | `1,835 / 1,829` | `1,836 / 1,830` | `1,888 / 1,886` |
| Healthy / degraded | `1,748 / 81` | `1,749 / 81` | `1,886 / 0` |
| HPT staging | `2.27 s` | `2.29 s` | `2.42 s` |
| USB publication | `1.91 s` | `0.39 s` | `0.28 s` |
| Total end to end | `4.19 s` | `2.73 s` | `2.73 s` |
| Row construction | `0.27 s` | `0.26 s` | `0.27 s` |
| File writes | `0.57 s` | `0.06 s` | `0.01 s` |
| Close / both flushes / rename | `0.01 / 0.54 / 0.03 s` | `0.00 / 0.04 / 0.03 s` | `0.00 / 0.00 / 0.00 s` |
| File write calls / buffered flushes | `1 / 1` | `1 / 1` | `1 / 1` |
| Bytes / largest write | `92,515 / 92,515` | `92,565 / 92,565` | `95,381 / 95,381` |
| Buffer capacity | `131,072 B` | `131,072 B` | `131,072 B` |
| Complete / published | `1 / 1` | `1 / 1` | `1 / 1` |

B's first result retains its USB stick's previously observed cold/flush
penalty. Its repeat result shows the transfer-path gain after the stick is
active. Both are acceptance evidence; the cold result is used for the
conservative projection.

## Performance disposition

Comparisons use elapsed time per selected record against the accepted `32 KiB`
image so the growing live logs do not bias the result.

| Comparison with 32 KiB | B first / cold media | B repeat | A |
| --- | ---: | ---: | ---: |
| USB throughput | `1.10x` | `5.39x` | `1.66x` |
| File-write phase throughput | `1.25x` | `11.86x` | `16.51x` |
| End-to-end throughput | `1.06x` | `1.62x` | `1.07x` |
| FileX application writes | `3 -> 1` | `3 -> 1` | `3 -> 1` |

The supported `128 KiB` knee is selected. The measured files are only
`92.5–95.4 KiB`, so every selected run already reaches one application/FileX
write. A `256`, `512`, or `1024 KiB` aggregation window cannot reduce that
count, while the configured BOT phase remains intentionally capped at
`128 KiB` to fit the existing 128-TD pool with margin. Consuming more SDRAM
therefore has no measured or structural benefit for this workload.

The owner-authorized maximum remains enforced at `1024 KiB` by both a
preprocessor error and a linker assertion. It is a ceiling, not the selected
production size.

## Long-range projections

These projections scale each measured per-record rate to one-minute logging.
They are not direct month-long captures and remain USB-media dependent.

| Control / condition | Range | HPT staging | USB publication | Total |
| --- | ---: | ---: | ---: | ---: |
| A | 30 days | `55.4 s` | `6.4 s` | `62.5 s` |
| A | 90 days | `2.77 min` | `0.32 min` | `3.13 min` |
| B first / cold | 30 days | `53.6 s` | `45.1 s` | `99.0 s` |
| B first / cold | 90 days | `2.68 min` | `2.26 min` | `4.95 min` |
| B repeat | 30 days | `54.1 s` | `9.2 s` | `64.4 s` |
| B repeat | 90 days | `2.70 min` | `0.46 min` | `3.22 min` |

The conservative measured-media estimate is now `4.95 min` for 90 days,
versus `5.22 min` on the 32 KiB image. The repeat/warm estimate is `3.22 min`.
HPT staging remains the dominant stable phase; B's cold durable flush remains
the worst variable phase.

## Renesas and configuration basis

- Renesas's Synergy SDRAM guidance supports deterministic static placement
  with a named linker section.
- Renesas's SSP USB performance guidance identifies DMAC, maximum USBHS FIFO,
  increased FileX memory, and larger BOT phases as the relevant controls and
  shows a practical `128 KiB` transfer knee.
- The installed SSP 2.6.1 module metadata defines `2048 B` as the maximum
  USBHS FIFO and says larger BOT phases improve throughput when enough TDs
  exist.
- USBHS already used DMAC channels 0/1 at priority 2 while USBHS was priority
  3, matching the Renesas priority recommendation.
- At a `2 KiB` FIFO payload, a `128 KiB` phase needs 64 data TDs plus
  wrapper/tail overhead. The existing `UX_MAX_TD=128` is retained.
- The FileX media buffer increased from `1 KiB` to `8 KiB`; the USBX pool
  increased by the same `7 KiB`, from `63,488` to `70,656 B`, preserving the
  prior allocation reserve.

References:

- `https://community.renesas.com/mcu/synergy-mcu/f/forum/10733/synergy---how-can-i-setup-the-heap-to-use-sdram/36661`
- `https://community.renesas.com/mcu/synergy-mcu/f/forum/15485/how-to-increase-the-speed-of-writing-to-usb-flash-driver-ssp-1-7-0`
- `https://www.renesas.com/en/document/apn/usbx-synergy-port-framework-module-guide-application-project`

## Candidate, memory, and software gates

- Debug S-record SHA-256:
  `6484150EAD23D1F2F9F7C5BFD5F0A9C0230BEE86F4702C04FB89280F8A236E1A`
- Debug ELF SHA-256:
  `AD7D00673647AE8718CF485655F8A3D29706E1F1993109FC88FFB1D9D78B2971`
- Debug map SHA-256:
  `1D347333993A4807D1D961CCC3298B56DCC5EACDC08604FFC9DFD155291EA42E`
- Production-name package: `7520553_SMI_FW_00_05_00`
- Repository check suites: `21/21 PASS`
- Python model suites: `8/8 PASS`; Python compilation gate: PASS
- Managed isolated clean Debug build and package: PASS
- `.smi_usb`: `0x91AAA080` through `0x91ACA07F`, `131,072 B`,
  `NOLOAD`, 64-byte aligned
- Internal SRAM headroom after configured heap/stacks: `44,600 B`
  (`43.55 KiB`), increased from `18.6 KiB`
- Remaining external SDRAM headroom: `5,463,936 B` (`5.21 MiB`)
- SDRAM ordering, total-capacity, and `1024 KiB` USB-window assertions: PASS
- Headless build cleanup now treats Windows overlong copied-evidence paths as
  deferred cleanup after a successful build; the bounded staging tree was
  subsequently removed and verified absent.

## Identity and preservation

| Control | Assembly / J-Link | Protocol / CID-valid / representative read | Raw CID |
| --- | --- | --- | --- |
| A | `1751136 / 69664082` | `6 / 1 / 0` at capture, `6 / 1 / 1` at export guard | `035344535330384780976F0084018559` |
| B | `1751219 / 69660123` | `6 / 1 / 0` at capture, `6 / 1 / 1` at export guard | `035344535330384780976F0085018507` |

Baseline after each programming reboot and post-export captures have matching
CIDs, zero system errors, zero dropped logs, zero mirror mismatches, and zero
lost records. A remains aligned at oldest starts `1 / 1 / 1`, active starts
`1024 / 1024 / 1024`, and retirements `0 / 0 / 0`. B was not formatted,
initialized, or normalized: oldest starts remain `86 / 86 / 1`, active starts
remain `1109 / 1109 / 1024`, and retirements remain `2 / 1 / 0`.

No SD format, initialization, card replacement, powered removal, or
configuration mutation occurred.

Boot cache timing on the exact image was:

- A: `2.20 s` traversal, `3.07 s` complete elapsed;
- B: `2.12 s` traversal, `2.97 s` complete elapsed.

## Operator-visible end state

Both Graph screens were reopened with RAM-only review commands and captured
active on the exact selected image. Both follow newest, have current render
sequences, and have zero chart-newest-to-viewport-edge lag. At final capture,
A's newest record was `3 s` behind RTC and B's was `6 s` behind RTC.

## Raw captures

- A:
  `work/evidence/hpt-log-store-circular-mirror/controller-a/usb-sdram-128k-usbhs-20260726/`
- B:
  `work/evidence/hpt-log-store-circular-mirror/controller-b/usb-sdram-128k-usbhs-20260726/`

The compact JSON files are the review surface. Binary target captures remain
supporting evidence and should not be reviewed through per-file diffs.
