/* at91sam4s series (has always one flash bank)*/
#define FLASH_BANK_BASE_S 0x00400000
+/* 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))
+
#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 at91sam4u4/2/1 data sheet table 19-2 */
+/* cmd6 is not present in the at91sam4u4/2/1 data sheet table 19-2 */
/* #define AT91C_EFC_FCMD_EPL (0x6) // (EFC) Erase plane? */
#define AT91C_EFC_FCMD_EPA (0x7) /* (EFC) Erase pages */
#define AT91C_EFC_FCMD_SLB (0x8) /* (EFC) Set Lock Bit */
/* so we can find the chip we belong to */
struct sam4_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;
struct sam4_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: "sam4_GetDetails() */
/* which copy/overwrites the */
}
/*The actual sector size of the SAM4S flash memory is 65536 bytes. 16 sectors for a 1024KB device*/
-/*The lockregions are 8KB per lock reqion, with a 1024KB device having 128 lock reqions. */
+/*The lockregions are 8KB per lock region, with a 1024KB device having 128 lock regions. */
/*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*/
},
},
},
+
+ /*at91sam4sd32c*/
+ {
+ .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 = 6, /* workaround silicon bug */
+ .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 = 6, /* workaround silicon bug */
+ .present = 1,
+ .size_bytes = 1024 * 1024,
+ .nsectors = 128,
+ .sector_size = 8192,
+ .page_size = 512,
+ },
+ },
+ },
+
/* terminate */
{
.chipid_cidr = 0,
break;
}
+ /* AT91C_EFC_FCMD_EPA
+ * According to the datasheet FARG[15:2] defines the page from which
+ * the erase will start.This page must be modulo 4, 8, 16 or 32
+ * according to the number of pages to erase. FARG[1:0] defines the
+ * number of pages to be erased. Previously (firstpage << 2) was used
+ * to conform to this, seems it should not be shifted...
+ */
return EFC_PerformCommand(pPrivate,
/* send Erase Page */
AT91C_EFC_FCMD_EPA,
- (firstPage << 2) | erasePages,
+ (firstPage) | erasePages,
status);
}
r = sam4_ReadThisReg(pChip,
sam4_get_reg_ptr(&(pChip->cfg), pReg));
if (r != ERROR_OK) {
- LOG_ERROR("Cannot read SAM4 registere: %s @ 0x%08x, Error: %d",
+ LOG_ERROR("Cannot read SAM4 register: %s @ 0x%08x, Error: %d",
pReg->name, ((unsigned)(pReg->address)), r);
return r;
}
switch (bank->base) {
default:
LOG_ERROR("Address 0x%08x invalid bank address (try 0x%08x"
- "[at91sam4s series] )",
- ((unsigned int)(bank->base)),
- ((unsigned int)(FLASH_BANK_BASE_S)));
+ "[at91sam4s series] )",
+ ((unsigned int)(bank->base)),
+ ((unsigned int)(FLASH_BANK_BASE_S)));
return ERROR_FAIL;
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:
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 */
+ case FLASH_BANK1_BASE_1024K_SD:
+ case FLASH_BANK1_BASE_2048K_SD:
+ 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. */
struct sam4_bank_private *pPrivate;
int r;
int i;
+ int pageCount;
+ /*16 pages equals 8KB - Same size as a lock region*/
+ pageCount = 16;
uint32_t status;
LOG_DEBUG("Here");
LOG_DEBUG("Here");
return FLASHD_EraseEntireBank(pPrivate);
}
- LOG_INFO("sam4 does not auto-erase while programing (Erasing relevant sectors)");
+ LOG_INFO("sam4 does not auto-erase while programming (Erasing relevant sectors)");
LOG_INFO("sam4 First: 0x%08x Last: 0x%08x", (unsigned int)(first), (unsigned int)(last));
for (i = first; i <= last; i++) {
/*16 pages equals 8KB - Same size as a lock region*/
- r = FLASHD_ErasePages(pPrivate, i, 16, &status);
+ r = FLASHD_ErasePages(pPrivate, (i * pageCount), pageCount, &status);
LOG_INFO("Erasing sector: 0x%08x", (unsigned int)(i));
if (r != ERROR_OK)
LOG_ERROR("SAM4: Error performing Erase page @ lock region number %d",
(unsigned int)(i));
if (status & (1 << 2)) {
- LOG_ERROR("SAM4: Lock Reqion %d is locked", (unsigned int)(i));
+ LOG_ERROR("SAM4: Lock Region %d is locked", (unsigned int)(i));
return ERROR_FAIL;
}
if (status & (1 << 1)) {