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

📄 i557_eep.c

📁 基于ecos的redboot
💻 C
📖 第 1 页 / 共 2 页
字号:
//=============================================================================
//
//      i557_eep.c - Cyclone Diagnostics
//
//=============================================================================
//####COPYRIGHTBEGIN####
//                                                                          
// -------------------------------------------                              
// The contents of this file are subject to the Red Hat eCos Public License 
// Version 1.1 (the "License"); you may not use this file except in         
// compliance with the License.  You may obtain a copy of the License at    
// http://www.redhat.com/                                                   
//                                                                          
// Software distributed under the License is distributed on an "AS IS"      
// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.  See the 
// License for the specific language governing rights and limitations under 
// the License.                                                             
//                                                                          
// The Original Code is eCos - Embedded Configurable Operating System,      
// released September 30, 1998.                                             
//                                                                          
// The Initial Developer of the Original Code is Red Hat.                   
// Portions created by Red Hat are                                          
// Copyright (C) 2001 Red Hat, Inc.                             
// All Rights Reserved.                                                     
// -------------------------------------------                              
//                                                                          
//####COPYRIGHTEND####
//=============================================================================
//#####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 */

    /* Select the serial EEPROM */
    SELECT_557_EEP(pci_base);

⌨️ 快捷键说明

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