📄 i557_eep.c
字号:
//=============================================================================//// 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 + -