IS66WVO8M8DBLL Memory Mapped Interface on STM32H563 in zephyr
Hi all,
I am bringing up an ISSI IS66WVO8M8DBLL OctalSPI PSRAM (OctaRAM) on an STM32H563VIT6 over
OCTOSPI1 in memory-mapped mode (window at 0x90000000). Reads, register access, and
"write a location then read it back immediately" all work perfectly. But any SUSTAINED
or SCATTERED write workload corrupts data: rows that are not continuously re-written
lose their contents within a few seconds, and some writes come back wrong.
This matches errata ES0565 section 2.5.12 ("Variable latency is not supported when a
refresh collision occurs during a write access to some OctaRAM memories"). I applied the
documented workaround - forcing FIXED latency in the memory's configuration register -
and I run in the documented MTYP=0b011 (Macronix OctaRAM) mode. The corruption persists,
byte-for-byte identical, with the workaround correctly applied and verified by read-back.
I have reproduced this on TWO separate boards with identical results, so it is not a
single bad device.
Has anyone got OCTOSPI memory-mapped WRITES to an ISSI OctaRAM working reliably on
STM32H5? Is the fixed-latency workaround supposed to fully eliminate this, or is there an
extra step / a fixed silicon revision?
CONFIGURATION
-------------
- MCU : STM32H563VIT6 (silicon rev: <fill in - e.g. rev X / date code>)
- External memory: ISSI IS66WVO8M8DBLL (64 Mbit / 8 MByte, x8 OctalSPI DTR PSRAM, 3.3 V)
- Interface : OCTOSPI1, memory-mapped at 0x90000000, 8-line DTR, DQS enabled
- Clock : PLL1_Q = 248 MHz -> OCTOSPI prescaler /2 -> SCLK = 124 MHz
- Boards : 2 independent units, identical behavior
- Software : bare-register + STM32 HAL (XSPI)
- Memory datasheet: IS66/67WVO8M8DALL/BLL Rev. A1 (02/25/2022)
Programmed OCTOSPI registers (read back at runtime):
DCR1 = 0x03160400 (MTYP[2:0] = 0b011 = Macronix OctaRAM mode; DEVSIZE = 8 MB)
DCR2 = 0x00000001 (PRESCALER = 1 -> SCLK 124 MHz)
DCR3 = 0x00080000 (CSBOUND = 8 -> 256-byte CS# boundary)
DCR4 = 0x00000140 (REFRESH = 320 clocks)
Device Configuration Register, read back from the IS66WVO:
CR = 0xf12a
CR[15] = 1 normal operation (out of deep power down)
CR[8] = 1 DQSM read pre-cycle
CR[7:4] = 0010 latency code = 5 clocks
CR[3] = 1 FIXED latency <-- ES0565 2.5.12 workaround applied
CR[1:0] = 10 32-byte burst length
Device ID register reads correctly: ID = 0x2c93 (manufacturer field = 0x3, ISSI).
ERRATUM TEXT (ES0565, section 2.5.12)
-------------------------------------
Description: "When the memory type (MTYP[2:0] bitfield of the OCTOSPI_DCR1 register) is
configured to 0b011 to target an OctaRAM memory, the host controller does not support
the variable latency requested by the external memory if a refresh collision occurs
during the write access. For example, some OctaRAM memories, such as ISSI memories,
request extra latency cycles for write accesses during refresh collision. In this case,
the controller does not sample the DQS input signal during the instruction phase, and
cannot detect the extra latency requested by the external memory for the refresh
operation. This results in data corruption."
Workaround: "When the application targets an OctaRAM memory that requests extra latency
cycles for write access during refresh collision, force the fixed latency mode in the
configuration register of the external memory."
WHAT I OBSERVE (with the workaround applied)
--------------------------------------------
Even with FIXED latency genuinely programmed (device CR = 0xf12a, CR[3] = 1, verified by
read-back) and MTYP = 0b011 (verified DCR1 = 0x03160400):
- Reads (any size), register access, and "write then read back immediately" all work.
- Write a large region, THEN read it back -> ~100% corruption.
- A write to one location disrupts the autonomous refresh of OTHER (un-accessed) rows;
those rows decay to 0x00000000 / garbage within a few seconds, even while CS# is idle.
- A realistic application struct (mix of frequently- and rarely-written fields) fails:
rarely-written fields decay during normal operation, and a constantly-written field is
also occasionally corrupted.
Things I tried that did NOT change the write corruption:
- MTYP = 0b010 (APMemory) and MTYP = 0b011 (Macronix OctaRAM) - identical corruption
- Fixed-latency window from 5 to 8 clocks (CR[7:4])
- CSBOUND disabled..256 B; REFRESH 320/400; transaction sizes 4 B..1 MB;
wrapped vs continuous burst
- Disabling the external data cache (DCACHE1) so accesses are genuinely uncached
- CS# internal pull-up; write DQS enable/disable
Reads stay clean throughout; only writes are affected.
REPRESENTATIVE LOGS
-------------------
Init - clocks, controller and device registers all correct (MTYP=0b011, FIXED latency):
INIT regs: ID=0x2c93 (mfr=0x3) CR=0xf12a
XSPI ker clk=248000000 Hz prescaler=1 -> SCLK=124000000 Hz
XSPI DCR1=0x03160400 DCR2=0x00000001 DCR3=0x00080000 DCR4=0x00000140
Write-then-immediately-read works; write-all-then-read-all fails:
interleaved write+read-back 1MB: 0 errors -> PASS
B FAIL @ +0x0: exp 0xc0de0000 got 0x00000000
B FAIL @ +0xc: exp 0xc0de0003 got 0xfffe8888
B FAIL @ +0x10: exp 0xc0de0004 got 0xffffc0e1
separate write pass then read pass, 1MB: 262104 errors -> FAIL
A write disrupts refresh of un-accessed rows; data decays although CS# is idle:
block @ +0x0 immediate read = OK; after 1MB write storm to other rows = LOST
1MB READ storm (no writes) -> block @ +0x0 = OK (reads do not disrupt refresh)
sparse writes + 400 ms idle -> block @ +0x0 = LOST
Realistic application struct in PSRAM, scattered read-modify-write over 5000 ticks:
app-vars after 5000 ticks: live_mismatch=39 full_mismatch=42 -> FAIL
boot_count=8 (exp 7) uptime=5000 (ok) temp=25904 (ok) crc=0x00001388 (exp 0xA5C3F00D)
app-vars after 5s idle: mismatch=42 -> DECAYED
QUESTIONS
---------
1. With ES0565 2.5.12's workaround applied as documented (device FIXED latency,
MTYP=0b011), I still see write corruption. Is the fixed-latency workaround expected to
FULLY eliminate it, or are there additional required conditions (controller settings,
refresh/CSBOUND constraints, write dummy-cycle requirements)?
2. Is this erratum corrected in any STM32H563 silicon revision? If so, which one, and how
do I identify it (package marking / DBGMCU_IDCODE REV_ID)?
3. Is the ISSI IS66WVO8M8 a validated/recommended OctaRAM for STM32H5 OCTOSPI
memory-mapped WRITE use? If not, can you recommend an OctaRAM PSRAM that does not
request extra write-access refresh latency (and would therefore be unaffected per the
erratum text)?
4. Is there a reference project / app note showing reliable OCTOSPI memory-mapped WRITES
to an ISSI OctaRAM on STM32H5 that I can compare against?
Thanks in advance for any pointers.


