@@ -11,10 +11,22 @@ use transport::Transport;
1111use zerocopy:: byteorder:: little_endian:: { U16 , U32 } ;
1212use zerocopy:: { FromBytes , FromZeros , Immutable , IntoBytes , Unaligned } ;
1313
14- use defmt:: { debug, error} ;
14+ use defmt:: { debug, error, Format } ;
1515
1616pub mod transport;
1717
18+ #[ derive( Format ) ]
19+ pub enum SerprogError {
20+ TransportRead ( & ' static str ) ,
21+ TransportWrite ( & ' static str ) ,
22+ SpiTransfer ( & ' static str ) ,
23+ SpiFlush ( & ' static str ) ,
24+ CsSetLow ( & ' static str ) ,
25+ CsSetHigh ( & ' static str ) ,
26+ LedSetLow ( & ' static str ) ,
27+ LedSetHigh ( & ' static str ) ,
28+ }
29+
1830// Convert 3 bytes in little-endian format to u32
1931fn le_u24_to_u32 ( bytes : & [ u8 ] ) -> u32 {
2032 u32:: from_le_bytes ( [ bytes[ 0 ] , bytes[ 1 ] , bytes[ 2 ] , 0 ] )
@@ -213,155 +225,180 @@ where
213225 let mut buf = [ 0 ; 1 ] ;
214226
215227 loop {
216- if let Err ( e ) = self . transport . read ( & mut buf) . await {
217- error ! ( "Read error: {:?}" , e ) ;
228+ if self . transport . read ( & mut buf) . await . is_err ( ) {
229+ error ! ( "Read error in main loop" ) ;
218230 continue ;
219231 }
220232
221233 let cmd = SerprogCommand :: try_from ( buf[ 0 ] ) . unwrap_or ( SerprogCommand :: Nop ) ;
222- self . handle_command ( cmd) . await ;
234+ if let Err ( e) = self . handle_command ( cmd) . await {
235+ error ! ( "Command error: {:?}" , e) ;
236+ }
223237 }
224238 }
225239
226- async fn handle_command ( & mut self , cmd : SerprogCommand )
240+ async fn handle_command ( & mut self , cmd : SerprogCommand ) -> Result < ( ) , SerprogError >
227241 where
228242 CS :: Error : core:: fmt:: Debug ,
229243 LED :: Error : core:: fmt:: Debug ,
230244 {
231245 match cmd {
232246 SerprogCommand :: Nop => {
233247 debug ! ( "Received Nop CMD" ) ;
234- if let Err ( e) = self . transport . write ( & [ S_ACK ] ) . await {
235- error ! ( "Error writing packet: {:?}" , e) ;
236- }
248+ self . transport
249+ . write ( & [ S_ACK ] )
250+ . await
251+ . map_err ( |_| SerprogError :: TransportWrite ( "Error writing ACK" ) ) ?;
252+ Ok ( ( ) )
237253 }
238254 SerprogCommand :: QIface => {
239255 debug ! ( "Received QIface CMD" ) ;
240256 let response = QIfaceResponse {
241257 ack : S_ACK ,
242258 version : U16 :: new ( 1 ) ,
243259 } ;
244- if let Err ( e) = self . transport . write ( response. as_bytes ( ) ) . await {
245- error ! ( "Error writing packet: {:?}" , e) ;
246- }
260+ self . transport
261+ . write ( response. as_bytes ( ) )
262+ . await
263+ . map_err ( |_| SerprogError :: TransportWrite ( "Error writing QIface response" ) ) ?;
264+ Ok ( ( ) )
247265 }
248266 SerprogCommand :: QCmdMap => {
249267 debug ! ( "Received QCmdMap CMD" ) ;
250268 let response = QCmdMapResponse :: new ( self . freq_callback . is_some ( ) ) ;
251- if let Err ( e) = self . transport . write ( response. as_bytes ( ) ) . await {
252- error ! ( "Error writing packet: {:?}" , e) ;
253- }
269+ self . transport
270+ . write ( response. as_bytes ( ) )
271+ . await
272+ . map_err ( |_| SerprogError :: TransportWrite ( "Error writing QCmdMap response" ) ) ?;
273+ Ok ( ( ) )
254274 }
255275 SerprogCommand :: QPgmName => {
256276 debug ! ( "Received QPgmName CMD" ) ;
257277 let response = QPgmNameResponse :: new ( "Picoprog" ) ;
258- if let Err ( e) = self . transport . write ( response. as_bytes ( ) ) . await {
259- error ! ( "Error writing packet: {:?}" , e) ;
260- }
278+ self . transport
279+ . write ( response. as_bytes ( ) )
280+ . await
281+ . map_err ( |_| SerprogError :: TransportWrite ( "Error writing QPgmName response" ) ) ?;
282+ Ok ( ( ) )
261283 }
262284 SerprogCommand :: QSerBuf => {
263285 debug ! ( "Received QSerBuf CMD" ) ;
264- if let Err ( e) = self . transport . write ( & [ S_ACK , 0xFF , 0xFF ] ) . await {
265- error ! ( "Error writing packet: {:?}" , e) ;
266- }
286+ self . transport
287+ . write ( & [ S_ACK , 0xFF , 0xFF ] )
288+ . await
289+ . map_err ( |_| SerprogError :: TransportWrite ( "Error writing QSerBuf response" ) ) ?;
290+ Ok ( ( ) )
267291 }
268292 SerprogCommand :: QWrNMaxLen | SerprogCommand :: QRdNMaxLen => {
269293 debug ! ( "Received QWrNMaxLen/QRdNMaxLen CMD" ) ;
270294 let response = QMaxLenResponse :: new ( MAX_BUFFER_SIZE ) ;
271- if let Err ( e) = self . transport . write ( response. as_bytes ( ) ) . await {
272- error ! ( "Error writing packet: {:?}" , e) ;
273- }
295+ self . transport
296+ . write ( response. as_bytes ( ) )
297+ . await
298+ . map_err ( |_| SerprogError :: TransportWrite ( "Error writing QMaxLen response" ) ) ?;
299+ Ok ( ( ) )
274300 }
275301 SerprogCommand :: QBustype => {
276302 debug ! ( "Received QBustype CMD" ) ;
277- if let Err ( e) = self . transport . write ( & [ S_ACK , 0x08 ] ) . await {
278- error ! ( "Error writing packet: {:?}" , e) ;
279- }
303+ self . transport
304+ . write ( & [ S_ACK , 0x08 ] )
305+ . await
306+ . map_err ( |_| SerprogError :: TransportWrite ( "Error writing QBustype response" ) ) ?;
307+ Ok ( ( ) )
280308 }
281309 SerprogCommand :: SyncNop => {
282310 debug ! ( "Received SyncNop CMD" ) ;
283- if let Err ( e) = self . transport . write ( & [ S_NAK , S_ACK ] ) . await {
284- error ! ( "Error writing packet: {:?}" , e) ;
285- }
311+ self . transport
312+ . write ( & [ S_NAK , S_ACK ] )
313+ . await
314+ . map_err ( |_| SerprogError :: TransportWrite ( "Error writing SyncNop response" ) ) ?;
315+ Ok ( ( ) )
286316 }
287317 SerprogCommand :: SBustype => {
288318 debug ! ( "Received SBustype CMD" ) ;
289319 let mut buf = [ 0u8 ; 1 ] ;
290- if let Err ( e ) = self . transport . read ( & mut buf ) . await {
291- error ! ( "Error reading packet: {:?}" , e ) ;
292- return ;
293- }
320+ self . transport
321+ . read ( & mut buf )
322+ . await
323+ . map_err ( |_| SerprogError :: TransportRead ( "Error reading SBustype data" ) ) ? ;
294324 if buf[ 0 ] == 0x08 {
295325 debug ! ( "Received SBustype 'SPI'" ) ;
296- if let Err ( e) = self . transport . write ( & [ S_ACK ] ) . await {
297- error ! ( "Error writing packet: {:?}" , e) ;
298- }
326+ self . transport
327+ . write ( & [ S_ACK ] )
328+ . await
329+ . map_err ( |_| SerprogError :: TransportWrite ( "Error writing SBustype ACK" ) ) ?;
299330 } else {
300331 debug ! ( "Received unknown SBustype" ) ;
301- if let Err ( e) = self . transport . write ( & [ S_NAK ] ) . await {
302- error ! ( "Error writing packet: {:?}" , e) ;
303- }
332+ self . transport
333+ . write ( & [ S_NAK ] )
334+ . await
335+ . map_err ( |_| SerprogError :: TransportWrite ( "Error writing SBustype NAK" ) ) ?;
304336 }
337+ Ok ( ( ) )
305338 }
306339 SerprogCommand :: OSpiOp => {
307340 debug ! ( "Received OSpiOp CMD" ) ;
308341 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 {
310- error ! ( "Error reading packet: {:?}" , e ) ;
311- return ;
312- }
342+ self . transport
343+ . read ( & mut spi_data )
344+ . await
345+ . map_err ( |_| SerprogError :: TransportRead ( "Error reading OSpiOp data" ) ) ? ;
313346 let op_slen = le_u24_to_u32 ( & spi_data[ 0 ..3 ] ) as usize ;
314347 let op_rlen = le_u24_to_u32 ( & spi_data[ 3 ..6 ] ) as usize ;
315348
316349 // This call is blocking according to the SPI HAL
317- if ( self . spi . flush ( ) . await ) . is_err ( ) {
318- error ! ( "Error flushing SPI" ) ;
319- }
350+ self . spi
351+ . flush ( )
352+ . await
353+ . map_err ( |_| SerprogError :: SpiFlush ( "Error flushing SPI before transfer" ) ) ?;
320354
321- if self . cs . set_low ( ) . is_err ( ) {
322- error ! ( "Error setting CS low" ) ;
323- }
355+ self . cs
356+ . set_low ( )
357+ . map_err ( |_| SerprogError :: CsSetLow ( "Error setting CS low" ) ) ? ;
324358
325359 let spi_data = & mut spi_data[ 6 ..] [ ..op_rlen + op_slen] ;
326360
327- match self
328- . spi
329- . transfer_in_place ( spi_data)
330- . await
331- {
361+ match self . spi . transfer_in_place ( spi_data) . await {
332362 Ok ( _) => {
333363 debug ! ( "SPI transfer successful" ) ;
334- if let Err ( e) = self . transport . write ( & [ S_ACK ] ) . await {
335- error ! ( "Error writing packet: {:?}" , e) ;
336- }
364+ self . transport . write ( & [ S_ACK ] ) . await . map_err ( |_| {
365+ SerprogError :: TransportWrite ( "Error writing OSpiOp ACK" )
366+ } ) ?;
367+
337368 // Embedded HAL says "Implementations are allowed to return before
338369 // the operation is complete" so flush here.
339- if ( self . spi . flush ( ) . await ) . is_err ( ) {
340- error ! ( "Error flushing SPI" ) ;
341- }
370+ self . spi . flush ( ) . await . map_err ( |_| {
371+ SerprogError :: SpiFlush ( "Error flushing SPI after transfer" )
372+ } ) ?;
373+
342374 let rdata = & spi_data[ op_slen..] ;
343375 // Send the full rdata in chunks
344- let _ = self . transport . write ( rdata) . await ;
376+ self . transport . write ( rdata) . await . map_err ( |_| {
377+ SerprogError :: TransportWrite ( "Error writing SPI read data" )
378+ } ) ?;
345379 }
346380 Err ( _) => {
347381 error ! ( "SPI transfer error" ) ;
348- if let Err ( e) = self . transport . write ( & [ S_NAK ] ) . await {
349- error ! ( "Error writing NAK: {:?}" , e) ;
350- }
382+ self . transport . write ( & [ S_NAK ] ) . await . map_err ( |_| {
383+ SerprogError :: TransportWrite ( "Error writing OSpiOp NAK" )
384+ } ) ?;
385+ return Err ( SerprogError :: SpiTransfer ( "SPI transfer failed" ) ) ;
351386 }
352387 }
353388
354- if self . cs . set_high ( ) . is_err ( ) {
355- error ! ( "Error setting CS high" ) ;
356- }
389+ self . cs
390+ . set_high ( )
391+ . map_err ( |_| SerprogError :: CsSetHigh ( "Error setting CS high" ) ) ?;
392+
393+ Ok ( ( ) )
357394 }
358395 SerprogCommand :: SSpiFreq => {
359396 debug ! ( "Received SSpiFreq CMD" ) ;
360397 let mut request = SSpiFreqRequest :: new_zeroed ( ) ;
361- if let Err ( e ) = self . transport . read ( request . as_mut_bytes ( ) ) . await {
362- error ! ( "Error reading packet: {:?}" , e ) ;
363- return ;
364- }
398+ self . transport
399+ . read ( request . as_mut_bytes ( ) )
400+ . await
401+ . map_err ( |_| SerprogError :: TransportRead ( "Error reading SSpiFreq data" ) ) ? ;
365402
366403 // Parse the request using zerocopy
367404 let try_freq = request. freq . get ( ) ;
@@ -379,33 +416,43 @@ where
379416 freq : U32 :: new ( try_freq) , // TODO can we report what the hardware has set up?
380417 } ;
381418
382- if let Err ( e) = self . transport . write ( response. as_bytes ( ) ) . await {
383- error ! ( "Error writing packet: {:?}" , e) ;
384- }
419+ self . transport
420+ . write ( response. as_bytes ( ) )
421+ . await
422+ . map_err ( |_| SerprogError :: TransportWrite ( "Error writing SSpiFreq response" ) ) ?;
423+
424+ Ok ( ( ) )
385425 }
386426 SerprogCommand :: SPinState => {
387427 debug ! ( "Received SPinState CMD" ) ;
388428 let mut buf = [ 0u8 ; 1 ] ;
389- if let Err ( e ) = self . transport . read ( & mut buf ) . await {
390- error ! ( "Error reading packet: {:?}" , e ) ;
391- return ;
392- }
429+ self . transport
430+ . read ( & mut buf )
431+ . await
432+ . map_err ( |_| SerprogError :: TransportRead ( "Error reading SPinState data" ) ) ? ;
393433 if buf[ 0 ] == 0 {
394- if self . led . set_low ( ) . is_err ( ) {
395- error ! ( "Error setting LED low" ) ;
396- }
397- } else if self . led . set_high ( ) . is_err ( ) {
398- error ! ( "Error setting LED high" ) ;
399- }
400- if let Err ( e) = self . transport . write ( & [ S_ACK ] ) . await {
401- error ! ( "Error writing packet: {:?}" , e) ;
434+ self . led
435+ . set_low ( )
436+ . map_err ( |_| SerprogError :: LedSetLow ( "Error setting LED low" ) ) ?;
437+ } else {
438+ self . led
439+ . set_high ( )
440+ . map_err ( |_| SerprogError :: LedSetHigh ( "Error setting LED high" ) ) ?;
402441 }
442+ self . transport
443+ . write ( & [ S_ACK ] )
444+ . await
445+ . map_err ( |_| SerprogError :: TransportWrite ( "Error writing SPinState ACK" ) ) ?;
446+
447+ Ok ( ( ) )
403448 }
404449 _ => {
405450 debug ! ( "Received unknown CMD" ) ;
406- if let Err ( e) = self . transport . write ( & [ S_NAK ] ) . await {
407- error ! ( "Error writing packet: {:?}" , e) ;
408- }
451+ self . transport . write ( & [ S_NAK ] ) . await . map_err ( |_| {
452+ SerprogError :: TransportWrite ( "Error writing unknown command NAK" )
453+ } ) ?;
454+
455+ Ok ( ( ) )
409456 }
410457 }
411458 }
0 commit comments