SPI转can芯片CSM300详解以及Linux驱动移植调试笔记

更多嵌入式Linux干货,请关注 一口Linux

一、CSM300概述

CSM300(A)系列是一款可以支持 SPI / UART 接口的CAN模块。

1. 简介

CSM300(A)系列隔离 SPI / UART 转 CAN 模块是集成微处理器、 CAN 收发器、 DC-DC
隔离电源、 信号隔离于一体的通信模块, 该芯片可以很方便地嵌入到具有 SPI 或 UART 接口的设备中, 在不需改变原有硬件结构的前提下使设备获得 CAN 通讯接口, 实现 SPI 设备或 UART 设备和 CAN 总线网络之间的数据通讯。

外观

[图片上传失败...(image-1bd93a-1604035765456)]

2. 参数

  1. 实现 SPI 或 UART 与 CAN 接口的双向数据通信;
  2. CAN 总线符合“ISO 11898-2”标准;
  3. 集成 1 路 SPI 接口, 支持用户自定义的速率, 最高可达 1.5Mbit/s(非自定义协议转换) ,或 1Mbit/s(自定义协议转换) ;
  4. 集成 1 路 UART 接口, 支持多种速率, 最高可达 921600bps;
  5. 集成 1 路 CAN 通讯接口, 支持多种波特率, 最高可达 1Mbps;
  6. 隔离耐压 2500VDC;
  7. 工作温度: -40℃~+85℃;
  8. 电磁辐射 EME 较低;
  9. 电磁抗干扰 EMS 较高;

[图片上传失败...(image-efd89b-1604035765456)]

如上图所示 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 引脚连接。

[图片上传失败...(image-339aed-1604035765457)]
引脚说明:

[图片上传失败...(image-557db3-1604035765457)]
引脚功能说明如下:

  1. MODE脚直接接高电压(高电平对应SPI模式,低电平对应UART模式);
  2. 10、11、12外接CAN总线,主要用于CAN通信;
  3. 3、6、7、24、19引脚接MCU/MPU,配置CSM300A的模式和读写操作都要依靠这几个引脚;
  4. 18、21、22、23这4个引脚需要接到MCU/MPU的SPI控制器引脚,主要是CPU侧发送配置信息和读写数据的SPI通路;
  5. 20 是INT引脚,CSM300A收到数据后,满足一定条件就会下拉该引脚,产生中断信号,通知CPU读取数据。

二、工作模式

1. 工作模式分类

CSM300(A)上电后, MODE、 CFG 引脚电平会决定产品处于 4 种不同的工作模式的其中一种: SPI 转 CAN 模式、 UART 转 CAN 模式、 SPI 配置模式、 UART 配置模式。

[图片上传失败...(image-2907b4-1604035765457)]如上表所示:

  1. 如果我们要配置CSM300A,就是要设置CSM300A模式为SPI配置模式,那么就需要将MODE引脚置为1,CFG置为0,RST置为1;
  2. 如果我们要通过CSM300A读写数据,就是要设置CSM300A模式为SPI转CAN模式,那么就需要将MODE引脚置为1,CFG置为1,RST置为1;
  3. 读写数据的操作,都属于SPI转CAN模式,不需要切换模式。
  4. 若需要切换产品的工作模式,更改引脚电平后,必须对产品进行复位,才能使其进入设
    定的工作模式。需要注意的是,为保证成功复位, 复位保持时间最少为 100us,复位后,
    产品初始化等待时间最少 3ms,待产品初始化完成后,才能进行正常操作。

下图是不同模式切换的时序图。
[图片上传失败...(image-d1c731-1604035765457)]

2. SPI 转 CAN 模式(数据读写)

在此工作模式下, CSM300(A)始终作为 SPI 从机, SPI 限定工作在模式 3(CPOL、 CPHA
均为 1),数据长度限定为 8 位, MSB 高位先传输。透明转换、透明带标识转换下最高通信
速率为 1.5Mbps,自定义协议转换最高通信速率为 1Mbps。

SPI 主机可以发送数据至 CAN 总线端, 且可接收 CAN 总线端收到的数据。 此时 UART
接口无效,不会处理任何出现在 UART 接口的数据,也不会返回 CAN 总线端接收到的数据
至 UART。

  1. SPI 帧
    SPI 一次片选有效至片选无效之间的数据定义为一帧数据。 帧与帧之间读写缓冲区数据应有 40us 的时间间隔。

[图片上传失败...(image-9e66af-1604035765457)][图片上传失败...(image-1a91fc-1604035765457)]

3. SPI 配置模式

在此模式下, CSM300(A)处于等待配置状态, 无法向 CAN 端发送或接收数据。此模式下仅能通过 SPI 接口进行配置。

三、主机控制

CSM300(A)有两个 SPI 主机控制引脚 CTL0, CTL1, 受主机端控制。主机通过控制 CTL0,
CTL1 引脚, 使 CSM300(A)进入不同的功能状态,实现对 CSM300(A)不同操作目的。 主机端控制引脚电平不同对应功能如下表所示:

[图片上传失败...(image-e862a0-1604035765457)]
主机可以通过读从机当前状态来获取产品当前可以读取的字节数以及可以写入的字节
数。主机将功能选择为主机读状态,然后通过 SPI 读出 4 个字节,即为状态码。状态码由
32 个位构成,具体定义如下表所示。
[图片上传失败...(image-c8ed88-1604035765457)]
若定义 status[]数组为 8 位整型, 通过 SPI 读状态依次读出的数据为 status[0]、 status[1]、
status[2]、 status[3],则其数据结构如下图:

[图片上传失败...(image-4d8417-1604035765457)]

四、反馈机制(中断)

CSM300(A)只能作为 SPI 从机,不能主动地控制其他 SPI 总线设备,所以如果接收CAN数据帧之后,必须主动返回给CPU侧。

CSM300(A)硬件上的 INT 反馈引脚, 此引脚与主机连接,出现以下两种情况时, INT
引脚会由高电平变成低电平,通知主机进行读数据操作(为避免数据丢失,建议主机使用低
电平触发方式检测):

  1. CAN 缓冲区 CAN 帧数达到设置的触发点时
    当产品 CAN 总线端接收缓冲区接收到的 CAN 帧数达到触发点时, INT 引脚电平置低,
    直到缓冲区清空, INT 引脚才会恢复高电平。用户可以在获得 INT 信号之后查询 CSM300(A)
    的状态,获取可读字节数,然后读取缓冲区 CAN 数据。

  2. CAN 缓冲区数据少于触发帧数,且在设定时间内主机未读取时
    CAN 缓冲区有数据但少于触发帧数时,若总线长时间未有新增数据,且主机未进行读
    取操作时, CAN 接收缓冲区的数据将有可能长期得不到处理, 这就导致数据的实时性不高。
    为了解决少量数据的实时性问题, CSM300(A)内部设置了一个计时器,若 CAN 缓冲区的数
    据在一定时间内未被读取, 将触发 INT 引脚置低,通知主机读取数据。 CSM300(A)在接收
    到最后一帧数据时, 计时器启动,主机进行读取操作时复位计时器。

五、组网方式

CAN 总线一般使用直线型布线方式,总线节点数可达 110 个。 布线推荐使用屏蔽双绞线, CANH、 CANL 与双绞线线芯连接, CGND 与屏蔽层连接,最后屏蔽层单点接地。

得益于 CSM300(A)的最低波特率 5kbps,总线的最长通信距离可达 10km。
[图片上传失败...(image-fa34bd-1604035765457)]

六、移植

1. 硬件连接图

[图片上传失败...(image-9a970-1604035765457)]

如上图所示:

  1. SOC上已经集成了SPI控制器,厂家的sdk已经包含了spi控制器的设备树和驱动信息;
  2. SOC的SPI控制器引脚需要先连接level shift进行升压,板子电压是1.8V,而CSM300要求电压是3.3V;
  3. SOC的GPIO 76/107/113/114通过level shift分别连接CSM300A的RST/CFG/CTL1/CTL0;
  4. 在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
驱动位置如下:
[图片上传失败...(image-db5120-1604035765457)]
选中该驱动:

[图片上传失败...(image-573017-1604035765457)]重新编译内核即可。

注意:该驱动还需要依赖CAN和SPI,一定要选上 。

4. 增加调试接口

在调试过程中,会有各种原因导致csm300驱动无法注册成功,那如何判定是spi控制器驱动有问题,还是csm300驱动有问题呢?

为了方便通过spi控制器发送出波形,我们增加以下代码,用于在板子目录/sys/bus/spi/drivers/csm300中创建state文件节点,通过写入不同的值来产生spi数据,或者控制RST、 CFG、 CTL0、 CTL1这4个引脚。

  1. 增加函数csm300_spi_store()
    [图片上传失败...(image-ae7cb3-1604035765457)] 重点说明一下函数check_csm300()是驱动自带的用于测试CSM300的SPI通信功能的函数。

该函数会先将CSM300A设置为SPI配置模式,然后写入9个数据,然后再读取出数据,进行校验数据是否正确。

  1. 修改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;
    }
    ……
}
  1. 测试命令
    进入csm300模块目录
cd /sys/bus/spi/drivers/csm300
  1. 产生spi数据
echo 3 > state
  1. 拉高RST、 CFG、 CTL0、 CTL1
echo 1 > state
  1. 拉低RST、 CFG、 CTL0、 CTL1
echo 0 > state

5. 正确的开机log与波形

开机后驱动会调用check_csm300()来测试spi通道,发送的数据为F7:F8:02……
[图片上传失败...(image-a8ca95-1604035765457)]
以下为SPI接口的CLK和MOSI引脚的波形:
[图片上传失败...(image-5d07df-1604035765457)]可以看到数据与我们发送的是一致的。

6. 接收数据波形图

接收数据步骤如下:

  1. 运行于PC上的CAN Test 软件发送数据 00 01 02 03 04 05 06 07,
  2. 经过USB转CAN设备后,转换成了差分信号,
  3. 到达CSM300A之后,信号被调制成举行方波,
  4. CSM300A通过拉低引脚INT向cpu发送中断信号,调用CSM300A注册的中断函数,
  5. 运行于CPU上的CSM300A中断程序通过SPI接口读走CSM300A上的数据,
  6. CSM300A缓冲区数据被读走后,拉高INT,
  7. 驱动程序将接收到的数据上传给应用层,于是candump命令得到了CAN帧的数据。

[图片上传失败...(image-278ab2-1604035765457)]数据发送过程和上述过程类似。

7. CAN命令

如果文件系统中没有can命令,需要自行移植。

1) 设置波特率并开启can0口

ip link set can0 up type can bitrate 800000

2) 发送数据

cansend can0 1F334455#1122334455667788

3) 查看接收的数据

candump can0

七、出错记录

调试过程中遇到了很多的错误,CSM300A定位问题步骤:

  1. 首先用示波器测试CSM300的MOSI引脚的波形,是不是和第七章第5节的波形一致,如果不一致,说明SPI控制器驱动加载不正确;
  2. 要通过SPI控制器产生数据,使用命令echo 3 > state;
  3. 如果波形一致,就测量RST、 CFG、 CTL0、 CTL1这四个引脚,查看电平是否正确;
  4. RST、 CFG、 CTL0、 CTL1控制是否正确,可以用echo 0 > state、echo 1 > state分别拉低拉高,查看对这几个引脚的控制是否正常。

基本上照着这个思路去调试很快就能定位到问题。

以下是驱动加载出错的log,出错的原因主要是调用check_csm300()函数向CSM300A写入数据再读取出来后数据不匹配,从而判定加载出错。
[图片上传失败...(image-a09e16-1604035765457)]

1. CFG引脚拉低异常

现象:
check_csm300()函数始终报错。

分析:
check不成功,基本上原因是SPI控制器与CSM300通信出了问题。
首先用示波器,查看SPI发送的数据是否正常到达CSM300(用示波器抓取SSEL、CLK、MOSI),结果是正常的。

于是检测检测 RST、 CFG、 CTL0、 CTL1四个引脚。
如下图所示,使用echo 0 > state 拉低CFG引脚,发现没有拉到0V。
[图片上传失败...(image-d92c6c-1604035765457)]解决方案:

交给硬件工程师去改。这兄弟给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采样不到这个电平。

[图片上传失败...(image-148406-1604035765457)]

修改方法:
驱动中每次rst操作,都要增加延迟时间:

gpio_set_value(priv->RST,0);
usleep_range(2000,2300);
gpio_set_value(priv->RST,1);

修改后,执行echo 3 > state,RST波形如下所示。
[图片上传失败...(image-c20be-1604035765457)]

官方资料下载
https://www.zlg.cn/index.php/power/power/product/id/218.html

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,029评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,395评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,570评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,535评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,650评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,850评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,006评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,747评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,207评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,536评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,683评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,342评论 4 330
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,964评论 3 315
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,772评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,004评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,401评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,566评论 2 349