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

📄 sysspinvram.c

📁 vxworks 串口通信程序例子 对vxworks下开发串口通信程序很有帮助
💻 C
📖 第 1 页 / 共 2 页
字号:
/* 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 <offset> = 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. */

⌨️ 快捷键说明

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