📄 spi.c
字号:
#include <string.h>
#include "s3c2410x.h"
#include "spi.h"
#include "def.h"
#include "string.h"
#include "consol.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);
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;
`/****************************************************************
* 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 SPI_Port_Init(int MASorSLV)
{
rGPEUP&=~(0x3800);
rGPEUP|=0x2000;
// rGPEUP|=(0x3800);
rGPECON=((rGPECON&0xf03fffff)|0xa800000);
rGPGUP|=0x4;
if(MASorSLV==1)
{
rGPGCON=((rGPGCON&0xffffffcf)|0x10); // Master(GPIO_Output)
rGPGDAT|=0x4; // Activate nSS
}
else
rGPGCON=((rGPGCON&0xffffffcf)|0x30); // Slave(nSS)
}
/*
void Test_Spi_MS_int(void)
{
char *txStr,*rxStr;
SPI_Port_Init(0);
CONSOL_Printf("[SPI0 Interrupt Tx/Rx Test]\n");
CONSOL_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<<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=(0<<5)|(0<<4)|(1<<3)|(1<<2)|(0<<1)|(0<<0);//Poll,dis-SCK,master,low,A,normal
*spiRxStr='\0';//attach End of String(Null)
CONSOL_Printf("Tx Strings:%s\n",txStr);
CONSOL_Printf("Rx Strings:%s :",rxStr+1);//remove first dummy data
if(strcmp(rxStr+1,txStr)==0)
CONSOL_Printf("O.K.\n");
else
CONSOL_Printf("ERROR!!!\n");
}
void __irq Spi_Int(void)
{
unsigned int status;
ClearPending(BIT_SPI0);
status=rSPSTA0;
if(rSPSTA0&0x6)
CONSOL_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
if(*spiTxStr!='\0')
rSPTDAT0=*spiTxStr++;
else
{
rINTMSK|=BIT_SPI0;
endSpiTx=1;
}
}
void Test_Spi_M_Int(void)
{
char *rxStr,*txStr;
SPI_Port_Init(1); // Master
CONSOL_Printf("[SPI Interrupt Master Rx test]\n");
CONSOL_Printf("This test should be configured two boards\nStart Tx first.\n");
pISR_SPI0=(unsigned)Spi_Int;
endSpiTx=0;
spiTxStr="1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890";
spiRxStr=(char *) SPI_BUFFER;
txStr=(char *)spiTxStr;
rxStr=(char *)spiRxStr;
rSPPRE0=0x1; //if PCLK=50Mhz,SPICLK=12.5Mhz
rSPCON0=(1<<5)|(1<<4)|(1<<3)|(1<<2)|(0<<1)|(0<<0);//int,en-SCK,master,low,A,normal
// rSPCON0=(1<<5)|(1<<4)|(1<<3)|(1<<2)|(1<<1)|(0<<0);//int,en-SCK,master,low,B,normal
rSPPIN0=(0<<2)|(1<<1)|(0<<0);//dis-ENMUL,SBO,release
rGPGDAT&=0xfffffffb; // Activate nSS
rINTMSK=~(BIT_SPI0);
while(endSpiTx==0);
rGPGDAT|=0x4; // Deactivate nSS
rSPCON0=(0<<5)|(0<<4)|(1<<3)|(1<<2)|(0<<1)|(0<<0);//Poll,dis-SCK,master,low,A,normal
// rSPCON0=(0<<5)|(0<<4)|(1<<3)|(1<<2)|(1<<1)|(0<<0);//Poll,dis-SCK,master,low,B,normal
*spiRxStr='\0';//attach End of String(Null)
CONSOL_Printf("Tx Strings:%s\n",txStr);
CONSOL_Printf("Rx Strings:%s :",rxStr+1);//remove first dummy data
if(strcmp((rxStr+1),txStr)==0)
CONSOL_Printf("O.K.\n");
else
CONSOL_Printf("ERROR!!!\n");
}
*/
void Spi_Int(void)
{
SPI_Port_Init(1); //master模式
rSPPRE0=0x07; //if PCLK=50Mhz,SPICLK=12.5Mhz
//rSPCON0=(1<<5)|(1<<4)|(1<<3)|(1<<2)|(0<<1)|(0<<0);//int,en-SCK,master,low,A,normal
rSPCON0=(1<<5)|(1<<4)|(1<<3)|(0<<2)|(0<<1)|(0<<0);//int,en-SCK,master,high,A,normal //my change
// rSPCON0=(1<<5)|(1<<4)|(1<<3)|(1<<2)|(1<<1)|(0<<0);//int,en-SCK,master,low,B,normal
rSPPIN0=(0<<2)|(1<<1)|(0<<0);//dis-ENMUL,SBO,release
}
unsigned char ReadSpi(void) //单字节读函数
{
rSPRDAT0=0;
while(!(rSPSTA0&0x1));
return rSPRDAT0;
}
void WriteSpi(unsigned char data) //单字节写函数
{
rSPTDAT0=data;
while(!(rSPSTA0&0x1));
}
unsigned char MCP_Read(unsigned char addr)
{
unsigned char data=0;
int i;
rGPGDAT&=0xfffffffb; // Activate nSS
// for(i=0;i<1000;i++); //延时
WriteSpi(0x03);
WriteSpi(addr);
WriteSpi(0xff); //提供时钟信号 ////////////////////!问题出在这里
data=ReadSpi();
rGPGDAT|=0x4; // Deactivate nSS
return data;
}
void MCP_Write(unsigned char addr,unsigned char data)
{
int i=0;
rGPGDAT&=0xfffffffb; // Activate nSS
WriteSpi(0x02);
WriteSpi(addr);
WriteSpi(data);
rGPGDAT|=0x4; // Deactivate nSS
for(i=0;i<1000;i++);
}
void MCP_RESET(void)
{
rGPGDAT&=0xfffffffb;
WriteSpi(0xc0);
rGPGDAT|=0x4;
}
void MCP_BitMod(U8 addr,U8 data1,U8 data2)
{
rGPGDAT&=0xfffffffb;
WriteSpi(0x05);
WriteSpi(addr);
WriteSpi(data1);
WriteSpi(data2);
rGPGDAT|=0x4;
}
void MCP_Init(void)
{
unsigned char b=0;
MCP_RESET();
MCP_Write(0x0f,0x86); //4分频,写CANCTRL寄存器,配置模式
b=MCP_Read(0x0f);
//for(i=0;i<10000;i++);
CONSOL_Printf("canctrl=%x\n",b);
MCP_Write(0x2a,04); //配置CNF1
b=MCP_Read(0x2a);
CONSOL_Printf("CNF1=%x\n",b);
MCP_Write(0x29,0xf1); //CNF2
b=MCP_Read(0x29);
CONSOL_Printf("CNF2=%x\n",b);
MCP_Write(0x28,0x85); //CNF3
b=MCP_Read(0x28);
CONSOL_Printf("CNF3=%x\n",b);
MCP_Write(0x60,0x64);//RXB0CTRL
b=MCP_Read(0x60);
CONSOL_Printf("RXB0CTRL=%x\n",b);
MCP_Write(0x70,0x60);//RXB1CTRL
b=MCP_Read(0x70);
CONSOL_Printf("RXB1CTRL=%x\n",b);
MCP_Write(0x30,0x00);//TXB0CTRL
b=MCP_Read(0x30);
CONSOL_Printf("TXB0CTRL=%x\n",b);
MCP_Write(0x40,0x00);//TXB1CTRL
b=MCP_Read(0x40);
CONSOL_Printf("TXB1CTRL=%x\n",b);
MCP_Write(0x2b,0x03);//CANINTE
b=MCP_Read(0x2b);
CONSOL_Printf("CANINTE=%x\n",b);
MCP_Write(0x2c,0x00);//CANINTF
b=MCP_Read(0x2c);
CONSOL_Printf("CANINTF=%x\n",b);
MCP_Write(0x0f,0x05); //CANCTRL noral模式!
b=MCP_Read(0x0f);
CONSOL_Printf("canctrl=%x\n",b);
}
void MCP_RequestSend(U8 i)
{
rGPGDAT&=0xfffffffb; // Activate nSS
WriteSpi(0x80|(0x01<<i));
rGPGDAT|=0x4; // Deactivate nSS
}
void MCP_Send( int TxBuf, int IdType, unsigned int id, int DataLen,unsigned char *data )
{
unsigned int flag;
int i, offset;
switch( TxBuf ){
case TXBUF0:
offset = 0;
flag=0x04;
break;
case TXBUF1:
offset = 0x10;
flag=0x08;
break;
case TXBUF2:
offset = 0x20;
flag=0x10;
break;
}
// Set the frame identifier
if( IdType==STANDID )
{
MCP_Write(0x32+offset,(id&0x7)<<5); //TXB0SIDL //配置标识符
MCP_Write(0x31+offset,(id>>3)&0xff); //TXB0SIDH
}
else if( IdType==EXTID )
{
MCP_Write(0x34+offset,id&0xff);
MCP_Write(0x33+offset,(id>>8)&0xff); //扩展标识符
MCP_Write(0x32+offset,((id>>16)&0x3)|0x08);
}
if( DataLen>8 )
DataLen = 8;
// Set the data length
MCP_Write(0x35+offset,DataLen);
// fill the data
for( i=0; i<DataLen; i++ )
{
MCP_Write(0x36+offset+i,data[i]);
}
while(MCP_Read(0x30+offset)&0x80); //等待
// initiate transmit
MCP_RequestSend(TxBuf);
// while(!(MCP_Read(0x2c)&flag)); //等待中断
CONSOL_Printf("CanintF=%x\n",MCP_Read(0x2c));
// clear the receive int flag
// MCP_BitMod(0x2c,flag,0x00); //清中断标志位
}
void MCP_Receive( int RxBuf,unsigned int *id, int *DataLen, unsigned char *data )
{
unsigned int flag;
int offset, i;
switch( RxBuf )
{
case RXBUF0:
flag = 0x1;
offset = 0x00;
break;
case RXBUF1:
flag = 0x2;
offset = 0x10;
break;
}
// wait for a frame to com
while(!(MCP_Read(0x2c)&flag)); //等待中断
CONSOL_Printf("CanintF=%x\n",MCP_Read(0x2c));
// Get the identifier
if((MCP_Read(0x62+offset))&0x08) //判断是标准帧还是扩展帧
{
// Extended identifier
*id = (MCP_Read(0x62+offset)&0x03)<<16;
*id |= (MCP_Read(0x63+offset))<<8;
*id |= (MCP_Read(0x64+offset));
}
else
{
// Standard identifier
// *id=123;
*id=((MCP_Read(0x61+offset))<<3) |((MCP_Read(0x62+offset))>>5);
// CONSOL_Printf("id1=%x\n",id);
CONSOL_Printf("id126=%x\n",*id);
}
// Get the data frame lenth
*DataLen = (MCP_Read(0x65+offset))&0x0f;
CONSOL_Printf("DataLen!=%d\n",*DataLen);
// Get the data
for(i=0;i<*DataLen;i++)
{
data[i]=MCP_Read(0x66+offset+i);
CONSOL_Printf ("data=%d\n",MCP_Read(0x66+offset+i));
}
// clear the receive int flag
MCP_BitMod(0x2c,flag,0x00); //清中断标志位
CONSOL_Printf("CanintF=%x\n",MCP_Read(0x2c));
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -