* (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 <http://www.gnu.org/licenses/>. *
****************************************************************************/
/* Some of the the lower level code was based on code supplied by
#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
/* 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 */
#define AT91C_EFC_FCMD_WPL (0x2) /* (EFC) Write Page and Lock */
/* these are used to *initialize* the "pChip->details" structure. */
static const struct sam4_chip_details all_sam4_details[] = {
- /* Start at91sam4s* series */
- /*atsam4s16c - LQFP100/BGA100*/
+ /* Start at91sam4c* series */
+ /* at91sam4c32e - LQFP144 */
{
- .chipid_cidr = 0x28AC0CE0,
- .name = "at91sam4s16c",
+ .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,
.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,
+ .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 = 0x289C0AE0,
+ .name = "at91sam4s8b",
+ .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,
+
+ },
+ },
+ },
+ /*atsam4s8a - LQFP48/BGA48*/
+ {
+ .chipid_cidr = 0x288C0AE0,
+ .name = "at91sam4s8a",
+ .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,
+
+ },
+ },
+ },
+
+ /*atsam4s4c - LQFP100/BGA100*/
+ {
+ .chipid_cidr = 0x28ab09e0,
+ .name = "at91sam4s4c",
+ .total_flash_size = 256 * 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 = 1024 * 1024,
- .nsectors = 128,
+ .size_bytes = 256 * 1024,
+ .nsectors = 32,
.sector_size = 8192,
.page_size = 512,
},
},
},
},
- /*atsam4s16b - LQFP64/QFN64*/
+
+ /*atsam4s4b - LQFP64/QFN64/WLCSP64*/
{
- .chipid_cidr = 0x289C0CE0,
- .name = "at91sam4s16b",
- .total_flash_size = 1024 * 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,
{
.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,
},
},
},
},
- /*atsam4s16a - LQFP48/QFN48*/
+
+ /*atsam4s4a - LQFP48/QFN48*/
{
- .chipid_cidr = 0x288C0CE0,
- .name = "at91sam4s16a",
- .total_flash_size = 1024 * 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,
{
.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,
},
},
},
},
- /*atsam4s8c - LQFP100/BGA100*/
+
+ /*atsam4s2c - LQFP100/BGA100*/
{
- .chipid_cidr = 0x28AC0AE0,
- .name = "at91sam4s8c",
- .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,
{
.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,
},
},
},
},
- /*atsam4s8b - LQFP64/BGA64*/
+
+ /*atsam4s2b - LQPF64/QFN64/WLCSP64*/
{
- .chipid_cidr = 0x289C0AE0,
- .name = "at91sam4s8b",
- .total_flash_size = 512 * 1024,
- .total_sram_size = 128 * 1024,
+ .chipid_cidr = 0x289b07e0,
+ .name = "at91sam4s2b",
+ .total_flash_size = 128 * 1024,
+ .total_sram_size = 64 * 1024,
.n_gpnvms = 2,
.n_banks = 1,
{
.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,
},
},
},
},
- /*atsam4s8a - LQFP48/BGA48*/
+
+ /*atsam4s2a - LQFP48/QFN48*/
{
- .chipid_cidr = 0x288C0AE0,
- .name = "at91sam4s8a",
- .total_flash_size = 512 * 1024,
- .total_sram_size = 128 * 1024,
+ .chipid_cidr = 0x288b07e0,
+ .name = "at91sam4s2a",
+ .total_flash_size = 128 * 1024,
+ .total_sram_size = 64 * 1024,
.n_gpnvms = 2,
.n_banks = 1,
{
.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,
},
},
},
- /*at91sam4sd32c*/
+ /*at91sam4sd32c - LQFP100/BGA100*/
{
.chipid_cidr = 0x29a70ee0,
.name = "at91sam4sd32c",
.bank_number = 0,
.base_address = FLASH_BANK0_BASE_SD,
.controller_address = 0x400e0a00,
- .flash_wait_states = 6, /* workaround silicon bug */
+ .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,
.bank_number = 1,
.base_address = FLASH_BANK1_BASE_2048K_SD,
.controller_address = 0x400e0c00,
- .flash_wait_states = 6, /* workaround silicon bug */
+ .flash_wait_states = 5,
.present = 1,
.size_bytes = 1024 * 1024,
.nsectors = 128,
},
},
+ /*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,
int r;
uint32_t v;
- long long ms_now, ms_end;
+ int64_t ms_now, ms_end;
/* default */
if (status)
}
/* 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);
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 */
"64K bytes", /* 5 */
_unknown, /* 6 */
"128K bytes", /* 7 */
- _unknown, /* 8 */
+ "160K bytes", /* 8 */
"256K bytes", /* 9 */
"512K bytes", /* 10 */
_unknown, /* 11 */
{ 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" },
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)
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));
}
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;
}
/**
{
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,
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],
/* 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 series */
+ /* 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;
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;
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_INFO("SAM4 Found chip %s, CIDR 0x%08x", pDetails->name, pDetails->chipid_cidr);
}
/* DANGER: THERE ARE DRAGONS HERE */
return ERROR_OK;
}
-static int _sam4_probe(struct flash_bank *bank, int noise)
+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;
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_INFO("SAM4 Set flash bank to %08X - %08X, idx %d", bank->base, bank->base + bank->size, x);
break;
}
}
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)
}
-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;
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 <stdint.h> */
-/* */
-/* 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_page_write(struct sam4_bank_private *pPrivate, unsigned pagenum, const uint8_t *buf)
{
uint32_t adr;
uint32_t status;
}
static int sam4_write(struct flash_bank *bank,
- uint8_t *buffer,
+ const uint8_t *buffer,
uint32_t offset,
uint32_t count)
{
.auto_probe = sam4_auto_probe,
.erase_check = default_flash_blank_check,
.protect_check = sam4_protect_check,
- .info = sam4_info,
+ .free_driver_priv = sam4_free_driver_priv,
};