MCP2515驱动 Rtthread GD32 CAN扩展

编程入门 行业动态 更新时间:2024-10-26 22:27:53

MCP2515驱动 <a href=https://www.elefans.com/category/jswz/34/1744912.html style=Rtthread GD32 CAN扩展"/>

MCP2515驱动 Rtthread GD32 CAN扩展

20231001

MCP2515扩展两路CAN接口,使用可以rtthread函数接口进行操作。对2515的设置可以直接配置结构体sit2515_config参数。

/****************************************************/
/*         基于GD32 RT_thread sit2515驱动程序  模拟SPI总线 
*/
/****************************************************/#include <rtthread.h>
#include <rtdevice.h>
#include <rtdbg.h>
#include <drv_sit2515.h>#ifdef BSP_USING_SIT2515	#ifdef BSP_USING_SIT2515_0
static struct rt_semaphore int02_sem;     /* 用于中断的信号量 */
static struct rt_semaphore rx02_sem;     /* 用于接收数据的信号量 */
static struct sit2515_config sit2515_cfg0 = 
{.config.baudrate = _1Mbps,//1000kbps.config.filter.mask_0.mask =0x7FF,//屏蔽位.config.filter.mask_0.ext_flag =0,//=0用于标准帧屏蔽位,=1用于扩展帧屏蔽位.config.filter.mask_1.mask =0x1FFFFFFF,//屏蔽位.config.filter.mask_1.ext_flag =1,.config.filter.filter_0.filter =0xAA,//ID.config.filter.filter_0.ext_flag =0,//=0用于标准滤波器,=1用于扩展帧滤波器	.config.filter.filter_1.filter =0xBB,.config.filter.filter_1.ext_flag =0,.config.filter.filter_2.filter =0x2bb,.config.filter.filter_2.ext_flag =1,.config.filter.filter_3.filter =0x3bb,.config.filter.filter_3.ext_flag =1,.config.filter.filter_4.filter =0x4bb,.config.filter.filter_4.ext_flag =1,	.config.filter.filter_5.filter =0x5bb,.config.filter.filter_5.ext_flag =1,.config.br_flag =1,//=1波特率配置有效.config.fi_flag =1,//=1滤波配置有效.mode.oper_mode =REQOP_NORMAL,//正常模式.irq.tx = 0,//发送中断.irq.rx = 1,//接收中断.irq.err = 1,//错误中断.irq.wakie = 0//唤醒中断
};
#endif#ifdef BSP_USING_SIT2515_1
static struct rt_semaphore int03_sem;     /* 用于中断的信号量 */
static struct rt_semaphore rx03_sem;     /* 用于接收数据的信号量 */
static struct sit2515_config sit2515_cfg1 = 
{.config.baudrate = _1Mbps,//1000kbps.config.filter.mask_0.mask =0x7FF,.config.filter.mask_0.ext_flag =0,//=0用于标准帧屏蔽位,=1用于扩展帧屏蔽位.config.filter.mask_1.mask =0x1FFFFFFF,.config.filter.mask_1.ext_flag =1,.config.filter.filter_0.filter =0xCC,.config.filter.filter_0.ext_flag =0,//=0用于标准滤波器,=1用于扩展帧滤波器	.config.filter.filter_1.filter =0xDD,.config.filter.filter_1.ext_flag =0,.config.filter.filter_2.filter =0x2bb,.config.filter.filter_2.ext_flag =1,.config.filter.filter_3.filter =0x3bb,.config.filter.filter_3.ext_flag =1,.config.filter.filter_4.filter =0x4bb,.config.filter.filter_4.ext_flag =1,	.config.filter.filter_5.filter =0x5bb,.config.filter.filter_5.ext_flag =1,.config.br_flag =1,//=1波特率配置有效.config.fi_flag =1,//=1滤波配置有效.mode.oper_mode =REQOP_NORMAL,//正常模式.irq.tx = 0,//发送中断.irq.rx = 1,//接收中断.irq.err = 1,//错误中断.irq.wakie = 0//唤醒中断
};
#endif/** sit2515设备结构体 */
struct sit2515_device
{struct rt_device         parent;struct rt_spi_device *bus;
};/*复位*/
static rt_err_t sit2515_reset(rt_device_t dev)
{struct sit2515_device *sit2515;sit2515 = (struct sit2515_device *) dev;	struct rt_spi_message msg={0};rt_uint8_t command;//命令/*写指令*/command = CAN_RESET;//msg.send_buf = &command;msg.recv_buf   = RT_NULL;msg.length     = 1;//8位宽,每个length发送1个字节msg.cs_take    = 1;    //=1表示传输前CS为有效msg.cs_release = 1;    //=1表示数据传输结束后释放对应的CSmsg.next       = RT_NULL;									/* 调用SPI设备接口传输数据 */rt_spi_transfer_message(sit2515->bus, &msg);	return RT_EOK;
}/**
* @brief sit2515设备写一个字节数据
* @param[in]  dev                设备句柄
* @param[in]  address            寄存器地址
* @param[in]  data               要写的数据
* @return  返回写状态
* - 1      写失败
* - 0	   写成功
*/
static rt_err_t sit2515_write_byte(rt_device_t dev,rt_uint8_t address,rt_uint8_t data)
{struct sit2515_device *sit2515;sit2515 = (struct sit2515_device *) dev;struct rt_spi_message msg[3]={0};rt_uint8_t command;//命令/*写指令*/command = CAN_WRITE;//CAN_WRITEmsg[0].send_buf = &command;msg[0].recv_buf   = RT_NULL;msg[0].length     = 1;//8位宽,每个length发送1个字节msg[0].cs_take    = 1;    //=1表示传输前CS为有效msg[0].cs_release = 0;    //=1表示数据传输结束后释放对应的CSmsg[0].next       = &msg[1];					/*寄存器*/	msg[1].send_buf = &address;msg[1].recv_buf   = RT_NULL;msg[1].length     = 1;//msg[1].cs_take    = 0;    //=1表示传输前CS为有效msg[1].cs_release = 0;    //=1表示数据传输结束后释放对应的CSmsg[1].next       = &msg[2];	/*写数据*/msg[2].send_buf = &data;msg[2].recv_buf   = RT_NULL;msg[2].length     = 1;//1;  16位宽度数据长度为16位时,每个length发送2个字节msg[2].cs_take    = 0;    //=1表示传输前CS为有效msg[2].cs_release = 1;    //=1表示数据传输结束后释放对应的CSmsg[2].next       = RT_NULL;				/* 调用SPI设备接口传输数据 */rt_spi_transfer_message(sit2515->bus, msg);	return RT_EOK;
}/**
* @brief sit2515设备写一位数据
* @param[in]  dev                设备句柄
* @param[in]  address            寄存器地址
* @param[in]  mask            	 屏蔽码     屏蔽码对应的位等于1时允许修改相应的位
* @param[in]  data               要写的数据
* @return  返回写状态
* - 1      写失败
* - 0	   写成功
*/
static rt_err_t sit2515_write_bit(rt_device_t dev,rt_uint8_t address,rt_uint8_t mask,rt_uint8_t data)
{struct sit2515_device *sit2515;sit2515 = (struct sit2515_device *) dev;struct rt_spi_message msg[4]={0};rt_uint8_t command;//命令RT_ASSERT(dev != 0);    /*写位指令*/command = CAN_BIT_MODIFY;//msg[0].send_buf = &command;msg[0].recv_buf   = RT_NULL;msg[0].length     = 1;//8位宽,每个length发送1个字节msg[0].cs_take    = 1;    //=1表示传输前CS为有效msg[0].cs_release = 0;    //=1表示数据传输结束后释放对应的CSmsg[0].next       = &msg[1];					/*寄存器地址*/	msg[1].send_buf = &address;msg[1].recv_buf   = RT_NULL;msg[1].length     = 1;//msg[1].cs_take    = 0;    //=1表示传输前CS为有效msg[1].cs_release = 0;    //=1表示数据传输结束后释放对应的CSmsg[1].next       = &msg[2];	/*写屏蔽字节*/msg[2].send_buf = &mask;msg[2].recv_buf   = RT_NULL;msg[2].length     = 1;//1;  16位宽度数据长度为16位时,每个length发送2个字节msg[2].cs_take    = 0;    //=1表示传输前CS为有效msg[2].cs_release = 0;    //=1表示数据传输结束后释放对应的CSmsg[2].next       = &msg[3];	/*写数据*/msg[3].send_buf = &data;msg[3].recv_buf   = RT_NULL;msg[3].length     = 1;//1;  16位宽度数据长度为16位时,每个length发送2个字节msg[3].cs_take    = 0;    //=1表示传输前CS为有效msg[3].cs_release = 1;    //=1表示数据传输结束后释放对应的CSmsg[3].next       = RT_NULL;	/* 调用SPI设备接口传输数据 */rt_spi_transfer_message(sit2515->bus, msg);	return RT_EOK;
}/**
* @brief sit2515设备读一个字节数据
* @param[in]  dev                设备句柄
* @param[in]  address            寄存器地址
* @return  返回读取的数据
* - 1      写失败
* - 0	   写成功
*/
rt_uint8_t sit2515_read_byte(rt_device_t dev,rt_uint8_t address)
{struct sit2515_device *sit2515;sit2515 = (struct sit2515_device *) dev;struct rt_spi_message msg[3]={0};rt_uint8_t data;rt_uint8_t command;//命令/*读指令*/command = CAN_READ;//msg[0].send_buf = &command;msg[0].recv_buf   = RT_NULL;msg[0].length     = 1;//8位宽,每个length发送1个字节msg[0].cs_take    = 1;    //=1表示传输前CS为有效msg[0].cs_release = 0;    //=1表示数据传输结束后释放对应的CSmsg[0].next       = &msg[1];					/*寄存器*/	msg[1].send_buf = &address;msg[1].recv_buf   = RT_NULL;msg[1].length     = 1;//msg[1].cs_take    = 0;    //=1表示传输前CS为有效msg[1].cs_release = 0;    //=1表示数据传输结束后释放对应的CSmsg[1].next       = &msg[2];	/*写数据*/msg[2].send_buf = RT_NULL;msg[2].recv_buf   = &data;msg[2].length     = 1;//1;  16位宽度数据长度为16位时,每个length发送2个字节msg[2].cs_take    = 0;    //=1表示传输前CS为有效msg[2].cs_release = 1;    //=1表示数据传输结束后释放对应的CSmsg[2].next       = RT_NULL;				/* 调用SPI设备接口传输数据 */rt_spi_transfer_message(sit2515->bus, msg);	return data;
}static rt_err_t init_sit2515t(rt_device_t dev)
{struct sit2515_device *sit2515;struct sit2515_config *cfg;sit2515 = (struct sit2515_device *) dev;RT_ASSERT(sit2515->parent.user_data != 0);cfg = (struct sit2515_config *)sit2515->parent.user_data;	
//	rt_uint8_t data;sit2515_reset(dev);//复位sit2515_write_bit(dev,CANCTRL,MASK_7,REQOP_CONFIG);//设定为配置模式	sit2515_write_bit(dev,CANCTRL,MASK_2,CLKOUT_DISABLED);///*CLKOUT 引脚禁止*/	if(cfg->config.baudrate==_125kbps){/*波特率125kbps*/sit2515_write_byte(dev,CNF1,CNF1_CAN_125Kbps);//设置sit2515_write_byte(dev,CNF2,BTLMODE_CNF3|PHSEG1_8TQ|PRSEG_5TQ);//设置sit2515_write_byte(dev,CNF3,WAKFIL_ENABLED|PHSEG2_2TQ);//设置	}else if(cfg->config.baudrate==_250kbps){/*波特率250kbps*/sit2515_write_byte(dev,CNF1,CNF1_CAN_250Kbps);//设置sit2515_write_byte(dev,CNF2,BTLMODE_CNF3|PHSEG1_8TQ|PRSEG_5TQ);//设置sit2515_write_byte(dev,CNF3,WAKFIL_ENABLED|PHSEG2_2TQ);//设置	}else if(cfg->config.baudrate==_500kbps){/*晶振16MHz,波特率500kbps*/sit2515_write_byte(dev,CNF1,CNF1_CAN_500Kbps);//设置sit2515_write_byte(dev,CNF2,BTLMODE_CNF3|PHSEG1_8TQ|PRSEG_5TQ);//设置sit2515_write_byte(dev,CNF3,WAKFIL_ENABLED|PHSEG2_2TQ);//设置	}else if(cfg->config.baudrate==_1Mbps){/*晶振16MHz,波特率1Mbps*/sit2515_write_byte(dev,CNF1,CNF1_CAN_1Mbps);//设置sit2515_write_byte(dev,CNF2,BTLMODE_CNF3|PHSEG1_4TQ|PRSEG_1TQ);//设置sit2515_write_byte(dev,CNF3,WAKFIL_ENABLED|PHSEG2_2TQ);//设置	}	/*滤波器初始化*/rt_uint8_t rx_sidh=0;//验收屏蔽/滤波寄存器0标准标识符高位rt_uint8_t rx_sidl=0;//验收屏蔽/滤波寄存器0标准标识符低位	rt_uint8_t rx_eid8=0;//验收屏蔽/滤波寄存器0扩展标识符高位rt_uint8_t rx_eid0=0;//验收屏蔽/滤波寄存器0扩展标识符低位if (cfg->config.fi_flag==0)//{sit2515_write_byte(dev,RXB0CTRL,RXM_RCV_ALL);//关闭滤波接收所有sit2515_write_byte(dev,RXB1CTRL,RXM_RCV_ALL);//关闭滤波接收所有}else{sit2515_write_byte(dev,RXB0CTRL,RXM_VALID_ALL);//接收符合滤波器条件的所有带扩展标识符或标准标识符的有效报文sit2515_write_byte(dev,RXB1CTRL,RXM_VALID_ALL);//接收符合滤波器条件的所有带扩展标识符或标准标识符的有效报文/*验收屏蔽寄存器设置*/if(cfg->config.filter.mask_0.ext_flag == 0){rx_sidh = (cfg->config.filter.mask_0.mask<<21)>>24;rx_sidl = (cfg->config.filter.mask_0.mask<<29)>>24;sit2515_write_byte(dev,RXM0SIDH,rx_sidh);//验收屏蔽寄存器0标准标识符高位sit2515_write_byte(dev,RXM0SIDL,rx_sidl);//验收屏蔽寄存器0标准标识符低位				}else if(cfg->config.filter.mask_0.ext_flag == 1) {rx_sidh = (cfg->config.filter.mask_0.mask<<3)>>24;rx_sidl = (cfg->config.filter.mask_0.mask>>16)&0x03;rx_sidl = rx_sidl|((cfg->config.filter.mask_0.mask>>13)&0xE0);rx_eid8 = (cfg->config.filter.mask_0.mask<<16)>>24;rx_eid0 = (cfg->config.filter.mask_0.mask)&0xFF;					sit2515_write_byte(dev,RXM0SIDH,rx_sidh);//验收屏蔽寄存器0标准标识符高位sit2515_write_byte(dev,RXM0SIDL,rx_sidl);//验收屏蔽寄存器0标准标识符低位	sit2515_write_byte(dev,RXM0EID8,rx_eid8);//验收屏蔽寄存器0扩展标识符高位sit2515_write_byte(dev,RXM0EID0,rx_eid0);//验收屏蔽寄存器0扩展标识符低位						}else {sit2515_write_byte(dev,RXM0SIDH,0);//验收屏蔽寄存器0标准标识符高位sit2515_write_byte(dev,RXM0SIDL,0);//验收屏蔽寄存器0标准标识符低位	sit2515_write_byte(dev,RXM0EID8,0);//验收屏蔽寄存器0扩展标识符高位sit2515_write_byte(dev,RXM0EID0,0);//验收屏蔽寄存器0扩展标识符低位				}if(cfg->config.filter.mask_1.ext_flag == 0){rx_sidh = (cfg->config.filter.mask_1.mask<<21)>>24;rx_sidl = (cfg->config.filter.mask_1.mask<<29)>>24;sit2515_write_byte(dev,RXM1SIDH,rx_sidh);//验收屏蔽寄存器1标准标识符高位sit2515_write_byte(dev,RXM1SIDL,rx_sidl);//验收屏蔽寄存器1标准标识符低位			}else if(cfg->config.filter.mask_1.ext_flag == 1) {rx_sidh = (cfg->config.filter.mask_1.mask<<3)>>24;rx_sidl = (cfg->config.filter.mask_1.mask>>16)&0x03;rx_sidl = rx_sidl|((cfg->config.filter.mask_1.mask>>13)&0xE0);rx_eid8 = (cfg->config.filter.mask_1.mask<<16)>>24;rx_eid0 = (cfg->config.filter.mask_1.mask)&0xFF;					sit2515_write_byte(dev,RXM1SIDH,rx_sidh);//验收屏蔽寄存器1标准标识符高位sit2515_write_byte(dev,RXM1SIDL,rx_sidl);//验收屏蔽寄存器1标准标识符低位	sit2515_write_byte(dev,RXM1EID8,rx_eid8);//验收屏蔽寄存器1扩展标识符高位sit2515_write_byte(dev,RXM1EID0,rx_eid0);//验收屏蔽寄存器1扩展标识符低位						}else {sit2515_write_byte(dev,RXM1SIDH,0);//验收屏蔽寄存器1标准标识符高位sit2515_write_byte(dev,RXM1SIDL,0);//验收屏蔽寄存器1标准标识符低位	sit2515_write_byte(dev,RXM1EID8,0);//验收屏蔽寄存器1扩展标识符高位sit2515_write_byte(dev,RXM1EID0,0);//验收屏蔽寄存器1扩展标识符低位				}/*验收滤波寄存器0设置*/if(cfg->config.filter.filter_0.ext_flag ==0)//仅用于标准帧滤波{rx_sidh = (cfg->config.filter.filter_0.filter<<21)>>24;rx_sidl = (cfg->config.filter.filter_0.filter<<29)>>24;sit2515_write_byte(dev,RXF0SIDH,rx_sidh);//验收滤波寄存器0标准标识符高位sit2515_write_byte(dev,RXF0SIDL,rx_sidl);//验收滤波寄存器0标准标识符低位						}else//仅用于扩展帧滤波{rx_sidh = (cfg->config.filter.filter_0.filter<<3)>>24;rx_sidl = (cfg->config.filter.filter_0.filter>>16)&0x03;rx_sidl = rx_sidl|((cfg->config.filter.filter_0.filter>>13)&0xE0)|EXIDE_SET;rx_eid8 = (cfg->config.filter.filter_0.filter<<16)>>24;rx_eid0 = (cfg->config.filter.filter_0.filter)&0xFF;					sit2515_write_byte(dev,RXF0SIDH,rx_sidh);//验收滤波寄存器0标准标识符高位sit2515_write_byte(dev,RXF0SIDL,rx_sidl);//验收滤波寄存器0标准标识符低位	sit2515_write_byte(dev,RXF0EID8,rx_eid8);//验收滤波寄存器0扩展标识符高位sit2515_write_byte(dev,RXF0EID0,rx_eid0);//验收滤波寄存器0扩展标识符低位				}/*验收滤波寄存器1设置*/if(cfg->config.filter.filter_1.ext_flag ==0)//仅用于标准帧滤波{rx_sidh = (cfg->config.filter.filter_1.filter<<21)>>24;rx_sidl = (cfg->config.filter.filter_1.filter<<29)>>24;sit2515_write_byte(dev,RXF1SIDH,rx_sidh);//验收滤波寄存器1标准标识符高位sit2515_write_byte(dev,RXF1SIDL,rx_sidl);//验收滤波寄存器1标准标识符低位						}else//仅用于扩展帧滤波{rx_sidh = (cfg->config.filter.filter_1.filter<<3)>>24;rx_sidl = (cfg->config.filter.filter_1.filter>>16)&0x03;rx_sidl = rx_sidl|((cfg->config.filter.filter_1.filter>>13)&0xE0)|EXIDE_SET;rx_eid8 = (cfg->config.filter.filter_1.filter<<16)>>24;rx_eid0 = (cfg->config.filter.filter_1.filter)&0xFF;					sit2515_write_byte(dev,RXF1SIDH,rx_sidh);//验收滤波寄存器1标准标识符高位sit2515_write_byte(dev,RXF1SIDL,rx_sidl);//验收滤波寄存器1标准标识符低位	sit2515_write_byte(dev,RXF1EID8,rx_eid8);//验收滤波寄存器1扩展标识符高位sit2515_write_byte(dev,RXF1EID0,rx_eid0);//验收滤波寄存器1扩展标识符低位				}/*验收滤波寄存器2设置*/if(cfg->config.filter.filter_2.ext_flag ==0)//仅用于标准帧滤波{rx_sidh = (cfg->config.filter.filter_2.filter<<21)>>24;rx_sidl = (cfg->config.filter.filter_2.filter<<29)>>24;sit2515_write_byte(dev,RXF2SIDH,rx_sidh);//验收滤波寄存器2标准标识符高位sit2515_write_byte(dev,RXF2SIDL,rx_sidl);//验收滤波寄存器2标准标识符低位						}else//仅用于扩展帧滤波{rx_sidh = (cfg->config.filter.filter_2.filter<<3)>>24;rx_sidl = (cfg->config.filter.filter_2.filter>>16)&0x03;rx_sidl = rx_sidl|((cfg->config.filter.filter_2.filter>>13)&0xE0)|EXIDE_SET;rx_eid8 = (cfg->config.filter.filter_2.filter<<16)>>24;rx_eid0 = (cfg->config.filter.filter_2.filter)&0xFF;					sit2515_write_byte(dev,RXF2SIDH,rx_sidh);//验收滤波寄存器2标准标识符高位sit2515_write_byte(dev,RXF2SIDL,rx_sidl);//验收滤波寄存器2标准标识符低位	sit2515_write_byte(dev,RXF2EID8,rx_eid8);//验收滤波寄存器2扩展标识符高位sit2515_write_byte(dev,RXF2EID0,rx_eid0);//验收滤波寄存器2扩展标识符低位				}/*验收滤波寄存器3设置*/if(cfg->config.filter.filter_3.ext_flag ==0)//仅用于标准帧滤波{rx_sidh = (cfg->config.filter.filter_3.filter<<21)>>24;rx_sidl = (cfg->config.filter.filter_3.filter<<29)>>24;sit2515_write_byte(dev,RXF3SIDH,rx_sidh);//验收滤波寄存器3标准标识符高位sit2515_write_byte(dev,RXF3SIDL,rx_sidl);//验收滤波寄存器3标准标识符低位						}else//仅用于扩展帧滤波{rx_sidh = (cfg->config.filter.filter_3.filter<<3)>>24;rx_sidl = (cfg->config.filter.filter_3.filter>>16)&0x03;rx_sidl = rx_sidl|((cfg->config.filter.filter_3.filter>>13)&0xE0)|EXIDE_SET;rx_eid8 = (cfg->config.filter.filter_3.filter<<16)>>24;rx_eid0 = (cfg->config.filter.filter_3.filter)&0xFF;					sit2515_write_byte(dev,RXF3SIDH,rx_sidh);//验收滤波寄存器3标准标识符高位sit2515_write_byte(dev,RXF3SIDL,rx_sidl);//验收滤波寄存器3标准标识符低位	sit2515_write_byte(dev,RXF3EID8,rx_eid8);//验收滤波寄存器3扩展标识符高位sit2515_write_byte(dev,RXF3EID0,rx_eid0);//验收滤波寄存器3扩展标识符低位				}/*验收滤波寄存器4设置*/if(cfg->config.filter.filter_4.ext_flag ==0)//仅用于标准帧滤波{rx_sidh = (cfg->config.filter.filter_4.filter<<21)>>24;rx_sidl = (cfg->config.filter.filter_4.filter<<29)>>24;sit2515_write_byte(dev,RXF4SIDH,rx_sidh);//验收滤波寄存器4标准标识符高位sit2515_write_byte(dev,RXF4SIDL,rx_sidl);//验收滤波寄存器4标准标识符低位						}else//仅用于扩展帧滤波{rx_sidh = (cfg->config.filter.filter_4.filter<<3)>>24;rx_sidl = (cfg->config.filter.filter_4.filter>>16)&0x03;rx_sidl = rx_sidl|((cfg->config.filter.filter_4.filter>>13)&0xE0)|EXIDE_SET;rx_eid8 = (cfg->config.filter.filter_4.filter<<16)>>24;rx_eid0 = (cfg->config.filter.filter_4.filter)&0xFF;					sit2515_write_byte(dev,RXF4SIDH,rx_sidh);//验收滤波寄存器4标准标识符高位sit2515_write_byte(dev,RXF4SIDL,rx_sidl);//验收滤波寄存器4标准标识符低位	sit2515_write_byte(dev,RXF4EID8,rx_eid8);//验收滤波寄存器4扩展标识符高位sit2515_write_byte(dev,RXF4EID0,rx_eid0);//验收滤波寄存器4扩展标识符低位				}/*验收滤波寄存器5设置*/if(cfg->config.filter.filter_5.ext_flag ==0)//仅用于标准帧滤波{rx_sidh = (cfg->config.filter.filter_5.filter<<21)>>24;rx_sidl = (cfg->config.filter.filter_5.filter<<29)>>24;sit2515_write_byte(dev,RXF5SIDH,rx_sidh);//验收滤波寄存器5标准标识符高位sit2515_write_byte(dev,RXF5SIDL,rx_sidl);//验收滤波寄存器5标准标识符低位						}else//仅用于扩展帧滤波{rx_sidh = (cfg->config.filter.filter_5.filter<<3)>>24;rx_sidl = (cfg->config.filter.filter_5.filter>>16)&0x03;rx_sidl = rx_sidl|((cfg->config.filter.filter_5.filter>>13)&0xE0)|EXIDE_SET;rx_eid8 = (cfg->config.filter.filter_5.filter<<16)>>24;rx_eid0 = (cfg->config.filter.filter_5.filter)&0xFF;					sit2515_write_byte(dev,RXF5SIDH,rx_sidh);//验收滤波寄存器5标准标识符高位sit2515_write_byte(dev,RXF5SIDL,rx_sidl);//验收滤波寄存器5标准标识符低位	sit2515_write_byte(dev,RXF5EID8,rx_eid8);//验收滤波寄存器5扩展标识符高位sit2515_write_byte(dev,RXF5EID0,rx_eid0);//验收滤波寄存器5扩展标识符低位				}			}	
/*中断配置*/if(cfg->irq.rx==0)sit2515_write_bit(dev,CANINTE,MASK_1|MASK_0,G_RXIE_DISABLED);//关闭接收缓冲器满中断else sit2515_write_bit(dev,CANINTE,MASK_1|MASK_0,G_RXIE_ENABLED);//开启接收缓冲器满中断if(cfg->irq.tx==0)sit2515_write_bit(dev,CANINTE,MASK_4|MASK_3|MASK_2,G_TXIE_DISABLED);//关闭发送缓冲器空中断else sit2515_write_bit(dev,CANINTE,MASK_4|MASK_3|MASK_2,G_TXIE_ENABLED);//开启发送缓冲器空中断if(cfg->irq.err==0)sit2515_write_bit(dev,CANINTE,MASK_7|MASK_5,ERRIE_DISABLED|IVRE_DISABLED);//关闭错误中断else sit2515_write_bit(dev,CANINTE,MASK_7|MASK_5,ERRIE_ENABLED|IVRE_ENABLED);//开启错误中断if(cfg->irq.wakie==0)sit2515_write_bit(dev,CANINTE,MASK_6,WAKIE_DISABLED);//关闭唤醒中断else sit2515_write_bit(dev,CANINTE,MASK_6,WAKIE_ENABLED);//开启唤醒中断		
/*工作模式设置*/sit2515_write_bit(dev,CANCTRL,MASK_7,REQOP_NORMAL);//设定为正常模式return RT_EOK;
}/**
* @brief sit2515设备读一帧数据
* @param[in]  dev                设备句柄
* @param[in]  *buf                读取数据指针
* @param[in]  rxb_num               接收缓存器 0/1
* @return  返回读取状态
* - 1      读取失败
* - 0	   读取成功
*/
static int sit2515_recvmsg(rt_device_t dev, void *buf, rt_uint32_t rxb_num)
{rt_uint8_t ReadData = 0 ;rt_uint8_t i=0;rt_uint32_t id;CanFrame *rx_data;rx_data = (CanFrame *) buf;	ReadData=sit2515_read_byte(dev,REC);//查看接收错误帧if(ReadData > 127){init_sit2515t(dev);//初始化通道return RT_ERROR ;}	if(rxb_num ==0)//RXB0{ReadData =sit2515_read_byte(dev,RXB0SIDL);  //判断是扩展帧还是数据帧,判断数据的第三位1为扩展帧,0为标准帧if(ReadData & 0x10)//远程发送请求位rx_data->rtr_flag =1;//收到标准远程发送请求帧else rx_data->rtr_flag =0;//收到标准数据帧if(ReadData & 0x08)//扩展标识符标志位{//表示扩展帧,取帧ID,帧ID高11位取标准帧的11位,17:16位取RXBnSIDL:0-1位,后16位取RXBnEID8和RXBnEID0//取高 28-21位		id=sit2515_read_byte(dev,RXB0SIDH);ReadData=sit2515_read_byte(dev,RXB0SIDL);//取20-18位,直接从ReadData中读取高三位和低两位id = ((id << 3) | (ReadData >>5));//取17-16位id = ((id << 2) | (ReadData & 0x03));//取15-8位ReadData =sit2515_read_byte(dev,RXB0EID8);id = ((id << 8) | ReadData);//取7-0位ReadData =sit2515_read_byte(dev,RXB0EID0);id = ((id << 8) | ReadData);  		rx_data->ext_flag = 1;//收到扩展帧		rx_data->id = id;		}else{	//读取标准帧,id = sit2515_read_byte(dev,RXB0SIDH);ReadData =sit2515_read_byte(dev,RXB0SIDL);id = ((id <<3) | (ReadData >>5));rx_data->ext_flag = 0;//收到标准帧		rx_data->id = id;}//读取数据长度rx_data->dlc=sit2515_read_byte(dev,RXB0DLC);//读取数据for(i=0;i<rx_data->dlc;i++){//把接收缓冲区里的数据,放到内部RAM缓冲区rx_data->data[i]=sit2515_read_byte(dev,RXB0D0+i);}sit2515_write_bit(dev,CANINTF,MASK_0,RX0IF_RESET);//清除RX0IF中断}else if(rxb_num ==1)//RXB1{ReadData =sit2515_read_byte(dev,RXB1SIDL);  //判断是扩展帧还是数据帧,判断数据的第三位1为扩展帧,0为标准帧//ReadData = ReadData & 0x08 ;if(ReadData & 0x10)//远程发送请求位rx_data->rtr_flag =1;//收到标准远程发送请求帧else rx_data->rtr_flag =0;//收到标准数据帧if(ReadData & 0x08)//扩展标识符标志位{//表示扩展帧,取帧ID,帧ID高11位取标准帧的11位,17:16位取RXBnSIDL:0-1位,后16位取RXBnEID8和RXBnEID0//取高 28-21位		id=sit2515_read_byte(dev,RXB1SIDH);ReadData=sit2515_read_byte(dev,RXB1SIDL);//取20-18位,直接从ReadData中读取高三位和低两位id = ((id << 3) | (ReadData >>5));//取17-16位id = ((id << 2) | (ReadData & 0x03));//取15-8位ReadData =sit2515_read_byte(dev,RXB1EID8);id = ((id << 8) | ReadData);//取7-0位ReadData =sit2515_read_byte(dev,RXB1EID0);id = ((id << 8) | ReadData);  		rx_data->ext_flag = 1;//收到扩展帧		rx_data->id = id;		}else{	//读取标准帧,id = sit2515_read_byte(dev,RXB1SIDH);ReadData =sit2515_read_byte(dev,RXB1SIDL);id = ((id <<3) | (ReadData >>5));rx_data->ext_flag = 0;//收到标准帧		rx_data->id = id;}//读取数据长度rx_data->dlc=sit2515_read_byte(dev,RXB1DLC);//读取数据for(i=0;i<rx_data->dlc;i++){//把接收缓冲区里的数据,放到内部RAM缓冲区rx_data->data[i]=sit2515_read_byte(dev,RXB1D0+i);}	sit2515_write_bit(dev,CANINTF,MASK_1,RX1IF_RESET);//清除RX0IF中断}return RT_EOK;
}/**
* @brief sit2515设备发送一帧数据
* @param[in]  dev                设备句柄
* @param[in]  *buf                发送数据指针
* @param[in]  txb_num               发送缓存器 0/1
* @return  返回发送状态
* - 1      发送失败
* - 0	   发送成功
*/
static int sit2515_sendmsg(rt_device_t dev, const void *buf, rt_uint32_t txb_num)
{	rt_uint8_t Data = 0 ;rt_uint8_t WriteData = 0; rt_uint8_t i=0;struct rt_can_msg *tx_data;tx_data = (struct rt_can_msg *) buf;		Data=sit2515_read_byte(dev,REC);//查看接收错误帧	if(Data > 127){init_sit2515t(dev);//初始化通道return RT_ERROR ;}	if(txb_num ==0)//TXB0{if(tx_data->ide==RT_CAN_EXTID)//扩展帧{//设定高8位,全部字节29位WriteData = (tx_data->id)>>21;sit2515_write_byte(dev,TXB0SIDH,WriteData);//设定扩展帧及中间5位以及数据帧111 000 11//发送扩展帧第三位必须为1		  WriteData = (tx_data->id)>>18;WriteData = (WriteData & 0x07)<<5;//确定扩展帧WriteData = WriteData | 0x08 ;//确定17和16位Data = (tx_data->id) >> 16;Data = Data &0x03;WriteData = WriteData | Data;sit2515_write_byte(dev,TXB0SIDL,WriteData);//发送8-15sit2515_write_byte(dev,TXB0EID8,(tx_data->id)>>8);//发送0-7sit2515_write_byte(dev,TXB0EID0,(tx_data->id));		}else//设定标准帧{  //设定高8位sit2515_write_byte(dev,TXB0SIDH,(tx_data->id)>>3);//设定低3位,第三位为0时表示发送标准帧sit2515_write_byte(dev,TXB0SIDL,((tx_data->id)<<5));		}if(tx_data->rtr==RT_CAN_DTR)WriteData = (tx_data->len)&0x0F;//数据帧+长度else  WriteData = ((tx_data->len)&0x0F)|0x40;//远程帧+长度sit2515_write_byte(dev,TXB0DLC,WriteData);//帧格式+长度			
//		do Data=sit2515_read_byte(dev,CAN_RD_STATUS);//读状态
//		while(Data&0x04);//判断TXB0CTRL.TXREQ标志位 =1等待报文发送			for(i=0;i<8;i++){sit2515_write_byte(dev,TXB0D0+i,tx_data->data[i]);}	sit2515_write_bit(dev,TXB0CTRL,MASK_3,TXREQ_SET);//报文发送请求位,将此位置 1 以请求报文发送-报文发送后该位自动清零		}else if(txb_num ==1)//TXB1{if(tx_data->ide==RT_CAN_EXTID)//扩展帧{//设定高8位,全部字节29位WriteData = (tx_data->id)>>21;sit2515_write_byte(dev,TXB1SIDH,WriteData);//设定扩展帧及中间5位以及数据帧111 000 11//发送扩展帧第三位必须为1		  WriteData = (tx_data->id)>>18;WriteData = (WriteData & 0x07)<<5;//确定扩展帧WriteData = WriteData | 0x08 ;//确定17和16位Data = (tx_data->id) >> 16;Data = Data &0x03;WriteData = WriteData | Data;sit2515_write_byte(dev,TXB1SIDL,WriteData);//发送8-15sit2515_write_byte(dev,TXB1EID8,(tx_data->id)>>8);//发送0-7sit2515_write_byte(dev,TXB1EID0,(tx_data->id));		}else//设定标准帧{ //设定高8位sit2515_write_byte(dev,TXB1SIDH,(tx_data->id)>>3);//设定低3位,第三位为0时表示发送标准帧sit2515_write_byte(dev,TXB1SIDL,((tx_data->id)<<5));		}if(tx_data->rtr==RT_CAN_DTR)WriteData = (tx_data->len)&0x0F;//数据帧+长度else  WriteData = ((tx_data->len)&0x0F)|0x40;//远程帧+长度sit2515_write_byte(dev,TXB1DLC,WriteData);//帧格式+长度			
//		do Data=sit2515_read_byte(dev,CAN_RD_STATUS);//读状态
//		while(Data&0x10);//判断TXB1CTRL.TXREQ标志位 =1等待报文发送			for(i=0;i<8;i++){sit2515_write_byte(dev,TXB1D0+i,tx_data->data[i]);}	sit2515_write_bit(dev,TXB1CTRL,MASK_3,TXREQ_SET);//报文发送请求位,将此位置 1 以请求报文发送-报文发送后该位自动清零	}else if(txb_num ==2)//TXB2{if(tx_data->ide==RT_CAN_EXTID)//扩展帧{//设定高8位,全部字节29位WriteData = (tx_data->id)>>21;sit2515_write_byte(dev,TXB2SIDH,WriteData);//设定扩展帧及中间5位以及数据帧111 000 11//发送扩展帧第三位必须为1		  WriteData = (tx_data->id)>>18;WriteData = (WriteData & 0x07)<<5;//确定扩展帧WriteData = WriteData | 0x08 ;//确定17和16位Data = (tx_data->id) >> 16;Data = Data &0x03;WriteData = WriteData | Data;sit2515_write_byte(dev,TXB2SIDL,WriteData);//发送8-15sit2515_write_byte(dev,TXB2EID8,(tx_data->id)>>8);//发送0-7sit2515_write_byte(dev,TXB2EID0,(tx_data->id));		}else//设定标准帧{//设定高8位sit2515_write_byte(dev,TXB2SIDH,(tx_data->id)>>3);//设定低3位,第三位为0时表示发送标准帧sit2515_write_byte(dev,TXB2SIDL,((tx_data->id)<<5));		}if(tx_data->rtr==RT_CAN_DTR)WriteData = (tx_data->len)&0x0F;//数据帧+长度else  WriteData = ((tx_data->len)&0x0F)|0x40;//远程帧+长度sit2515_write_byte(dev,TXB2DLC,WriteData);//帧格式+长度		
//		do Data=sit2515_read_byte(dev,CAN_RD_STATUS);//读状态
//		while(Data&0x40);//判断TXB2CTRL.TXREQ标志位 =1等待报文发送			for(i=0;i<8;i++){sit2515_write_byte(dev,TXB2D0+i,tx_data->data[i]);}	sit2515_write_bit(dev,TXB2CTRL,MASK_3,TXREQ_SET);//报文发送请求位,将此位置 1 以请求报文发送-报文发送后该位自动清零		}	return RT_EOK;
}/* RT-Thread device interface */
static rt_err_t sit2515_init(rt_device_t dev)
{init_sit2515t(dev);		return RT_EOK;
}static rt_err_t sit2515_open(rt_device_t dev, rt_uint16_t oflag)
{return RT_EOK;
}static rt_err_t sit2515_close(rt_device_t dev)
{return RT_EOK;
}static rt_err_t sit2515_control(rt_device_t dev, int cmd, void *args)/
{struct sit2515_device *sit2515;struct sit2515_config *cfg;sit2515 = (struct sit2515_device *) dev;RT_ASSERT(sit2515->parent.user_data != 0);cfg = (struct sit2515_config *)sit2515->parent.user_data;switch (cmd){case RT_DEVICE_CTRL_SET_INT://设置中断sit2515_write_byte(dev,CANCTRL,REQOP_CONFIG);//设定为配置模式if(cfg->irq.rx==0)sit2515_write_bit(dev,CANINTE,MASK_1|MASK_0,G_RXIE_DISABLED);//关闭接收缓冲器满中断else sit2515_write_bit(dev,CANINTE,MASK_1|MASK_0,G_RXIE_ENABLED);//开启接收缓冲器满中断if(cfg->irq.tx==0)sit2515_write_bit(dev,CANINTE,MASK_4|MASK_3|MASK_2,G_TXIE_DISABLED);//关闭发送缓冲器空中断else sit2515_write_bit(dev,CANINTE,MASK_4|MASK_3|MASK_2,G_TXIE_ENABLED);//开启发送缓冲器空中断if(cfg->irq.err==0)sit2515_write_bit(dev,CANINTE,MASK_7|MASK_5,ERRIE_DISABLED|IVRE_DISABLED);//关闭错误中断else sit2515_write_bit(dev,CANINTE,MASK_7|MASK_5,ERRIE_ENABLED|IVRE_ENABLED);//开启错误中断if(cfg->irq.wakie==0)sit2515_write_bit(dev,CANINTE,MASK_6,WAKIE_DISABLED);//关闭唤醒中断else sit2515_write_bit(dev,CANINTE,MASK_6,WAKIE_ENABLED);//开启唤醒中断sit2515_write_byte(dev,CANCTRL,REQOP_NORMAL);//设定为正常模式break;case RT_CAN_CMD_SET_FILTER:// 滤波设置{rt_uint8_t rx_sidh=0;//验收屏蔽/滤波寄存器0标准标识符高位rt_uint8_t rx_sidl=0;//验收屏蔽/滤波寄存器0标准标识符低位	rt_uint8_t rx_eid8=0;//验收屏蔽/滤波寄存器0扩展标识符高位rt_uint8_t rx_eid0=0;//验收屏蔽/滤波寄存器0扩展标识符低位sit2515_write_byte(dev,CANCTRL,REQOP_CONFIG);//设定为配置模式	if (cfg->config.fi_flag==0)//{sit2515_write_byte(dev,RXB0CTRL,RXM_RCV_ALL);//关闭滤波接收所有sit2515_write_byte(dev,RXB1CTRL,RXM_RCV_ALL);//关闭滤波接收所有}else{sit2515_write_byte(dev,RXB0CTRL,RXM_VALID_ALL);//接收符合滤波器条件的所有带扩展标识符或标准标识符的有效报文sit2515_write_byte(dev,RXB1CTRL,RXM_VALID_ALL);//接收符合滤波器条件的所有带扩展标识符或标准标识符的有效报文/*验收屏蔽寄存器设置*/if(cfg->config.filter.mask_0.ext_flag == 0){rx_sidh = (cfg->config.filter.mask_0.mask<<21)>>24;rx_sidl = (cfg->config.filter.mask_0.mask<<29)>>24;sit2515_write_byte(dev,RXM0SIDH,rx_sidh);//验收屏蔽寄存器0标准标识符高位sit2515_write_byte(dev,RXM0SIDL,rx_sidl);//验收屏蔽寄存器0标准标识符低位				}else if(cfg->config.filter.mask_0.ext_flag == 1) {rx_sidh = (cfg->config.filter.mask_0.mask<<3)>>24;rx_sidl = (cfg->config.filter.mask_0.mask>>16)&0x03;rx_sidl = rx_sidl|((cfg->config.filter.mask_0.mask>>13)&0xE0);rx_eid8 = (cfg->config.filter.mask_0.mask<<16)>>24;rx_eid0 = (cfg->config.filter.mask_0.mask)&0xFF;					sit2515_write_byte(dev,RXM0SIDH,rx_sidh);//验收屏蔽寄存器0标准标识符高位sit2515_write_byte(dev,RXM0SIDL,rx_sidl);//验收屏蔽寄存器0标准标识符低位	sit2515_write_byte(dev,RXM0EID8,rx_eid8);//验收屏蔽寄存器0扩展标识符高位sit2515_write_byte(dev,RXM0EID0,rx_eid0);//验收屏蔽寄存器0扩展标识符低位						}else {sit2515_write_byte(dev,RXM0SIDH,0);//验收屏蔽寄存器0标准标识符高位sit2515_write_byte(dev,RXM0SIDL,0);//验收屏蔽寄存器0标准标识符低位	sit2515_write_byte(dev,RXM0EID8,0);//验收屏蔽寄存器0扩展标识符高位sit2515_write_byte(dev,RXM0EID0,0);//验收屏蔽寄存器0扩展标识符低位				}if(cfg->config.filter.mask_1.ext_flag == 0){rx_sidh = (cfg->config.filter.mask_1.mask<<21)>>24;rx_sidl = (cfg->config.filter.mask_1.mask<<29)>>24;sit2515_write_byte(dev,RXM1SIDH,rx_sidh);//验收屏蔽寄存器1标准标识符高位sit2515_write_byte(dev,RXM1SIDL,rx_sidl);//验收屏蔽寄存器1标准标识符低位			}else if(cfg->config.filter.mask_1.ext_flag == 1) {rx_sidh = (cfg->config.filter.mask_1.mask<<3)>>24;rx_sidl = (cfg->config.filter.mask_1.mask>>16)&0x03;rx_sidl = rx_sidl|((cfg->config.filter.mask_1.mask>>13)&0xE0);rx_eid8 = (cfg->config.filter.mask_1.mask<<16)>>24;rx_eid0 = (cfg->config.filter.mask_1.mask)&0xFF;					sit2515_write_byte(dev,RXM1SIDH,rx_sidh);//验收屏蔽寄存器1标准标识符高位sit2515_write_byte(dev,RXM1SIDL,rx_sidl);//验收屏蔽寄存器1标准标识符低位	sit2515_write_byte(dev,RXM1EID8,rx_eid8);//验收屏蔽寄存器1扩展标识符高位sit2515_write_byte(dev,RXM1EID0,rx_eid0);//验收屏蔽寄存器1扩展标识符低位						}else {sit2515_write_byte(dev,RXM1SIDH,0);//验收屏蔽寄存器1标准标识符高位sit2515_write_byte(dev,RXM1SIDL,0);//验收屏蔽寄存器1标准标识符低位	sit2515_write_byte(dev,RXM1EID8,0);//验收屏蔽寄存器1扩展标识符高位sit2515_write_byte(dev,RXM1EID0,0);//验收屏蔽寄存器1扩展标识符低位				}/*验收滤波寄存器0设置*/if(cfg->config.filter.filter_0.ext_flag ==0)//仅用于标准帧滤波{rx_sidh = (cfg->config.filter.filter_0.filter<<21)>>24;rx_sidl = (cfg->config.filter.filter_0.filter<<29)>>24;sit2515_write_byte(dev,RXF0SIDH,rx_sidh);//验收滤波寄存器0标准标识符高位sit2515_write_byte(dev,RXF0SIDL,rx_sidl);//验收滤波寄存器0标准标识符低位						}else//仅用于扩展帧滤波{rx_sidh = (cfg->config.filter.filter_0.filter<<3)>>24;rx_sidl = (cfg->config.filter.filter_0.filter>>16)&0x03;rx_sidl = rx_sidl|((cfg->config.filter.filter_0.filter>>13)&0xE0)|EXIDE_SET;rx_eid8 = (cfg->config.filter.filter_0.filter<<16)>>24;rx_eid0 = (cfg->config.filter.filter_0.filter)&0xFF;					sit2515_write_byte(dev,RXF0SIDH,rx_sidh);//验收滤波寄存器0标准标识符高位sit2515_write_byte(dev,RXF0SIDL,rx_sidl);//验收滤波寄存器0标准标识符低位	sit2515_write_byte(dev,RXF0EID8,rx_eid8);//验收滤波寄存器0扩展标识符高位sit2515_write_byte(dev,RXF0EID0,rx_eid0);//验收滤波寄存器0扩展标识符低位				}/*验收滤波寄存器1设置*/if(cfg->config.filter.filter_1.ext_flag ==0)//仅用于标准帧滤波{rx_sidh = (cfg->config.filter.filter_1.filter<<21)>>24;rx_sidl = (cfg->config.filter.filter_1.filter<<29)>>24;sit2515_write_byte(dev,RXF1SIDH,rx_sidh);//验收滤波寄存器1标准标识符高位sit2515_write_byte(dev,RXF1SIDL,rx_sidl);//验收滤波寄存器1标准标识符低位						}else//仅用于扩展帧滤波{rx_sidh = (cfg->config.filter.filter_1.filter<<3)>>24;rx_sidl = (cfg->config.filter.filter_1.filter>>16)&0x03;rx_sidl = rx_sidl|((cfg->config.filter.filter_1.filter>>13)&0xE0)|EXIDE_SET;rx_eid8 = (cfg->config.filter.filter_1.filter<<16)>>24;rx_eid0 = (cfg->config.filter.filter_1.filter)&0xFF;					sit2515_write_byte(dev,RXF1SIDH,rx_sidh);//验收滤波寄存器1标准标识符高位sit2515_write_byte(dev,RXF1SIDL,rx_sidl);//验收滤波寄存器1标准标识符低位	sit2515_write_byte(dev,RXF1EID8,rx_eid8);//验收滤波寄存器1扩展标识符高位sit2515_write_byte(dev,RXF1EID0,rx_eid0);//验收滤波寄存器1扩展标识符低位				}/*验收滤波寄存器2设置*/if(cfg->config.filter.filter_2.ext_flag ==0)//仅用于标准帧滤波{rx_sidh = (cfg->config.filter.filter_2.filter<<21)>>24;rx_sidl = (cfg->config.filter.filter_2.filter<<29)>>24;sit2515_write_byte(dev,RXF2SIDH,rx_sidh);//验收滤波寄存器2标准标识符高位sit2515_write_byte(dev,RXF2SIDL,rx_sidl);//验收滤波寄存器2标准标识符低位						}else//仅用于扩展帧滤波{rx_sidh = (cfg->config.filter.filter_2.filter<<3)>>24;rx_sidl = (cfg->config.filter.filter_2.filter>>16)&0x03;rx_sidl = rx_sidl|((cfg->config.filter.filter_2.filter>>13)&0xE0)|EXIDE_SET;rx_eid8 = (cfg->config.filter.filter_2.filter<<16)>>24;rx_eid0 = (cfg->config.filter.filter_2.filter)&0xFF;					sit2515_write_byte(dev,RXF2SIDH,rx_sidh);//验收滤波寄存器2标准标识符高位sit2515_write_byte(dev,RXF2SIDL,rx_sidl);//验收滤波寄存器2标准标识符低位	sit2515_write_byte(dev,RXF2EID8,rx_eid8);//验收滤波寄存器2扩展标识符高位sit2515_write_byte(dev,RXF2EID0,rx_eid0);//验收滤波寄存器2扩展标识符低位				}/*验收滤波寄存器3设置*/if(cfg->config.filter.filter_3.ext_flag ==0)//仅用于标准帧滤波{rx_sidh = (cfg->config.filter.filter_3.filter<<21)>>24;rx_sidl = (cfg->config.filter.filter_3.filter<<29)>>24;sit2515_write_byte(dev,RXF3SIDH,rx_sidh);//验收滤波寄存器3标准标识符高位sit2515_write_byte(dev,RXF3SIDL,rx_sidl);//验收滤波寄存器3标准标识符低位						}else//仅用于扩展帧滤波{rx_sidh = (cfg->config.filter.filter_3.filter<<3)>>24;rx_sidl = (cfg->config.filter.filter_3.filter>>16)&0x03;rx_sidl = rx_sidl|((cfg->config.filter.filter_3.filter>>13)&0xE0)|EXIDE_SET;rx_eid8 = (cfg->config.filter.filter_3.filter<<16)>>24;rx_eid0 = (cfg->config.filter.filter_3.filter)&0xFF;					sit2515_write_byte(dev,RXF3SIDH,rx_sidh);//验收滤波寄存器3标准标识符高位sit2515_write_byte(dev,RXF3SIDL,rx_sidl);//验收滤波寄存器3标准标识符低位	sit2515_write_byte(dev,RXF3EID8,rx_eid8);//验收滤波寄存器3扩展标识符高位sit2515_write_byte(dev,RXF3EID0,rx_eid0);//验收滤波寄存器3扩展标识符低位				}/*验收滤波寄存器4设置*/if(cfg->config.filter.filter_4.ext_flag ==0)//仅用于标准帧滤波{rx_sidh = (cfg->config.filter.filter_4.filter<<21)>>24;rx_sidl = (cfg->config.filter.filter_4.filter<<29)>>24;sit2515_write_byte(dev,RXF4SIDH,rx_sidh);//验收滤波寄存器4标准标识符高位sit2515_write_byte(dev,RXF4SIDL,rx_sidl);//验收滤波寄存器4标准标识符低位						}else//仅用于扩展帧滤波{rx_sidh = (cfg->config.filter.filter_4.filter<<3)>>24;rx_sidl = (cfg->config.filter.filter_4.filter>>16)&0x03;rx_sidl = rx_sidl|((cfg->config.filter.filter_4.filter>>13)&0xE0)|EXIDE_SET;rx_eid8 = (cfg->config.filter.filter_4.filter<<16)>>24;rx_eid0 = (cfg->config.filter.filter_4.filter)&0xFF;					sit2515_write_byte(dev,RXF4SIDH,rx_sidh);//验收滤波寄存器4标准标识符高位sit2515_write_byte(dev,RXF4SIDL,rx_sidl);//验收滤波寄存器4标准标识符低位	sit2515_write_byte(dev,RXF4EID8,rx_eid8);//验收滤波寄存器4扩展标识符高位sit2515_write_byte(dev,RXF4EID0,rx_eid0);//验收滤波寄存器4扩展标识符低位				}/*验收滤波寄存器5设置*/if(cfg->config.filter.filter_5.ext_flag ==0)//仅用于标准帧滤波{rx_sidh = (cfg->config.filter.filter_5.filter<<21)>>24;rx_sidl = (cfg->config.filter.filter_5.filter<<29)>>24;sit2515_write_byte(dev,RXF5SIDH,rx_sidh);//验收滤波寄存器5标准标识符高位sit2515_write_byte(dev,RXF5SIDL,rx_sidl);//验收滤波寄存器5标准标识符低位						}else//仅用于扩展帧滤波{rx_sidh = (cfg->config.filter.filter_5.filter<<3)>>24;rx_sidl = (cfg->config.filter.filter_5.filter>>16)&0x03;rx_sidl = rx_sidl|((cfg->config.filter.filter_5.filter>>13)&0xE0)|EXIDE_SET;rx_eid8 = (cfg->config.filter.filter_5.filter<<16)>>24;rx_eid0 = (cfg->config.filter.filter_5.filter)&0xFF;					sit2515_write_byte(dev,RXF5SIDH,rx_sidh);//验收滤波寄存器5标准标识符高位sit2515_write_byte(dev,RXF5SIDL,rx_sidl);//验收滤波寄存器5标准标识符低位	sit2515_write_byte(dev,RXF5EID8,rx_eid8);//验收滤波寄存器5扩展标识符高位sit2515_write_byte(dev,RXF5EID0,rx_eid0);//验收滤波寄存器5扩展标识符低位				}			}sit2515_write_byte(dev,CANCTRL,REQOP_NORMAL);//设定为正常模式break;}case RT_CAN_CMD_SET_MODE://设置模式sit2515_write_byte(dev,CANCTRL,REQOP_CONFIG);//设定为配置模式if(cfg->mode.oper_mode==RT_CAN_MODE_NORMAL)sit2515_write_byte(dev,CANCTRL,cfg->mode.oper_mode);//正常工作模式else if(cfg->mode.oper_mode==RT_CAN_MODE_LISTEN)sit2515_write_byte(dev,CANCTRL,cfg->mode.oper_mode);//监听工作模式else if(cfg->mode.oper_mode==RT_CAN_MODE_LOOPBACK)sit2515_write_byte(dev,CANCTRL,cfg->mode.oper_mode);//环回工作模式break;case RT_CAN_CMD_SET_BAUD:// 波特率设置if(cfg->config.br_flag==1){		sit2515_write_byte(dev,CANCTRL,REQOP_CONFIG);//设定为配置模式if(cfg->config.baudrate==_1Mbps){sit2515_write_byte(dev,CNF1,CNF1_CAN_1Mbps);//设置sit2515_write_byte(dev,CNF2,BTLMODE_CNF3|PHSEG1_4TQ|PRSEG_1TQ);//设置sit2515_write_byte(dev,CNF3,WAKFIL_ENABLED|PHSEG2_2TQ);//设置	}else if(cfg->config.baudrate==_500kbps){sit2515_write_byte(dev,CNF1,CNF1_CAN_500Kbps);//设置sit2515_write_byte(dev,CNF2,BTLMODE_CNF3|PHSEG1_8TQ|PRSEG_5TQ);//设置sit2515_write_byte(dev,CNF3,WAKFIL_ENABLED|PHSEG2_2TQ);//设置	}else if(cfg->config.baudrate==_250kbps){sit2515_write_byte(dev,CNF1,CNF1_CAN_250Kbps);//设置sit2515_write_byte(dev,CNF2,BTLMODE_CNF3|PHSEG1_8TQ|PRSEG_5TQ);//设置sit2515_write_byte(dev,CNF3,WAKFIL_ENABLED|PHSEG2_2TQ);//设置}else if(cfg->config.baudrate==_125kbps){		/*波特率125kbps*/sit2515_write_byte(dev,CNF1,CNF1_CAN_125Kbps);//设置sit2515_write_byte(dev,CNF2,BTLMODE_CNF3|PHSEG1_8TQ|PRSEG_5TQ);//设置sit2515_write_byte(dev,CNF3,WAKFIL_ENABLED|PHSEG2_2TQ);//设置							}		sit2515_write_byte(dev,CANCTRL,REQOP_NORMAL);//设定为正常模式}break;default:break;}	return RT_EOK;
}/**
* @brief sit2515设备读操作  缓冲区
* @param[in]  dev                设备句柄
* @param[in]  pos                spi读寻址地址
* @param[in]  *buffer            读取数据的指针
* @param[in]  size               读取数据的长度
* @return  返回读取成功的字节
* - 0      读取失败
* - Others 读取成功的字节数
*/
static rt_size_t sit2515_read(rt_device_t dev, rt_off_t pos, void *buffer, rt_size_t size)
{	struct sit2515_device *sit2515;struct sit2515_config *cfg;sit2515 = (struct sit2515_device *) dev;RT_ASSERT(sit2515->parent.user_data != 0);cfg = (struct sit2515_config *)sit2515->parent.user_data;	struct rt_can_msg *rxmsg;rxmsg = buffer;rt_uint8_t i=0;	rxmsg->id = cfg->Can_Dev.can_recv_buf[cfg->Can_Dev.read_pos].id;rxmsg->len = cfg->Can_Dev.can_recv_buf[cfg->Can_Dev.read_pos].dlc;rxmsg->rtr = cfg->Can_Dev.can_recv_buf[cfg->Can_Dev.read_pos].rtr_flag;rxmsg->ide = cfg->Can_Dev.can_recv_buf[cfg->Can_Dev.read_pos].ext_flag;for(i=0;i<rxmsg->len;i++)rxmsg->data[i] = cfg->Can_Dev.can_recv_buf[cfg->Can_Dev.read_pos].data[i];	cfg->Can_Dev.read_pos = (cfg->Can_Dev.read_pos +1)%RECV_BUF_SIZE;//	LOG_D("read_pos =%d \n", Can_Dev.read_pos);return size;
}/**
* @brief sit2515设备写操作
* @param[in]  dev                设备句柄
* @param[in]  pos                spi写寻址地址
* @param[in]  *buffer            写入数据的指针
* @param[in]  size               写入数据的长度
* @return  返回写入成功的字节
* - 0      写入失败
* - Others 写入成功的字节数
*/
static rt_size_t sit2515_write(rt_device_t dev, rt_off_t pos, const void *buffer, rt_size_t size)
{CanFrame *tx_data;tx_data = (CanFrame *) buffer;		rt_uint8_t data;		RT_ASSERT(dev != 0);data=sit2515_read_byte(dev,CAN_RD_STATUS);//读状态if((data&0x04)!=0x04)//判断TXB0CTRL.TXREQ标志位 =1等待报文发送	=0 缓冲器无等待发送报文{sit2515_sendmsg(dev, tx_data, 0);//TXB0发送	//LOG_D("TXB0 send! \n");}else if((data&0x10)!=0x10)//判断TXB1CTRL.TXREQ标志位 =1等待报文发送	=0 缓冲器无等待发送报文{sit2515_sendmsg(dev, tx_data, 1);//TXB1发送//LOG_D("TXB1 send! \n");}else if((data&0x40)!=0x40)//判断TXB2CTRL.TXREQ标志位 =1等待报文发送	=0 缓冲器无等待发送报文{sit2515_sendmsg(dev, tx_data, 2);//TXB2发送//LOG_D("TXB2 send! \n");}	else {LOG_E("TXB is fall,send faild! \n");return RT_ERROR;}return size;
}#ifdef RT_USING_DEVICE_OPS
/** sit2515设备操作ops */
const static struct rt_device_ops sit2515_ops =
{sit2515_init,sit2515_open,sit2515_close,sit2515_read,sit2515_write,sit2515_control
};
#endif#ifdef BSP_USING_SIT2515_0
/**
* @brief sit2515设备注册
* @param[in]  *device_name     设备名称
* @param[in]  *spi_bus            spi总线设备名称
* @param[in]  *user_data        用户数据sit2515_config 
* @return  函数执行结果
* - RT_EOK 执行成功
* - Others 失败
*/
rt_err_t sit2515_0_register(const char *device_name, const char *spi_bus, void *user_data)
{	static struct sit2515_device sit2515_drv;struct rt_spi_device *bus;rt_soft_spi_device_attach(spi_bus, SSPI_DEVICE_NAME0, GPIOA , GPIO_PIN_4);//根据实际CS引脚修改bus = (struct rt_spi_device *)rt_device_find(SSPI_DEVICE_NAME0);//if (bus == RT_NULL){return RT_ENOSYS;}	/* config spi */bus->config.data_width = 8;//16位宽度bus->config.mode = RT_SPI_MASTER|RT_SPI_MODE_0 | RT_SPI_MSB; /* SPI Compatible: Mode 0 and Mode 3 */bus->config.max_hz = 10 * 1000 * 1000; /* 10M */rt_soft_spi_configure(bus, &bus->config);sit2515_drv.bus = bus;sit2515_drv.parent.type      = RT_Device_Class_CAN;
#ifdef RT_USING_DEVICE_OPSsit2515_drv.parent.ops       = &sit2515_ops;
#elsesit2515_drv.parent.init      = sit2515_init;sit2515_drv.parent.open      = sit2515_open;sit2515_drv.parent.close     = sit2515_close;sit2515_drv.parent.read      = sit2515_read;sit2515_drv.parent.write     = sit2515_write;sit2515_drv.parent.control   = sit2515_control;
#endifsit2515_drv.parent.user_data = user_data;rt_device_register(&sit2515_drv.parent, device_name, RT_DEVICE_FLAG_RDWR);//rt_device_unregister((rt_device_t)bus);//把"sspi00"这个中间驱动注销return RT_EOK;
}/***************************************************************************
功能:外部中断处理函数
参数:无
反馈:无
注意:
*****************************************************************************/
void sit2515_0_irq(void  *dev)
{ //rt_enter_critical();/*进入临界区*/rt_sem_release(&int02_sem);//释放中断信号量	//rt_exit_critical();/*退出临界区*/
}/*中断处理线程*/
static void sit2515_0_irq_thread(void *dev)
{struct sit2515_device *sit2515;struct sit2515_config *cfg;sit2515 = (struct sit2515_device *) dev;RT_ASSERT(sit2515->parent.user_data != 0);cfg = (struct sit2515_config *)sit2515->parent.user_data;	rt_uint8_t data=0;	rt_uint8_t err=0;	while (1){	/* 阻塞等待中断信号量 */rt_sem_take(&int02_sem, RT_WAITING_FOREVER);//RT_WAITING_FOREVER);data=sit2515_read_byte(dev,CANINTF);//读中断标志寄存器if(data&(RX0IF|RX1IF))//接收0或1中断{if(data&RX0IF){sit2515_recvmsg(dev, &cfg->Can_Dev.can_recv_buf[cfg->Can_Dev.recv_pos],0);//读取RXB0cfg->Can_Dev.recv_pos = (cfg->Can_Dev.recv_pos +1)%RECV_BUF_SIZE;//接收缓冲区地址+1LOG_D("SIT2515CAN0 RXB0 receive! \n");}if(data&RX1IF){sit2515_recvmsg(dev, &cfg->Can_Dev.can_recv_buf[cfg->Can_Dev.recv_pos],1);//读取RXB1cfg->Can_Dev.recv_pos = (cfg->Can_Dev.recv_pos +1)%RECV_BUF_SIZE;//接收缓冲区地址+1	LOG_D("SIT2515CAN0 RXB1 receive! \n");}LOG_D("SIT2515CAN0 recv_pos =%d \n", Can_Dev.recv_pos);rt_sem_release(&rx02_sem);//释放接收数据信号量	}data=sit2515_read_byte(dev,CANINTF);//读中断标志寄存器if(data&(TX0IF|TX1IF|TX2IF))//清除发送中断{if(data&TX0IF){sit2515_write_bit(dev,CANINTF,MASK_2,TX0IF_RESET);//清除TX0IF中断}if(data&TX1IF){sit2515_write_bit(dev,CANINTF,MASK_3,TX1IF_RESET);//清除TX0IF中断}if(data&TX2IF){sit2515_write_bit(dev,CANINTF,MASK_4,TX2IF_RESET);//清除TX0IF中断}		}data=sit2515_read_byte(dev,CANINTF);//读中断标志寄存器if(data&(ERRIF|MERRF))//错误中断标志位,报文错误中断标志位{		err = sit2515_read_byte(dev,EFLG);//读错误中断标志LOG_E("CANINTF =0x%x EFLG =0x%x SIT2515CAN0 reset!\n",data, err);			sit2515_write_bit(dev,CANINTF,ERRIF|MERRF,ERRIF_RESET|IVRF_RESET);//清除ERRIF,MERRF中断init_sit2515t(dev);			}}
}int init_sit2515_0(void)
{rt_err_t ret;   rt_thread_t thread;ret = sit2515_0_register(SIT2515_DEVICE_NAME0, SIT2515_SPI_BUS_NAME0, &sit2515_cfg0);rt_device_t sit2515_dev = rt_device_find(SIT2515_DEVICE_NAME0);if (sit2515_dev == RT_NULL){rt_kprintf("sit2515can0 init failed! can't find %s device!\n", SIT2515_DEVICE_NAME0);return RT_ERROR;}/*SIT2515 INT引脚为输入模式 */rt_pin_mode(SIT2515_INT_PIN_NUM0, PIN_MODE_INPUT_PULLUP);//输入上拉,INT中断时输入低电平/* 绑定中断,下降沿模式,回调函数名为sit2515_0_irq */rt_pin_attach_irq(SIT2515_INT_PIN_NUM0, PIN_IRQ_MODE_FALLING, sit2515_0_irq, RT_NULL);/* 使能中断 */rt_pin_irq_enable(SIT2515_INT_PIN_NUM0, PIN_IRQ_ENABLE);		/* 初始化 中断信号量 */rt_sem_init(&int02_sem, "int02_sem", 0, RT_IPC_FLAG_FIFO);	/* 初始化 接收数据信号量 */rt_sem_init(&rx02_sem, "rx02_sem", 0, RT_IPC_FLAG_FIFO);	/* 创建中断处理线程 */thread = rt_thread_create("can2_irq", sit2515_0_irq_thread, sit2515_dev, 1024, 7, 5);	if (thread != RT_NULL){rt_thread_startup(thread);}		return ret;
}
INIT_DEVICE_EXPORT(init_sit2515_0);
#endif#ifdef BSP_USING_SIT2515_1
/**
* @brief sit2515设备注册
* @param[in]  *device_name     设备名称
* @param[in]  *spi_bus            spi总线设备名称
* @param[in]  *user_data        用户数据sit2515_config 
* @return  函数执行结果
* - RT_EOK 执行成功
* - Others 失败
*/
rt_err_t sit2515_1_register(const char *device_name, const char *spi_bus, void *user_data)
{static struct sit2515_device sit2515_drv;struct rt_spi_device *bus;rt_soft_spi_device_attach(spi_bus, SSPI_DEVICE_NAME1, GPIOD , GPIO_PIN_3);//根据实际CS引脚修改bus = (struct rt_spi_device *)rt_device_find(SSPI_DEVICE_NAME1);//if (bus == RT_NULL){return RT_ENOSYS;}	/* config spi */bus->config.data_width = 8;//16位宽度bus->config.mode = RT_SPI_MASTER|RT_SPI_MODE_0 | RT_SPI_MSB; /* SPI Compatible: Mode 0 and Mode 3 */bus->config.max_hz = 10 * 1000 * 1000; /* 10M */rt_soft_spi_configure(bus, &bus->config);sit2515_drv.bus = bus;sit2515_drv.parent.type      = RT_Device_Class_CAN;
#ifdef RT_USING_DEVICE_OPSsit2515_drv.parent.ops       = &sit2515_ops;
#elsesit2515_drv.parent.init      = sit2515_init;sit2515_drv.parent.open      = sit2515_open;sit2515_drv.parent.close     = sit2515_close;sit2515_drv.parent.read      = sit2515_read;sit2515_drv.parent.write     = sit2515_write;sit2515_drv.parent.control   = sit2515_control;
#endifsit2515_drv.parent.user_data = user_data;rt_device_register(&sit2515_drv.parent, device_name, RT_DEVICE_FLAG_RDWR);//rt_device_unregister((rt_device_t)bus);//把"sspi10"这个中间驱动注销return RT_EOK;
}/***************************************************************************
功能:外部中断处理函数
参数:无
反馈:无
注意:
*****************************************************************************/
void sit2515_1_irq(void  *dev)
{ //rt_enter_critical();/*进入临界区*/rt_sem_release(&int03_sem);//释放中断信号量	//rt_exit_critical();/*退出临界区*/
}/*中断处理线程*/
static void sit2515_1_irq_thread(void *dev)
{struct sit2515_device *sit2515;struct sit2515_config *cfg;sit2515 = (struct sit2515_device *) dev;RT_ASSERT(sit2515->parent.user_data != 0);cfg = (struct sit2515_config *)sit2515->parent.user_data;	rt_uint8_t data=0;	rt_uint8_t err=0;	while (1){	/* 阻塞等待中断信号量 */rt_sem_take(&int03_sem, RT_WAITING_FOREVER);//RT_WAITING_FOREVER);data=sit2515_read_byte(dev,CANINTF);//读中断标志寄存器if(data&(RX0IF|RX1IF))//接收0或1中断{if(data&RX0IF){sit2515_recvmsg(dev, &cfg->Can_Dev.can_recv_buf[cfg->Can_Dev.recv_pos],0);//读取RXB0cfg->Can_Dev.recv_pos = (cfg->Can_Dev.recv_pos +1)%RECV_BUF_SIZE;//接收缓冲区地址+1LOG_D("2515CAN1 RXB0 receive! \n");}if(data&RX1IF){sit2515_recvmsg(dev, &cfg->Can_Dev.can_recv_buf[cfg->Can_Dev.recv_pos],1);//读取RXB1cfg->Can_Dev.recv_pos = (cfg->Can_Dev.recv_pos +1)%RECV_BUF_SIZE;//接收缓冲区地址+1	LOG_D("2515CAN1 RXB1 receive! \n");}LOG_D("2515CAN1 recv_pos =%d \n", Can_Dev.recv_pos);rt_sem_release(&rx03_sem);//释放接收数据信号量	}data=sit2515_read_byte(dev,CANINTF);//读中断标志寄存器if(data&(TX0IF|TX1IF|TX2IF))//清除发送中断{if(data&TX0IF){sit2515_write_bit(dev,CANINTF,MASK_2,TX0IF_RESET);//清除TX0IF中断}if(data&TX1IF){sit2515_write_bit(dev,CANINTF,MASK_3,TX1IF_RESET);//清除TX0IF中断}if(data&TX2IF){sit2515_write_bit(dev,CANINTF,MASK_4,TX2IF_RESET);//清除TX0IF中断}		}data=sit2515_read_byte(dev,CANINTF);//读中断标志寄存器if(data&(ERRIF|MERRF))//错误中断标志位,报文错误中断标志位{		err = sit2515_read_byte(dev,EFLG);//读错误中断标志LOG_E("CANINTF =0x%x EFLG =0x%x SIT2515CAN1 reset!\n", data,err);				sit2515_write_bit(dev,CANINTF,ERRIF|MERRF,ERRIF_RESET|IVRF_RESET);//清除ERRIF,MERRF中断		init_sit2515t(dev);	}}
}int init_sit2515_1(void)
{rt_err_t ret;   rt_thread_t thread;//rcu_periph_clock_enable(RCU_GPIOD);//开启用到的ret = sit2515_1_register(SIT2515_DEVICE_NAME1, SIT2515_SPI_BUS_NAME1, &sit2515_cfg1);rt_device_t sit2515_dev = rt_device_find(SIT2515_DEVICE_NAME1);if (sit2515_dev == RT_NULL){rt_kprintf("sit2515can1 init failed! can't find %s device!\n", SIT2515_DEVICE_NAME1);return RT_ERROR;}/*SIT2515 INT引脚为输入模式 */rt_pin_mode(SIT2515_INT_PIN_NUM1, PIN_MODE_INPUT_PULLUP);//输入上拉,INT中断时输入低电平/* 绑定中断,下降沿模式,回调函数名为sit2515_1_irq */rt_pin_attach_irq(SIT2515_INT_PIN_NUM1, PIN_IRQ_MODE_FALLING, sit2515_1_irq, RT_NULL);/* 使能中断 */rt_pin_irq_enable(SIT2515_INT_PIN_NUM1, PIN_IRQ_ENABLE);		/* 初始化 中断信号量 */rt_sem_init(&int03_sem, "int03_sem", 0, RT_IPC_FLAG_FIFO);	/* 初始化 接收数据信号量 */rt_sem_init(&rx03_sem, "rx03_sem", 0, RT_IPC_FLAG_FIFO);	/* 创建中断处理线程 */thread = rt_thread_create("can3_irq", sit2515_1_irq_thread, sit2515_dev, 1024, 8, 5);	if (thread != RT_NULL){rt_thread_startup(thread);}		return ret;
}
INIT_DEVICE_EXPORT(init_sit2515_1);
#endif/*************************************SIT2515 CAN0使用例程***************************************************************/
#ifdef BSP_USING_SIT2515_0
rt_mutex_t can2_mutex = RT_NULL;/* 指向互斥量的指针 */
rt_device_t can2_dev;            /* CAN 设备句柄 */
static void can2_rx_thread(void *parameter)
{struct rt_can_msg rxmsg = {0};	while (1){	/* 阻塞等待接收信号量 */rt_sem_take(&rx02_sem, RT_WAITING_FOREVER);/* 从 CAN 读取一帧数据 */rt_device_read(can2_dev, 0, &rxmsg, sizeof(rxmsg));	/*发送接收到的数据*/if(rt_mutex_take(can2_mutex, RT_WAITING_FOREVER)==RT_EOK)/*获取互斥信号量*/{rt_device_write(can2_dev,0x00, &rxmsg, sizeof(rxmsg));rt_mutex_release(can2_mutex);/*释放互斥信号量*/}}
}
static int can2_sample_init(void)
{rt_err_t res;rt_thread_t thread;/* 查找 CAN 设备 */can2_dev = rt_device_find(SIT2515_DEVICE_NAME0);if (!can2_dev){rt_kprintf("find %s failed!\n", SIT2515_DEVICE_NAME0);return RT_ERROR;}else {			res = rt_device_open(can2_dev, RT_DEVICE_FLAG_RDWR);if(res==RT_EOK){res = rt_device_control(can2_dev, RT_CAN_CMD_SET_BAUD,RT_NULL);res = rt_device_control(can2_dev, RT_CAN_CMD_SET_FILTER,RT_NULL);res = rt_device_control(can2_dev, RT_CAN_CMD_SET_MODE,RT_NULL);res = rt_device_control(can2_dev, RT_DEVICE_CTRL_SET_INT,RT_NULL);/* 创建一个动态互斥量 用于发送互斥*/can2_mutex = rt_mutex_create("can2_mutex", RT_IPC_FLAG_FIFO);	/* 创建数据接收线程 */thread = rt_thread_create("can2_rx", can2_rx_thread, RT_NULL, 1024, 13, 5);if (thread != RT_NULL){rt_thread_startup(thread);}else{rt_kprintf("create can2_rx thread failed!\n");}}return res;}
}
INIT_APP_EXPORT(can2_sample_init);
#endif/*************************************SIT2515 CAN1使用例程***************************************************************/
#ifdef BSP_USING_SIT2515_1
rt_mutex_t can3_mutex = RT_NULL;	/* 指向互斥量的指针 */
rt_device_t can3_dev;            /* CAN 设备句柄 */static void can3_rx_thread(void *parameter)
{struct rt_can_msg rxmsg = {0};	while (1){	/* 阻塞等待接收信号量 */rt_sem_take(&rx03_sem, RT_WAITING_FOREVER);/* 从 CAN 读取一帧数据 */rt_device_read(can3_dev, 0, &rxmsg, sizeof(rxmsg));	/*发送接收到的数据*/if(rt_mutex_take(can3_mutex, RT_WAITING_FOREVER)==RT_EOK)/*获取互斥信号量*/{rt_device_write(can3_dev,0x00, &rxmsg, sizeof(rxmsg));rt_mutex_release(can3_mutex);/*释放互斥信号量*/}}
}
static int can3_sample_init(void)
{rt_err_t res;rt_thread_t thread;/* 查找 CAN 设备 */can3_dev = rt_device_find(SIT2515_DEVICE_NAME1);if (!can3_dev){rt_kprintf("find %s failed!\n", SIT2515_DEVICE_NAME1);return RT_ERROR;}else {				res = rt_device_open(can3_dev, RT_DEVICE_FLAG_RDWR);if(res==RT_EOK){res = rt_device_control(can3_dev, RT_CAN_CMD_SET_BAUD,RT_NULL);res = rt_device_control(can3_dev, RT_CAN_CMD_SET_FILTER,RT_NULL);res = rt_device_control(can3_dev, RT_CAN_CMD_SET_MODE,RT_NULL);res = rt_device_control(can3_dev, RT_DEVICE_CTRL_SET_INT,RT_NULL);/* 创建一个动态互斥量 用于发送互斥*/can3_mutex = rt_mutex_create("can3_mutex", RT_IPC_FLAG_FIFO);	/* 创建数据接收线程 */thread = rt_thread_create("can3_rx", can3_rx_thread, RT_NULL, 1024, 12, 5);if (thread != RT_NULL){rt_thread_startup(thread);}else{rt_kprintf("create can3_rx thread failed!\n");}}return res;}
}
INIT_APP_EXPORT(can3_sample_init);
#endif#endif

******************************************以下是头文件****************************************************


#ifndef __DRV_SIT2515_H__
#define __DRV_SIT2515_H__
#include <rtdevice.h>/**//*SIT2515CAN0*/
#ifdef BSP_USING_SIT2515_0
#define SIT2515_DEVICE_NAME0     "2515can0" /*驱动设备名称*/
#define SIT2515_SPI_BUS_NAME0       "sspi0"  /* 传感器连接的SPI总线设备名称 */
#define SSPI_DEVICE_NAME0             "sspi00"
/* 引脚编号,通过查看设备驱动文件drv_gpio.c确定 */
#ifndef SIT2515_INT_PIN_NUM0 //中断引脚配置#define SIT2515_INT_PIN_NUM0            8  /* PA8 */
#endif
#endif
/*SIT2515CAN1*/
#ifdef BSP_USING_SIT2515_1
#define SIT2515_DEVICE_NAME1     "2515can1" /*驱动设备名称*/
#define SIT2515_SPI_BUS_NAME1       "sspi1"  /* 传感器连接的SPI总线设备名称 */
#define SSPI_DEVICE_NAME1             "sspi10"
/* 引脚编号,通过查看设备驱动文件drv_gpio.c确定 */
#ifndef SIT2515_INT_PIN_NUM1 //中断引脚配置#define SIT2515_INT_PIN_NUM1            55  /* PD7 */
#endif
#endif/*环形数据接收缓冲区长度*/
#define RECV_BUF_SIZE 	20/* Configuration Registers */
#define CANSTAT         0x0E
#define CANCTRL         0x0F
#define BFPCTRL         0x0C
#define TEC             0x1C
#define REC             0x1D
#define CNF3            0x28
#define CNF2            0x29
#define CNF1            0x2A
#define CANINTE         0x2B
#define CANINTF         0x2C
#define EFLG            0x2D
#define TXRTSCTRL       0x0D/*  Recieve Filters */
#define RXF0SIDH        0x00
#define RXF0SIDL        0x01
#define RXF0EID8        0x02
#define RXF0EID0        0x03
#define RXF1SIDH        0x04
#define RXF1SIDL        0x05
#define RXF1EID8        0x06
#define RXF1EID0        0x07
#define RXF2SIDH        0x08
#define RXF2SIDL        0x09
#define RXF2EID8        0x0A
#define RXF2EID0        0x0B
#define RXF3SIDH        0x10
#define RXF3SIDL        0x11
#define RXF3EID8        0x12
#define RXF3EID0        0x13
#define RXF4SIDH        0x14
#define RXF4SIDL        0x15
#define RXF4EID8        0x16
#define RXF4EID0        0x17
#define RXF5SIDH        0x18
#define RXF5SIDL        0x19
#define RXF5EID8        0x1A
#define RXF5EID0        0x1B/* Receive Masks */
#define RXM0SIDH        0x20
#define RXM0SIDL        0x21
#define RXM0EID8        0x22
#define RXM0EID0        0x23
#define RXM1SIDH        0x24
#define RXM1SIDL        0x25
#define RXM1EID8        0x26
#define RXM1EID0        0x27/* Tx Buffer 0 */
#define TXB0CTRL        0x30
#define TXB0SIDH        0x31
#define TXB0SIDL        0x32
#define TXB0EID8        0x33
#define TXB0EID0        0x34
#define TXB0DLC         0x35
#define TXB0D0          0x36
#define TXB0D1          0x37
#define TXB0D2          0x38
#define TXB0D3          0x39
#define TXB0D4          0x3A
#define TXB0D5          0x3B
#define TXB0D6          0x3C
#define TXB0D7          0x3D/* Tx Buffer 1 */
#define TXB1CTRL        0x40
#define TXB1SIDH        0x41
#define TXB1SIDL        0x42
#define TXB1EID8        0x43
#define TXB1EID0        0x44
#define TXB1DLC         0x45
#define TXB1D0          0x46
#define TXB1D1          0x47
#define TXB1D2          0x48
#define TXB1D3          0x49
#define TXB1D4          0x4A
#define TXB1D5          0x4B
#define TXB1D6          0x4C
#define TXB1D7          0x4D/* Tx Buffer 2 */
#define TXB2CTRL        0x50
#define TXB2SIDH        0x51
#define TXB2SIDL        0x52
#define TXB2EID8        0x53
#define TXB2EID0        0x54
#define TXB2DLC         0x55
#define TXB2D0          0x56
#define TXB2D1          0x57
#define TXB2D2          0x58
#define TXB2D3          0x59
#define TXB2D4          0x5A
#define TXB2D5          0x5B
#define TXB2D6          0x5C
#define TXB2D7          0x5D/* Rx Buffer 0 */
#define RXB0CTRL        0x60
#define RXB0SIDH        0x61
#define RXB0SIDL        0x62
#define RXB0EID8        0x63
#define RXB0EID0        0x64
#define RXB0DLC         0x65
#define RXB0D0          0x66
#define RXB0D1          0x67
#define RXB0D2          0x68
#define RXB0D3          0x69
#define RXB0D4          0x6A
#define RXB0D5          0x6B
#define RXB0D6          0x6C
#define RXB0D7          0x6D/* Rx Buffer 1 */
#define RXB1CTRL        0x70
#define RXB1SIDH        0x71
#define RXB1SIDL        0x72
#define RXB1EID8        0x73
#define RXB1EID0        0x74
#define RXB1DLC         0x75
#define RXB1D0          0x76
#define RXB1D1          0x77
#define RXB1D2          0x78
#define RXB1D3          0x79
#define RXB1D4          0x7A
#define RXB1D5          0x7B
#define RXB1D6          0x7C
#define RXB1D7          0x7D/********************************************************************               Bit register masks                                ********************************************************************//* TXBnCTRL */
#define TXREQ           0x08
#define TXP             0x03/* RXBnCTRL */
#define RXM             0x60
#define BUKT            0x04/* CANCTRL */
#define REQOP           0xE0 
#define ABAT            0x10
#define	OSM             0x08
#define CLKEN           0x04
#define CLKPRE          0x03/* CANSTAT */
#define REQOP           0xE0
#define ICOD            0x0E/* CANINTE */
#define RX0IE           0x01
#define RX1IE           0x02
#define TX0IE           0x04
#define TX1IE           0x80
#define TX2IE           0x10
#define ERRIE           0x20
#define WAKIE           0x40
#define MERRE           0x80/* CANINTF */
#define RX0IF           0x01
#define RX1IF           0x02
#define TX0IF           0x04
#define TX1IF           0x80
#define TX2IF           0x10
#define ERRIF           0x20
#define WAKIF           0x40
#define MERRF           0x80/* BFPCTRL */
#define B1BFS           0x20
#define B0BFS           0x10
#define B1BFE           0x08
#define B0BFE           0x04
#define B1BFM           0x02
#define B0BFM           0x01/* CNF1 Masks */
#define SJW             0xC0
#define BRP             0x3F/* CNF2 Masks */
#define BTLMODE         0x80
#define SAM             0x40
#define PHSEG1          0x38
#define PRSEG           0x07/* CNF3 Masks */
#define WAKFIL          0x40
#define PHSEG2          0x07/* TXRTSCTRL Masks */
#define TXB2RTS         0x04
#define TXB1RTS         0x02
#define TXB0RTS         0x01/********************************************************************                    Bit Timing Configuration                     ********************************************************************//* CNF1 */
#define SJW_1TQ         0x40
#define SJW_2TQ         0x80
#define SJW_3TQ         0x90
#define SJW_4TQ         0xC0/* CNF2 */
#define BTLMODE_CNF3    0x80
#define BTLMODE_PH1_IPT 0x00#define SMPL_3X         0x40
#define SMPL_1X         0x00#define PHSEG1_8TQ      0x38
#define PHSEG1_7TQ      0x30
#define PHSEG1_6TQ      0x28
#define PHSEG1_5TQ      0x20
#define PHSEG1_4TQ      0x18
#define PHSEG1_3TQ      0x10
#define PHSEG1_2TQ      0x08
#define PHSEG1_1TQ      0x00#define PRSEG_8TQ       0x07
#define PRSEG_7TQ       0x06
#define PRSEG_6TQ       0x05
#define PRSEG_5TQ       0x04
#define PRSEG_4TQ       0x03
#define PRSEG_3TQ       0x02
#define PRSEG_2TQ       0x01
#define PRSEG_1TQ       0x00/* CNF3 */
#define PHSEG2_8TQ      0x07
#define PHSEG2_7TQ      0x06
#define PHSEG2_6TQ      0x05
#define PHSEG2_5TQ      0x04
#define PHSEG2_4TQ      0x03
#define PHSEG2_3TQ      0x02
#define PHSEG2_2TQ      0x01
#define PHSEG2_1TQ      0x00#define SOF_ENABLED     0x80
#define WAKFIL_ENABLED  0x40  //开启过滤器
#define WAKFIL_DISABLED 0x00  //关闭过滤器/********************************************************************                  Control/Configuration Registers                ********************************************************************//* CANINTE */
#define RX0IE_ENABLED   0x01
#define RX0IE_DISABLED  0x00
#define RX1IE_ENABLED   0x02
#define RX1IE_DISABLED  0x00
#define G_RXIE_ENABLED  0x03
#define G_RXIE_DISABLED 0x00#define TX0IE_ENABLED   0x04
#define TX0IE_DISABLED  0x00
#define TX1IE_ENABLED   0x08
#define TX2IE_DISABLED  0x00
#define TX2IE_ENABLED   0x10
#define TX2IE_DISABLED  0x00
#define G_TXIE_ENABLED  0x1C
#define G_TXIE_DISABLED 0x00#define ERRIE_ENABLED   0x20
#define ERRIE_DISABLED  0x00
#define WAKIE_ENABLED   0x40
#define WAKIE_DISABLED  0x00
#define IVRE_ENABLED    0x80
#define IVRE_DISABLED   0x00/* CANINTF */
#define RX0IF_SET       0x01
#define RX0IF_RESET     0x00
#define RX1IF_SET       0x02
#define RX1IF_RESET     0x00
#define TX0IF_SET       0x04
#define TX0IF_RESET     0x00
#define TX1IF_SET       0x08
#define TX1IF_RESET     0x00
#define TX2IF_SET       0x10
#define TX2IF_RESET     0x00
#define ERRIF_SET       0x20
#define ERRIF_RESET     0x00
#define WAKIF_SET       0x40
#define WAKIF_RESET     0x00
#define IVRF_SET        0x80
#define IVRF_RESET      0x00/* CANCTRL */ 
#define REQOP_CONFIG    0x80
#define REQOP_LISTEN    0x60
#define REQOP_LOOPBACK  0x40
#define REQOP_SLEEP     0x20
#define REQOP_NORMAL    0x00 #define ABORT           0x10#define OSM_ENABLED     0x08#define CLKOUT_ENABLED  0x04
#define CLKOUT_DISABLED 0x00
#define CLKOUT_PRE_8    0x03
#define CLKOUT_PRE_4    0x02
#define CLKOUT_PRE_2    0x01
#define CLKOUT_PRE_1    0x00/* CANSTAT */
#define OPMODE_CONFIG   0x80
#define OPMODE_LISTEN   0x60
#define OPMODE_LOOPBACK 0x40
#define OPMODE_SLEEP    0x20
#define OPMODE_NORMAL   0x00/* RXBnCTRL */
#define RXM_RCV_ALL     0x60
#define RXM_VALID_EXT   0x40
#define RXM_VALID_STD   0x20
#define RXM_VALID_ALL   0x00#define RXRTR_REMOTE    0x08
#define RXRTR_NO_REMOTE 0x00#define BUKT_ROLLOVER    0x04
#define BUKT_NO_ROLLOVER 0x00#define FILHIT0_FLTR_1  0x01
#define FILHIT0_FLTR_0  0x00#define FILHIT1_FLTR_5  0x05
#define FILHIT1_FLTR_4  0x04
#define FILHIT1_FLTR_3  0x03
#define FILHIT1_FLTR_2  0x02
#define FILHIT1_FLTR_1  0x01
#define FILHIT1_FLTR_0  0x00/* TXBnCTRL */
#define TXREQ_SET       0x08
#define TXREQ_CLEAR     0x00#define TXP_HIGHEST     0x03
#define TXP_INTER_HIGH  0x02
#define TXP_INTER_LOW   0x01
#define TXP_LOWEST      0x00/********************************************************************                  Register Bit Masks                             ********************************************************************/#define MASK_0          0x01#define MASK_1          0x02#define MASK_2          0x04#define MASK_3          0x08#define MASK_4          0x10#define MASK_5          0x20#define MASK_6          0x40#define MASK_7          0x80    /********************************************************************                  CAN SPI commands                               ********************************************************************/#define CAN_RESET       0xC0
#define CAN_READ        0x03
#define CAN_WRITE       0x02
#define CAN_RTS         0x80
#define CAN_RTS_TXB0    0x81
#define CAN_RTS_TXB1    0x82
#define CAN_RTS_TXB2    0x84
#define CAN_RD_STATUS   0xA0
#define CAN_BIT_MODIFY  0x05  
#define CAN_RX_STATUS   0xB0
#define CAN_RD_RX_BUFF  0x90
#define CAN_LOAD_TX     0X40  /********************************************************************                  Miscellaneous                                  ********************************************************************/#define DUMMY_BYTE      0x00
#define TXB0            0x31
#define TXB1            0x41
#define TXB2            0x51
#define RXB0            0x61
#define RXB1            0x71
#define EXIDE_SET       0x08
#define EXIDE_RESET     0x00//MCP2515   采用8MHz晶振   建议使用20M晶振,否则CAN通讯速率较慢。
//#define CNF1_CAN_10Kbps 0x13
//#define CNF1_CAN_20Kbps 0x09
//#define CNF1_CAN_50Kbps 0x03
//#define CNF1_CAN_100Kbps 0x01
//#define CNF1_CAN_125Kbps 0x01
//#define CNF1_CAN_250Kbps 0x00
//#define CNF1_CAN_500Kbps 0x00
//#define CNF1_CAN_1Mbps 0x00	//MCP2515   采用16MHz晶振
#define CNF1_CAN_10Kbps 0x31
#define CNF1_CAN_20Kbps 0x13
#define CNF1_CAN_50Kbps 0x07
#define CNF1_CAN_100Kbps 0x03
#define CNF1_CAN_125Kbps 0x03
#define CNF1_CAN_250Kbps 0x01
#define CNF1_CAN_500Kbps 0x00
#define CNF1_CAN_1Mbps 0x00	//MCP2515   采用20MHz晶振
//#define CNF1_CAN_10Kbps 0x31
//#define CNF1_CAN_20Kbps 0x18
//#define CNF1_CAN_50Kbps 0x09
//#define CNF1_CAN_100Kbps 0x04
//#define CNF1_CAN_125Kbps 0x03
//#define CNF1_CAN_250Kbps 0x01
//#define CNF1_CAN_500Kbps 0x00
//#define CNF1_CAN_1Mbps 0x00typedef enum
{_125kbps, /* 125 kBit/sec */_250kbps, /* 250 kBit/sec */_500kbps, /* 500 kBit/sec */_1Mbps/* 1 MBit/sec   */
}CanBaudRate;typedef struct
{rt_uint32_t mask;//帧标识符屏蔽位rt_bool_t ext_flag;//=0为标准帧屏蔽位,=1为扩展帧标识符屏蔽位
}Mask;typedef struct
{rt_uint32_t filter;rt_bool_t ext_flag;//=1仅用于扩展帧滤波 =0仅用于标准帧滤波
}Filter;typedef struct
{Mask mask_0;Mask mask_1;Filter filter_0;	Filter filter_1;	Filter filter_2;	Filter filter_3;	Filter filter_4;	Filter filter_5;	
}CanFilter;/*CAN报文结构体*/
typedef struct
{
//	rt_uint8_t node_num;	//节点号,用于多个sit2515的情况rt_uint32_t id;			//标识符rt_uint8_t dlc;			//数据长度0~8rt_uint8_t data[8];		//数据缓冲区rt_bool_t ext_flag;		//扩展帧标识 0标准帧 1扩展帧rt_bool_t rtr_flag;		//帧类型标识 0远程帧 1数据帧
}CanFrame;
/*波特率和报文滤波配置结构体*/
typedef struct
{
//	rt_uint8_t node_num;	//节点号rt_uint8_t baudrate;	//波特率CanFilter filter;		//滤波配置rt_bool_t br_flag;		//波特率配置是否有效标识rt_bool_t fi_flag;		//滤波是否有效标识
}CanDevConfig;
/*工作模式配置结构体*/
typedef struct
{
//	rt_uint8_t node_num;	//节点号rt_uint32_t oper_mode;	//节点工作模式
}CanDevMode;/*环形数据接收缓冲区结构体*/
typedef struct
{CanFrame can_recv_buf[RECV_BUF_SIZE];	//环形数据缓冲区rt_int16_t recv_pos;					//数据存入缓冲区位置rt_int16_t read_pos;					//数据读出缓冲区位置
//	rt_mutex_t rw;							//数据读写互斥			
//	struct rt_messagequeue wq;//等待队列,用于实现阻塞型读操作
}CanDev;/*中断结构体*/
typedef struct
{rt_bool_t tx;//发送中断rt_bool_t rx;//接收中断rt_bool_t err;//错误中断rt_bool_t wakie;//唤醒中断	
}IRQ;/** sit2515设备用户操作配置结构图 */
struct sit2515_config
{CanDevConfig 	config;CanDevMode		mode;CanDev 			Can_Dev;//环形数据缓冲区IRQ				irq; 	//中断控制
//    rt_uint16_t     flags;   //SPI操作标志
};#endif

更多推荐

MCP2515驱动 Rtthread GD32 CAN扩展

本文发布于:2024-03-08 12:48:47,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1720918.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:Rtthread

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!