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扩展
发布评论