@@ -29,6 +29,7 @@ char verbose;
29
29
char testmode ;
30
30
char first_device ;
31
31
int restart_after_program ;
32
+ int ignore_smarteeprom_config ;
32
33
int hex_cols ;
33
34
int hex_colw ;
34
35
@@ -382,6 +383,126 @@ int test_mcu(char silent)
382
383
return 1 ;
383
384
}
384
385
386
+ static void sleep_between_writes (void )
387
+ {
388
+ printf ("." );
389
+ fflush (stdout );
390
+ slp (SLEEP_BETWEEN_WRITES );
391
+ }
392
+
393
+ // SmartEEPROM NVMCTRL section
394
+ uint8_t write_user_row (uint32_t * data )
395
+ {
396
+ //Read the current state of NVMCTRL.CTRLA
397
+ NVMCTRL_CTRLA_Type ctrla ;
398
+ ctrla .reg = read_half_word (NVMCTRL_CTRLA );
399
+ if (verbose ) printf ("NVMCTRL.CTRLA: 0x%04x\n\tAUTOWS: 0x%01x\n\tSUSPEN: 0x%01x\n\tWMODE: 0x%02x\n\tPRM: 0x%02x\n\tRWS: 0x%04x\n\tAHBNS0: 0x%01x\n\tAHBNS1: 0x%01x\n\tCACHEDIS0: 0x%01x\n\tCACHEDIS1: 0x%01x\n" , ctrla .reg , ctrla .bit .AUTOWS , ctrla .bit .SUSPEN , ctrla .bit .WMODE , ctrla .bit .PRM , ctrla .bit .RWS , ctrla .bit .AHBNS0 , ctrla .bit .AHBNS1 , ctrla .bit .CACHEDIS0 , ctrla .bit .CACHEDIS1 );
400
+
401
+ printf ("SmartEEPROM: Configuring..." );
402
+
403
+ //Set WMODE to Manual
404
+ ctrla .bit .WMODE = NVMCTRL_CTRLA_WMODE_MAN ;
405
+ if (!write_half_word (NVMCTRL_CTRLA , ctrla .reg ))
406
+ {
407
+ printf ("Error: setting NVMCTRL.CTRLA.WMODE to Manual.\n" );
408
+ return 0 ;
409
+ }
410
+ sleep_between_writes ();
411
+
412
+ // Set user row address
413
+ if (!write_word (NVMCTRL_ADDR , NVMCTRL_USER ))
414
+ {
415
+ printf ("Error: setting NVMCTRL_ADDR to NVMCTRL_USER (1).\n" );
416
+ return 0 ;
417
+ }
418
+ sleep_between_writes ();
419
+
420
+ // Erase page
421
+ NVMCTRL_CTRLB_Type ctrlb ;
422
+ ctrlb .reg = 0 ;
423
+ ctrlb .bit .CMD = NVMCTRL_CTRLB_CMD_EP ;
424
+ ctrlb .bit .CMDEX = NVMCTRL_CTRLB_CMDEX_KEY ;
425
+ if (!write_half_word (NVMCTRL_CTRLB , ctrlb .reg ))
426
+ {
427
+ printf ("Error: setting NVMCTRL_CTRLB to 0x%04x (Erase page).\n" , ctrlb .reg );
428
+ return 0 ;
429
+ }
430
+ sleep_between_writes ();
431
+
432
+ // Page buffer clear
433
+ ctrlb .reg = 0 ;
434
+ ctrlb .bit .CMD = NVMCTRL_CTRLB_CMD_PBC ;
435
+ ctrlb .bit .CMDEX = NVMCTRL_CTRLB_CMDEX_KEY ;
436
+ if (!write_half_word (NVMCTRL_CTRLB , ctrlb .reg ))
437
+ {
438
+ printf ("Error: setting NVMCTRL_CTRLB to 0x%04x (Page buffer clear).\n" , ctrlb .reg );
439
+ return 0 ;
440
+ }
441
+ sleep_between_writes ();
442
+
443
+ // Write in the write buffer
444
+ for (int i = 0 ; i < 4 ; i ++ )
445
+ {
446
+ if (!write_word (NVMCTRL_USER + i * 4 , data [i ]))
447
+ {
448
+ printf ("Error: Unable to write NVMCTRL_USER page %i.\n" , i );
449
+ return 0 ;
450
+ }
451
+ sleep_between_writes ();
452
+ }
453
+
454
+ if (!write_word (NVMCTRL_ADDR , NVMCTRL_USER ))
455
+ {
456
+ printf ("Error: setting NVMCTRL_ADDR to NVMCTRL_USER (2).\n" );
457
+ return 0 ;
458
+ }
459
+ sleep_between_writes ();
460
+
461
+ // Write quad word (128bits)
462
+ ctrlb .reg = 0 ;
463
+ ctrlb .bit .CMD = NVMCTRL_CTRLB_CMD_WQW ;
464
+ ctrlb .bit .CMDEX = NVMCTRL_CTRLB_CMDEX_KEY ;
465
+ if (!write_half_word (NVMCTRL_CTRLB , ctrlb .reg ))
466
+ {
467
+ printf ("Error: setting NVMCTRL_CTRLB to 0x%04x (Write Quad Word).\n" , ctrlb .reg );
468
+ return 0 ;
469
+ }
470
+ sleep_between_writes ();
471
+
472
+ printf (" Success!\n" );
473
+ return 1 ;
474
+ }
475
+
476
+ uint8_t configure_smarteeprom (void )
477
+ {
478
+ uint32_t user_row [4 ];
479
+ for (int i = 0 ; i < 4 ; i ++ )
480
+ {
481
+ user_row [i ] = read_word (NVMCTRL_USER + i * 4 );
482
+ }
483
+
484
+ NVMCTRL_USER_ROW_MAPPING1_Type * puser_row1 = (NVMCTRL_USER_ROW_MAPPING1_Type * )(& user_row [1 ]);
485
+
486
+ if (verbose ) printf ("SmartEEPROM: config - SBLK: 0x%04x - PSZ: 0x%03x.\n" , puser_row1 -> bit .SBLK , puser_row1 -> bit .PSZ );
487
+
488
+ if (puser_row1 -> bit .SBLK == SMARTEEPROM_TARGET_SBLK && puser_row1 -> bit .PSZ == SMARTEEPROM_TARGET_PSZ )
489
+ {
490
+ if (verbose ) printf ("SmartEEPROM: Configured!\n" );
491
+ return 1 ;
492
+ }
493
+
494
+ if (ignore_smarteeprom_config )
495
+ {
496
+ printf ("SmartEEPROM: Your settings do not match the recommended values - Some functionality may not work as expected!" );
497
+ return 1 ;
498
+ }
499
+
500
+ // Set SmartEEPROM Virtual Size.
501
+ puser_row1 -> bit .SBLK = SMARTEEPROM_TARGET_SBLK ;
502
+ puser_row1 -> bit .PSZ = SMARTEEPROM_TARGET_PSZ ;
503
+ return write_user_row (user_row );
504
+ }
505
+
385
506
//Upper case any lower case characters in a string
386
507
void strlower (char * str )
387
508
{
@@ -495,6 +616,7 @@ void display_help(void)
495
616
printf (" -s --size size Read firmware size of <size>\n" );
496
617
printf (" -D --download file Write firmware from <file> into device\n" );
497
618
printf (" -t --test Test mode (download/upload writes disabled, upload outputs data to stdout, restart disabled)\n" );
619
+ printf (" --ignore-eep Ignore differences in SmartEEPROM configuration\n" );
498
620
printf (" --cols count Hex listing column count <count> [%i]\n" , COLS );
499
621
printf (" --colw width Hex listing column width <width> [%i]\n" , COLW );
500
622
printf (" --restart Restart device after successful programming\n" );
@@ -507,7 +629,8 @@ void display_help(void)
507
629
//Program command line options
508
630
struct option long_options [] = {
509
631
//Flags
510
- { "restart" , no_argument , & restart_after_program , 1 },
632
+ { "restart" , no_argument , & restart_after_program , 1 },
633
+ { "ignore-eep" , no_argument , & ignore_smarteeprom_config , 1 },
511
634
//Other
512
635
{ "verbose" , no_argument , 0 , 'v' },
513
636
{ "help" , no_argument , 0 , 'h' },
@@ -531,6 +654,7 @@ int main(int argc, char *argv[])
531
654
testmode = 0 ;
532
655
first_device = 0 ;
533
656
restart_after_program = 0 ;
657
+ ignore_smarteeprom_config = 0 ;
534
658
hex_cols = COLS ;
535
659
hex_colw = COLW ;
536
660
@@ -756,7 +880,13 @@ int main(int argc, char *argv[])
756
880
print_bootloader_version ();
757
881
if (verbose ) printf ("Device ID: %08X\n" , mcu -> cidr );
758
882
883
+ if (!configure_smarteeprom ())
884
+ {
885
+ printf ("Error: Config feature failed!\n" );
886
+ goto closePort ;
887
+ }
759
888
889
+ //Load applet
760
890
memcpy (& appinfo , applet_data + applet_size - sizeof (appinfo_t ), sizeof (appinfo_t ));
761
891
if (appinfo .magic != 0x4142444D )
762
892
{
0 commit comments