1
+ #[ cfg( feature = "serialport" ) ]
2
+ use std:: collections:: HashMap ;
1
3
use std:: ops:: Range ;
2
4
3
5
#[ cfg( feature = "serialport" ) ]
4
- use crate :: { connection:: Connection , targets :: bytes_to_mac_addr } ;
6
+ use crate :: connection:: Connection ;
5
7
use crate :: {
6
8
flasher:: { FlashData , FlashFrequency } ,
7
9
image_format:: IdfBootloaderFormat ,
8
- targets:: { Chip , Esp32Params , ReadEFuse , SpiRegisters , Target , XtalFrequency } ,
10
+ targets:: { Chip , EfuseField , Esp32Params , ReadEFuse , SpiRegisters , Target , XtalFrequency } ,
9
11
Error ,
10
12
} ;
11
13
@@ -38,19 +40,151 @@ impl Esp32 {
38
40
#[ cfg( feature = "serialport" ) ]
39
41
/// Return the package version based on the eFuses
40
42
fn package_version ( & self , connection : & mut Connection ) -> Result < u32 , Error > {
41
- let word3 = self . read_efuse ( connection, 3 ) ?;
42
-
43
- let pkg_version = ( word3 >> 9 ) & 0x7 ;
44
- let pkg_version = pkg_version + ( ( ( word3 >> 2 ) & 0x1 ) << 3 ) ;
43
+ let fields = self . common_fields ( ) ;
44
+ let pkg_version = self . read_field ( connection, fields[ "CHIP_VER_PKG" ] ) ?;
45
+ let pkg_version_4bit = self . read_field ( connection, fields[ "CHIP_VER_PKG_4BIT" ] ) ?;
45
46
46
- Ok ( pkg_version)
47
+ Ok ( pkg_version + ( pkg_version_4bit << 3 ) )
47
48
}
48
49
}
49
50
50
51
impl ReadEFuse for Esp32 {
51
52
fn efuse_reg ( & self ) -> u32 {
52
53
0x3ff5_a000
53
54
}
55
+
56
+ #[ cfg( feature = "serialport" ) ]
57
+ fn common_fields ( & self ) -> HashMap < & ' static str , EfuseField > {
58
+ let mut fields = HashMap :: new ( ) ;
59
+
60
+ // MAC address fields
61
+ fields. insert (
62
+ "MAC_FACTORY_0" ,
63
+ EfuseField {
64
+ word_offset : 1 ,
65
+ bit_offset : 0 ,
66
+ bit_count : 32 ,
67
+ } ,
68
+ ) ;
69
+ fields. insert (
70
+ "MAC_FACTORY_1" ,
71
+ EfuseField {
72
+ word_offset : 2 ,
73
+ bit_offset : 0 ,
74
+ bit_count : 16 ,
75
+ } ,
76
+ ) ;
77
+
78
+ // Chip version fields
79
+ fields. insert (
80
+ "CHIP_VER_REV1" ,
81
+ EfuseField {
82
+ word_offset : 3 ,
83
+ bit_offset : 15 ,
84
+ bit_count : 1 ,
85
+ } ,
86
+ ) ;
87
+ fields. insert (
88
+ "CHIP_VERSION" ,
89
+ EfuseField {
90
+ word_offset : 3 ,
91
+ bit_offset : 12 ,
92
+ bit_count : 2 ,
93
+ } ,
94
+ ) ;
95
+ fields. insert (
96
+ "CHIP_VER_REV2" ,
97
+ EfuseField {
98
+ word_offset : 5 ,
99
+ bit_offset : 20 ,
100
+ bit_count : 1 ,
101
+ } ,
102
+ ) ;
103
+ fields. insert (
104
+ "CHIP_CPU_FREQ_RATED" ,
105
+ EfuseField {
106
+ word_offset : 3 ,
107
+ bit_offset : 13 ,
108
+ bit_count : 1 ,
109
+ } ,
110
+ ) ;
111
+ fields. insert (
112
+ "CHIP_CPU_FREQ_LOW" ,
113
+ EfuseField {
114
+ word_offset : 3 ,
115
+ bit_offset : 12 ,
116
+ bit_count : 1 ,
117
+ } ,
118
+ ) ;
119
+ fields. insert (
120
+ "CHIP_VER_PKG" ,
121
+ EfuseField {
122
+ word_offset : 3 ,
123
+ bit_offset : 9 ,
124
+ bit_count : 3 ,
125
+ } ,
126
+ ) ;
127
+ fields. insert (
128
+ "CHIP_VER_PKG_4BIT" ,
129
+ EfuseField {
130
+ word_offset : 3 ,
131
+ bit_offset : 2 ,
132
+ bit_count : 1 ,
133
+ } ,
134
+ ) ;
135
+ fields. insert (
136
+ "CODING_SCHEME" ,
137
+ EfuseField {
138
+ word_offset : 6 ,
139
+ bit_offset : 0 ,
140
+ bit_count : 2 ,
141
+ } ,
142
+ ) ;
143
+
144
+ // Feature bits
145
+ fields. insert (
146
+ "CHIP_VER_DIS_APP_CPU" ,
147
+ EfuseField {
148
+ word_offset : 3 ,
149
+ bit_offset : 0 ,
150
+ bit_count : 1 ,
151
+ } ,
152
+ ) ;
153
+ fields. insert (
154
+ "CHIP_VER_DIS_BT" ,
155
+ EfuseField {
156
+ word_offset : 3 ,
157
+ bit_offset : 1 ,
158
+ bit_count : 1 ,
159
+ } ,
160
+ ) ;
161
+ fields. insert (
162
+ "ADC_VREF" ,
163
+ EfuseField {
164
+ word_offset : 4 ,
165
+ bit_offset : 8 ,
166
+ bit_count : 1 ,
167
+ } ,
168
+ ) ;
169
+ fields. insert (
170
+ "BLK3_PART_RESERVE" ,
171
+ EfuseField {
172
+ word_offset : 3 ,
173
+ bit_offset : 14 ,
174
+ bit_count : 1 ,
175
+ } ,
176
+ ) ;
177
+ fields. insert (
178
+ "MINOR_VERSION" ,
179
+ EfuseField {
180
+ word_offset : 5 ,
181
+ bit_offset : 24 ,
182
+ bit_count : 2 ,
183
+ } ,
184
+ ) ;
185
+
186
+ fields
187
+ }
54
188
}
55
189
56
190
impl Target for Esp32 {
@@ -60,27 +194,25 @@ impl Target for Esp32 {
60
194
61
195
#[ cfg( feature = "serialport" ) ]
62
196
fn chip_features ( & self , connection : & mut Connection ) -> Result < Vec < & str > , Error > {
63
- let word3 = self . read_efuse ( connection, 3 ) ?;
64
- let word4 = self . read_efuse ( connection, 4 ) ?;
65
- let word6 = self . read_efuse ( connection, 6 ) ?;
197
+ let fields = self . common_fields ( ) ;
66
198
67
199
let mut features = vec ! [ "WiFi" ] ;
68
200
69
- let chip_ver_dis_bt = word3 & 0x2 ;
201
+ let chip_ver_dis_bt = self . read_field ( connection , fields [ "CHIP_VER_DIS_BT" ] ) ? ;
70
202
if chip_ver_dis_bt == 0 {
71
203
features. push ( "BT" ) ;
72
204
}
73
205
74
- let chip_ver_dis_app_cpu = word3 & 0x1 ;
206
+ let chip_ver_dis_app_cpu = self . read_field ( connection , fields [ "CHIP_VER_DIS_APP_CPU" ] ) ? ;
75
207
if chip_ver_dis_app_cpu == 0 {
76
208
features. push ( "Dual Core" ) ;
77
209
} else {
78
210
features. push ( "Single Core" ) ;
79
211
}
80
212
81
- let chip_cpu_freq_rated = word3 & ( 1 << 13 ) ;
213
+ let chip_cpu_freq_rated = self . read_field ( connection , fields [ "CHIP_CPU_FREQ_RATED" ] ) ? ;
82
214
if chip_cpu_freq_rated != 0 {
83
- let chip_cpu_freq_low = word3 & ( 1 << 12 ) ;
215
+ let chip_cpu_freq_low = self . read_field ( connection , fields [ "CHIP_CPU_FREQ_LOW" ] ) ? ;
84
216
if chip_cpu_freq_low != 0 {
85
217
features. push ( "160MHz" ) ;
86
218
} else {
@@ -96,17 +228,17 @@ impl Target for Esp32 {
96
228
features. push ( "Embedded PSRAM" ) ;
97
229
}
98
230
99
- let adc_vref = ( word4 >> 8 ) & 0x1 ;
231
+ let adc_vref = self . read_field ( connection , fields [ "ADC_VREF" ] ) ? ;
100
232
if adc_vref != 0 {
101
233
features. push ( "VRef calibration in efuse" ) ;
102
234
}
103
235
104
- let blk3_part_res = ( word3 >> 14 ) & 0x1 ;
236
+ let blk3_part_res = self . read_field ( connection , fields [ "BLK3_PART_RESERVE" ] ) ? ;
105
237
if blk3_part_res != 0 {
106
238
features. push ( "BLK3 partially reserved" ) ;
107
239
}
108
240
109
- let coding_scheme = word6 & 0x3 ;
241
+ let coding_scheme = self . read_field ( connection , fields [ "CODING_SCHEME" ] ) ? ;
110
242
features. push ( match coding_scheme {
111
243
0 => "Coding Scheme None" ,
112
244
1 => "Coding Scheme 3/4" ,
@@ -120,9 +252,10 @@ impl Target for Esp32 {
120
252
#[ cfg( feature = "serialport" ) ]
121
253
fn major_chip_version ( & self , connection : & mut Connection ) -> Result < u32 , Error > {
122
254
let apb_ctl_date = connection. read_reg ( 0x3FF6_607C ) ?;
255
+ let fields = self . common_fields ( ) ;
123
256
124
- let rev_bit0 = ( self . read_efuse ( connection, 3 ) ? >> 15 ) & 0x1 ;
125
- let rev_bit1 = ( self . read_efuse ( connection, 5 ) ? >> 20 ) & 0x1 ;
257
+ let rev_bit0 = self . read_field ( connection, fields [ "CHIP_VER_REV1" ] ) ? ;
258
+ let rev_bit1 = self . read_field ( connection, fields [ "CHIP_VER_REV2" ] ) ? ;
126
259
let rev_bit2 = ( apb_ctl_date >> 31 ) & 0x1 ;
127
260
128
261
let combine_value = ( rev_bit2 << 2 ) | ( rev_bit1 << 1 ) | rev_bit0;
@@ -137,7 +270,8 @@ impl Target for Esp32 {
137
270
138
271
#[ cfg( feature = "serialport" ) ]
139
272
fn minor_chip_version ( & self , connection : & mut Connection ) -> Result < u32 , Error > {
140
- Ok ( ( self . read_efuse ( connection, 5 ) ? >> 24 ) & 0x3 )
273
+ let fields = self . common_fields ( ) ;
274
+ self . read_field ( connection, fields[ "MINOR_VERSION" ] )
141
275
}
142
276
143
277
#[ cfg( feature = "serialport" ) ]
@@ -189,14 +323,12 @@ impl Target for Esp32 {
189
323
190
324
#[ cfg( feature = "serialport" ) ]
191
325
fn mac_address ( & self , connection : & mut Connection ) -> Result < String , Error > {
192
- let word1 = self . read_efuse ( connection, 1 ) ?;
193
- let word2 = self . read_efuse ( connection, 2 ) ?;
194
-
195
- let words = ( ( word2 as u64 ) << 32 ) | word1 as u64 ;
196
- let bytes = words. to_be_bytes ( ) ;
197
- let bytes = & bytes[ 2 ..8 ] ;
198
-
199
- Ok ( bytes_to_mac_addr ( bytes) )
326
+ let fields = self . common_fields ( ) ;
327
+ self . read_mac_address_from_words (
328
+ connection,
329
+ fields[ "MAC_FACTORY_0" ] ,
330
+ fields[ "MAC_FACTORY_1" ] ,
331
+ )
200
332
}
201
333
202
334
fn spi_registers ( & self ) -> SpiRegisters {
0 commit comments