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

📄 spi.c

📁 MCP2515在2410下的测试程序
💻 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 + -