SPI转can芯片CSM300详解以及Linux驱动移植调试笔记
一、CSM300概述
CSM300(A)系列是一款可以支持 SPI / UART 接口的CAN模块。
1. 简介
CSM300(A)系列隔离 SPI / UART 转 CAN 模块是集成微处理器、 CAN 收发器、 DC-DC
隔离电源、 信号隔离于一体的通信模块, 该芯片可以很方便地嵌入到具有 SPI 或 UART 接口的设备中, 在不需改变原有硬件结构的前提下使设备获得 CAN 通讯接口, 实现 SPI 设备或 UART 设备和 CAN 总线网络之间的数据通讯。
外观
2. 参数
- 实现 SPI 或 UART 与 CAN 接口的双向数据通信;
- CAN 总线符合“ISO 11898-2”标准;
- 集成 1 路 SPI 接口, 支持用户自定义的速率, 最高可达 1.5Mbit/s(非自定义协议转换) ,或 1Mbit/s(自定义协议转换) ;
- 集成 1 路 UART 接口, 支持多种速率, 最高可达 921600bps;
- 集成 1 路 CAN 通讯接口, 支持多种波特率, 最高可达 1Mbps;
- 隔离耐压 2500VDC;
- 工作温度: -40℃~+85℃;
- 电磁辐射 EME 较低;
- 电磁抗干扰 EMS 较高;
如上图所示 CSM300是5V工作电压,CSM300A是3.3V工作电压。
如果MCU、MPU侧工作电压不是1.8V那么久需要增加一个level shift来进行电压转换。
此次调试的板子使用的是CSM300A,只使用其中的SPI接口。
3. 引脚定义及参考电路
使用SPI转CAN功能时, 需要将MODE引脚接至高电平。MCU的SPI接口与CSM300(A)的 SPI 接口连接,同时 MCU 需要提供 GPIO 与 RST、 INT、 CTL0、 CTL1 引脚连接,实现对 CSM300(A)的有效监测与控制。 若需要通过 MCU 对CSM300(A)进行配置,则需要额外的 GPIO 与 CFG 引脚连接。
引脚说明:
引脚功能说明如下:
- MODE脚直接接高电压(高电平对应SPI模式,低电平对应UART模式);
- 10、11、12外接CAN总线,主要用于CAN通信;
- 3、6、7、24、19引脚接MCU/MPU,配置CSM300A的模式和读写操作都要依靠这几个引脚;
- 18、21、22、23这4个引脚需要接到MCU/MPU的SPI控制器引脚,主要是CPU侧发送配置信息和读写数据的SPI通路;
- 20 是INT引脚,CSM300A收到数据后,满足一定条件就会下拉该引脚,产生中断信号,通知CPU读取数据。
二、工作模式
1. 工作模式分类
CSM300(A)上电后, MODE、 CFG 引脚电平会决定产品处于 4 种不同的工作模式的其中一种: SPI 转 CAN 模式、 UART 转 CAN 模式、 SPI 配置模式、 UART 配置模式。
如上表所示:
- 如果我们要配置CSM300A,就是要设置CSM300A模式为SPI配置模式,那么就需要将MODE引脚置为1,CFG置为0,RST置为1;
- 如果我们要通过CSM300A读写数据,就是要设置CSM300A模式为SPI转CAN模式,那么就需要将MODE引脚置为1,CFG置为1,RST置为1;
- 读写数据的操作,都属于SPI转CAN模式,不需要切换模式。
- 若需要切换产品的工作模式,更改引脚电平后,必须对产品进行复位,才能使其进入设
定的工作模式。需要注意的是,为保证成功复位, 复位保持时间最少为 100us,复位后,
产品初始化等待时间最少 3ms,待产品初始化完成后,才能进行正常操作。
下图是不同模式切换的时序图。
2. SPI 转 CAN 模式(数据读写)
在此工作模式下, CSM300(A)始终作为 SPI 从机, SPI 限定工作在模式 3(CPOL、 CPHA
均为 1),数据长度限定为 8 位, MSB 高位先传输。透明转换、透明带标识转换下最高通信
速率为 1.5Mbps,自定义协议转换最高通信速率为 1Mbps。
SPI 主机可以发送数据至 CAN 总线端, 且可接收 CAN 总线端收到的数据。 此时 UART
接口无效,不会处理任何出现在 UART 接口的数据,也不会返回 CAN 总线端接收到的数据
至 UART。
- SPI 帧
SPI 一次片选有效至片选无效之间的数据定义为一帧数据。 帧与帧之间读写缓冲区数据应有 40us 的时间间隔。
3. SPI 配置模式
在此模式下, CSM300(A)处于等待配置状态, 无法向 CAN 端发送或接收数据。此模式下仅能通过 SPI 接口进行配置。
三、主机控制
CSM300(A)有两个 SPI 主机控制引脚 CTL0, CTL1, 受主机端控制。主机通过控制 CTL0,
CTL1 引脚, 使 CSM300(A)进入不同的功能状态,实现对 CSM300(A)不同操作目的。 主机端控制引脚电平不同对应功能如下表所示:
主机可以通过读从机当前状态来获取产品当前可以读取的字节数以及可以写入的字节
数。主机将功能选择为主机读状态,然后通过 SPI 读出 4 个字节,即为状态码。状态码由
32 个位构成,具体定义如下表所示。
若定义 status[]数组为 8 位整型, 通过 SPI 读状态依次读出的数据为 status[0]、 status[1]、
status[2]、 status[3],则其数据结构如下图:
四、反馈机制(中断)
CSM300(A)只能作为 SPI 从机,不能主动地控制其他 SPI 总线设备,所以如果接收CAN数据帧之后,必须主动返回给CPU侧。
CSM300(A)硬件上的 INT 反馈引脚, 此引脚与主机连接,出现以下两种情况时, INT
引脚会由高电平变成低电平,通知主机进行读数据操作(为避免数据丢失,建议主机使用低
电平触发方式检测):
CAN 缓冲区 CAN 帧数达到设置的触发点时
当产品 CAN 总线端接收缓冲区接收到的 CAN 帧数达到触发点时, INT 引脚电平置低,
直到缓冲区清空, INT 引脚才会恢复高电平。用户可以在获得 INT 信号之后查询 CSM300(A)
的状态,获取可读字节数,然后读取缓冲区 CAN 数据。CAN 缓冲区数据少于触发帧数,且在设定时间内主机未读取时
CAN 缓冲区有数据但少于触发帧数时,若总线长时间未有新增数据,且主机未进行读
取操作时, CAN 接收缓冲区的数据将有可能长期得不到处理, 这就导致数据的实时性不高。
为了解决少量数据的实时性问题, CSM300(A)内部设置了一个计时器,若 CAN 缓冲区的数
据在一定时间内未被读取, 将触发 INT 引脚置低,通知主机读取数据。 CSM300(A)在接收
到最后一帧数据时, 计时器启动,主机进行读取操作时复位计时器。
五、组网方式
CAN 总线一般使用直线型布线方式,总线节点数可达 110 个。 布线推荐使用屏蔽双绞线, CANH、 CANL 与双绞线线芯连接, CGND 与屏蔽层连接,最后屏蔽层单点接地。
得益于 CSM300(A)的最低波特率 5kbps,总线的最长通信距离可达 10km。
六、移植
1. 硬件连接图
如上图所示:
- SOC上已经集成了SPI控制器,厂家的sdk已经包含了spi控制器的设备树和驱动信息;
- SOC的SPI控制器引脚需要先连接level shift进行升压,板子电压是1.8V,而CSM300要求电压是3.3V;
- SOC的GPIO 76/107/113/114通过level shift分别连接CSM300A的RST/CFG/CTL1/CTL0;
- 在PC上运行CAN-Test软件,可以通过USB转CAN设备从CAN总线上读取和发送数据。
【注】USB转CAN设备,可以自行搜索,杜绝广告。
2. 设备树
以下是官方提供的设备树:
csm300@0 {
pinctrl-names = "default";
pinctrl-0 =<&pinctrl_csm300>;
gpios=<&gpio3 21 0 /*ctl0*/
&gpio3 22 0 /*ctl1*/
&gpio3 30 0 /*rst*/
&gpio3 31 0 /*cfg*/
>;
interrupt-parent = <&gpio3>;
interrupts = <26 IRQ_LEVEL_LOW>;
compatible = "zhiyuan,csm300";
spi-max-frequency = <500000>;
reg = <1>;
status = "okay";
};
以下是根据自己的平台修改的结果,读者移植的时候需要根据自己的平台来移植,不可教条。
csm300@0 {
pinctrl-names = "default";
gpios=<&gpio 114 0 /*ctl0*/
&gpio 113 0 /*ctl1*/
&gpio 76 0 /*rst*/
&gpio 107 0 /*cfg*/
>;
interrupt-parent = <&gpio>;
interrupts = <196 IRQ_LEVEL_LOW>;
compatible = "zhiyuan,csm300";
spi-max-frequency = <500000>;
reg = <0>;
status = "okay";
};
3. 驱动
官方会提供驱动程序csm300.c,具体实际原理,本篇暂不讨论。
拷贝到以下目录:
drivers/net/can/spi
修改本级目录下的Makefile
obj-$(CONFIG_CAN_CSM300) += csm300.o
修改本级目录下的Kconfig
config CAN_CSM300
tristate "Microchip CSM300 driver"
depends on SPI
---help---
Driver for the Microchip CSM300 .
执行make menuconfig
驱动位置如下:
选中该驱动:
重新编译内核即可。
注意:该驱动还需要依赖CAN和SPI,一定要选上 。
4. 增加调试接口
在调试过程中,会有各种原因导致csm300驱动无法注册成功,那如何判定是spi控制器驱动有问题,还是csm300驱动有问题呢?
为了方便通过spi控制器发送出波形,我们增加以下代码,用于在板子目录/sys/bus/spi/drivers/csm300中创建state文件节点,通过写入不同的值来产生spi数据,或者控制RST、 CFG、 CTL0、 CTL1这4个引脚。
- 增加函数csm300_spi_store()
重点说明一下函数check_csm300()是驱动自带的用于测试CSM300的SPI通信功能的函数。
该函数会先将CSM300A设置为SPI配置模式,然后写入9个数据,然后再读取出数据,进行校验数据是否正确。
- 修改probe函数
struct net_device *global_net = NULL ;
csm_probe()
{
……
global_net = net;
ret = check_csm300(net);
……
ret = driver_create_file(&(csm300_can_driver.driver),&driver_attr_state);
if(ret < 0){
ret = -ENOENT;
goto out_free;
}
……
}
- 测试命令
进入csm300模块目录
cd /sys/bus/spi/drivers/csm300
- 产生spi数据
echo 3 > state
- 拉高RST、 CFG、 CTL0、 CTL1
echo 1 > state
- 拉低RST、 CFG、 CTL0、 CTL1
echo 0 > state
5. 正确的开机log与波形
开机后驱动会调用check_csm300()来测试spi通道,发送的数据为F7:F8:02……
以下为SPI接口的CLK和MOSI引脚的波形:
可以看到数据与我们发送的是一致的。
6. 接收数据波形图
接收数据步骤如下:
- 运行于PC上的CAN Test 软件发送数据 00 01 02 03 04 05 06 07,
- 经过USB转CAN设备后,转换成了差分信号,
- 到达CSM300A之后,信号被调制成举行方波,
- CSM300A通过拉低引脚INT向cpu发送中断信号,调用CSM300A注册的中断函数,
- 运行于CPU上的CSM300A中断程序通过SPI接口读走CSM300A上的数据,
- CSM300A缓冲区数据被读走后,拉高INT,
- 驱动程序将接收到的数据上传给应用层,于是candump命令得到了CAN帧的数据。
数据发送过程和上述过程类似。
7. CAN命令
如果文件系统中没有can命令,需要自行移植。
1) 设置波特率并开启can0口
ip link set can0 up type can bitrate 800000
2) 发送数据
cansend can0 1F334455#1122334455667788
3) 查看接收的数据
candump can0
七、出错记录
调试过程中遇到了很多的错误,CSM300A定位问题步骤:
- 首先用示波器测试CSM300的MOSI引脚的波形,是不是和第七章第5节的波形一致,如果不一致,说明SPI控制器驱动加载不正确;
- 要通过SPI控制器产生数据,使用命令echo 3 > state;
- 如果波形一致,就测量RST、 CFG、 CTL0、 CTL1这四个引脚,查看电平是否正确;
- RST、 CFG、 CTL0、 CTL1控制是否正确,可以用echo 0 > state、echo 1 > state分别拉低拉高,查看对这几个引脚的控制是否正常。
基本上照着这个思路去调试很快就能定位到问题。
以下是驱动加载出错的log,出错的原因主要是调用check_csm300()函数向CSM300A写入数据再读取出来后数据不匹配,从而判定加载出错。
1. CFG引脚拉低异常
现象:
check_csm300()函数始终报错。
分析:
check不成功,基本上原因是SPI控制器与CSM300通信出了问题。
首先用示波器,查看SPI发送的数据是否正常到达CSM300(用示波器抓取SSEL、CLK、MOSI),结果是正常的。
于是检测检测 RST、 CFG、 CTL0、 CTL1四个引脚。
如下图所示,使用echo 0 > state 拉低CFG引脚,发现没有拉到0V。
解决方案:
交给硬件工程师去改。这兄弟给CFG加了一个反向电阻,驱动部分需要将所有设置CFG的代码,全部反置。
gpio_set_value(priv->CFG,0);
修改成
gpio_set_value(priv->RST,1);
gpio_set_value(priv->CFG,1);
修改成
gpio_set_value(priv->RST,0);
2. RST 延时不够
现象:
echo 0 > state 可以拉低,测量也是正确的,但是CSM300始终无法接收到数据帧。
分析:
一般数据接收不到,有两种可能:就是CSM300给出的中断信号CPU没有截取到,CSM300没有处于SPI转CAN模式。
先用示波器确定了,USB转CAN的数据已经成功到达CSM300,于是检测对应的引脚电平 RST、 CFG、 CTL0、 CTL1,发现也是对的。
检查中断计数,用cat /proc/interrupts查看CSM300是否有中断计数,结果发现数据为0。
怀疑CSM300没有rst成功,于是执行echo 3 > state,查看rst是否正确设置,结果发现以下波形,确定了该引脚拉高比较缓慢,所以CSM300采样不到这个电平。
修改方法:
驱动中每次rst操作,都要增加延迟时间:
gpio_set_value(priv->RST,0);
usleep_range(2000,2300);
gpio_set_value(priv->RST,1);
修改后,执行echo 3 > state,RST波形如下所示。
官方资料下载
https://www.zlg.cn/index.php/power/power/product/id/218.html
更多嵌入式 Linux知识 请关注 一口Linux
SPI转can芯片CSM300详解以及Linux驱动移植调试笔记的更多相关文章
- SSL握手通信详解及linux下c/c++ SSL Socket代码举例
SSL握手通信详解及linux下c/c++ SSL Socket代码举例 摘自:http://www.169it.com/article/3215130236.html 分享到:8 发布时 ...
- SSL握手通信详解及linux下c/c++ SSL Socket代码举例(另附SSL双向认证客户端代码)
SSL握手通信详解及linux下c/c++ SSL Socket代码举例(另附SSL双向认证客户端代码) 摘自: https://blog.csdn.net/sjin_1314/article/det ...
- 详解在Linux系统中安装Tomcat
本文以在CentOS 7.6中安装Tomcat8.5为例进行安装,其他系统和版本都是大同小异的. 安装JDK 安装Tomcat之前,需要先安装JDK,可以参看之前的文章详解在Linux系统中安装JDK ...
- Linux /dev目录详解和Linux系统各个目录的作用
Linux /dev目录详解(转http://blog.csdn.net/maopig/article/details/7195048) 在linux下,/dev目录是很重要的,各种设备都在下面.下面 ...
- 『TCP/IP详解——卷一:协议』读书笔记——10
2013-08-22 22:57:17 3.8 ifconfig命令 这个命令在Linux系统下可以通过下面的指令阅读说明文档: ifconfig 由于书中作者用的系统比较早的某Unix系统,所以我的 ...
- 『TCP/IP详解——卷一:协议』读书笔记——01
从今日起开始认真研读TCP/IP详解这本经典制作,一是巩固我薄弱的计算机网络知识,二来提高我的假期的时间利用率.将心得与思考记录下来,防止白看-哦耶 2013-08-14 18:47:06 第一章 概 ...
- .Neter玩转Linux系列之五:crontab使用详解和Linux的进程管理以及网络状态监控
一.crontab使用详解 概述:任务调度:是指系统在某个时间执行的特定的命令或程序. 任务调度分类: (1)系统工作:有些重要的工作必须周而 复始地执行. (2)个别用户工作:个别用户可能希望执 行 ...
- Linux进程退出详解(do_exit)--Linux进程的管理与调度(十四)
Linux进程的退出 linux下进程退出的方式 正常退出 从main函数返回return 调用exit 调用_exit 异常退出 调用abort 由信号终止 _exit, exit和_Exit的区别 ...
- 详解基于linux环境MySQL搭建与卸载
本篇文章将从实际操作的层面,讲解基于linux环境的mysql的搭建和卸载. 1 搭建mysql 1.1 官网下载mysql压缩包 下载压缩包时,可以先把安装包下载到本地,再上传到服务器,也可以在 ...
- 详解在Linux中安装配置MySQL
最近在整理自己私人服务器上的各种阿猫阿狗,正好就顺手详细记录一下清理之后重装的步骤,今天先写点数据库的内容,关于在Linux中安装配置MySQL 安装环境 CentOS7 + MySQL5.7 下载安 ...
随机推荐
- shell脚本获取函数返回值
方式1 原理:return返回的值可以通过$?得到. 缺点:return只能返回整数 #!/bin/sh function test() { return 100 } test echo $? 方式2 ...
- LLM并行训练4-megascale论文学习
算法优化 并行注意力机制 \[串行版本: y = x + MLP(LayerNorm(x + Attention(LayerNorm(x)))) \] \[并行版本: y = x + MLP(Laye ...
- JavaSE进阶核心之class类
Java顶级对象之Object 什么是Object类 Object类位于java.lang包中,java.lang包包含着Java最基础和核心的类,在编译时会自动导入 Object类是所有java类的 ...
- Python代码学习
1.生成四位数字字母验证码,大小写字母随机 import random if __name__ =="__main__": #四位数字字母验证码的生成 checkcode=&quo ...
- Vue 3 后端错误消息处理范例
1. 错误消息格式 前后端消息传递时,我们可以通过 json 的 errors 字段传递错误信息,一个比较好的格式范例为: { errors: { global: ["网络错误"] ...
- 怒肝半月!Python 学习路线+资源大汇总
Python 学习路线 by 鱼皮. 原创不易,请勿抄袭,违者必究! 大家好,我是鱼皮,肝了十天左右的 Python 学习路线终于来了~ 和之前一样,在看路线前,建议大家先通过以下视频了解几个问题: ...
- iOS开发基础133-崩溃预防
现代移动应用的用户体验依赖于其稳定性和可靠性.然而,在开发过程中,我们时常会遇到各种崩溃问题.崩溃不仅会影响用户的使用体验,还可能损害应用的声誉.因此,本文将详细介绍一个名为CrashPreventi ...
- vue项目中实现sql编辑器功能自定义高亮词汇可提示关键词-codemirror
先上图:左侧是数据库表,右侧上部是sql编辑器,下部是执行sql的返回接口 HTML: <el-row> <el-col :span="4" class=&quo ...
- 第十二节 JMeter基础-中级地址信息【IF控制器】
声明:本文所记录的仅本次操作学习到的知识点,其中商城IP错误,请自行更改. 背景:提交订单前,我们需要核对一些信息,比如商品信息,收货地址,支付方式等.现在核对一下收货地址信息. 思路: 1.前提条件 ...
- selenium启动Chrome配置参数问题
每次当selenium启动chrome浏览器的时候,chrome浏览器很干净,没有插件.没有收藏.没有历史记录,这是因为selenium在启动chrome时为了保证最快的运行效率,启动了一个裸浏览器, ...