#include <string.h>
#include "2440addr.h"
#include "2440lib.h"
#include "spi.h"
#include "def.h"
#define spi_count 0x80
#define SPI_BUFFER _NONCACHE_STARTADDRESS
void __irq Spi_Int(void);
//void __irq Spi_M_Rx_Int(void);
//void __irq Spi_S_Tx_Int(void);
void __irq Dma1Tx_Int(void);
void __irq Dma1Rx_Int(void);
void Test_Spi1_MS_poll(void); // added by junon
volatile char *spiTxStr,*spiRxStr;
volatile int endSpiTx;
volatile int tx_dma1Done;
volatile int rx_dma1Done;
unsigned int spi_rGPECON,spi_rGPEDAT,spi_rGPEUP;
unsigned int spi_rGPGCON,spi_rGPGDAT,spi_rGPGUP;
unsigned int spi_rGPDCON,spi_rGPDDAT,spi_rGPDUP;
/****************************************************************
* SMDK2400 SPI configuration *
* GPG2=nSS0, GPE11=SPIMISO0, GPE12=SPIMOSI0, GPE13=SPICLK0 *
* GPG3=nSS1, GPG5 =SPIMISO1, GPG6 =SPIMOSI1, GPG7 =SPICLK1 *
* SPI1 is tested by OS(WINCE). So, Only SPI0 is tested by this code *
****************************************************************/
void * func_spi_test[][2]=
{
// "0123456789012345" max 15자 로한정하여 comment하세요.
//SPI
(void *) Test_Spi_MS_int, "SPI0 RxTx Int ",
(void *)Test_Spi_MS_poll, "SPI0 RxTx POLL ",
(void *)Test_Spi_M_Int, "SPI0 M Rx INT ",
(void *)Test_Spi_S_Int, "SPI0 S Tx INT ",
(void *)Test_Spi_M_Tx_DMA1, "SPI0 M Tx DMA1 ",
(void *)Test_Spi_S_Rx_DMA1, "SPI0 S Rx DMA1 ",
(void *)Test_Spi_M_Rx_DMA1, "SPI0 M Rx DMA1 ",
(void *)Test_Spi_S_Tx_DMA1, "SPI0 S Tx DMA1 ",
(void *)Test_Spi1_MS_poll, "SPI1 RxTx POLL ",
0,0
};
void Spi_Test(void)
{
int i;
while(1)
{
Uart_Printf("\n====== SPI Test program start ======\n");
Uart_Printf("1 : SPI0 RxTx Int \n");
Uart_Printf("2 : SPI0 RxTx POLL\n");
Uart_Printf("3 : SPI0 M Rx INT\n");
Uart_Printf("4 : SPI0 S Tx INT\n");
Uart_Printf("5 : SPI0 M Tx DMA1\n");
Uart_Printf("\n");
Uart_Printf("6 : SPI0 S Rx DMA1\n");
Uart_Printf("7 : SPI0 M Rx DMA1\n");
Uart_Printf("8 : SPI0 S Tx DMA1\n");
Uart_Printf("9 : SPI1 RxTx POLL\n");
Uart_Printf("\nPress Enter key to exit : ");
i = Uart_GetIntNum();
if(i==-1) break; // return.
// if(i>=0 && (i<((sizeof(func_spi_test)-1)/8)) ) // select and execute...
// ( (void (*)(void)) (func_spi_test[i][0]) )();
switch(i)
{
case 1: Test_Spi_MS_int();
break;
case 2: Test_Spi_MS_poll();
break;
case 3: Test_Spi_M_Int();
break;
case 4: Test_Spi_S_Int();
break;
case 5: Test_Spi_M_Tx_DMA1();
break;
case 6: Test_Spi_S_Rx_DMA1();
break;
case 7: Test_Spi_M_Rx_DMA1();
break;
case 8: Test_Spi_S_Tx_DMA1();
break;
case 9: Test_Spi1_MS_poll();
break;
default:
break;
}
}
Uart_Printf("\n====== SPI Test program end ======\n");
}
void SPI_Port_Init(int MASorSLV)
{
// SPI channel 0 setting
spi_rGPECON=rGPECON;
spi_rGPEDAT=rGPEDAT;
spi_rGPEUP=rGPEUP;
rGPECON=((rGPECON&0xf03fffff)|0xa800000); // using SPI 0
rGPEUP = (rGPEUP & ~(7<<11)) | (1<<13);
spi_rGPGCON=rGPGCON;
spi_rGPGDAT=rGPGDAT;
spi_rGPGUP=rGPGUP;
if(MASorSLV==1)
{
rGPGCON=((rGPGCON&0xffffffcf)|0x10); // Master(GPIO_Output)
rGPGDAT|=0x4; // Activate nSS
}
else
rGPGCON=((rGPGCON&0xffffffcf)|0x30); // Slave(nSS)
rGPGUP|=0x4;
/*
// SPI channel 1-1 setting --> Key board
rGPGCON=(rGPGCON&0xffff033f)|(3<<6)|(3<<10)|(3<<12)|(1<<14); // MISO1, MOSI1, CLK1, Master
rGPGDAT|=0x8;
rGPGUP=(rGPGUP&~(7<<5))|(1<<7);
*/
// SPI channel 1-2 setting --> VD16~18
spi_rGPDCON=rGPDCON;
spi_rGPDDAT=rGPDDAT;
spi_rGPDUP=rGPDUP;
rGPDCON=(rGPDCON&0xcfc0ffff)|(3<<16)|(3<<18)|(3<<20)|(1<<28); // MISO1, MOSI1, CLK1, Master
rGPDDAT|=1<<14;
rGPDUP=(rGPDUP&~(7<<8))|(1<<10);
}
void SPI_Port_Return(void)
{
rGPECON=spi_rGPECON;
rGPEDAT=spi_rGPEDAT;
rGPEUP=spi_rGPEUP;
rGPGCON=spi_rGPGCON;
rGPGDAT=spi_rGPGDAT;
rGPGUP=spi_rGPGUP;
rGPDCON=spi_rGPDCON;
rGPDDAT=spi_rGPDDAT;
rGPDUP=spi_rGPDUP;
}
void Test_Spi1_MS_poll(void)
{
// int i;
char *txStr,*rxStr;
SPI_Port_Init(1);
Uart_Printf("[SPI Polling Tx/Rx Test]\n");
Uart_Printf("Connect SPIMOSI1 into SPIMISO1.\n");
endSpiTx=0;
spiTxStr="ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789 - SPI1";
spiRxStr=(char *) SPI_BUFFER;
txStr=(char *)spiTxStr;
rxStr=(char *)spiRxStr;
rSPPRE1=0x0; //if PCLK=50Mhz,SPICLK=25Mhz
rSPCON1=(0<<5)|(1<<4)|(1<<3)|(1<<2)|(0<<1)|(0<<0);//Polling,en-SCK,master,low,A,normal
rSPPIN1=(0<<2)|(1<<1)|(0<<0);//dis-ENMUL,SBO,release
while(endSpiTx==0)
{
if(rSPSTA1&0x1) //Check Tx ready state
{
if(*spiTxStr!='\0')
rSPTDAT1=*spiTxStr++;
else
endSpiTx=1;
while(!(rSPSTA1&0x1)); //Check Rx ready state
*spiRxStr++=rSPRDAT1;
}
}
rSPCON1&=~(1<<4);//dis-SCK
*(spiRxStr-1)='\0';//remove last dummy data & attach End of String(Null)
Uart_Printf("Tx Strings:%s\n",txStr);
Uart_Printf("Rx Strings:%s :",rxStr);
if(strcmp(rxStr,txStr)==0)
Uart_Printf("O.K.\n");
else
Uart_Printf("ERROR!!!\n");
SPI_Port_Return();
}
void Test_Spi_MS_int(void)
{
char *txStr,*rxStr;
SPI_Port_Init(1);
Uart_Printf("[SPI0 Interrupt Tx/Rx Test]\n");
Uart_Printf("Connect SPIMOSI0 into SPIMISO0.\n");
pISR_SPI0=(unsigned)Spi_Int;
endSpiTx=0;
spiTxStr="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
spiRxStr=(char *) SPI_BUFFER;
txStr=(char *)spiTxStr;
rxStr=(char *)spiRxStr;
rSPPRE0=0x0; //if PCLK=50Mhz,SPICLK=25Mhz
rSPCON0=(1<<5)|(1<<4)|(1<<3)|(1<<2)|(0<<1)|0;//int,en-SCK,master,low,A,normal
rSPPIN0=(0<<2)|(1<<1)|(0<<0);//dis-ENMUL,SBO,release
rINTMSK=~(BIT_SPI0);
while(endSpiTx==0);
rSPCON0&=~((1<<5)|(1<<4));//poll, dis-SCK
Uart_Printf("Current Rx address = 0x%x\n",spiRxStr);
*spiRxStr='\0';//attach End of String(Null)
Uart_Printf("Tx Strings:%s\n",txStr);
Uart_Printf("Rx Strings:%s :",rxStr+1);//remove first dummy data
if(strcmp(rxStr+1,txStr)==0)
Uart_Printf("O.K.\n");
else
Uart_Printf("ERROR!!!\n");
SPI_Port_Return();
}
void __irq Spi_Int(void)
{
unsigned int status;
rINTMSK|=BIT_SPI0;
ClearPending(BIT_SPI0);
status=rSPSTA0;
if(rSPSTA0&0x6)
Uart_Printf("Data Collision or Multi Master Error(0x%x)!!!\n", status);
while(!(rSPSTA0&0x1)); //Check ready state
*spiRxStr++=rSPRDAT0; //First Rx data is garbage data
// Uart_Printf("Current Rx address = 0x%x\n",spiRxStr);
if(*spiTxStr!='\0')
{
rSPTDAT0=*spiTxStr++;
rINTMSK&=~BIT_SPI0;
}
else
{
endSpiTx=1;
}
}
void Test_Spi_MS_poll(void)
{
// int i;
char *txStr,*rxStr;
SPI_Port_Init(1);
Uart_Printf("[SPI Polling Tx/Rx Test]\n");
Uart_Printf("Connect SPIMOSI0 into SPIMISO0.\n");
endSpiTx=0;
spiTxStr="ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
spiRxStr=(char *) SPI_BUFFER;
txStr=(char *)spiTxStr;
rxStr=(char *)spiRxStr;
rSPPRE0=0x0; //if PCLK=50Mhz,SPICLK=25Mhz
rSPCON0=(0<<5)|(1<<4)|(1<<3)|(1<<2)|(0<<1)|(0<<0);//Polling,en-SCK,master,low,A,normal
rSPPIN0=(0<<2)|(1<<1)|(0<<0);//dis-ENMUL,SBO,release
while(endSpiTx==0)
{
if(rSPSTA0&0x1) //Check Tx ready state
{
if(*spiTxStr!='\0')
rSPTDAT0=*spiTxStr++;
else
endSpiTx=1;
while(!(rSPSTA0&0x1)); //Check Rx ready state
*spiRxStr++=rSPRDAT0;
}
}
rSPCON0&=~(1<<4);//dis-SCK
*(