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))來(lái)控制 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)體:
第四步:通過(guò)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ù)來(lái)進(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)后,通過(guò) getevent 命令 :
其中我們可以看到:
這樣表示我們的設(shè)備已經(jīng)創(chuàng)建成功。
按鍵檢測(cè)
adc-keys.c驅(qū)動(dòng)是通過(guò)輸入子系統(tǒng)的輪詢檢測(cè)函數(shù)adc_keys_poll(),來(lái)不斷地讀取saradc通道的值,當(dāng)不同按鍵按下的時(shí)候,是有不同的電壓值的:
所以當(dāng)recovery按鍵按下的時(shí)候,通過(guò)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 來(lái)獲取ADC電壓轉(zhuǎn)換后的數(shù)字量
獲取 AD 通道
注:iio_channel_get 通過(guò) probe 函數(shù)傳進(jìn)來(lái)的參數(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通道來(lái)使用時(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)都是輸入模式,可以通過(guò)軟件設(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ù)位)引腳來(lái)講述GPIO的輸入輸出操作。 在DTS配置如下資源:
AIO-PX30JD4的dts對(duì)引腳的描述與Firefly-RK3288有所區(qū)別,GPIO0_B4被描述為:<&gpio0 12 GPIO_ACTIVE_HIGH>,這里的12來(lái)源于: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(中斷) 引腳來(lái)講述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的字段屬性沒(méi)有添加,所以默認(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中并沒(méi)有加上gpio的選擇,所以,在i2c總線驅(qū)動(dòng)中:kernel/drivers/i2c/busses/i2c-rk3x.c,并沒(méi)有加上切換復(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 來(lái)申請(qǐng) gpio,接著是調(diào)用 pinctrl_lookup_state 來(lái)查找 “gpio” 狀態(tài),而默認(rèn)狀態(tài) “default” 已經(jīng)由框架保存到 i2c->dev-pins->default_state 中了。最后調(diào)用 pinctrl_select_state 來(lái)選擇是 “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。如果初始化過(guò)程出錯(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)都列出來(lá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腳沒(méi)有被其他模塊所使用。
Q2: 為什么我用IO指令讀出來(lái)的值都是0x00000000?
A2: 如果用IO命令讀某個(gè)GPIO的寄存器,讀出來(lái)的值異常,如 0x00000000或0xffffffff等,請(qǐng)確認(rèn)該GPIO的CLK是不是被關(guān)了,GPIO的CLK是由CRU控制,可以通過(guò)讀取datasheet下面CRU_CLKGATE_CON* 寄存器來(lái)查到CLK是否開啟,如果沒(méi)有開啟可以用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 來(lái)描述 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ù)。
通過(guò) 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ù)來(lái)進(jìn)行接受或者發(fā)送的時(shí)候,也是調(diào)用i2c_transfer()這個(gè)函數(shù)來(lái)處理一個(gè)消息結(jié)構(gòu)體(i2c_msg),而對(duì)于一些處理信息比較復(fù)雜的I2C設(shè)備,可以直接調(diào)用i2c_transfer()來(lái)處理信息,不過(guò)要自己構(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è)備無(wú)應(yīng)答響應(yīng),這種情況一般為外設(shè)的問(wèn)題,常見的有以下幾種情況:
-
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)容如下所示:
注:通過(guò) 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è)背光接口用來(lái)控制屏幕背光,如下圖所示:
主要有背光電源引腳以及控制亮度引腳,DTS:kernel/arch/arm64/boot/dts/rockchip/px30-firefly-aiojd4-lvds.dts配置如下
-
enable-gpios 屬性為背光的電源控制引腳。
-
pwms屬性:配置PWM,可用來(lái)改變輸出占空比(范例里面默認(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ì)過(guò)暗,所以默認(rèn)最大值為200。
-
default-brightness-level屬性:開機(jī)時(shí)默認(rèn)背光亮度,范圍為0-255。
具體請(qǐng)參考kernel中的說(shuō)明文檔:kernel/Documentation/devicetree/bindings/leds/backlight/pwm-backlight.txt
顯示時(shí)序配置
在kernel/arch/arm64/boot/dts/rockchip/px30-firefly-aiojd4-lvds.dts中可以看到以下語(yǔ)句:
時(shí)序?qū)傩詤⒖枷聢D:
lvds屏上完電后需要完成一些初始化的工作才可以工作。
u-boot 部分 ->u-boot/drivers/video/drm/rockchip-dw-mipi-dsi.c
詳細(xì)流程說(shuō)明可參考以下附件: Rockchip DRM Panel Porting Guide.pdf
AIO-PX30-JD4 開發(fā)板上有 2 個(gè) LED 燈,如下表所示:
以設(shè)備的方式控制 LED可通過(guò)使用 LED 設(shè)備子系統(tǒng)或者直接操作 GPIO 控制該 LED。
標(biāo)準(zhǔn)的 Linux 專門為 LED 設(shè)備定義了 LED 子系統(tǒng)。 在 AIO-PX30-JD4 開發(fā)板中的兩個(gè) LED 均以設(shè)備的形式被定義。
用戶可以通過(guò) /sys/class/leds/ 目錄控制這兩個(gè) LED。
開發(fā)板上的 LED 的默認(rèn)狀態(tài)為:
-
Blue: 系統(tǒng)上電時(shí)打開
-
Yellow:用戶自定義
用戶可以通過(guò) echo 向其 brightness屬性輸入命令控制每一個(gè) LED:
Trigger 包含多種方式可以控制LED,這里就用兩個(gè)例子來(lái)說(shuō)明
-
Simple trigger LED
-
Complex trigger LED
更詳細(xì)的說(shuō)明請(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ā)方式控制來(lái)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)沒(méi)有打開,如果需要的話可以使用以下補(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ā)板上的配置過(guò)程。
kernel/arch/arm64/boot/dts/rockchip/px30.dtsi:
與攝像頭相關(guān)的代碼目錄如下:
設(shè)置攝像頭相關(guān)的引腳和時(shí)鐘,即可完成配置過(guò)程。
從以下攝像頭接口原理圖可知,需要配置的引腳有: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 來(lái)注冊(cè)攝像頭:
-
嵌入式主板
+關(guān)注
關(guān)注
7文章
6086瀏覽量
35638 -
安卓
+關(guān)注
關(guān)注
5文章
2137瀏覽量
57637 -
Firefly
+關(guān)注
關(guān)注
2文章
538瀏覽量
7138
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論