www.pudn.com > tyShow.rar > sysSpiNvRam.c


/* sysSpiNvRam.c - SPI interface to serial EEPROM library */ 
  
 /* Copyright 1984-1996 Wind River Systems, Inc. */ 
 #include "copyright_wrs.h" 
  
 /* 
 modification history 
 -------------------- 
 */ 
  
 /* 
 DESCRIPTION 
 This library contains routines to manipulate non-volatile RAM (NV-RAM) 
 which is accessed as a Serial Peripheral Interface (SPI).  Read and write 
 routines are included. 
  
 The macro NV_RAM_SIZE must be defined to provide parameter checking 
 for sysNvRamSet() and sysNvRamGet().  The macro NV_BOOT_OFFSET must be 
 defined and point to an offset that allows enough room for 256 bytes. 
  
 This library provides processor specific routines. 
  
 SEE ALSO: 
 .pG "Configuration" */ 
  
  
 /* includes */ 
  
 #include "vxWorks.h" 
 #include "vme.h" 
 #include "memLib.h" 
 #include "cacheLib.h" 
 #include "sysLib.h" 
 #include "config.h" 
 #include "string.h" 
 #include "intLib.h" 
 #include "logLib.h" 
 #include "stdio.h" 
 #include "taskLib.h" 
 #include "vxLib.h" 
 #include "arch/ppc/vxPpcLib.h" 
 #include "drv/sio/ppc860Sio.h" 
 #include "drv/multi/ppc860Siu.h" 
 #include "yourBsp.h" /* e.g. ads860.h */ 
  
 /* Definitions for SPI. */ 
 #define SPI_RX_BD_BASE	0x480 
 #define SPI_TX_BD_BASE	0x488 
  
 #define SPI_TX_BUF_SZ	0x100 
 #define SPI_RX_BUF_SZ	0x100 
 #define SPI_TRANS_RX_BD_LAST	0x0800		/* last in frame */ 
 #define SPI_TRANS_RX_BD_WRAP    0x2000		/* wrap back to first BD */ 
 #define SPI_TRANS_RX_BD_EMPTY	0x8000		/* buffer is empty */ 
 #define SPI_TRANS_TX_BD_LAST	0x0800		/* last in frame */ 
 #define SPI_TRANS_TX_BD_WRAP	0x2000		/* wrap back to first BD */ 
 #define SPI_TRANS_TX_BD_READY	0x8000		/* ready for Tx */ 
  
 #define SPI_INTERFACE_PINS	0x0000E 
 #define EnSPI	0x0F77 
 #define DisSPI	0x0E77 
 #define SPI_STR	0x80 
  
 #define SPI_SERIAL_EEPROM_SZ  NV_RAM_SIZE  /* bytes */ 
 #define SPI_SERIAL_CMD_SEQ_SZ 3 
  
 LOCAL UCHAR	eep_wt_scratch[(SPI_SERIAL_EEPROM_SZ + SPI_SERIAL_CMD_SEQ_SZ)]; 
 LOCAL UCHAR*	eep_wt_ptr; 
  
 LOCAL UCHAR	spiTxBuf[SPI_TX_BUF_SZ]; 
 LOCAL UCHAR	spiRxBuf[SPI_RX_BUF_SZ]; 
  
 typedef struct          /* SPI_BUF */ 
 { 
   VUINT16 statusMode;     /* status and control */ 
   VUINT16 dataLength;     /* length of data buffer in bytes */ 
   u_char *    dataPointer;        /* points to data buffer */ 
 } SPI_BD; 
   
 typedef struct          /* SPI_PARAM */ 
 { 
   VUINT16 rbase;          /* Rx buffer descriptor base address */ 
   VUINT16 tbase;          /* Tx buffer descriptor base address */ 
   VUINT8  rfcr;           /* Rx function code */ 
   VUINT8  tfcr;           /* Tx function code */ 
   VUINT16 mrblr;          /* maximum receive buffer length */ 
   VUINT32 rstate;         /* Rx internal state */ 
   VUINT32 res1;           /* reserved/internal */ 
   VUINT16 rbptr;          /* Rx buffer descriptor pointer */ 
   VUINT16 res2;           /* reserved/internal */ 
   VUINT32 res3;           /* reserved/internal */ 
   VUINT32 tstate;         /* Tx internal state */ 
   VUINT32 res4;           /* reserved/internal */ 
   VUINT16 tbptr;          /* Tx buffer descriptor pointer */ 
   VUINT16 res5;           /* reserved/internal */ 
   VUINT32 res6;           /* reserved/internal */ 
   VUINT32 res7;           /* reserved/internal */ 
   VUINT16 rpbase;         /* relocatable parameter ram base */ 
   VUINT16 res8;           /* reserved/internal */ 
 } SPI_PARAM; 
 typedef SPI_PARAM *pSPI_PARAM; 
 typedef SPI_BD * pSPI_BD ; 
  
 typedef struct spi_dev 
 { 
   BOOL              init; 
   BOOL              open; 
   pSPI_PARAM          pPram; 
   pSPI_BD             pTxBdBase; 
   UINT16              txBdBaseOffset; 
   int                 txBdNext; 
   pSPI_BD             pRxBdBase; 
   UINT16              rxBdBaseOffset; 
   int                 rxBdNext; 
   VUINT32             xmitState; 
   VUINT32             rcvState; 
   VUINT32             regBase;        /* register/DPR base address */ 
   VUINT32             dualpRam;       /* dual port ram base address */ 
   VUINT16             pram_base_offset; 
   INT32               loopbackType;   /* type of loopback to use */ 
 } SPI_DEV; 
  
 LOCAL SPI_DEV		spiDev = 
 { 
   FALSE, FALSE, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 
   NULL, NULL, NULL 
 }; 
  
  
 /* Forward declarations for NV-RAM (serial EEPROM). */ 
 LOCAL STATUS	sysNvRamGetStatus( 
                                   void); 
 LOCAL void	sysNvRamWriteEnable( 
                                 void); 
 LOCAL void	sysNvRamWriteByte( 
                               UCHAR		data, 
                               USHORT		eep_addr); 
  
  
 /****************************************************************************** 
 * 
 * sysHwSpiInit - initializes NV-RAM 
 * 
 * This routine initializes NV-RAM to prepare for subsequent reads from or 
 * writes to NV-RAM. 
 * 
 * RETURNS: none 
 */ 
  
 void	sysHwSpiInit( 
                      void) 
 { 
   SPI_DEV*	pSpi; 
  
  
   pSpi = &spiDev; 
  
   /* SPI initialization cannot occur more than once. */ 
   if (pSpi->init == TRUE) 
     { 
       return; 
     } 
  
   /* Get IMMR register base. */ 
   pSpi->regBase = vxImmrGet(); 
  
   /* Get pointer to dual-ported RAM. */ 
   pSpi->dualpRam = (INT32) DPRAM(pSpi->regBase); 
  
   /* Set pointer to SPI parameter RAM. */ 
   pSpi->pPram = (pSPI_PARAM) (PPC860_DPR_SPI(pSpi->dualpRam)); 
  
   /* Clear parameter RAM values. */ 
   pSpi->pPram->rbase	= 0; 
   pSpi->pPram->tbase	= 0; 
   pSpi->pPram->rfcr	= 0; 
   pSpi->pPram->tfcr	= 0; 
   pSpi->pPram->mrblr	= 0; 
   pSpi->pPram->rstate	= 0; 
   pSpi->pPram->res1	= 0; 
   pSpi->pPram->rbptr	= 0; 
   pSpi->pPram->res2	= 0; 
   pSpi->pPram->res3	= 0; 
   pSpi->pPram->tstate	= 0; 
   pSpi->pPram->res4	= 0; 
   pSpi->pPram->tbptr	= 0; 
   pSpi->pPram->res5	= 0; 
   pSpi->pPram->res6	= 0; 
   pSpi->pPram->rpbase	= 0; 
   pSpi->pPram->res8	= 0; 
  
   /* Set up SCC dual-ported RAM. */ 
 #ifdef	INCLUDE_CPM 
 	{ 
 	UINT32	tempeRx = (UINT32) allocDpramFromPool(8); 
 	UINT32	tempeTx = (UINT32) allocDpramFromPool(8); 
 	pSpi->rxBdBaseOffset = (UINT16) (tempeRx & 0x0000FFFF); 
 	pSpi->txBdBaseOffset = (UINT16) (tempeTx & 0x0000FFFF); 
  
 	/* Adjust dual port RAM addresses, which are offsets from IMMR. */ 
 	pSpi->rxBdBaseOffset -= 0x2000; 
 	pSpi->txBdBaseOffset -= 0x2000; 
 	} 
 #else 
   pSpi->rxBdBaseOffset = (UINT16) SPI_RX_BD_BASE; 
   pSpi->txBdBaseOffset = (UINT16) SPI_TX_BD_BASE; 
 #endif 
   pSpi->pRxBdBase = (pSPI_BD) (pSpi->dualpRam + pSpi->rxBdBaseOffset); 
   pSpi->pTxBdBase = (pSPI_BD) (pSpi->dualpRam + pSpi->txBdBaseOffset); 
  
   /* 
   **	Configure port B pins to enable SPIMOSI, SPIMISO and SPICLK pins. 
   **	PBPAR and PBDIR bits 30, 29, 28 ones; 
   **	PBODR bits 30, 29, 28 zeros. 
   **	(SPI_INTERFACE_PINS is 0xE.) 
   */ 
   *PBPAR(pSpi->regBase) |= SPI_INTERFACE_PINS; 
   *PBDIR(pSpi->regBase) |= SPI_INTERFACE_PINS; 
  
   /* Set up the Port B pins. */ 
   *PBPAR(pSpi->regBase) &= ~0x00001;		/* make CS a GP I/O pin */ 
   *PBDIR(pSpi->regBase) |=  0x00001; 
   *PBDAT(pSpi->regBase) |=  0x00001;		/* de-assert for now */ 
  
   /* 
   **	Write RBASE and TBASE in the SPI parameter RAM to point to 
   **	Rx BD and Tx BD in dual port RAM. 
   */ 
   pSpi->pPram->rbase = (UINT16) ((UINT32) pSpi->rxBdBaseOffset & 0x0000ffff); 
   pSpi->pPram->tbase = (UINT16) ((UINT32) pSpi->txBdBaseOffset & 0x0000ffff); 
  
   /* Initialize Rx and Tx parameters for SPI. */ 
   *MPC860_CPCR(pSpi->regBase) = 0x0051; 
  
   /* Wait for initialization to complete. */ 
   while (*MPC860_CPCR(pSpi->regBase) & 1) 
     { 
       /* Busy-wait. */ 
       ; 
     } 
  
   /* Initialize the SDMA register. */ 
   *MPC860_SDCR(pSpi->regBase) |= 0x0001; 
  
   /* Write MRBLR with the maximum # of bytes per receive. */ 
   /* SPI_RX_BUF_SZ is 0x100. */ 
   pSpi->pPram->mrblr = 1; 
  
   /* Write RFCR and TFCR for normal operation. */ 
   /* MPC860_RFCR_MOT_BE is 0x18. */ 
   pSpi->pPram->rfcr = MPC860_RFCR_MOT_BE; 
   pSpi->pPram->tfcr = MPC860_RFCR_MOT_BE; 
  
   /* Set up buffer pointers. */ 
   eep_wt_ptr = &eep_wt_scratch[0]; 
  
   /* Initialize buffer descriptors. */ 
   pSpi->pTxBdBase->statusMode = 
     (SPI_TRANS_TX_BD_LAST | SPI_TRANS_TX_BD_WRAP); 
   pSpi->pTxBdBase->dataLength  = 0; 
   pSpi->pTxBdBase->dataPointer = spiTxBuf; 
  
   pSpi->pRxBdBase->statusMode = 
     (SPI_TRANS_RX_BD_EMPTY | SPI_TRANS_RX_BD_LAST | SPI_TRANS_RX_BD_WRAP); 
   pSpi->pRxBdBase->dataLength  = 0; 
   pSpi->pRxBdBase->dataPointer = spiRxBuf; 
  
   /* Clear events. */ 
   *MPC860_SPIE(pSpi->regBase) = 0xFF; 
  
   pSpi->init = TRUE; 
  
   *MPC860_SPMODE(pSpi->regBase) = DisSPI; 
  
   return; 
 }	/* end of sysHwSpiInit */ 
  
  
 /****************************************************************************** 
 * 
 * sysNvRamGet - get the contents of non-volatile RAM 
 * 
 * This routine copies the contents of non-volatile memory into a specified 
 * string.  The string is terminated with an EOS. 
 * 
 * RETURNS: OK, or ERROR if access is outside the non-volatile RAM range. 
 * 
 * SEE ALSO: sysNvRamSet(), sysHwSpiInit() 
 */ 
  
 STATUS	sysNvRamGet( 
                     char*	string, 
                     int		strLen, 
                     int		offset) 
 { 
   UCHAR		eeprom_data[(SPI_SERIAL_EEPROM_SZ + SPI_SERIAL_CMD_SEQ_SZ)]; 
   SPI_DEV*	pSpi; 
  
   pSpi = &spiDev; 
  
   if (pSpi->init != TRUE) 
       return(ERROR); 
  
   offset += NV_BOOT_OFFSET;   /* boot line begins at  = 0 */ 
    
   if ((offset < 0) 
       || (strLen < 0) 
       || ((offset + strLen) > SPI_SERIAL_EEPROM_SZ)) 
     return (ERROR); 
  
   /* Wait for EEPROM to become ready. */ 
   while (sysNvRamGetStatus() == ERROR) 
     { 
       /* Busy-wait. */ 
       ; 
     } 
  
   /* Assert EEPROM chip select (CS). */ 
   *PBDAT(pSpi->regBase) &= 0x3FFFE; 
  
   /* Disable SPI (serial port interface). */ 
   *MPC860_SPMODE(pSpi->regBase) = DisSPI; 
  
   /* Set SPI read value. */ 
   pSpi->pPram->mrblr = strLen + SPI_SERIAL_CMD_SEQ_SZ; 
  
   /* Set up buffer descriptors. */ 
   pSpi->pRxBdBase->dataPointer = &eeprom_data[0]; 
   pSpi->pRxBdBase->dataLength = 0; 
   pSpi->pRxBdBase->statusMode = (SPI_TRANS_RX_BD_EMPTY | SPI_TRANS_RX_BD_WRAP); 
   pSpi->pTxBdBase->dataPointer = eep_wt_ptr; 
   pSpi->pTxBdBase->statusMode = 0x0000; 
  
   /* Enable SPI. */ 
   *MPC860_SPMODE(pSpi->regBase) = EnSPI; 
  
   /* Set up for "read data from memory array beginning at selected addr". */ 
   *eep_wt_ptr = 3; 
  
   /* Start address of EEPROM block to be read. */ 
   *(USHORT*) (eep_wt_ptr + 1) = (USHORT)offset; 
  
 	/* Buffer length to read. */ 
   pSpi->pTxBdBase->dataLength = strLen + SPI_SERIAL_CMD_SEQ_SZ; 
  
   pSpi->pTxBdBase->statusMode = ( SPI_TRANS_TX_BD_READY | 
                                   SPI_TRANS_TX_BD_WRAP  | 
                                   SPI_TRANS_TX_BD_LAST ); 
  
 	/* Start transfer. */ 
   *MPC860_SPCOM(pSpi->regBase) = SPI_STR; 
  
   /* Wait for reading to finish. */ 
   while (pSpi->pRxBdBase->statusMode & SPI_TRANS_RX_BD_EMPTY) 
     { 
       /* Busy-wait. */ 
       ; 
     } 
  
   /* De-assert EEPROM chip select (CS). */ 
   *PBDAT(pSpi->regBase) |= 0x00001; 
  
   /* Copy EEPROM data into given string. */ 
   bcopyBytes(&eeprom_data[3], string, strLen); 
   return(OK); 
 }	/* end of sysNvRamGet */ 
  
  
 /****************************************************************************** 
 * 
 * sysNvRamSet - write to non-volatile RAM 
 * 
 * This routine copies a specified string into non-volatile RAM. 
 * 
 * RETURNS: OK, or ERROR if access is outside the non-volatile RAM range. 
 * 
 * SEE ALSO: sysNvRamGet(), sysHwSpiInit() 
 */ 
  
 STATUS	sysNvRamSet( 
                     char*	string, 
                     int		strLen, 
                     int		offset) 
 { 
   /* (Note - given offset is not used by this routine.) */ 
  
   UCHAR	dataChar; 
   USHORT	int_offset = 0; 
   SPI_DEV*	pSpi; 
  
   pSpi = &spiDev; 
  
   if (pSpi->init != TRUE) 
       return(ERROR); 
  
   offset += NV_BOOT_OFFSET;   /* boot line begins at  = 0 */ 
    
   if ((offset < 0) 
       || (strLen < 0) 
       || ((offset + strLen) > SPI_SERIAL_EEPROM_SZ)) 
     return (ERROR); 
  
   int_offset = offset; 
  
   while (strLen) 
     { 
       sysNvRamWriteEnable(); 
       dataChar = (UCHAR) *string++; 
       sysNvRamWriteByte(dataChar, int_offset++); 
       strLen--; 
     } 
  
   return(OK); 
 }	/* end of sysNvRamSet */ 
  
  
 /****************************************************************************** 
 * 
 * sysNvRamWriteEnable - enable writing to NVRAM 
 * 
 * This routine enables writing to NVRAM 
 * 
 * RETURNS: none 
 * 
 * NOMANUAL 
 */ 
  
 LOCAL void	sysNvRamWriteEnable( 
                                 void) 
 { 
   SPI_DEV*	pSpi; 
  
  
   pSpi = &spiDev; 
  
   /* Wait for EEPROM to become ready. */ 
   while (sysNvRamGetStatus() == ERROR) 
     { 
       /* Busy-wait. */ 
       ; 
     } 
  
   /* Assert EEPROM chip select (CS). */ 
   *PBDAT(pSpi->regBase) &= 0x3FFFE; 
  
   /* Wait for transmit to finish (first). */ 
   while (pSpi->pTxBdBase->statusMode & SPI_TRANS_TX_BD_READY) 
     { 
       /* Busy-wait. */ 
       ; 
     } 
  
   /* Disable SPI (serial port interface). */ 
   *MPC860_SPMODE(pSpi->regBase) = DisSPI; 
  
   /* Set up for "write enable latch (enable write operations)". */ 
   *eep_wt_ptr = 6; 
  
   /* Set up transmit buffer descriptor. */ 
   pSpi->pTxBdBase->dataPointer = eep_wt_ptr; 
   pSpi->pTxBdBase->dataLength = 1; 
   pSpi->pTxBdBase->statusMode = ( SPI_TRANS_TX_BD_READY | 
                                   SPI_TRANS_TX_BD_WRAP  | 
                                   SPI_TRANS_TX_BD_LAST ); 
  
   /* Set SPI read value. */ 
   pSpi->pPram->mrblr = 1; 
  
   /* Set up receive buffer descriptor. */ 
   pSpi->pRxBdBase->dataPointer = eep_wt_ptr + 16; 
   pSpi->pRxBdBase->statusMode = ( SPI_TRANS_RX_BD_EMPTY | 
                                   SPI_TRANS_RX_BD_WRAP ); 
  
   /* Assert EEPROM chip select (CS). */ 
   *PBDAT(pSpi->regBase) &= 0x3FFFE; 
  
   /* Enable SPI. */ 
   *MPC860_SPMODE(pSpi->regBase) = EnSPI; 
  
   /* Start transfer. */ 
   *MPC860_SPCOM(pSpi->regBase) = SPI_STR; 
  
   /* Wait for reading to finish. */ 
   while (pSpi->pRxBdBase->statusMode & 0x8000) 
     { 
       /* Busy-wait. */ 
       ; 
     } 
  
   /* De-assert EEPROM chip select (CS). */ 
   *PBDAT(pSpi->regBase) |= 0x00001; 
  
   return; 
 }	/* end of sysNvRamWriteEnable */ 
  
  
 /****************************************************************************** 
 * 
 * sysNvRamWriteByte - write a byte to NVRAM 
 * 
 * This routine writes one byte to NVRAM 
 * 
 * RETURNS: none 
 * 
 * NOMANUAL 
 */ 
  
 LOCAL void	sysNvRamWriteByte( 
                               UCHAR		data, 
                               USHORT		eep_addr) 
 { 
   SPI_DEV*	pSpi; 
  
  
   pSpi = &spiDev; 
  
   /* Wait for EEPROM to become ready. */ 
   while (sysNvRamGetStatus() == ERROR) 
     { 
       /* Busy-wait. */ 
       ; 
     } 
  
   /* Wait for transmit to finish (first). */ 
   while (pSpi->pTxBdBase->statusMode & SPI_TRANS_TX_BD_READY) 
     { 
       /* Busy-wait. */ 
       ; 
     } 
  
   /* Disable SPI (serial port interface). */ 
   *MPC860_SPMODE(pSpi->regBase) = DisSPI; 
  
  
   /* Set up for "write data to memory array beginning at selected addr". */ 
   *eep_wt_ptr = 2; 
  
   /* Write the given character into the proper write buffer location. */ 
   *(eep_wt_ptr + 3) = data; 
  
   *(USHORT*) (eep_wt_ptr + 1) = eep_addr; 
  
   /* Set up transmit buffer descriptor. */ 
   pSpi->pTxBdBase->dataPointer = eep_wt_ptr; 
   pSpi->pTxBdBase->dataLength = 4; 
   pSpi->pTxBdBase->statusMode =  ( SPI_TRANS_TX_BD_READY | 
                                    SPI_TRANS_TX_BD_WRAP  | 
                                    SPI_TRANS_TX_BD_LAST ); 
  
   /* Set SPI read value. */ 
   pSpi->pPram->mrblr = 4; 
  
   /* Set up receive buffer descriptor. */ 
   pSpi->pRxBdBase->dataPointer = eep_wt_ptr + 32; 
   pSpi->pRxBdBase->statusMode = ( SPI_TRANS_RX_BD_WRAP  | 
                                   SPI_TRANS_RX_BD_EMPTY ); 
   /* Assert EEPROM chip select (CS). */ 
   *PBDAT(pSpi->regBase) &= 0x3FFFE; 
  
   /* Enable SPI. */ 
   *MPC860_SPMODE(pSpi->regBase) = EnSPI; 
  
   /* Start transfer. */ 
   *MPC860_SPCOM(pSpi->regBase) = SPI_STR; 
  
   /* Wait for reading to finish. */ 
   while (pSpi->pRxBdBase->statusMode & SPI_TRANS_RX_BD_EMPTY) 
     { 
       /* Busy-wait. */ 
       ; 
     } 
  
   /* De-assert EEPROM chip select (CS). */ 
   *PBDAT(pSpi->regBase) |= 0x00001; 
  
   return; 
 }	/* end of sysNvRamWriteByte */ 
  
  
 /****************************************************************************** 
 * 
 * sysNvRamGetStatus - get the status of NVRAM 
 * 
 * This routine gets the status of the NVRAM 
 * 
 * RETURNS: OK or ERROR 
 * 
 * NOMANUAL 
 */ 
  
 LOCAL STATUS	sysNvRamGetStatus( 
                                   void) 
 { 
   SPI_DEV*	pSpi; 
  
  
   pSpi = &spiDev; 
  
   /* Wait for transmit to finish (first). */ 
   while (pSpi->pTxBdBase->statusMode & SPI_TRANS_TX_BD_READY) 
     { 
       /* Busy-wait. */ 
       ; 
     } 
  
   /* Assert EEPROM chip select (CS). */ 
   *PBDAT(pSpi->regBase) &= 0x3FFFE; 
  
   /* Disable SPI (serial port interface). */ 
   *MPC860_SPMODE(pSpi->regBase) = DisSPI; 
  
   /* Set up for "read status register". */ 
   *eep_wt_ptr = 5; 
  
   /* Set up transmit buffer descriptor. */ 
   pSpi->pTxBdBase->dataPointer = eep_wt_ptr; 
   pSpi->pTxBdBase->dataLength = 2; 
   pSpi->pTxBdBase->statusMode = ( SPI_TRANS_TX_BD_READY | 
                                   SPI_TRANS_TX_BD_WRAP  | 
                                   SPI_TRANS_TX_BD_LAST ); 
  
   /* Set SPI read value. */ 
   pSpi->pPram->mrblr = 2; 
  
   /* Set up receive buffer descriptor. */ 
   pSpi->pRxBdBase->dataPointer = eep_wt_ptr + 16; 
   pSpi->pRxBdBase->statusMode = ( SPI_TRANS_RX_BD_WRAP  | 
                                   SPI_TRANS_RX_BD_EMPTY ); 
  
   /* Enable SPI. */ 
   *MPC860_SPMODE(pSpi->regBase) = EnSPI; 
  
   /* Start transfer. */ 
   *MPC860_SPCOM(pSpi->regBase) = SPI_STR; 
  
   /* Wait for reading to finish. */ 
   while (pSpi->pRxBdBase->statusMode & SPI_TRANS_RX_BD_EMPTY) 
     { 
       ; 
     } 
  
   /* De-assert EEPROM chip select (CS). */ 
   *PBDAT(pSpi->regBase) |= 0x00001; 
  
   if (*(eep_wt_ptr + 17) & 1) 
     { 
       return(ERROR); 
     } 
   else 
     { 
       return(OK); 
     } 
 }	/* end of sysNvRamGetStatus */ 
  
  
  
 /* NV-RAM test. */ 
 UCHAR	read_from_EEPROM[(SPI_SERIAL_EEPROM_SZ + SPI_SERIAL_CMD_SEQ_SZ)]; 
 UCHAR	write_to_EEPROM[(SPI_SERIAL_EEPROM_SZ + SPI_SERIAL_CMD_SEQ_SZ)]; 
 void	nvram_test(int seed,int offset ) 
 { 
   STATUS	status; 
   int		i; 
  
  
   printf("About to init SPI.\n"); 
   sysHwSpiInit(); 
   printf("About to read contents of entire EEPROM.\n"); 
   status = sysNvRamGet(&read_from_EEPROM[0], SPI_SERIAL_EEPROM_SZ, 0); 
   printf("Status of sysNvRamGet is %d.\n", status); 
   printf("Contents of EEPROM are: \n"); 
   for (i = 0; i < 64; i++) 
     { 
       printf("\n%x %x %x %x", 
              *((UINT*) &read_from_EEPROM[i * 16]), 
              *((UINT*) &read_from_EEPROM[(i * 16) + 4]), 
              *((UINT*) &read_from_EEPROM[(i * 16) + 8]), 
              *((UINT*) &read_from_EEPROM[(i * 16) + 12])); 
     } 
   for (i = 0; i < SPI_SERIAL_EEPROM_SZ; i++) 
     { 
       write_to_EEPROM[i] = (unsigned char)0; 
     } 
   printf("About to write contents of entire EEPROM.\n"); 
 	status = sysNvRamSet(&write_to_EEPROM[0], SPI_SERIAL_EEPROM_SZ - offset, 
 							offset); 
   printf("Status of sysNvRamSet is %d.\n", status); 
   printf("About to read contents of entire EEPROM.\n"); 
   status = sysNvRamGet(&read_from_EEPROM[0], SPI_SERIAL_EEPROM_SZ, 0); 
  
 	for (i = 0; i < SPI_SERIAL_EEPROM_SZ; i++) 
 		{ 
 		if (read_from_EEPROM[i] != write_to_EEPROM[i]) 
 			{ 
 			printf("\n%d: 0x%02x != 0x%02x ", i, read_from_EEPROM[i], 
 					write_to_EEPROM[i]); 
 			} 
 		} 
   printf("\nDONE"); 
      
   return; 
 } 
  
  
 /* end of sysSpiNvRam.c */