cmd: add missing usage var
[fw/openocd] / src / flash / nor / at91sam3.c
index f895935fd9b756fd70ec75cea6430a761b6123d8..21bfa39c3492a2a52a9194cbcd322a697679febd 100644 (file)
@@ -73,6 +73,9 @@
 // at91sam3s series (has always one flash bank)
 #define FLASH_BANK_BASE_S   0x00400000
 
+// at91sam3n series (has always one flash bank)
+#define FLASH_BANK_BASE_N   0x00400000
+
 #define        AT91C_EFC_FCMD_GETD                 (0x0) // (EFC) Get Flash Descriptor
 #define        AT91C_EFC_FCMD_WP                   (0x1) // (EFC) Write Page
 #define        AT91C_EFC_FCMD_WPL                  (0x2) // (EFC) Write Page and Lock
@@ -164,6 +167,15 @@ struct sam3_cfg {
        uint32_t PMC_FSPR;
 };
 
+/*
+ * The AT91SAM3N data sheet 04-Oct-2010, AT91SAM3U data sheet 22-Aug-2011
+ * and AT91SAM3S data sheet 09-Feb-2011 state that for flash writes
+ * the flash wait state (FWS) should be set to 6. It seems like that the
+ * cause of the problem is not the flash itself, but the flash write
+ * buffer. Ie the wait states have to be set before writing into the
+ * buffer.
+ * Tested and confirmed with SAM3N and SAM3U
+ */
 
 struct sam3_bank_private {
        int probed;
@@ -180,6 +192,7 @@ struct sam3_bank_private {
        unsigned bank_number;
        uint32_t controller_address;
        uint32_t base_address;
+       uint32_t flash_wait_states;
        bool present;
        unsigned size_bytes;
        unsigned nsectors;
@@ -295,6 +308,7 @@ static const struct sam3_chip_details all_sam3_details[] = {
                        .bank_number = 0,
                        .base_address = FLASH_BANK0_BASE_U,
                        .controller_address = 0x400e0800,
+                       .flash_wait_states = 6, /* workaround silicon bug */
                        .present = 1,
                        .size_bytes = 128 * 1024,
                        .nsectors   = 16,
@@ -310,6 +324,7 @@ static const struct sam3_chip_details all_sam3_details[] = {
                        .bank_number = 1,
                        .base_address = FLASH_BANK1_BASE_U,
                        .controller_address = 0x400e0a00,
+                       .flash_wait_states = 6, /* workaround silicon bug */
                        .present = 1,
                        .size_bytes = 128 * 1024,
                        .nsectors   = 16,
@@ -344,6 +359,7 @@ static const struct sam3_chip_details all_sam3_details[] = {
                        .bank_number = 0,
                        .base_address = FLASH_BANK0_BASE_U,
                        .controller_address = 0x400e0800,
+                       .flash_wait_states = 6, /* workaround silicon bug */
                        .present = 1,
                        .size_bytes = 128 * 1024,
                        .nsectors   = 16,
@@ -385,6 +401,7 @@ static const struct sam3_chip_details all_sam3_details[] = {
                        .bank_number = 0,
                        .base_address = FLASH_BANK0_BASE_U,
                        .controller_address = 0x400e0800,
+                       .flash_wait_states = 6, /* workaround silicon bug */
                        .present = 1,
                        .size_bytes =  64 * 1024,
                        .nsectors   =  8,
@@ -433,6 +450,7 @@ static const struct sam3_chip_details all_sam3_details[] = {
                        .bank_number = 0,
                        .base_address = FLASH_BANK0_BASE_U,
                        .controller_address = 0x400e0800,
+                       .flash_wait_states = 6, /* workaround silicon bug */
                        .present = 1,
                        .size_bytes = 128 * 1024,
                        .nsectors   = 16,
@@ -447,6 +465,7 @@ static const struct sam3_chip_details all_sam3_details[] = {
                        .bank_number = 1,
                        .base_address = FLASH_BANK1_BASE_U,
                        .controller_address = 0x400e0a00,
+                       .flash_wait_states = 6, /* workaround silicon bug */
                        .present = 1,
                        .size_bytes = 128 * 1024,
                        .nsectors   = 16,
@@ -481,6 +500,7 @@ static const struct sam3_chip_details all_sam3_details[] = {
                        .bank_number = 0,
                        .base_address = FLASH_BANK0_BASE_U,
                        .controller_address = 0x400e0800,
+                       .flash_wait_states = 6, /* workaround silicon bug */
                        .present = 1,
                        .size_bytes = 128 * 1024,
                        .nsectors   = 16,
@@ -522,6 +542,7 @@ static const struct sam3_chip_details all_sam3_details[] = {
                        .bank_number = 0,
                        .base_address = FLASH_BANK0_BASE_U,
                        .controller_address = 0x400e0800,
+                       .flash_wait_states = 6, /* workaround silicon bug */
                        .present = 1,
                        .size_bytes =  64 * 1024,
                        .nsectors   =  8,
@@ -558,8 +579,8 @@ static const struct sam3_chip_details all_sam3_details[] = {
                        .pBank  = NULL,
                        .bank_number = 0,
                        .base_address = FLASH_BANK_BASE_S,
-
                        .controller_address = 0x400e0a00,
+                       .flash_wait_states = 6, /* workaround silicon bug */
                        .present = 1,
                        .size_bytes =  256 * 1024,
                        .nsectors   =  32,
@@ -591,8 +612,8 @@ static const struct sam3_chip_details all_sam3_details[] = {
                        .pBank  = NULL,
                        .bank_number = 0,
                        .base_address = FLASH_BANK_BASE_S,
-
                        .controller_address = 0x400e0a00,
+                       .flash_wait_states = 6, /* workaround silicon bug */
                        .present = 1,
                        .size_bytes =  256 * 1024,
                        .nsectors   =  32,
@@ -623,8 +644,8 @@ static const struct sam3_chip_details all_sam3_details[] = {
                        .pBank  = NULL,
                        .bank_number = 0,
                        .base_address = FLASH_BANK_BASE_S,
-
                        .controller_address = 0x400e0a00,
+                       .flash_wait_states = 6, /* workaround silicon bug */
                        .present = 1,
                        .size_bytes =  256 * 1024,
                        .nsectors   =  32,
@@ -655,8 +676,8 @@ static const struct sam3_chip_details all_sam3_details[] = {
                        .pBank  = NULL,
                        .bank_number = 0,
                        .base_address = FLASH_BANK_BASE_S,
-
                        .controller_address = 0x400e0a00,
+                       .flash_wait_states = 6, /* workaround silicon bug */
                        .present = 1,
                        .size_bytes =  128 * 1024,
                        .nsectors   =  16,
@@ -687,8 +708,8 @@ static const struct sam3_chip_details all_sam3_details[] = {
                        .pBank  = NULL,
                        .bank_number = 0,
                        .base_address = FLASH_BANK_BASE_S,
-
                        .controller_address = 0x400e0a00,
+                       .flash_wait_states = 6, /* workaround silicon bug */
                        .present = 1,
                        .size_bytes =  128 * 1024,
                        .nsectors   =  16,
@@ -719,8 +740,8 @@ static const struct sam3_chip_details all_sam3_details[] = {
                        .pBank  = NULL,
                        .bank_number = 0,
                        .base_address = FLASH_BANK_BASE_S,
-
                        .controller_address = 0x400e0a00,
+                       .flash_wait_states = 6, /* workaround silicon bug */
                        .present = 1,
                        .size_bytes =  128 * 1024,
                        .nsectors   =  16,
@@ -751,8 +772,8 @@ static const struct sam3_chip_details all_sam3_details[] = {
                        .pBank  = NULL,
                        .bank_number = 0,
                        .base_address = FLASH_BANK_BASE_S,
-
                        .controller_address = 0x400e0a00,
+                       .flash_wait_states = 6, /* workaround silicon bug */
                        .present = 1,
                        .size_bytes =  64 * 1024,
                        .nsectors   =  8,
@@ -783,8 +804,8 @@ static const struct sam3_chip_details all_sam3_details[] = {
                        .pBank  = NULL,
                        .bank_number = 0,
                        .base_address = FLASH_BANK_BASE_S,
-
                        .controller_address = 0x400e0a00,
+                       .flash_wait_states = 6, /* workaround silicon bug */
                        .present = 1,
                        .size_bytes =  64 * 1024,
                        .nsectors   =  8,
@@ -815,8 +836,8 @@ static const struct sam3_chip_details all_sam3_details[] = {
                        .pBank  = NULL,
                        .bank_number = 0,
                        .base_address = FLASH_BANK_BASE_S,
-
                        .controller_address = 0x400e0a00,
+                       .flash_wait_states = 6, /* workaround silicon bug */
                        .present = 1,
                        .size_bytes =  64 * 1024,
                        .nsectors   =  8,
@@ -832,6 +853,449 @@ static const struct sam3_chip_details all_sam3_details[] = {
                  },
                },
        },
+
+       // Start at91sam3n* series
+       {
+               .chipid_cidr    = 0x29540960,
+               .name           = "at91sam3n4c",
+               .total_flash_size     = 256 * 1024,
+               .total_sram_size      = 24 * 1024,
+               .n_gpnvms       = 3,
+               .n_banks        = 1,
+
+               // System boots at address 0x0
+               // gpnvm[1] = selects boot code
+               //     if gpnvm[1] == 0
+               //         boot is via "SAMBA" (rom)
+               //     else
+               //         boot is via FLASH
+               //         Selection is via gpnvm[2]
+               //     endif
+               //
+               // NOTE: banks 0 & 1 switch places
+               //     if gpnvm[2] == 0
+               //         Bank0 is the boot rom
+               //      else
+               //         Bank1 is the boot rom
+               //      endif
+//             .bank[0] = {
+               {
+                 {
+                       .probed = 0,
+                       .pChip  = NULL,
+                       .pBank  = NULL,
+                       .bank_number = 0,
+                       .base_address = FLASH_BANK_BASE_N,
+                       .controller_address = 0x400e0A00,
+                       .flash_wait_states = 6, /* workaround silicon bug */
+                       .present = 1,
+                       .size_bytes = 256 * 1024,
+                       .nsectors   = 16,
+                       .sector_size = 16384,
+                       .page_size   = 256,
+                 },
+
+//             .bank[1] = {
+                 {
+                       .present = 0,
+                       .probed = 0,
+                       .bank_number = 1,
+                 },
+               },
+       },
+
+       {
+               .chipid_cidr    = 0x29440960,
+               .name           = "at91sam3n4b",
+               .total_flash_size     = 256 * 1024,
+               .total_sram_size      = 24 * 1024,
+               .n_gpnvms       = 3,
+               .n_banks        = 1,
+
+               // System boots at address 0x0
+               // gpnvm[1] = selects boot code
+               //     if gpnvm[1] == 0
+               //         boot is via "SAMBA" (rom)
+               //     else
+               //         boot is via FLASH
+               //         Selection is via gpnvm[2]
+               //     endif
+               //
+               // NOTE: banks 0 & 1 switch places
+               //     if gpnvm[2] == 0
+               //         Bank0 is the boot rom
+               //      else
+               //         Bank1 is the boot rom
+               //      endif
+//             .bank[0] = {
+               {
+                 {
+                       .probed = 0,
+                       .pChip  = NULL,
+                       .pBank  = NULL,
+                       .bank_number = 0,
+                       .base_address = FLASH_BANK_BASE_N,
+                       .controller_address = 0x400e0A00,
+                       .flash_wait_states = 6, /* workaround silicon bug */
+                       .present = 1,
+                       .size_bytes = 256 * 1024,
+                       .nsectors   = 16,
+                       .sector_size = 16384,
+                       .page_size   = 256,
+                 },
+
+//             .bank[1] = {
+                 {
+                       .present = 0,
+                       .probed = 0,
+                       .bank_number = 1,
+                 },
+               },
+       },
+
+       {
+               .chipid_cidr    = 0x29340960,
+               .name           = "at91sam3n4a",
+               .total_flash_size     = 256 * 1024,
+               .total_sram_size      = 24 * 1024,
+               .n_gpnvms       = 3,
+               .n_banks        = 1,
+
+               // System boots at address 0x0
+               // gpnvm[1] = selects boot code
+               //     if gpnvm[1] == 0
+               //         boot is via "SAMBA" (rom)
+               //     else
+               //         boot is via FLASH
+               //         Selection is via gpnvm[2]
+               //     endif
+               //
+               // NOTE: banks 0 & 1 switch places
+               //     if gpnvm[2] == 0
+               //         Bank0 is the boot rom
+               //      else
+               //         Bank1 is the boot rom
+               //      endif
+//             .bank[0] = {
+               {
+                 {
+                       .probed = 0,
+                       .pChip  = NULL,
+                       .pBank  = NULL,
+                       .bank_number = 0,
+                       .base_address = FLASH_BANK_BASE_N,
+                       .controller_address = 0x400e0A00,
+                       .flash_wait_states = 6, /* workaround silicon bug */
+                       .present = 1,
+                       .size_bytes = 256 * 1024,
+                       .nsectors   = 16,
+                       .sector_size = 16384,
+                       .page_size   = 256,
+                 },
+
+//             .bank[1] = {
+                 {
+                       .present = 0,
+                       .probed = 0,
+                       .bank_number = 1,
+                 },
+               },
+       },
+
+       {
+               .chipid_cidr    = 0x29590760,
+               .name           = "at91sam3n2c",
+               .total_flash_size     = 128 * 1024,
+               .total_sram_size      = 16 * 1024,
+               .n_gpnvms       = 3,
+               .n_banks        = 1,
+
+               // System boots at address 0x0
+               // gpnvm[1] = selects boot code
+               //     if gpnvm[1] == 0
+               //         boot is via "SAMBA" (rom)
+               //     else
+               //         boot is via FLASH
+               //         Selection is via gpnvm[2]
+               //     endif
+               //
+               // NOTE: banks 0 & 1 switch places
+               //     if gpnvm[2] == 0
+               //         Bank0 is the boot rom
+               //      else
+               //         Bank1 is the boot rom
+               //      endif
+//             .bank[0] = {
+               {
+                 {
+                       .probed = 0,
+                       .pChip  = NULL,
+                       .pBank  = NULL,
+                       .bank_number = 0,
+                       .base_address = FLASH_BANK_BASE_N,
+                       .controller_address = 0x400e0A00,
+                       .flash_wait_states = 6, /* workaround silicon bug */
+                       .present = 1,
+                       .size_bytes = 128 * 1024,
+                       .nsectors   = 8,
+                       .sector_size = 16384,
+                       .page_size   = 256,
+                 },
+
+//             .bank[1] = {
+                 {
+                       .present = 0,
+                       .probed = 0,
+                       .bank_number = 1,
+                 },
+               },
+       },
+
+       {
+               .chipid_cidr    = 0x29490760,
+               .name           = "at91sam3n2b",
+               .total_flash_size     = 128 * 1024,
+               .total_sram_size      = 16 * 1024,
+               .n_gpnvms       = 3,
+               .n_banks        = 1,
+
+               // System boots at address 0x0
+               // gpnvm[1] = selects boot code
+               //     if gpnvm[1] == 0
+               //         boot is via "SAMBA" (rom)
+               //     else
+               //         boot is via FLASH
+               //         Selection is via gpnvm[2]
+               //     endif
+               //
+               // NOTE: banks 0 & 1 switch places
+               //     if gpnvm[2] == 0
+               //         Bank0 is the boot rom
+               //      else
+               //         Bank1 is the boot rom
+               //      endif
+//             .bank[0] = {
+               {
+                 {
+                       .probed = 0,
+                       .pChip  = NULL,
+                       .pBank  = NULL,
+                       .bank_number = 0,
+                       .base_address = FLASH_BANK_BASE_N,
+                       .controller_address = 0x400e0A00,
+                       .flash_wait_states = 6, /* workaround silicon bug */
+                       .present = 1,
+                       .size_bytes = 128 * 1024,
+                       .nsectors   = 8,
+                       .sector_size = 16384,
+                       .page_size   = 256,
+                 },
+
+//             .bank[1] = {
+                 {
+                       .present = 0,
+                       .probed = 0,
+                       .bank_number = 1,
+                 },
+               },
+       },
+
+       {
+               .chipid_cidr    = 0x29390760,
+               .name           = "at91sam3n2a",
+               .total_flash_size     = 128 * 1024,
+               .total_sram_size      = 16 * 1024,
+               .n_gpnvms       = 3,
+               .n_banks        = 1,
+
+               // System boots at address 0x0
+               // gpnvm[1] = selects boot code
+               //     if gpnvm[1] == 0
+               //         boot is via "SAMBA" (rom)
+               //     else
+               //         boot is via FLASH
+               //         Selection is via gpnvm[2]
+               //     endif
+               //
+               // NOTE: banks 0 & 1 switch places
+               //     if gpnvm[2] == 0
+               //         Bank0 is the boot rom
+               //      else
+               //         Bank1 is the boot rom
+               //      endif
+//             .bank[0] = {
+               {
+                 {
+                       .probed = 0,
+                       .pChip  = NULL,
+                       .pBank  = NULL,
+                       .bank_number = 0,
+                       .base_address = FLASH_BANK_BASE_N,
+                       .controller_address = 0x400e0A00,
+                       .flash_wait_states = 6, /* workaround silicon bug */
+                       .present = 1,
+                       .size_bytes = 128 * 1024,
+                       .nsectors   = 8,
+                       .sector_size = 16384,
+                       .page_size   = 256,
+                 },
+
+//             .bank[1] = {
+                 {
+                       .present = 0,
+                       .probed = 0,
+                       .bank_number = 1,
+                 },
+               },
+       },
+
+       {
+               .chipid_cidr    = 0x29580560,
+               .name           = "at91sam3n1c",
+               .total_flash_size     = 64 * 1024,
+               .total_sram_size      = 8 * 1024,
+               .n_gpnvms       = 3,
+               .n_banks        = 1,
+
+               // System boots at address 0x0
+               // gpnvm[1] = selects boot code
+               //     if gpnvm[1] == 0
+               //         boot is via "SAMBA" (rom)
+               //     else
+               //         boot is via FLASH
+               //         Selection is via gpnvm[2]
+               //     endif
+               //
+               // NOTE: banks 0 & 1 switch places
+               //     if gpnvm[2] == 0
+               //         Bank0 is the boot rom
+               //      else
+               //         Bank1 is the boot rom
+               //      endif
+//             .bank[0] = {
+               {
+                 {
+                       .probed = 0,
+                       .pChip  = NULL,
+                       .pBank  = NULL,
+                       .bank_number = 0,
+                       .base_address = FLASH_BANK_BASE_N,
+                       .controller_address = 0x400e0A00,
+                       .flash_wait_states = 6, /* workaround silicon bug */
+                       .present = 1,
+                       .size_bytes = 64 * 1024,
+                       .nsectors   = 4,
+                       .sector_size = 16384,
+                       .page_size   = 256,
+                 },
+
+//             .bank[1] = {
+                 {
+                       .present = 0,
+                       .probed = 0,
+                       .bank_number = 1,
+                 },
+               },
+       },
+
+       {
+               .chipid_cidr    = 0x29480560,
+               .name           = "at91sam3n1b",
+               .total_flash_size     = 64 * 1024,
+               .total_sram_size      = 8 * 1024,
+               .n_gpnvms       = 3,
+               .n_banks        = 1,
+
+               // System boots at address 0x0
+               // gpnvm[1] = selects boot code
+               //     if gpnvm[1] == 0
+               //         boot is via "SAMBA" (rom)
+               //     else
+               //         boot is via FLASH
+               //         Selection is via gpnvm[2]
+               //     endif
+               //
+               // NOTE: banks 0 & 1 switch places
+               //     if gpnvm[2] == 0
+               //         Bank0 is the boot rom
+               //      else
+               //         Bank1 is the boot rom
+               //      endif
+//             .bank[0] = {
+               {
+                 {
+                       .probed = 0,
+                       .pChip  = NULL,
+                       .pBank  = NULL,
+                       .bank_number = 0,
+                       .base_address = FLASH_BANK_BASE_N,
+                       .controller_address = 0x400e0A00,
+                       .flash_wait_states = 6, /* workaround silicon bug */
+                       .present = 1,
+                       .size_bytes = 64 * 1024,
+                       .nsectors   = 4,
+                       .sector_size = 16384,
+                       .page_size   = 256,
+                 },
+
+//             .bank[1] = {
+                 {
+                       .present = 0,
+                       .probed = 0,
+                       .bank_number = 1,
+                 },
+               },
+       },
+
+       {
+               .chipid_cidr    = 0x29380560,
+               .name           = "at91sam3n1a",
+               .total_flash_size     = 64 * 1024,
+               .total_sram_size      = 8 * 1024,
+               .n_gpnvms       = 3,
+               .n_banks        = 1,
+
+               // System boots at address 0x0
+               // gpnvm[1] = selects boot code
+               //     if gpnvm[1] == 0
+               //         boot is via "SAMBA" (rom)
+               //     else
+               //         boot is via FLASH
+               //         Selection is via gpnvm[2]
+               //     endif
+               //
+               // NOTE: banks 0 & 1 switch places
+               //     if gpnvm[2] == 0
+               //         Bank0 is the boot rom
+               //      else
+               //         Bank1 is the boot rom
+               //      endif
+//             .bank[0] = {
+               {
+                 {
+                       .probed = 0,
+                       .pChip  = NULL,
+                       .pBank  = NULL,
+                       .bank_number = 0,
+                       .base_address = FLASH_BANK_BASE_N,
+                       .controller_address = 0x400e0A00,
+                       .flash_wait_states = 6, /* workaround silicon bug */
+                       .present = 1,
+                       .size_bytes = 64 * 1024,
+                       .nsectors   = 4,
+                       .sector_size = 16384,
+                       .page_size   = 256,
+                 },
+
+//             .bank[1] = {
+                 {
+                       .present = 0,
+                       .probed = 0,
+                       .bank_number = 1,
+                 },
+               },
+       },
+
        // terminate
        {
                .chipid_cidr    = 0,
@@ -1954,11 +2418,13 @@ FLASH_BANK_COMMAND_HANDLER(sam3_flash_bank_command)
        switch (bank->base) {
        default:
                LOG_ERROR("Address 0x%08x invalid bank address (try 0x%08x or 0x%08x \
-                       [at91sam3u series] or 0x%08x [at91sam3s series])",
+                       [at91sam3u series] or 0x%08x [at91sam3s series] or \
+                       0x%08x [at91sam3n series])",
                                  ((unsigned int)(bank->base)),
                                  ((unsigned int)(FLASH_BANK0_BASE_U)),
                                  ((unsigned int)(FLASH_BANK1_BASE_U)),
-                                 ((unsigned int)(FLASH_BANK_BASE_S)));
+                                 ((unsigned int)(FLASH_BANK_BASE_S)),
+                                 ((unsigned int)(FLASH_BANK_BASE_N)));
                return ERROR_FAIL;
                break;
 
@@ -1974,8 +2440,9 @@ FLASH_BANK_COMMAND_HANDLER(sam3_flash_bank_command)
                bank->bank_number = 1;
                pChip->details.bank[1].pChip = pChip;
                pChip->details.bank[1].pBank = bank;
+               break;
 
-       // at91sam3s series
+       /* at91sam3s and at91sam3n series */
        case FLASH_BANK_BASE_S:
                bank->driver_priv = &(pChip->details.bank[0]);
                bank->bank_number = 0;
@@ -1999,7 +2466,8 @@ sam3_GetDetails(struct sam3_bank_private *pPrivate)
        LOG_DEBUG("Begin");
        pDetails = all_sam3_details;
        while (pDetails->name) {
-               if (pDetails->chipid_cidr == pPrivate->pChip->cfg.CHIPID_CIDR) {
+               // Compare cidr without version bits
+               if (pDetails->chipid_cidr == (pPrivate->pChip->cfg.CHIPID_CIDR & 0xFFFFFFE0)) {
                        break;
                } else {
                        pDetails++;
@@ -2090,8 +2558,8 @@ _sam3_probe(struct flash_bank *bank, int noise)
 
        // update the flash bank size
        for (x = 0 ; x < SAM3_MAX_FLASH_BANKS ; x++) {
-               if (bank->base == pPrivate->pChip->details.bank[0].base_address) {
-                       bank->size =  pPrivate->pChip->details.bank[0].size_bytes;
+               if (bank->base == pPrivate->pChip->details.bank[x].base_address) {
+                       bank->size =  pPrivate->pChip->details.bank[x].size_bytes;
                        break;
                }
        }
@@ -2332,11 +2800,28 @@ sam3_page_write(struct sam3_bank_private *pPrivate, unsigned pagenum, uint8_t *b
 {
        uint32_t adr;
        uint32_t status;
+       uint32_t fmr; /* EEFC Flash Mode Register */
        int r;
 
        adr = pagenum * pPrivate->page_size;
        adr += (adr + pPrivate->base_address);
 
+       /* Get flash mode register value */
+       r = target_read_u32(pPrivate->pChip->target, pPrivate->controller_address, &fmr);
+       if (r != ERROR_OK)
+               LOG_DEBUG("Error Read failed: read flash mode register");
+
+       /* Clear flash wait state field */
+       fmr &= 0xfffff0ff;
+
+       /* set FWS (flash wait states) field in the FMR (flash mode register) */
+       fmr |= (pPrivate->flash_wait_states << 8);
+
+       LOG_DEBUG("Flash Mode: 0x%08x", ((unsigned int)(fmr)));
+       r = target_write_u32(pPrivate->pBank->target, pPrivate->controller_address, fmr);
+       if (r != ERROR_OK)
+               LOG_DEBUG("Error Write failed: set flash mode register");
+
        LOG_DEBUG("Wr Page %u @ phys address: 0x%08x", pagenum, (unsigned int)(adr));
        r = target_write_memory(pPrivate->pChip->target,
                                                         adr,
@@ -2487,6 +2972,10 @@ sam3_write(struct flash_bank *bank,
                page_cur++;
        }
 
+       /* By checking that offset is correct here, we also
+       fix a clang warning */
+       assert(offset == pPrivate->page_size);
+
        // intermediate large pages
        // also - the final *terminal*
        // if that terminal page is a full page
@@ -2519,7 +3008,6 @@ sam3_write(struct flash_bank *bank,
                        goto done;
                }
                buffer += count;
-               count  -= count;
        }
        LOG_DEBUG("Done!");
        r = ERROR_OK;
@@ -2533,15 +3021,13 @@ sam3_write(struct flash_bank *bank,
 COMMAND_HANDLER(sam3_handle_info_command)
 {
        struct sam3_chip *pChip;
-       unsigned x;
-       int r;
-
        pChip = get_current_sam3(CMD_CTX);
        if (!pChip) {
                return ERROR_OK;
        }
 
-       r = 0;
+       unsigned x;
+       int r;
 
        // bank0 must exist before we can do anything
        if (pChip->details.bank[0].pBank == NULL) {
@@ -2626,14 +3112,11 @@ COMMAND_HANDLER(sam3_handle_gpnvm_command)
                }
        }
 
-
        switch (CMD_ARGC) {
        default:
-               command_print(CMD_CTX,"Too many parameters\n");
                return ERROR_COMMAND_SYNTAX_ERROR;
                break;
        case 0:
-               who = -1;
                goto showall;
                break;
        case 1:
@@ -2684,7 +3167,7 @@ showall:
                           (0 == strcmp("clear", CMD_ARGV[0]))) { // quietly accept both
                r = FLASHD_ClrGPNVM(&(pChip->details.bank[0]), who);
        } else {
-               command_print(CMD_CTX, "Unkown command: %s", CMD_ARGV[0]);
+               command_print(CMD_CTX, "Unknown command: %s", CMD_ARGV[0]);
                r = ERROR_COMMAND_SYNTAX_ERROR;
        }
        return r;
@@ -2761,6 +3244,7 @@ static const struct command_registration at91sam3_command_handlers[] = {
                .name = "at91sam3",
                .mode = COMMAND_ANY,
                .help = "at91sam3 flash command group",
+               .usage = "",
                .chain = at91sam3_exec_command_handlers,
        },
        COMMAND_REGISTRATION_DONE