一、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