1
- use hidapi:: { DeviceInfo , HidApi , HidDevice } ;
1
+ use hidapi:: { DeviceInfo , HidApi , HidDevice , HidError } ;
2
2
3
3
use crate :: ccgx;
4
4
use crate :: ccgx:: device:: { decode_flash_row_size, FwMode } ;
@@ -155,25 +155,6 @@ pub fn check_ccg_fw_version(device: &HidDevice) {
155
155
print_fw_info ( & info) ;
156
156
}
157
157
158
- // 0 .. 2 = HID header
159
- // 2 .. 4 = signature (CY)
160
- // 4 = Operating Mode
161
- // 5 = Bootloader (security, no-flashing, priority, row_size)
162
- // 6 = Boot mode reason, jump-bootloader, reserved, fw1 invalid, fw2 invalid
163
- // 7 = ??
164
- // 8 .. 12 = Silicon ID
165
- // 12 .. 16 = bootloader Version
166
- // 15 .. 20 = ??
167
- // 20 .. 24 = Image 1 Version
168
- // 24 .. 26 = Image 1 ??
169
- // 26 .. 28 = Image 1 ??
170
- // 28 .. 32 = Image 2 Version
171
- // 32 .. 34 = Image 2 ??
172
- // 34 .. 36 = Image 2 ??
173
- // 36 .. 40 = Image 1 Start Address
174
- // 40 .. 44 = Image 2 Start Address
175
- // 44 .. 52 = ?? [c9 d7 3e 02 23 19 0b 00]
176
-
177
158
fn decode_fw_info ( buf : & [ u8 ] ) -> HidFirmwareInfo {
178
159
let info_len = std:: mem:: size_of :: < HidFirmwareInfo > ( ) ;
179
160
let info: HidFirmwareInfo = unsafe { std:: ptr:: read ( buf[ ..info_len] . as_ptr ( ) as * const _ ) } ;
@@ -191,77 +172,84 @@ fn decode_fw_info(buf: &[u8]) -> HidFirmwareInfo {
191
172
fn print_fw_info ( info : & HidFirmwareInfo ) {
192
173
assert_eq ! ( info. report_id, ReportIdCmd :: E0Read as u8 ) ;
193
174
194
- debug ! ( " Signature: {:X?}" , info. signature) ;
175
+ info ! ( " Signature: {:X?}" , info. signature) ;
195
176
// Something's totally off if the signature is invalid
196
- assert_eq ! ( info. signature, [ b'C' , b'Y' ] ) ;
177
+ if info. signature != [ b'C' , b'Y' ] {
178
+ println ! ( "Firmware Signature is invalid." ) ;
179
+ return ;
180
+ }
197
181
198
- debug ! (
199
- " Operating Mode: {:?} ({})" ,
200
- FwMode :: try_from( info. operating_mode) . unwrap( ) ,
201
- info. operating_mode
202
- ) ;
203
- debug ! ( " Bootloader Info" ) ;
204
- debug ! (
182
+ info ! ( " Bootloader Info" ) ;
183
+ info ! (
205
184
" Security Support: {:?}" ,
206
185
info. bootloader_info & 0b001 != 0
207
186
) ;
208
- debug ! (
187
+ info ! (
209
188
" Flashing Support: {:?}" ,
210
189
info. bootloader_info & 0b010 == 0
211
190
) ;
212
- debug ! (
213
- " App Priority: {:?}" ,
214
- info. bootloader_info & 0b100 != 0
215
- ) ;
216
- debug ! (
217
- " Flash Row Size: {:?}" ,
191
+ // App Priority means you can configure whether the main or backup firmware
192
+ // has priority. This can either be configured in the flash image or by
193
+ // sending a command. But the CCG3 SDK lets you disable support for this at
194
+ // compile-time. If disabled, both images have the same priority.
195
+ let app_priority_support = info. bootloader_info & 0b100 != 0 ;
196
+ info ! ( " App Priority: {:?}" , app_priority_support) ;
197
+ info ! (
198
+ " Flash Row Size: {:?} B" ,
218
199
decode_flash_row_size( info. bootloader_info)
219
200
) ;
220
- debug ! ( " Boot Mode Reason" ) ;
221
- debug ! (
201
+ info ! ( " Boot Mode Reason" ) ;
202
+ info ! (
222
203
" Jump to Bootloader: {:?}" ,
223
204
info. bootmode_reason & 0b000001 != 0
224
205
) ;
225
206
let image_1_valid = info. bootmode_reason & 0b000100 == 0 ;
226
207
let image_2_valid = info. bootmode_reason & 0b001000 == 0 ;
227
- debug ! ( " FW 1 valid: {:?}" , image_1_valid) ;
228
- debug ! ( " FW 2 valid: {:?}" , image_2_valid) ;
229
- debug ! (
230
- " App Priority: {:?}" ,
231
- info. bootmode_reason & 0b110000
232
- ) ;
233
- debug ! ( " UID: {:X?}" , info. device_uid) ;
234
- debug ! ( " Silicon ID: {:X?}" , info. silicon_id) ;
208
+ info ! ( " FW 1 valid: {:?}" , image_1_valid) ;
209
+ info ! ( " FW 2 valid: {:?}" , image_2_valid) ;
210
+ if app_priority_support {
211
+ info ! (
212
+ " App Priority: {:?}" ,
213
+ info. bootmode_reason & 0b110000
214
+ ) ;
215
+ }
216
+ info ! ( " UID: {:X?}" , info. device_uid) ;
217
+ info ! ( " Silicon ID: {:X?}" , info. silicon_id) ;
235
218
let bl_ver = BaseVersion :: from ( info. bl_version . as_slice ( ) ) ;
236
219
let base_version_1 = BaseVersion :: from ( info. image_1_ver . as_slice ( ) ) ;
237
220
let base_version_2 = BaseVersion :: from ( info. image_2_ver . as_slice ( ) ) ;
238
- debug ! (
239
- " BL Version: {} Build {}" ,
240
- bl_ver, bl_ver. build_number
241
- ) ;
242
- debug ! (
221
+ info ! ( " BL Version: {} " , bl_ver, ) ;
222
+ info ! (
243
223
" Image 1 start: 0x{:08X}" ,
244
224
u32 :: from_le_bytes( info. image_1_row)
245
225
) ;
246
- debug ! (
226
+ info ! (
247
227
" Image 2 start: 0x{:08X}" ,
248
228
u32 :: from_le_bytes( info. image_2_row)
249
229
) ;
250
230
231
+ let operating_mode = FwMode :: try_from ( info. operating_mode ) . unwrap ( ) ;
232
+ let ( active_ver, active_valid, inactive_ver, inactive_valid) = match operating_mode {
233
+ FwMode :: MainFw | FwMode :: BootLoader => {
234
+ ( base_version_2, image_2_valid, base_version_1, image_1_valid)
235
+ }
236
+ FwMode :: BackupFw => ( base_version_1, image_1_valid, base_version_2, image_2_valid) ,
237
+ } ;
238
+
251
239
println ! (
252
- " FW Image 1 Version: {:03} ({}){}" ,
253
- base_version_1 . build_number,
254
- base_version_1 ,
255
- if image_1_valid { "" } else { " - INVALID!" }
240
+ " Active Firmware: {:03} ({}){}" ,
241
+ active_ver . build_number,
242
+ active_ver ,
243
+ if active_valid { "" } else { " - INVALID!" }
256
244
) ;
257
245
println ! (
258
- " FW Image 2 Version: {:03} ({}){}" ,
259
- base_version_2 . build_number,
260
- base_version_2 ,
261
- if image_2_valid { "" } else { " - INVALID!" }
246
+ " Inactive Firmware: {:03} ({}){}" ,
247
+ inactive_ver . build_number,
248
+ inactive_ver ,
249
+ if inactive_valid { "" } else { " - INVALID!" }
262
250
) ;
263
251
println ! (
264
- " Currently running : {:?} ({})" ,
252
+ " Operating Mode : {:?} (# {})" ,
265
253
FwMode :: try_from( info. operating_mode) . unwrap( ) ,
266
254
info. operating_mode
267
255
) ;
@@ -361,21 +349,25 @@ pub fn flash_firmware(fw_binary: &[u8]) {
361
349
println ! ( " Updating Firmware Image 1" ) ;
362
350
flash_firmware_image ( & device, fw_binary, FW1_START , FW1_METADATA , fw1_rows, 1 ) ;
363
351
364
- let ( device, _) =
365
- wait_to_reappear ( & mut api, & filter_devs, sn) . expect ( "Device did not reappear" ) ;
352
+ // We don't actually need to update both firmware images.
353
+ // It'll stay on the one we updated. So it's totally fine to
354
+ // keep the other one on the older version.
355
+ //let (device, _) =
356
+ // wait_to_reappear(&mut api, &filter_devs, sn).expect("Device did not reappear");
366
357
367
- println ! ( " Updating Firmware Image 2" ) ;
368
- flash_firmware_image ( & device, fw_binary, FW2_START , FW2_METADATA , fw2_rows, 2 ) ;
358
+ // println!(" Updating Firmware Image 2");
359
+ // flash_firmware_image(&device, fw_binary, FW2_START, FW2_METADATA, fw2_rows, 2);
369
360
}
370
361
1 => {
371
362
println ! ( " Updating Firmware Image 2" ) ;
372
363
flash_firmware_image ( & device, fw_binary, FW2_START , FW2_METADATA , fw2_rows, 2 ) ;
373
364
374
- let ( device, _) =
375
- wait_to_reappear ( & mut api, & filter_devs, sn) . expect ( "Device did not reappear" ) ;
365
+ // See above
366
+ //let (device, _) =
367
+ // wait_to_reappear(&mut api, &filter_devs, sn).expect("Device did not reappear");
376
368
377
- println ! ( " Updating Firmware Image 1" ) ;
378
- flash_firmware_image ( & device, fw_binary, FW1_START , FW1_METADATA , fw1_rows, 1 ) ;
369
+ // println!(" Updating Firmware Image 1");
370
+ // flash_firmware_image(&device, fw_binary, FW1_START, FW1_METADATA, fw1_rows, 1);
379
371
}
380
372
_ => unreachable ! ( ) ,
381
373
}
@@ -414,13 +406,21 @@ fn flash_firmware_image(
414
406
row
415
407
) ;
416
408
}
417
- write_row ( device, ( start_row + row_no) as u16 , row) ;
409
+ write_row ( device, ( start_row + row_no) as u16 , row) . unwrap_or_else ( |err| {
410
+ panic ! (
411
+ "Failed to write firmware row #{} (@{:X}): {:?}" ,
412
+ row_no,
413
+ start_row + row_no,
414
+ err
415
+ )
416
+ } ) ;
418
417
}
419
418
info ! (
420
419
"Writing metadata row@{:X?}: {:X?}" ,
421
420
metadata_row, metadata_slice
422
421
) ;
423
- write_row ( device, metadata_row as u16 , metadata_slice) ;
422
+ write_row ( device, metadata_row as u16 , metadata_slice)
423
+ . expect ( "Failed to write firmware metadata" ) ;
424
424
425
425
// Not quite sure what this is. But on the first update it has
426
426
// 0x01 and on the second it has 0x02. So I think this switches the boot order?
@@ -454,7 +454,7 @@ fn flash_firmware_image(
454
454
. unwrap ( ) ;
455
455
}
456
456
457
- fn write_row ( device : & HidDevice , row_no : u16 , row : & [ u8 ] ) {
457
+ fn write_row ( device : & HidDevice , row_no : u16 , row : & [ u8 ] ) -> Result < usize , HidError > {
458
458
let row_no_bytes = row_no. to_le_bytes ( ) ;
459
459
trace ! ( "Writing row {:04X}. Data: {:X?}" , row_no, row) ;
460
460
@@ -476,7 +476,7 @@ fn write_row(device: &HidDevice, row_no: u16, row: &[u8]) {
476
476
buffer[ 2 ] = row_no_bytes[ 0 ] ;
477
477
buffer[ 3 ] = row_no_bytes[ 1 ] ;
478
478
buffer[ 4 ..] . copy_from_slice ( row) ;
479
- device. write ( & buffer) . unwrap ( ) ;
479
+ device. write ( & buffer)
480
480
}
481
481
482
482
/// Wait for the specific card to reappear
0 commit comments