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

📄 hspi.c

📁 三星2443芯片
💻 C
📖 第 1 页 / 共 2 页
字号:
	RxBufAddr = (U8 *)SPI_RX_BUFFER;
#else
	TxBufAddr = (U32 *)SPI_TX_BUFFER;
	RxBufAddr = (U32 *)SPI_RX_BUFFER;
#endif

	pISR_SPI0 = (unsigned)HSPI_Tx_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);
	
	rMODE_CFG &= ~(MODE_RXDMA_ON | MODE_TXDMA_ON); // Set the INT mode		
	rSPI_INT_EN |= INT_TX_FIFORDY;
	rPENDING_CLR = 0xffffffff;
	rCH_CFG |= CH_TXCH_ON; // Rx Channel On		
	rINTMSK &= ~(BIT_SPI0);
	
	nSSLow();

	while(!SpiTxIntEnd);	
	
	while ((rSPI_STATUS>>6)&0x7f); // check if Tx Fifo empty
	while (!(rSPI_STATUS & STUS_TX_DONE)); // check if Tx done

	nSSHigh();
	
	printf("\nTransfer End\n");

	TransferdDataCnt = 0;
	ReceivedDataCnt=0;
	SpiTxIntEnd=0;
	SpiRxIntEnd=0;
}

void Test_SlaveRxOnly_INT(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

	pISR_SPI0 = (unsigned)HSPI_Rx_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. Slave
	Reset();	
	InitHSPI(Slave, CPOLHIGH, FORMAT_A, HSPI_CLK);
	
	rMODE_CFG &= ~(MODE_RXDMA_ON | MODE_TXDMA_ON); // Set the INT mode		
	rPENDING_CLR = 0xffffffff;
	//rSPI_INT_EN |= INT_TRAILING | INT_RX_OVERRUN | INT_RX_UNDERRUN | INT_TX_FIFORDY;	
	rSPI_INT_EN |= INT_RX_FIFORDY;	
	rCH_CFG |= CH_RXCH_ON; // Tx Rx Channel On		
	rINTMSK &= ~(BIT_SPI0);
	
	while(!SpiRxIntEnd);
	
	//while ((rSPI_STATUS>>13)&0x7f); // check if Rx Fifo empty


	CompareData(uTxBufAddr, uRxBufAddr, DataCnt);

	TransferdDataCnt = 0;
	ReceivedDataCnt=0;
	SpiTxIntEnd=0;
	SpiRxIntEnd=0;
}

void Test_MasterRxOnly_INT(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;

	m_uTxTrigLvl = 0x8;
	m_uRxTrigLvl = 0x8;
#endif

	pISR_SPI0 = (unsigned)HSPI_Rx_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);
	//printf("\nTotal Transfer size = %d",DataCnt);
	
	rPACKET_CNT = (1<<16) | (PacketCntValue);
	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_FIFORDY;	
	rCH_CFG |= CH_RXCH_ON; // Tx Rx Channel On		
	rINTMSK &= ~(BIT_SPI0);
	
	nSSLow();

	while(SpiRxIntEnd == 0);

	SpiRxIntEnd = 0;

	//Uart_getc();

	nSSHigh();
	

	CompareData(uTxBufAddr, uRxBufAddr, DataCnt);


	TransferdDataCnt = 0;
	ReceivedDataCnt=0;
	SpiTxIntEnd=0;
	SpiRxIntEnd=0;
}


void Test_SlaveTxOnly_INT(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

	pISR_SPI0 = (unsigned)HSPI_Tx_Int;
	// 0. Clear the Rx buffer.
	for (i = 0; i<DataCnt+20; 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 &= ~(MODE_RXDMA_ON | MODE_TXDMA_ON); // Set the INT mode		
	rSPI_INT_EN |= INT_TX_FIFORDY;
	rPENDING_CLR = 0xffffffff;
	rCH_CFG |= CH_TXCH_ON; // Rx Channel On		
	rINTMSK &= ~(BIT_SPI0);

	while(SpiTxIntEnd == 0);

	SpiTxIntEnd = 0;

	while ((rSPI_STATUS>>6)&0x7f); // check if Tx Fifo empty
	while (!(rSPI_STATUS & STUS_TX_DONE)); // check if Tx done

	printf("\nTransfer Complete");

	TransferdDataCnt = 0;
	ReceivedDataCnt=0;
	SpiTxIntEnd=0;
	SpiRxIntEnd=0;
}

void HS_SPI_ERROR_CHECK(void)
{
	printf("\nError check");
	pISR_SPI0 = (unsigned)HSPI_ERR_Int;
	rSPI_INT_EN |= INT_TRAILING | INT_RX_OVERRUN | INT_RX_UNDERRUN | INT_TX_FIFORDY;	
	rINTMSK &= ~(BIT_SPI0);
}

void InitHSPI(U32 MasterSlave, U32 Cpol, U32 Cpha, U32 ClkSel)
{
	float uPrescaler = .0;

	if(BYTEOPERATION == 1)
		PacketCntValue = DataCnt;
	else
		PacketCntValue = DataCnt*4;

	if (ClkSel == HSPI_PCLK)
		uPrescaler = (float)(PCLK/2/Baudrate) - 1;
	else if(ClkSel == HSPI_EPLL)
		uPrescaler = (float)(ECLK/2/Baudrate) - 1;

	printf("\nuPrescaler = %f",uPrescaler);

	// 1. Set Tranfer Type
	rCH_CFG = (rCH_CFG & ~(0x3f)) |
		((MasterSlave == Master)? CH_MASTER : CH_SLAVE) |
		((Cpol == CPOLHIGH)? CH_RISING : CH_FALLING) |
		((Cpha == FORMAT_A)? CH_FORMAT_A : CH_FORMAT_B);

	// 2. Clock Config
	rCLK_CFG = (rCLK_CFG & ~(0x7ff)) |
		((ClkSel == HSPI_PCLK)? CLK_CLKSEL_PCLK : CLK_CLKSEL_ECLK) |
		((MasterSlave == Master)? CLK_ENCLK_ENABLE : CLK_ENCLK_DISABLE)| // SPI clk enable
		PRESCALER((U8)uPrescaler);

	// 3. Mode Config
	rMODE_CFG = (rMODE_CFG & ~(0x1fffffff)) |
		TRAIL_CNT(0x3ff) |
		((BYTEOPERATION == 0)? MODE_BUS_SZ_WORD : MODE_BUS_SZ_BYTE) |
		RX_TRIG_LVL(m_uRxTrigLvl) |
		TX_TRIG_LVL(m_uTxTrigLvl) |
		//(1<<4)|
		((BURSTOPERATION == 1)? MODE_BUS_4BURST : MODE_BUS_SINGLE);	
}

void TxDMAInit(U32 uSrcAddr, U32 uDstAddr,U32 uDataCnt)
{
	U32 uIsSrcApb = LOCAHB; 
	U32 uIsDstApb = LOCAPB;
	U32 bSrcFixed = ADDRINC;
	U32 bDstFixed = ADDRFIX;
	U32 TC=0;
	U32 eDataSz=0, Burst=0;

	if(BYTEOPERATION == 1  && BURSTOPERATION == 1)
		{
		eDataSz = HSPI_BYTE;
		TC = uDataCnt/4;
		}
	else if(BYTEOPERATION == 1  && BURSTOPERATION == 0)
		{
		eDataSz = HSPI_BYTE;
		TC = uDataCnt;
		}
	else if(BYTEOPERATION == 0  && BURSTOPERATION == 1) 
		{
		eDataSz = HSPI_WORD;
		TC = uDataCnt/4;
		}
	else if(BYTEOPERATION == 0  && BURSTOPERATION == 0) 
		{
		eDataSz = HSPI_WORD;
		TC = uDataCnt;
		}
	Burst = BURSTOPERATION;

	printf("\nTC = %x",TC);
	
	rDISRC0 = uSrcAddr;
	rDISRCC0 =  uIsSrcApb<<1 | bSrcFixed<<0;
	rDIDST0 = uDstAddr;
	rDIDSTC0 = uIsDstApb<<1 | bDstFixed<<0;
	rDCON0 = (rDCON0 & ~(0xffffffff)) |(U32)( (1<<31) |(1<<29) |(Burst<<28) |(0<<27)|(1<<24) |(1<<22) |(eDataSz<<20) |(TC));
	rDMAREQSEL0 = (0 <<1) | 1;
}

void RxDMAInit(U32 uSrcAddr, U32 uDstAddr, U32 uDataCnt)
{
	U32 uIsSrcApb = LOCAPB; 
	U32 uIsDstApb = LOCAHB;
	U32 bSrcFixed = ADDRFIX;
	U32 bDstFixed = ADDRINC;
	U32 TC=0;
	U32 eDataSz=0, Burst=0;

	if(BYTEOPERATION == 1  && BURSTOPERATION == 1)
		{
		eDataSz = HSPI_BYTE;
		TC = uDataCnt/4;
		}
	else if(BYTEOPERATION == 1  && BURSTOPERATION == 0)
		{
		eDataSz = HSPI_BYTE;
		TC = uDataCnt;
		}
	else if(BYTEOPERATION == 0  && BURSTOPERATION == 1) 
		{
		eDataSz = HSPI_WORD;
		TC = uDataCnt/4;
		}
	else if(BYTEOPERATION == 0  && BURSTOPERATION == 0) 
		{
		eDataSz = HSPI_WORD;
		TC = uDataCnt;
		}
	Burst = BURSTOPERATION;
	
	printf("\nTC = %x",TC);
	
	rDISRC1 = uSrcAddr;
	rDISRCC1 =  uIsSrcApb<<1 | bSrcFixed<<0;
	rDIDST1 = uDstAddr;
	rDIDSTC1 = uIsDstApb<<1 | bDstFixed<<0;
	rDCON1 = (rDCON1 & ~(0xffffffff)) | (U32)((1<<31) |(1<<29) |(Burst<<28) |(0<<27) |(1<<24) |(1<<22) |(eDataSz<<20) |(TC)); 
	rDMAREQSEL1 = (1 <<1) | 1;
}

void __irq HSPI_Tx_Int(void)
{
	U32 i=0;
	U32 x,TxTriglevel =0;
	
	rINTMSK |= (BIT_SPI0);
	ClearPending(BIT_SPI0);
	rPENDING_CLR |= (1<<4) | (1<<3) | (1<<2) | (1<<1);

	#if BYTEOPERATION
		x = ((rSPI_STATUS>>6)&0x7f);
		TxTriglevel = 64 -x;
	#else
		x = ((rSPI_STATUS>>6)&0x7f)/4;
		TxTriglevel = 16-x;
	#endif
	
	while (i<TxTriglevel && TransferdDataCnt < DataCnt) // check if Rx Fifo empty
		{				
			rSPI_TX_DATA = (*(TxBufAddr+TransferdDataCnt));
			TransferdDataCnt++;
			i++;
			//printf("TransferdDataCnt ISR= %d\n",TransferdDataCnt);			
		}
	rINTMSK &= ~(BIT_SPI0);

	if(TransferdDataCnt == DataCnt)
		{
			rINTMSK |= (BIT_SPI0);
			ClearPending(BIT_SPI0);
			SpiTxIntEnd = 1;
		}				
}

void __irq HSPI_Rx_Int(void)
{
	int i=0;
	int RxTriglevel=0;
	
	rINTMSK |= (BIT_SPI0);
	ClearPending(BIT_SPI0);
	rPENDING_CLR |= (1<<4) | (1<<3) | (1<<2) | (1<<1);

	#if BYTEOPERATION
		RxTriglevel = ((rSPI_STATUS>>13)&0x7f);
	#else
		RxTriglevel = ((rSPI_STATUS>>13)&0x7f)/4;
	#endif
	
	//printf("\nRxTriglevel = %x",(rSPI_STATUS>>13)&0x7f);
	while (i<RxTriglevel) // check if Rx Fifo empty
		{
			*(RxBufAddr+ReceivedDataCnt) = rSPI_RX_DATA;
			i++;
			ReceivedDataCnt ++;
			//printf("TransferdDataCnt ISR= %d\n",ReceivedDataCnt);					
		}

	rINTMSK &= ~(BIT_SPI0);

	if(ReceivedDataCnt == DataCnt)
		{
			rINTMSK |= (BIT_SPI0);
			ClearPending(BIT_SPI0);
			SpiRxIntEnd = 1;
		}
}

void __irq HSPI_Int(void)
{
	int i=0;
	int RxReadCnt=0;
	int x, TxWriteCnt=0;	
	int Status = 0;

	rINTMSK |= (BIT_SPI0);
	ClearPending(BIT_SPI0);

	Status = rSPI_STATUS;	
	
	rPENDING_CLR |= (1<<4) | (1<<3) | (1<<2) | (1<<1);


	if(Status & (1<<1) || Status & (1<<20))//Read FIFO ready
		{
			if(BYTEOPERATION)
				{
				RxReadCnt = ((rSPI_STATUS>>13)&0x7f);
				}
			else
				RxReadCnt = ((rSPI_STATUS>>13)&0x7f)/4;			
			
			while (i<RxReadCnt) // check if Rx Fifo empty
			{
				*(RxBufAddr+ReceivedDataCnt) = rSPI_RX_DATA;
				i++;
				ReceivedDataCnt ++;
				//printf("Rx ISR cnt= %d\n",ReceivedDataCnt);
				//if(ReceivedDataCnt == DataCnt)
				//	break;
			}
		}
	else if(Status & (1<<0))//Write FIFO ready
		{
			if(BYTEOPERATION)
				{
				x = ((rSPI_STATUS>>6)&0x7f);
				TxWriteCnt = 64 -x;
				}
			else
				{
				x = ((rSPI_STATUS>>6)&0x7f)/4;
				TxWriteCnt = 16-x;
				}
			
			while (i<TxWriteCnt && TransferdDataCnt < DataCnt) // check if Rx Fifo empty
			{				
				rSPI_TX_DATA = (*(TxBufAddr+TransferdDataCnt));
				TransferdDataCnt++;
				i++;
				//printf("Tx ISR cnt= %d\n",TransferdDataCnt);
				//if(TransferdDataCnt == DataCnt)
				//	break;
			}			
		}
/*
	else if(1<<2)
		{
		printf("\nTx Underrun Error");
		}
	else if(1<<3)
		{
		printf("\nTx Overrun Error");
		}
	else if(1<<4)
		{
		printf("\nRx Underrun Error");
		}
	else if(1<<5)
		{
		printf("\nRx Overrun Error");
		}	
*/
	rINTMSK &= ~(BIT_SPI0);

	if(TransferdDataCnt == DataCnt && ReceivedDataCnt == DataCnt)
		{
		rINTMSK |= (BIT_SPI0);
		ClearPending(BIT_SPI0);		
		SpiTxIntEnd = 1;
		SpiRxIntEnd = 1;
		}
}

void __irq DmaDone(void)
{
	rINTMSK|=BIT_DMA;
	ClearPending(BIT_DMA);

	if(rSUBSRCPND & BIT_SUB_DMA0)
		{
			printf("\nTX DMA Done");
			SpiTxDmaEnd=1;
			rINTSUBMSK |= BIT_SUB_DMA0;
			rSUBSRCPND |= BIT_SUB_DMA0;
		}
	else if(rSUBSRCPND & BIT_SUB_DMA1)
		{
			printf("\nRX DMA Done");
			SpiRxDmaEnd=1;
			rINTSUBMSK |= BIT_SUB_DMA1;
			rSUBSRCPND |= BIT_SUB_DMA1;		
		}
}

void __irq HSPI_ERR_Int(void)
{
	rINTMSK |= (BIT_SPI0);
	ClearPending(BIT_SPI0);
	printf("\nError ISR");
	
	if(rSPI_STATUS & (INT_RX_OVERRUN))
		printf("\nRx Overrun Error");
	else if(rSPI_STATUS & (INT_RX_UNDERRUN))
		printf("\nRx Underrun Error");
	else if(rSPI_STATUS & (INT_TX_OVERRUN))
		printf("\nRx Overrun Error");
	else if(rSPI_STATUS & (INT_TX_UNDERRUN))
		printf("\nTx Underrun Error");

	rSPI_STATUS = INT_RX_OVERRUN |INT_RX_UNDERRUN | INT_TX_OVERRUN |INT_TX_UNDERRUN;
}

void CompareData(U32 a0, U32 a1, U32 bytes)
{
	U32 * pD0 = (U32 *)a0;
	U32 * pD1 = (U32 *)a1;
	U32  ErrCnt = 0;
	U32 i;

	#if BYTEOPERATION
		bytes = DataCnt;
	#else
		bytes = DataCnt/4;
	#endif

	for (i=0; i<bytes; i++)
	{
		if (*pD0 != *pD1) 
		{
			printf("\n%08x=%02x <-> %08x=%02x", pD0, *pD0, pD1, *pD1);
			ErrCnt++;
		}
		pD0++;
		pD1++;
	}
	printf("\nTotal Error cnt = %d",ErrCnt);

	if(ErrCnt == 0)
		printf("\nData Compare Ok\n");
}

void CompareDataByte(U8 a0, U8 a1, U8 bytes)
{
	U8 * pD0 = (U8 *)a0;
	U8 * pD1 = (U8 *)a1;
	U8  ErrCnt = 0;
	U32 i;

	for (i=0; i<bytes; i++)
	{
		if (*pD0 != *pD1) 
		{
			printf("\n%08x=%02x <-> %08x=%02x", pD0, *pD0, pD1, *pD1);
			ErrCnt++;
		}
		pD0++;
		pD1++;
	}
	printf("\nTotal Error cnt = %d",ErrCnt);

	if(ErrCnt == 0)
		printf("\nData Compare Ok\n");
}

void Reset(void)
{
	rCH_CFG |= (1<<5);
	printf("\nHS SPI reset\n");
	rCH_CFG &= ~(1<<5);
}

void nSSLow(void)
{
	rSLAVE_SEL = 0;
}

void nSSHigh(void)
{
	rSLAVE_SEL = 1;
}

void GPIOPortSet(void)
{
	rMISCCR |= (U32)(1<<31);
	rGPECON = rGPECON & ~(0x3f<<22) | (1<<27) | (1<<25) | (1<<23); // SPICLK0, SPIMOSI0, SPIMISO0
	rGPLCON = rGPLCON & ~(0x3ff<<20) | (1<<29) | (1<<27) | (1<<25) | (1<<23) | (1<<21); // SS1, SS0, SPIMISO1, SPIMOSI1, SPICLK1
}

⌨️ 快捷键说明

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