📄 sysspi.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 "ads860.h" /* liefe 030819 "yourBsp.h" e.g. ads860.h */
#include "fpga.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
#if 1
#define EnSPI 0x2F77
#define DisSPI 0x2E77
#else /* loopback */
#define EnSPI 0x4F77
#define DisSPI 0x4E77
#endif
#define SPI_STR 0x80
UCHAR spiTxBuf[SPI_TX_BUF_SZ];
UCHAR spiRxBuf[SPI_RX_BUF_SZ];
/*
UCHAR * spiTxBuf = (UCHAR *)cacheDmaMalloc(SPI_TX_BUF_SZ);
UCHAR * spiRxBuf = (UCHAR *)cacheDmaMalloc(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 struct spi_dev
{
SPI_PARAM *pPram;
SPI_BD *pTxBD;
SPI_BD *pRxBD;
VUINT32 xmitState;
VUINT32 rcvState;
} SPI_DEV;
LOCAL SPI_DEV spiDev =
{
NULL, NULL, NULL, NULL, NULL
};
/******************************************************************************
*
* sysHwSpiInit - initializes SPI port
*
* This routine initializes SPI port to prepare for subsequent reads from or
* writes to SPI.
*
* RETURNS: none
*/
void sysHwSpiInit(void)
{
SPI_DEV* pSpi;
UINT immrVal,dprbase,spiprbase,rxBdBaseOffset,txBdBaseOffset;
/*
cacheDisable(DATA_CACHE);
cacheDisable(INSTRUCTION_CACHE);
*/
immrVal = INTERNAL_MEM_MAP_ADDR; /* Base address of Internal Memory */
dprbase = immrVal+0x2000; /* Dual-Ported RAM base address */
spiprbase = dprbase+0x1d80; /* SPI paralell RAM base address */
rxBdBaseOffset = SPI_RX_BD_BASE;
txBdBaseOffset = SPI_TX_BD_BASE;
pSpi = &spiDev;
/* Set pointer to SPI parameter RAM. */
pSpi->pPram = (SPI_PARAM *) spiprbase;
pSpi->pRxBD = (SPI_BD *) (rxBdBaseOffset+dprbase);
pSpi->pTxBD = (SPI_BD *) (txBdBaseOffset+dprbase);
/* 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;
/*
** 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(immrVal) |= SPI_INTERFACE_PINS;
*PBDIR(immrVal) |= SPI_INTERFACE_PINS;
/* Set up the Port B pins. */
*PDPAR(immrVal) &= ~0x1800; /* make CS a GP I/O pin */
*PDDIR(immrVal) |= 0x1800;
*PDDAT(immrVal) |= 0x1800; /* 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) (rxBdBaseOffset & 0x0000ffff);
pSpi->pPram->tbase = (UINT16) (txBdBaseOffset & 0x0000ffff);
/* Initialize Rx and Tx parameters for SPI. */
*MPC860_CPCR(immrVal) = 0x0051;
/* Wait for initialization to complete. */
while (*MPC860_CPCR(immrVal) & 1)
{
/* Busy-wait. */
;
}
/* Initialize the SDMA register. */
*MPC860_SDCR(immrVal) |= 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;
/* Initialize buffer descriptors. */
pSpi->pTxBD->statusMode =
(SPI_TRANS_TX_BD_LAST | SPI_TRANS_TX_BD_WRAP);
pSpi->pTxBD->dataLength = 0;
pSpi->pTxBD->dataPointer = spiTxBuf;
pSpi->pRxBD->statusMode =
(SPI_TRANS_RX_BD_EMPTY | SPI_TRANS_RX_BD_LAST | SPI_TRANS_RX_BD_WRAP);
pSpi->pRxBD->dataLength = 0;
pSpi->pRxBD->dataPointer = spiRxBuf;
/* Clear events. */
*MPC860_SPIE(immrVal) = 0xFF;
*MPC860_SPMODE(immrVal) = DisSPI;
printf("RxBD=%08x\n", pSpi->pRxBD);
printf("TxBD=%08x\n", pSpi->pTxBD);
printf("Rx Buffer=%08x\n", spiRxBuf);
printf("Tx Buffer=%08x\n", spiTxBuf);
return;
} /* end of sysHwSpiInit */
/******************************************************************************
*
* sysNvRamWriteByte - write a byte to NVRAM
*
* This routine writes one byte to NVRAM
*
* RETURNS: none
*
* NOMANUAL
*/
void sysSPIWrite(int len)
{
SPI_DEV* pSpi;
UINT immrVal;
int i;
immrVal = INTERNAL_MEM_MAP_ADDR; /* Base address of Internal Memory */
pSpi = &spiDev;
/* Wait for transmit to finish (first). */
while (pSpi->pTxBD->statusMode & SPI_TRANS_TX_BD_READY)
{
/* Busy-wait. */
;
}
/* Disable SPI (serial port interface). */
*MPC860_SPMODE(immrVal) = 0x2EF7;
/* Set up transmit buffer descriptor. */
pSpi->pTxBD->dataPointer = spiTxBuf;
pSpi->pTxBD->dataLength = len;
pSpi->pTxBD->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->pRxBD->dataPointer = spiRxBuf;
pSpi->pRxBD->statusMode = ( SPI_TRANS_RX_BD_WRAP |
SPI_TRANS_RX_BD_EMPTY );
/* Assert SCPEN1. */
*PDDAT(immrVal) &= ~0x0800;
/* Enable SPI. */
*MPC860_SPMODE(immrVal) = 0x2FF7;
/* Start transfer. */
*MPC860_SPCOM(immrVal) = SPI_STR;
/* Wait for reading to finish. */
while (pSpi->pRxBD->statusMode & SPI_TRANS_RX_BD_EMPTY)
{
}
/* De-assert SCPEN1. */
*PDDAT(immrVal) |= 0x0800;
return;
} /* end of sysNvRamWriteByte */
/******************************************************************************
*
* sysSPIRead - get the contents of SPI port
*
* 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 sysSPIRead()
{
SPI_DEV* pSpi;
UINT immrVal;
immrVal = INTERNAL_MEM_MAP_ADDR; /* Base address of Internal Memory */
pSpi = &spiDev;
/* Assert EEPROM chip select (CS). */
*PDDAT(immrVal) &= ~0x1000;
/* Disable SPI (serial port interface). */
*MPC860_SPMODE(immrVal) = DisSPI;
/* Set SPI read value. */
pSpi->pPram->mrblr = 1;
/* Set up buffer descriptors. */
pSpi->pRxBD->dataPointer = spiRxBuf;
pSpi->pRxBD->dataLength = 0;
pSpi->pRxBD->statusMode = (SPI_TRANS_RX_BD_EMPTY | SPI_TRANS_RX_BD_WRAP);
/* Enable SPI. */
*MPC860_SPMODE(immrVal) = EnSPI;
/* Start transfer. */
*MPC860_SPCOM(immrVal) = SPI_STR;
/* Wait for reading to finish. */
while (pSpi->pRxBD->statusMode & SPI_TRANS_RX_BD_EMPTY)
{
/* Busy-wait. */
;
}
/* De-assert EEPROM chip select (CS). */
*PDDAT(immrVal) |= 0x1000;
/* Copy EEPROM data into given string. */
/*
bcopyBytes(&spiRxBuf[0], string, strLen);
*/
return(OK);
} /* end of sysNvRamGet */
/* end of sysSPI.c */
void write_nb(unsigned char regval)
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -