X-Git-Url: https://review.openocd.org/gitweb?a=blobdiff_plain;f=src%2Fflash%2Fnor%2Fat91sam4.c;h=621754c90ec98d1e329c2feca619b002fd9f1785;hb=0a13ca1a8a83119a4e1ffba13a6a8d1977591bc5;hp=1cfe28f2160daac60cc4426dec5574c6be8f6c97;hpb=443197aff0e4b3e2ba01635f2862aca90ac26349;p=openocd.git
diff --git a/src/flash/nor/at91sam4.c b/src/flash/nor/at91sam4.c
index 1cfe28f216..621754c90e 100644
--- a/src/flash/nor/at91sam4.c
+++ b/src/flash/nor/at91sam4.c
@@ -9,19 +9,17 @@
* (at91sam3x* & at91sam4 support)* *
* *
* This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General public License as published by *
+ * it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS for A PARTICULAR PURPOSE. See the *
- * GNU General public License for more details. *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
* *
- * You should have received a copy of the GNU General public License *
- * along with this program; if not, write to the *
- * Free Software Foundation, Inc., *
- * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program. If not, see . *
****************************************************************************/
/* Some of the the lower level code was based on code supplied by
@@ -67,8 +65,20 @@
#define REG_NAME_WIDTH (12)
-/* at91sam4s series (has always one flash bank)*/
+/* at91sam4s/at91sam4e/at91sam4c series (has always one flash bank)*/
#define FLASH_BANK_BASE_S 0x00400000
+#define FLASH_BANK_BASE_C 0x01000000
+
+/* at91sam4sd series (two one flash banks), first bank address */
+#define FLASH_BANK0_BASE_SD FLASH_BANK_BASE_S
+/* at91sam4sd16x, second bank address */
+#define FLASH_BANK1_BASE_1024K_SD (FLASH_BANK0_BASE_SD+(1024*1024/2))
+/* at91sam4sd32x, second bank address */
+#define FLASH_BANK1_BASE_2048K_SD (FLASH_BANK0_BASE_SD+(2048*1024/2))
+
+/* at91sam4c32x, first and second bank address */
+#define FLASH_BANK0_BASE_C32 FLASH_BANK_BASE_C
+#define FLASH_BANK1_BASE_C32 (FLASH_BANK_BASE_C+(2048*1024/2))
#define AT91C_EFC_FCMD_GETD (0x0) /* (EFC) Get Flash Descriptor */
#define AT91C_EFC_FCMD_WP (0x1) /* (EFC) Write Page */
@@ -93,7 +103,7 @@
#define offset_EFC_FSR 8
#define offset_EFC_FRR 12
-extern struct flash_driver at91sam4_flash;
+extern const struct flash_driver at91sam4_flash;
static float _tomhz(uint32_t freq_hz)
{
@@ -218,14 +228,14 @@ struct sam4_reg_list {
static struct sam4_chip *all_sam4_chips;
-static struct sam4_chip *get_current_sam4(struct command_context *cmd_ctx)
+static struct sam4_chip *get_current_sam4(struct command_invocation *cmd)
{
struct target *t;
static struct sam4_chip *p;
- t = get_current_target(cmd_ctx);
+ t = get_current_target(cmd->ctx);
if (!t) {
- command_print(cmd_ctx, "No current target?");
+ command_print(cmd, "No current target?");
return NULL;
}
@@ -233,7 +243,7 @@ static struct sam4_chip *get_current_sam4(struct command_context *cmd_ctx)
if (!p) {
/* this should not happen */
/* the command is not registered until the chip is created? */
- command_print(cmd_ctx, "No SAM4 chips exist?");
+ command_print(cmd, "No SAM4 chips exist?");
return NULL;
}
@@ -242,7 +252,7 @@ static struct sam4_chip *get_current_sam4(struct command_context *cmd_ctx)
return p;
p = p->next;
}
- command_print(cmd_ctx, "Cannot find SAM4 chip?");
+ command_print(cmd, "Cannot find SAM4 chip?");
return NULL;
}
@@ -251,14 +261,598 @@ static struct sam4_chip *get_current_sam4(struct command_context *cmd_ctx)
/*For the best results, nsectors are thus set to the amount of lock regions, and the sector_size*/
/*set to the lock region size. Page erases are used to erase 8KB sections when programming*/
-/* these are used to *initialize* the "pChip->details" structure. */
-static const struct sam4_chip_details all_sam4_details[] = {
- /* Start at91sam4s* series */
- /*atsam4s16c - LQFP100/BGA100*/
+/* these are used to *initialize* the "pChip->details" structure. */
+static const struct sam4_chip_details all_sam4_details[] = {
+ /* Start at91sam4c* series */
+ /* at91sam4c32e - LQFP144 */
+ {
+ .chipid_cidr = 0xA66D0EE0,
+ .name = "at91sam4c32e",
+ .total_flash_size = 2024 * 1024,
+ .total_sram_size = 256 * 1024,
+ .n_gpnvms = 3,
+ .n_banks = 2,
+/* .bank[0] = { */
+ {
+ {
+ .probed = 0,
+ .pChip = NULL,
+ .pBank = NULL,
+ .bank_number = 0,
+ .base_address = FLASH_BANK0_BASE_C32,
+ .controller_address = 0x400e0a00,
+ .flash_wait_states = 5,
+ .present = 1,
+ .size_bytes = 1024 * 1024,
+ .nsectors = 128,
+ .sector_size = 8192,
+ .page_size = 512,
+ },
+/* .bank[1] = { */
+ {
+ .probed = 0,
+ .pChip = NULL,
+ .pBank = NULL,
+ .bank_number = 1,
+ .base_address = FLASH_BANK1_BASE_C32,
+ .controller_address = 0x400e0c00,
+ .flash_wait_states = 5,
+ .present = 1,
+ .size_bytes = 1024 * 1024,
+ .nsectors = 128,
+ .sector_size = 8192,
+ .page_size = 512,
+ },
+ },
+ },
+ /* at91sam4c32c - LQFP100 */
+ {
+ .chipid_cidr = 0xA64D0EE0,
+ .name = "at91sam4c32c",
+ .total_flash_size = 2024 * 1024,
+ .total_sram_size = 256 * 1024,
+ .n_gpnvms = 3,
+ .n_banks = 2,
+/* .bank[0] = { */
+ {
+ {
+ .probed = 0,
+ .pChip = NULL,
+ .pBank = NULL,
+ .bank_number = 0,
+ .base_address = FLASH_BANK0_BASE_C32,
+ .controller_address = 0x400e0a00,
+ .flash_wait_states = 5,
+ .present = 1,
+ .size_bytes = 1024 * 1024,
+ .nsectors = 128,
+ .sector_size = 8192,
+ .page_size = 512,
+ },
+/* .bank[1] = { */
+ {
+ .probed = 0,
+ .pChip = NULL,
+ .pBank = NULL,
+ .bank_number = 1,
+ .base_address = FLASH_BANK1_BASE_C32,
+ .controller_address = 0x400e0c00,
+ .flash_wait_states = 5,
+ .present = 1,
+ .size_bytes = 1024 * 1024,
+ .nsectors = 128,
+ .sector_size = 8192,
+ .page_size = 512,
+ },
+ },
+ },
+ /* at91sam4c16c - LQFP100 */
+ {
+ .chipid_cidr = 0xA64C0CE0,
+ .name = "at91sam4c16c",
+ .total_flash_size = 1024 * 1024,
+ .total_sram_size = 128 * 1024,
+ .n_gpnvms = 2,
+ .n_banks = 1,
+ {
+/* .bank[0] = {*/
+ {
+ .probed = 0,
+ .pChip = NULL,
+ .pBank = NULL,
+ .bank_number = 0,
+ .base_address = FLASH_BANK_BASE_C,
+ .controller_address = 0x400e0a00,
+ .flash_wait_states = 5,
+ .present = 1,
+ .size_bytes = 1024 * 1024,
+ .nsectors = 128,
+ .sector_size = 8192,
+ .page_size = 512,
+ },
+/* .bank[1] = {*/
+ {
+ .present = 0,
+ .probed = 0,
+ .bank_number = 1,
+
+ },
+ },
+ },
+ /* at91sam4c8c - LQFP100 */
+ {
+ .chipid_cidr = 0xA64C0AE0,
+ .name = "at91sam4c8c",
+ .total_flash_size = 512 * 1024,
+ .total_sram_size = 128 * 1024,
+ .n_gpnvms = 2,
+ .n_banks = 1,
+ {
+/* .bank[0] = {*/
+ {
+ .probed = 0,
+ .pChip = NULL,
+ .pBank = NULL,
+ .bank_number = 0,
+ .base_address = FLASH_BANK_BASE_C,
+ .controller_address = 0x400e0a00,
+ .flash_wait_states = 5,
+ .present = 1,
+ .size_bytes = 512 * 1024,
+ .nsectors = 64,
+ .sector_size = 8192,
+ .page_size = 512,
+ },
+/* .bank[1] = {*/
+ {
+ .present = 0,
+ .probed = 0,
+ .bank_number = 1,
+
+ },
+ },
+ },
+ /* at91sam4c4c (rev B) - LQFP100 */
+ {
+ .chipid_cidr = 0xA64C0CE5,
+ .name = "at91sam4c4c",
+ .total_flash_size = 256 * 1024,
+ .total_sram_size = 128 * 1024,
+ .n_gpnvms = 2,
+ .n_banks = 1,
+ {
+/* .bank[0] = {*/
+ {
+ .probed = 0,
+ .pChip = NULL,
+ .pBank = NULL,
+ .bank_number = 0,
+ .base_address = FLASH_BANK_BASE_C,
+ .controller_address = 0x400e0a00,
+ .flash_wait_states = 5,
+ .present = 1,
+ .size_bytes = 256 * 1024,
+ .nsectors = 32,
+ .sector_size = 8192,
+ .page_size = 512,
+ },
+/* .bank[1] = {*/
+ {
+ .present = 0,
+ .probed = 0,
+ .bank_number = 1,
+
+ },
+ },
+ },
+
+ /* Start at91sam4e* series */
+ /*atsam4e16e - LQFP144/LFBGA144*/
+ {
+ .chipid_cidr = 0xA3CC0CE0,
+ .name = "at91sam4e16e",
+ .total_flash_size = 1024 * 1024,
+ .total_sram_size = 128 * 1024,
+ .n_gpnvms = 2,
+ .n_banks = 1,
+ {
+/* .bank[0] = {*/
+ {
+ .probed = 0,
+ .pChip = NULL,
+ .pBank = NULL,
+ .bank_number = 0,
+ .base_address = FLASH_BANK_BASE_S,
+ .controller_address = 0x400e0a00,
+ .flash_wait_states = 5,
+ .present = 1,
+ .size_bytes = 1024 * 1024,
+ .nsectors = 128,
+ .sector_size = 8192,
+ .page_size = 512,
+ },
+/* .bank[1] = {*/
+ {
+ .present = 0,
+ .probed = 0,
+ .bank_number = 1,
+
+ },
+ },
+ },
+
+ /* Start at91sam4n* series */
+ /*atsam4n8a - LQFP48/QFN48*/
+ {
+ .chipid_cidr = 0x293B0AE0,
+ .name = "at91sam4n8a",
+ .total_flash_size = 512 * 1024,
+ .total_sram_size = 64 * 1024,
+ .n_gpnvms = 2,
+ .n_banks = 1,
+ {
+/* .bank[0] = {*/
+ {
+ .probed = 0,
+ .pChip = NULL,
+ .pBank = NULL,
+ .bank_number = 0,
+ .base_address = FLASH_BANK_BASE_S,
+ .controller_address = 0x400e0a00,
+ .flash_wait_states = 5,
+ .present = 1,
+ .size_bytes = 512 * 1024,
+ .nsectors = 64,
+ .sector_size = 8192,
+ .page_size = 512,
+ },
+/* .bank[1] = {*/
+ {
+ .present = 0,
+ .probed = 0,
+ .bank_number = 1,
+
+ },
+ },
+ },
+ /*atsam4n8b - LQFP64/QFN64*/
+ {
+ .chipid_cidr = 0x294B0AE0,
+ .name = "at91sam4n8b",
+ .total_flash_size = 512 * 1024,
+ .total_sram_size = 64 * 1024,
+ .n_gpnvms = 2,
+ .n_banks = 1,
+ {
+/* .bank[0] = {*/
+ {
+ .probed = 0,
+ .pChip = NULL,
+ .pBank = NULL,
+ .bank_number = 0,
+ .base_address = FLASH_BANK_BASE_S,
+ .controller_address = 0x400e0a00,
+ .flash_wait_states = 5,
+ .present = 1,
+ .size_bytes = 512 * 1024,
+ .nsectors = 64,
+ .sector_size = 8192,
+ .page_size = 512,
+ },
+/* .bank[1] = {*/
+ {
+ .present = 0,
+ .probed = 0,
+ .bank_number = 1,
+
+ },
+ },
+ },
+ /*atsam4n8c - LQFP100/TFBGA100/VFBGA100*/
+ {
+ .chipid_cidr = 0x295B0AE0,
+ .name = "at91sam4n8c",
+ .total_flash_size = 512 * 1024,
+ .total_sram_size = 64 * 1024,
+ .n_gpnvms = 2,
+ .n_banks = 1,
+ {
+/* .bank[0] = {*/
+ {
+ .probed = 0,
+ .pChip = NULL,
+ .pBank = NULL,
+ .bank_number = 0,
+ .base_address = FLASH_BANK_BASE_S,
+ .controller_address = 0x400e0a00,
+ .flash_wait_states = 5,
+ .present = 1,
+ .size_bytes = 512 * 1024,
+ .nsectors = 64,
+ .sector_size = 8192,
+ .page_size = 512,
+ },
+/* .bank[1] = {*/
+ {
+ .present = 0,
+ .probed = 0,
+ .bank_number = 1,
+
+ },
+ },
+ },
+ /*atsam4n16b - LQFP64/QFN64*/
+ {
+ .chipid_cidr = 0x29460CE0,
+ .name = "at91sam4n16b",
+ .total_flash_size = 1024 * 1024,
+ .total_sram_size = 80 * 1024,
+ .n_gpnvms = 2,
+ .n_banks = 1,
+ {
+/* .bank[0] = {*/
+ {
+ .probed = 0,
+ .pChip = NULL,
+ .pBank = NULL,
+ .bank_number = 0,
+ .base_address = FLASH_BANK_BASE_S,
+ .controller_address = 0x400e0a00,
+ .flash_wait_states = 5,
+ .present = 1,
+ .size_bytes = 1024 * 1024,
+ .nsectors = 128,
+ .sector_size = 8192,
+ .page_size = 512,
+ },
+/* .bank[1] = {*/
+ {
+ .present = 0,
+ .probed = 0,
+ .bank_number = 1,
+
+ },
+ },
+ },
+ /*atsam4n16c - LQFP100/TFBGA100/VFBGA100*/
+ {
+ .chipid_cidr = 0x29560CE0,
+ .name = "at91sam4n16c",
+ .total_flash_size = 1024 * 1024,
+ .total_sram_size = 80 * 1024,
+ .n_gpnvms = 2,
+ .n_banks = 1,
+ {
+/* .bank[0] = {*/
+ {
+ .probed = 0,
+ .pChip = NULL,
+ .pBank = NULL,
+ .bank_number = 0,
+ .base_address = FLASH_BANK_BASE_S,
+ .controller_address = 0x400e0a00,
+ .flash_wait_states = 5,
+ .present = 1,
+ .size_bytes = 1024 * 1024,
+ .nsectors = 128,
+ .sector_size = 8192,
+ .page_size = 512,
+ },
+/* .bank[1] = {*/
+ {
+ .present = 0,
+ .probed = 0,
+ .bank_number = 1,
+
+ },
+ },
+ },
+
+ /* Start at91sam4s* series */
+ /*atsam4s16c - LQFP100/BGA100*/
+ {
+ .chipid_cidr = 0x28AC0CE0,
+ .name = "at91sam4s16c",
+ .total_flash_size = 1024 * 1024,
+ .total_sram_size = 128 * 1024,
+ .n_gpnvms = 2,
+ .n_banks = 1,
+ {
+/* .bank[0] = {*/
+ {
+ .probed = 0,
+ .pChip = NULL,
+ .pBank = NULL,
+ .bank_number = 0,
+ .base_address = FLASH_BANK_BASE_S,
+ .controller_address = 0x400e0a00,
+ .flash_wait_states = 5,
+ .present = 1,
+ .size_bytes = 1024 * 1024,
+ .nsectors = 128,
+ .sector_size = 8192,
+ .page_size = 512,
+ },
+/* .bank[1] = {*/
+ {
+ .present = 0,
+ .probed = 0,
+ .bank_number = 1,
+
+ },
+ },
+ },
+ /*at91sam4sa16c - TFBGA100/VFBGA100/LQFP100*/
+ {
+ .chipid_cidr = 0x28a70ce0,
+ .name = "at91sam4sa16c",
+ .total_flash_size = 1024 * 1024,
+ .total_sram_size = 160 * 1024,
+ .n_gpnvms = 2,
+ .n_banks = 1,
+
+/* .bank[0] = { */
+ {
+ {
+ .probed = 0,
+ .pChip = NULL,
+ .pBank = NULL,
+ .bank_number = 0,
+ .base_address = FLASH_BANK_BASE_S,
+ .controller_address = 0x400e0a00,
+ .flash_wait_states = 5,
+ .present = 1,
+ .size_bytes = 1024 * 1024,
+ .nsectors = 128,
+ .sector_size = 8192,
+ .page_size = 512,
+ },
+/* .bank[1] = {*/
+ {
+ .present = 0,
+ .probed = 0,
+ .bank_number = 1,
+
+ },
+ },
+ },
+ /*atsam4s16b - LQFP64/QFN64/WLCSP64*/
+ {
+ .chipid_cidr = 0x289C0CE0,
+ .name = "at91sam4s16b",
+ .total_flash_size = 1024 * 1024,
+ .total_sram_size = 128 * 1024,
+ .n_gpnvms = 2,
+ .n_banks = 1,
+ {
+/* .bank[0] = {*/
+ {
+ .probed = 0,
+ .pChip = NULL,
+ .pBank = NULL,
+ .bank_number = 0,
+ .base_address = FLASH_BANK_BASE_S,
+ .controller_address = 0x400e0a00,
+ .flash_wait_states = 5,
+ .present = 1,
+ .size_bytes = 1024 * 1024,
+ .nsectors = 128,
+ .sector_size = 8192,
+ .page_size = 512,
+ },
+/* .bank[1] = {*/
+ {
+ .present = 0,
+ .probed = 0,
+ .bank_number = 1,
+
+ },
+ },
+ },
+ /*atsam4sa16b - LQFP64/QFN64*/
+ {
+ .chipid_cidr = 0x28970CE0,
+ .name = "at91sam4sa16b",
+ .total_flash_size = 1024 * 1024,
+ .total_sram_size = 160 * 1024,
+ .n_gpnvms = 2,
+ .n_banks = 1,
+ {
+/* .bank[0] = {*/
+ {
+ .probed = 0,
+ .pChip = NULL,
+ .pBank = NULL,
+ .bank_number = 0,
+ .base_address = FLASH_BANK_BASE_S,
+ .controller_address = 0x400e0a00,
+ .flash_wait_states = 5,
+ .present = 1,
+ .size_bytes = 1024 * 1024,
+ .nsectors = 128,
+ .sector_size = 8192,
+ .page_size = 512,
+ },
+/* .bank[1] = {*/
+ {
+ .present = 0,
+ .probed = 0,
+ .bank_number = 1,
+
+ },
+ },
+ },
+ /*atsam4s16a - LQFP48/QFN48*/
+ {
+ .chipid_cidr = 0x288C0CE0,
+ .name = "at91sam4s16a",
+ .total_flash_size = 1024 * 1024,
+ .total_sram_size = 128 * 1024,
+ .n_gpnvms = 2,
+ .n_banks = 1,
+ {
+/* .bank[0] = {*/
+ {
+ .probed = 0,
+ .pChip = NULL,
+ .pBank = NULL,
+ .bank_number = 0,
+ .base_address = FLASH_BANK_BASE_S,
+ .controller_address = 0x400e0a00,
+ .flash_wait_states = 5,
+ .present = 1,
+ .size_bytes = 1024 * 1024,
+ .nsectors = 128,
+ .sector_size = 8192,
+ .page_size = 512,
+ },
+/* .bank[1] = {*/
+ {
+ .present = 0,
+ .probed = 0,
+ .bank_number = 1,
+
+ },
+ },
+ },
+ /*atsam4s8c - LQFP100/BGA100*/
+ {
+ .chipid_cidr = 0x28AC0AE0,
+ .name = "at91sam4s8c",
+ .total_flash_size = 512 * 1024,
+ .total_sram_size = 128 * 1024,
+ .n_gpnvms = 2,
+ .n_banks = 1,
+ {
+/* .bank[0] = {*/
+ {
+ .probed = 0,
+ .pChip = NULL,
+ .pBank = NULL,
+ .bank_number = 0,
+ .base_address = FLASH_BANK_BASE_S,
+ .controller_address = 0x400e0a00,
+ .flash_wait_states = 5,
+ .present = 1,
+ .size_bytes = 512 * 1024,
+ .nsectors = 64,
+ .sector_size = 8192,
+ .page_size = 512,
+ },
+/* .bank[1] = {*/
+ {
+ .present = 0,
+ .probed = 0,
+ .bank_number = 1,
+
+ },
+ },
+ },
+ /*atsam4s8b - LQFP64/QFN64/WLCSP64*/
{
- .chipid_cidr = 0x28AC0CE0,
- .name = "at91sam4s16c",
- .total_flash_size = 1024 * 1024,
+ .chipid_cidr = 0x289C0AE0,
+ .name = "at91sam4s8b",
+ .total_flash_size = 512 * 1024,
.total_sram_size = 128 * 1024,
.n_gpnvms = 2,
.n_banks = 1,
@@ -271,10 +865,10 @@ static const struct sam4_chip_details all_sam4_details[] = {
.bank_number = 0,
.base_address = FLASH_BANK_BASE_S,
.controller_address = 0x400e0a00,
- .flash_wait_states = 6, /* workaround silicon bug */
+ .flash_wait_states = 5,
.present = 1,
- .size_bytes = 1024 * 1024,
- .nsectors = 128,
+ .size_bytes = 512 * 1024,
+ .nsectors = 64,
.sector_size = 8192,
.page_size = 512,
},
@@ -287,11 +881,11 @@ static const struct sam4_chip_details all_sam4_details[] = {
},
},
},
- /*atsam4s16b - LQFP64/QFN64*/
+ /*atsam4s8a - LQFP48/BGA48*/
{
- .chipid_cidr = 0x289C0CE0,
- .name = "at91sam4s16b",
- .total_flash_size = 1024 * 1024,
+ .chipid_cidr = 0x288C0AE0,
+ .name = "at91sam4s8a",
+ .total_flash_size = 512 * 1024,
.total_sram_size = 128 * 1024,
.n_gpnvms = 2,
.n_banks = 1,
@@ -304,10 +898,10 @@ static const struct sam4_chip_details all_sam4_details[] = {
.bank_number = 0,
.base_address = FLASH_BANK_BASE_S,
.controller_address = 0x400e0a00,
- .flash_wait_states = 6, /* workaround silicon bug */
+ .flash_wait_states = 5,
.present = 1,
- .size_bytes = 1024 * 1024,
- .nsectors = 128,
+ .size_bytes = 512 * 1024,
+ .nsectors = 64,
.sector_size = 8192,
.page_size = 512,
},
@@ -320,12 +914,13 @@ static const struct sam4_chip_details all_sam4_details[] = {
},
},
},
- /*atsam4s16a - LQFP48/QFN48*/
+
+ /*atsam4s4c - LQFP100/BGA100*/
{
- .chipid_cidr = 0x288C0CE0,
- .name = "at91sam4s16a",
- .total_flash_size = 1024 * 1024,
- .total_sram_size = 128 * 1024,
+ .chipid_cidr = 0x28ab09e0,
+ .name = "at91sam4s4c",
+ .total_flash_size = 256 * 1024,
+ .total_sram_size = 64 * 1024,
.n_gpnvms = 2,
.n_banks = 1,
{
@@ -337,10 +932,10 @@ static const struct sam4_chip_details all_sam4_details[] = {
.bank_number = 0,
.base_address = FLASH_BANK_BASE_S,
.controller_address = 0x400e0a00,
- .flash_wait_states = 6, /* workaround silicon bug */
+ .flash_wait_states = 5,
.present = 1,
- .size_bytes = 1024 * 1024,
- .nsectors = 128,
+ .size_bytes = 256 * 1024,
+ .nsectors = 32,
.sector_size = 8192,
.page_size = 512,
},
@@ -353,12 +948,13 @@ static const struct sam4_chip_details all_sam4_details[] = {
},
},
},
- /*atsam4s8c - LQFP100/BGA100*/
+
+ /*atsam4s4b - LQFP64/QFN64/WLCSP64*/
{
- .chipid_cidr = 0x28AC0AE0,
- .name = "at91sam4s8c",
- .total_flash_size = 512 * 1024,
- .total_sram_size = 128 * 1024,
+ .chipid_cidr = 0x289b09e0,
+ .name = "at91sam4s4b",
+ .total_flash_size = 256 * 1024,
+ .total_sram_size = 64 * 1024,
.n_gpnvms = 2,
.n_banks = 1,
{
@@ -370,10 +966,10 @@ static const struct sam4_chip_details all_sam4_details[] = {
.bank_number = 0,
.base_address = FLASH_BANK_BASE_S,
.controller_address = 0x400e0a00,
- .flash_wait_states = 6, /* workaround silicon bug */
+ .flash_wait_states = 5,
.present = 1,
- .size_bytes = 512 * 1024,
- .nsectors = 64,
+ .size_bytes = 256 * 1024,
+ .nsectors = 32,
.sector_size = 8192,
.page_size = 512,
},
@@ -386,12 +982,13 @@ static const struct sam4_chip_details all_sam4_details[] = {
},
},
},
- /*atsam4s8b - LQFP64/BGA64*/
+
+ /*atsam4s4a - LQFP48/QFN48*/
{
- .chipid_cidr = 0x289C0AE0,
- .name = "at91sam4s8b",
- .total_flash_size = 512 * 1024,
- .total_sram_size = 128 * 1024,
+ .chipid_cidr = 0x288b09e0,
+ .name = "at91sam4s4a",
+ .total_flash_size = 256 * 1024,
+ .total_sram_size = 64 * 1024,
.n_gpnvms = 2,
.n_banks = 1,
{
@@ -403,10 +1000,10 @@ static const struct sam4_chip_details all_sam4_details[] = {
.bank_number = 0,
.base_address = FLASH_BANK_BASE_S,
.controller_address = 0x400e0a00,
- .flash_wait_states = 6, /* workaround silicon bug */
+ .flash_wait_states = 5,
.present = 1,
- .size_bytes = 512 * 1024,
- .nsectors = 64,
+ .size_bytes = 256 * 1024,
+ .nsectors = 32,
.sector_size = 8192,
.page_size = 512,
},
@@ -419,12 +1016,13 @@ static const struct sam4_chip_details all_sam4_details[] = {
},
},
},
- /*atsam4s8a - LQFP48/BGA48*/
+
+ /*atsam4s2c - LQFP100/BGA100*/
{
- .chipid_cidr = 0x288C0AE0,
- .name = "at91sam4s8a",
- .total_flash_size = 512 * 1024,
- .total_sram_size = 128 * 1024,
+ .chipid_cidr = 0x28ab07e0,
+ .name = "at91sam4s2c",
+ .total_flash_size = 128 * 1024,
+ .total_sram_size = 64 * 1024,
.n_gpnvms = 2,
.n_banks = 1,
{
@@ -436,10 +1034,78 @@ static const struct sam4_chip_details all_sam4_details[] = {
.bank_number = 0,
.base_address = FLASH_BANK_BASE_S,
.controller_address = 0x400e0a00,
- .flash_wait_states = 6, /* workaround silicon bug */
+ .flash_wait_states = 5,
.present = 1,
- .size_bytes = 512 * 1024,
- .nsectors = 64,
+ .size_bytes = 128 * 1024,
+ .nsectors = 16,
+ .sector_size = 8192,
+ .page_size = 512,
+ },
+/* .bank[1] = {*/
+ {
+ .present = 0,
+ .probed = 0,
+ .bank_number = 1,
+
+ },
+ },
+ },
+
+ /*atsam4s2b - LQPF64/QFN64/WLCSP64*/
+ {
+ .chipid_cidr = 0x289b07e0,
+ .name = "at91sam4s2b",
+ .total_flash_size = 128 * 1024,
+ .total_sram_size = 64 * 1024,
+ .n_gpnvms = 2,
+ .n_banks = 1,
+ {
+/* .bank[0] = {*/
+ {
+ .probed = 0,
+ .pChip = NULL,
+ .pBank = NULL,
+ .bank_number = 0,
+ .base_address = FLASH_BANK_BASE_S,
+ .controller_address = 0x400e0a00,
+ .flash_wait_states = 5,
+ .present = 1,
+ .size_bytes = 128 * 1024,
+ .nsectors = 16,
+ .sector_size = 8192,
+ .page_size = 512,
+ },
+/* .bank[1] = {*/
+ {
+ .present = 0,
+ .probed = 0,
+ .bank_number = 1,
+
+ },
+ },
+ },
+
+ /*atsam4s2a - LQFP48/QFN48*/
+ {
+ .chipid_cidr = 0x288b07e0,
+ .name = "at91sam4s2a",
+ .total_flash_size = 128 * 1024,
+ .total_sram_size = 64 * 1024,
+ .n_gpnvms = 2,
+ .n_banks = 1,
+ {
+/* .bank[0] = {*/
+ {
+ .probed = 0,
+ .pChip = NULL,
+ .pBank = NULL,
+ .bank_number = 0,
+ .base_address = FLASH_BANK_BASE_S,
+ .controller_address = 0x400e0a00,
+ .flash_wait_states = 5,
+ .present = 1,
+ .size_bytes = 128 * 1024,
+ .nsectors = 16,
.sector_size = 8192,
.page_size = 512,
},
@@ -452,6 +1118,286 @@ static const struct sam4_chip_details all_sam4_details[] = {
},
},
},
+
+ /*at91sam4sd32c - LQFP100/BGA100*/
+ {
+ .chipid_cidr = 0x29a70ee0,
+ .name = "at91sam4sd32c",
+ .total_flash_size = 2048 * 1024,
+ .total_sram_size = 160 * 1024,
+ .n_gpnvms = 3,
+ .n_banks = 2,
+
+/* .bank[0] = { */
+ {
+ {
+ .probed = 0,
+ .pChip = NULL,
+ .pBank = NULL,
+ .bank_number = 0,
+ .base_address = FLASH_BANK0_BASE_SD,
+ .controller_address = 0x400e0a00,
+ .flash_wait_states = 5,
+ .present = 1,
+ .size_bytes = 1024 * 1024,
+ .nsectors = 128,
+ .sector_size = 8192,
+ .page_size = 512,
+ },
+
+/* .bank[1] = { */
+ {
+ .probed = 0,
+ .pChip = NULL,
+ .pBank = NULL,
+ .bank_number = 1,
+ .base_address = FLASH_BANK1_BASE_2048K_SD,
+ .controller_address = 0x400e0c00,
+ .flash_wait_states = 5,
+ .present = 1,
+ .size_bytes = 1024 * 1024,
+ .nsectors = 128,
+ .sector_size = 8192,
+ .page_size = 512,
+ },
+ },
+ },
+
+ /*at91sam4sd32b - LQFP64/BGA64*/
+ {
+ .chipid_cidr = 0x29970ee0,
+ .name = "at91sam4sd32b",
+ .total_flash_size = 2048 * 1024,
+ .total_sram_size = 160 * 1024,
+ .n_gpnvms = 3,
+ .n_banks = 2,
+
+/* .bank[0] = { */
+ {
+ {
+ .probed = 0,
+ .pChip = NULL,
+ .pBank = NULL,
+ .bank_number = 0,
+ .base_address = FLASH_BANK0_BASE_SD,
+ .controller_address = 0x400e0a00,
+ .flash_wait_states = 5,
+ .present = 1,
+ .size_bytes = 1024 * 1024,
+ .nsectors = 128,
+ .sector_size = 8192,
+ .page_size = 512,
+ },
+
+/* .bank[1] = { */
+ {
+ .probed = 0,
+ .pChip = NULL,
+ .pBank = NULL,
+ .bank_number = 1,
+ .base_address = FLASH_BANK1_BASE_2048K_SD,
+ .controller_address = 0x400e0c00,
+ .flash_wait_states = 5,
+ .present = 1,
+ .size_bytes = 1024 * 1024,
+ .nsectors = 128,
+ .sector_size = 8192,
+ .page_size = 512,
+ },
+ },
+ },
+
+ /*at91sam4sd16c - LQFP100/BGA100*/
+ {
+ .chipid_cidr = 0x29a70ce0,
+ .name = "at91sam4sd16c",
+ .total_flash_size = 1024 * 1024,
+ .total_sram_size = 160 * 1024,
+ .n_gpnvms = 3,
+ .n_banks = 2,
+
+/* .bank[0] = { */
+ {
+ {
+ .probed = 0,
+ .pChip = NULL,
+ .pBank = NULL,
+ .bank_number = 0,
+ .base_address = FLASH_BANK0_BASE_SD,
+ .controller_address = 0x400e0a00,
+ .flash_wait_states = 5,
+ .present = 1,
+ .size_bytes = 512 * 1024,
+ .nsectors = 64,
+ .sector_size = 8192,
+ .page_size = 512,
+ },
+
+/* .bank[1] = { */
+ {
+ .probed = 0,
+ .pChip = NULL,
+ .pBank = NULL,
+ .bank_number = 1,
+ .base_address = FLASH_BANK1_BASE_1024K_SD,
+ .controller_address = 0x400e0c00,
+ .flash_wait_states = 5,
+ .present = 1,
+ .size_bytes = 512 * 1024,
+ .nsectors = 64,
+ .sector_size = 8192,
+ .page_size = 512,
+ },
+ },
+ },
+
+ /*at91sam4sd16b - LQFP64/BGA64*/
+ {
+ .chipid_cidr = 0x29970ce0,
+ .name = "at91sam4sd16b",
+ .total_flash_size = 1024 * 1024,
+ .total_sram_size = 160 * 1024,
+ .n_gpnvms = 3,
+ .n_banks = 2,
+
+/* .bank[0] = { */
+ {
+ {
+ .probed = 0,
+ .pChip = NULL,
+ .pBank = NULL,
+ .bank_number = 0,
+ .base_address = FLASH_BANK0_BASE_SD,
+ .controller_address = 0x400e0a00,
+ .flash_wait_states = 5,
+ .present = 1,
+ .size_bytes = 512 * 1024,
+ .nsectors = 64,
+ .sector_size = 8192,
+ .page_size = 512,
+ },
+
+/* .bank[1] = { */
+ {
+ .probed = 0,
+ .pChip = NULL,
+ .pBank = NULL,
+ .bank_number = 1,
+ .base_address = FLASH_BANK1_BASE_1024K_SD,
+ .controller_address = 0x400e0c00,
+ .flash_wait_states = 5,
+ .present = 1,
+ .size_bytes = 512 * 1024,
+ .nsectors = 64,
+ .sector_size = 8192,
+ .page_size = 512,
+ },
+ },
+ },
+
+ /* atsamg53n19 */
+ {
+ .chipid_cidr = 0x247e0ae0,
+ .name = "atsamg53n19",
+ .total_flash_size = 512 * 1024,
+ .total_sram_size = 96 * 1024,
+ .n_gpnvms = 2,
+ .n_banks = 1,
+
+/* .bank[0] = {*/
+ {
+ {
+ .probed = 0,
+ .pChip = NULL,
+ .pBank = NULL,
+ .bank_number = 0,
+ .base_address = FLASH_BANK_BASE_S,
+ .controller_address = 0x400e0a00,
+ .flash_wait_states = 5,
+ .present = 1,
+ .size_bytes = 512 * 1024,
+ .nsectors = 64,
+ .sector_size = 8192,
+ .page_size = 512,
+ },
+/* .bank[1] = {*/
+ {
+ .present = 0,
+ .probed = 0,
+ .bank_number = 1,
+
+ },
+ }
+ },
+
+ /* atsamg55g19 */
+ {
+ .chipid_cidr = 0x24470ae0,
+ .name = "atsamg55g19",
+ .total_flash_size = 512 * 1024,
+ .total_sram_size = 160 * 1024,
+ .n_gpnvms = 2,
+ .n_banks = 1,
+
+ {
+/* .bank[0] = */
+ {
+ .probed = 0,
+ .pChip = NULL,
+ .pBank = NULL,
+ .bank_number = 0,
+ .base_address = FLASH_BANK_BASE_S,
+ .controller_address = 0x400e0a00,
+ .flash_wait_states = 5,
+ .present = 1,
+ .size_bytes = 512 * 1024,
+ .nsectors = 64,
+ .sector_size = 8192,
+ .page_size = 512,
+ },
+/* .bank[1] = */
+ {
+ .present = 0,
+ .probed = 0,
+ .bank_number = 1,
+ },
+ }
+ },
+
+ /* atsamg55j19 */
+ {
+ .chipid_cidr = 0x24570ae0,
+ .name = "atsamg55j19",
+ .total_flash_size = 512 * 1024,
+ .total_sram_size = 160 * 1024,
+ .n_gpnvms = 2,
+ .n_banks = 1,
+
+ {
+/* .bank[0] = */
+ {
+ .probed = 0,
+ .pChip = NULL,
+ .pBank = NULL,
+ .bank_number = 0,
+ .base_address = FLASH_BANK_BASE_S,
+ .controller_address = 0x400e0a00,
+ .flash_wait_states = 5,
+ .present = 1,
+ .size_bytes = 512 * 1024,
+ .nsectors = 64,
+ .sector_size = 8192,
+ .page_size = 512,
+ },
+/* .bank[1] = */
+ {
+ .present = 0,
+ .probed = 0,
+ .bank_number = 1,
+ },
+ }
+ },
+
/* terminate */
{
.chipid_cidr = 0,
@@ -610,7 +1556,7 @@ static int EFC_PerformCommand(struct sam4_bank_private *pPrivate,
int r;
uint32_t v;
- long long ms_now, ms_end;
+ int64_t ms_now, ms_end;
/* default */
if (status)
@@ -950,7 +1896,7 @@ static uint32_t sam4_reg_fieldname(struct sam4_chip *pChip,
}
/* show the basics */
- LOG_USER_N("\t%*s: %*d [0x%0*x] ",
+ LOG_USER_N("\t%*s: %*" PRId32 " [0x%0*" PRIx32 "] ",
REG_NAME_WIDTH, regname,
dwidth, v,
hwidth, v);
@@ -959,14 +1905,14 @@ static uint32_t sam4_reg_fieldname(struct sam4_chip *pChip,
static const char _unknown[] = "unknown";
static const char *const eproc_names[] = {
- _unknown, /* 0 */
+ "Cortex-M7", /* 0 */
"arm946es", /* 1 */
"arm7tdmi", /* 2 */
- "cortex-m3", /* 3 */
+ "Cortex-M3", /* 3 */
"arm920t", /* 4 */
"arm926ejs", /* 5 */
- "cortex-a5", /* 6 */
- "cortex-m4", /* 7 */
+ "Cortex-A5", /* 6 */
+ "Cortex-M4", /* 7 */
_unknown, /* 8 */
_unknown, /* 9 */
_unknown, /* 10 */
@@ -987,7 +1933,7 @@ static const char *const nvpsize[] = {
"64K bytes", /* 5 */
_unknown, /* 6 */
"128K bytes", /* 7 */
- _unknown, /* 8 */
+ "160K bytes", /* 8 */
"256K bytes", /* 9 */
"512K bytes", /* 10 */
_unknown, /* 11 */
@@ -1024,12 +1970,21 @@ static const struct archnames { unsigned value; const char *name; } archnames[]
{ 0x37, "CAP7 Series" },
{ 0x39, "CAP9 Series" },
{ 0x3B, "CAP11 Series" },
+ { 0x3C, "ATSAM4E" },
{ 0x40, "AT91x40 Series" },
{ 0x42, "AT91x42 Series" },
+ { 0x43, "SAMG51 Series"
+ },
+ { 0x44, "SAMG55 Series (49-pin WLCSP)" },
+ { 0x45, "SAMG55 Series (64-pin)" },
+ { 0x47, "SAMG53 Series"
+ },
{ 0x55, "AT91x55 Series" },
{ 0x60, "AT91SAM7Axx Series" },
{ 0x61, "AT91SAM7AQxx Series" },
{ 0x63, "AT91x63 Series" },
+ { 0x64, "SAM4CxxC (100-pin version)" },
+ { 0x66, "SAM4CxxE (144-pin version)" },
{ 0x70, "AT91SAM7Sxx Series" },
{ 0x71, "AT91SAM7XCxx Series" },
{ 0x72, "AT91SAM7SExx Series" },
@@ -1175,10 +2130,10 @@ static void sam4_explain_ckgr_mcfr(struct sam4_chip *pChip)
v = (v * pChip->cfg.slow_freq) / 16;
pChip->cfg.mainosc_freq = v;
- LOG_USER("(%3.03f Mhz (%d.%03dkhz slowclk)",
+ LOG_USER("(%3.03f Mhz (%" PRIu32 ".%03" PRIu32 "khz slowclk)",
_tomhz(v),
- pChip->cfg.slow_freq / 1000,
- pChip->cfg.slow_freq % 1000);
+ (uint32_t)(pChip->cfg.slow_freq / 1000),
+ (uint32_t)(pChip->cfg.slow_freq % 1000));
}
static void sam4_explain_ckgr_plla(struct sam4_chip *pChip)
@@ -1194,8 +2149,8 @@ static void sam4_explain_ckgr_plla(struct sam4_chip *pChip)
LOG_USER("\tPLLA Freq: (Disabled,mula = 0)");
else if (diva == 0)
LOG_USER("\tPLLA Freq: (Disabled,diva = 0)");
- else if (diva == 1) {
- pChip->cfg.plla_freq = (pChip->cfg.mainosc_freq * (mula + 1));
+ else if (diva >= 1) {
+ pChip->cfg.plla_freq = (pChip->cfg.mainosc_freq * (mula + 1) / diva);
LOG_USER("\tPLLA Freq: %3.03f MHz",
_tomhz(pChip->cfg.plla_freq));
}
@@ -1346,7 +2301,7 @@ static const struct sam4_reg_list sam4_all_regs[] = {
static struct sam4_bank_private *get_sam4_bank_private(struct flash_bank *bank)
{
- return (struct sam4_bank_private *)(bank->driver_priv);
+ return bank->driver_priv;
}
/**
@@ -1421,13 +2376,18 @@ static int sam4_GetInfo(struct sam4_chip *pChip)
{
const struct sam4_reg_list *pReg;
uint32_t regval;
+ int r;
+
+ r = sam4_ReadAllRegs(pChip);
+ if (r != ERROR_OK)
+ return r;
pReg = &(sam4_all_regs[0]);
while (pReg->name) {
/* display all regs */
LOG_DEBUG("Start: %s", pReg->name);
regval = *sam4_get_reg_ptr(&(pChip->cfg), pReg);
- LOG_USER("%*s: [0x%08x] -> 0x%08x",
+ LOG_USER("%*s: [0x%08" PRIx32 "] -> 0x%08" PRIx32,
REG_NAME_WIDTH,
pReg->name,
pReg->address,
@@ -1443,7 +2403,7 @@ static int sam4_GetInfo(struct sam4_chip *pChip)
LOG_USER(" cpu-freq: %3.03f MHz", _tomhz(pChip->cfg.cpu_freq));
LOG_USER("mclk-freq: %3.03f MHz", _tomhz(pChip->cfg.mclk_freq));
- LOG_USER(" UniqueId: 0x%08x 0x%08x 0x%08x 0x%08x",
+ LOG_USER(" UniqueId: 0x%08" PRIx32 " 0x%08" PRIx32 " 0x%08" PRIx32 " 0x%08"PRIx32,
pChip->cfg.unique_id[0],
pChip->cfg.unique_id[1],
pChip->cfg.unique_id[2],
@@ -1525,18 +2485,46 @@ FLASH_BANK_COMMAND_HANDLER(sam4_flash_bank_command)
break;
/* at91sam4s series only has bank 0*/
+ /* at91sam4sd series has the same address for bank 0 (FLASH_BANK0_BASE_SD)*/
case FLASH_BANK_BASE_S:
+ case FLASH_BANK_BASE_C:
bank->driver_priv = &(pChip->details.bank[0]);
bank->bank_number = 0;
pChip->details.bank[0].pChip = pChip;
pChip->details.bank[0].pBank = bank;
break;
+
+ /* Bank 1 of at91sam4sd/at91sam4c32 series */
+ case FLASH_BANK1_BASE_1024K_SD:
+ case FLASH_BANK1_BASE_2048K_SD:
+ case FLASH_BANK1_BASE_C32:
+ bank->driver_priv = &(pChip->details.bank[1]);
+ bank->bank_number = 1;
+ pChip->details.bank[1].pChip = pChip;
+ pChip->details.bank[1].pBank = bank;
+ break;
}
/* we initialize after probing. */
return ERROR_OK;
}
+/**
+ * Remove all chips from the internal list without distingushing which one
+ * is owned by this bank. This simplification works only for one shot
+ * deallocation like current flash_free_all_banks()
+ */
+static void sam4_free_driver_priv(struct flash_bank *bank)
+{
+ struct sam4_chip *chip = all_sam4_chips;
+ while (chip) {
+ struct sam4_chip *next = chip->next;
+ free(chip);
+ chip = next;
+ }
+ all_sam4_chips = NULL;
+}
+
static int sam4_GetDetails(struct sam4_bank_private *pPrivate)
{
const struct sam4_chip_details *pDetails;
@@ -1557,10 +2545,12 @@ static int sam4_GetDetails(struct sam4_bank_private *pPrivate)
LOG_ERROR("SAM4 ChipID 0x%08x not found in table (perhaps you can ID this chip?)",
(unsigned int)(pPrivate->pChip->cfg.CHIPID_CIDR));
/* Help the victim, print details about the chip */
- LOG_INFO("SAM4 CHIPID_CIDR: 0x%08x decodes as follows",
+ LOG_INFO("SAM4 CHIPID_CIDR: 0x%08" PRIx32 " decodes as follows",
pPrivate->pChip->cfg.CHIPID_CIDR);
sam4_explain_chipid_cidr(pPrivate->pChip);
return ERROR_FAIL;
+ } else {
+ LOG_DEBUG("SAM4 Found chip %s, CIDR 0x%08x", pDetails->name, pDetails->chipid_cidr);
}
/* DANGER: THERE ARE DRAGONS HERE */
@@ -1596,14 +2586,35 @@ static int sam4_GetDetails(struct sam4_bank_private *pPrivate)
return ERROR_OK;
}
-static int _sam4_probe(struct flash_bank *bank, int noise)
+static int sam4_info(struct flash_bank *bank, char *buf, int buf_size)
+{
+ struct sam4_bank_private *pPrivate;
+ int k = bank->size / 1024;
+
+ pPrivate = get_sam4_bank_private(bank);
+ if (pPrivate == NULL) {
+ buf[0] = '\0';
+ return ERROR_FAIL;
+ }
+
+ snprintf(buf, buf_size,
+ "%s bank %d: %d kB at " TARGET_ADDR_FMT,
+ pPrivate->pChip->details.name,
+ pPrivate->bank_number,
+ k,
+ bank->base);
+
+ return ERROR_OK;
+}
+
+static int sam4_probe(struct flash_bank *bank)
{
unsigned x;
int r;
struct sam4_bank_private *pPrivate;
- LOG_DEBUG("Begin: Bank: %d, Noise: %d", bank->bank_number, noise);
+ LOG_DEBUG("Begin: Bank: %d", bank->bank_number);
if (bank->target->state != TARGET_HALTED) {
LOG_ERROR("Target not halted");
return ERROR_TARGET_NOT_HALTED;
@@ -1631,6 +2642,9 @@ static int _sam4_probe(struct flash_bank *bank, int noise)
for (x = 0; x < SAM4_MAX_FLASH_BANKS; x++) {
if (bank->base == pPrivate->pChip->details.bank[x].base_address) {
bank->size = pPrivate->pChip->details.bank[x].size_bytes;
+ LOG_DEBUG("SAM4 Set flash bank to " TARGET_ADDR_FMT " - "
+ TARGET_ADDR_FMT ", idx %d", bank->base,
+ bank->base + bank->size, x);
break;
}
}
@@ -1669,14 +2683,15 @@ static int _sam4_probe(struct flash_bank *bank, int noise)
return r;
}
-static int sam4_probe(struct flash_bank *bank)
-{
- return _sam4_probe(bank, 1);
-}
-
static int sam4_auto_probe(struct flash_bank *bank)
{
- return _sam4_probe(bank, 0);
+ struct sam4_bank_private *pPrivate;
+
+ pPrivate = get_sam4_bank_private(bank);
+ if (pPrivate && pPrivate->probed)
+ return ERROR_OK;
+
+ return sam4_probe(bank);
}
static int sam4_erase(struct flash_bank *bank, int first, int last)
@@ -1757,16 +2772,6 @@ static int sam4_protect(struct flash_bank *bank, int set, int first, int last)
}
-static int sam4_info(struct flash_bank *bank, char *buf, int buf_size)
-{
- if (bank->target->state != TARGET_HALTED) {
- LOG_ERROR("Target not halted");
- return ERROR_TARGET_NOT_HALTED;
- }
- buf[0] = 0;
- return ERROR_OK;
-}
-
static int sam4_page_read(struct sam4_bank_private *pPrivate, unsigned pagenum, uint8_t *buf)
{
uint32_t adr;
@@ -1786,107 +2791,17 @@ static int sam4_page_read(struct sam4_bank_private *pPrivate, unsigned pagenum,
return r;
}
-/* The code below is basically this: */
-/* compiled with */
-/* arm-none-eabi-gcc -mthumb -mcpu = cortex-m3 -O9 -S ./foobar.c -o foobar.s */
-/* */
-/* Only the *CPU* can write to the flash buffer. */
-/* the DAP cannot... so - we download this 28byte thing */
-/* Run the algorithm - (below) */
-/* to program the device */
-/* */
-/* ======================================== */
-/* #include */
-/* */
-/* struct foo { */
-/* uint32_t *dst; */
-/* const uint32_t *src; */
-/* int n; */
-/* volatile uint32_t *base; */
-/* uint32_t cmd; */
-/* }; */
-/* */
-/* */
-/* uint32_t sam4_function(struct foo *p) */
-/* { */
-/* volatile uint32_t *v; */
-/* uint32_t *d; */
-/* const uint32_t *s; */
-/* int n; */
-/* uint32_t r; */
-/* */
-/* d = p->dst; */
-/* s = p->src; */
-/* n = p->n; */
-/* */
-/* do { */
-/* *d++ = *s++; */
-/* } while (--n) */
-/* ; */
-/* */
-/* v = p->base; */
-/* */
-/* v[ 1 ] = p->cmd; */
-/* do { */
-/* r = v[8/4]; */
-/* } while (!(r&1)) */
-/* ; */
-/* return r; */
-/* } */
-/* ======================================== */
-
-static const uint8_t
- sam4_page_write_opcodes[] = {
- /* 24 0000 0446 mov r4, r0 */
- 0x04, 0x46,
- /* 25 0002 6168 ldr r1, [r4, #4] */
- 0x61, 0x68,
- /* 26 0004 0068 ldr r0, [r0, #0] */
- 0x00, 0x68,
- /* 27 0006 A268 ldr r2, [r4, #8] */
- 0xa2, 0x68,
- /* 28 @ lr needed for prologue */
- /* 29 .L2: */
- /* 30 0008 51F8043B ldr r3, [r1], #4 */
- 0x51, 0xf8, 0x04, 0x3b,
- /* 31 000c 12F1FF32 adds r2, r2, #-1 */
- 0x12, 0xf1, 0xff, 0x32,
- /* 32 0010 40F8043B str r3, [r0], #4 */
- 0x40, 0xf8, 0x04, 0x3b,
- /* 33 0014 F8D1 bne .L2 */
- 0xf8, 0xd1,
- /* 34 0016 E268 ldr r2, [r4, #12] */
- 0xe2, 0x68,
- /* 35 0018 2369 ldr r3, [r4, #16] */
- 0x23, 0x69,
- /* 36 001a 5360 str r3, [r2, #4] */
- 0x53, 0x60,
- /* 37 001c 0832 adds r2, r2, #8 */
- 0x08, 0x32,
- /* 38 .L4: */
- /* 39 001e 1068 ldr r0, [r2, #0] */
- 0x10, 0x68,
- /* 40 0020 10F0010F tst r0, #1 */
- 0x10, 0xf0, 0x01, 0x0f,
- /* 41 0024 FBD0 beq .L4 */
- 0xfb, 0xd0,
- 0x00, 0xBE /* bkpt #0 */
-};
-
-static int sam4_page_write(struct sam4_bank_private *pPrivate, unsigned pagenum, uint8_t *buf)
+static int sam4_set_wait(struct sam4_bank_private *pPrivate)
{
- 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");
+ if (r != ERROR_OK) {
+ LOG_ERROR("Error Read failed: read flash mode register");
+ return r;
+ }
/* Clear flash wait state field */
fmr &= 0xfffff0ff;
@@ -1897,7 +2812,19 @@ static int sam4_page_write(struct sam4_bank_private *pPrivate, unsigned pagenum,
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_ERROR("Error Write failed: set flash mode register");
+
+ return r;
+}
+
+static int sam4_page_write(struct sam4_bank_private *pPrivate, unsigned pagenum, const uint8_t *buf)
+{
+ uint32_t adr;
+ uint32_t status;
+ int r;
+
+ adr = pagenum * pPrivate->page_size;
+ adr = (adr + pPrivate->base_address);
/* 1st sector 8kBytes - page 0 - 15*/
/* 2nd sector 8kBytes - page 16 - 30*/
@@ -1935,7 +2862,7 @@ static int sam4_page_write(struct sam4_bank_private *pPrivate, unsigned pagenum,
}
static int sam4_write(struct flash_bank *bank,
- uint8_t *buffer,
+ const uint8_t *buffer,
uint32_t offset,
uint32_t count)
{
@@ -1985,6 +2912,10 @@ static int sam4_write(struct flash_bank *bank,
goto done;
}
+ r = sam4_set_wait(pPrivate);
+ if (r != ERROR_OK)
+ goto done;
+
/* what page do we start & end in? */
page_cur = offset / pPrivate->page_size;
page_end = (offset + count - 1) / pPrivate->page_size;
@@ -2087,7 +3018,7 @@ done:
COMMAND_HANDLER(sam4_handle_info_command)
{
struct sam4_chip *pChip;
- pChip = get_current_sam4(CMD_CTX);
+ pChip = get_current_sam4(CMD);
if (!pChip)
return ERROR_OK;
@@ -2098,7 +3029,7 @@ COMMAND_HANDLER(sam4_handle_info_command)
if (pChip->details.bank[0].pBank == NULL) {
x = 0;
need_define:
- command_print(CMD_CTX,
+ command_print(CMD,
"Please define bank %d via command: flash bank %s ... ",
x,
at91sam4_flash.name);
@@ -2147,7 +3078,7 @@ COMMAND_HANDLER(sam4_handle_gpnvm_command)
int r, who;
struct sam4_chip *pChip;
- pChip = get_current_sam4(CMD_CTX);
+ pChip = get_current_sam4(CMD);
if (!pChip)
return ERROR_OK;
@@ -2157,7 +3088,7 @@ COMMAND_HANDLER(sam4_handle_gpnvm_command)
}
if (pChip->details.bank[0].pBank == NULL) {
- command_print(CMD_CTX, "Bank0 must be defined first via: flash bank %s ...",
+ command_print(CMD, "Bank0 must be defined first via: flash bank %s ...",
at91sam4_flash.name);
return ERROR_FAIL;
}
@@ -2196,22 +3127,23 @@ showall:
r = FLASHD_GetGPNVM(&(pChip->details.bank[0]), x, &v);
if (r != ERROR_OK)
break;
- command_print(CMD_CTX, "sam4-gpnvm%u: %u", x, v);
+ command_print(CMD, "sam4-gpnvm%u: %u", x, v);
}
return r;
}
if ((who >= 0) && (((unsigned)(who)) < pChip->details.n_gpnvms)) {
r = FLASHD_GetGPNVM(&(pChip->details.bank[0]), who, &v);
- command_print(CMD_CTX, "sam4-gpnvm%u: %u", who, v);
+ if (r == ERROR_OK)
+ command_print(CMD, "sam4-gpnvm%u: %u", who, v);
return r;
} else {
- command_print(CMD_CTX, "sam4-gpnvm invalid GPNVM: %u", who);
+ command_print(CMD, "sam4-gpnvm invalid GPNVM: %u", who);
return ERROR_COMMAND_SYNTAX_ERROR;
}
}
if (who == -1) {
- command_print(CMD_CTX, "Missing GPNVM number");
+ command_print(CMD, "Missing GPNVM number");
return ERROR_COMMAND_SYNTAX_ERROR;
}
@@ -2221,7 +3153,7 @@ showall:
(0 == strcmp("clear", CMD_ARGV[0]))) /* quietly accept both */
r = FLASHD_ClrGPNVM(&(pChip->details.bank[0]), who);
else {
- command_print(CMD_CTX, "Unknown command: %s", CMD_ARGV[0]);
+ command_print(CMD, "Unknown command: %s", CMD_ARGV[0]);
r = ERROR_COMMAND_SYNTAX_ERROR;
}
return r;
@@ -2231,7 +3163,7 @@ COMMAND_HANDLER(sam4_handle_slowclk_command)
{
struct sam4_chip *pChip;
- pChip = get_current_sam4(CMD_CTX);
+ pChip = get_current_sam4(CMD);
if (!pChip)
return ERROR_OK;
@@ -2246,7 +3178,7 @@ COMMAND_HANDLER(sam4_handle_slowclk_command)
COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], v);
if (v > 200000) {
/* absurd slow clock of 200Khz? */
- command_print(CMD_CTX, "Absurd/illegal slow clock freq: %d\n", (int)(v));
+ command_print(CMD, "Absurd/illegal slow clock freq: %d\n", (int)(v));
return ERROR_COMMAND_SYNTAX_ERROR;
}
pChip->cfg.slow_freq = v;
@@ -2254,11 +3186,11 @@ COMMAND_HANDLER(sam4_handle_slowclk_command)
}
default:
/* error */
- command_print(CMD_CTX, "Too many parameters");
+ command_print(CMD, "Too many parameters");
return ERROR_COMMAND_SYNTAX_ERROR;
break;
}
- command_print(CMD_CTX, "Slowclk freq: %d.%03dkhz",
+ command_print(CMD, "Slowclk freq: %d.%03dkhz",
(int)(pChip->cfg.slow_freq / 1000),
(int)(pChip->cfg.slow_freq % 1000));
return ERROR_OK;
@@ -2280,6 +3212,7 @@ static const struct command_registration at91sam4_exec_command_handlers[] = {
.mode = COMMAND_EXEC,
.help = "Print information about the current at91sam4 chip"
"and its flash configuration.",
+ .usage = "",
},
{
.name = "slowclk",
@@ -2302,7 +3235,7 @@ static const struct command_registration at91sam4_command_handlers[] = {
COMMAND_REGISTRATION_DONE
};
-struct flash_driver at91sam4_flash = {
+const struct flash_driver at91sam4_flash = {
.name = "at91sam4",
.commands = at91sam4_command_handlers,
.flash_bank_command = sam4_flash_bank_command,
@@ -2315,4 +3248,5 @@ struct flash_driver at91sam4_flash = {
.erase_check = default_flash_blank_check,
.protect_check = sam4_protect_check,
.info = sam4_info,
+ .free_driver_priv = sam4_free_driver_priv,
};