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

📄 asmi.c.svn-base

📁 u-boot for S3c2443 processor
💻 SVN-BASE
📖 第 1 页 / 共 2 页
字号:
/* * (C) Copyright 2003, Psyent Corporation <www.psyent.com> * Scott McNutt <smcnutt@psyent.com> * * See file CREDITS for list of people who contributed to this * project. * * 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 <common.h>#if defined(CONFIG_NIOS_ASMI)#include <command.h>#include <nios-io.h>#if !defined(CFG_NIOS_ASMIBASE)#error "*** CFG_NIOS_ASMIBASE not defined ***"#endif/*-----------------------------------------------------------------------*/#define SHORT_HELP\	"asmi    - read/write Cyclone ASMI configuration device.\n"#define LONG_HELP\	"\n"\	"asmi erase start [end]\n"\	"    - erase sector start or sectors start through end.\n"\	"asmi info\n"\	"    - display ASMI device information.\n"\	"asmi protect on | off\n"\	"    - turn device protection on or off.\n"\	"asmi read addr offset count\n"\	"    - read count bytes from offset to addr.\n"\	"asmi write addr offset count\n"\	"    - write count bytes to offset from addr.\n"\	"asmi verify addr offset count\n"\	"    - verify count bytes at offset from addr.\n"/*-----------------------------------------------------------------------*//* Operation codes for serial configuration devices */#define ASMI_WRITE_ENA		0x06	/* Write enable */#define ASMI_WRITE_DIS		0x04	/* Write disable */#define ASMI_READ_STAT		0x05	/* Read status */#define ASMI_READ_BYTES		0x03	/* Read bytes */#define ASMI_READ_ID		0xab	/* Read silicon id */#define ASMI_WRITE_STAT		0x01	/* Write status */#define ASMI_WRITE_BYTES	0x02	/* Write bytes */#define ASMI_ERASE_BULK		0xc7	/* Erase entire device */#define ASMI_ERASE_SECT		0xd8	/* Erase sector *//* Device status register bits */#define ASMI_STATUS_WIP		(1<<0)	/* Write in progress */#define ASMI_STATUS_WEL		(1<<1)	/* Write enable latch */static nios_asmi_t *asmi = (nios_asmi_t *)CFG_NIOS_ASMIBASE;/*********************************************************************** * Device access ***********************************************************************/static void asmi_cs (int assert){	if (assert) {		asmi->control |= NIOS_ASMI_SSO;	} else {		/* Let all bits shift out */		while ((asmi->status & NIOS_ASMI_TMT) == 0)			;		asmi->control &= ~NIOS_ASMI_SSO;	}}static void asmi_tx (unsigned char c){	while ((asmi->status & NIOS_ASMI_TRDY) == 0)		;	asmi->txdata = c;}static int asmi_rx (void){	while ((asmi->status & NIOS_ASMI_RRDY) == 0)		;	return (asmi->rxdata);}static unsigned char bitrev[] = {	0x00, 0x08, 0x04, 0x0c, 0x02, 0x0a, 0x06, 0x0e,	0x01, 0x09, 0x05, 0x0d, 0x03, 0x0b, 0x07, 0x0f};static unsigned char asmi_bitrev( unsigned char c ){	unsigned char val;	val  = bitrev[c>>4];	val |= bitrev[c & 0x0f]<<4;	return (val);}static void asmi_rcv (unsigned char *dst, int len){	while (len--) {		asmi_tx (0);		*dst++ = asmi_rx ();	}}static void asmi_rrcv (unsigned char *dst, int len){	while (len--) {		asmi_tx (0);		*dst++ = asmi_bitrev (asmi_rx ());	}}static void asmi_snd (unsigned char *src, int len){	while (len--) {		asmi_tx (*src++);		asmi_rx ();	}}static void asmi_rsnd (unsigned char *src, int len){	while (len--) {		asmi_tx (asmi_bitrev (*src++));		asmi_rx ();	}}static void asmi_wr_enable (void){	asmi_cs (1);	asmi_tx (ASMI_WRITE_ENA);	asmi_rx ();	asmi_cs (0);}static unsigned char asmi_status_rd (void){	unsigned char status;	asmi_cs (1);	asmi_tx (ASMI_READ_STAT);	asmi_rx ();	asmi_tx (0);	status = asmi_rx ();	asmi_cs (0);	return (status);}static void asmi_status_wr (unsigned char status){	asmi_wr_enable ();	asmi_cs (1);	asmi_tx (ASMI_WRITE_STAT);	asmi_rx ();	asmi_tx (status);	asmi_rx ();	asmi_cs (0);	return;}/*********************************************************************** * Device information ***********************************************************************/typedef struct asmi_devinfo_t {	const char 	*name;		/* Device name */	unsigned char	id;		/* Device silicon id */	unsigned char	size;		/* Total size log2(bytes)*/	unsigned char	num_sects;	/* Number of sectors */	unsigned char	sz_sect;	/* Sector size log2(bytes) */	unsigned char	sz_page;	/* Page size log2(bytes) */	unsigned char   prot_mask;	/* Protection mask */}asmi_devinfo_t;static struct asmi_devinfo_t devinfo[] = {	{ "EPCS1 ", 0x10, 17, 4, 15, 8, 0x0c },	{ "EPCS4 ", 0x12, 19, 8, 16, 8, 0x1c },	{ 0, 0, 0, 0, 0, 0 }};static asmi_devinfo_t *asmi_dev_find (void){	unsigned char buf[4];	unsigned char id;	int i;	struct asmi_devinfo_t *dev = NULL;	/* Read silicon id requires 3 "dummy bytes" before it's put	 * on the wire.	 */	buf[0] = ASMI_READ_ID;	buf[1] = 0;	buf[2] = 0;	buf[3] = 0;	asmi_cs (1);	asmi_snd (buf,4);	asmi_rcv (buf,1);	asmi_cs (0);	id = buf[0];	/* Find the info struct */	i = 0;	while (devinfo[i].name) {		if (id == devinfo[i].id) {			dev = &devinfo[i];			break;		}		i++;	}	return (dev);}/*********************************************************************** * Misc Utilities ***********************************************************************/static unsigned asmi_cfgsz (void){	unsigned sz = 0;	unsigned char buf[128];	unsigned char *p;	/* Read in the first 128 bytes of the device */	buf[0] = ASMI_READ_BYTES;	buf[1] = 0;	buf[2] = 0;	buf[3] = 0;	asmi_cs (1);	asmi_snd (buf,4);	asmi_rrcv (buf, sizeof(buf));	asmi_cs (0);	/* Search for the starting 0x6a which is followed by the	 * 4-byte 'register' and 4-byte bit-count.	 */	p = buf;	while (p < buf + sizeof(buf)-8) {		if ( *p == 0x6a ) {			/* Point to bit count and extract */			p += 5;			sz = *p++;			sz |= *p++ << 8;			sz |= *p++ << 16;			sz |= *p++ << 24;			/* Convert to byte count */			sz += 7;			sz >>= 3;		} else if (*p == 0xff) {			/* 0xff is ok ... just skip */			p++;			continue;		} else {			/* Not 0xff or 0x6a ... something's not			 * right ... report 'unknown' (sz=0).			 */			break;		}	}	return (sz);}static int asmi_erase (unsigned start, unsigned end){	unsigned off, sectsz;	unsigned char buf[4];	struct asmi_devinfo_t *dev = asmi_dev_find ();	if (!dev || (start>end))		return (-1);	/* Erase the requested sectors. An address is required	 * that lies within the requested sector -- we'll just	 * use the first address in the sector.	 */	printf ("asmi erasing sector %d ", start);	if (start != end)		printf ("to %d ", end);	sectsz = (1 << dev->sz_sect);	while (start <= end) {		off = start * sectsz;		start++;		buf[0] = ASMI_ERASE_SECT;		buf[1] = off >> 16;		buf[2] = off >> 8;		buf[3] = off;		asmi_wr_enable ();		asmi_cs (1);		asmi_snd (buf,4);		asmi_cs (0);		printf ("."); /* Some user feedback */		/* Wait for erase to complete */		while (asmi_status_rd() & ASMI_STATUS_WIP)			;	}	printf (" done.\n");	return (0);}static int asmi_read (ulong addr, ulong off, ulong cnt){	unsigned char buf[4];	buf[0] = ASMI_READ_BYTES;	buf[1] = off >> 16;	buf[2] = off >> 8;	buf[3] = off;	asmi_cs (1);	asmi_snd (buf,4);	asmi_rrcv ((unsigned char *)addr, cnt);	asmi_cs (0);	return (0);}staticint asmi_write (ulong addr, ulong off, ulong cnt){	ulong wrcnt;	unsigned pgsz;	unsigned char buf[4];	struct asmi_devinfo_t *dev = asmi_dev_find ();

⌨️ 快捷键说明

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