BERGSONNE

Store.O.128

Store.O.128 tile driver — Renesas/Adesto AT25QL128A 128 Mbit QSPI NOR flash.

16 MB serial NOR flash on SPI / Quad-SPI. Standard SPI-NOR command set: JEDEC ID, status, write-enable, page program (256 B pages), 4 KB sector / 64 KB block / chip erase, read, deep power-down.

Platform-agnostic: uses the framework's raw SPI transaction primitive (`tiles_pal_t.spi_transfer`) so command + 24-bit address + data fit one CS assertion. A platform that doesn't implement spi_transfer yet leaves it NULL; every call here guards against that (init reports an error; later calls return 0 / do nothing) rather than faulting.

Supply is 1.7-2.0 V only (datasheet §9, VCC). VIH max is VCC + 0.4 V, so the SPI lines must be driven at the tile's 1.8 V rail, not 3.3 V.

Sidebands: the AT25QL128A ships with QE = 1 (datasheet §7.7, factory default), so WP (pad 6) and HOLD (pad 9) act as IO2/IO3 and their WP/HOLD functions are inactive in single-lane SPI. Neither pin has an internal pull-up (datasheet Table 1); the tile fits a 47 kΩ pull-up on WP only, HOLD is not pulled.

Timing (datasheet Table 26, max): tPP 5 ms, tSE 0.4 s, tBE2 2.5 s, tCE 300 s. READ (0x03) is limited to 50 MHz SCK; FAST_READ (0x0B) to 104 MHz.

Examples

Quick start

  #include "core_tiles.h"

  tile_t flash;
  uint8_t buf[256];
  tile_store_o_128_init(core_tiles_pal(&core_spi1), 0, &flash, NULL);
  if (tile_is_ready(&flash)) {
      tile_store_o_128_read(&flash, 0x000000, buf, sizeof buf);
  }

API reference

Initialization

tile_store_o_128_find

uint8_t tile_store_o_128_find(tiles_pal_t* hal, uint8_t instance)

Probe instance `instance`: reads the JEDEC ID, returns 1 if it matches.

tile_store_o_128_init

void tile_store_o_128_init(tiles_pal_t* hal, uint8_t instance, tile_t* tile, const store_o_128_cfg_t* cfg)

Initialize: verify JEDEC identity, wake from deep power-down.

Lifecycle

tile_store_o_128_deep_power_down

Studio
void tile_store_o_128_deep_power_down(tile_t* tile)

Enter Deep Power-Down (typ 2 µA; every command except release is ignored).

tile_store_o_128_release

Studio
void tile_store_o_128_release(tile_t* tile)

Release from Deep Power-Down.

Runtime

tile_store_o_128_read_jedec_id

Studio
uint32_t tile_store_o_128_read_jedec_id(tile_t* tile)

Read the 24-bit JEDEC ID (manufacturer << 16 | type << 8 | capacity).

Returns Packed JEDEC ID (e.g. 0x1F4218 for the AT25QL128A).

tile_store_o_128_read_status

Studio
uint8_t tile_store_o_128_read_status(tile_t* tile)

Read Status Register 1.

Returns SR1 byte (AT25QL128A_SR1_* bits).

tile_store_o_128_is_busy

Studio
uint8_t tile_store_o_128_is_busy(tile_t* tile)

Whether a program/erase is in progress (WIP bit).

Returns 1 if busy, 0 if idle.

tile_store_o_128_get_capacity

Studio
uint32_t tile_store_o_128_get_capacity(tile_t* tile)

Total flash capacity in bytes.

Returns 16777216 (16 MB).

tile_store_o_128_read

Studio
void tile_store_o_128_read(tile_t* tile, uint32_t addr, uint8_t* buf, uint16_t len)

Read `len` bytes starting at `addr` (READ 0x03).

addr
Byte address (0 .. capacity-1).
buf
Output buffer.
len
Number of bytes.

tile_store_o_128_fast_read

Studio
void tile_store_o_128_fast_read(tile_t* tile, uint32_t addr, uint8_t* buf, uint16_t len)

Same result as tile_store_o_128_read(); use it when the SPI clock is above the 50 MHz READ (0x03) limit (FAST_READ runs to 104 MHz).

addr
Byte address (0 .. capacity-1).
buf
Output buffer.
len
Number of bytes.

tile_store_o_128_page_program

Studio
void tile_store_o_128_page_program(tile_t* tile, uint32_t addr, const uint8_t* buf, uint16_t len)

Issues Write-Enable, programs, and waits for completion (up to 10 ms; tPP max 5 ms). The caller must keep the write inside one 256-byte page: (addr & 0xFF) + len ≤ 256. Bytes past the page end wrap to the start of the same page (chip behavior), so use tile_store_o_128_write() for unaligned spans. Programming only clears bits: erase first.

addr
Start address.
buf
Data to program.
len
Byte count (1..256).

tile_store_o_128_write

Studio
void tile_store_o_128_write(tile_t* tile, uint32_t addr, const uint8_t* buf, uint32_t len)

Programming only clears bits (1 → 0); erase the covering sector(s) first.

addr
Start address (0 .. capacity-1).
buf
Data to program.
len
Byte count.

tile_store_o_128_erase_sector

Studio
void tile_store_o_128_erase_sector(tile_t* tile, uint32_t addr)

Erase the 4 KB sector containing `addr` (and wait, up to 0.5 s).

addr
Any address inside the sector (low 12 bits ignored).

tile_store_o_128_erase_block

Studio
void tile_store_o_128_erase_block(tile_t* tile, uint32_t addr)

Erase the 64 KB block containing `addr` (and wait, up to 3 s).

addr
Any address inside the block (low 16 bits ignored).

tile_store_o_128_erase_chip

Studio
void tile_store_o_128_erase_chip(tile_t* tile)

Erase the entire chip (and wait; typ 60 s, max 300 s).

tile_store_o_128_wait_ready

Studio
uint8_t tile_store_o_128_wait_ready(tile_t* tile, uint32_t timeout_ms)

Block until any in-progress program/erase finishes, or timeout.

timeout_ms
Max wait.

Returns 1 if ready, 0 if timed out.

Config

tile_store_o_128_write_enable

Studio
void tile_store_o_128_write_enable(tile_t* tile)

Issue Write-Enable (sets WEL). Required before any program/erase.

Driver gaps · 4

Chip capabilities this driver doesn’t expose yet.

nicheQuad / QPI I/O modesThe AT25QL128A supports Dual/Quad SPI and QPI (≤4 data lines). This driver drives standard single-lane SPI only; quad modes need a quad-capable SPI transfer in the platform layer (driver-deferred, not chip-gated).
advancedBlock protection / status register writeNo Write Status Register (0x01/0x31) support: BP/TB/SEC/CMP block protection, SRP lock modes and the QE bit can't be changed. Factory default is nothing protected, so program/erase work out of the box (driver-deferred).
niche32 KB block eraseThe chip also erases 32 KB blocks (0x52); the driver exposes only 4 KB sector, 64 KB block and chip erase (driver-deferred).
nicheSuspend / resume, reset, OTP, SFDPErase/program suspend-resume (0x75/0x7A), software reset (0x66/0x99), the 4 kbit one-time-programmable security register and the SFDP table are not exposed (driver-deferred).

Constants

TILE_STORE_O_128_VERSION_MAJOR1
TILE_STORE_O_128_VERSION_MINOR1
TILE_STORE_O_128_VERSION_PATCH0
AT25QL128A_CAPACITY0x1000000
AT25QL128A_PAGE_SIZE256
AT25QL128A_SECTOR_SIZE4096
AT25QL128A_BLOCK_SIZE65536
AT25QL128A_MFR_ID0x1FAdesto / Renesas manufacturer
AT25QL128A_CAPACITY_ID0x182^24 bytes density code
AT25QL128A_CMD_WREN0x06Write Enable
AT25QL128A_CMD_WRDI0x04Write Disable
AT25QL128A_CMD_RDID0x9FRead JEDEC ID (3 bytes)
AT25QL128A_CMD_RDSR10x05Read Status Register 1
AT25QL128A_CMD_RDSR20x35Read Status Register 2
AT25QL128A_CMD_WRSR0x01Write Status Register
AT25QL128A_CMD_READ0x03Read Data (cmd + 24-bit addr)
AT25QL128A_CMD_FAST_READ0x0BFast Read (+1 dummy byte)
AT25QL128A_CMD_PP0x02Page Program
AT25QL128A_CMD_SE0x20Sector Erase (4 KB)
AT25QL128A_CMD_BE0xD8Block Erase (64 KB)
AT25QL128A_CMD_CE0xC7Chip Erase
AT25QL128A_CMD_DP0xB9Deep Power-Down
AT25QL128A_CMD_RDP0xABRelease from Deep Power-Down
AT25QL128A_SR1_WIP0x01Write In Progress (busy)
AT25QL128A_SR1_WEL0x02Write Enable Latch