X-Git-Url: https://review.openocd.org/gitweb?a=blobdiff_plain;f=src%2Fflash%2Fnor%2Fat91sam4.c;h=1ba39109efcd7cac3a10677ad95fa8d8aaf3bd7a;hb=b3d4a44686c8ed14baab7c466f14321b2dc5fec8;hp=4bc511c2aa6e8b6bccbbcfb75cda0de631bdc1d4;hpb=d1cd97777b9f271698cc0efdaec16aca9ce42449;p=openocd.git diff --git a/src/flash/nor/at91sam4.c b/src/flash/nor/at91sam4.c index 4bc511c2aa..1ba39109ef 100644 --- a/src/flash/nor/at91sam4.c +++ b/src/flash/nor/at91sam4.c @@ -21,7 +21,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 @@ -70,14 +70,20 @@ /* 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 */ @@ -166,7 +172,7 @@ struct sam4_bank_private { /* 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; @@ -182,7 +188,7 @@ struct sam4_bank_private { 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 */ @@ -248,7 +254,7 @@ static struct sam4_chip *get_current_sam4(struct command_context *cmd_ctx) } /*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*/ @@ -453,6 +459,51 @@ static const struct sam4_chip_details all_sam4_details[] = { }, }, }, + + /*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, @@ -722,10 +773,17 @@ static int FLASHD_ErasePages(struct sam4_bank_private *pPrivate, 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); } @@ -849,9 +907,9 @@ static int FLASHD_GetLockBits(struct sam4_bank_private *pPrivate, uint32_t *v) LOG_DEBUG("Here"); r = EFC_PerformCommand(pPrivate, AT91C_EFC_FCMD_GLB, 0, NULL); if (r == ERROR_OK) { - r = EFC_GetResult(pPrivate, v); - r = EFC_GetResult(pPrivate, v); - r = EFC_GetResult(pPrivate, v); + EFC_GetResult(pPrivate, v); + EFC_GetResult(pPrivate, v); + EFC_GetResult(pPrivate, v); r = EFC_GetResult(pPrivate, v); } LOG_DEBUG("End: %d", r); @@ -1401,7 +1459,7 @@ static int sam4_ReadAllRegs(struct sam4_chip *pChip) 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; } @@ -1512,19 +1570,29 @@ FLASH_BANK_COMMAND_HANDLER(sam4_flash_bank_command) 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. */ @@ -1678,6 +1746,9 @@ static int sam4_erase(struct flash_bank *bank, int first, int last) 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"); @@ -1701,17 +1772,17 @@ static int sam4_erase(struct flash_bank *bank, int first, int last) 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)) { @@ -2066,7 +2137,6 @@ static int sam4_write(struct flash_bank *bank, r = sam4_page_write(pPrivate, page_cur, pagebuffer); if (r != ERROR_OK) goto done; - buffer += count; } LOG_DEBUG("Done!"); r = ERROR_OK;