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).
|
/// 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() {
|
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 {
|
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)
|
/// 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.
|
// heap for track-format (Vec/String). The Pico has 264 KB SRAM; 24 KB is plenty for a track.
|
||||||
{
|
{
|
||||||
use core::mem::MaybeUninit;
|
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];
|
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) }
|
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);
|
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
|
// --- 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. ---
|
// "Device audio"). We send a GM note-on per lane hit on channel 10. ---
|
||||||
let usb_bus = UsbBusAllocator::new(hal::usb::UsbBus::new(
|
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 mut btn_y = pins.gpio15.into_pull_up_input();
|
||||||
|
|
||||||
let now_us = || timer.get_counter().ticks() as i64;
|
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);
|
let mut app = App::new(now_us() * 1000, user_setlists);
|
||||||
info!("groove: bpm={} lanes={}", app.tempo, app.track.lanes.len());
|
info!("groove: bpm={} lanes={}", app.tempo, app.track.lanes.len());
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue