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打?。?/p>
將 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來讀寫數據。
成功后會打?。?/p>
打開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文章
6096瀏覽量
36130 -
安卓
+關注
關注
5文章
2147瀏覽量
58296 -
Firefly
+關注
關注
2文章
541瀏覽量
7390
發布評論請先 登錄
fireflyCORE-3399PRO主板JD4燒寫固件簡介

fireflyCORE-3399主板JD4--FAQs方案

fireflyCORE-3399主板JD4接口定義

fireflyCORE-3399主板JD4產品簡介
Core 3399Pro JD4文檔Core 3399Pro JD4核心板產品規格書

Core 3399 JD4工具Erase IDB Tool

Core 3399 JD4工具SD Firmware Tool

Core 3399 JD4固件Android 7.1系統

Core 3399 JD4文檔AIO 3399JD4產品規格書

Core 3399 JD4文檔AIO 3399JD4 Product Specifications

Core 3399 JD4文檔mb jd4 rk3399&3399pro v1.1.pdf

Core 3399 JD4 V2文檔MB JD4 RK3399/3399Pro V1.1貼片圖

Core 3399 JD4 V2文檔mb jd4 rk3399/3399pro v1.1

評論