i557_eep.c

来自「eCos操作系统源码」· C语言 代码 · 共 551 行 · 第 1/2 页

C
551
字号
//=============================================================================////      i557_eep.c - Cyclone Diagnostics////=============================================================================//####ECOSGPLCOPYRIGHTBEGIN####// -------------------------------------------// This file is part of eCos, the Embedded Configurable Operating System.// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.//// eCos 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 or (at your option) any later version.//// eCos 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 eCos; if not, write to the Free Software Foundation, Inc.,// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.//// As a special exception, if other files instantiate templates or use macros// or inline functions from this file, or you compile this file and link it// with other works to produce a work based on this file, this file does not// by itself cause the resulting work to be covered by the GNU General Public// License. However the source code for this file must still be made available// in accordance with section (3) of the GNU General Public License.//// This exception does not invalidate any other reasons why a work based on// this file might be covered by the GNU General Public License.//// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.// at http://sources.redhat.com/ecos/ecos-license/// -------------------------------------------//####ECOSGPLCOPYRIGHTEND####//=============================================================================//#####DESCRIPTIONBEGIN####//// Author(s):   Scott Coulter, Jeff Frazier, Eric Breeden// Contributors:// Date:        2001-01-25// Purpose:     // Description: ////####DESCRIPTIONEND####////===========================================================================*/#include "i557_eep.h"/******************************************************************************* Serial EEPROM Access code for the i557/558** Revision History:* -----------------** * 05jun98, snc Added setup time for eeprom CS.  Changed eeprom_delay to use the*			   processor's internal timer.  Fixed programming algorithm to poll*			   the eeprom's DO line to look for the transition from BUSY to READY*			   which indicates that the programming operation has completed.* 03jun98, snc Added setup time delay on data writes (delay before asserting*			   a rising edge on the SK.  Fixed eeprom_get_word() to explicitly*			   clear a bit position in the buffer after reading a low on the *			   data lines.* 23oct96, snc Ported to the PCI914**//* * Timing information.  According to the National Semiconductor manual, * the SK High Minimum time = SK Low Minimum time = 250 nsec.  However, * the minimum SK cycle time is 1 usec, so a 250 nsec high/750 nsec. low * sequence or equivalent would be required. *//* Serial clock line */#define SK_LOW_PERIOD		500	/* nsec, Time serial clock is low */#define SK_HIGH_PERIOD		500	/* nsec, Time serial clock is high *//* Serial data line */#define DATA_IN_HOLD_TIME	20	/* nsec, SK low to EEDI change */#define DATA_IN_SETUP_TIME	100	/* nsec, EEDI change to SK high *//* Serial clock and data line states (assumes ports are non-inverting) */#define HIGH			1#define LOW			0/* Select setup time to rising edge of SK */#define SELECT_SETUP_TIME	50	/* nsec *//* De-select time between consecutive commands */#define DESELECT_TIME		100	/* nsec *//* local functions */static void set_sda_line (unsigned long pci_base,	/* PCI Base address */			  int state);			/* HIGH or LOW */static int get_sda_line (unsigned long pci_base);	/* PCI Base address */static void set_scl_line (unsigned long pci_base,	/* PCI Base address */			  int state);			/* HIGH or LOW */void eeprom_delay (int nsec);static int eeprom_send_start (unsigned long pci_base, int command);static int eeprom_send_addr (unsigned long pci_base,			     unsigned char eeprom_addr);static int eeprom_get_word (unsigned long pci_base,			    unsigned short *word_addr);static int eeprom_put_word (unsigned long pci_base,			    unsigned short data);static int eeprom_write_enable(unsigned long pci_base);static int eeprom_write_disable(unsigned long pci_base);/* global variables */int powerup_wait_done = 0;		/* set true after power-up wait done *//*------------------------------------------------------------- * Function:	int eeprom_read () * * Action:	Read data from the eeprom, place it at p_data * * Returns:	OK if read worked, EEPROM_NOT_RESPONDING if *		read fails. *-------------------------------------------------------------*/int eeprom_read (unsigned long pci_base,/* PCI Base address */		 int eeprom_addr,	/* word offset from start of eeprom */		 unsigned short *p_data,/* where to put data in memory */		 int nwords		/* number of 16bit words to read */		 ){    int status;		/* result code */    int i;		/* loop variable */    /*     * Make sure caller isn't requesting a read beyond the end of the      * eeprom.     */    if ((eeprom_addr + nwords) > EEPROM_WORD_SIZE)	return (EEPROM_TO_SMALL);    /* Read in desired number of words */    for (i = 0; i < nwords; i++, eeprom_addr++) {     	/* Select the serial EEPROM */    	SELECT_557_EEP(pci_base);	/* Wait CS setup time */	eeprom_delay (SELECT_SETUP_TIME);    	/* Send start/read command to begin the read */    	if (((status = eeprom_send_start (pci_base, EEPROM_READ)) != OK) ||    	/* Send address */	    ((status = eeprom_send_addr (pci_base, eeprom_addr)) != OK))	    return (status);	if ((status = eeprom_get_word (pci_base, p_data++)) != OK)	    return (status);    	/* De-Select the serial EEPROM */    	DESELECT_557_EEP(pci_base);	/* wait the required de-select time between commands */	eeprom_delay (DESELECT_TIME);    }    return (OK);}/*------------------------------------------------------------- * Function:	int eeprom_write () * * Action:	Write data from p_data to the eeprom * * Returns:	OK if write worked, EEPROM_NOT_RESPONDING if *		write failed. *-------------------------------------------------------------*/int eeprom_write (unsigned long pci_base,/* PCI Base address */		 int eeprom_addr,	/* word offset from start of eeprom */		 unsigned short *p_data,/* data source in memory */		 int nwords		/* number of 16bit words to read */		 ){    int status;			/* result code */    int i;			/* loop variable */    int check_cntr;    unsigned short data;    /*     * Make sure caller isn't requesting a read beyond the end of the      * eeprom.     */    if ((eeprom_addr + nwords) > EEPROM_WORD_SIZE)	return (EEPROM_TO_SMALL);        /* enable eeprom writes */    if ((status = eeprom_write_enable(pci_base)) != OK)	return(status);    /* Read in desired number of words */    for (i = 0; i < nwords; i++, eeprom_addr++) {     	/* Select the serial EEPROM */    	SELECT_557_EEP(pci_base);	/* Wait CS setup time */	eeprom_delay (SELECT_SETUP_TIME);    	/* Send start/write command to begin the read */    	if (((status = eeprom_send_start (pci_base, EEPROM_WRITE)) != OK) ||    	/* Send address */	    ((status = eeprom_send_addr (pci_base, eeprom_addr)) != OK))	    return (status);	data = *p_data++;	if ((status = eeprom_put_word (pci_base, data)) != OK)	    return (status);    	/* De-Select the serial EEPROM */    	DESELECT_557_EEP(pci_base);	/* wait the required de-select time between commands */	eeprom_delay (DESELECT_TIME);	/* Re-Select the serial EEPROM */    	SELECT_557_EEP(pci_base);	/* now that the write command/data have been clocked into the EEPROM	   we must wait for the BUSY indicator (DO driven low) to indicate	   READY (DO driven high) */	check_cntr = 0;	while (1) {	    check_cntr++;	    if (get_sda_line (pci_base) == HIGH) break;		/* programming complete */	    if (check_cntr > 100000) {						/* timeout */		/* De-Select the serial EEPROM */		DESELECT_557_EEP(pci_base);		/* wait the required de-select time between commands */		eeprom_delay (DESELECT_TIME);		return (EEPROM_ERROR);	    }	}	/* De-Select the serial EEPROM */    	DESELECT_557_EEP(pci_base);	/* wait the required de-select time between commands */	eeprom_delay (DESELECT_TIME);    }    /* disable eeprom writes */    if ((status = eeprom_write_disable(pci_base)) != OK)	return(status);    return (OK);}/*------------------------------------------------------------- * Function:	int eeprom_write_enable () * * Action:	Enable writes to the eeprom * * Returns:	OK if command sent, EEPROM_NOT_RESPONDING if not. * *-------------------------------------------------------------*/int eeprom_write_enable (unsigned long pci_base){    int status;				/* result code */

⌨️ 快捷键说明

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