?? test_mcp2510.cbackup
字號:
/****************************************************************************
【文 件 名 稱】Test_MCP2510.C
【功 能 描 述】三星S3C2410A板demo程序代碼
【程 序 版 本】4.0
【創建人及創建日期】icesoar//2002年11月19日19:26
【修改人及修改日期】icesoar//2004-12-8 17:25
****************************************************************************/
//***************************************************************************
#include "def.h"
#include "2410addr.h"
#include "config.h"
#include "board.h"
#include "utils.h"
#include "MCP2510_Reg.h"
#include "MCP2510.h"
/****************************************************************************
MCP2510_CS GPE11 output
MCP2510_SI GPB5 output
MCP2510_SO GPB6 input
MCP2510_SCK GPB7 output
MCP2510_INT GPG0 input (EINT8)
****************************************************************************/
#define DELAY_TIME 150
#define MCP2510_CS_OUT ( rGPECON = rGPECON & (~(3<<22)) | (1<<22) ) //GPE11
#define MCP2510_CS(a) rGPEDAT = ( rGPEDAT&(~(1<<11)) ) | ((a&1)<<11)
#define MCP2510_SI_OUT ( rGPBCON = rGPBCON & (~(3<<10)) | (1<<10) ) //GPB5
#define MCP2510_SI_PUT(a) ( rGPBDAT = ( rGPBDAT&(~(1<<5)) ) | ((a&1)<<5) )
#define MCP2510_SCK_OUT ( rGPBCON = rGPBCON & (~(3<<14)) | (1<<14) ) //GPB7
#define MCP2510_SCK_PUT(a) ( rGPBDAT = ( rGPBDAT&(~(1<<7)) ) | ((a&1)<<7) )
#define MCP2510_SO_IN ( rGPBCON = rGPBCON & (~(3<<12)) | (0<<12) ) //GPB6
#define MCP2510_SO_GET ( rGPBDAT & 0x40 )
#define MCP2510_INT_IN ( rGPGCON = rGPGCON & (~(3<<0)) )
#define MCP2510_INT_GET ( rGPGDAT & 0x01 )
U32 m_CANDRV_aulCANDrvMask[2] = { 0, 0 } ;
U32 m_CANDRV_aulSendingStartTicks[3]={ 0, 0, 0 } ;
CANFILTER m_CANDRV_aStruRXFilter[6] =
{
{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}
};
CANMESSAGE m_CANDRV_aStruRXMsg0[3], m_CANDRV_aStruRXMsg1[3] ;
//***************************************************************************
/****************************************************************************
【功能說明】
****************************************************************************/
void MCP2510_IO_CS_Init( void )
{
MCP2510_CS_OUT ;
MCP2510_SI_OUT ;
MCP2510_SCK_OUT ;
MCP2510_SO_IN ;
MCP2510_SCK_PUT( 1 ) ; //SCK put 1
{ U16 k=0; for( ; k <= DELAY_TIME; k++ ) ; } //延時至少300ns
MCP2510_CS( 0 ) ; // Select the MCP2510
{ U16 k=0; for( ; k <= DELAY_TIME; k++ ) ; } //延時至少300ns
}
/****************************************************************************
【功能說明】
****************************************************************************/
void Spi_Write( U8 Data )
{
U8 m ;
for( m = 0; m < 8; m++ )
{
MCP2510_SCK_PUT( 0 ) ; //SCK put 0
{ U16 k=0; for( ; k <= DELAY_TIME; k++ ) ; } //延時至少300ns
if( (Data&0x80)==0x80 )
MCP2510_SI_PUT( 1 ); //SI put 1
else
MCP2510_SI_PUT( 0 ); //SI put 0
{ U16 k=0; for( ; k <= DELAY_TIME; k++ ) ; } //延時至少300ns
MCP2510_SCK_PUT( 1 ) ; //SCK put 1
Data = Data<<1 ;
{ U16 k=0; for( ; k <= DELAY_TIME; k++ ) ; } //延時至少300ns
}
}
/****************************************************************************
【功能說明】
****************************************************************************/
U8 Spi_Read(U8 mode)
{
U8 m ;
U8 data = 0 ;
for( m = 0; m < 8; m++ )
{
MCP2510_SCK_PUT( 0 ) ; //SCK put 0
{ U16 k=0; for( ; k <= DELAY_TIME; k++ ) ; } //延時至少300ns
data=data<<1;
if( MCP2510_SO_GET != 0 )
data |= 0x01 ;
else
data &= 0xfe;
{ U16 k=0; for( ; k <= DELAY_TIME; k++ ) ; } //延時至少300ns
MCP2510_SCK_PUT( 1 ) ; //SCK put 1
{ U16 k=0; for( ; k <= DELAY_TIME; k++ ) ; } //延時至少300ns
}
return (data);
}
/****************************************************************************
【功能說明】 Read a register from the MCP2510 via SPI
****************************************************************************/
U8 ReadMCP2510Reg( U8 regaddr )
{
U8 rreg=0;
MCP2510_IO_CS_Init() ; //Initial IO port and CS is select
Spi_Write(CAN_SPIREAD ); // Send the Read command
Spi_Write( regaddr ); // Send the register address
rreg = Spi_Read( 0 ); // Read back the register
MCP2510_CS( 1 ) ; // Deselect the MCP2510
return( rreg );
}
/****************************************************************************
【功能說明】Read multiple registers from the MCP2510 over SPI
****************************************************************************/
void ReadMCP2510ManyRegS( U8 regaddr, U8 len, U8 *dta )
{
U16 x=0;
MCP2510_IO_CS_Init() ; //Initial IO port and CS is select
Spi_Write( CAN_SPIREAD ); // Send the Read command
Spi_Write( regaddr ); // Send the register address
for( x=0; x<len; x++ )
{
*dta =Spi_Read( 0 );
dta++;
}
MCP2510_CS( 1 ) ; // Deselect the MCP2510
}
/****************************************************************************
【功能說明】Write 1 MCP2510 register
****************************************************************************/
void WriteMCP2510Reg( U8 regaddr, U8 regvalue )
{
MCP2510_IO_CS_Init() ; //Initial IO port and CS is select
Spi_Write( CAN_SPIWRITE ); // Send the Write command
Spi_Write( regaddr ); //send the register address
Spi_Write( regvalue );
MCP2510_CS( 1 ) ; // Deselect the MCP2510
}
/****************************************************************************
【功能說明】Write Many Registers over SPI
****************************************************************************/
void WriteMCP2510ManyRegS( U8 regaddr, U8 len, U8 *dta )
{
U16 x=0;
MCP2510_IO_CS_Init() ; //Initial IO port and CS is select
Spi_Write( CAN_SPIWRITE ); // Send the Read command
Spi_Write( regaddr ); // Send the register address
for( x=0; x<len; x++ )
{
Spi_Write( *dta );
dta++;
}
MCP2510_CS( 1 ) ; // Deselect the MCP2510
}
/****************************************************************************
【功能說明】 Send Command to MCP2510 via SPI
****************************************************************************/
void SendCMDMCP2510( U8 CMD )
{
MCP2510_IO_CS_Init() ; //Initial IO port and CS is select
Spi_Write(CMD );
MCP2510_CS( 1 ) ; // Deselect the MCP2510
}
/****************************************************************************
【功能說明】 Read often used status
//Status 7 6 5 4 3 2 1 0
// | | | | | | | |
// | | | | | | | |___CANINTF.RX0IF
// | | | | | | |_______CANINTF.RX1IF
// | | | | | |___________TXB0CTRL.TXREQ
// | | | | |_______________CANINTF.TX0IF
// | | | |___________________TXB1CTRL.TXREQ
// | | |_______________________CANINTF.TX1IF
// | |___________________________TXB2CTRL.TXREQ
// |_______________________________CANINTF.TX2IF
****************************************************************************/
U8 ReadMCP2510Status( void )
{
U8 val;
MCP2510_IO_CS_Init() ; //Initial IO port and CS is select
Spi_Write(CAN_SPIREADSTAT); //Send Read status Command
val=Spi_Read(0); //read the often used status
MCP2510_CS( 1 ) ; // Deselect the MCP2510
return (val);
}
/****************************************************************************
【功能說明】Modify MCP2510Reg By Bit
****************************************************************************/
void BitModifyMCP2510Reg(U8 regaddr,U8 Mask,U8 regvalue )
{
MCP2510_IO_CS_Init() ; //Initial IO port and CS is select
Spi_Write(CAN_SPIBITMOD);
Spi_Write(regaddr);
Spi_Write(Mask);
Spi_Write(regvalue);
MCP2510_CS( 1 ) ; // Deselect the MCP2510
}
/****************************************************************************
【功能說明】Set the MCP2510 operation mode
1.normal mode 2.sleep mode 3.loop back mode 4.listen only mode 5 configure mode
ClkOutPreScale: 1-CLKOUT=OSC; 2--CLKOUT=OSC/2 4--CLKOUT=OSC/4 8 --CLKOUT=OSC/8
****************************************************************************/
U8 Set_MCP2510_Mode( U8 mode,U8 ClkOutPreScale )
{
U8 value=0;
U8 modeval=0;
U8 modeval1=0;
U8 ReadBackCNT=0;
if(mode==1) modeval=CAN_NORMAL_MODE;
else if(mode==2) modeval=CAN_SLEEP_MODE;
else if(mode==3) modeval=CAN_LOOP_MODE;
else if(mode==4) modeval=CAN_LISTEN_MODE;
else if(mode==5) modeval=CAN_CFG_MOEE;
else ;
modeval1=modeval;
switch(ClkOutPreScale)
{
case 1: modeval=modeval| CLKEN | CLKPRE1 ;
break;
case 2: modeval=modeval| CLKEN | CLKPRE2 ;
break;
case 4: modeval=modeval| CLKEN | CLKPRE4 ;
break;
case 8: modeval=modeval| CLKEN | CLKPRE8 ;
break;
default: modeval=modeval ;
break;
}
WriteMCP2510Reg( CANCTRL,modeval );
while( ReadBackCNT<5 )
{
value=( ReadMCP2510Reg(CANSTAT) & 0xe0 );
if( value == modeval1 )
{
break;
}
ReadBackCNT++;
}
if( ReadBackCNT==5 ) //Set mcp2510's mode failed,redo it again
{
printf( "Set MCP2510 mode failed, redo it!\n" ) ; //Printf message
WriteMCP2510Reg( CANCTRL,modeval ); //redo to set mcp2510 mode
Delay( 1 );
}
value = ( ReadMCP2510Reg(CANSTAT) & 0xe0 ); //read back mode from CANSTAT Register
return (value);
}
/****************************************************************************
【功能說明】Set the Baud Rate for MCP2510
//BaudIndex: Baud Nominal Bit Time
// 0 1000K 1uS
// 1 800K 1.25uS
// 2 500K 2uS
// 3 250K 4uS
// 4 125K 8uS
// 5 100K 10uS
// 6 50K 20uS
// 7 20K 50uS
// 8 10K 100uS
****************************************************************************/
U8 Set_MCP2510_Baud( U8 BaudIndex )
{
U8 CNF1Reg,CNF2Reg,CNF3Reg;
U8 val;
// For 1000k,500k,250k,125k,100k,50k,20k Tbit=8 TQ
// For 800k Tbit=10 TQ
// For 10k Tbit=16 TQ
CNF2Reg=0x90; //PSeg=1 TQ PS1=3 TQ
CNF3Reg=0x02; //PS2=2 TQ SYNC=1 TQ //Tbit=8 TQ
switch(BaudIndex)
{
case 0: CNF1Reg=0x00; //1000k
break;
case 1: CNF1Reg=0x00; //800k 10TQ
CNF2Reg=0x98; //PS1=4 TQ PSeg=1 TQ
CNF3Reg=0x03; //PS2=4 TQ SYNC=1 TQ
break;
case 2: CNF1Reg=0x01; //500k
break;
case 3: CNF1Reg=0x03; //250k
break;
case 4: CNF1Reg=0x07; //125k
break;
case 5: CNF1Reg=0x09; //100k
break;
case 6: CNF1Reg=0x13; //50k
break;
case 7: CNF1Reg=0x31; //20k
break;
case 8: CNF1Reg=0x31; //10k 16TQ
CNF2Reg=0xB0; //PS1=7 TQ PSeg=1 TQ
CNF3Reg=0x06; //PS2=7 TQ SYNC=1 TQ
break;
}
WriteMCP2510Reg( CNF1,CNF1Reg );
WriteMCP2510Reg( CNF2,CNF2Reg );
WriteMCP2510Reg( CNF3,CNF3Reg );
return (val);
}
/****************************************************************************
【功能說明】Set RXBuffer's Filter
FilterIndex(0---5): 0,1 For RXBuffer0 2,3,4,5 for RXBuffer1
****************************************************************************/
void SetMCP2510Filter( U8 FilterIndex, CANFILTER* Filter )
{
U8 ID[4];
U8 RID1;
ID[0]=(U8)((Filter->ID & 0xff000000)>>24);
ID[1]=(U8)((Filter->ID & 0x00ff0000)>>16);
ID[2]=(U8)((Filter->ID & 0x0000ff00)>>8);
ID[3]=(U8)((Filter->ID & 0x000000ff));
ID[3]=ID[3]>>3;
ID[3]=ID[3] |(ID[2]<<5);
ID[2]=ID[2]>>3;
ID[2]=ID[2] |(ID[1]<<5);
RID1=ID[1];
ID[1]=ID[1]>>3;
ID[1]=ID[1] & 0x03;
ID[1]=(RID1 & 0xe0) + ID[1];
if(Filter->EXFrame) //concern extend frame
{
ID[1]=ID[1] |0x08;
}
m_CANDRV_aStruRXFilter[FilterIndex %6 ].ID = Filter->ID;
m_CANDRV_aStruRXFilter[FilterIndex %6].EXFrame = Filter->EXFrame;
if(FilterIndex==0)
{
WriteMCP2510ManyRegS(RXF0SIDH,4,ID );
}
else if(FilterIndex==1)
{
WriteMCP2510ManyRegS(RXF1SIDH,4,ID );
}
else if(FilterIndex==2)
{
WriteMCP2510ManyRegS(RXF2SIDH,4,ID );
}
else if(FilterIndex==3)
{
WriteMCP2510ManyRegS(RXF3SIDH,4,ID );
}
else if(FilterIndex==4)
{
WriteMCP2510ManyRegS(RXF4SIDH,4,ID );
}
else if(FilterIndex==5)
{
WriteMCP2510ManyRegS(RXF5SIDH,4,ID );
}
else ;
}
/****************************************************************************
【功能說明】Set RXBuffer's Mask
MaskIndex(0---1): 0 For RXBuffer0 1 for RXBuffer1
****************************************************************************/
void SetMCP2510Mask(U8 MaskIndex, U32 mask )
{
U8 ID[4];
U8 RID1;
ID[0]=(U8)((mask & 0xff000000)>>24);
ID[1]=(U8)((mask & 0x00ff0000)>>16);
ID[2]=(U8)((mask & 0x0000ff00)>>8);
ID[3]=(U8)((mask & 0x000000ff));
ID[3]=ID[3]>>3;
ID[3]=ID[3] |(ID[2]<<5);
ID[2]=ID[2]>>3;
ID[2]=ID[2] |(ID[1]<<5);
RID1=ID[1];
ID[1]=ID[1]>>3;
ID[1]=ID[1] &0x03;
ID[1]=(RID1 & 0xe0 )+ ID[1];
m_CANDRV_aulCANDrvMask[MaskIndex] = mask;
if(MaskIndex==0)
{
WriteMCP2510ManyRegS(RXM0SIDH,4,ID );
}
else if(MaskIndex==1)
{
WriteMCP2510ManyRegS(RXM1SIDH,4,ID );
}
else ;
}
/****************************************************************************
【功能說明】
****************************************************************************/
void ClearTXEmptyFlag( U8 TXBufferIndex )
{
U8 mask=0x00;
if (TXBufferIndex==0) mask=0x04;
else if(TXBufferIndex==1) mask=0x08;
else if(TXBufferIndex==2) mask=0x10;
else;
BitModifyMCP2510Reg(CANINTF,mask, 0x00 );
}
/****************************************************************************
【功能說明】Clear Recieve Buffer over flow Flag
****************************************************************************/
void ClearRXBufferOVR(U8 RXBufferIndex )
{
U8 mask=0x00;
if (RXBufferIndex==0) mask=0x40;
else if(RXBufferIndex==1) mask=0x80;
else;
BitModifyMCP2510Reg(EFLG,mask, 0x00 );
}
/****************************************************************************
【功能說明】Before this function was called,you must check the RXBuffer and take the frame data away
Clear the RXBuffer
this result is if RXBuffIndex=0 then CANINTF.RX0IF=0
if RXBuffIndex=1 then CANINTF.RX1IF=0
****************************************************************************/
void ClearRXBufferFull(U8 RXBufferIndex )
{
U8 mask;
if(RXBufferIndex==0) mask=0x01;
else if(RXBufferIndex==1) mask=0x02;
else mask=0x00;
BitModifyMCP2510Reg(CANINTF, mask,0x00 );
}
/****************************************************************************
【功能說明】function:Try to Send a CAN Frame;
if one of the three TX Buffers is empty then CAN Frame was Written into success=1
else success=0xff indicating that CAN Frame was not wirtten into any TX Buffer and was not transmitted;
****************************************************************************/
U8 SendCANMessage( CANMESSAGE* Msg )
{
U8 status,SendData[13];
U8 success=1;
U8 ID[4];
//U8 err;
U32 ulTemp;
ID[3]=(U8)((Msg->ID & 0xff000000)>>24);
ID[2]=(U8)((Msg->ID & 0x00ff0000)>>16);
ID[1]=(U8)((Msg->ID & 0x0000ff00)>>8);
ID[0]=(U8)((Msg->ID & 0x000000ff));
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -