SPI轉(zhuǎn)can芯片CSM300詳解、Linux驅(qū)動(dòng)移植調(diào)試筆記
一口君最近移植了一款SPI轉(zhuǎn)CAN的芯片CSM300A,在這里和大家做個(gè)分享。
一、CSM300概述
CSM300(A)系列是一款可以支持 SPI / UART 接口的CAN模塊。
1. 簡(jiǎn)介
CSM300(A)系列隔離 SPI / UART 轉(zhuǎn) CAN 模塊是集成微處理器、 CAN 收發(fā)器、 DC-DC 隔離電源、 信號(hào)隔離于一體的通信模塊, 該芯片可以很方便地嵌入到具有 SPI 或 UART 接口的設(shè)備中, 在不需改變?cè)杏布Y(jié)構(gòu)的前提下使設(shè)備獲得 CAN 通訊接口, 實(shí)現(xiàn) SPI 設(shè)備或 UART 設(shè)備和 CAN 總線網(wǎng)絡(luò)之間的數(shù)據(jù)通訊。
外觀
CSM3002. 參數(shù)
- 實(shí)現(xiàn) SPI 或 UART 與 CAN 接口的雙向數(shù)據(jù)通信;
- CAN 總線符合“ISO 11898-2”標(biāo)準(zhǔn);
- 集成 1 路 SPI 接口, 支持用戶自定義的速率, 最高可達(dá) 1.5Mbit/s(非自定義協(xié)議轉(zhuǎn)換) ,或 1Mbit/s(自定義協(xié)議轉(zhuǎn)換) ;
- 集成 1 路 UART 接口, 支持多種速率, 最高可達(dá) 921600bps;
- 集成 1 路 CAN 通訊接口, 支持多種波特率, 最高可達(dá) 1Mbps;
- 隔離耐壓 2500VDC;
- 工作溫度:-40℃~+85℃;
- 電磁輻射 EME 較低;
- 電磁抗干擾 EMS 較高;
如上圖所示 CSM300是5V工作電壓,CSM300A是3.3V工作電壓。
如果MCU、MPU側(cè)工作電壓不是1.8V那么就需要增加一個(gè)level shift來(lái)進(jìn)行電壓轉(zhuǎn)換。
此次調(diào)試的板子使用的是CSM300A,只使用其中的SPI接口。
可以在如下搜索框中搜索需要的內(nèi)容:
3. 引腳定義及參考電路
使用SPI轉(zhuǎn)CAN功能時(shí), 需要將MODE引腳接至高電平。MCU的SPI接口與CSM300(A)的 SPI 接口連接,同時(shí) MCU 需要提供 GPIO 與 RST、 INT、 CTL0、 CTL1 引腳連接,實(shí)現(xiàn)對(duì) CSM300(A)的有效監(jiān)測(cè)與控制。若需要通過(guò) MCU 對(duì)CSM300(A)進(jìn)行配置,則需要額外的 GPIO 與 CFG 引腳連接。
SPI 轉(zhuǎn) CAN 參考電路(CSM300A)引腳說(shuō)明:
引腳說(shuō)明引腳功能說(shuō)明如下:
- MODE腳直接接高電壓(高電平對(duì)應(yīng)SPI模式,低電平對(duì)應(yīng)UART模式);
- 10、11、12外接CAN總線,主要用于CAN通信;
- 3、6、7、24、19引腳接MCU/MPU,配置CSM300A的模式和讀寫操作都要依靠這幾個(gè)引腳;
- 18、21、22、23這4個(gè)引腳需要接到MCU/MPU的SPI控制器引腳,主要是CPU側(cè)發(fā)送配置信息和讀寫數(shù)據(jù)的SPI通路;
- 20 是INT引腳,CSM300A收到數(shù)據(jù)后,滿足一定條件就會(huì)下拉該引腳,產(chǎn)生中斷信號(hào),通知CPU讀取數(shù)據(jù)。
二、工作模式
1. 工作模式分類
CSM300(A)上電后, MODE、 CFG 引腳電平會(huì)決定產(chǎn)品處于 4 種不同的工作模式的其中一種:SPI 轉(zhuǎn) CAN 模式、 UART 轉(zhuǎn) CAN 模式、 SPI 配置模式、 UART 配置模式。
CSM300(A)工作模式如上表所示:
- 如果我們要配置CSM300A,就是要設(shè)置CSM300A模式為SPI配置模式,那么就需要將MODE引腳置為1,CFG置為0,RST置為1;
- 如果我們要通過(guò)CSM300A讀寫數(shù)據(jù),就是要設(shè)置CSM300A模式為SPI轉(zhuǎn)CAN模式,那么就需要將MODE引腳置為1,CFG置為1,RST置為1;
- 讀寫數(shù)據(jù)的操作,都屬于SPI轉(zhuǎn)CAN模式,不需要切換模式。
- 若需要切換產(chǎn)品的工作模式,更改引腳電平后,必須對(duì)產(chǎn)品進(jìn)行復(fù)位,才能使其進(jìn)入設(shè) 定的工作模式。需要注意的是,為保證成功復(fù)位, 復(fù)位保持時(shí)間最少為 100us,復(fù)位后, 產(chǎn)品初始化等待時(shí)間最少 3ms,待產(chǎn)品初始化完成后,才能進(jìn)行正常操作。
下圖是不同模式切換的時(shí)序圖。
工作模式切換時(shí)序2. SPI 轉(zhuǎn) CAN 模式(數(shù)據(jù)讀寫)
在此工作模式下, CSM300(A)始終作為 SPI 從機(jī), SPI 限定工作在模式 3(CPOL、 CPHA 均為 1),數(shù)據(jù)長(zhǎng)度限定為 8 位, MSB 高位先傳輸。透明轉(zhuǎn)換、透明帶標(biāo)識(shí)轉(zhuǎn)換下最高通信 速率為 1.5Mbps,自定義協(xié)議轉(zhuǎn)換最高通信速率為 1Mbps。
SPI 主機(jī)可以發(fā)送數(shù)據(jù)至 CAN 總線端, 且可接收 CAN 總線端收到的數(shù)據(jù)。此時(shí) UART 接口無(wú)效,不會(huì)處理任何出現(xiàn)在 UART 接口的數(shù)據(jù),也不會(huì)返回 CAN 總線端接收到的數(shù)據(jù) 至 UART。
- SPI 幀 SPI 一次片選有效至片選無(wú)效之間的數(shù)據(jù)定義為一幀數(shù)據(jù)。幀與幀之間讀寫緩沖區(qū)數(shù)據(jù)應(yīng)有 40us 的時(shí)間間隔。
3. SPI 配置模式
在此模式下, CSM300(A)處于等待配置狀態(tài), 無(wú)法向 CAN 端發(fā)送或接收數(shù)據(jù)。此模式下僅能通過(guò) SPI 接口進(jìn)行配置。
三、主機(jī)控制
CSM300(A)有兩個(gè) SPI 主機(jī)控制引腳 CTL0, CTL1, 受主機(jī)端控制。主機(jī)通過(guò)控制 CTL0, CTL1 引腳, 使 CSM300(A)進(jìn)入不同的功能狀態(tài),實(shí)現(xiàn)對(duì) CSM300(A)不同操作目的。主機(jī)端控制引腳電平不同對(duì)應(yīng)功能如下表所示:
SPI 模式下主機(jī)控制功能主機(jī)可以通過(guò)讀從機(jī)當(dāng)前狀態(tài)來(lái)獲取產(chǎn)品當(dāng)前可以讀取的字節(jié)數(shù)以及可以寫入的字節(jié) 數(shù)。主機(jī)將功能選擇為主機(jī)讀狀態(tài),然后通過(guò) SPI 讀出 4 個(gè)字節(jié),即為狀態(tài)碼。狀態(tài)碼由 32 個(gè)位構(gòu)成,具體定義如下表所示。
狀態(tài)碼若定義 status[]數(shù)組為 8 位整型, 通過(guò) SPI 讀狀態(tài)依次讀出的數(shù)據(jù)為 status[0]、 status[1]、 status[2]、 status[3],則其數(shù)據(jù)結(jié)構(gòu)如下圖:
狀態(tài)字節(jié)數(shù)據(jù)結(jié)構(gòu)四、反饋機(jī)制(中斷)
CSM300(A)只能作為 SPI 從機(jī),不能主動(dòng)地控制其他 SPI 總線設(shè)備,所以如果接收CAN數(shù)據(jù)幀之后,必須主動(dòng)返回給CPU側(cè)。
CSM300(A)硬件上的 INT 反饋引腳, 此引腳與主機(jī)連接,出現(xiàn)以下兩種情況時(shí), INT 引腳會(huì)由高電平變成低電平,通知主機(jī)進(jìn)行讀數(shù)據(jù)操作(為避免數(shù)據(jù)丟失,建議主機(jī)使用低 電平觸發(fā)方式檢測(cè)):
-
CAN 緩沖區(qū) CAN 幀數(shù)達(dá)到設(shè)置的觸發(fā)點(diǎn)時(shí) 當(dāng)產(chǎn)品 CAN 總線端接收緩沖區(qū)接收到的 CAN 幀數(shù)達(dá)到觸發(fā)點(diǎn)時(shí), INT 引腳電平置低, 直到緩沖區(qū)清空, INT 引腳才會(huì)恢復(fù)高電平。用戶可以在獲得 INT 信號(hào)之后查詢 CSM300(A) 的狀態(tài),獲取可讀字節(jié)數(shù),然后讀取緩沖區(qū) CAN 數(shù)據(jù)。
-
CAN 緩沖區(qū)數(shù)據(jù)少于觸發(fā)幀數(shù),且在設(shè)定時(shí)間內(nèi)主機(jī)未讀取時(shí) CAN 緩沖區(qū)有數(shù)據(jù)但少于觸發(fā)幀數(shù)時(shí),若總線長(zhǎng)時(shí)間未有新增數(shù)據(jù),且主機(jī)未進(jìn)行讀 取操作時(shí), CAN 接收緩沖區(qū)的數(shù)據(jù)將有可能長(zhǎng)期得不到處理, 這就導(dǎo)致數(shù)據(jù)的實(shí)時(shí)性不高。為了解決少量數(shù)據(jù)的實(shí)時(shí)性問(wèn)題, CSM300(A)內(nèi)部設(shè)置了一個(gè)計(jì)時(shí)器,若 CAN 緩沖區(qū)的數(shù) 據(jù)在一定時(shí)間內(nèi)未被讀取, 將觸發(fā) INT 引腳置低,通知主機(jī)讀取數(shù)據(jù)。CSM300(A)在接收 到最后一幀數(shù)據(jù)時(shí), 計(jì)時(shí)器啟動(dòng),主機(jī)進(jìn)行讀取操作時(shí)復(fù)位計(jì)時(shí)器。
五、組網(wǎng)方式
CAN 總線一般使用直線型布線方式,總線節(jié)點(diǎn)數(shù)可達(dá) 110 個(gè)。布線推薦使用屏蔽雙絞線, CANH、 CANL 與雙絞線線芯連接, CGND 與屏蔽層連接,最后屏蔽層單點(diǎn)接地。
得益于 CSM300(A)的最低波特率 5kbps,總線的最長(zhǎng)通信距離可達(dá) 10km。
推薦組網(wǎng)示意圖六、移植
1. 硬件連接圖
硬件連接圖如上圖所示:
- SOC上已經(jīng)集成了SPI控制器,廠家的sdk已經(jīng)包含了spi控制器的設(shè)備樹(shù)和驅(qū)動(dòng)信息;
- SOC的SPI控制器引腳需要先連接level shift進(jìn)行升壓,板子電壓是1.8V,而CSM300要求電壓是3.3V;
- SOC的GPIO 76/107/113/114通過(guò)level shift分別連接CSM300A的RST/CFG/CTL1/CTL0;
- 在PC上運(yùn)行CAN-Test軟件,可以通過(guò)USB轉(zhuǎn)CAN設(shè)備從CAN總線上讀取和發(fā)送數(shù)據(jù)。
【注】USB轉(zhuǎn)CAN設(shè)備,可以自行搜索,杜絕廣告。
2. 設(shè)備樹(shù)
以下是官方提供的設(shè)備樹(shù):
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";
};
以下是根據(jù)自己的平臺(tái)修改的結(jié)果,讀者移植的時(shí)候需要根據(jù)自己的平臺(tái)來(lái)移植,不可教條。
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. 驅(qū)動(dòng)
官方會(huì)提供驅(qū)動(dòng)程序csm300.c,具體實(shí)際原理,本篇暫不討論。
拷貝到以下目錄:
drivers/net/can/spi
修改本級(jí)目錄下的Makefile
obj-$(CONFIG_CAN_CSM300) += csm300.o
修改本級(jí)目錄下的Kconfig
config CAN_CSM300
tristate "Microchip CSM300 driver" depends on SPI
---help---
Driver for the Microchip CSM300 .
執(zhí)行make menuconfig 驅(qū)動(dòng)位置如下:
選中該驅(qū)動(dòng):
menuconfig重新編譯內(nèi)核即可。
注意:該驅(qū)動(dòng)還需要依賴CAN和SPI,一定要選上 。
4. 增加調(diào)試接口
在調(diào)試過(guò)程中,會(huì)有各種原因?qū)е耤sm300驅(qū)動(dòng)無(wú)法注冊(cè)成功,那如何判定是spi控制器驅(qū)動(dòng)有問(wèn)題,還是csm300驅(qū)動(dòng)有問(wèn)題呢?
為了方便通過(guò)spi控制器發(fā)送出波形,我們?cè)黾右韵麓a,用于在板子目錄/sys/bus/spi/drivers/csm300中創(chuàng)建state文件節(jié)點(diǎn),通過(guò)寫入不同的值來(lái)產(chǎn)生spi數(shù)據(jù),或者控制RST、 CFG、 CTL0、 CTL1這4個(gè)引腳。
- 增加函數(shù)csm300_spi_store()
重點(diǎn)說(shuō)明一下函數(shù)**check_csm300()**是驅(qū)動(dòng)自帶的用于測(cè)試CSM300的SPI通信功能的函數(shù)。
該函數(shù)會(huì)先將CSM300A設(shè)置為SPI配置模式,然后寫入9個(gè)數(shù)據(jù),然后再讀取出數(shù)據(jù),進(jìn)行校驗(yàn)數(shù)據(jù)是否正確。
- 修改probe函數(shù)
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;
}
……
}
- 測(cè)試命令 進(jìn)入csm300模塊目錄
cd /sys/bus/spi/drivers/csm300
- 產(chǎn)生spi數(shù)據(jù)
echo 3 > state
- 拉高RST、 CFG、 CTL0、 CTL1
echo 1 > state
- 拉低RST、 CFG、 CTL0、 CTL1
echo 0 > state
5. 正確的開(kāi)機(jī)log與波形
開(kāi)機(jī)后驅(qū)動(dòng)會(huì)調(diào)用check_csm300()來(lái)測(cè)試spi通道,發(fā)送的數(shù)據(jù)為F7:F8:02……
正確的開(kāi)機(jī)log以下為SPI接口的CLK和MOSI引腳的波形:
開(kāi)機(jī)SPI的波形可以看到數(shù)據(jù)與我們發(fā)送的是一致的。
6. 接收數(shù)據(jù)波形圖
接收數(shù)據(jù)步驟如下:
- 運(yùn)行于PC上的CAN Test 軟件發(fā)送數(shù)據(jù) 00 01 02 03 04 05 06 07,
- 經(jīng)過(guò)USB轉(zhuǎn)CAN設(shè)備后,轉(zhuǎn)換成了差分信號(hào),
- 到達(dá)CSM300A之后,信號(hào)被調(diào)制成矩形方波,
- CSM300A通過(guò)拉低引腳INT向cpu發(fā)送中斷信號(hào),調(diào)用CSM300A注冊(cè)的中斷函數(shù),
- 運(yùn)行于CPU上的CSM300A中斷程序通過(guò)SPI接口讀走CSM300A上的數(shù)據(jù),
- CSM300A緩沖區(qū)數(shù)據(jù)被讀走后,拉高INT,
- 驅(qū)動(dòng)程序?qū)⒔邮盏降臄?shù)據(jù)上傳給應(yīng)用層,于是candump命令得到了CAN幀的數(shù)據(jù)。
數(shù)據(jù)發(fā)送過(guò)程和上述過(guò)程類似。
7. CAN命令
如果文件系統(tǒng)中沒(méi)有can命令,需要自行移植。
1) 設(shè)置波特率并開(kāi)啟can0口
ip link set can0 up type can bitrate 800000
2) 發(fā)送數(shù)據(jù)
cansend can0 1F334455#1122334455667788
3) 查看接收的數(shù)據(jù)
candump can0
七、出錯(cuò)記錄
調(diào)試過(guò)程中遇到了很多的錯(cuò)誤,CSM300A定位問(wèn)題步驟:
- 首先用示波器測(cè)試CSM300的MOSI引腳的波形,是不是和第七章第5節(jié)的波形一致,如果不一致,說(shuō)明SPI控制器驅(qū)動(dòng)加載不正確;
- 要通過(guò)SPI控制器產(chǎn)生數(shù)據(jù),使用命令echo 3 > state;
- 如果波形一致,就測(cè)量RST、 CFG、 CTL0、 CTL1這四個(gè)引腳,查看電平是否正確;
- RST、 CFG、 CTL0、 CTL1控制是否正確,可以用echo 0 > state、echo 1 > state分別拉低拉高,查看對(duì)這幾個(gè)引腳的控制是否正常。
基本上照著這個(gè)思路去調(diào)試很快就能定位到問(wèn)題。
以下是驅(qū)動(dòng)加載出錯(cuò)的log,出錯(cuò)的原因主要是調(diào)用check_csm300()函數(shù)向CSM300A寫入數(shù)據(jù)再讀取出來(lái)后數(shù)據(jù)不匹配,從而判定加載出錯(cuò)。
出錯(cuò)log1. CFG引腳拉低異常
現(xiàn)象:check_csm300()函數(shù)始終報(bào)錯(cuò)。
分析:check不成功,基本上原因是SPI控制器與CSM300通信出了問(wèn)題。首先用示波器,查看SPI發(fā)送的數(shù)據(jù)是否正常到達(dá)CSM300(用示波器抓取SSEL、CLK、MOSI),結(jié)果是正常的。
于是檢測(cè)檢測(cè) RST、 CFG、 CTL0、 CTL1四個(gè)引腳。如下圖所示,使用echo 0 > state 拉低CFG引腳,發(fā)現(xiàn)沒(méi)有拉到0V。
在這里插入圖片描述解決方案:
交給硬件工程師去改。這兄弟給CFG加了一個(gè)反向電阻,驅(qū)動(dòng)部分需要將所有設(shè)置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 延時(shí)不夠
現(xiàn)象:echo 0 > state 可以拉低,測(cè)量也是正確的,但是CSM300始終無(wú)法接收到數(shù)據(jù)幀。
分析:一般數(shù)據(jù)接收不到,有兩種可能:就是CSM300給出的中斷信號(hào)CPU沒(méi)有截取到,CSM300沒(méi)有處于SPI轉(zhuǎn)CAN模式。
先用示波器確定了,USB轉(zhuǎn)CAN的數(shù)據(jù)已經(jīng)成功到達(dá)CSM300,于是檢測(cè)對(duì)應(yīng)的引腳電平 RST、 CFG、 CTL0、 CTL1,發(fā)現(xiàn)也是對(duì)的。
檢查中斷計(jì)數(shù),用cat /proc/interrupts查看CSM300是否有中斷計(jì)數(shù),結(jié)果發(fā)現(xiàn)數(shù)據(jù)為0。
懷疑CSM300沒(méi)有rst成功,于是執(zhí)行echo 3 > state,查看rst是否正確設(shè)置,結(jié)果發(fā)現(xiàn)以下波形,確定了該引腳拉高比較緩慢,所以CSM300采樣不到這個(gè)電平。
在這里插入圖片描述修改方法:驅(qū)動(dòng)中每次rst操作,都要增加延遲時(shí)間:
gpio_set_value(priv->RST,0);
usleep_range(2000,2300);
gpio_set_value(priv->RST,1);
修改后,執(zhí)行echo 3 > state,RST波形如下所示。
在這里插入圖片描述
免責(zé)聲明:本文內(nèi)容由21ic獲得授權(quán)后發(fā)布,版權(quán)歸原作者所有,本平臺(tái)僅提供信息存儲(chǔ)服務(wù)。文章僅代表作者個(gè)人觀點(diǎn),不代表本平臺(tái)立場(chǎng),如有問(wèn)題,請(qǐng)聯(lián)系我們,謝謝!