SPI轉can晶片CSM300詳解以及Linux驅動移植除錯筆記

一口網發表於2020-10-30

更多嵌入式Linux乾貨,請關注 一口Linux

一、CSM300概述

CSM300(A)系列是一款可以支援 SPI / UART 介面的CAN模組。

1. 簡介

CSM300(A)系列隔離 SPI / UART 轉 CAN 模組是整合微處理器、 CAN 收發器、 DC-DC
隔離電源、 訊號隔離於一體的通訊模組, 該晶片可以很方便地嵌入到具有 SPI 或 UART 介面的裝置中, 在不需改變原有硬體結構的前提下使裝置獲得 CAN 通訊介面, 實現 SPI 裝置或 UART 裝置和 CAN 匯流排網路之間的資料通訊。

外觀

CSM300

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 較高;

型號

如上圖所示 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 引腳連線。

SPI 轉 CAN 參考電路(CSM300A)
引腳說明:

引腳說明
引腳功能說明如下:

  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 配置模式。

CSM300(A)工作模式如上表所示:

  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,待產品初始化完成後,才能進行正常操作。

下圖是不同模式切換的時序圖。
工作模式切換時序

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 的時間間隔。

主機讀資料幀主機寫資料幀

3. SPI 配置模式

在此模式下, CSM300(A)處於等待配置狀態, 無法向 CAN 端傳送或接收資料。此模式下僅能通過 SPI 介面進行配置。

三、主機控制

CSM300(A)有兩個 SPI 主機控制引腳 CTL0, CTL1, 受主機端控制。主機通過控制 CTL0,
CTL1 引腳, 使 CSM300(A)進入不同的功能狀態,實現對 CSM300(A)不同操作目的。 主機端控制引腳電平不同對應功能如下表所示:

SPI 模式下主機控制功能
主機可以通過讀從機當前狀態來獲取產品當前可以讀取的位元組數以及可以寫入的位元組
數。主機將功能選擇為主機讀狀態,然後通過 SPI 讀出 4 個位元組,即為狀態碼。狀態碼由
32 個位構成,具體定義如下表所示。
狀態碼
若定義 status[]陣列為 8 位整型, 通過 SPI 讀狀態依次讀出的資料為 status[0]、 status[1]、
status[2]、 status[3],則其資料結構如下圖:

狀態位元組資料結構

四、反饋機制(中斷)

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。
推薦組網示意圖

六、移植

1. 硬體連線圖

硬體連線圖

如上圖所示:

  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
驅動位置如下:
menuconfig
選中該驅動:

menuconfig重新編譯核心即可。

注意:該驅動還需要依賴CAN和SPI,一定要選上 。

4. 增加除錯介面

在除錯過程中,會有各種原因導致csm300驅動無法註冊成功,那如何判定是spi控制器驅動有問題,還是csm300驅動有問題呢?

為了方便通過spi控制器傳送出波形,我們增加以下程式碼,用於在板子目錄/sys/bus/spi/drivers/csm300中建立state檔案節點,通過寫入不同的值來產生spi資料,或者控制RST、 CFG、 CTL0、 CTL1這4個引腳。

  1. 增加函式csm300_spi_store()
    測試介面 重點說明一下函式**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……
正確的開機log
以下為SPI介面的CLK和MOSI引腳的波形:
開機SPI的波形可以看到資料與我們傳送的是一致的。

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幀的資料。

接收資料流程資料傳送過程和上述過程類似。

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寫入資料再讀取出來後資料不匹配,從而判定載入出錯。
出錯log

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

相關文章