@@ -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,118 @@ 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
+ uint32_t user_row [4 ];
471
+ for (int i = 0 ; i < 4 ; i ++ )
472
+ {
473
+ user_row [i ] = read_word (NVMCTRL_USER + i * 4 );
474
+ }
475
+
476
+ NVMCTRL_USER_ROW_MAPPING1_Type * puser_row1 = (NVMCTRL_USER_ROW_MAPPING1_Type * )(& user_row [1 ]);
477
+
478
+ if (verbose ) printf ("SmartEEPROM: config - SBLK: 0x%04x - PSZ: 0x%03x.\n" , puser_row1 -> bit .SBLK , puser_row1 -> bit .PSZ );
479
+
480
+ if (puser_row1 -> bit .SBLK == SMARTEEPROM_TARGET_SBLK && puser_row1 -> bit .PSZ == SMARTEEPROM_TARGET_PSZ )
481
+ {
482
+ if (verbose ) printf ("SmartEEPROM: Configured!\n" );
483
+ return 1 ;
484
+ }
485
+
486
+ if (ignore_smarteeprom_config )
487
+ {
488
+ printf ("SmartEEPROM: Your settings do not match the recommended values. Skipped!" );
489
+ return 1 ;
490
+ }
491
+
492
+ // Set SmartEEPROM Virtual Size.
493
+ puser_row1 -> bit .SBLK = SMARTEEPROM_TARGET_SBLK ;
494
+ puser_row1 -> bit .PSZ = SMARTEEPROM_TARGET_PSZ ;
495
+ return write_user_row (user_row );
496
+ }
497
+
385
498
//Upper case any lower case characters in a string
386
499
void strlower (char * str )
387
500
{
@@ -495,6 +608,7 @@ void display_help(void)
495
608
printf (" -s --size size Read firmware size of <size>\n" );
496
609
printf (" -D --download file Write firmware from <file> into device\n" );
497
610
printf (" -t --test Test mode (download/upload writes disabled, upload outputs data to stdout, restart disabled)\n" );
611
+ printf (" --ignore-eep Ignore differences in SmartEEPROM configuration\n" );
498
612
printf (" --cols count Hex listing column count <count> [%i]\n" , COLS );
499
613
printf (" --colw width Hex listing column width <width> [%i]\n" , COLW );
500
614
printf (" --restart Restart device after successful programming\n" );
@@ -507,7 +621,8 @@ void display_help(void)
507
621
//Program command line options
508
622
struct option long_options [] = {
509
623
//Flags
510
- { "restart" , no_argument , & restart_after_program , 1 },
624
+ { "restart" , no_argument , & restart_after_program , 1 },
625
+ { "ignore-eep" , no_argument , & ignore_smarteeprom_config , 1 },
511
626
//Other
512
627
{ "verbose" , no_argument , 0 , 'v' },
513
628
{ "help" , no_argument , 0 , 'h' },
@@ -531,6 +646,7 @@ int main(int argc, char *argv[])
531
646
testmode = 0 ;
532
647
first_device = 0 ;
533
648
restart_after_program = 0 ;
649
+ ignore_smarteeprom_config = 0 ;
534
650
hex_cols = COLS ;
535
651
hex_colw = COLW ;
536
652
@@ -756,7 +872,13 @@ int main(int argc, char *argv[])
756
872
print_bootloader_version ();
757
873
if (verbose ) printf ("Device ID: %08X\n" , mcu -> cidr );
758
874
875
+ if (!configure_smarteeprom ())
876
+ {
877
+ printf ("Error: Config feature failed!\n" );
878
+ goto closePort ;
879
+ }
759
880
881
+ //Load applet
760
882
memcpy (& appinfo , applet_data + applet_size - sizeof (appinfo_t ), sizeof (appinfo_t ));
761
883
if (appinfo .magic != 0x4142444D )
762
884
{
0 commit comments