pm-grid: harden FAT-read boot (fix black screen regression)
The drive-read at boot bricked the display (barely blinked, then black). Likely the new fatfs + owned set lists exhausted the 24KB heap (alloc panic -> halt before the splash). Three fixes: - Heap 24KB -> 96KB (Pico has 264KB). - format_pmg1 writes one 4KB sector per call (the proven MSC write pattern) instead of a single 7-sector erase+program. - Run read_user_setlists AFTER the splash, so a FAT/flash failure can no longer leave the screen black; added defmt logs around it to localize any remaining failure over the probe. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
768ec0021f
commit
219fb267a0
1 changed files with 19 additions and 10 deletions
|
|
@ -141,11 +141,19 @@ impl fatfs::Seek for FlashIo {
|
|||
}
|
||||
|
||||
/// Write the blank PM_G-1 template over the metadata sectors (erases the leftover volume → empty).
|
||||
/// One 4 KB sector per call — exactly the proven MSC write pattern (a multi-sector call is riskier).
|
||||
fn format_pmg1() {
|
||||
let faddr = FILESYSTEM.as_ptr() as u32 & 0x00ff_ffff & !0xfff; // flash offset 0x100000
|
||||
let base = FILESYSTEM.as_ptr() as u32 & 0x00ff_ffff & !0xfff; // flash offset 0x100000
|
||||
let sz = FS_BLOCK_SIZE as usize;
|
||||
let sectors = FAT_TEMPLATE.len() / sz;
|
||||
for s in 0..sectors {
|
||||
let mut sector = [0u8; FS_BLOCK_SIZE as usize];
|
||||
sector.copy_from_slice(&FAT_TEMPLATE[s * sz..(s + 1) * sz]);
|
||||
let faddr = base + (s as u32) * FS_BLOCK_SIZE;
|
||||
cortex_m::interrupt::free(|_| unsafe {
|
||||
rp2040_flash::flash::flash_range_erase_and_program(faddr, FAT_TEMPLATE, false);
|
||||
rp2040_flash::flash::flash_range_erase_and_program(faddr, §or, false);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/// Mount the drive; if it isn't a "PM_G-1"-labelled FAT, format it. Then read programs.json (if any)
|
||||
|
|
@ -1538,7 +1546,7 @@ fn main() -> ! {
|
|||
// heap for track-format (Vec/String). The Pico has 264 KB SRAM; 24 KB is plenty for a track.
|
||||
{
|
||||
use core::mem::MaybeUninit;
|
||||
const HEAP_SIZE: usize = 24 * 1024;
|
||||
const HEAP_SIZE: usize = 96 * 1024; // fatfs + owned set lists + track parse (Pico has 264 KB)
|
||||
static mut HEAP_MEM: [MaybeUninit<u8>; HEAP_SIZE] = [MaybeUninit::uninit(); HEAP_SIZE];
|
||||
unsafe { HEAP.init(core::ptr::addr_of_mut!(HEAP_MEM) as usize, HEAP_SIZE) }
|
||||
}
|
||||
|
|
@ -1578,11 +1586,6 @@ fn main() -> ! {
|
|||
|
||||
let mut mtx = Matrix::new(i2c, &mut delay);
|
||||
|
||||
// Read the drive's set lists (and (re)format it to "PM_G-1" if it isn't ours) — BEFORE USB
|
||||
// setup, so the one-time format flash-write can't disrupt enumeration.
|
||||
let user_setlists = read_user_setlists();
|
||||
info!("boot: {} total set list(s)", SETLISTS.len() + user_setlists.len());
|
||||
|
||||
// --- USB-MIDI: the Scroll Pack has no speaker, so clicks play through the host (the editor's
|
||||
// "Device audio"). We send a GM note-on per lane hit on channel 10. ---
|
||||
let usb_bus = UsbBusAllocator::new(hal::usb::UsbBus::new(
|
||||
|
|
@ -1622,6 +1625,12 @@ fn main() -> ! {
|
|||
let mut btn_y = pins.gpio15.into_pull_up_input();
|
||||
|
||||
let now_us = || timer.get_counter().ticks() as i64;
|
||||
// Read the drive's set lists (and (re)format it to "PM_G-1" if it isn't ours). Done AFTER the
|
||||
// splash so the screen shows life first and a FAT/flash problem can't leave it black.
|
||||
info!("fat: reading drive...");
|
||||
let user_setlists = read_user_setlists();
|
||||
info!("boot: {} total set list(s)", SETLISTS.len() + user_setlists.len());
|
||||
|
||||
let mut app = App::new(now_us() * 1000, user_setlists);
|
||||
info!("groove: bpm={} lanes={}", app.tempo, app.track.lanes.len());
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue