@@ -29,6 +29,7 @@ char verbose;
29
29
char testmode ;
30
30
char first_device ;
31
31
int restart_after_program ;
32
+ int force_smarteeprom_config ;
32
33
int hex_cols ;
33
34
int hex_colw ;
34
35
@@ -382,6 +383,132 @@ int test_mcu(char silent)
382
383
return 1 ;
383
384
}
384
385
386
+ // SmartEEPROM NVMCTRL section
387
+ uint8_t write_user_row (uint32_t * data )
388
+ {
389
+ //Read the current state of NVMCTRL.CTRLA
390
+ NVMCTRL_CTRLA_Type ctrla ;
391
+ ctrla .reg = read_half_word (NVMCTRL_CTRLA );
392
+ 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 );
393
+
394
+ printf ("SmartEEPROM: Configuring... " );
395
+
396
+ //Set WMODE to Manual
397
+ ctrla .bit .WMODE = NVMCTRL_CTRLA_WMODE_MAN ;
398
+ if (!write_half_word (NVMCTRL_CTRLA , ctrla .reg ))
399
+ {
400
+ printf ("Error: setting NVMCTRL.CTRLA.WMODE to Manual.\n" );
401
+ return 0 ;
402
+ }
403
+ slp (SLEEP_BETWEEN_WRITES );
404
+
405
+ // Set user row address
406
+ if (!write_word (NVMCTRL_ADDR , NVMCTRL_USER ))
407
+ {
408
+ printf ("Error: setting NVMCTRL_ADDR to NVMCTRL_USER (1).\n" );
409
+ return 0 ;
410
+ }
411
+
412
+ // Erase page
413
+ NVMCTRL_CTRLB_Type ctrlb ;
414
+ ctrlb .reg = 0 ;
415
+ ctrlb .bit .CMD = NVMCTRL_CTRLB_CMD_EP ;
416
+ ctrlb .bit .CMDEX = NVMCTRL_CTRLB_CMDEX_KEY ;
417
+ if (!write_half_word (NVMCTRL_CTRLB , ctrlb .reg ))
418
+ {
419
+ printf ("Error: setting NVMCTRL_CTRLB to 0x%04x (Erase page).\n" , ctrlb .reg );
420
+ return 0 ;
421
+ }
422
+ slp (SLEEP_BETWEEN_WRITES );
423
+
424
+ // Page buffer clear
425
+ ctrlb .reg = 0 ;
426
+ ctrlb .bit .CMD = NVMCTRL_CTRLB_CMD_PBC ;
427
+ ctrlb .bit .CMDEX = NVMCTRL_CTRLB_CMDEX_KEY ;
428
+ if (!write_half_word (NVMCTRL_CTRLB , ctrlb .reg ))
429
+ {
430
+ printf ("Error: setting NVMCTRL_CTRLB to 0x%04x (Page buffer clear).\n" , ctrlb .reg );
431
+ return 0 ;
432
+ }
433
+ slp (SLEEP_BETWEEN_WRITES );
434
+
435
+ // Write in the write buffer
436
+ for (int i = 0 ; i < 4 ; i ++ )
437
+ {
438
+ if (!write_word (NVMCTRL_USER + i * 4 , data [i ]))
439
+ {
440
+ printf ("Error: Unable to write NVMCTRL_USER page %i.\n" , i );
441
+ return 0 ;
442
+ }
443
+ slp (SLEEP_BETWEEN_WRITES );
444
+ }
445
+
446
+ if (!write_word (NVMCTRL_ADDR , NVMCTRL_USER ))
447
+ {
448
+ printf ("Error: setting NVMCTRL_ADDR to NVMCTRL_USER (2).\n" );
449
+ return 0 ;
450
+ }
451
+ slp (SLEEP_BETWEEN_WRITES );
452
+
453
+ // Write quad word (128bits)
454
+ ctrlb .reg = 0 ;
455
+ ctrlb .bit .CMD = NVMCTRL_CTRLB_CMD_WQW ;
456
+ ctrlb .bit .CMDEX = NVMCTRL_CTRLB_CMDEX_KEY ;
457
+ if (!write_half_word (NVMCTRL_CTRLB , ctrlb .reg ))
458
+ {
459
+ printf ("Error: setting NVMCTRL_CTRLB to 0x%04x (Write Quad Word).\n" , ctrlb .reg );
460
+ return 0 ;
461
+ }
462
+ slp (SLEEP_BETWEEN_WRITES );
463
+
464
+ printf ("Success!\n" );
465
+ return 1 ;
466
+ }
467
+
468
+ uint8_t configure_smarteeprom (void )
469
+ {
470
+ // Configure for 2048 bytes - DS60001507E-page 653
471
+ #define TARGET_SBLK 1 // 1 block
472
+ #define TARGET_PSZ 2 // 16 bytes
473
+
474
+ uint32_t user_row [4 ];
475
+ for (int i = 0 ; i < 4 ; i ++ )
476
+ {
477
+ user_row [i ] = read_word (NVMCTRL_USER + i * 4 );
478
+ }
479
+
480
+ NVMCTRL_USER_ROW_MAPPING1_Type * puser_row1 = (NVMCTRL_USER_ROW_MAPPING1_Type * )(& user_row [1 ]);
481
+
482
+ if (verbose ) printf ("SmartEEPROM: config - SBLK: 0x%04x - PSZ: 0x%03x.\n" , puser_row1 -> bit .SBLK , puser_row1 -> bit .PSZ );
483
+
484
+ if (puser_row1 -> bit .SBLK == TARGET_SBLK && puser_row1 -> bit .PSZ == TARGET_PSZ )
485
+ {
486
+ if (verbose ) printf ("SmartEEPROM: Configured!\n" );
487
+ return 1 ;
488
+ }
489
+
490
+ uint8_t should_reconfigure ;
491
+ if (force_smarteeprom_config == FORCE_NONE )
492
+ {
493
+ should_reconfigure = prompt_yes_no ("SmartEEPROM: Your settings do not match the recommended values. Update setting?" );
494
+ }
495
+ else
496
+ {
497
+ should_reconfigure = (force_smarteeprom_config == FORCE_YES );
498
+ }
499
+
500
+ if (!should_reconfigure )
501
+ {
502
+ printf ("SmartEEPROM: Skipped!\n" );
503
+ return 1 ;
504
+ }
505
+
506
+ // Set SmartEEPROM Virtual Size.
507
+ puser_row1 -> bit .SBLK = TARGET_SBLK ;
508
+ puser_row1 -> bit .PSZ = TARGET_PSZ ;
509
+ return write_user_row (user_row );
510
+ }
511
+
385
512
//Upper case any lower case characters in a string
386
513
void strlower (char * str )
387
514
{
@@ -404,6 +531,21 @@ void strupper(char *str)
404
531
}
405
532
}
406
533
534
+ //Prompt for Yy/Nn with message
535
+ uint8_t prompt_yes_no (const char * msg )
536
+ {
537
+ printf (msg );
538
+ printf (" (y/n):\n" );
539
+
540
+ char c ;
541
+ do {
542
+ scanf (" %c" , & c );
543
+ c = toupper (c );
544
+ } while (c != 'N' && c != 'Y' );
545
+
546
+ return c == 'Y' ;
547
+ }
548
+
407
549
//Return file size of given file
408
550
int filesize (char * fname )
409
551
{
@@ -495,6 +637,7 @@ void display_help(void)
495
637
printf (" -s --size size Read firmware size of <size>\n" );
496
638
printf (" -D --download file Write firmware from <file> into device\n" );
497
639
printf (" -t --test Test mode (download/upload writes disabled, upload outputs data to stdout, restart disabled)\n" );
640
+ printf (" --forceeep answer Automatic answer to Smart EEPROM re-configuration prompt <y/n>\n" );
498
641
printf (" --cols count Hex listing column count <count> [%i]\n" , COLS );
499
642
printf (" --colw width Hex listing column width <width> [%i]\n" , COLW );
500
643
printf (" --restart Restart device after successful programming\n" );
@@ -503,6 +646,7 @@ void display_help(void)
503
646
504
647
#define SW_COLS 1000
505
648
#define SW_COLW 1001
649
+ #define SW_FORCEEEP 1002
506
650
507
651
//Program command line options
508
652
struct option long_options [] = {
@@ -522,6 +666,7 @@ struct option long_options[] = {
522
666
{ "test" , no_argument , 0 , 't' },
523
667
{ "cols" , required_argument , 0 , SW_COLS },
524
668
{ "colw" , required_argument , 0 , SW_COLW },
669
+ { "forceeep" , required_argument , 0 , SW_FORCEEEP },
525
670
{ 0 , 0 , 0 , 0 }
526
671
};
527
672
@@ -531,6 +676,7 @@ int main(int argc, char *argv[])
531
676
testmode = 0 ;
532
677
first_device = 0 ;
533
678
restart_after_program = 0 ;
679
+ force_smarteeprom_config = FORCE_NONE ;
534
680
hex_cols = COLS ;
535
681
hex_colw = COLW ;
536
682
@@ -651,6 +797,11 @@ int main(int argc, char *argv[])
651
797
}
652
798
break ;
653
799
800
+ case SW_FORCEEEP :
801
+ strlower (optarg );
802
+ force_smarteeprom_config = (strstr (optarg , "y" ) != NULL ) ? FORCE_YES : FORCE_NO ;
803
+ break ;
804
+
654
805
default :
655
806
command = CMD_ABORT ;
656
807
break ;
@@ -756,7 +907,13 @@ int main(int argc, char *argv[])
756
907
print_bootloader_version ();
757
908
if (verbose ) printf ("Device ID: %08X\n" , mcu -> cidr );
758
909
910
+ if (!configure_smarteeprom ())
911
+ {
912
+ printf ("Error: Config feature failed!\n" );
913
+ goto closePort ;
914
+ }
759
915
916
+ //Load applet
760
917
memcpy (& appinfo , applet_data + applet_size - sizeof (appinfo_t ), sizeof (appinfo_t ));
761
918
if (appinfo .magic != 0x4142444D )
762
919
{
0 commit comments