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

📄 hspi.c

📁 三星2443芯片
💻 C
📖 第 1 页 / 共 2 页
字号:
/*****************************************
  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 + -