Found by an adversarial review of last week's changes.
- disk_ioctl(GET_SECTOR_COUNT): add READ_BL_LEN and C_SIZE_MULT of CSD v1
cards (<= 2 GB) instead of ORing them. USB DISK mode reported half or a
quarter of the card size. Mask the reserved bits of C_SIZE for CSD v2.
- fw_update_ui() is not inlined into browser_open_file(): its locals
enlarged the browser's stack frame from 280 to 416 bytes for every file
type, leaving little headroom on the sweep thread stack.
- Firmware update: the image trailer is a C constant built from the
fw_update.h values, the linker script only places it; the RAM range check
uses the linker's RAM symbols; SD_SPI_SPEED and SD_INIT_SPI_SPEED move to
spi.h and are shared with the flasher, with a build check that the LCD
uses the same speed; the linker script checks that the flasher's write
limit (SAVE_CONFIG_ADDR) is the end of flash0.
STORAGE -> UPDATE FIRMWARE installs a firmware .bin from the SD card.
The shell command "fwupdate {file}" checks a file, "fwupdate {file} flash"
installs it. Config, calibration and presets (0x0803C000 and up) are never
touched; ROM DFU (jog held at power-on) stays the recovery.
- Image format: STM32F303xC.ld inlines the code rules to place a header
(magic, model, size, version) directly after the vector table and a
trailer (end magic, size, CRC field left unset) at the end of the image.
Only images with the header are accepted.
- Before anything is erased, the running firmware reads the whole file with
FatFs (page CRCs, image CRC, card sector map from FIL.clust) and reads it
again with the raw sector reader used by the update (dry run).
- The flasher runs from CCM RAM with interrupts off and VTOR in CCM. It keeps
page 0 in RAM, erases page 0 first and programs it last after a full image
CRC check, skips unchanged pages, retries errors without user input and
initializes the SD card again after it was removed or keeps failing.
It draws a progress bar and resets only after jog is released, because
jog pressed at reset starts the ROM bootloader.