Skip to content

Commit ebf391e

Browse files
committed
fix: Use transfer instead of read + write
One some hardware like stm32 it's not guaranteed to be one transaction. Signed-off-by: Arthur Heymans <arthur@aheymans.xyz>
1 parent a594724 commit ebf391e

File tree

1 file changed

+21
-33
lines changed

1 file changed

+21
-33
lines changed

serprog/src/lib.rs

Lines changed: 21 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -305,23 +305,13 @@ where
305305
}
306306
SerprogCommand::OSpiOp => {
307307
debug!("Received OSpiOp CMD");
308-
let mut sdata = [0_u8; MAX_BUFFER_SIZE + 6];
309-
if let Err(e) = self.transport.read(sdata.as_mut_slice()).await {
308+
let mut spi_data = [0_u8; MAX_BUFFER_SIZE * 2 + 6]; // Use twice the size for read and write
309+
if let Err(e) = self.transport.read(&mut spi_data).await {
310310
error!("Error reading packet: {:?}", e);
311311
return;
312312
}
313-
let op_slen = le_u24_to_u32(&sdata[0..3]) as usize;
314-
let op_rlen = le_u24_to_u32(&sdata[3..6]) as usize;
315-
316-
let mut rdata = [0_u8; MAX_BUFFER_SIZE];
317-
318-
let sdata = &sdata.as_slice()[6..6 + op_slen];
319-
320-
debug!(
321-
"Starting SPI transfer, sdata: {:?}, rdata: {:?}",
322-
&sdata[..op_slen as usize],
323-
&rdata[..op_rlen as usize]
324-
);
313+
let op_slen = le_u24_to_u32(&spi_data[0..3]) as usize;
314+
let op_rlen = le_u24_to_u32(&spi_data[3..6]) as usize;
325315

326316
// This call is blocking according to the SPI HAL
327317
if (self.spi.flush().await).is_err() {
@@ -332,28 +322,26 @@ where
332322
error!("Error setting CS low");
333323
}
334324

335-
match self.spi.write(&sdata[..op_slen as usize]).await {
325+
let spi_data = &mut spi_data[6..][..op_rlen + op_slen];
326+
327+
match self
328+
.spi
329+
.transfer_in_place(spi_data)
330+
.await
331+
{
336332
Ok(_) => {
337333
debug!("SPI transfer successful");
338-
debug!("Received data (rdata): {:?}", &rdata[..op_rlen as usize]);
339-
match self.spi.read(&mut rdata[..op_rlen as usize]).await {
340-
Ok(_) => {
341-
debug!("SPI read successful");
342-
debug!("Received data (rdata): {:?}", &rdata[..op_rlen as usize]);
343-
if let Err(e) = self.transport.write(&[S_ACK]).await {
344-
error!("Error writing packet: {:?}", e);
345-
}
346-
347-
// Send the full rdata in chunks
348-
let _ = self.transport.write(&rdata[..op_rlen as usize]).await;
349-
}
350-
Err(_) => {
351-
error!("SPI read error");
352-
if let Err(e) = self.transport.write(&[S_NAK]).await {
353-
error!("Error writing NAK: {:?}", e);
354-
}
355-
}
334+
if let Err(e) = self.transport.write(&[S_ACK]).await {
335+
error!("Error writing packet: {:?}", e);
336+
}
337+
// Embedded HAL says "Implementations are allowed to return before
338+
// the operation is complete" so flush here.
339+
if (self.spi.flush().await).is_err() {
340+
error!("Error flushing SPI");
356341
}
342+
let rdata = &spi_data[op_slen..];
343+
// Send the full rdata in chunks
344+
let _ = self.transport.write(rdata).await;
357345
}
358346
Err(_) => {
359347
error!("SPI transfer error");

0 commit comments

Comments
 (0)