@@ -26,6 +26,7 @@ char first_device;
26
26
int restart_after_program ;
27
27
int hex_cols ;
28
28
int hex_colw ;
29
+ int force_smarteeprom_config ;
29
30
30
31
//SAM-BA Settings
31
32
mailbox_t initparams ;
@@ -377,6 +378,125 @@ int test_mcu(char silent)
377
378
return 1 ;
378
379
}
379
380
381
+ // SmartEEPROM NVMCTRL section
382
+ int write_user_row (uint32_t * data )
383
+ {
384
+ //Read the current state of NVMCTRL.CTRLA
385
+ NVMCTRL_CTRLA_Type ctrla ;
386
+ ctrla .reg = read_half_word (NVMCTRL_CTRLA );
387
+ 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 );
388
+
389
+ printf ("Configuring SmartEEPROM... " );
390
+
391
+ //Set WMODE to Manual
392
+ ctrla .bit .WMODE = NVMCTRL_CTRLA_WMODE_MAN ;
393
+ if (!write_half_word (NVMCTRL_CTRLA , ctrla .reg ))
394
+ {
395
+ printf ("Error setting NVMCTRL.CTRLA.WMODE to Manual.\n" );
396
+ return 0 ;
397
+ }
398
+ slp (SLEEP_BETWEEN_WRITES );
399
+
400
+ // Set user row address
401
+ if (!write_word (NVMCTRL_ADDR , NVMCTRL_USER ))
402
+ {
403
+ printf ("Error setting NVMCTRL_ADDR to NVMCTRL_USER (1).\n" );
404
+ return 0 ;
405
+ }
406
+
407
+ // Erase page
408
+ NVMCTRL_CTRLB_Type ctrlb ;
409
+ ctrlb .reg = 0 ;
410
+ ctrlb .bit .CMD = NVMCTRL_CTRLB_CMD_EP ;
411
+ ctrlb .bit .CMDEX = NVMCTRL_CTRLB_CMDEX_KEY ;
412
+ if (!write_half_word (NVMCTRL_CTRLB , ctrlb .reg ))
413
+ {
414
+ printf ("Error setting NVMCTRL_CTRLB to 0x%04x (Erase page).\n" , ctrlb .reg );
415
+ return 0 ;
416
+ }
417
+ slp (SLEEP_BETWEEN_WRITES );
418
+
419
+ // Page buffer clear
420
+ ctrlb .reg = 0 ;
421
+ ctrlb .bit .CMD = NVMCTRL_CTRLB_CMD_PBC ;
422
+ ctrlb .bit .CMDEX = NVMCTRL_CTRLB_CMDEX_KEY ;
423
+ if (!write_half_word (NVMCTRL_CTRLB , ctrlb .reg ))
424
+ {
425
+ printf ("Error setting NVMCTRL_CTRLB to 0x%04x (Page buffer clear).\n" , ctrlb .reg );
426
+ return 0 ;
427
+ }
428
+ slp (SLEEP_BETWEEN_WRITES );
429
+
430
+ // Write in the write buffer
431
+ for (int i = 0 ; i < 4 ; i ++ )
432
+ {
433
+ if (!write_word (NVMCTRL_USER + i * 4 , data [i ]))
434
+ {
435
+ printf ("Error: Unable to write NVMCTRL_USER page %i.\n" , i );
436
+ return 0 ;
437
+ }
438
+ slp (SLEEP_BETWEEN_WRITES );
439
+ }
440
+
441
+ if (!write_word (NVMCTRL_ADDR , NVMCTRL_USER ))
442
+ {
443
+ printf ("Error setting NVMCTRL_ADDR to NVMCTRL_USER (2).\n" );
444
+ return 0 ;
445
+ }
446
+ slp (SLEEP_BETWEEN_WRITES );
447
+
448
+ // Write quad word (128bits)
449
+ ctrlb .reg = 0 ;
450
+ ctrlb .bit .CMD = NVMCTRL_CTRLB_CMD_WQW ;
451
+ ctrlb .bit .CMDEX = NVMCTRL_CTRLB_CMDEX_KEY ;
452
+ if (!write_half_word (NVMCTRL_CTRLB , ctrlb .reg ))
453
+ {
454
+ printf ("Error setting NVMCTRL_CTRLB to 0x%04x (Write Quad Word).\n" , ctrlb .reg );
455
+ return 0 ;
456
+ }
457
+
458
+ printf ("Success!\n" );
459
+ return 1 ;
460
+ }
461
+
462
+ void configure_smarteeprom (void )
463
+ {
464
+ uint32_t user_row [4 ];
465
+ printf ("user row: " );
466
+ for (int i = 0 ; i < 4 ; i ++ )
467
+ {
468
+ user_row [i ] = read_word (NVMCTRL_USER + i * 4 );
469
+ printf ("0x%08x " , user_row [i ]);
470
+ }
471
+ printf ("\n" );
472
+
473
+ NVMCTRL_USER_ROW_MAPPING1_Type * puser_row1 = (NVMCTRL_USER_ROW_MAPPING1_Type * )(& user_row [1 ]);
474
+
475
+ // Check current status and proceed accordingly.
476
+ if (puser_row1 -> bit .SBLK == 0 && puser_row1 -> bit .PSZ == 0 )
477
+ {
478
+ printf ("SmartEEPROM not configured, proceed.\n" );
479
+ }
480
+ else
481
+ {
482
+ printf ("SmartEEPROM already configured - SBLK: 0x%04x - PSZ: 0x%03x.\n" , puser_row1 -> bit .SBLK , puser_row1 -> bit .PSZ );
483
+ if (force_smarteeprom_config )
484
+ {
485
+ printf ("--forceeep enabled, proceed.\n" );
486
+ }
487
+ else
488
+ {
489
+ printf ("Use --forceeep to force to configure it anyway.\n" );
490
+ return ;
491
+ }
492
+ }
493
+
494
+ // Set SmartEEPROM Virtual Size.
495
+ puser_row1 -> bit .SBLK = 0x1 ; // 1 block
496
+ puser_row1 -> bit .PSZ = 0x1 ; // 8 bytes
497
+ write_user_row (user_row );
498
+ }
499
+
380
500
//Upper case any lower case characters in a string
381
501
void strlower (char * str )
382
502
{
@@ -490,6 +610,8 @@ void display_help(void)
490
610
printf (" -s --size size Read firmware size of <size>\n" );
491
611
printf (" -D --download file Write firmware from <file> into device\n" );
492
612
printf (" -t --test Test mode (download/upload writes disabled, upload outputs data to stdout, restart disabled)\n" );
613
+ printf (" --smarteep Enable Smart EEPROM MCU feature\n" );
614
+ printf (" --forceeep Force re-configuration of Smart EEPROM MCU feature. Requires --smarteep.\n" );
493
615
printf (" --cols count Hex listing column count <count> [%i]\n" , COLS );
494
616
printf (" --colw width Hex listing column width <width> [%i]\n" , COLW );
495
617
printf (" --restart Restart device after successful programming\n" );
@@ -498,11 +620,13 @@ void display_help(void)
498
620
499
621
#define SW_COLS 1000
500
622
#define SW_COLW 1001
623
+ #define SW_SMARTEEP 1002
501
624
502
625
//Program command line options
503
626
struct option long_options [] = {
504
627
//Flags
505
628
{ "restart" , no_argument , & restart_after_program , 1 },
629
+ { "forceeep" , no_argument , & force_smarteeprom_config , 1 },
506
630
//Other
507
631
{ "verbose" , no_argument , 0 , 'v' },
508
632
{ "help" , no_argument , 0 , 'h' },
@@ -515,6 +639,7 @@ struct option long_options[] = {
515
639
{ "addr" , required_argument , 0 , 'a' },
516
640
{ "size" , required_argument , 0 , 's' },
517
641
{ "test" , no_argument , 0 , 't' },
642
+ { "smarteep" , no_argument , 0 , SW_SMARTEEP },
518
643
{ "cols" , required_argument , 0 , SW_COLS },
519
644
{ "colw" , required_argument , 0 , SW_COLW },
520
645
{ 0 , 0 , 0 , 0 }
@@ -528,6 +653,7 @@ int main(int argc, char *argv[])
528
653
restart_after_program = 0 ;
529
654
hex_cols = COLS ;
530
655
hex_colw = COLW ;
656
+ force_smarteeprom_config = 0 ;
531
657
532
658
display_version ();
533
659
display_copyright ();
@@ -628,6 +754,10 @@ int main(int argc, char *argv[])
628
754
testmode = 1 ;
629
755
break ;
630
756
757
+ case SW_SMARTEEP :
758
+ command = CMD_CONFIG_SMARTEEPROM ;
759
+ break ;
760
+
631
761
case SW_COLS :
632
762
hex_cols = atoi (optarg );
633
763
if (hex_cols < 1 )
@@ -751,14 +881,24 @@ int main(int argc, char *argv[])
751
881
print_bootloader_version ();
752
882
if (verbose ) printf ("Device ID: %08X\n" , mcu -> cidr );
753
883
884
+ if (command == CMD_CONFIG_SMARTEEPROM )
885
+ {
886
+ configure_smarteeprom ();
887
+
888
+ if (restart_after_program )
889
+ jump_application ();
890
+
891
+ goto exitProgram ;
892
+ }
893
+
754
894
//Load applet
755
895
FILE * fIn ;
756
896
char appletfname [128 ] = "" ;
757
897
strlower (mcu -> name );
758
898
759
899
//sprintf(appletfname, "applet-flash-%s.bin", mcu->name);
760
900
sprintf (appletfname , "applet-mdflash.bin" ); //make filename non-dependent upon mcu->name
761
-
901
+
762
902
printf ("Applet file: %s\n" , appletfname );
763
903
764
904
fIn = fopen (appletfname , "rb" );
0 commit comments