AIO-PX30JD4 開發(fā)板上的 AD 接口有兩種,分別為:溫度傳感器 (Temperature Sensor)、逐次逼近ADC (Successive Approximation Register)。其中:
-
TS-ADC(Temperature Sensor):支持兩通道,時(shí)鐘頻率必須低于800KHZ
-
SAR-ADC(Successive Approximation Register):支持三通道單端10位的SAR-ADC,時(shí)鐘頻率必須小于13MHZ。
Linux內(nèi)核采用工業(yè) I/O 子系統(tǒng)(iio子系統(tǒng))來控制 ADC,該子系統(tǒng)主要為 AD 轉(zhuǎn)換或者 DA 轉(zhuǎn)換而設(shè)計(jì)。本文以配置SAR-ADC為例,主要介紹 SAR-ADC的基本配置和使用的方法,其相關(guān)的數(shù)據(jù)結(jié)構(gòu),源碼路徑以及配置步驟如下:
iio_channel結(jié)構(gòu)體
iio_dev結(jié)構(gòu)體
該結(jié)構(gòu)體主要是用于描述IO口所屬的設(shè)備,其具體定義如下:
iio_chan_spec結(jié)構(gòu)體
該結(jié)構(gòu)體主要用于描述單個(gè)通道的屬性,具體定義如下:
配置DTS節(jié)點(diǎn)
第一步:在AIO-PX30JD4的 DTS 文件:kernel/arch/arm64/boot/dts/rockchip/px30.dtsi中,添加saradc資源,應(yīng)如下:
第二步:根據(jù)用戶的通道需要選擇對(duì)應(yīng)的saradc通道,本次例程使用AIO-PX30-JD4上的ADC按鍵檢測(cè),選擇通道2,配置如下:
-
io-channels 屬性 為 選擇的通道號(hào),這里選擇通道2
-
io-channel-names 屬性 表示 為申請(qǐng)的通道起一個(gè)別名。
-
keyup-threshold-microvolt 屬性 表示按鍵抬起,saradc通道2的電壓(單位微伏)。
-
press-threshold-microvolt 屬性 表示按鍵按下,saradc通道2的電壓。
-
vol-up-key 在硬件連接上,為AIO-PX30-JD4 上的recovery 按鍵。
-
linux,code 屬性 為 按鍵上報(bào)的鍵值,鍵值對(duì)應(yīng)的動(dòng)作 為 “音量+” 。
在saradc驅(qū)動(dòng)文件中匹配 saradc 的dts 節(jié)點(diǎn)
第一步: 在內(nèi)核設(shè)備樹添加saradc資源之后,可以在源碼kernel/drivers/iio/adc/rockchip_saradc.c中添加對(duì)應(yīng)的saradc數(shù)據(jù)結(jié)構(gòu)體
第二步: 在rockchip_saradc_match[] 中,添加px30的compatible屬性,使得saradc驅(qū)動(dòng)可以匹配到saradc設(shè)備。因如下:
第三步: 填充saradc的platform_driver結(jié)構(gòu)體:
第四步:通過module_platform_driver(rockchip_saradc_driver)宏平進(jìn)行驅(qū)動(dòng)的注冊(cè)。
在設(shè)備上電的時(shí)候,內(nèi)核會(huì)解析內(nèi)核設(shè)備樹,當(dāng)檢測(cè)到設(shè)備樹上saradc的compatible屬性與saradc驅(qū)動(dòng)的of_device_id中的compatible成員一致的時(shí)候,便會(huì)調(diào)用rockchip_saradc.c中的rockchip_saradc_probe()函數(shù)來進(jìn)行iio系統(tǒng)的adc設(shè)備的資源申請(qǐng)以及初始化(此處不再贅述,用戶可自行查看源碼)。
在進(jìn)入系統(tǒng)后,會(huì)出現(xiàn)一個(gè) /sys/bus/iio/devices/iio:device0的目錄,表示創(chuàng)建成功。
在adc-keys.c驅(qū)動(dòng)文件中匹配 adc-keys的dts 節(jié)點(diǎn)
第一步: 填充ADC按鍵驅(qū)動(dòng)的adc_keys_of_match[]中的compatible成員用于匹配設(shè)備
第二步: 填充驅(qū)動(dòng)結(jié)構(gòu)體
第三步: 使用module_platform_driver(adc_keys_driver);往內(nèi)核注冊(cè)該驅(qū)動(dòng)。
第四步: 設(shè)備樹 compatible匹配正確,驅(qū)動(dòng)注冊(cè)成功之后,便會(huì)調(diào)用ADC按鍵驅(qū)動(dòng)的adc_keys_probe()函數(shù),進(jìn)行輸入子系統(tǒng)設(shè)備的注冊(cè)(因?yàn)槭前存I驅(qū)動(dòng),所以使用輸入子系統(tǒng),此部分不在此講述)與saradc的io通道的申請(qǐng)。
在進(jìn)入系統(tǒng)后,通過 getevent 命令 :
其中我們可以看到:
這樣表示我們的設(shè)備已經(jīng)創(chuàng)建成功。
按鍵檢測(cè)
adc-keys.c驅(qū)動(dòng)是通過輸入子系統(tǒng)的輪詢檢測(cè)函數(shù)adc_keys_poll(),來不斷地讀取saradc通道的值,當(dāng)不同按鍵按下的時(shí)候,是有不同的電壓值的:
所以當(dāng)recovery按鍵按下的時(shí)候,通過iio_read_channel_processed()函數(shù)獲取到的電壓值如果與設(shè)備樹配置相符合的話,就會(huì)觸發(fā)按鍵上報(bào)事件,而用戶層會(huì)收到事件,從屏幕可以看到有 ”音量+“ 的動(dòng)作。
獲取所有ADC值
有個(gè)便捷的方法可以在命令行中直接查詢到每個(gè)SARADC的值:
其中in_voltage0_raw為通道0,in_voltage01_raw為通道1,以此類推。
以上面的例子為例,命令行輸入 cat /sys/bus/iio/devices/iio:device0/in_voltage2_raw 來獲取ADC電壓轉(zhuǎn)換后的數(shù)字量
獲取 AD 通道
注:iio_channel_get 通過 probe 函數(shù)傳進(jìn)來的參數(shù) pdev 獲取 IIO 通道結(jié)構(gòu)體,probe 函數(shù)如下:
讀取 AD 采集到的原始數(shù)據(jù)
調(diào)用 iio_read_channel_raw 函數(shù)讀取 AD 采集的原始數(shù)據(jù)并存入 val 中。
計(jì)算采集到的電壓
使用標(biāo)準(zhǔn)電壓將 AD 轉(zhuǎn)換的值轉(zhuǎn)換為用戶所需要的電壓值。其計(jì)算公式如下:
注:
-
Vref 為標(biāo)準(zhǔn)電壓
-
n 為 AD 轉(zhuǎn)換的位數(shù)
-
Vresult 為用戶所需要的采集電壓
-
raw 為 AD 采集的原始數(shù)據(jù)
例如,標(biāo)準(zhǔn)電壓為 1.8V,AD 采集位數(shù)為 10 位,AD 采集到的原始數(shù)據(jù)為 568,則:
-
功能:獲取 iio 通道描述
-
參數(shù):
-
dev: 使用該通道的設(shè)備描述指針
-
consumer_channel: 該設(shè)備所使用的 IIO 通道描述指針
-
-
功能:釋放 iio_channel_get 函數(shù)獲取到的通道
-
參數(shù):
-
chan:要被釋放的通道描述指針
-
-
功能:讀取 chan 通道 AD 采集的原始數(shù)據(jù)。
-
參數(shù):
-
chan:要讀取的采集通道指針
-
val:存放讀取結(jié)果的指針
-
為何按上面的步驟申請(qǐng)SARADC,會(huì)出現(xiàn)申請(qǐng)報(bào)錯(cuò)的情況?
驅(qū)動(dòng)需要獲取ADC通道來使用時(shí),需要對(duì)驅(qū)動(dòng)的加載時(shí)間進(jìn)行控制,必須要在saradc初始化之后。saradc是使用module_platform_driver()進(jìn)行平臺(tái)設(shè)備驅(qū)動(dòng)注冊(cè),最終調(diào)用的是module_init()。所以用戶的驅(qū)動(dòng)加載函數(shù)只需使用比module_init()優(yōu)先級(jí)低的,例如:late_initcall(),就能保證驅(qū)動(dòng)的加載的時(shí)間比saradc初始化時(shí)間晚,可避免出錯(cuò)。
GPIO, 全稱 General-Purpose Input/Output(通用輸入輸出),是一種軟件運(yùn)行期間能夠動(dòng)態(tài)配置和控制的通用引腳。 PX30有4組GPIO bank:GPIO0~GPIO3,每組又以 A0~A7, B0~B7, C0~C7, D0~D7 作為編號(hào)區(qū)分(GPIO0在PD_PMU子系統(tǒng)中,GPIO1/GPIO2/GPIO3在PD_BUS子系統(tǒng)中)。 所有的GPIO在上電后的初始狀態(tài)都是輸入模式,可以通過軟件設(shè)為上拉或下拉,也可以設(shè)置為中斷腳,驅(qū)動(dòng)強(qiáng)度都是可編程的。每個(gè) GPIO 口除了通用輸入輸出功能外,還可能有其它復(fù)用功能,例如:
每個(gè) GPIO 口的驅(qū)動(dòng)電流、上下拉和重置后的初始狀態(tài)都不盡相同,詳細(xì)情況請(qǐng)參考《px30 規(guī)格書》中的 “Chapter 21 GPIO” 一章。 px30 的 GPIO 驅(qū)動(dòng)是在以下 pinctrl 文件中實(shí)現(xiàn)的:
其核心是填充 GPIO bank 的方法和參數(shù),并調(diào)用 gpiochip_add 注冊(cè)到內(nèi)核中。
DTS配置
本文以px30的gslx680外設(shè)(基于i2c通信的觸摸屏)為例,講述 gpio的輸入輸出,中斷,復(fù)用功能的使用,該驅(qū)動(dòng)源碼在SDK的路徑為:
以下就以該驅(qū)動(dòng)為例介紹GPIO的操作。
本例子所需添加的DTS資源如下所示:
輸入輸出引腳配置
這里使用的是gslx680外設(shè)的reset(復(fù)位)引腳來講述GPIO的輸入輸出操作。 在DTS配置如下資源:
AIO-PX30JD4的dts對(duì)引腳的描述與Firefly-RK3288有所區(qū)別,GPIO0_B4被描述為:<&gpio0 12 GPIO_ACTIVE_HIGH>,這里的12來源于:8+4=12,其中8是因?yàn)镚PIO0_B4是屬于GPIO0的B組,如果是A組的話則為0,如果是C組則為16,如果是D組則為24,以此遞推,而4是因?yàn)锽4后面的4。GPIO_ACTIVE_HIGH表示高電平有效,如果想要低電平有效,可以改為:GPIO_ACTIVE_LOW,這個(gè)屬性將被驅(qū)動(dòng)所讀取。
中斷引腳配置
這里使用的是gslx680外設(shè)的irq(中斷) 引腳來講述GPIO的中斷功能 在DTS中配置如下資源:
其中 gpio0 5 的意思是使用gpio0_A5 為中斷引腳,IRQ_TYPE_LEVEL_LOW意思是該引腳低電平(下降沿)的時(shí)候觸發(fā)中斷,跳到中斷函數(shù)執(zhí)行,中斷的觸發(fā)類型還可以配置如下:
復(fù)用功能引腳配置
查看芯片的數(shù)據(jù)手冊(cè),可以知道:
在上面i2c1的dts的配置中,主要有以下關(guān)鍵的描述
-
pinctrl-names 定義了狀態(tài)名稱列表: default (i2c 功能) 和 gpio 兩種狀態(tài)。
-
pinctrl-0 定義了狀態(tài) 0 (即 default)時(shí)需要設(shè)置的 pinctrl: &i2c4_xfer
-
pinctrl-1 定義了狀態(tài) 1 (即 gpio)時(shí)需要設(shè)置的 pinctrl: &i2c4_gpio
由于在i2c1的dts上gpio的字段屬性沒有添加,所以默認(rèn)該兩個(gè)引腳設(shè)置為i2c復(fù)用功能,其中pinctrl的描述可以在kernel/arch/arm64/boot/dts/rockchip/px30.dtsi 找到 :
其中 0 RK_PC2 表示的是GPIO0_C2引腳,0 RK_PC3 表示的是 GPIO0_C3引腳
RK_FUNC_1,RK_FUNC_GPIO的定義在 kernel/include/dt-bindings/pinctrl/rockchip.h 中可以找到:
在復(fù)用時(shí),如果選擇了 “default” (即 i2c 功能),系統(tǒng)會(huì)應(yīng)用 i2c1_xfer 這個(gè) pinctrl,最終將 GPIO0_C2 和 GPIO0_C3 兩個(gè)針腳切換成對(duì)應(yīng)的 i2c 功能;而如果選擇了 “gpio” ,系統(tǒng)會(huì)應(yīng)用 i2c1_gpio 這個(gè) pinctrl,將 GPIO0_C2 和 GPIO0_C3 兩個(gè)針腳還原為 GPIO 功能。
由于px30的i2c都是默認(rèn)復(fù)用的,所以在源SDK的px30.dtsi中并沒有加上gpio的選擇,所以,在i2c總線驅(qū)動(dòng)中:kernel/drivers/i2c/busses/i2c-rk3x.c,并沒有加上切換復(fù)用功能的源碼
如需了解i2c總線驅(qū)動(dòng)是如何切換復(fù)用功能的,可以參考源碼SDK中的rockchip的官方例子:kernel/drivers/i2c/busses/i2c-rockchip.c 中的rockchip_i2c_probe()函數(shù)。
首先是調(diào)用 of_get_gpio 取出設(shè)備樹中 i2c1 結(jié)點(diǎn)的 gpios 屬于所定義的兩個(gè) gpio:
然后是調(diào)用 devm_gpio_request 來申請(qǐng) gpio,接著是調(diào)用 pinctrl_lookup_state 來查找 “gpio” 狀態(tài),而默認(rèn)狀態(tài) “default” 已經(jīng)由框架保存到 i2c->dev-pins->default_state 中了。最后調(diào)用 pinctrl_select_state 來選擇是 “default” 還是 “gpio” 功能。
下面是常用的GPIO復(fù)用 API的定義:
gslx680 驅(qū)動(dòng)解析之輸入輸出,中斷
以下是對(duì)px30源SDK中g(shù)slx680外設(shè)驅(qū)動(dòng)中g(shù)sl_ts_probe()函數(shù),gslX680_init()函數(shù),static irqreturn_t gsl_ts_irq()進(jìn)行部分的解析,用戶可以從中了解gpio的輸入輸出,中斷功能的使用,而用于復(fù)用功能的i2c通信,則在下一章i2c進(jìn)行講解。
-
of_get_named_gpio_flags 從設(shè)備樹中讀取 “reset-gpio” 和 “touch-gpio” 的 GPIO 配置編號(hào)和標(biāo)志,gpio_is_valid 判斷該 GPIO 編號(hào)是否有效,devm_gpio_request_one則申請(qǐng)占用該 GPIO。如果初始化過程出錯(cuò),會(huì)跳到dev_err()函數(shù)進(jìn)行報(bào)錯(cuò)與gpio資源釋放處理。
-
調(diào)用gpio_to_irq把GPIO的PIN值轉(zhuǎn)換為相應(yīng)的IRQ值,調(diào)用devm_request_threaded_irq申請(qǐng)中斷,如果失敗會(huì)goto到標(biāo)簽error_req_irq_fail進(jìn)行錯(cuò)誤處理,gpio資源的釋放,該函數(shù)中ts->irq是要申請(qǐng)的硬件中斷號(hào),gsl_ts_irq是中斷函數(shù),irq_flags | IRQF_ONESHOT是中斷標(biāo)志位, client->name是設(shè)備驅(qū)動(dòng)程序名稱,ts是該設(shè)備的device結(jié)構(gòu)體,在注冊(cè)共享中斷時(shí)會(huì)用到。
在gsl_ts_probe()中,會(huì)在上電的時(shí)候,對(duì)復(fù)位引腳以及中斷引腳進(jìn)行初始化操作:
由上面的步驟可知曉,在設(shè)備上電的時(shí)候,可以用示波器測(cè)試出,該reset引腳會(huì)出現(xiàn)一個(gè)復(fù)位的操作。
而對(duì)于中斷而言,在用戶在進(jìn)入系統(tǒng)之后,點(diǎn)擊觸摸屏,會(huì)把中斷引腳拉低,由上面的devm_request_threaded_irq()函數(shù)可知,該中斷在觸發(fā)的時(shí)候,會(huì)跳到static irqreturn_t gsl_ts_irq()中斷函數(shù)中去執(zhí)行:
上面這個(gè)中斷函數(shù)主要是做了一些鍵值的上報(bào),由于本文未涉及input輸入子系統(tǒng),所以不在此處講述。
下面是常用的 GPIO 輸入輸出的API 定義:
IO指令
GPIO調(diào)試有一個(gè)很好用的工具,那就是IO指令,Android系統(tǒng)默認(rèn)已經(jīng)內(nèi)置了IO指令,使用IO指令可以實(shí)時(shí)讀取或?qū)懭朊總€(gè)IO口的狀態(tài),這里簡(jiǎn)單介紹IO指令的使用。 首先查看 io 指令的幫助:
從幫助上可以看出,如果要讀或者寫一個(gè)寄存器,可以用:
使用示例:
-
查看GPIO0當(dāng)前各引腳值的情況
-
從主控的datasheet查到GPIO0_IOMUX對(duì)應(yīng)寄存器基地址為:FF040000
-
如果想改變GPIO的配置值,可以使用以下指令設(shè)置:
GPIO調(diào)試接口
Debugfs文件系統(tǒng)目的是為開發(fā)人員提供更多內(nèi)核數(shù)據(jù),方便調(diào)試。 這里GPIO的調(diào)試也可以用Debugfs文件系統(tǒng),獲得更多的內(nèi)核信息。 GPIO在Debugfs文件系統(tǒng)中的接口為 /sys/kernel/debug/gpio,可以這樣讀取該接口的信息:
從讀取到的信息中可以知道,內(nèi)核把GPIO當(dāng)前的狀態(tài)都列出來了,以GPIO0組為例,gpio-5(GPIO0_A5)作為gslX680 模塊的中斷引腳,設(shè)置輸入,輸出高電平。
Q1: 如何將PIN的MUX值切換為一般的GPIO?
A1: 當(dāng)使用GPIO request時(shí)候,會(huì)將該P(yáng)IN的MUX值強(qiáng)制切換為GPIO,所以使用該pin腳為GPIO功能的時(shí)候確保該pin腳沒有被其他模塊所使用。
Q2: 為什么我用IO指令讀出來的值都是0x00000000?
A2: 如果用IO命令讀某個(gè)GPIO的寄存器,讀出來的值異常,如 0x00000000或0xffffffff等,請(qǐng)確認(rèn)該GPIO的CLK是不是被關(guān)了,GPIO的CLK是由CRU控制,可以通過讀取datasheet下面CRU_CLKGATE_CON* 寄存器來查到CLK是否開啟,如果沒有開啟可以用io命令設(shè)置對(duì)應(yīng)的寄存器,從而打開對(duì)應(yīng)的CLK,打開CLK之后應(yīng)該就可以讀到正確的寄存器值了。
Q3: 測(cè)量到PIN腳的電壓不對(duì)應(yīng)該怎么查?
A3: 測(cè)量該P(yáng)IN腳的電壓不對(duì)時(shí),如果排除了外部因素,可以確認(rèn)下該pin所在的io電壓源是否正確,以及IO-Domain配置是否正確。
Q4: gpio_set_value()與gpio_direction_output()有什么區(qū)別?
A4: 如果使用該GPIO時(shí),不會(huì)動(dòng)態(tài)的切換輸入輸出,建議在開始時(shí)就設(shè)置好GPIO 輸出方向,后面拉高拉低時(shí)使用gpio_set_value()接口,而不建議使用gpio_direction_output(), 因?yàn)間pio_direction_output接口里面有mutex鎖,對(duì)中斷上下文調(diào)用會(huì)有錯(cuò)誤異常,且相比 gpio_set_value,gpio_direction_output 所做事情更多,浪費(fèi)。
AIO-PX30-JD4 開發(fā)板上有 4 個(gè)片上 I2C 控制器,各個(gè) I2C 的使用情況如下表:
本文主要描述如何在該開發(fā)板上配置 I2C。
配置 I2C 可分為兩大步驟:
-
定義和注冊(cè) I2C 設(shè)備
-
定義和注冊(cè) I2C 驅(qū)動(dòng)
下面以配置 GSL3680 (觸摸屏)為例。
在注冊(cè)I2C設(shè)備時(shí),需要結(jié)構(gòu)體 i2c_client 來描述 I2C 設(shè)備。然而在標(biāo)準(zhǔn)Linux中,用戶只需要提供相應(yīng)的 I2C 設(shè)備信息,Linux就會(huì)根據(jù)所提供的信息構(gòu)造 i2c_client 結(jié)構(gòu)體。
用戶所提供的 I2C 設(shè)備信息以節(jié)點(diǎn)的形式寫到 dts 文件中,路徑為 kernel/arch/arm64/boot/dts/rockchip/px30-firefly-aiojd4-lvds.dts ,如下所示:
該驅(qū)動(dòng)的路徑為:kernel/drivers/input/touchscreen/gslx680_firefly.c
定義 I2C 驅(qū)動(dòng)
在定義 I2C 驅(qū)動(dòng)之前,用戶首先要定義變量 of_device_id 和 i2c_device_id 。
of_device_id 用于在驅(qū)動(dòng)中調(diào)用dts文件中定義的設(shè)備信息,其定義如下所示:
定義變量 i2c_device_id:
i2c_driver 如下所示:
注:變量id_table指示該驅(qū)動(dòng)所支持的設(shè)備。
注冊(cè) I2C 驅(qū)動(dòng)
使用i2c_add_driver函數(shù)注冊(cè) I2C 驅(qū)動(dòng)。
在調(diào)用 i2c_add_driver 注冊(cè) I2C 驅(qū)動(dòng)時(shí),會(huì)遍歷 I2C 設(shè)備,如果該驅(qū)動(dòng)支持所遍歷到的設(shè)備(即id_table的值與設(shè)備樹的compatible屬性值相同),則會(huì)調(diào)用該驅(qū)動(dòng)的 probe 函數(shù)。
通過 I2C 收發(fā)數(shù)據(jù)
在注冊(cè)好 I2C 驅(qū)動(dòng)后,即可進(jìn)行 I2C 通訊。
在該驅(qū)動(dòng)的gsl_ts_probe()函數(shù)中,會(huì)對(duì)gslx680的IC進(jìn)行初始化,而在初始化的代碼中,會(huì)對(duì)主從設(shè)備的通訊進(jìn)行一個(gè)測(cè)試
而在 test_i2c()這個(gè)函數(shù)中,會(huì)存在gsl_ts_read(),gsl_ts_write()兩個(gè)gslx680驅(qū)動(dòng)自己封裝的主機(jī)發(fā)送和主機(jī)接受函數(shù),其內(nèi)部真正調(diào)用的是Linux內(nèi)核提供的I2C通訊函數(shù)。
-
向從機(jī)發(fā)送信息:
-
向從機(jī)讀取信息:
在使用i2c_master_xxx()函數(shù)來進(jìn)行接受或者發(fā)送的時(shí)候,也是調(diào)用i2c_transfer()這個(gè)函數(shù)來處理一個(gè)消息結(jié)構(gòu)體(i2c_msg),而對(duì)于一些處理信息比較復(fù)雜的I2C設(shè)備,可以直接調(diào)用i2c_transfer()來處理信息,不過要自己構(gòu)造 i2c_msg 結(jié)構(gòu)體。
Q1: 通信失敗,出現(xiàn)這種log:”timeout, ipd: 0x00, state: 1”該如何調(diào)試?
A1: 請(qǐng)檢查硬件上拉是否給電。
Q2: 調(diào)用i2c_transfer返回值為-6?
A2: 返回值為-6表示為NACK錯(cuò)誤,即對(duì)方設(shè)備無應(yīng)答響應(yīng),這種情況一般為外設(shè)的問題,常見的有以下幾種情況:
-
I2C地址錯(cuò)誤,解決方法是測(cè)量I2C波形,確認(rèn)是否I2C 設(shè)備地址錯(cuò)誤;
-
I2C slave 設(shè)備不處于正常工作狀態(tài),比如未給電,錯(cuò)誤的上電時(shí)序等;
-
時(shí)序不符合 I2C slave設(shè)備所要求也會(huì)產(chǎn)生Nack信號(hào)。
Q3: 當(dāng)外設(shè)對(duì)于讀時(shí)序要求中間是stop信號(hào)不是repeat start信號(hào)的時(shí)候,該如何處理?
A3: 這時(shí)需要調(diào)用兩次i2c_transfer, I2C read 拆分成兩次,修改如下:
AIO-PX30-JD4 開發(fā)板上使用紅外收發(fā)傳感器 IR (麥克風(fēng)和i2c0之間)實(shí)現(xiàn)遙控功能,在IR接口處接上紅外接收器。本文主要描述在開發(fā)板上如何配置紅外遙控器。
其配置步驟可分為兩個(gè)部分:
-
修改內(nèi)核驅(qū)動(dòng):內(nèi)核空間修改,Linux 和 Android 都要修改這部分的內(nèi)容。
-
修改鍵值映射:用戶空間修改(僅限 Android 系統(tǒng))。
在PX30的DTS文件 : kernel/arch/arm64/boot/dts/rockchip/px30-firefly-aiojd4-lvds.dts 中:
注1:第一列為鍵值,第二列為要響應(yīng)的按鍵碼。 注2:由于UART3的RX與IR復(fù)用了,所以要使用IR功能,就需要在設(shè)備樹上關(guān)閉UART3。
在 Linux 內(nèi)核中,IR 驅(qū)動(dòng)僅支持 NEC 編碼格式。以下是在內(nèi)核中配置紅外遙控的方法。
所涉及到的文件
如何獲取用戶碼和IR 鍵值
在 remotectl_do_something 函數(shù)中獲取用戶碼和鍵值:
注:用戶可以使用 DBG_CODE() 函數(shù)打印用戶碼。
使用下面命令可以使能DBG_CODE打?。?/p>
將 IR 驅(qū)動(dòng)編譯進(jìn)內(nèi)核
將 IR 驅(qū)動(dòng)編譯進(jìn)內(nèi)核的步驟如下所示:
(1)、向配置文件 drivers/input/remotectl/Kconfig 中添加如下配置:
(2)、修改 drivers/input/remotectl 路徑下的 Makefile,添加如下編譯選項(xiàng):
(3)、在 kernel 路徑下使用 make menuconfig ,按照如下方法將IR驅(qū)動(dòng)選中。
保存后,執(zhí)行 make 命令即可將該驅(qū)動(dòng)編進(jìn)內(nèi)核。
文件 /system/usr/keylayout/ff200030_pwm.kl 用于將 Linux 層獲取的鍵值映射到 Android 上對(duì)應(yīng)的鍵值。用戶可以添加或者修改該文件的內(nèi)容以實(shí)現(xiàn)不同的鍵值映射。
該文件內(nèi)容如下所示:
注:通過 adb 修改該文件重啟后即可生效。
下圖是當(dāng)紅外遙控器按鈕按下的時(shí)候,所產(chǎn)生的波形,主要由head,Control,information,signed free這四部分組成,具體可以參考RC6 Protocol。
AIO-PX30-JD4開發(fā)板默認(rèn)外置支持了一個(gè)LCD屏接口,為L(zhǎng)VDS,另外板子也支持MIPI屏幕,但需要注意的是MIPI和LVDS是復(fù)用的,使用LVDS之后不能使用MIPI,接口如下圖:
由于AIO-PX30-JD4默認(rèn)使用的是LVDS屏幕,同時(shí)在默認(rèn)的配置文件kernel/arch/arm64/configs/firefly_defconfig已經(jīng)把LCD相關(guān)的配置設(shè)置好了,如果自己做了修改,請(qǐng)注意把以下配置加上:
DSI_PHY配置
AIO-PX30-JD4中關(guān)于LVDS(MIPI) DSI_PHY的DTS配置在:kernel/arch/arm64/boot/dts/rockchip/px30.dtsi中,從該文件我們可以看到:
而在kernel/arch/arm64/boot/dts/rockchip/px30-firefly-aiojd4-lvds.dts 也存在對(duì)以上dts進(jìn)行引用配置
Backlight配置
AIO-PX30-JD4開發(fā)板外置了一個(gè)背光接口用來控制屏幕背光,如下圖所示:
主要有背光電源引腳以及控制亮度引腳,DTS:kernel/arch/arm64/boot/dts/rockchip/px30-firefly-aiojd4-lvds.dts配置如下
-
enable-gpios 屬性為背光的電源控制引腳。
-
pwms屬性:配置PWM,可用來改變輸出占空比(范例里面默認(rèn)使用pwm0,50000ns是周期(20 KHz)。
-
brightness-levels屬性:配置背光亮度數(shù)組,最大值為255,配置暗區(qū)和亮區(qū),并把亮區(qū)數(shù)組做255的比例調(diào)節(jié)。比如范例中暗區(qū)是255-221,亮區(qū)是220-0。 由于PX30使用200以上的level屏幕就會(huì)過暗,所以默認(rèn)最大值為200。
-
default-brightness-level屬性:開機(jī)時(shí)默認(rèn)背光亮度,范圍為0-255。
具體請(qǐng)參考kernel中的說明文檔:kernel/Documentation/devicetree/bindings/leds/backlight/pwm-backlight.txt
顯示時(shí)序配置
在kernel/arch/arm64/boot/dts/rockchip/px30-firefly-aiojd4-lvds.dts中可以看到以下語句:
時(shí)序?qū)傩詤⒖枷聢D:
lvds屏上完電后需要完成一些初始化的工作才可以工作。
u-boot 部分 ->u-boot/drivers/video/drm/rockchip-dw-mipi-dsi.c
詳細(xì)流程說明可參考以下附件: Rockchip DRM Panel Porting Guide.pdf
AIO-PX30-JD4 開發(fā)板上有 2 個(gè) LED 燈,如下表所示:
以設(shè)備的方式控制 LED可通過使用 LED 設(shè)備子系統(tǒng)或者直接操作 GPIO 控制該 LED。
標(biāo)準(zhǔn)的 Linux 專門為 LED 設(shè)備定義了 LED 子系統(tǒng)。 在 AIO-PX30-JD4 開發(fā)板中的兩個(gè) LED 均以設(shè)備的形式被定義。
用戶可以通過 /sys/class/leds/ 目錄控制這兩個(gè) LED。
開發(fā)板上的 LED 的默認(rèn)狀態(tài)為:
-
Blue: 系統(tǒng)上電時(shí)打開
-
Yellow:用戶自定義
用戶可以通過 echo 向其 brightness屬性輸入命令控制每一個(gè) LED:
Trigger 包含多種方式可以控制LED,這里就用兩個(gè)例子來說明
-
Simple trigger LED
-
Complex trigger LED
更詳細(xì)的說明請(qǐng)參考 kernel/Documentation/leds/leds-class.txt ,有內(nèi)核對(duì)LED相關(guān)功能的支持的描述。
首先我們需要知道定義多少個(gè)LED,同時(shí)對(duì)應(yīng)的LED的屬性是什么。
在 kernel/arch/arm64/boot/dts/rockchip/px30-firefly-aiojd4-lvds.dts 文件中定義LED節(jié)點(diǎn),具體定義如下:
注意:compatible 的值要跟 drivers/leds/leds-gpio.c 中的 .compatible 的值要保持一致。
Simple trigger LED
這是使用簡(jiǎn)單的觸發(fā)方式控制來LED,如下就默認(rèn)打開黃燈:
(1)定義 LED 觸發(fā)器 在kernel/drivers/leds/trigger/led-firefly-demo.c 文件中有如下添加
(2)注冊(cè)該觸發(fā)器
(3)控制 LED 的亮。
(4)打開LED demo
led-firefly-demo默認(rèn)沒有打開,如果需要的話可以使用以下補(bǔ)丁打開demo驅(qū)動(dòng):
Complex trigger LED
如下是trigger方式控制LED復(fù)雜一點(diǎn)的例子,timer trigger 就是讓LED達(dá)到不斷亮滅的效果
我們需要在內(nèi)核把timer trigger配置上
在 kernel 路徑下使用 make menuconfig ,按照如下方法將timer trigger驅(qū)動(dòng)選中。
保存配置并編譯內(nèi)核,把kernel.img 燒到AIO-PX30-JD4板子上 我們可以使用串口輸入命令,就可以看到藍(lán)燈不停的間隔閃爍
用戶還可以使用 cat 命令獲取 trigger 的可用值:
AIO-PX30-JD4 開發(fā)板帶有一個(gè)MIPI camera,為MIPI_CSI,MIPI最高支持 3264x2448 pixels拍照。
本文以 OV13850 攝像頭為例,講解在該開發(fā)板上的配置過程。
kernel/arch/arm64/boot/dts/rockchip/px30.dtsi:
與攝像頭相關(guān)的代碼目錄如下:
設(shè)置攝像頭相關(guān)的引腳和時(shí)鐘,即可完成配置過程。
從以下攝像頭接口原理圖可知,需要配置的引腳有:CIF_PWR、DVP_PWR和MIPI_RST。
-
mipi接口
-
DVP_PWR 對(duì)應(yīng) PX30 的 GPIO1_B7;
-
CIF_PWR 對(duì)應(yīng) PX30 的 GPIO1_B6;
-
MIPI_RST對(duì)應(yīng) PX30 的 GPIO2_B3;
在開發(fā)板中,這三個(gè)引腳都是在 cam_board_rk3326.xml 中設(shè)置。
配置 Android
修改hardware/rockchip/camera/Config/cam_board_rk3326.xml 來注冊(cè)攝像頭:
-
嵌入式主板
+關(guān)注
關(guān)注
7文章
6100瀏覽量
36292 -
安卓
+關(guān)注
關(guān)注
5文章
2152瀏覽量
58668 -
Firefly
+關(guān)注
關(guān)注
2文章
542瀏覽量
8376
發(fā)布評(píng)論請(qǐng)先 登錄
AIO-PX30-JD4核心板上手教程
fireflyCORE-PX30-JD4燒寫工作介紹

fireflyCORE-PX30-JD4接口定義介紹

fireflyCORE-PX30-JD4編譯Buildroot 固件簡(jiǎn)介
fireflyCORE-PX30-JD4編譯 Ubuntu 固件簡(jiǎn)介
fireflyCORE-PX30-JD4燒寫固件簡(jiǎn)介
fireflyCORE-PX30-JD4產(chǎn)品簡(jiǎn)介
Core PX30 JD4 AndroidTools燒寫工具

Core PX30JD4工具Linux upgrade tool文件分享

Core PX30 JD4工具DriverAssitant驅(qū)動(dòng)助手

Core PX30 JD4 Android 8.1 SDK源碼分享

Core PX30 JD4源代碼Linux SDK分享

Core PX30 JD4固件Android 8.1固件分享

Core PX30 JD4固件Buildroot(GPT)文件分享

Core PX30 JD4資源linux headers文件分享

評(píng)論