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

📄 spi01.c

📁 三星s3c2460开发板完整功能测试代码
💻 C
📖 第 1 页 / 共 5 页
字号:
/************************
 SPI Test       
 ************************/


#include <stdio.h>
#include <string.h>
#include "2460addr.h"
#include "2460lib.h"
#include "spi01.h"
#include "pll.h"
#include "type.h"

#define SPITX_COUNT 0x50
#define SPIRX_COUNT 0x50
#define SPI0_COUNT 0x81
#define SPI1_COUNT 0x81


#define SPI_BUFFER0 _NONCACHE_STARTADDRESS
#define SPI_BUFFER1 _NONCACHE_STARTADDRESS+0x1000

#define DMA1_RxBUFFER0 _NONCACHE_STARTADDRESS+0x2000
#define DMA1_TxBUFFER0 _NONCACHE_STARTADDRESS+0x3000
#define DMA3_RxBUFFER1 _NONCACHE_STARTADDRESS+0x4000
#define DMA3_TxBUFFER1 _NONCACHE_STARTADDRESS+0x5000

#define SPI0_POLARITY	1	//0:active high, 1:active low
#define SPI1_POLARITY	1
#define SPI0_FORMAT		0	//0:format A, 1: format B
#define SPI1_FORMAT		0

#define S3C2460A	1
#define S3C2460X	0


#define SPI_DMA_MODE	(2<<5)
#define SPI_POLLING_MODE	(0<<5)
#define SPI_INT_MODE (1<<5)
#define SCKEN	(1<<4)
#define SCKDIS	(0<<4)
#define MASTER   (1<<3)
#define SLAVE	(0<<3)
#define CPOLHIGH (0<<2)
#define CPOLLOW (1<<2)
#define FORMATA (0<<1)
#define FORMATB (1<<1)
#define NORMALMODE (0<<0)
#define AUTOGARBAGE (1<<0)


void __irq Spi0_Int(void);
void __irq Spi01_Int(void);
void __irq Spi10_Int(void);

void __irq Dma1Tx_Int(void);//SPI 0
void __irq DmaTx_Int(void);

void Init_DMA_Regs(uint8 ch);


volatile char *spi0TxStr,*spi0RxStr;
volatile char *spi1TxStr,*spi1RxStr;
volatile int end0SpiTx;
volatile int end0SpiRx;
volatile int end1SpiTx;
volatile int end1SpiRx;
volatile char transdata=0;
volatile int spi0Rx_done;
volatile int spi1Rx_done;

unsigned char *tx0_ptr;
unsigned char *tx1_ptr;
unsigned char *rx0_ptr;
unsigned char *rx1_ptr;
uint8 tmp_data[10];
uint8 *garbage=tmp_data;

volatile int tx_dma1Done;
volatile int rx_dma1Done;
volatile int tx_dma3Done;
volatile int rx_dma3Done;

volatile int spi_flag;
volatile int spi_garbage;
volatile int spi_datacount;

unsigned int spi_rGPHCON, spi_rGPHDAT,spi_rGPHPU;

extern unsigned int Pclk;


void * spi_func[][2]=
{
#if 1
	(void *)Test_Spi0_MS_int,				"SPI0 RxTx Int			        ",
	(void *)Test_Spi0_MS_poll,				"SPI0 RxTx POLL 		        ",
	
	//these four function must be revised..
	//	refer to SPI 1 test code
	(void *)Test_Spi0_M_Tx_Int, 			"SPI0 Master Tx INT",
	(void *)Test_Spi0_M_Rx_Int, 			"SPI0 Master Rx INT",
	(void *)Test_Spi0_S_Tx_Int, 			"SPI0 Slave Tx INT ",
	(void *)Test_Spi0_S_Rx_Int, 			"SPI0 Slave Rx INT ",
	(void *)Test_Spi0_M_Tx_Polling, 		"SPI0 Master Tx Poll  ",
	(void *)Test_Spi0_M_Rx_Polling, 		"SPI0 Master Rx Poll  ",
	(void *)Test_Spi0_S_Tx_Polling, 		"SPI0 Slave Tx Poll  ",	
	(void *)Test_Spi0_S_Rx_Polling, 		"SPI0 Slave Rx Poll  ",
	(void *)Test_Spi0_M_Tx_DMA1, 			"SPI0 Master Tx DMA1 ",
	(void *)Test_Spi0_M_Rx_DMA1, 			"SPI0 Master Rx DMA1 ",
	(void *)Test_Spi0_S_Tx_DMA1, 			"SPI0 Slave Tx DMA1  ",
	(void *)Test_Spi0_S_Rx_DMA1, 			"SPI0 Slave Rx DMA1  ",
	
	(void *)Test_Spi1_MS_int,				"SPI1 RxTx Int 	  ",
	(void *)Test_Spi1_MS_poll,				"SPI1 RxTx POLL 	 ",
	
	(void *)Test_Spi1_M_Tx_Int, 			"SPI1 Master Tx INT",
	(void *)Test_Spi1_M_Rx_Int, 			"SPI1 Master Rx INT",
	(void *)Test_Spi1_S_Tx_Int, 			"SPI1 Slave Tx INT ",
	(void *)Test_Spi1_S_Rx_Int, 			"SPI1 Slave Rx INT ",
	(void *)Test_Spi1_M_Tx_Polling, 		"SPI1 Master Tx Poll  ",
	(void *)Test_Spi1_M_Rx_Polling, 		"SPI1 Master Rx Poll  ",
	(void *)Test_Spi1_S_Tx_Polling, 		"SPI1 Slave Tx Poll  ",
	(void *)Test_Spi1_S_Rx_Polling, 		"SPI1 Slave Rx Poll  ",
	(void *)Test_Spi1_M_Tx_DMA3, 			"SPI1 Master Tx DMA3 ",
	(void *)Test_Spi1_M_Rx_DMA3, 			"SPI1 Master Rx DMA3 ",
	(void *)Test_Spi1_S_Tx_DMA3, 			"SPI1 Slave Tx DMA3  ",
	(void *)Test_Spi1_S_Rx_DMA3, 			"SPI1 Slave Rx DMA3  ",
	
	(void *)Test_Spi01_MS_Int,              "SPI0:Master, SPI1:Slave INT    ",
	(void *)Test_Spi01_SM_Int,              "SPI0:Slave, SPI1:Master INT    ",
	
	(void *)Test_SPI01_MS_DMA_TxRx,         "SPI0:Master(Tx), SPI1:Slave(Rx) DMA",
	(void *)Test_SPI01_MS_DMA_RxTx,         "SPI0:Master(Rx), SPI1:Slave(Tx) DMA",
	(void *)Test_Spi01_SM_DMA_RxTx,         "SPI0:Slave(Rx), SPI1:Master(Tx) DMA",
	(void *)Test_Spi01_SM_DMA_TxRx,         "SPI0:Slave(Tx), SPI1:Master(Rx) DMA",
#else	//SPI 0 is not working normally		
	(void *)Test_Spi1_M_Tx_Int, 			"SPI1 Master Tx INT",
	(void *)Test_Spi1_M_Rx_Int, 			"SPI1 Master Rx INT",
	(void *)Test_Spi1_S_Tx_Int, 			"SPI1 Slave Tx INT ",
	(void *)Test_Spi1_S_Rx_Int, 			"SPI1 Slave Rx INT ",
	
	(void *)Test_Spi1_M_Tx_Polling, 		"SPI1 Master Tx Poll  ",
	(void *)Test_Spi1_M_Rx_Polling, 		"SPI1 Master Rx Poll  ",
	(void *)Test_Spi1_S_Tx_Polling, 		"SPI1 Slave Tx Poll  ",
	(void *)Test_Spi1_S_Rx_Polling, 		"SPI1 Slave Rx Poll  ",
	
	(void *)Test_Spi1_M_Tx_DMA3, 			"SPI1 Master Tx DMA3 ",
	(void *)Test_Spi1_M_Rx_DMA3, 			"SPI1 Master Rx DMA3 ",
	(void *)Test_Spi1_S_Tx_DMA3, 			"SPI1 Slave Tx DMA3  ",
	(void *)Test_Spi1_S_Rx_DMA3, 			"SPI1 Slave Rx DMA3  ",
#endif
	0,0
};

void Ch15_SPI(void)
{
	while(1)
	{
		int i = 0;
  		printf("\n");
		while(1)
		{	//display menu
			printf("%2d:%s\n",i,spi_func[i][1]);
			i++;
			if(i%2 == 0)
				printf("\n");
			if((int)(spi_func[i][0])==0)
			{
				printf("\n");
				break;
			}
		}
		printf("\nSelect the function to test : ");
		i = GetIntNum();
		printf("\n");
	 	if(i==-1) break;
		if(i>=0 && (i<(sizeof(spi_func)/8)) ) 
		( (void (*)(void)) (spi_func[i][0]) )();			
	}
}


void SPI_Port_Set(void)
{
   spi_rGPHCON=rGPHCON;
    spi_rGPHDAT=rGPHDAT;
    spi_rGPHPU=rGPHPU;
}

void SPI_Port_Return(void)
{
    rGPHCON=spi_rGPHCON;
    rGPHDAT=spi_rGPHDAT;
    rGPHPU=spi_rGPHPU;
}

void Master_nSS_Con0(int Set)
{
    rGPHDAT=rGPHDAT&~(1<<15)|(Set<<15);
}

void Master_nSS_Con1(int Set)
{
    rGPHDAT=rGPHDAT&~(1<<7)|(Set<<7);
}

void SPI0_Port_Init(char MASorSLV) // for 496 pkg
{
	rGPHPU=rGPHPU&~(0xf<<12);//Disable sclk. 		Enable MISO, MOSI.
      
	if(MASorSLV==1)
	{
      rGPHDAT|=(1<<15); // Master(GPHCON_Output=High)
      rGPHCON=rGPHCON&~(0xff<<24)|(0x6a<<24); // Master(GPHCON15_Output)
   	}
	else if (MASorSLV==0)  rGPHCON=rGPHCON&~(0xff<<24)|(0xaa<<24);
   
 }

void SPI1_Port_Init(char MASorSLV)
{
	rGPHPU=rGPHPU&~(0xf<<4);//Disable sclk.		 Enable MISO, MOSI.
      
   if(MASorSLV==1)
   {
      rGPHDAT|=(1<<7); // Master(GPHCON_Output=High)
      rGPHCON=rGPHCON&~(0xff<<8)|(0x7f<<8); // Master(GPHCON15_Output)
   }
   else if (MASorSLV==0)  rGPHCON=rGPHCON&~(0xff<<8)|(0xff<<8);
 }


int ClockSelection(void)
{
	int i;
	
	printf("Clock selection  0.PCLK/2  1.PCLK/4  2.PCLK/6 ... 63.PCLK/128 \n");
	i = GetIntNum();
	if ( (i<0)||(i>63) ) i = 0;
	
	return i;	
}


void __irq Spi0_Int(void)
{
    unsigned int status;

    rINTMSK|=BIT_IIC_SPI;
    rINTSUBMSK|=BIT_SUB_SPI0;
   
    ClearPending(BIT_IIC_SPI);
    rSUBSRCPND|=BIT_SUB_SPI0;
    status=rSPSTA0;

    if(status&0x6) 
    	printf("Data Collision or Multi Master Error(0x%x)!!!\n", status);
    while(!(status&0x1));   //Check ready state
    *spi0RxStr++=rSPRDAT0;    //First Rx data is garbage data
    
    if(*spi0TxStr!='\0') {
    	rSPTDAT0=*spi0TxStr++;
       rINTMSK&=~BIT_IIC_SPI;
       rINTSUBMSK&=~BIT_SUB_SPI0;
	}
	else
    {
    	*spi0RxStr='\0';
		end0SpiTx=1;
    }
}


void Test_Spi0_MS_int(void)
{
    char *txStr,*rxStr,i;
    SPI_Port_Set();
    SPI0_Port_Init(1); 
    printf("[SPI0 Interrupt Tx/Rx Self-Test]\n");
    printf("Connect SPIMOSI0 into SPIMISO0.\n");

    pISR_IIC_SPI=(unsigned)Spi0_Int;
    end0SpiTx=0;
    spi0TxStr="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ\n";

    spi0RxStr=(char *) SPI_BUFFER0;
    txStr=(char *)spi0TxStr;
    rxStr=(char *)spi0RxStr;
	
	rSPPRE0=ClockSelection();	// Baudrate=PCLK/2
	printf("SPI clock is %3.2fMHz!!\n", (float)((PCLK)/(2*(rSPPRE0+1)))/1000000 );
	
    rSPCON0=(1<<5)|(1<<4)|(1<<3)|(SPI0_POLARITY<<2)|(SPI0_FORMAT<<1)|(0<<0);//int,en-SCK,master,low,A,normal
    rSPPIN0=(0<<2)|(1<<1)|(0<<0);//dis-ENMUL,SBO,release
    rINTMSK=~(BIT_IIC_SPI);
    rINTSUBMSK=~(BIT_SUB_SPI0);

    while(end0SpiTx==0);

    rSPCON0=(0<<5)|(0<<4)|(1<<3)|(SPI0_POLARITY<<2)|(SPI0_FORMAT<<1)|(0<<0);//Poll,dis-SCK,master,low,A,normal
    printf("Tx Strings:%s\n",txStr);
    printf("Rx Strings:%s :",rxStr+2);//remove first dummy data
    if(strcmp(rxStr+2,txStr)==0)
        printf("O.K.\n");
    else 
        printf("ERROR!!!\n");

    SPI_Port_Return();
}


void Test_Spi0_MS_poll(void)
{
    char *txStr,*rxStr,i;
     SPI_Port_Set();
    SPI0_Port_Init(1); 
    printf("[SPI Polling Tx/Rx Self-Test]\n");
    printf("Connect SPIMOSI0 into SPIMISO0.\n");
    end0SpiTx=0;
    spi0TxStr="ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789\n";
    spi0RxStr=(char *) SPI_BUFFER0;
    txStr=(char *)spi0TxStr;
    rxStr=(char *)spi0RxStr;

    rSPPRE0=ClockSelection();	// Baudrate=PCLK/2
	printf("SPI clock is %3.2fMHz!!\n", (float)((PCLK)/(2*(rSPPRE0+1)))/1000000 );
    rSPCON0=(0<<5)|(1<<4)|(1<<3)|(SPI0_POLARITY<<2)|(SPI0_FORMAT<<1)|(0<<0);//Polling,en-SCK,master,low,A,normal
    rSPPIN0=(0<<2)|(1<<1)|(0<<0);//dis-ENMUL,SBO,release
    
    while(end0SpiTx==0)
    {
		if(rSPSTA0&0x1)   //Check Tx ready state    
		{
		  if(*spi0TxStr!='\0')
			rSPTDAT0=*spi0TxStr++;
		  else
			end0SpiTx=1;
		  while(!(rSPSTA0&0x1));   //Check Rx ready state 
		  *spi0RxStr++=rSPRDAT0;
		}
    }

    rSPCON0=(0<<5)|(0<<4)|(1<<3)|(SPI0_POLARITY<<2)|(SPI0_FORMAT<<1)|(0<<0);//Polling,dis-SCK,master,low,A,normal
    *(spi0RxStr)='\0';//remove last dummy data & attach End of String(Null)
    
    printf("Tx Strings:%s\n",txStr);
    printf("Rx Strings:%s :",rxStr+1);
    
    if(strcmp(rxStr+1,txStr)==0)
        printf("O.K.\n");
    else 
        printf("ERROR!!!\n");

    SPI_Port_Return();
}

/////////////////////////// Interrupt //////////////////////////

uint8 int_tx0data[SPI0_COUNT];
uint8 int_rx0data[SPI0_COUNT+2];
uint8 int_tx0_cnt=0;
uint8 int_rx0_cnt=0;

void __irq Spi0_Tx_Int(void)
{
    unsigned int status;
    rINTMSK|=BIT_IIC_SPI;
    rINTSUBMSK|=BIT_SUB_SPI0;
	
    ClearPending(BIT_IIC_SPI);
    rSUBSRCPND=BIT_SUB_SPI0;
    status=rSPSTA0;
    
    if(status&0x6) 
    	printf("Data Collision or Multi Master Error(0x%x)!!!\n", status);
    while(!(status&0x1));   //Check ready state
  
    if(int_tx0_cnt < (SPI0_COUNT)) 
    {
    	rSPTDAT0 = int_tx0data[int_tx0_cnt++];
		rINTMSK&=~BIT_IIC_SPI;
		rINTSUBMSK&=~BIT_SUB_SPI0;
    }
    else
    {
        end0SpiTx=1;
    }
}

void __irq Spi0_Rx_Int(void)
{
    unsigned int status;
    
    rINTMSK|=BIT_IIC_SPI;
    rINTSUBMSK|=BIT_SUB_SPI0;
	
    ClearPending(BIT_IIC_SPI);
    rSUBSRCPND=BIT_SUB_SPI0;
    status=rSPSTA1;
    
    if(status&0x6) 
    	printf("Data Collision or Multi Master Error(0x%x)!!!\n", status);
    	
    while(!(status&0x1));   //Check ready state
    int_rx0data[int_rx0_cnt++]=rSPRDAT0;
    
    if(int_rx0_cnt < (SPI0_COUNT+1))
    {
    	rINTMSK&=~BIT_IIC_SPI;
		rINTSUBMSK&=~BIT_SUB_SPI0;
    }
    else
    {
    	end0SpiRx=1;    
    }
    
}

void Test_Spi0_M_Tx_Int(void)
{
    char *rxStr,*txStr,i;

    SPI_Port_Set();
    SPI0_Port_Init(1); // Master
    Master_nSS_Con0(1);
    printf("[SPI Interrupt Master TxRx test]\n");
    printf("This test should be configured two boards\nStart Slave TxRx first.\n");
    
	//init rSPCON1
	rSPCON0 = (1<<3);

    pISR_IIC_SPI=(unsigned)Spi0_Tx_Int;
    end0SpiTx=0;
	for(i=0;i<SPI0_COUNT;i++)
		int_tx0data[i]=i+1;
		
    rSPPRE0=ClockSelection();	// Baudrate=PCLK/2
	printf("SPI clock is %3.2fMHz!!\n", (float)((PCLK)/(2*(rSPPRE0+1)))/1000000 );
    rSPPIN0=(0<<2)|(1<<1)|(0<<0);//dis-ENMUL,SBO,release
    rSPCON0=(1<<5)|(1<<4)|(1<<3)|(SPI0_POLARITY<<2)|(SPI0_FORMAT<<1)|(0<<0);//int,en-SCK,master,low,A,normal
    
    Master_nSS_Con0(0); // Activate nSS 
    rINTMSK&=~(BIT_IIC_SPI);
    rINTSUBMSK&=~(BIT_SUB_SPI0);
    
    while((end0SpiTx==0)&&(!Uart_GetKey()));
    
    Master_nSS_Con0(1);

	//init rSPCON1
	rSPCON0 = (1<<3);
    
    printf("Tx End...\n");
    printf("Tx data:\n");
    
    for(i=0;i<SPI0_COUNT;i++)
    	printf("0x%02x,",int_tx0data[i]);
    
    printf("\n");
    int_tx0_cnt = 0;
    
    SPI_Port_Return();
}

void Test_Spi0_M_Rx_Int(void)
{
    char *rxStr,*txStr,i,rx_tmp;

    SPI_Port_Set();
    SPI0_Port_Init(1); // Master
    Master_nSS_Con0(1);
    printf("[SPI Interrupt Master TxRx test]\n");
    printf("This test should be configured two boards\nStart Slave TxRx first.\n");
    
	//init rSPCON1
	rSPCON0 = (1<<3);

    pISR_IIC_SPI=(unsigned)Spi0_Rx_Int;
    end0SpiRx=0;
	for(i=0;i<(SPI0_COUNT+1);i++)
		int_rx0data[i]=0;
    	
    rSPPRE0=ClockSelection();	// Baudrate=PCLK/2
	printf("SPI clock is %3.2fMHz!!\n", (float)((PCLK)/(2*(rSPPRE0+1)))/1000000 );
		
    rSPPIN0=(0<<2)|(1<<1)|(0<<0);//dis-ENMUL,SBO,release
    rSPCON0=(1<<5)|(1<<4)|(1<<3)|(SPI0_POLARITY<<2)|(SPI0_FORMAT<<1)|(1<<0);//int,en-SCK,master,low,A,normal
    
    Master_nSS_Con0(0); // Activate nSS 
	
    rINTMSK&=~(BIT_IIC_SPI);
    rINTSUBMSK&=~(BIT_SUB_SPI0);
    
    while((end0SpiRx==0)&&(!Uart_GetKey()));
    
    Master_nSS_Con0(1);

⌨️ 快捷键说明

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