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

📄 mcp2510.c

📁 武汉创维特的arm培训例程试验程序
💻 C
字号:
/*
 * mcp2510.c
 * Common Function Definition for mcp2510 CAN Controller
 * Date	: 2004/04/29
 * By	: Zhang Jing
 */

#define	MCP2510_FLAG
#include	"mcp2510.h"
#include	"spi_cmd.h"
#include    "spi.h"

/* Initialize the mcp2510 */
void MCP2510_Init( void )
{
	// Configure the SPI Interface in MX1
	SPI_Init( ); 
	// Configure the mcp2510 through spi interface

	// Reset controller
	CAN_SPI_CMD( SPI_CMD_RESET, ARG_UNUSED, ARG_UNUSED, ARG_UNUSED );
	
	CAN_SPI_CMD( SPI_CMD_BITMOD, TOLONG(&(MCP2510_MAP->CANCTRL)), 0xe0, 0x80 );		// LOOP BACK MODE
	
	// make sure we are in configuration mode
	while( (CAN_SPI_CMD( SPI_CMD_READ, TOLONG(&(MCP2510_MAP->CANSTAT)), ARG_UNUSED, ARG_UNUSED )>>5)!=0x04 );
	// start configuration
	CAN_SPI_CMD( SPI_CMD_WRITE, TOLONG(&(MCP2510_MAP->BFPCTRL)), 	BFPCTRL_INIT_VAL, 	ARG_UNUSED);
	CAN_SPI_CMD( SPI_CMD_WRITE, TOLONG(&(MCP2510_MAP->TXRTSCTRL)), 	TXRTSCTRL_INIT_VAL, ARG_UNUSED);
	CAN_SPI_CMD( SPI_CMD_WRITE, TOLONG(&(MCP2510_MAP->CNF3)), 		CNF3_INIT_VAL, 		ARG_UNUSED);
	CAN_SPI_CMD( SPI_CMD_WRITE, TOLONG(&(MCP2510_MAP->CNF2)), 		CNF2_INIT_VAL, 		ARG_UNUSED);
	CAN_SPI_CMD( SPI_CMD_WRITE, TOLONG(&(MCP2510_MAP->CNF1)),		CNF1_INIT_VAL, 		ARG_UNUSED);
	CAN_SPI_CMD( SPI_CMD_WRITE, TOLONG(&(MCP2510_MAP->CANINTE)),	CANINTE_INIT_VAL, 	ARG_UNUSED);
	CAN_SPI_CMD( SPI_CMD_WRITE, TOLONG(&(MCP2510_MAP->CANINTF)), 	CANINTF_INIT_VAL, 	ARG_UNUSED);
	CAN_SPI_CMD( SPI_CMD_WRITE, TOLONG(&(MCP2510_MAP->EFLG)), 		EFLG_INIT_VAL, 		ARG_UNUSED);
	CAN_SPI_CMD( SPI_CMD_WRITE, TOLONG(&(MCP2510_MAP->TXB0CTRL)), 	TXBnCTRL_INIT_VAL, 	ARG_UNUSED);
	CAN_SPI_CMD( SPI_CMD_WRITE, TOLONG(&(MCP2510_MAP->TXB1CTRL)), 	TXBnCTRL_INIT_VAL, 	ARG_UNUSED);
	CAN_SPI_CMD( SPI_CMD_WRITE, TOLONG(&(MCP2510_MAP->TXB2CTRL)), 	TXBnCTRL_INIT_VAL, 	ARG_UNUSED);
	CAN_SPI_CMD( SPI_CMD_WRITE, TOLONG(&(MCP2510_MAP->RXB0CTRL)), 	RXB1CTRL_INIT_VAL, 	ARG_UNUSED);
	CAN_SPI_CMD( SPI_CMD_WRITE, TOLONG(&(MCP2510_MAP->RXB1CTRL)), 	RXB1CTRL_INIT_VAL, 	ARG_UNUSED);
	
	// switch to normal mode or loopback mode ( for testing)
	//CAN_SPI_CMD( SPI_CMD_BITMOD, TOLONG(&(MCP2510_MAP->CANCTRL)), 0xe0, 0x40 );		// LOOP BACK MODE
	CAN_SPI_CMD( SPI_CMD_BITMOD, TOLONG(&(MCP2510_MAP->CANCTRL)), 0xe0, 0x00 );	// NORMAL OPERATION MODE
	
	// Flush the MX1 SPI receive buffer
	
	CAN_SPI_CMD( SPI_CMD_READ, TOLONG(&(MCP2510_MAP->CANSTAT)), ARG_UNUSED, ARG_UNUSED );
}
/* Transmit data */
/*
 TxBuf	: select the transmit buffer( 0=buffer0 or 1=buffer1 2=buffer2 )
 IdType	: 0=standard id or 1=extended id
 id	: frame identifier
 DataLen	: the number of byte
 data	: the pointer to data byte
*/
void MCP2510_TX( int TxBuf, int IdType, unsigned int id, int DataLen, char * data )
{
	int i, offset;

	switch( TxBuf ){
		case TXBUF0:
			offset = 0;
			break;
		case TXBUF1:
			offset = 0x10;
			break;
		case TXBUF2:
			offset = 0x20;
			break;
	}
	// Set the frame identifier
	if( IdType==STANDID ){
		CAN_SPI_CMD( SPI_CMD_WRITE, TOLONG(&(MCP2510_MAP->TXB0SIDL))+offset, (id&0x7)<<5, ARG_UNUSED );
		CAN_SPI_CMD( SPI_CMD_WRITE, TOLONG(&(MCP2510_MAP->TXB0SIDH))+offset, (id>>3)&0xff, ARG_UNUSED );
	}else if( IdType==EXTID ){
		CAN_SPI_CMD( SPI_CMD_WRITE, TOLONG(&(MCP2510_MAP->TXB0EID0))+offset, id&0xff, ARG_UNUSED );
		CAN_SPI_CMD( SPI_CMD_WRITE, TOLONG(&(MCP2510_MAP->TXB0EID8))+offset, (id>>8)&0xff, ARG_UNUSED );			CAN_SPI_CMD( SPI_CMD_WRITE, TOLONG(&(MCP2510_MAP->TXB0SIDL)), ((id>>16)&0x3)|0x08, ARG_UNUSED );
	}
	// Set the data length
	CAN_SPI_CMD( SPI_CMD_WRITE, TOLONG(&(MCP2510_MAP->TXB0DLC))+offset, DataLen, ARG_UNUSED );
	// fill the data
	if( DataLen>8 )
		DataLen = 8;
	for( i=0; i<DataLen; i++ ){
		CAN_SPI_CMD( SPI_CMD_WRITE, TOLONG(&(MCP2510_MAP->TXB0D0))+offset+i, data[i], ARG_UNUSED );
	}
	// initiate transmit
	while( CAN_SPI_CMD( SPI_CMD_READ, TOLONG(&(MCP2510_MAP->TXB0CTRL))+offset, ARG_UNUSED, ARG_UNUSED )&0x08 );
	CAN_SPI_CMD( SPI_CMD_BITMOD, TOLONG(&(MCP2510_MAP->TXB0CTRL))+offset, 0x08, 0x08 );
}

/* Receive data */
/*
 * RxBuf		: The receive buffer from which the data is get
 * IdType		: Identifier type of the data frame ( STANDID, EXTID )
 * id		: The identifier of the received frame
 * DataLen	: The number of bytes received
 * data		: The received data
 */
void MCP2510_RX( int RxBuf, int *IdType, unsigned int *id, int *DataLen, 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( !(CAN_SPI_CMD( SPI_CMD_READ, TOLONG(&(MCP2510_MAP->CANINTF)), ARG_UNUSED, ARG_UNUSED )&flag) );
	// Get the identifier
	if( CAN_SPI_CMD( SPI_CMD_READ, TOLONG(&(MCP2510_MAP->RXB0SIDL))+offset, ARG_UNUSED, ARG_UNUSED )&0x08 ){
		// Extended identifier
		if( IdType )
			*IdType = EXTID;
		if( id ){
			*id = (CAN_SPI_CMD( SPI_CMD_READ, TOLONG(&(MCP2510_MAP->RXB0SIDL))+offset, ARG_UNUSED, ARG_UNUSED )&0x3)<<16;
			*id |= (CAN_SPI_CMD( SPI_CMD_READ, TOLONG(&(MCP2510_MAP->RXB0EID8))+offset, ARG_UNUSED, ARG_UNUSED ))<<8;
			*id |= (CAN_SPI_CMD( SPI_CMD_READ, TOLONG(&(MCP2510_MAP->RXB0EID0))+offset, ARG_UNUSED, ARG_UNUSED ));
		}
	}else{
		// Standard identifier
		if( IdType )
			*IdType = STANDID;
		if( id ){
			*id = (CAN_SPI_CMD( SPI_CMD_READ, TOLONG(&(MCP2510_MAP->RXB0SIDH))+offset, ARG_UNUSED, ARG_UNUSED ))<<3;
			*id |= (CAN_SPI_CMD( SPI_CMD_READ, TOLONG(&(MCP2510_MAP->RXB0SIDL))+offset, ARG_UNUSED, ARG_UNUSED ))>>5;
		}
	}
	// Get the data frame lenth
	if( DataLen )
		*DataLen = (CAN_SPI_CMD( SPI_CMD_READ, TOLONG(&(MCP2510_MAP->RXB0DLC))+offset, ARG_UNUSED, ARG_UNUSED )&0xf);
	// Get the data
	for( i=0; DataLen&&(i<*DataLen)&&data; i++ ){
		data[i] = CAN_SPI_CMD( SPI_CMD_READ, TOLONG(&(MCP2510_MAP->RXB0D0))+offset+i, ARG_UNUSED, ARG_UNUSED );
	}
	// clear the receive int flag
	CAN_SPI_CMD( SPI_CMD_BITMOD, TOLONG(&(MCP2510_MAP->CANINTF)), flag, 0x00 );
	
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -