@@ -377,6 +377,110 @@ int test_mcu(char silent)
377
377
return 1 ;
378
378
}
379
379
380
+ // SmartEEPROM NVMCTRL section
381
+ int write_user_row (uint32_t * data )
382
+ {
383
+ //Set WMODE to Manual
384
+ NVMCTRL_CTRLA_Type ctrla ;
385
+ ctrla .reg = read_half_word (NVMCTRL_CTRLA );
386
+ 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 );
387
+ ctrla .bit .WMODE = NVMCTRL_CTRLA_WMODE_MAN ;
388
+
389
+ printf ("Configuring SmartEEPROM... " );
390
+
391
+ if (!write_half_word (NVMCTRL_CTRLA , ctrla .reg ))
392
+ {
393
+ printf ("Error setting NVMCTRL.CTRLA.WMODE to Manual\n" );
394
+ return 0 ;
395
+ }
396
+ slp (100 );
397
+
398
+ // Set user row address
399
+ if (!write_word (NVMCTRL_ADDR , NVMCTRL_USER ))
400
+ {
401
+ printf ("Error setting NVMCTRL_ADDR to NVMCTRL_USER (1)\n" );
402
+ return 0 ;
403
+ }
404
+
405
+ // Erase page
406
+ NVMCTRL_CTRLB_Type ctrlb ;
407
+ ctrlb .reg = 0 ;
408
+ ctrlb .bit .CMD = NVMCTRL_CTRLB_CMD_EP ;
409
+ ctrlb .bit .CMDEX = NVMCTRL_CTRLB_CMDEX_KEY ;
410
+ if (!write_half_word (NVMCTRL_CTRLB , ctrlb .reg ))
411
+ {
412
+ printf ("Error setting NVMCTRL_CTRLB to 0x%04x (Erase page)\n" , ctrlb .reg );
413
+ return 0 ;
414
+ }
415
+ slp (100 );
416
+
417
+ // Page buffer clear
418
+ ctrlb .reg = 0 ;
419
+ ctrlb .bit .CMD = NVMCTRL_CTRLB_CMD_PBC ;
420
+ ctrlb .bit .CMDEX = NVMCTRL_CTRLB_CMDEX_KEY ;
421
+ if (!write_half_word (NVMCTRL_CTRLB , ctrlb .reg ))
422
+ {
423
+ printf ("Error setting NVMCTRL_CTRLB to 0x%04x (Page buffer clear)\n" , ctrlb .reg );
424
+ return 0 ;
425
+ }
426
+ slp (100 );
427
+
428
+ // Write in the write buffer
429
+ for (int i = 0 ; i < 4 ; i ++ )
430
+ {
431
+ if (!write_word (NVMCTRL_USER + i * 4 , data [i ]))
432
+ {
433
+ printf ("Warning: Unable to write NVMCTRL_USER page %i\n" , i );
434
+ }
435
+ slp (100 );
436
+ }
437
+
438
+ if (!write_word (NVMCTRL_ADDR , NVMCTRL_USER ))
439
+ {
440
+ printf ("Error setting NVMCTRL_ADDR to NVMCTRL_USER (2)\n" );
441
+ return 0 ;
442
+ }
443
+ slp (100 );
444
+
445
+ // Write quad word (128bits)
446
+ ctrlb .reg = 0 ;
447
+ ctrlb .bit .CMD = NVMCTRL_CTRLB_CMD_WQW ;
448
+ ctrlb .bit .CMDEX = NVMCTRL_CTRLB_CMDEX_KEY ;
449
+ if (!write_half_word (NVMCTRL_CTRLB , ctrlb .reg ))
450
+ {
451
+ printf ("Error setting NVMCTRL_CTRLB to 0x%04x (Write Quad Word)\n" , ctrlb .reg );
452
+ return 0 ;
453
+ }
454
+
455
+ printf ("Success!\n" );
456
+ return 1 ;
457
+ }
458
+
459
+ void read_user_row (void )
460
+ {
461
+ uint32_t user_row [4 ];
462
+ printf ("user row: " );
463
+ for (int i = 0 ; i < 4 ; i ++ )
464
+ {
465
+ user_row [i ] = read_word (NVMCTRL_USER + i * 4 );
466
+ printf ("0x%08x " , user_row [i ]);
467
+ }
468
+ printf ("\n" );
469
+
470
+ NVMCTRL_USER_ROW_MAPPING1_Type * puser_row1 = (NVMCTRL_USER_ROW_MAPPING1_Type * )(& user_row [1 ]);
471
+ if (puser_row1 -> bit .SBLK == 0 && puser_row1 -> bit .PSZ == 0 )
472
+ {
473
+ printf ("SmartEEPROM not configured, proceed\n" );
474
+ puser_row1 -> bit .SBLK = 0x2 ; // 2 blocks
475
+ puser_row1 -> bit .PSZ = 0x1 ; // 8 bytes
476
+ write_user_row (user_row );
477
+ }
478
+ else
479
+ {
480
+ printf ("SmartEEPROM already configured - SBLK: 0x%04x - PSZ: 0x%03x\n" , puser_row1 -> bit .SBLK , puser_row1 -> bit .PSZ );
481
+ }
482
+ }
483
+
380
484
//Upper case any lower case characters in a string
381
485
void strlower (char * str )
382
486
{
@@ -490,6 +594,7 @@ void display_help(void)
490
594
printf (" -s --size size Read firmware size of <size>\n" );
491
595
printf (" -D --download file Write firmware from <file> into device\n" );
492
596
printf (" -t --test Test mode (download/upload writes disabled, upload outputs data to stdout, restart disabled)\n" );
597
+ printf (" --smarteep Enable Smart EEPROM MCU feature\n" );
493
598
printf (" --cols count Hex listing column count <count> [%i]\n" , COLS );
494
599
printf (" --colw width Hex listing column width <width> [%i]\n" , COLW );
495
600
printf (" --restart Restart device after successful programming\n" );
@@ -498,6 +603,7 @@ void display_help(void)
498
603
499
604
#define SW_COLS 1000
500
605
#define SW_COLW 1001
606
+ #define SW_SMARTEEP 1002
501
607
502
608
//Program command line options
503
609
struct option long_options [] = {
@@ -515,6 +621,7 @@ struct option long_options[] = {
515
621
{ "addr" , required_argument , 0 , 'a' },
516
622
{ "size" , required_argument , 0 , 's' },
517
623
{ "test" , no_argument , 0 , 't' },
624
+ { "smarteep" , no_argument , 0 , SW_SMARTEEP },
518
625
{ "cols" , required_argument , 0 , SW_COLS },
519
626
{ "colw" , required_argument , 0 , SW_COLW },
520
627
{ 0 , 0 , 0 , 0 }
@@ -628,6 +735,10 @@ int main(int argc, char *argv[])
628
735
testmode = 1 ;
629
736
break ;
630
737
738
+ case SW_SMARTEEP :
739
+ command = CMD_READ_USER_ROW ;
740
+ break ;
741
+
631
742
case SW_COLS :
632
743
hex_cols = atoi (optarg );
633
744
if (hex_cols < 1 )
@@ -751,14 +862,24 @@ int main(int argc, char *argv[])
751
862
print_bootloader_version ();
752
863
if (verbose ) printf ("Device ID: %08X\n" , mcu -> cidr );
753
864
865
+ if (command == CMD_READ_USER_ROW )
866
+ {
867
+ read_user_row ();
868
+
869
+ if (restart_after_program )
870
+ jump_application ();
871
+
872
+ goto exitProgram ;
873
+ }
874
+
754
875
//Load applet
755
876
FILE * fIn ;
756
877
char appletfname [128 ] = "" ;
757
878
strlower (mcu -> name );
758
879
759
880
//sprintf(appletfname, "applet-flash-%s.bin", mcu->name);
760
881
sprintf (appletfname , "applet-mdflash.bin" ); //make filename non-dependent upon mcu->name
761
-
882
+
762
883
printf ("Applet file: %s\n" , appletfname );
763
884
764
885
fIn = fopen (appletfname , "rb" );
0 commit comments