AIO-3399JD4 開發板上的 AD 接口有兩種,分別為:溫度傳感器 (Temperature Sensor)、逐次逼近ADC (Successive Approximation Register)。其中:
-
TS-ADC(Temperature Sensor):支持兩通道,時鐘頻率必須低于800KHZ
-
SAR-ADC(Successive Approximation Register):支持六通道單端10位的SAR-ADC,時鐘頻率必須小于13MHZ。
內核采用工業 I/O 子系統來控制 ADC,該子系統主要為 AD 轉換或者 DA 轉換的傳感器設計。
下面以SAR-ADC使用ADC風扇為例子,介紹 ADC 的基本配置方法。
配置DTS節點
AIO-3399JD4 SAR-ADC 的 DTS 節點在 kernel/arch/arm64/boot/dts/rockchip/rk3399.dtsi 文件中定義,如下所示:
用戶首先需在DTS文件中添加ADC的資源描述:
這里申請的是SARADC通道3,在 AIO-3399JD4 中是不提供給客戶外部使用的,而且也沒有風扇接口,這里只是提供一個參考, 客戶可自行參考這個例子 運用SARADC通道0 去做自己的一些開發。
在驅動文件中匹配 DTS 節點
用戶驅動可參考Firefly adc demo :kernel/drivers/adc/adc-firefly-demo.c,這是一個偵測Firefly-rk3399風扇狀態的驅動。 首先在驅動文件中定義 of_device_id 結構體數組:
然后將該結構體數組填充到要使用 ADC 的 platform_driver 中:
接著在firefly_adc_probe中對DTS所添加的資源進行解析:
獲取 AD 通道
注:iio_channel_get 通過 probe 函數傳進來的參數 pdev 獲取 IIO 通道結構體,probe 函數如下:
讀取 AD 采集到的原始數據
調用 iio_read_channel_raw 函數讀取 AD 采集的原始數據并存入 val 中。
使用標準電壓將 AD 轉換的值轉換為用戶所需要的電壓值。其計算公式如下:
注:
-
Vref 為標準電壓
-
n 為 AD 轉換的位數
-
Vresult 為用戶所需要的采集電壓
-
raw 為 AD 采集的原始數據
例如,標準電壓為 1.8V,AD 采集位數為 10 位,AD 采集到的原始數據為 568,則:
-
功能:獲取 iio 通道描述
-
參數:
-
dev: 使用該通道的設備描述指針
-
consumer_channel: 該設備所使用的 IIO 通道描述指針
-
-
功能:釋放 iio_channel_get 函數獲取到的通道
-
參數:
-
chan:要被釋放的通道描述指針
-
-
功能:讀取 chan 通道 AD 采集的原始數據。
-
參數:
-
chan:要讀取的采集通道指針
-
val:存放讀取結果的指針
-
Demo程序使用
在kernel/arch/arm64/boot/dts/rockchip/rk3399-firefly-demo.dtsi中使能adc_demo,將”disabled” 改為 “okay”:
編譯內核,燒錄內核到Firefly-RK3399 開發板上,然后插拔風扇時,會打印內核log信息如下:
獲取所有ADC值
有個便捷的方法可以查詢到每個SARADC的值:
為何按上面的步驟申請SARADC,會出現申請報錯的情況?
驅動需要獲取ADC通道來使用時,需要對驅動的加載時間進行控制,必須要在saradc初始化之后。saradc是使用module_platform_driver()進行平臺設備驅動注冊,最終調用的是module_init()。所以用戶的驅動加載函數只需使用比module_init()優先級低的,例如:late_initcall(),就能保證驅動的加載的時間比saradc初始化時間晚,可避免出錯。
GPIO, 全稱 General-Purpose Input/Output(通用輸入輸出),是一種軟件運行期間能夠動態配置和控制的通用引腳。 RK3399有5組GPIO bank:GPIO0~GPIO4,每組又以 A0~A7, B0~B7, C0~C7, D0~D7 作為編號區分(不是所有 bank 都有全部編號,例如 GPIO4 就只有 C0~C7, D0~D2)。 所有的GPIO在上電后的初始狀態都是輸入模式,可以通過軟件設為上拉或下拉,也可以設置為中斷腳,驅動強度都是可編程的。 每個 GPIO 口除了通用輸入輸出功能外,還可能有其它復用功能,例如 GPIO2_A2,可以利用成以下功能:
-
GPIO2_A2
-
CIF_D2
每個 GPIO 口的驅動電流、上下拉和重置后的初始狀態都不盡相同,詳細情況請參考《RK3399 規格書》中的 “Chapter 10 GPIO” 一章。 RK3399 的 GPIO 驅動是在以下 pinctrl 文件中實現的:
其核心是填充 GPIO bank 的方法和參數,并調用 gpiochip_add 注冊到內核中。
本文以TP_RST(GPIO0_B4)和LCD_RST(GPIO4_D5)這兩個通用GPIO口為例寫了一份簡單操作GPIO口的驅動,在SDK的路徑為:
以下就以該驅動為例介紹GPIO的操作。
首先在DTS文件中增加驅動的資源描述:
這里定義了一個腳作為一般的輸出輸入口:
AIO-3399JD4 的dts對引腳的描述與Firefly-RK3288有所區別,GPIO0_B4被描述為:<&gpio0 12 GPIO_ACTIVE_HIGH>,這里的12來源于:8+4=12,其中8是因為GPIO0_B4是屬于GPIO0的B組,如果是A組的話則為0,如果是C組則為16,如果是D組則為24,以此遞推,而4是因為B4后面的4。 GPIO_ACTIVE_HIGH表示高電平有效,如果想要低電平有效,可以改為:GPIO_ACTIVE_LOW,這個屬性將被驅動所讀取。
然后在probe函數中對DTS所添加的資源進行解析,代碼如下:
of_get_named_gpio_flags 從設備樹中讀取 firefly-gpio 和 firefly-irq-gpio 的 GPIO 配置編號和標志,gpio_is_valid 判斷該 GPIO 編號是否有效,gpio_request 則申請占用該 GPIO。如果初始化過程出錯,需要調用 gpio_free 來釋放之前申請過且成功的 GPIO 。 在驅動中調用 gpio_direction_output 就可以設置輸出高還是低電平,這里默認輸出從DTS獲取得到的有效電平GPIO_ACTIVE_HIGH,即為高電平,如果驅動正常工作,可以用萬用表測得對應的引腳應該為高電平。 實際中如果要讀出 GPIO,需要先設置成輸入模式,然后再讀取值:
下面是常用的 GPIO API 定義:
在Firefly的例子程序中還包含了一個中斷引腳,GPIO口的中斷使用與GPIO的輸入輸出類似,首先在DTS文件中增加驅動的資源描述:
IRQ_TYPE_EDGE_RISING表示中斷由上升沿觸發,當該引腳接收到上升沿信號時可以觸發中斷函數。 這里還可以配置成如下:
然后在probe函數中對DTS所添加的資源進行解析,再做中斷的注冊申請,代碼如下:
調用gpio_to_irq把GPIO的PIN值轉換為相應的IRQ值,調用gpio_request申請占用該IO口,調用request_irq申請中斷,如果失敗要調用free_irq釋放,該函數中gpio_info-firefly_irq是要申請的硬件中斷號,firefly_gpio_irq是中斷函數,gpio_info->firefly_irq_mode是中斷處理的屬性,”firefly-gpio”是設備驅動程序名稱,gpio_info是該設備的device結構,在注冊共享中斷時會用到。
如何定義 GPIO 有哪些功能可以復用,在運行時又如何切換功能呢?以 I2C4 為例作簡單的介紹。
查規格表可知,I2C4_SDA 與 I2C4_SCL 的功能定義如下:
在 kernel/arch/arm64/boot/dts/rockchip/rk3399.dtsi 里有:
此處,跟復用控制相關的是 pinctrl- 開頭的屬性:
-
pinctrl-names 定義了狀態名稱列表: default (i2c 功能) 和 gpio 兩種狀態。
-
pinctrl-0 定義了狀態 0 (即 default)時需要設置的 pinctrl: &i2c4_xfer
-
pinctrl-1 定義了狀態 1 (即 gpio)時需要設置的 pinctrl: &i2c4_gpio
這些 pinctrl 在kernel/arch/arm64/boot/dts/rockchip/rk3399.dtsi中這樣定義:
RK_FUNC_1,RK_FUNC_GPIO 的定義在 kernel/include/dt-bindings/pinctrl/rk.h 中:
另外,像”1 11”,”1 12”這樣的值是有編碼規則的,編碼方式與上一小節”輸入輸出”描述的一樣,”1 11”代表GPIO1_B3,”1 12”代表GPIO1_B4。
在復用時,如果選擇了 “default” (即 i2c 功能),系統會應用 i2c4_xfer 這個 pinctrl,最終將 GPIO1_B3 和 GPIO1_B4 兩個針腳切換成對應的 i2c 功能;而如果選擇了 “gpio” ,系統會應用 i2c4_gpio 這個 pinctrl,將 GPIO1_B3 和 GPIO1_B4 兩個針腳還原為 GPIO 功能。
我們看看 i2c 的驅動程序 kernel/drivers/i2c/busses/i2c-rockchip.c 是如何切換復用功能的:
首先是調用 of_get_gpio 取出設備樹中 i2c4 結點的 gpios 屬于所定義的兩個 gpio:
然后是調用 devm_gpio_request 來申請 gpio,接著是調用 pinctrl_lookup_state 來查找 “gpio” 狀態,而默認狀態 “default” 已經由框架保存到 i2c->dev-pins->default_state 中了。
最后調用 pinctrl_select_state 來選擇是 “default” 還是 “gpio” 功能。
下面是常用的復用 API 定義:
在復雜的片上系統(SOC)中,設計者一般會將系統的供電分為多個獨立的block,這稱作電源域(Power Domain),這樣做有很多好處,例如:
-
在IO-Domain的DTS節點統一配置電壓域,不需要每個驅動都去配置一次,便于管理;
-
依照的是Upstream的做法,以后如果需要Upstream比較方便;
-
IO-Domain的驅動支持運行過程中動態調整電壓域,例如PMIC的某個Regulator可以1.8v和3.3v的動態切換,一旦Regulator電壓發生改變,會通知IO-Domain驅動去重新設置電壓域。
AIO-3399C原理圖上的 Power Domain Map 表以及配置如下表所示:
通過RK3399 SDK的原理圖可以看到bt656-supply 的電壓域連接的是vcc18_dvp, vcc_io是從PMIC RK808的VLDO1出來的; 在DTS里面可以找到vcc1v8_dvp, 將bt656-supply = <&vcc18_dvp>。 其他路的配置也類似,需要注意的是如果這里是其他PMIC,所用的Regulator也不一樣,具體以實際電路情況為標準。
IO指令
GPIO調試有一個很好用的工具,那就是IO指令,AIO-3399C的Android系統默認已經內置了IO指令,使用IO指令可以實時讀取或寫入每個IO口的狀態,這里簡單介紹IO指令的使用。 首先查看 io 指令的幫助:
從幫助上可以看出,如果要讀或者寫一個寄存器,可以用:
使用示例:
-
查看GPIO1_B3引腳的復用情況
-
從主控的datasheet查到GPIO1對應寄存器基地址為:0xff320000
-
從主控的datasheet查到GPIO1B_IOMUX的偏移量為:0x00014
-
GPIO1_B3的iomux寄存器地址為:基址(Operational Base) + 偏移量(offset)=0xff320000+0x00014=0xff320014
-
用以下指令查看GPIO1_B3的復用情況:
-
從datasheet查到[7:6]:
因此可以確定該GPIO被復用為 i2c4sensor_sda。
-
如果想復用為GPIO,可以使用以下指令設置:
GPIO調試接口
Debugfs文件系統目的是為開發人員提供更多內核數據,方便調試。 這里GPIO的調試也可以用Debugfs文件系統,獲得更多的內核信息。 GPIO在Debugfs文件系統中的接口為 /sys/kernel/debug/gpio,可以這樣讀取該接口的信息:
從讀取到的信息中可以知道,內核把GPIO當前的狀態都列出來了,以GPIO0組為例,gpio-2(GPIO0_A2)作為3G模塊的電源控制腳(vcc3v3_3g),輸出高電平(out hi)。
Q1: 如何將PIN的MUX值切換為一般的GPIO?
A1: 當使用GPIO request時候,會將該PIN的MUX值強制切換為GPIO,所以使用該pin腳為GPIO功能的時候確保該pin腳沒有被其他模塊所使用。
Q2: 為什么我用IO指令讀出來的值都是0x00000000?
A2: 如果用IO命令讀某個GPIO的寄存器,讀出來的值異常,如 0x00000000或0xffffffff等,請確認該GPIO的CLK是不是被關了,GPIO的CLK是由CRU控制,可以通過讀取datasheet下面CRU_CLKGATE_CON* 寄存器來查到CLK是否開啟,如果沒有開啟可以用io命令設置對應的寄存器,從而打開對應的CLK,打開CLK之后應該就可以讀到正確的寄存器值了。
Q3: 測量到PIN腳的電壓不對應該怎么查?
A3: 測量該PIN腳的電壓不對時,如果排除了外部因素,可以確認下該pin所在的io電壓源是否正確,以及IO-Domain配置是否正確。
Q4: gpio_set_value()與gpio_direction_output()有什么區別?
A4: 如果使用該GPIO時,不會動態的切換輸入輸出,建議在開始時就設置好GPIO 輸出方向,后面拉高拉低時使用gpio_set_value()接口,而不建議使用gpio_direction_output(), 因為gpio_direction_output接口里面有mutex鎖,對中斷上下文調用會有錯誤異常,且相比 gpio_set_value,gpio_direction_output 所做事情更多,浪費。
AIO-3399JD4 開發板上有 9 個片上 I2C 控制器,各個 I2C 的使用情況如下表:
本文主要描述如何在該開發板上配置 I2C。
配置 I2C 可分為兩大步驟:
-
定義和注冊 I2C 設備
-
定義和注冊 I2C 驅動
下面以配置 GSL3680 為例。
在注冊I2C設備時,需要結構體 i2c_client 來描述 I2C 設備。然而在標準Linux中,用戶只需要提供相應的 I2C 設備信息,Linux就會根據所提供的信息構造 i2c_client 結構體。
用戶所提供的 I2C 設備信息以節點的形式寫到 dts 文件中,如下所示:
定義 I2C 驅動
在定義 I2C 驅動之前,用戶首先要定義變量 of_device_id 和 i2c_device_id 。
of_device_id 用于在驅動中調用dts文件中定義的設備信息,其定義如下所示:
定義變量 i2c_device_id:
i2c_driver 如下所示:
注:變量id_table指示該驅動所支持的設備。
注冊 I2C 驅動
使用i2c_add_driver函數注冊 I2C 驅動。
在調用 i2c_add_driver 注冊 I2C 驅動時,會遍歷 I2C 設備,如果該驅動支持所遍歷到的設備,則會調用該驅動的 probe 函數。
通過 I2C 收發數據
在注冊好 I2C 驅動后,即可進行 I2C 通訊。
-
向從機發送信息:
-
向從機讀取信息:
Q1: 通信失敗,出現這種log:”timeout, ipd: 0x00, state: 1”該如何調試?
A1: 請檢查硬件上拉是否給電。
Q2: 調用i2c_transfer返回值為-6?
A2: 返回值為-6表示為NACK錯誤,即對方設備無應答響應,這種情況一般為外設的問題,常見的有以下幾種情況:
-
I2C地址錯誤,解決方法是測量I2C波形,確認是否I2C 設備地址錯誤;
-
I2C slave 設備不處于正常工作狀態,比如未給電,錯誤的上電時序等;
-
時序不符合 I2C slave設備所要求也會產生Nack信號。
Q3: 當外設對于讀時序要求中間是stop信號不是repeat start信號的時候,該如何處理?
A3: 這時需要調用兩次i2c_transfer, I2C read 拆分成兩次,修改如下:
AIO-3399JD4 開發板上使用紅外收發傳感器 IR (耳機接口和recovery之間)實現遙控功能,在IR接口處接上紅外接收器。本文主要描述在開發板上如何配置紅外遙控器。
其配置步驟可分為兩個部分:
-
修改內核驅動:內核空間修改,Linux 和 Android 都要修改這部分的內容。
-
修改鍵值映射:用戶空間修改(僅限 Android 系統)。
在 Linux 內核中,IR 驅動僅支持 NEC 編碼格式。以下是在內核中配置紅外遙控的方法。 所涉及到的文件
定義相關數據結構
以下是定義數據結構的步驟:
注:第一列為鍵值,第二列為要響應的按鍵碼。
如何獲取用戶碼和IR 鍵值
在 remotectl_do_something 函數中獲取用戶碼和鍵值:
注:用戶可以使用 DBG_CODE() 函數打印用戶碼。
使用下面命令可以使能DBG_CODE打印:
將 IR 驅動編譯進內核
將 IR 驅動編譯進內核的步驟如下所示:
(1)、向配置文件 drivers/input/remotectl/Kconfig 中添加如下配置:
(2)、修改 drivers/input/remotectl 路徑下的 Makefile,添加如下編譯選項:
(3)、在 kernel 路徑下使用 make menuconfig ,按照如下方法將IR驅動選中。
保存后,執行 make 命令即可將該驅動編進內核。
Android 鍵值映射
文件 /system/usr/keylayout/ff420030_pwm.kl 用于將 Linux 層獲取的鍵值映射到 Android 上對應的鍵值。用戶可以添加或者修改該文件的內容以實現不同的鍵值映射。
該文件內容如下所示:
注:通過 adb 修改該文件重啟后即可生效。
如下圖是通過按紅外遙控器按鈕,所產生的波形,主要由head,Control,information,signed free這四部分組成,具體可以參考RC6 Protocol。
AIO-3399JD4開發板默認外置支持了兩個LCD屏接口,一個是LVDS,一個是EDP,接口對應板子上的位置如下圖:
另外板子也支持MIPI屏幕,但需要注意的是MIPI和LVDS是復用的,使用MIPI之后不能使用LVDS。MIPI接口如下圖:
如Android7.1,由于使用的是mipi轉lvds,AIO-3399JD4默認的配置文件kernel/arch/arm64/configs/firefly_defconfig已經把LCD相關的配置設置好了,如果自己做了修改,請注意把以下配置加上:
引腳配置
LVDS屏
AIO-3399JD4的SDK有LVDS DSI的DTS文件:kernel/arch/arm64/boot/dts/rockchip/rk3399-firefly-aiojd4-lvds-HSX101H40C.dts,從該文件中我們可以看到以下語句:
保存配置并編譯內核,把kernel.img 燒到AIO-3399JD4板子上 我們可以使用串口輸入命令,就可以看到藍燈不停的間隔閃爍
用戶還可以使用 cat 命令獲取 trigger 的可用值:
與攝像頭相關的代碼目錄如下:
設置攝像頭相關的引腳和時鐘,即可完成配置過程。
從以下攝像頭接口原理圖可知,需要配置的引腳有:MIPI_PDN0_CAM和MIPI_RST。
mipi接口
MIPI_PDN0_CAM 對應 RK3399 的 GPIO2_A0;
MIPI_RST 對應GPIO0_B0;
在開發板中,這兩個引腳都是在 cam_board.xml 中設置。
配置 Android
修改device/rockchip/rk3399/XXX_PRODUCT/cam_board.xml 來注冊攝像頭:
最后執行:
即可完成內核的編譯。
終端下可以直接修改/system/etc/cam_board.xml調試各參數并重啟生效
1.無法打開攝像頭,首先確定sensor I2C是否通信。若不通則可檢查mclk以及供電是否正常(Power/PowerDown/Reset/Mclk/I2cBus)分別排查 2.支持列表? 13M? OV13850/IMX214-0AQH5 8M? OV8825/OV8820/OV8858-Z(R1A)/OV8858-R2A 5M? OV5648/OV5640 2M? OV2680 詳細資料可查詢SDK/RKDocs
AIO-3399JD4開發板上引出有 3 路 PWM 輸出,分別為:
PWM0 屏背光
PWM2 VDDLOG供電
PWM3 紅外IR
本章主要描述如何配置 PWM。
RK3399的 PWM 驅動為: kernel/drivers/pwm/pwm-rockchip.c
配置 PWM 主要有以下三大步驟:配置 PWM DTS 節點、配置 PWM 內核驅動、控制 PWM 設備。
配置 PWM DTS節點
在 DTS 源文件kernel/arch/arm64/boot/dts/rockchip/rk3399-firefly-demo.dtsi 添加 PWM DTS 配置,如下所示:
pwm_id:需要申請的pwm通道數。
min_period:周期時長最小值。
max_period:周期時長最大值。
duty_ns:pwm 的占空比激活的時長,單位 ns。
用戶可在其它驅動文件中使用以上步驟生成的 PWM 節點。具體方法如下:
(1)、在要使用 PWM 控制的設備驅動文件中包含以下頭文件:
該頭文件主要包含 PWM 的函數接口。
(2)、申請 PWM使用
函數申請 PWM。 例如:
(3)、配置 PWM使用
配置 PWM 的占空比, 例如:
(4)、使能PWM 函數
用于使能 PWM,例如:
(5)控制 PWM 輸出主要使用以下接口函數:
功能:用于申請 pwm
功能:用于釋放所申請的 pwm
功能:用于配置 pwm 的占空比
功能:使能 pwm
功能:禁止 pwm
參考Demo:kernel/drivers/pwm/pwm-firefly.c
通過內核豐富的debug接口查看pwm注冊狀態,adb shell或者串口進入android終端 cat /sys/kernel/debug/pwm —注冊是否成功,成功則返回接口名和寄存器地址
Pwm無法注冊成功:
dts配置文件是否打開對應的pwm。
pwm所在的io口是否被其他資源占用,可以根據報錯的返回值去查看原因。
SPI是一種高速的,全雙工,同步串行通信接口,用于連接微控制器、傳感器、存儲設備等。 AIO-3399JD4 SPI引出來了一路SPI2(可復用GPIO)給外部使用。 AIO-3399JD4 開發板提供了 SPI2(單片選)接口,具體位置如下圖:
SPI以主從方式工作,這種模式通常有一個主設備和一個或多個從設備,需要至少4根線,分別是:
Linux內核用CPOL和CPHA的組合來表示當前SPI的四種工作模式:
CPOL:表示時鐘信號的初始電平的狀態,0為低電平,1為高電平。CPHA:表示在哪個時鐘沿采樣,0為第一個時鐘沿采樣,1為第二個時鐘沿采樣。SPI的四種工作模式波形圖如下:
下面以 W25Q128FV Flash模塊為例簡單介紹SPI驅動的編寫。
硬件連接
AIO-3399JD4 與 W25Q128FV 硬件連接如下表:
在kernel/drivers/spi/Kconfig中添加對應的驅動文件配置:
在kernel/drivers/spi/Makefile中添加對應的驅動文件名:
config中選中所添加的驅動文件,如:
配置DTS節點
在kernel/arch/arm64/boot/dts/rockchip/rk3399-firefly-demo.dtsi中添加SPI驅動結點描述,如下所示:
status:如果要啟用SPI,則設為okay,如不啟用,設為disable。
spi-demo@00:由于本例子使用CS0,故此處設為00,如果使用CS1,則設為01。
compatible:這里的屬性必須與驅動中的結構體:of_device_id 中的成員compatible 保持一致。
reg:此處與spi-demo@00保持一致,本例設為:0x00。
spi-max-frequency:此處設置spi使用的最高頻率。Firefly-RK3399最高支持48000000。
spi-cpha,spi-cpol:SPI的工作模式在此設置,本例所用的模塊SPI工作模式為SPI_MODE_0或者SPI_MODE_3,這里我們選用SPI_MODE_0,如果使用SPI_MODE_3,spi_demo中打開spi-cpha和spi-cpol即可。
spidev0: 由于spi_demo與spidev0使用一樣的硬件資源,需要把spidev0關掉才能打開spi_demo
定義SPI驅動
在內核源碼目錄kernel/drivers/spi/中創建新的驅動文件,如:spi-firefly-demo.c 在定義 SPI 驅動之前,用戶首先要定義變量 of_device_id 。 of_device_id 用于在驅動中調用dts文件中定義的設備信息,其定義如下所示:
此處的compatible與DTS文件中的保持一致。
spi_driver定義如下所示:
注冊SPI設備
在初始化函數static int __init spidev_init(void)中向內核注冊SPI驅動: spi_register_driver(&firefly_spi_driver);
如果內核啟動時匹配成功,則SPI核心會配置SPI的參數(mode、speed等),并調用firefly_spi_probe。
讀寫 SPI 數據
firefly_spi_probe中使用了兩種接口操作讀取W25Q128FV的ID: firefly_spi_read_w25x_id_0接口直接使用了spi_transfer和spi_message來傳送數據。 firefly_spi_read_w25x_id_1接口則使用SPI接口spi_write_then_read來讀寫數據。
成功后會打印:
打開SPI demo
spi-firefly-demo默認沒有打開,如果需要的話可以使用以下補丁打開demo驅動:
常用SPI接口
下面是常用的 SPI API 定義:
Linux提供了一個功能有限的SPI用戶接口,如果不需要用到IRQ或者其他內核驅動接口,可以考慮使用接口spidev編寫用戶層程序控制SPI設備。 在 Firefly-RK3399 開發板中對應的路徑為: /dev/spidev0.0
spidev對應的驅動代碼: kernel/drivers/spi/spidev.c
內核config需要選上SPI_SPIDEV:
DTS配置如下:
詳細使用說明請參考文檔 spidev 。
Q1: SPI數據傳送異常
A1: 確保 SPI 4個引腳的 IOMUX 配置正確, 確認 TX 送數據時,TX 引腳有正常的波形,CLK 頻率正確,CS 信號有拉低,mode 與設備匹配。
RK3399有12 個Timers (timer0-timer11),有12 個Secure Timers(stimer0~stimer11) 和 2 個Timers(pmutimer0~pmutimer1), 我們主要用到的是Timers(timer0-timer11)時鐘頻率為24MHZ ,工作模式有 free-running 和 user-defined count 模式
user-defined count:Timer 先載入初始值到 TIMERn_LOAD_COUNT3 和 TIMER_LOADn_COUNT2寄存器, 當時間累加的值在寄存器TIMERn_LOAD_COUNT1和TIMERn_LOAD_COUNT0時,將不會自動載入到計數寄存器。 用戶需要重新關閉計數器和然后重新設置計數器相關才能繼續工作。
free-running:Timer先載入初始值到TIMER_LOAD_COUNT3 和 TIMER_LOAD_COUNT2寄存器, 當時間累加的值在寄存器TIMERn_LOAD_COUNT1和TIMERn_LOAD_COUNT0時,Timer將一直自動加載計數寄存器。
1.在 dts 文件中定義 Timer 的相關配置 kernel/arch/arm64/boot/dts/rockchip/rk3399.dtsi
其中定義的Timer0 的寄存器和中斷號和時鐘等
其他Timer 對應的中斷號可看如下圖片
2.對應的驅動文件Kernel/drivers/clocksource/rockchip_timer.c
1.寄存器如下圖片
文件kernel/arch/arm64/boot/dts/rockchip/rk3399-firefly-port.dtsi 有spi轉uart相關節點的定義:
可以看到,在kernel/arch/arm64/boot/dts/rockchip/rk3399-firefly-aiojd4.dts文件中使能該節點即可使用。另外,由于我們板子使用的spi轉uart串口模塊掛到spi1上,所以還要使能spi1節點。如下:
注意:由于spi1_rxd和spi1_txd兩個腳可復用為uart4_rx和uart4_tx,所以要留意關閉掉uart4的使用,如下:
配置好串口后,硬件接口對應軟件上的節點分別為:
用戶可以根據不同的接口使用不同的主機的 USB 轉串口適配器向開發板的串口收發數據,例如RS485的調試步驟如下:
(1) 連接硬件
將開發板RS485 的A、B、GND 引腳分別和主機串口適配器(USB轉485轉串口模塊)的 A、B、GND 引腳相連。
(2) 打開主機的串口終端
在終端打開kermit,并設置波特率:
/dev/ttyUSB0 為 USB 轉串口適配器的設備文件
(3) 發送數據
RS485 的設備文件為 /dev/ttysWK0。在設備上運行下列命令:
主機中的串口終端即可接收到字符串“firefly RS485 test…”
(4) 接收數據
首先在設備上運行下列命令:
然后在主機的串口終端輸入字符串 “Firefly RS485 test…”,設備端即可見到相同的字符串。
-->
-
嵌入式主板
+關注
關注
7文章
6086瀏覽量
35643 -
安卓
+關注
關注
5文章
2137瀏覽量
57654 -
Firefly
+關注
關注
2文章
538瀏覽量
7141
發布評論請先 登錄
相關推薦
fireflyCORE-3399PRO主板JD4燒寫固件簡介
![<b class='flag-5'>fireflyCORE-3399</b>PRO<b class='flag-5'>主板</b><b class='flag-5'>JD4</b>燒寫固件<b class='flag-5'>簡介</b>](https://file.elecfans.com/web1/M00/AB/A3/pIYBAF220n-ATTWEAAAxRuygt_I295.png)
fireflyCORE-3399主板JD4--FAQs方案
![<b class='flag-5'>fireflyCORE-3399</b><b class='flag-5'>主板</b><b class='flag-5'>JD4</b>--FAQs方案](https://file.elecfans.com/web1/M00/AB/A3/pIYBAF2203eAYTyKAABl8KbNMas811.jpg)
fireflyCORE-3399主板JD4接口定義
![<b class='flag-5'>fireflyCORE-3399</b><b class='flag-5'>主板</b><b class='flag-5'>JD4</b>接口定義](https://file.elecfans.com/web1/M00/AB/4B/o4YBAF22012AFelBABE_leIrdqs896.png)
fireflyCORE-3399主板JD4產品簡介
Core 3399Pro JD4工具SDDiskTool
![Core <b class='flag-5'>3399</b>Pro <b class='flag-5'>JD4</b>工具SDDiskTool](https://file.elecfans.com/web1/M00/D9/4E/pIYBAF_1ac2Ac0EEAABDkS1IP1s689.png)
Core 3399Pro JD4文檔Core 3399Pro JD4核心板產品規格書
![Core <b class='flag-5'>3399</b>Pro <b class='flag-5'>JD4</b>文檔Core <b class='flag-5'>3399</b>Pro <b class='flag-5'>JD4</b>核心板產品規格書](https://file.elecfans.com/web1/M00/D9/4E/pIYBAF_1ac2Ac0EEAABDkS1IP1s689.png)
Core 3399 JD4工具SD Firmware Tool
![Core <b class='flag-5'>3399</b> <b class='flag-5'>JD4</b>工具SD Firmware Tool](https://file.elecfans.com/web1/M00/D9/4E/pIYBAF_1ac2Ac0EEAABDkS1IP1s689.png)
Core 3399 JD4文檔AIO 3399JD4產品規格書
![Core <b class='flag-5'>3399</b> <b class='flag-5'>JD4</b>文檔AIO <b class='flag-5'>3399JD4</b>產品規格書](https://file.elecfans.com/web1/M00/D9/4E/pIYBAF_1ac2Ac0EEAABDkS1IP1s689.png)
Core 3399 JD4文檔AIO 3399JD4 Product Specifications
![Core <b class='flag-5'>3399</b> <b class='flag-5'>JD4</b>文檔AIO <b class='flag-5'>3399JD4</b> Product Specifications](https://file.elecfans.com/web1/M00/D9/4E/pIYBAF_1ac2Ac0EEAABDkS1IP1s689.png)
Core 3399 JD4文檔mb jd4 rk3399&3399pro v1.1.pdf
![Core <b class='flag-5'>3399</b> <b class='flag-5'>JD4</b>文檔mb <b class='flag-5'>jd4</b> rk<b class='flag-5'>3399</b>&<b class='flag-5'>3399</b>pro v1.1.pdf](https://file.elecfans.com/web1/M00/D9/4E/pIYBAF_1ac2Ac0EEAABDkS1IP1s689.png)
Core 3399 JD4 V2文檔MB JD4 RK3399/3399Pro V1.1貼片圖
![Core <b class='flag-5'>3399</b> <b class='flag-5'>JD4</b> V2文檔MB <b class='flag-5'>JD4</b> RK<b class='flag-5'>3399</b>/<b class='flag-5'>3399</b>Pro V1.1貼片圖](https://file.elecfans.com/web1/M00/D9/4E/pIYBAF_1ac2Ac0EEAABDkS1IP1s689.png)
Core 3399 JD4 V2文檔mb jd4 rk3399/3399pro v1.1
![Core <b class='flag-5'>3399</b> <b class='flag-5'>JD4</b> V2文檔mb <b class='flag-5'>jd4</b> rk<b class='flag-5'>3399</b>/<b class='flag-5'>3399</b>pro v1.1](https://file.elecfans.com/web1/M00/D9/4E/pIYBAF_1ac2Ac0EEAABDkS1IP1s689.png)
評論