Skip to content

Commit c61301f

Browse files
committed
Keep the page read/write loops in the library
The page loops (init_read + read_page x N, init_write + write_page x N) are mechanical protocol with no timing, so they belong in the library as ISPDevice::read/write rather than being duplicated in every consumer. They take a dep-free '&dyn Fn(done, total)' progress callback, so the loop stays in the lib without dragging back any runtime/UI dependency. The CLI flasher (and the web app) now just create their progress bar, pass a callback, and keep owning the surrounding cycle: sequencing, the post-erase/reboot settle delays, and verification.
1 parent 3216b36 commit c61301f

2 files changed

Lines changed: 71 additions & 23 deletions

File tree

crates/sinowealth-isp/src/isp_device.rs

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,54 @@ impl ISPDevice {
191191
Ok(())
192192
}
193193

194+
/// Reads `length` bytes starting at `start_addr` by looping over pages.
195+
///
196+
/// `progress` is invoked after each page with `(pages_done, pages_total)`;
197+
/// pass `&|_, _| {}` if you do not need it. This is mechanical protocol with
198+
/// no delays, so it stays in the library; sequencing it into a full read
199+
/// cycle (and the surrounding settle delays) is the caller's job.
200+
pub async fn read(
201+
&self,
202+
start_addr: usize,
203+
length: usize,
204+
progress: &dyn Fn(usize, usize),
205+
) -> Result<Vec<u8>, ISPError> {
206+
let page_size = self.device_spec.platform.page_size;
207+
let num_page = length / page_size;
208+
209+
self.init_read(start_addr).await?;
210+
211+
let mut result: Vec<u8> = vec![];
212+
for i in 0..num_page {
213+
self.read_page(&mut result).await?;
214+
progress(i + 1, num_page);
215+
}
216+
Ok(result)
217+
}
218+
219+
/// Writes `num_pages` pages from `buffer`, starting at `start_addr`.
220+
///
221+
/// `progress` is invoked after each page with `(pages_done, pages_total)`;
222+
/// pass `&|_, _| {}` if you do not need it.
223+
pub async fn write(
224+
&self,
225+
start_addr: usize,
226+
buffer: &[u8],
227+
progress: &dyn Fn(usize, usize),
228+
) -> Result<(), ISPError> {
229+
let page_size = self.device_spec.platform.page_size;
230+
let num_page = self.device_spec.num_pages();
231+
232+
self.init_write(start_addr).await?;
233+
234+
for i in 0..num_page {
235+
self.write_page(&buffer[(i * page_size)..((i + 1) * page_size)])
236+
.await?;
237+
progress(i + 1, num_page);
238+
}
239+
Ok(())
240+
}
241+
194242
/// Erases everything in flash, except the ISP bootloader section itself and initializes the
195243
/// reset vector to jump to ISP.
196244
///

crates/sinowealth-kb-tool/src/flasher.rs

Lines changed: 23 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -67,42 +67,42 @@ pub fn write_cycle(device: &ISPDevice, firmware: &mut [u8]) -> Result<(), ISPErr
6767
fn read(device: &ISPDevice, start_addr: usize, length: usize) -> Result<Vec<u8>, ISPError> {
6868
let page_size = device.device_spec().platform.page_size;
6969
let num_page = length / page_size;
70-
let mut result: Vec<u8> = vec![];
7170

7271
eprintln!("Reading...");
7372
let bar = ProgressBar::new(num_page as u64);
7473

75-
device.init_read(start_addr).wait()?;
74+
let result = device
75+
.read(start_addr, length, &|done, _total| {
76+
debug!(
77+
"Reading page {} @ offset {:#06x}",
78+
done - 1,
79+
start_addr + (done - 1) * page_size
80+
);
81+
bar.set_position(done as u64);
82+
})
83+
.wait()?;
7684

77-
for i in 0..num_page {
78-
bar.inc(1);
79-
debug!(
80-
"Reading page {} @ offset {:#06x}",
81-
i,
82-
start_addr + i * page_size
83-
);
84-
device.read_page(&mut result).wait()?;
85-
}
8685
bar.finish();
8786
Ok(result)
8887
}
8988

9089
fn write(device: &ISPDevice, start_addr: usize, buffer: &[u8]) -> Result<(), ISPError> {
91-
let spec = *device.device_spec();
92-
let page_size = spec.platform.page_size;
90+
let page_size = device.device_spec().platform.page_size;
9391

9492
eprintln!("Writing...");
95-
let bar = ProgressBar::new(spec.num_pages() as u64);
93+
let bar = ProgressBar::new(device.device_spec().num_pages() as u64);
94+
95+
device
96+
.write(start_addr, buffer, &|done, _total| {
97+
debug!(
98+
"Writing page {} @ offset {:#06x}",
99+
done - 1,
100+
(done - 1) * page_size
101+
);
102+
bar.set_position(done as u64);
103+
})
104+
.wait()?;
96105

97-
device.init_write(start_addr).wait()?;
98-
99-
for i in 0..spec.num_pages() {
100-
bar.inc(1);
101-
debug!("Writing page {} @ offset {:#06x}", i, i * page_size);
102-
device
103-
.write_page(&buffer[(i * page_size)..((i + 1) * page_size)])
104-
.wait()?;
105-
}
106106
bar.finish();
107107
Ok(())
108108
}

0 commit comments

Comments
 (0)