1
0
mirror of https://git.code.sf.net/p/openocd/code synced 2024-11-22 17:46:26 +00:00
openocd/contrib/loaders/flash/at91sam7x/samflash.c
Antonio Borneo 382148e4dd openocd: fix SPDX tag format for files .c
With the old checkpatch we cannot use the correct format for the
SPDX tags in the file .c, in fact the C99 comments are not allowed
and we had to use the block comment.

With the new checkpatch, let's switch to the correct SPDX format.

Change created automatically through the command:
	sed -i \
	's,^/\* *\(SPDX-License-Identifier: .*[^ ]\) *\*/$,// \1,' \
	$(find src/ contrib/ -name \*.c)

Change-Id: I6da16506baa7af718947562505dd49606d124171
Signed-off-by: Antonio Borneo <borneo.antonio@gmail.com>
Reviewed-on: https://review.openocd.org/c/openocd/+/7153
Tested-by: jenkins
2022-09-18 08:22:01 +00:00

184 lines
4.3 KiB
C

// SPDX-License-Identifier: GPL-2.0-or-later
/***************************************************************************
* Copyright (C) 2007 by Pavel Chromy *
* chromy@asix.cz *
***************************************************************************/
#include "samflash.h"
unsigned int flash_page_count = 1024;
unsigned int flash_page_size = 256;
/* pages per lock bit */
unsigned int flash_lock_pages = 1024/16;
/* detect chip and set loader parameters */
int flash_init(void)
{
unsigned int nvpsiz;
nvpsiz = (inr(DBGU_CIDR) >> 8)&0xf;
switch (nvpsiz) {
case 3:
/* AT91SAM7x32 */
flash_page_count = 256;
flash_page_size = 128;
flash_lock_pages = 256/8;
break;
case 5:
/* AT91SAM7x64 */
flash_page_count = 512;
flash_page_size = 128;
flash_lock_pages = 512/16;
break;
case 7:
/* AT91SAM7x128*/
flash_page_count = 512;
flash_page_size = 256;
flash_lock_pages = 512/8;
break;
case 9:
/* AT91SAM7x256 */
flash_page_count = 1024;
flash_page_size = 256;
flash_lock_pages = 1024/16;
break;
case 10:
/* AT91SAM7x512 */
flash_page_count = 2048;
flash_page_size = 256;
flash_lock_pages = 2048/32;
break;
default:
return FLASH_STAT_INITE;
}
return FLASH_STAT_OK;
}
/* program single flash page */
int flash_page_program(uint32 *data, int page_num)
{
int i;
int efc_ofs;
uint32 *flash_ptr;
uint32 *data_ptr;
/* select proper controller */
if (page_num >= 1024) efc_ofs = 0x10;
else efc_ofs = 0;
/* wait until FLASH is ready, just for sure */
while ((inr(MC_FSR + efc_ofs)&MC_FRDY) == 0);
/* calculate page address, only lower 8 bits are used to address the latch,
but the upper part of address is needed for writing to proper EFC */
flash_ptr = (uint32 *)(FLASH_AREA_ADDR + (page_num*flash_page_size));
data_ptr = data;
/* copy data to latch */
for (i = flash_page_size/4; i; i--) {
/* we do not use memcpy to be sure that only 32 bit access is used */
*(flash_ptr++)=*(data_ptr++);
}
/* page number and page write command to FCR */
outr(MC_FCR + efc_ofs, ((page_num&0x3ff) << 8) | MC_KEY | MC_FCMD_WP);
/* wait until it's done */
while ((inr(MC_FSR + efc_ofs)&MC_FRDY) == 0);
/* check for errors */
if ((inr(MC_FSR + efc_ofs)&MC_PROGE)) return FLASH_STAT_PROGE;
if ((inr(MC_FSR + efc_ofs)&MC_LOCKE)) return FLASH_STAT_LOCKE;
#if 0
/* verify written data */
flash_ptr = (uint32 *)(FLASH_AREA_ADDR + (page_num*flash_page_size));
data_ptr = data;
for (i = flash_page_size/4; i; i--) {
if (*(flash_ptr++)!=*(data_ptr++)) return FLASH_STAT_VERIFE;
}
#endif
return FLASH_STAT_OK;
}
int flash_erase_plane(int efc_ofs)
{
unsigned int lockbits;
int page_num;
page_num = 0;
lockbits = inr(MC_FSR + efc_ofs) >> 16;
while (lockbits) {
if (lockbits&1) {
/* wait until FLASH is ready, just for sure */
while ((inr(MC_FSR + efc_ofs)&MC_FRDY) == 0);
outr(MC_FCR + efc_ofs, ((page_num&0x3ff) << 8) | 0x5a000004);
/* wait until it's done */
while ((inr(MC_FSR + efc_ofs)&MC_FRDY) == 0);
/* check for errors */
if ((inr(MC_FSR + efc_ofs)&MC_PROGE)) return FLASH_STAT_PROGE;
if ((inr(MC_FSR + efc_ofs)&MC_LOCKE)) return FLASH_STAT_LOCKE;
}
if ((page_num += flash_lock_pages) > flash_page_count) break;
lockbits>>=1;
}
/* wait until FLASH is ready, just for sure */
while ((inr(MC_FSR + efc_ofs)&MC_FRDY) == 0);
/* erase all command to FCR */
outr(MC_FCR + efc_ofs, 0x5a000008);
/* wait until it's done */
while ((inr(MC_FSR + efc_ofs)&MC_FRDY) == 0);
/* check for errors */
if ((inr(MC_FSR + efc_ofs)&MC_PROGE)) return FLASH_STAT_PROGE;
if ((inr(MC_FSR + efc_ofs)&MC_LOCKE)) return FLASH_STAT_LOCKE;
/* set no erase before programming */
outr(MC_FMR + efc_ofs, inr(MC_FMR + efc_ofs) | 0x80);
return FLASH_STAT_OK;
}
/* erase whole chip */
int flash_erase_all(void)
{
int result;
if ((result = flash_erase_plane(0)) != FLASH_STAT_OK) return result;
/* the second flash controller, if any */
if (flash_page_count > 1024) result = flash_erase_plane(0x10);
return result;
}
int flash_verify(uint32 adr, unsigned int len, uint8 *src)
{
unsigned char *flash_ptr;
flash_ptr = (uint8 *)FLASH_AREA_ADDR + adr;
for (;len; len--) {
if (*(flash_ptr++)!=*(src++)) return FLASH_STAT_VERIFE;
}
return FLASH_STAT_OK;
}