⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 samflash.c

📁 openocd是比较好的调试工具软件,支持wiggle调试arm,也支持其他调试接口,例如USB口的FT2232.
💻 C
字号:
/*************************************************************************** *   Copyright (C) 2007 by Pavel Chromy                                    * *   chromy@asix.cz                                                        * *                                                                         * *   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     * *   (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.                          * *                                                                         * *   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.             * ***************************************************************************/#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;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -