@@ -5,7 +5,10 @@ use std::{io::Write, mem::size_of, time::Duration};
5
5
use bytemuck:: { Pod , Zeroable , bytes_of} ;
6
6
use strum:: Display ;
7
7
8
- use crate :: flasher:: { SpiAttachParams , SpiSetParams } ;
8
+ use crate :: {
9
+ Error ,
10
+ flasher:: { SpiAttachParams , SpiSetParams } ,
11
+ } ;
9
12
10
13
const DEFAULT_TIMEOUT : Duration = Duration :: from_secs ( 3 ) ;
11
14
const ERASE_REGION_TIMEOUT_PER_MB : Duration = Duration :: from_secs ( 30 ) ;
@@ -14,7 +17,7 @@ const ERASE_CHIP_TIMEOUT: Duration = Duration::from_secs(120);
14
17
const MEM_END_TIMEOUT : Duration = Duration :: from_millis ( 50 ) ;
15
18
const SYNC_TIMEOUT : Duration = Duration :: from_millis ( 100 ) ;
16
19
const FLASH_DEFLATE_END_TIMEOUT : Duration = Duration :: from_secs ( 10 ) ;
17
- const FLASH_MD5_TIMEOUT : Duration = Duration :: from_secs ( 8 ) ;
20
+ const FLASH_MD5_TIMEOUT_PER_MB : Duration = Duration :: from_secs ( 8 ) ;
18
21
19
22
/// Input data for SYNC command (36 bytes: 0x07 0x07 0x12 0x20, followed by
20
23
/// 32 x 0x55)
@@ -63,6 +66,82 @@ pub enum CommandType {
63
66
FlashDetect = 0x9F ,
64
67
}
65
68
69
+ /// The value of a command response.
70
+ #[ derive( Debug , Clone ) ]
71
+ pub enum CommandResponseValue {
72
+ /// A 32-bit value.
73
+ ValueU32 ( u32 ) ,
74
+ /// A 128-bit value.
75
+ ValueU128 ( u128 ) ,
76
+ /// A vector of bytes.
77
+ Vector ( Vec < u8 > ) ,
78
+ }
79
+
80
+ impl TryInto < u32 > for CommandResponseValue {
81
+ type Error = Error ;
82
+
83
+ fn try_into ( self ) -> Result < u32 , Self :: Error > {
84
+ match self {
85
+ CommandResponseValue :: ValueU32 ( value) => Ok ( value) ,
86
+ CommandResponseValue :: ValueU128 ( _) => Err ( Error :: InvalidResponse (
87
+ "expected `u32` but found `u128`" . into ( ) ,
88
+ ) ) ,
89
+ CommandResponseValue :: Vector ( _) => Err ( Error :: InvalidResponse (
90
+ "expected `u32` but found `Vec`" . into ( ) ,
91
+ ) ) ,
92
+ }
93
+ }
94
+ }
95
+
96
+ impl TryInto < u128 > for CommandResponseValue {
97
+ type Error = Error ;
98
+
99
+ fn try_into ( self ) -> Result < u128 , Self :: Error > {
100
+ match self {
101
+ CommandResponseValue :: ValueU32 ( _) => Err ( Error :: InvalidResponse (
102
+ "expected `u128` but found `u32`" . into ( ) ,
103
+ ) ) ,
104
+ CommandResponseValue :: ValueU128 ( value) => Ok ( value) ,
105
+ CommandResponseValue :: Vector ( _) => Err ( Error :: InvalidResponse (
106
+ "expected `u128` but found `Vec`" . into ( ) ,
107
+ ) ) ,
108
+ }
109
+ }
110
+ }
111
+
112
+ impl TryInto < Vec < u8 > > for CommandResponseValue {
113
+ type Error = Error ;
114
+
115
+ fn try_into ( self ) -> Result < Vec < u8 > , Self :: Error > {
116
+ match self {
117
+ CommandResponseValue :: ValueU32 ( _) => Err ( Error :: InvalidResponse (
118
+ "expected `Vec` but found `u32`" . into ( ) ,
119
+ ) ) ,
120
+ CommandResponseValue :: ValueU128 ( _) => Err ( Error :: InvalidResponse (
121
+ "expected `Vec` but found `u128`" . into ( ) ,
122
+ ) ) ,
123
+ CommandResponseValue :: Vector ( value) => Ok ( value) ,
124
+ }
125
+ }
126
+ }
127
+
128
+ /// A response from a target device following a command.
129
+ #[ derive( Debug , Clone ) ]
130
+ pub struct CommandResponse {
131
+ /// The response byte.
132
+ pub resp : u8 ,
133
+ /// The return operation byte.
134
+ pub return_op : u8 ,
135
+ /// The length of the return value.
136
+ pub return_length : u16 ,
137
+ /// The value of the response.
138
+ pub value : CommandResponseValue ,
139
+ /// The error byte.
140
+ pub error : u8 ,
141
+ /// The status byte.
142
+ pub status : u8 ,
143
+ }
144
+
66
145
impl CommandType {
67
146
/// Return the default timeout for the [`CommandType`] variant.
68
147
pub fn timeout ( & self ) -> Duration {
@@ -71,7 +150,14 @@ impl CommandType {
71
150
CommandType :: Sync => SYNC_TIMEOUT ,
72
151
CommandType :: EraseFlash => ERASE_CHIP_TIMEOUT ,
73
152
CommandType :: FlashDeflEnd => FLASH_DEFLATE_END_TIMEOUT ,
74
- CommandType :: FlashMd5 => FLASH_MD5_TIMEOUT ,
153
+ CommandType :: FlashMd5 => {
154
+ log:: warn!(
155
+ "Using default timeout for {}, this may not be sufficient for large flash regions. Consider using `timeout_for_size` instead." ,
156
+ self
157
+ ) ;
158
+
159
+ DEFAULT_TIMEOUT
160
+ }
75
161
_ => DEFAULT_TIMEOUT ,
76
162
}
77
163
}
@@ -93,6 +179,7 @@ impl CommandType {
93
179
CommandType :: FlashData | CommandType :: FlashDeflData => {
94
180
calc_timeout ( ERASE_WRITE_TIMEOUT_PER_MB , size)
95
181
}
182
+ CommandType :: FlashMd5 => calc_timeout ( FLASH_MD5_TIMEOUT_PER_MB , size) ,
96
183
_ => self . timeout ( ) ,
97
184
}
98
185
}
0 commit comments