Files
audio_project_hub/src/storage/storage_config.h
T
2026-08-14 08:24:33 -06:00

160 lines
7.1 KiB
C

#pragma once
// ============================================================================
// Storage configuration
// ============================================================================
//
// This header is the single place to configure how the Hub talks to the
// SD card. Two hardware interfaces are supported by the Arduino-ESP32
// framework, and both are implemented behind the StorageBackend interface
// in sd_manager.cpp:
//
// STORAGE_IFACE_SPI - Uses the `SD` library (SPI protocol). This is the
// bring-up path for the current breakout module,
// which only breaks out the 4 SPI lines.
// Max practical throughput: ~1-2 MB/s. NOT enough
// for the 6-8 MB/s audio logging target.
//
// STORAGE_IFACE_SDMMC - Uses the `SD_MMC` library (SDIO protocol, the
// SDMMC peripheral). This is the production path.
// 4-bit mode @ 40 MHz (SDMMC_FREQ_HIGHSPEED) gives
// roughly 8-12 MB/s, which comfortably meets the
// target. REQUIRED for the final design.
//
// TO MIGRATE TO SDIO (the new SDIO-capable board that is being shipped):
//
// 1. Change STORAGE_IFACE below from STORAGE_IFACE_SPI to
// STORAGE_IFACE_SDMMC.
//
// 2. Wire the SD card to the SDIO lines listed in the STORAGE_SDMMC_*
// defines below. On the classic ESP32 the SDMMC peripheral is routed
// through the GPIO matrix, so these pins can be changed to any free
// GPIO simply by editing the defines.
//
// 3. Keep STORAGE_SDMMC_MODE_1BIT as `false` (4-bit bus is required for
// the write throughput) and keep STORAGE_SDMMC_FORMAT_IF_FAILED as
// `false` (a foreign/unformatted card must never be auto-formatted).
//
// 4. Everything downstream (StorageTask, SDManager, and the future
// DataLogger) talks only through the `fs::FS` interface, so no other
// code changes are needed.
// ============================================================================
// --- Backend selection ------------------------------------------------------
#define STORAGE_IFACE_SPI 1
#define STORAGE_IFACE_SDMMC 2
// SPI until the SDIO-capable board arrives.
#ifndef STORAGE_IFACE
#define STORAGE_IFACE STORAGE_IFACE_SDMMC
#endif
// --- Common -----------------------------------------------------------------
// Single canonical mount point so file paths never change when the backend
// is switched (the SD lib defaults to "/sd", SD_MMC to "/sdcard").
#define STORAGE_MOUNT_POINT "/sdcard"
#define STORAGE_MAX_OPEN_FILES 5
// --- SPI (bring-up only) ----------------------------------------------------
// Default VSPI pins on the classic ESP32 DevKitC (variant/pins_arduino.h).
#define STORAGE_SPI_CS 5
#define STORAGE_SPI_SCK 18
#define STORAGE_SPI_MOSI 23
#define STORAGE_SPI_MISO 19
// 10 MHz is a reliable default for breadboard/jumper-wire bring-up. The SD
// init handshake always runs at 400 kHz regardless (see sd_diskio.cpp), so a
// mount failure is NOT a frequency problem - check power, wiring, pull-ups
// and card seating first. Raise to 20 MHz once the wiring is proven.
#define STORAGE_SPI_FREQ 10000000UL
// --- SDIO / SD_MMC (production, 4-bit) --------------------------------------
// Default ESP32 SDMMC slot-1 pins (GPIO matrix, freely re-routable).
// Interface 1: #define STORAGE_SDMMC_CLK 6
// Interface 1: #define STORAGE_SDMMC_CMD 11
// Interface 1: #define STORAGE_SDMMC_D0 7
// Interface 1: #define STORAGE_SDMMC_D1 8
// Interface 1: #define STORAGE_SDMMC_D2 9
// Interface 1: #define STORAGE_SDMMC_D3 10
#define STORAGE_SDMMC_CLK 14
#define STORAGE_SDMMC_CMD 15
#define STORAGE_SDMMC_D0 2
#define STORAGE_SDMMC_D1 4
#define STORAGE_SDMMC_D2 12
#define STORAGE_SDMMC_D3 13
// false = 4-bit wide bus (required for >8 MB/s). Do NOT enable 1-bit mode.
#define STORAGE_SDMMC_MODE_1BIT false
// NEVER auto-format: an unformatted/foreign card must never be destroyed.
#define STORAGE_SDMMC_FORMAT_IF_FAILED false
// 40 MHz == SDMMC_FREQ_HIGHSPEED. Written as a literal to keep this header
// free of driver includes.
#define STORAGE_SDMMC_FREQ_HZ 40000000
// --- Boot-time file listing -------------------------------------------------
// Maximum directory depth printed during the recursive boot listing. Guards
// the StorageTask stack against pathological directory nesting.
#define STORAGE_LIST_MAX_DEPTH 10
// --- Write-speed estimation -------------------------------------------------
// Path of the temporary scratch file used to measure write throughput. It is
// created, written, measured, then deleted, so it never appears in listings.
#define STORAGE_SPEED_MEASURE_PATH STORAGE_MOUNT_POINT "/.writespeed.tmp"
// Size of the scratch file written per measurement (bytes).
#define STORAGE_SPEED_MEASURE_BYTES (0.5 * 1024 * 1024)
// How often to re-measure write speed (ms). This is a bring-up ESTIMATE only:
// it writes STORAGE_SPEED_MEASURE_BYTES to the card on every tick. Once real
// logging exists, throughput should be derived from actual logging writes and
// this benchmark disabled by setting the interval to 0 (measure once at boot).
#define STORAGE_SPEED_MEASURE_INTERVAL_MS 0
// --- Bring-up sanity test ----------------------------------------------------
// Small fixed-content file written at boot to prove the card's write path
// works end to end (create/open/write/close on the live mount).
#define STORAGE_TEST_FILE_PATH STORAGE_MOUNT_POINT "/happy_file.txt"
// --- Audio logging ----------------------------------------------------------
//
// The DataLogger (docs/audio_logging.md) writes one multichannel WAV file
// per rotation. The Node collection task feeds it interleaved 40-channel PCM
// as chunks; the logger appends them and only the consumer touches the card.
//
// Stream rate: 40 ch x 48 kHz x 2 B = 3,840,000 B/s. The 64 KB pool holds
// ~17 ms of audio, so collection rounds must stay <= ~12 ms (<= 48 KB) or
// the pool must grow (see docs/audio_logging.md section 7).
// WAV parameters (must match what the Nodes produce).
#define STORAGE_AUDIO_SAMPLE_RATE_HZ 48000
#define STORAGE_AUDIO_CHANNELS 40 // 10 nodes x 4 mics
#define STORAGE_AUDIO_BITS 16
// Chunk pool: STORAGE_LOG_POOL_SIZE chunks of STORAGE_LOG_CHUNK_SIZE bytes,
// allocated with MALLOC_CAP_DMA. 64 KB total. Each interleave round (see
// NET_ROUND_FRAMES) must fit inside one chunk.
#define STORAGE_LOG_CHUNK_SIZE (8 * 1024)
#define STORAGE_LOG_POOL_SIZE 8
// Recording directory and rotation policy.
#define STORAGE_LOG_DIR STORAGE_MOUNT_POINT "/audio"
#define STORAGE_LOG_ROTATE_BYTES (1024LL * 1024 * 1024) // 1 GiB / file
#define STORAGE_LOG_FLUSH_BYTES (16LL * 1024 * 1024) // f_sync cadence
// Overflow warning LED: lights while chunks are being dropped because the SD
// card cannot keep up. GPIO 4 is unused by the SD card lines (SPI 5/18/19/23,
// SDMMC 6-11). Change both values if a different LED is wired.
#define STORAGE_WARN_LED_GPIO 4
#define STORAGE_WARN_LED_ACTIVE_HIGH true