X-Git-Url: https://review.openocd.org/gitweb?a=blobdiff_plain;f=src%2Fflash%2Fnor%2Fat91sam3.c;h=2d5b684a53f084a49949c5fe7e211bef81938c15;hb=dba153bbce59985b0d8a23fc8d01c3b51d7e8528;hp=50f522f94e41bd178a50e8138fbe5475254e2091;hpb=4b4ce4f27e26b38807b65cce8fd6961e28a7733f;p=openocd.git diff --git a/src/flash/nor/at91sam3.c b/src/flash/nor/at91sam3.c index 50f522f94e..2d5b684a53 100644 --- a/src/flash/nor/at91sam3.c +++ b/src/flash/nor/at91sam3.c @@ -4,8 +4,9 @@ * * * Copyright (C) 2010 by Olaf Lüke (at91sam3s* support) * * olaf@uni-paderborn.de * - * * - * * + * * + * Copyright (C) 2011 by Olivier Schonken (at91sam3x* support) * * + * and Jim Norris * * 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 * * the Free Software Foundation; either version 2 of the License, or * @@ -19,7 +20,7 @@ * 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. * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * ****************************************************************************/ /* Some of the the lower level code was based on code supplied by @@ -72,19 +73,29 @@ /* at91sam3s series (has always one flash bank) */ #define FLASH_BANK_BASE_S 0x00400000 +/* at91sam3sd series (has always two flash banks) */ +#define FLASH_BANK0_BASE_SD FLASH_BANK_BASE_S +#define FLASH_BANK1_BASE_512K_SD (FLASH_BANK0_BASE_SD+(512*1024/2)) + + /* at91sam3n series (has always one flash bank) */ #define FLASH_BANK_BASE_N 0x00400000 +/* at91sam3a/x series has two flash banks*/ +#define FLASH_BANK0_BASE_AX 0x00080000 +/*Bank 1 of the at91sam3a/x series starts at 0x00080000 + half flash size*/ +#define FLASH_BANK1_BASE_256K_AX 0x000A0000 +#define FLASH_BANK1_BASE_512K_AX 0x000C0000 + #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 */ #define AT91C_EFC_FCMD_EWP (0x3) /* (EFC) Erase Page and Write Page */ -#define AT91C_EFC_FCMD_EWPL (0x4) /* (EFC) Erase Page and Write Page - * then Lock */ +#define AT91C_EFC_FCMD_EWPL (0x4) /* (EFC) Erase Page and Write Page then Lock */ #define AT91C_EFC_FCMD_EA (0x5) /* (EFC) Erase All */ -/* cmd6 is not present int he at91sam3u4/2/1 data sheet table 17-2 */ +/* cmd6 is not present in the at91sam3u4/2/1 data sheet table 17-2 */ /* #define AT91C_EFC_FCMD_EPL (0x6) // (EFC) Erase plane? */ -/* cmd7 is not present int he at91sam3u4/2/1 data sheet table 17-2 */ +/* cmd7 is not present in the at91sam3u4/2/1 data sheet table 17-2 */ /* #define AT91C_EFC_FCMD_EPA (0x7) // (EFC) Erase pages? */ #define AT91C_EFC_FCMD_SLB (0x8) /* (EFC) Set Lock Bit */ #define AT91C_EFC_FCMD_CLB (0x9) /* (EFC) Clear Lock Bit */ @@ -128,8 +139,13 @@ struct sam3_cfg { #define SAM3_CHIPID_CIDR (0x400E0740) uint32_t CHIPID_CIDR; +#define SAM3_CHIPID_CIDR2 (0x400E0940) /*SAM3X and SAM3A cidr at this address*/ + uint32_t CHIPID_CIDR2; #define SAM3_CHIPID_EXID (0x400E0744) uint32_t CHIPID_EXID; +#define SAM3_CHIPID_EXID2 (0x400E0944) /*SAM3X and SAM3A cidr at this address*/ + uint32_t CHIPID_EXID2; + #define SAM3_PMC_BASE (0x400E0400) #define SAM3_PMC_SCSR (SAM3_PMC_BASE + 0x0008) @@ -182,7 +198,7 @@ struct sam3_bank_private { /* so we can find the chip we belong to */ struct sam3_chip *pChip; - /* so we can find the orginal bank pointer */ + /* so we can find the original bank pointer */ struct flash_bank *pBank; unsigned bank_number; uint32_t controller_address; @@ -198,7 +214,7 @@ struct sam3_bank_private { struct sam3_chip_details { /* THERE ARE DRAGONS HERE.. */ /* note: If you add pointers here */ - /* becareful about them as they */ + /* be careful about them as they */ /* may need to be updated inside */ /* the function: "sam3_GetDetails() */ /* which copy/overwrites the */ @@ -553,7 +569,7 @@ static const struct sam3_chip_details all_sam3_details[] = { /* Note: The preliminary at91sam3s datasheet says on page 302 */ /* that the flash controller is at address 0x400E0800. */ - /* This is _not_ the case, the controller resides at address 0x400e0a0. */ + /* This is _not_ the case, the controller resides at address 0x400e0a00. */ { .chipid_cidr = 0x28A00960, .name = "at91sam3s4c", @@ -715,6 +731,126 @@ static const struct sam3_chip_details all_sam3_details[] = { }, }, }, + { + .chipid_cidr = 0x298B0A60, + .name = "at91sam3sd8a", + .total_flash_size = 512 * 1024, + .total_sram_size = 64 * 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 = 6, /* workaround silicon bug */ + .present = 1, + .size_bytes = 256 * 1024, + .nsectors = 16, + .sector_size = 32768, + .page_size = 256, + }, +/* .bank[1] = { */ + { + .probed = 0, + .pChip = NULL, + .pBank = NULL, + .bank_number = 1, + .base_address = FLASH_BANK1_BASE_512K_SD, + .controller_address = 0x400e0a00, + .flash_wait_states = 6, /* workaround silicon bug */ + .present = 1, + .size_bytes = 256 * 1024, + .nsectors = 16, + .sector_size = 32768, + .page_size = 256, + }, + }, + }, + { + .chipid_cidr = 0x299B0A60, + .name = "at91sam3sd8b", + .total_flash_size = 512 * 1024, + .total_sram_size = 64 * 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 = 6, /* workaround silicon bug */ + .present = 1, + .size_bytes = 256 * 1024, + .nsectors = 16, + .sector_size = 32768, + .page_size = 256, + }, +/* .bank[1] = { */ + { + .probed = 0, + .pChip = NULL, + .pBank = NULL, + .bank_number = 1, + .base_address = FLASH_BANK1_BASE_512K_SD, + .controller_address = 0x400e0a00, + .flash_wait_states = 6, /* workaround silicon bug */ + .present = 1, + .size_bytes = 256 * 1024, + .nsectors = 16, + .sector_size = 32768, + .page_size = 256, + }, + }, + }, + { + .chipid_cidr = 0x29ab0a60, + .name = "at91sam3sd8c", + .total_flash_size = 512 * 1024, + .total_sram_size = 64 * 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 = 6, /* workaround silicon bug */ + .present = 1, + .size_bytes = 256 * 1024, + .nsectors = 16, + .sector_size = 32768, + .page_size = 256, + }, +/* .bank[1] = { */ + { + .probed = 0, + .pChip = NULL, + .pBank = NULL, + .bank_number = 1, + .base_address = FLASH_BANK1_BASE_512K_SD, + .controller_address = 0x400e0a00, + .flash_wait_states = 6, /* workaround silicon bug */ + .present = 1, + .size_bytes = 256 * 1024, + .nsectors = 16, + .sector_size = 32768, + .page_size = 256, + }, + }, + }, { .chipid_cidr = 0x288A0760, .name = "at91sam3s2a", @@ -843,6 +979,102 @@ static const struct sam3_chip_details all_sam3_details[] = { }, }, }, + { + .chipid_cidr = 0x288B0A60, + .name = "at91sam3s8a", + .total_flash_size = 256 * 2048, + .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 = 6, /* workaround silicon bug */ + .present = 1, + .size_bytes = 256 * 2048, + .nsectors = 16, + .sector_size = 32768, + .page_size = 256, + }, +/* .bank[1] = { */ + { + .present = 0, + .probed = 0, + .bank_number = 1, + + }, + }, + }, + { + .chipid_cidr = 0x289B0A60, + .name = "at91sam3s8b", + .total_flash_size = 256 * 2048, + .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 = 6, /* workaround silicon bug */ + .present = 1, + .size_bytes = 256 * 2048, + .nsectors = 16, + .sector_size = 32768, + .page_size = 256, + }, +/* .bank[1] = { */ + { + .present = 0, + .probed = 0, + .bank_number = 1, + + }, + }, + }, + { + .chipid_cidr = 0x28AB0A60, + .name = "at91sam3s8c", + .total_flash_size = 256 * 2048, + .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 = 6, /* workaround silicon bug */ + .present = 1, + .size_bytes = 256 * 2048, + .nsectors = 16, + .sector_size = 32768, + .page_size = 256, + }, +/* .bank[1] = { */ + { + .present = 0, + .probed = 0, + .bank_number = 1, + + }, + }, + }, /* Start at91sam3n* series */ { @@ -1286,6 +1518,507 @@ static const struct sam3_chip_details all_sam3_details[] = { }, }, + { + .chipid_cidr = 0x29480360, + .name = "at91sam3n0b", + .total_flash_size = 32 * 1024, + .total_sram_size = 8 * 1024, + .n_gpnvms = 3, + .n_banks = 1, + +/* .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 = 32 * 1024, + .nsectors = 2, + .sector_size = 16384, + .page_size = 256, + }, + +/* .bank[1] = { */ + { + .present = 0, + .probed = 0, + .bank_number = 1, + }, + }, + }, + + { + .chipid_cidr = 0x29380360, + .name = "at91sam3n0a", + .total_flash_size = 32 * 1024, + .total_sram_size = 8 * 1024, + .n_gpnvms = 3, + .n_banks = 1, + +/* .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 = 32 * 1024, + .nsectors = 2, + .sector_size = 16384, + .page_size = 256, + }, + +/* .bank[1] = { */ + { + .present = 0, + .probed = 0, + .bank_number = 1, + }, + }, + }, + + { + .chipid_cidr = 0x29450260, + .name = "at91sam3n00b", + .total_flash_size = 16 * 1024, + .total_sram_size = 4 * 1024, + .n_gpnvms = 3, + .n_banks = 1, + +/* .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 = 16 * 1024, + .nsectors = 1, + .sector_size = 16384, + .page_size = 256, + }, + +/* .bank[1] = { */ + { + .present = 0, + .probed = 0, + .bank_number = 1, + }, + }, + }, + + { + .chipid_cidr = 0x29350260, + .name = "at91sam3n00a", + .total_flash_size = 16 * 1024, + .total_sram_size = 4 * 1024, + .n_gpnvms = 3, + .n_banks = 1, + +/* .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 = 16 * 1024, + .nsectors = 1, + .sector_size = 16384, + .page_size = 256, + }, + +/* .bank[1] = { */ + { + .present = 0, + .probed = 0, + .bank_number = 1, + }, + }, + }, + + + /* Start at91sam3a series*/ + /* 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 */ + + { + .chipid_cidr = 0x283E0A60, + .name = "at91sam3a8c", + .total_flash_size = 512 * 1024, + .total_sram_size = 96 * 1024, + .n_gpnvms = 3, + .n_banks = 2, + { +/* .bank[0] = { */ + { + .probed = 0, + .pChip = NULL, + .pBank = NULL, + .bank_number = 0, + .base_address = FLASH_BANK0_BASE_AX, + .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] = { */ + { + .probed = 0, + .pChip = NULL, + .pBank = NULL, + .bank_number = 1, + .base_address = FLASH_BANK1_BASE_512K_AX, + .controller_address = 0x400e0c00, + .flash_wait_states = 6, /* workaround silicon bug */ + .present = 1, + .size_bytes = 256 * 1024, + .nsectors = 16, + .sector_size = 16384, + .page_size = 256, + + }, + }, + }, + { + .chipid_cidr = 0x283B0960, + .name = "at91sam3a4c", + .total_flash_size = 256 * 1024, + .total_sram_size = 64 * 1024, + .n_gpnvms = 3, + .n_banks = 2, + { +/* .bank[0] = { */ + { + .probed = 0, + .pChip = NULL, + .pBank = NULL, + .bank_number = 0, + .base_address = FLASH_BANK0_BASE_AX, + .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] = { */ + { + .probed = 0, + .pChip = NULL, + .pBank = NULL, + .bank_number = 1, + .base_address = FLASH_BANK1_BASE_256K_AX, + .controller_address = 0x400e0c00, + .flash_wait_states = 6, /* workaround silicon bug */ + .present = 1, + .size_bytes = 128 * 1024, + .nsectors = 8, + .sector_size = 16384, + .page_size = 256, + + }, + }, + }, + + /* Start at91sam3x* series */ + /* 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 */ + /*at91sam3x8h - ES has an incorrect CIDR of 0x286E0A20*/ + { + .chipid_cidr = 0x286E0A20, + .name = "at91sam3x8h - ES", + .total_flash_size = 512 * 1024, + .total_sram_size = 96 * 1024, + .n_gpnvms = 3, + .n_banks = 2, + { +/* .bank[0] = { */ + { + .probed = 0, + .pChip = NULL, + .pBank = NULL, + .bank_number = 0, + .base_address = FLASH_BANK0_BASE_AX, + .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] = { */ + { + .probed = 0, + .pChip = NULL, + .pBank = NULL, + .bank_number = 1, + .base_address = FLASH_BANK1_BASE_512K_AX, + .controller_address = 0x400e0c00, + .flash_wait_states = 6, /* workaround silicon bug */ + .present = 1, + .size_bytes = 256 * 1024, + .nsectors = 16, + .sector_size = 16384, + .page_size = 256, + + }, + }, + }, + /*at91sam3x8h - ES2 and up uses the correct CIDR of 0x286E0A60*/ + { + .chipid_cidr = 0x286E0A60, + .name = "at91sam3x8h", + .total_flash_size = 512 * 1024, + .total_sram_size = 96 * 1024, + .n_gpnvms = 3, + .n_banks = 2, + { +/* .bank[0] = { */ + { + .probed = 0, + .pChip = NULL, + .pBank = NULL, + .bank_number = 0, + .base_address = FLASH_BANK0_BASE_AX, + .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] = { */ + { + .probed = 0, + .pChip = NULL, + .pBank = NULL, + .bank_number = 1, + .base_address = FLASH_BANK1_BASE_512K_AX, + .controller_address = 0x400e0c00, + .flash_wait_states = 6, /* workaround silicon bug */ + .present = 1, + .size_bytes = 256 * 1024, + .nsectors = 16, + .sector_size = 16384, + .page_size = 256, + + }, + }, + }, + { + .chipid_cidr = 0x285E0A60, + .name = "at91sam3x8e", + .total_flash_size = 512 * 1024, + .total_sram_size = 96 * 1024, + .n_gpnvms = 3, + .n_banks = 2, + { +/* .bank[0] = { */ + { + .probed = 0, + .pChip = NULL, + .pBank = NULL, + .bank_number = 0, + .base_address = FLASH_BANK0_BASE_AX, + .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] = { */ + { + .probed = 0, + .pChip = NULL, + .pBank = NULL, + .bank_number = 1, + .base_address = FLASH_BANK1_BASE_512K_AX, + .controller_address = 0x400e0c00, + .flash_wait_states = 6, /* workaround silicon bug */ + .present = 1, + .size_bytes = 256 * 1024, + .nsectors = 16, + .sector_size = 16384, + .page_size = 256, + + }, + }, + }, + { + .chipid_cidr = 0x284E0A60, + .name = "at91sam3x8c", + .total_flash_size = 512 * 1024, + .total_sram_size = 96 * 1024, + .n_gpnvms = 3, + .n_banks = 2, + { +/* .bank[0] = { */ + { + .probed = 0, + .pChip = NULL, + .pBank = NULL, + .bank_number = 0, + .base_address = FLASH_BANK0_BASE_AX, + .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] = { */ + { + .probed = 0, + .pChip = NULL, + .pBank = NULL, + .bank_number = 1, + .base_address = FLASH_BANK1_BASE_512K_AX , + .controller_address = 0x400e0c00, + .flash_wait_states = 6, /* workaround silicon bug */ + .present = 1, + .size_bytes = 256 * 1024, + .nsectors = 16, + .sector_size = 16384, + .page_size = 256, + + }, + }, + }, + { + .chipid_cidr = 0x285B0960, + .name = "at91sam3x4e", + .total_flash_size = 256 * 1024, + .total_sram_size = 64 * 1024, + .n_gpnvms = 3, + .n_banks = 2, + { +/* .bank[0] = { */ + { + .probed = 0, + .pChip = NULL, + .pBank = NULL, + .bank_number = 0, + .base_address = FLASH_BANK0_BASE_AX, + .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] = { */ + { + .probed = 0, + .pChip = NULL, + .pBank = NULL, + .bank_number = 1, + .base_address = FLASH_BANK1_BASE_256K_AX, + .controller_address = 0x400e0c00, + .flash_wait_states = 6, /* workaround silicon bug */ + .present = 1, + .size_bytes = 128 * 1024, + .nsectors = 8, + .sector_size = 16384, + .page_size = 256, + + }, + }, + }, + { + .chipid_cidr = 0x284B0960, + .name = "at91sam3x4c", + .total_flash_size = 256 * 1024, + .total_sram_size = 64 * 1024, + .n_gpnvms = 3, + .n_banks = 2, + { +/* .bank[0] = { */ + { + .probed = 0, + .pChip = NULL, + .pBank = NULL, + .bank_number = 0, + .base_address = FLASH_BANK0_BASE_AX, + .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] = { */ + { + .probed = 0, + .pChip = NULL, + .pBank = NULL, + .bank_number = 1, + .base_address = FLASH_BANK1_BASE_256K_AX, + .controller_address = 0x400e0c00, + .flash_wait_states = 6, /* workaround silicon bug */ + .present = 1, + .size_bytes = 128 * 1024, + .nsectors = 8, + .sector_size = 16384, + .page_size = 256, + + }, + }, + }, /* terminate */ { .chipid_cidr = 0, @@ -1737,7 +2470,7 @@ static uint32_t sam3_reg_fieldname(struct sam3_chip *pChip, } /* show the basics */ - LOG_USER_N("\t%*s: %*d [0x%0*x] ", + LOG_USER_N("\t%*s: %*" PRIu32 " [0x%0*" PRIx32 "] ", REG_NAME_WIDTH, regname, dwidth, v, hwidth, v); @@ -1962,10 +2695,10 @@ static void sam3_explain_ckgr_mcfr(struct sam3_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 sam3_explain_ckgr_plla(struct sam3_chip *pChip) @@ -1981,8 +2714,8 @@ static void sam3_explain_ckgr_plla(struct sam3_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)); } @@ -2125,8 +2858,9 @@ static const struct sam3_reg_list sam3_all_regs[] = { SAM3_ENTRY(PMC_SCSR, NULL), SAM3_ENTRY(PMC_SR, NULL), SAM3_ENTRY(CHIPID_CIDR, sam3_explain_chipid_cidr), + SAM3_ENTRY(CHIPID_CIDR2, sam3_explain_chipid_cidr), SAM3_ENTRY(CHIPID_EXID, NULL), - + SAM3_ENTRY(CHIPID_EXID2, NULL), /* TERMINATE THE LIST */ { .name = NULL } }; @@ -2134,7 +2868,7 @@ static const struct sam3_reg_list sam3_all_regs[] = { static struct sam3_bank_private *get_sam3_bank_private(struct flash_bank *bank) { - return (struct sam3_bank_private *)(bank->driver_priv); + return bank->driver_priv; } /** @@ -2195,14 +2929,32 @@ static int sam3_ReadAllRegs(struct sam3_chip *pChip) r = sam3_ReadThisReg(pChip, sam3_get_reg_ptr(&(pChip->cfg), pReg)); if (r != ERROR_OK) { - LOG_ERROR("Cannot read SAM3 registere: %s @ 0x%08x, Error: %d", + LOG_ERROR("Cannot read SAM3 register: %s @ 0x%08x, Error: %d", pReg->name, ((unsigned)(pReg->address)), r); return r; } - pReg++; } + /* Chip identification register + * + * Unfortunately, the chip identification register is not at + * a constant address across all of the SAM3 series'. As a + * consequence, a simple heuristic is used to find where it's + * at... + * + * If the contents at the first address is zero, then we know + * that the second address is where the chip id register is. + * We can deduce this because for those SAM's that have the + * chip id @ 0x400e0940, the first address, 0x400e0740, is + * located in the memory map of the Power Management Controller + * (PMC). Furthermore, the address is not used by the PMC. + * So when read, the memory controller returns zero.*/ + if (pChip->cfg.CHIPID_CIDR == 0) { + /*Put the correct CIDR and EXID values in the pChip structure */ + pChip->cfg.CHIPID_CIDR = pChip->cfg.CHIPID_CIDR2; + pChip->cfg.CHIPID_EXID = pChip->cfg.CHIPID_EXID2; + } return ERROR_OK; } @@ -2216,7 +2968,7 @@ static int sam3_GetInfo(struct sam3_chip *pChip) /* display all regs */ LOG_DEBUG("Start: %s", pReg->name); regval = *sam3_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, @@ -2232,7 +2984,7 @@ static int sam3_GetInfo(struct sam3_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], @@ -2330,36 +3082,37 @@ FLASH_BANK_COMMAND_HANDLER(sam3_flash_bank_command) default: LOG_ERROR("Address 0x%08x invalid bank address (try 0x%08x or 0x%08x " "[at91sam3u series] or 0x%08x [at91sam3s series] or " - "0x%08x [at91sam3n series])", + "0x%08x [at91sam3n series] or 0x%08x or 0x%08x or 0x%08x[at91sam3ax 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_N))); + ((unsigned int)(FLASH_BANK_BASE_N)), + ((unsigned int)(FLASH_BANK0_BASE_AX)), + ((unsigned int)(FLASH_BANK1_BASE_256K_AX)), + ((unsigned int)(FLASH_BANK1_BASE_512K_AX))); return ERROR_FAIL; break; - /* at91sam3u series */ + /* at91sam3s and at91sam3n series only has bank 0*/ + /* at91sam3u and at91sam3ax series has the same address for bank 0*/ + case FLASH_BANK_BASE_S: case FLASH_BANK0_BASE_U: 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 at91sam3u or at91sam3ax series */ case FLASH_BANK1_BASE_U: + case FLASH_BANK1_BASE_256K_AX: + case FLASH_BANK1_BASE_512K_AX: bank->driver_priv = &(pChip->details.bank[1]); bank->bank_number = 1; pChip->details.bank[1].pChip = pChip; pChip->details.bank[1].pBank = bank; break; - - /* at91sam3s and at91sam3n series */ - case FLASH_BANK_BASE_S: - bank->driver_priv = &(pChip->details.bank[0]); - bank->bank_number = 0; - pChip->details.bank[0].pChip = pChip; - pChip->details.bank[0].pBank = bank; - break; } /* we initialize after probing. */ @@ -2377,16 +3130,16 @@ static int sam3_GetDetails(struct sam3_bank_private *pPrivate) pDetails = all_sam3_details; while (pDetails->name) { /* Compare cidr without version bits */ - if (pDetails->chipid_cidr == (pPrivate->pChip->cfg.CHIPID_CIDR & 0xFFFFFFE0)) + if (((pDetails->chipid_cidr ^ pPrivate->pChip->cfg.CHIPID_CIDR) & 0xFFFFFFE0) == 0) break; else pDetails++; } if (pDetails->name == NULL) { - LOG_ERROR("SAM3 ChipID 0x%08x not found in table (perhaps you can this chip?)", + LOG_ERROR("SAM3 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("SAM3 CHIPID_CIDR: 0x%08x decodes as follows", + LOG_INFO("SAM3 CHIPID_CIDR: 0x%08" PRIx32 " decodes as follows", pPrivate->pChip->cfg.CHIPID_CIDR); sam3_explain_chipid_cidr(pPrivate->pChip); return ERROR_FAIL; @@ -2534,7 +3287,7 @@ static int sam3_erase(struct flash_bank *bank, int first, int last) LOG_DEBUG("Here"); return FLASHD_EraseEntireBank(pPrivate); } - LOG_INFO("sam3 auto-erases while programing (request ignored)"); + LOG_INFO("sam3 auto-erases while programming (request ignored)"); return ERROR_OK; } @@ -2563,23 +3316,13 @@ static int sam3_protect(struct flash_bank *bank, int set, int first, int last) } -static int sam3_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 sam3_page_read(struct sam3_bank_private *pPrivate, unsigned pagenum, uint8_t *buf) { uint32_t adr; int r; adr = pagenum * pPrivate->page_size; - adr += adr + pPrivate->base_address; + adr += pPrivate->base_address; r = target_read_memory(pPrivate->pChip->target, adr, @@ -2679,7 +3422,7 @@ static const uint8_t 0x00, 0xBE /* bkpt #0 */ }; -static int sam3_page_write(struct sam3_bank_private *pPrivate, unsigned pagenum, uint8_t *buf) +static int sam3_page_write(struct sam3_bank_private *pPrivate, unsigned pagenum, const uint8_t *buf) { uint32_t adr; uint32_t status; @@ -2687,7 +3430,7 @@ static int sam3_page_write(struct sam3_bank_private *pPrivate, unsigned pagenum, int r; adr = pagenum * pPrivate->page_size; - adr += (adr + pPrivate->base_address); + adr += pPrivate->base_address; /* Get flash mode register value */ r = target_read_u32(pPrivate->pChip->target, pPrivate->controller_address, &fmr); @@ -2738,7 +3481,7 @@ static int sam3_page_write(struct sam3_bank_private *pPrivate, unsigned pagenum, } static int sam3_write(struct flash_bank *bank, - uint8_t *buffer, + const uint8_t *buffer, uint32_t offset, uint32_t count) { @@ -2878,7 +3621,6 @@ static int sam3_write(struct flash_bank *bank, r = sam3_page_write(pPrivate, page_cur, pagebuffer); if (r != ERROR_OK) goto done; - buffer += count; } LOG_DEBUG("Done!"); r = ERROR_OK; @@ -3118,5 +3860,4 @@ struct flash_driver at91sam3_flash = { .auto_probe = sam3_auto_probe, .erase_check = sam3_erase_check, .protect_check = sam3_protect_check, - .info = sam3_info, };