📄 spi01.c
字号:
/************************
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 + -