@@ -31,6 +31,7 @@ char first_device;
31
31
int restart_after_program ;
32
32
int hex_cols ;
33
33
int hex_colw ;
34
+ int force_smarteeprom_config ;
34
35
35
36
//SAM-BA Settings
36
37
mailbox_t initparams ;
@@ -382,6 +383,125 @@ int test_mcu(char silent)
382
383
return 1 ;
383
384
}
384
385
386
+ // SmartEEPROM NVMCTRL section
387
+ int 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
+ 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 ("Configuring SmartEEPROM... " );
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
+
463
+ printf ("Success!\n" );
464
+ return 1 ;
465
+ }
466
+
467
+ void configure_smarteeprom (void )
468
+ {
469
+ uint32_t user_row [4 ];
470
+ printf ("user row: " );
471
+ for (int i = 0 ; i < 4 ; i ++ )
472
+ {
473
+ user_row [i ] = read_word (NVMCTRL_USER + i * 4 );
474
+ printf ("0x%08x " , user_row [i ]);
475
+ }
476
+ printf ("\n" );
477
+
478
+ NVMCTRL_USER_ROW_MAPPING1_Type * puser_row1 = (NVMCTRL_USER_ROW_MAPPING1_Type * )(& user_row [1 ]);
479
+
480
+ // Check current status and proceed accordingly.
481
+ if (puser_row1 -> bit .SBLK == 0 && puser_row1 -> bit .PSZ == 0 )
482
+ {
483
+ printf ("SmartEEPROM not configured, proceed.\n" );
484
+ }
485
+ else
486
+ {
487
+ printf ("SmartEEPROM already configured - SBLK: 0x%04x - PSZ: 0x%03x.\n" , puser_row1 -> bit .SBLK , puser_row1 -> bit .PSZ );
488
+ if (force_smarteeprom_config )
489
+ {
490
+ printf ("--forceeep enabled, proceed.\n" );
491
+ }
492
+ else
493
+ {
494
+ printf ("Use --forceeep to force to configure it anyway.\n" );
495
+ return ;
496
+ }
497
+ }
498
+
499
+ // Set SmartEEPROM Virtual Size.
500
+ puser_row1 -> bit .SBLK = 0x1 ; // 1 block
501
+ puser_row1 -> bit .PSZ = 0x1 ; // 8 bytes
502
+ write_user_row (user_row );
503
+ }
504
+
385
505
//Upper case any lower case characters in a string
386
506
void strlower (char * str )
387
507
{
@@ -495,6 +615,8 @@ void display_help(void)
495
615
printf (" -s --size size Read firmware size of <size>\n" );
496
616
printf (" -D --download file Write firmware from <file> into device\n" );
497
617
printf (" -t --test Test mode (download/upload writes disabled, upload outputs data to stdout, restart disabled)\n" );
618
+ printf (" --smarteep Enable Smart EEPROM MCU feature\n" );
619
+ printf (" --forceeep Force re-configuration of Smart EEPROM MCU feature. Requires --smarteep.\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" );
@@ -503,11 +625,13 @@ void display_help(void)
503
625
504
626
#define SW_COLS 1000
505
627
#define SW_COLW 1001
628
+ #define SW_SMARTEEP 1002
506
629
507
630
//Program command line options
508
631
struct option long_options [] = {
509
632
//Flags
510
633
{ "restart" , no_argument , & restart_after_program , 1 },
634
+ { "forceeep" , no_argument , & force_smarteeprom_config , 1 },
511
635
//Other
512
636
{ "verbose" , no_argument , 0 , 'v' },
513
637
{ "help" , no_argument , 0 , 'h' },
@@ -520,6 +644,7 @@ struct option long_options[] = {
520
644
{ "addr" , required_argument , 0 , 'a' },
521
645
{ "size" , required_argument , 0 , 's' },
522
646
{ "test" , no_argument , 0 , 't' },
647
+ { "smarteep" , no_argument , 0 , SW_SMARTEEP },
523
648
{ "cols" , required_argument , 0 , SW_COLS },
524
649
{ "colw" , required_argument , 0 , SW_COLW },
525
650
{ 0 , 0 , 0 , 0 }
@@ -533,6 +658,7 @@ int main(int argc, char *argv[])
533
658
restart_after_program = 0 ;
534
659
hex_cols = COLS ;
535
660
hex_colw = COLW ;
661
+ force_smarteeprom_config = 0 ;
536
662
537
663
display_version ();
538
664
display_copyright ();
@@ -633,6 +759,10 @@ int main(int argc, char *argv[])
633
759
testmode = 1 ;
634
760
break ;
635
761
762
+ case SW_SMARTEEP :
763
+ command = CMD_CONFIG_SMARTEEPROM ;
764
+ break ;
765
+
636
766
case SW_COLS :
637
767
hex_cols = atoi (optarg );
638
768
if (hex_cols < 1 )
@@ -754,7 +884,17 @@ int main(int argc, char *argv[])
754
884
printf ("Found MCU: %s\n" , mcu -> name );
755
885
756
886
print_bootloader_version ();
887
+
757
888
if (verbose ) printf ("Device ID: %08X\n" , mcu -> cidr );
889
+ if (command == CMD_CONFIG_SMARTEEPROM )
890
+ {
891
+ configure_smarteeprom ();
892
+
893
+ if (restart_after_program )
894
+ jump_application ();
895
+
896
+ goto exitProgram ;
897
+ }
758
898
759
899
760
900
memcpy (& appinfo , applet_data + applet_size - sizeof (appinfo_t ), sizeof (appinfo_t ));
0 commit comments