📄 hspi.c
字号:
/*****************************************
NAME: Hspi
DESC: High Speed SPI test
HISTORY:
2006.12.18:GOM: draft ver 1.0
*****************************************/
#include "system.h"
#include "hspi.h"
#define ECLK 100*1000000
////////////////////////////////////////////////////////////////////////////
#define BYTEOPERATION 1
#define BURSTOPERATION 0
#define Baudrate 8000000
#define HSPI_CLK HSPI_EPLL
volatile int DataCnt = 1024;
///////////////////////////////////////////////////////////////////////////
volatile int TransferdDataCnt = 0;
volatile int ReceivedDataCnt = 0;
volatile char uMaxFifoSize = 64;
#if BYTEOPERATION
volatile unsigned char *TxBufAddr, *RxBufAddr;
#else
volatile unsigned int *TxBufAddr, *RxBufAddr;
#endif
volatile int BusTransWord;
volatile int BusTransByte;
volatile int PacketCntValue;
volatile int SpiTxIntEnd=0;
volatile int SpiRxIntEnd=0;
volatile int SpiTxDmaEnd=0;
volatile int SpiRxDmaEnd=0;
#define TRAIL_CNT(n) (((n)&0x3FF)<<19)
#define RX_TRIG_LVL(n) (((n)&0x3F)<<11)
#define TX_TRIG_LVL(n) (((n)&0x3F)<<5)
#define PRESCALER(n) (((n)&0xFF)<<0)
#if 1//DMA Mode
volatile int m_uTxTrigLvl = 0x14;
volatile int m_uRxTrigLvl = 0x8;
#else
volatile int m_uTxTrigLvl = 0x4;
volatile int m_uRxTrigLvl = 0x30;
#endif
#define SPI_TX_BUFFER _NONCACHE_STARTADDRESS
#define SPI_RX_BUFFER (_NONCACHE_STARTADDRESS+0x200000)
extern unsigned int ARMCLK, HCLK, PCLK;
void * func_HSPI_test[][2]=
{
(void *)Test_Master_DMA_FullDuplex, "B2B Master DMA Full Duplex ",
(void *)Test_Slave_DMA_FullDuplex, "B2B Slave DMA Full Duplex ",
(void *)Test_MasterTxOnly_DMA, "B2B Master Tx only by DMA ",
(void *)Test_SlaveRxOnly_DMA, "B2B Slave Rx only by DMA ",
(void *)Test_MasterRxOnly_DMA, "B2B Master Rx only by DMA ",
(void *)Test_SlaveTxOnly_DMA, "B2B Slave Tx only by DMA ",
(void *)Test_Master_INT_FullDuplex, "B2B Master INT Full Duplex ",
(void *)Test_Slave_INT_FullDuplex, "B2B Slave INT Full Duplex ",
(void *)Test_MasterTxOnly_INT, "B2B Master Tx only by INT ",
(void *)Test_SlaveRxOnly_INT, "B2B Slave Rx only by INT ",
(void *)Test_MasterRxOnly_INT, "B2B Master Rx only by INT ",
(void *)Test_SlaveTxOnly_INT, "B2B Slave Tx only by INT ",
0,0
};
void Test_HSPI(void)
{
int i;
rSCLKCON |= (1<<14);
rPCLKCON |= (1<<6);
GPIOPortSet();
rLOCKCON1=0x800;
rCLKSRC|=(1<<6); // EPLL Output
SetEPLL(40, 1, 1);//96MHz
rEPLLCON &= ~(1<<24); // EPLL ON
rCLKDIV1 = (rCLKDIV1 & ~(0x3<<24)) | (0x0<<24);
rMISCCR = rMISCCR & ~(0x7<<8) | (1<<8);
//rGPHCON = rGPHCON & ~(0x3<<28) | (1<<29);
//Uart_getc();
while(1)
{
i=0;
printf("\n\n");
while(1)
{ //display menu
printf("%2d:%s",i,func_HSPI_test[i][1]);
i++;
if((int)(func_HSPI_test[i][0])==0)
{
printf("\n");
break;
}
if((i%2)==0)
printf("\n");
}
printf("\nSelect (\"-1\" to exit) : ");
i = GetIntNum();
if(i==-1)
break; // return.
if( (i<((sizeof(func_HSPI_test)-1)/8)) ) // select and execute...
( (void (*)(void)) (func_HSPI_test[i][0]) )();
}
}
void Test_Master_DMA_FullDuplex(void)
{
U32 i;
U32 uTxBufAddr = _NONCACHE_STARTADDRESS;
U32 uRxBufAddr = (_NONCACHE_STARTADDRESS+0x200000);
BusTransWord = 1;
#if BYTEOPERATION
TxBufAddr = (U8 *)SPI_TX_BUFFER;
RxBufAddr = (U8 *)SPI_RX_BUFFER;
#else
TxBufAddr = (U32 *)SPI_TX_BUFFER;
RxBufAddr = (U32 *)SPI_RX_BUFFER;
#endif
// 0. Clear the Rx buffer.
for (i = 0; i<DataCnt; i++)
*(RxBufAddr+i) = 0;
// 1. Set up the Tx buffer.
for (i = 0; i<DataCnt; i++)
*(TxBufAddr+i) = (i+1)%0xff;
pISR_DMA = (unsigned)DmaDone;
rINTMSK &= ~(BIT_DMA);
rINTSUBMSK &= ~(BIT_SUB_DMA0|BIT_SUB_DMA1);
// 2. Master
Reset();
InitHSPI(Master, CPOLHIGH, FORMAT_A, HSPI_CLK);
TxDMAInit(uTxBufAddr, SPI_TX_DATA, DataCnt);
RxDMAInit(SPI_RX_DATA, uRxBufAddr, DataCnt);
rMODE_CFG |= (MODE_RXDMA_ON | MODE_TXDMA_ON); // Set the INT mode
//rSPI_INT_EN |= INT_TRAILING | INT_RX_OVERRUN | INT_RX_UNDERRUN | INT_TX_FIFORDY;
rPENDING_CLR = 0xffffffff;
rCH_CFG |= CH_RXCH_ON | CH_TXCH_ON; // Tx Rx Channel On
rDMASKTRIG0 |= (1<<1);
rDMASKTRIG1 |= (1<<1);
nSSLow();
while(SpiTxDmaEnd == 1 && SpiRxDmaEnd == 1);
while ((rSPI_STATUS>>13)&0x7f); // check if Tx Fifo empty
while (!(rSPI_STATUS & STUS_TX_DONE)); // check if Tx done
nSSHigh();
CompareData(uTxBufAddr, uRxBufAddr, DataCnt);
TransferdDataCnt = 0;
ReceivedDataCnt=0;
SpiTxDmaEnd=0;
SpiRxDmaEnd=0;
}
void Test_Slave_DMA_FullDuplex(void)
{
U32 i;
U32 uTxBufAddr = _NONCACHE_STARTADDRESS;
U32 uRxBufAddr = (_NONCACHE_STARTADDRESS+0x200000);
BusTransWord = 1;
#if BYTEOPERATION
TxBufAddr = (U8 *)SPI_TX_BUFFER;
RxBufAddr = (U8 *)SPI_RX_BUFFER;
#else
TxBufAddr = (U32 *)SPI_TX_BUFFER;
RxBufAddr = (U32 *)SPI_RX_BUFFER;
#endif
// 0. Clear the Rx buffer.
for (i = 0; i<DataCnt; i++)
*(RxBufAddr+i) = 0;
// 1. Set up the Tx buffer.
for (i = 0; i<DataCnt; i++)
*(TxBufAddr+i) = (i+1)%0xff;
pISR_DMA = (unsigned)DmaDone;
rINTMSK &= ~(BIT_DMA);
rINTSUBMSK &= ~(BIT_SUB_DMA0|BIT_SUB_DMA1);
// 2. Master
Reset();
InitHSPI(Slave, CPOLHIGH, FORMAT_A, HSPI_CLK);
TxDMAInit(uTxBufAddr, SPI_TX_DATA, DataCnt);
RxDMAInit(SPI_RX_DATA, uRxBufAddr, DataCnt);
rMODE_CFG |= (MODE_RXDMA_ON | MODE_TXDMA_ON); // Set the INT mode
//rSPI_INT_EN |= INT_TRAILING | INT_RX_OVERRUN | INT_RX_UNDERRUN | INT_TX_FIFORDY;
//rPENDING_CLR = 0xffffffff;
rCH_CFG |= CH_RXCH_ON | CH_TXCH_ON; // Tx Rx Channel On
rDMASKTRIG0 |= (1<<1);
rDMASKTRIG1 |= (1<<1);
while(SpiTxDmaEnd == 1 && SpiRxDmaEnd == 1);
while ((rSPI_STATUS>>13)&0x7f); // check if Tx Fifo empty
while (!(rSPI_STATUS & STUS_TX_DONE)); // check if Tx done
CompareData(uTxBufAddr, uRxBufAddr, DataCnt);
TransferdDataCnt = 0;
ReceivedDataCnt=0;
SpiTxDmaEnd=0;
SpiRxDmaEnd=0;
}
void Test_MasterTxOnly_DMA(void)
{
U32 i;
U32 uTxBufAddr = _NONCACHE_STARTADDRESS;
//U32 uRxBufAddr = (_NONCACHE_STARTADDRESS+0x200000);
BusTransWord = 1;
#if BYTEOPERATION
TxBufAddr = (U8 *)SPI_TX_BUFFER;
RxBufAddr = (U8 *)SPI_RX_BUFFER;
#else
TxBufAddr = (U32 *)SPI_TX_BUFFER;
RxBufAddr = (U32 *)SPI_RX_BUFFER;
#endif
// 0. Clear the Rx buffer.
for (i = 0; i<DataCnt; i++)
*(RxBufAddr+i) = 0;
// 1. Set up the Tx buffer.
for (i = 0; i<DataCnt; i++)
*(TxBufAddr+i) = (i+1)%0xff;
// *(TxBufAddr+i) = 0x5555aaaa;
pISR_DMA = (unsigned)DmaDone;
rINTMSK &= ~(BIT_DMA);
rINTSUBMSK &= ~(BIT_SUB_DMA0);
// 2. Master
Reset();
InitHSPI(Master, CPOLHIGH, FORMAT_A, HSPI_CLK);
TxDMAInit(uTxBufAddr, SPI_TX_DATA, DataCnt);
printf("\nTotal Transfer size = %d",DataCnt);
rMODE_CFG |= MODE_TXDMA_ON; // Set the DMA mode
//rSPI_INT_EN |= INT_TRAILING | INT_RX_OVERRUN | INT_RX_UNDERRUN | INT_TX_FIFORDY;
//rPENDING_CLR = 0xffffffff;
rCH_CFG |= CH_TXCH_ON; // Tx Channel On
nSSLow();
rDMASKTRIG0 |= (1<<1);
while(SpiTxDmaEnd == 0);
SpiTxDmaEnd = 0;
while ((rSPI_STATUS>>6)&0x7f); // check if Tx Fifo empty
while (!(rSPI_STATUS & STUS_TX_DONE)); // check if Tx done
nSSHigh();
printf("\nDMA transfer is done");
rDISRC0 = 0;
rDISRCC0 = 0;
rDIDST0 = 0;
rDIDSTC0 = 0;
rDCON0 = 0;
rDMAREQSEL0 = 0;
TransferdDataCnt = 0;
ReceivedDataCnt=0;
SpiTxDmaEnd=0;
SpiRxDmaEnd=0;
}
void Test_SlaveRxOnly_DMA(void)
{
U32 i;
U32 uTxBufAddr = _NONCACHE_STARTADDRESS;
U32 uRxBufAddr = (_NONCACHE_STARTADDRESS+0x200000);
BusTransWord = 1;
#if BYTEOPERATION
TxBufAddr = (U8 *)SPI_TX_BUFFER;
RxBufAddr = (U8 *)SPI_RX_BUFFER;
#else
TxBufAddr = (U32 *)SPI_TX_BUFFER;
RxBufAddr = (U32 *)SPI_RX_BUFFER;
#endif
// 0. Clear the Rx buffer.
for (i = 0; i<DataCnt; i++)
*(RxBufAddr+i) = 0;
// 1. Set up the Tx buffer.
for (i = 0; i<DataCnt; i++)
*(TxBufAddr+i) = (i+1)%0xff;
//*(TxBufAddr+i) = 0x5555aaaa;
pISR_DMA = (unsigned)DmaDone;
rINTMSK &= ~(BIT_DMA);
rINTSUBMSK &= ~(BIT_SUB_DMA1);
HS_SPI_ERROR_CHECK();
// 2. Master
Reset();
InitHSPI(Slave, CPOLHIGH, FORMAT_A, HSPI_CLK);
RxDMAInit(SPI_RX_DATA, uRxBufAddr, DataCnt);
printf("\nTotal Transfer size = %d",DataCnt);
rMODE_CFG |= (MODE_RXDMA_ON); // Set the DMA mode
//rSPI_INT_EN |= INT_TRAILING | INT_RX_OVERRUN | INT_RX_UNDERRUN | INT_TX_FIFORDY;
//rPENDING_CLR = 0xffffffff;
rCH_CFG |= CH_RXCH_ON; // Rx Channel On
rDMASKTRIG1 |= (1<<1);
printf("\ncurrent TC = %x",(rDSTAT1&0xfffff));
while(SpiRxDmaEnd == 0) ;
SpiRxDmaEnd = 0;
CompareData(uTxBufAddr, uRxBufAddr, DataCnt);
TransferdDataCnt = 0;
ReceivedDataCnt=0;
SpiTxDmaEnd=0;
SpiRxDmaEnd=0;
}
void Test_MasterRxOnly_DMA(void)
{
U32 i;
U32 uTxBufAddr = _NONCACHE_STARTADDRESS;
U32 uRxBufAddr = (_NONCACHE_STARTADDRESS+0x200000);
BusTransWord = 1;
#if BYTEOPERATION
TxBufAddr = (U8 *)SPI_TX_BUFFER;
RxBufAddr = (U8 *)SPI_RX_BUFFER;
#else
TxBufAddr = (U32 *)SPI_TX_BUFFER;
RxBufAddr = (U32 *)SPI_RX_BUFFER;
#endif
// 0. Clear the Rx buffer.
for (i = 0; i<DataCnt; i++)
*(RxBufAddr+i) = 0;
// 1. Set up the Tx buffer.
for (i = 0; i<DataCnt; i++)
*(TxBufAddr+i) = (i+1)%0xff;
//*(TxBufAddr+i) = 0x5555aaaa;
pISR_DMA = (unsigned)DmaDone;
rINTMSK &= ~(BIT_DMA);
rINTSUBMSK &= ~(BIT_SUB_DMA1);
// 2. Master
Reset();
InitHSPI(Master, CPOLHIGH, FORMAT_A, HSPI_CLK);
RxDMAInit(SPI_RX_DATA, uRxBufAddr, DataCnt);
printf("\nTotal Transfer size = %d",DataCnt);
//rSPI_INT_EN |= INT_TRAILING | INT_RX_OVERRUN | INT_RX_UNDERRUN | INT_TX_FIFORDY;
//rPENDING_CLR = 0xffffffff;
rPACKET_CNT = (1<<16) | (PacketCntValue);
rDMASKTRIG1 |= (1<<1);
rMODE_CFG |= (1<<17) | MODE_RXDMA_ON; // Set the DMA mode
rCH_CFG |= CH_RXCH_ON; // Tx Channel On
nSSLow();
while(SpiRxDmaEnd == 0);
SpiRxDmaEnd = 0;
nSSHigh();
CompareData(uTxBufAddr, uRxBufAddr, DataCnt);
TransferdDataCnt = 0;
ReceivedDataCnt=0;
SpiTxDmaEnd=0;
SpiRxDmaEnd=0;
}
void Test_SlaveTxOnly_DMA(void)
{
U32 i;
U32 uTxBufAddr = _NONCACHE_STARTADDRESS;
//U32 uRxBufAddr = (_NONCACHE_STARTADDRESS+0x200000);
BusTransWord = 1;
#if BYTEOPERATION
TxBufAddr = (U8 *)SPI_TX_BUFFER;
RxBufAddr = (U8 *)SPI_RX_BUFFER;
#else
TxBufAddr = (U32 *)SPI_TX_BUFFER;
RxBufAddr = (U32 *)SPI_RX_BUFFER;
#endif
// 0. Clear the Rx buffer.
for (i = 0; i<DataCnt; i++)
*(RxBufAddr+i) = 0;
// 1. Set up the Tx buffer.
for (i = 0; i<DataCnt; i++)
*(TxBufAddr+i) = (i+1)%0xff;
//*(TxBufAddr+i) = 0x5555aaaa;
pISR_DMA = (unsigned)DmaDone;
rINTMSK &= ~(BIT_DMA);
rINTSUBMSK &= ~(BIT_SUB_DMA0);
// 2. Master
Reset();
InitHSPI(Slave, CPOLHIGH, FORMAT_A, HSPI_CLK);
TxDMAInit(uTxBufAddr, SPI_TX_DATA, DataCnt);
rDMASKTRIG0 |= (1<<1);
rMODE_CFG |= MODE_TXDMA_ON; // Set the DMA mode
rCH_CFG |= CH_TXCH_ON; // Tx Rx Channel On
while(SpiTxDmaEnd == 0);
SpiTxDmaEnd = 0;
while ((rSPI_STATUS>>6)&0x7f); // check if Tx Fifo empty
printf("\nTransfer Complete");
TransferdDataCnt = 0;
ReceivedDataCnt=0;
SpiTxDmaEnd=0;
SpiRxDmaEnd=0;
}
void Test_Master_INT_FullDuplex(void)
{
U32 i;
U32 uTxBufAddr = _NONCACHE_STARTADDRESS;
U32 uRxBufAddr = (_NONCACHE_STARTADDRESS+0x200000);
SpiTxIntEnd = 0;
SpiRxIntEnd = 0;
#if BYTEOPERATION
TxBufAddr = (U8 *)SPI_TX_BUFFER;
RxBufAddr = (U8 *)SPI_RX_BUFFER;
#else
TxBufAddr = (U32 *)SPI_TX_BUFFER;
RxBufAddr = (U32 *)SPI_RX_BUFFER;
#endif
pISR_SPI0 = (unsigned)HSPI_Int;
// 0. Clear the Rx buffer.
for (i = 0; i<DataCnt; i++)
*(RxBufAddr+i) = 0;
// 1. Set up the Tx buffer.
for (i = 0; i<DataCnt; i++)
*(TxBufAddr+i) = (i+1)%0xff;
//*(TxBufAddr+i) = 0x5555aaaa;
// 2. Master
Reset();
InitHSPI(Master, CPOLHIGH, FORMAT_A, HSPI_CLK);
rPACKET_CNT = (1<<16) | (PacketCntValue);
rMODE_CFG = (rMODE_CFG & ~(MODE_RXDMA_ON | MODE_TXDMA_ON)) | (0x3ff<<19)| (0x1<<17); // Set the INT mode
rSPI_INT_EN |= INT_TRAILING | INT_RX_OVERRUN | INT_RX_UNDERRUN | INT_RX_FIFORDY | INT_TX_FIFORDY;
rPENDING_CLR = 0xffffffff;
rCH_CFG |= CH_RXCH_ON | CH_TXCH_ON; // Tx Rx Channel On
rINTMSK &= ~(BIT_SPI0);
nSSLow();
while(!(SpiTxIntEnd ==1 && SpiRxIntEnd ==1));
while ((rSPI_STATUS>>13)&0x7f); // check if Rx Fifo empty
//while (!(rSPI_STATUS & STUS_TX_DONE)); // check if Tx done
nSSHigh();
CompareData(uTxBufAddr, uRxBufAddr, DataCnt);
TransferdDataCnt = 0;
ReceivedDataCnt=0;
SpiTxIntEnd=0;
SpiRxIntEnd=0;
}
void Test_Slave_INT_FullDuplex(void)
{
U32 i;
U32 uTxBufAddr = _NONCACHE_STARTADDRESS;
U32 uRxBufAddr = (_NONCACHE_STARTADDRESS+0x200000);
SpiTxIntEnd = 0;
SpiRxIntEnd = 0;
#if BYTEOPERATION
TxBufAddr = (U8 *)SPI_TX_BUFFER;
RxBufAddr = (U8 *)SPI_RX_BUFFER;
#else
TxBufAddr = (U32 *)SPI_TX_BUFFER;
RxBufAddr = (U32 *)SPI_RX_BUFFER;
#endif
pISR_SPI0 = (unsigned)HSPI_Int;
// 0. Clear the Rx buffer.
for (i = 0; i<DataCnt; i++)
*(RxBufAddr+i) = 0;
// 1. Set up the Tx buffer.
for (i = 0; i<DataCnt; i++)
*(TxBufAddr+i) = (i+1)%0xff;
//*(TxBufAddr+i) = 0x5555aaaa;
// 2. Master
Reset();
InitHSPI(Slave, CPOLHIGH, FORMAT_A, HSPI_CLK);
rMODE_CFG = (rMODE_CFG & ~(MODE_RXDMA_ON | MODE_TXDMA_ON)) | (0x3ff<<19); // Set the INT mode
rPENDING_CLR = 0xffffffff;
rSPI_INT_EN |= INT_TRAILING | INT_RX_OVERRUN | INT_RX_UNDERRUN | INT_RX_FIFORDY | INT_TX_FIFORDY;
rCH_CFG |= CH_RXCH_ON | CH_TXCH_ON; // Tx Rx Channel On
rINTMSK &= ~(BIT_SPI0);
while(!(SpiTxIntEnd ==1 && SpiRxIntEnd ==1));
while ((rSPI_STATUS>>13)&0x7f); // check if Rx Fifo empty
//while (!(rSPI_STATUS & STUS_TX_DONE)); // check if Tx done
CompareData(uTxBufAddr, uRxBufAddr, DataCnt);
TransferdDataCnt = 0;
ReceivedDataCnt=0;
SpiTxIntEnd=0;
SpiRxIntEnd=0;
}
void Test_MasterTxOnly_INT(void)
{
U32 i;
//U32 uTxBufAddr = _NONCACHE_STARTADDRESS;
//U32 uRxBufAddr = (_NONCACHE_STARTADDRESS+0x200000);
BusTransWord = 1;
#if BYTEOPERATION
TxBufAddr = (U8 *)SPI_TX_BUFFER;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -