Commit graph

4 commits

Author SHA1 Message Date
Julian Oes
2fd76ea150 drivers/mtd/w25n: address review comments
- Replace syslog() with finfo()/fwarn() to follow the NuttX subsystem
  debug convention.
- Merge adjacent early-continue `if` branches in w25n_pick_free_spare
  and w25n_scan_factory_bad.
- Add Input Parameters / Returned Value sections to the BBM helper
  headers.
- Clarify why only -EIO triggers a remap retry in w25n_erase and
  w25n_bwrite (block-level E-FAIL/P-FAIL vs. transient bus faults).

Signed-off-by: Julian Oes <julian@oes.ch>
2026-04-23 16:26:44 +02:00
Julian Oes
0c287d6f45 drivers/mtd/w25n: implement bad block management
Use the chip's built-in 20-entry non-volatile Bad Block Management
Look-Up Table (datasheet section 8.2.7) to transparently route around
bad blocks.

Init:
- Reserve the top 24 blocks of the array as a spare pool
- Clamp the MTD geometry to W25N_USER_BLOCKS = 1000 so upper layers
  never see the spare area (125 MB usable instead of 128 MB)
- Force BUF=1 alongside enabling ECC. The W25N01GVxxIT variant
  power-ups with BUF=0 (Continuous Read mode), in which Read Data
  ignores the column address and always starts at byte 0 - which
  silently broke any read targeting a non-zero column (OOB markers,
  sub-page reads in w25n_read).
- Scan all 1024 blocks for factory bad markers (non-FFh at byte 0 of
  the spare area of page 0) and remap any user-area bad blocks via the
  A1h BBM command. Idempotent across reboots: blocks already present
  in the LUT are skipped, so repeated scans don't consume LUT slots.

Runtime:
- On E-FAIL from w25n_block_erase or P-FAIL from w25n_program_execute,
  allocate a spare and issue A1h, then retry the operation once. The
  chip routes the retry to the spare PBA transparently. Data buffer is
  reloaded on program retry.
- Uncorrectable read ECC is left as -EIO (soft errors shouldn't trigger
  permanent remap, and remapping discards data we may still recover).

Safeguards against burning LUT slots on bogus bad blocks:
- w25n_pick_free_spare erases each candidate spare as an active proof
  of life before returning it - the factory OOB marker alone isn't
  trusted.
- w25n_bbm_swap rejects A1h with LBA outside the user area or PBA
  outside the spare pool.

Stack discipline for the logger-thread hot path:
- The 20-entry cached LUT lives in the device struct, not on the stack.
- w25n_read_bbm_lut decodes 4 bytes at a time instead of reading the
  full 80-byte LUT dump into a local buffer.

Boot diagnostics are emitted via syslog so they appear unconditionally:
- [w25n] BBM scan summary (new/remapped/unremapped/previously-remapped/
  LUT slots used)
- [w25n] W25N01GV ready line with user blocks, spare count, geometry,
  and actual SPI frequency
- [w25n] per-remap info and warnings on runtime E-FAIL/P-FAIL paths

Note: existing littlefs filesystems become unmountable because the
block count shrinks from 1024 to 1000; both PX4 board init.c paths
already mount with autoformat so they reformat on first boot after
this change.

Signed-off-by: Julian Oes <julian@oes.ch>
2026-04-23 16:26:44 +02:00
Piyush Patle
0dccc8ba21 include/debug.h: Move to include/nuttx/debug.h
debug.h is a NuttX-specific, non-POSIX header. Placing it in the
top-level include/ directory creates naming conflicts with external
projects that define their own debug.h.
This commit moves the canonical header to include/nuttx/debug.h,
following the NuttX convention for non-POSIX/non-standard headers,
and updates all in-tree references.

A backward-compatibility shim is left at include/debug.h that
emits a deprecation #warning and re-includes <nuttx/debug.h>,
allowing out-of-tree code to continue building while migrating.

Signed-off-by: Piyush Patle <piyushpatle228@gmail.com>
2026-04-07 07:50:06 -03:00
Julian Oes
7e46d282eb drivers/mtd: Add W25N SPI NAND flash driver
Add MTD driver for Winbond W25N series SPI NAND flash.

Currently supports W25N01GV (1Gbit/128MB).

Features:
- Standard SPI interface with configurable frequency (up to 104 MHz)
- Hardware ECC enabled by default
- Block erase with sleep-based wait (releases SPI bus)
- Page read/write with busy-wait for fast operations

Limitations:
- No bad block management (BBM). Factory bad blocks and runtime bad
  blocks are not tracked.
- No bad block table (BBT) scanning at initialization.
- No Quad SPI support (standard SPI only).
- No access to spare area (64 bytes/page) or OTP region.

Tested using:
- Board with STM32H743
- W25N01GV on SPI at 96 MHz with DMA enabled
- Flash mounted using littlefs
- Tested using sdbench:
  - Sequential write speed of 1760 KB/s
  - Sequential read speed of 4900 KB/s

Signed-off-by: Julian Oes <julian@oes.ch>
2025-12-19 10:00:33 +08:00