@@ -426,8 +426,8 @@ impl Hardware {
426426 /// Give the device 2000ns before we take away CS.
427427 const CS_BUS_HOLD_CPU_CLOCKS : u32 = 2000 / Self :: NS_PER_CLOCK_CYCLE ;
428428
429- /// Give the device 10ms to sort itself out when we do a retry.
430- const SPI_RETRY_CPU_CLOCKS : u32 = 10_000_000 / Self :: NS_PER_CLOCK_CYCLE ;
429+ /// Give the device 100ms to sort itself out when we do a retry.
430+ const BMC_RETRY_CPU_CLOCKS : u32 = 100_000_000 / Self :: NS_PER_CLOCK_CYCLE ;
431431
432432 /// Give the BMC 6us to calculate its response
433433 const BMC_REQUEST_RESPONSE_DELAY_CLOCKS : u32 = 6_000 / Self :: NS_PER_CLOCK_CYCLE ;
@@ -616,7 +616,7 @@ impl Hardware {
616616 spi_bus : hal:: Spi :: new ( spi) . init (
617617 resets,
618618 clocks. peripheral_clock . freq ( ) ,
619- 2_000_000 . Hz ( ) ,
619+ 4_000_000 . Hz ( ) ,
620620 & embedded_hal:: spi:: MODE_0 ,
621621 ) ,
622622 delay,
@@ -833,9 +833,9 @@ impl Hardware {
833833 /// The number of bytes you want is set by the length of the `buffer` argument.
834834 ///
835835 fn bmc_read_register ( & mut self , register : u8 , buffer : & mut [ u8 ] ) -> Result < ( ) , ( ) > {
836- const MAX_LATENCY : usize = 12 ;
836+ const MAX_LATENCY : usize = 128 ;
837837
838- if ( buffer. len ( ) + MAX_LATENCY ) > self . bmc_buffer . len ( ) {
838+ if buffer. len ( ) > self . bmc_buffer . len ( ) {
839839 defmt:: error!( "Asked for too much data ({})" , buffer. len( ) ) ;
840840 return Err ( ( ) ) ;
841841 }
@@ -851,64 +851,62 @@ impl Hardware {
851851 for byte in self . bmc_buffer . iter_mut ( ) {
852852 * byte = 0xFF ;
853853 }
854- // Allow for up to eight bytes of padding (i.e. latency).
855- let response_len = buffer. len ( ) + MAX_LATENCY ;
854+ let expected_response_len = buffer. len ( ) + 2 ;
856855 defmt:: debug!( "req: {=[u8; 4]:02x}" , req_bytes) ;
857- self . with_bus_cs ( 0 , |spi, buffer| {
856+ let mut latency = 0 ;
857+ self . with_bus_cs ( 0 , |spi, borrowed_buffer| {
858858 // Send the request
859859 spi. write ( & req_bytes) . unwrap ( ) ;
860- cortex_m:: asm:: delay ( Self :: BMC_REQUEST_RESPONSE_DELAY_CLOCKS ) ;
861- // Get the response
862- spi. transfer ( & mut buffer[ ..response_len] ) . unwrap ( ) ;
860+ for retry in 0 ..MAX_LATENCY {
861+ cortex_m:: asm:: delay ( Self :: BMC_REQUEST_RESPONSE_DELAY_CLOCKS ) ;
862+ spi. transfer ( & mut borrowed_buffer[ 0 ..=0 ] ) . unwrap ( ) ;
863+ if neotron_bmc_protocol:: ResponseResult :: try_from ( borrowed_buffer[ 0 ] ) . is_ok ( ) {
864+ latency = retry;
865+ break ;
866+ }
867+ }
868+ // Get the rest of the response now we know it's queued up.
869+ spi. transfer ( & mut borrowed_buffer[ 1 ..expected_response_len] )
870+ . unwrap ( ) ;
863871 } ) ;
864- // Trim the padding off the front
865- let mut response_buffer = & self . bmc_buffer [ ..response_len] ;
866- let mut latency = 0 ;
867- while response_buffer. len ( ) > 0
868- && neotron_bmc_protocol:: ResponseResult :: try_from ( response_buffer[ 0 ] ) . is_err ( )
869- {
870- response_buffer = & response_buffer[ 1 ..] ;
871- latency += 1 ;
872- }
873- defmt:: debug!( "res: {=[u8]:02x} ({})" , response_buffer, latency) ;
874- let expected_response_len = buffer. len ( ) + 2 ;
872+ defmt:: debug!(
873+ "res: {=[u8]:02x} ({})" ,
874+ self . bmc_buffer[ 0 ..expected_response_len] ,
875+ latency
876+ ) ;
875877 // 8 bytes of data requested, plus one bytes of response code and one byte of CRC
876- if response_buffer. len ( ) >= expected_response_len {
877- let response_portion = & response_buffer[ 0 ..expected_response_len] ;
878- match neotron_bmc_protocol:: Response :: from_bytes ( response_portion) {
879- Ok ( res) => {
880- if res. result == neotron_bmc_protocol:: ResponseResult :: Ok
881- && res. data . len ( ) == buffer. len ( )
882- {
883- buffer. copy_from_slice ( res. data ) ;
884- return Ok ( ( ) ) ;
885- } else {
886- defmt:: warn!(
887- "Error reading {} bytes from {}: Error from BMC {:?} {=[u8]:x}" ,
888- buffer. len( ) ,
889- register,
890- res. result,
891- response_portion
892- ) ;
893- // No point retrying - we heardly them perfectly
894- return Err ( ( ) ) ;
895- }
896- }
897- Err ( e) => {
878+ let response_portion = & self . bmc_buffer [ 0 ..expected_response_len] ;
879+ match neotron_bmc_protocol:: Response :: from_bytes ( response_portion) {
880+ Ok ( res) => {
881+ if res. result == neotron_bmc_protocol:: ResponseResult :: Ok
882+ && res. data . len ( ) == buffer. len ( )
883+ {
884+ buffer. copy_from_slice ( res. data ) ;
885+ return Ok ( ( ) ) ;
886+ } else {
898887 defmt:: warn!(
899- "Error reading {} bytes from {}: Decoding Error {:?} {=[u8]:x}" ,
888+ "Error reading {} bytes from {}: Error from BMC {:?} {=[u8]:x}" ,
900889 buffer. len( ) ,
901890 register,
902- e ,
891+ res . result ,
903892 response_portion
904893 ) ;
894+ // No point retrying - we heardly them perfectly
895+ return Err ( ( ) ) ;
905896 }
906897 }
907- } else {
908- defmt:: warn!( "Short packet {=[u8]:x}" , response_buffer) ;
898+ Err ( e) => {
899+ defmt:: warn!(
900+ "Error reading {} bytes from {}: Decoding Error {:?} {=[u8]:x}" ,
901+ buffer. len( ) ,
902+ register,
903+ e,
904+ response_portion
905+ ) ;
906+ }
909907 }
910908 // Wait a bit before we try again
911- cortex_m:: asm:: delay ( Self :: SPI_RETRY_CPU_CLOCKS ) ;
909+ cortex_m:: asm:: delay ( Self :: BMC_RETRY_CPU_CLOCKS ) ;
912910 }
913911 panic ! ( "Failed to talk to BMC after several retries." ) ;
914912 }
0 commit comments