imx6芯片通过EIM总线外扩多路sja1000 CAN控制器
有時會需要擴展多個CAN接口,在CAN設備比較多的時候作分組控制。這里使用imx6q芯片,它本身已經自帶了兩個CAN接口,如果需再擴展4個接口,就要想想辦法了。sja1000是一個經典的CAN控制器,穩定可靠,由于它在業界使用方案比較成熟,用它來擴展再好不過。imx6q作為一款性能強大的處理器,擴展sja1000這種相對慢速的芯片,著實有點屈才。可是沒辦法,項目需要,就像PCIE轉ISA,或者USB轉PCIE一樣,效率并不是最重要的,硬件的兼容性和軟件的易維護性同樣重要。
這篇文檔分硬件部分和軟件部分來介紹下imx6q如何來與sja1000芯片組合應用起來,主要實現了通過imx6芯片的eim總線外擴4個sja1000 can控制器的功能。
一、硬件部分
首先來一張sja1000芯片的經典電路,是與8051單片機配合使用的。
看到這張圖,是不是首先就想到了8051單片機的P0腳,還記得當時剛剛接觸51單片機時,還會對P0與P1/P2/P3引腳的特性不同有些困惑。P0腳是3態的,可以應用在地址/數據總線。51單片機就是通過P0接口來擴展些SRAM、ROM啥的。這個電路圖中,就是一個典型的外擴SRAM的接法:P0做地址/數據總線,P2.7獨立GPIO控制CS腳(CS腳為低SJA1000芯片才工作),ALE/RO/WE是讀寫控制信號,INT中斷腳接到P3.2接口上。從而可以看出,sja1000芯片留給外部的接口就是一個SRAM接口(CPU通過總線讀寫sja1000芯片的寄存器來控制),只要CPU有能夠擴展SRAM的總線接口,那么就能外擴sja1000芯片。那么imx6芯片有沒有類似的總線呢?
答案是肯定的,imx6系列芯片功能豐富,性能爆表,區區一個SRAM總線接口,怎會沒有。imx6芯片帶有WEIM接口,支持16/32bit的地址/數據總線混合模式,不過地址線最高為27bit,這個接口可靈活配置地址/數據端口,支持外接SRAM、NorFalsh和OneNAND等設備,先來看一張典型的imx6芯片的EIM接口圖。
EIM總線地址總線引腳范圍為EIM_DA0_15、EIM_A16_26,數據總線引腳范圍為EIM_DA0_15、EIM_D16_31(圖中有些引腳沒有引出)。sja1000與之相連,可以是地址/數據總線復用的方式,也可以是地址總線與數據總線分離的方式(通過配置地址和數據引腳端口)。從電路簡潔性上講,當然采用復用的方式,就像51單片機的P0接口一樣。有些芯片的SRAM接口并不支持地址/數據總線復用,與sja1000芯片相接時需要在電路上加邏輯器件,這個在另一篇文檔中再寫吧。
imx6芯片手冊中指出,EIM總線只支持16/32bit的復用方式,通過EIM_CSnGCR1寄存器來配置,如下圖。
EIM總線與sja1000這種8位的SRAM接口類型芯片相連,用16bit的multiplexing模式搓搓有余。可以16位的總線來訪問8位總線存儲器時,會有地址無法對齊的尷尬情況。舉個例子說,16位總線讀地址0x0000時(忽略基地址),read_byte()讀的是D0_7這一組的電平值,讀地址0x0001時,read_byte(),讀的是D8_15這一組的電平值,反之寫操作也是一樣。那么16位總線與sja1000相連時,如果只用DA0_7腳,必然導致雖偶地址訪問正常,奇地址訪問不到的情況。這個也好解決,我們用DA1_8引腳就可以了。整個連接起來如下圖的樣子。
其中EIM_nOE、EIM_nWE和EIM_LBA與51單片機的WR、RD和ALE類似,DA1_8為地址/數據復用總線的0_7位,DA9_12則用來當4個CS信號線用(接了4片SJA1000芯片),EIM總線有CS0_3,不過被其它功能引腳復用占了,這里就只能這么干了。至于RST和INT線,隨便找幾個GPIO就行。
接下來簡單分析下硬件時序,先看sja1000芯片的讀時序。
從圖中可以看出,讀操作周期中,主機端先給出要讀的地址(AD0_7上產生),然后拉低ALE信號,提示sja1000設備進行地址鎖存,拉低CS信號,使能sja1000設備,最后拉低RD信號,釋放地址/數據總線。sja1000設備在t_RLQV時間內準備好數據,然后寫在數據總線上。主機在t_W/R時間后,拉高RD信號,讀取地址/總線上的數據,拉高CS線,完成一個讀操作周期。整個讀操作周期中WR信號為高。寫操作周期與之類似,如下圖所示。
同樣,主機端準備好地址信號,拉低ALE信號、CS信號,然后拉低WR信號,提示sja1000設備將進行寫操作。之后主機端在地址/總線上寫數據信號,等待t_DVWH后,拉高WR信號線,在t_WHDX時間后釋放總線。sja100設備在拉高WR信號的時候進行接收數據。
二、軟件部分
這里使用的是3.14.28版本linux內核,由于支持設備樹,為驅動程序的編寫帶來了很多便利。首先修改dts文件,使能WEIM總線,并配置需要用到的功能引腳、GPIO、中斷引腳。
weim總線中配置的引腳有 EIM_DA0_15(只用到DA1_12)、EIM_OE、EIM_RW、EIM_LBA、EIM_CS0(cs線由高位地址線取代,這里無用),sja1000驅動中添加了四個中斷引腳(對應4個sja1000芯片)、4個LED gpio(CAN通信指示燈用)、RST GPIO(產生硬復位信號,一般不用)。接下來看sja1000驅動需要添加的dts文件內容。
/ {sja1000@08001C00 {compatible = "weim,sja1000";reg = <0x08001C00 0x1FF>;nxp,external-clock-frequency = <16000000>;nxp,tx-output-config = <0x16>;nxp,no-comparator-bypass;interrupt-parent = <&gpio4>;interrupts = <16 0>;int-gpios = <&gpio4 16 0>;rst-gpios = <&gpio2 28 0>;led-gpios = <&gpio4 26 0>;};sja1000@08001A00 {compatible = "weim,sja1000";reg = <0x08001A00 0x1FF>;nxp,external-clock-frequency = <16000000>;nxp,tx-output-config = <0x16>;nxp,no-comparator-bypass;interrupt-parent = <&gpio4>;interrupts = <17 0>;int-gpios = <&gpio4 17 0>;led-gpios = <&gpio4 27 0>;};sja1000@08001600 {compatible = "weim,sja1000";reg = <0x08001600 0x1FF>;nxp,external-clock-frequency = <16000000>;nxp,tx-output-config = <0x16>;nxp,no-comparator-bypass;interrupt-parent = <&gpio4>;interrupts = <18 0>;int-gpios = <&gpio4 18 0>;led-gpios = <&gpio4 28 0>;};sja1000@08000E00 {compatible = "weim,sja1000";reg = <0x08000E00 0x1FF>;nxp,external-clock-frequency = <16000000>;nxp,tx-output-config = <0x16>;nxp,no-comparator-bypass;interrupt-parent = <&gpio4>;interrupts = <19 0>;int-gpios = <&gpio4 19 0>;led-gpios = <&gpio4 29 0>;}; };四片sja1000芯片的基地址計算方式:weim總線的基地址為0x08000000,第一片sja1000芯片讀寫時DA1_8 對應地址/數據總線的D0_7,地址范圍為 0x08000000~0x080001FF(忽略DA0的信號),由于DA9_12充當CS信號,讀寫第一片sja1000芯片時,需要保持DA9為0、DA10為1、DA11為1、DA12為1,從而第一片sja1000芯片的基地址為0x08001C00。同理,第二三四片sja1000芯片的基地址分別為 0x08001A00 、0x08001600、0x08000E00。
dts資源配置好后,需要在對應的驅動程序中正確引用。linux內核中已經有了sja1000_platform驅動(位于driver/net/can/sja1000目錄下),直接在它的基礎上修改下就行。
1. of_device_id添加
這里是為了驅動能與dts文件中“weim,sja1000”資源匹配。
2. 初始化weim總線
這里通過修改寄存器完成,程序在加載驅動程序時調用,主要配置weim時鐘、中斷、地址/數據總線端口、時序控制等,詳見imx6數據手冊。
3、probe函數修改
probe函數中主要針對添加了rst引腳和led引腳,其它未做改變。可以看到,probe函數中,申請了sja1000設備的總線資源,根據GPIO中斷引腳號申請了終端,然后將platform設備注冊到sja1000驅動中。
4. read/write 地址偏移
由于使用的是DA1_8引腳(DA9_12充當了CS信號),其讀寫地址肯定不能直接在基地址上了。修改sja100_platform中的write8和read8函數,完成讀寫的地址偏移。
完整的驅動程序見https://gitee.com/westlor/imx6_sja1000。
如有錯誤請指正。
總結
以上是生活随笔為你收集整理的imx6芯片通过EIM总线外扩多路sja1000 CAN控制器的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 最强的志愿军战俘:炸掉一飞机美军后逃离
- 下一篇: 液晶显示屏行业信息汇总