Firefly-RK3399開發(fā)板上的 AD 接口有兩種,分別為:溫度傳感器 (Temperature Sensor)、逐次逼近ADC (Successive Approximation Register)。其中:
-
TS-ADC(Temperature Sensor):支持兩通道,時鐘頻率必須低于800KHZ
-
SAR-ADC(Successive Approximation Register):支持六通道單端10位的SAR-ADC,時鐘頻率必須小于13MHZ。
內(nèi)核采用工業(yè) I/O 子系統(tǒng)來控制 ADC,該子系統(tǒng)主要為 AD 轉(zhuǎn)換或者 DA 轉(zhuǎn)換的傳感器設(shè)計。 下面以SAR-ADC為例子,介紹 ADC 的基本配置方法。
Firefly-RK3399 SAR-ADC 的 DTS 節(jié)點在 kernel/arch/arm64/boot/dts/rockchip/rk3399.dtsi 文件中定義,如下所示:
用戶首先需在DTS文件中添加ADC的資源描述:
kernel/arch/arm64/boot/dts/rockchip/rk3399-firefly-demo.dtsi : adc_demo: adc_demo{ status = "disabled"; compatible = "firefly,rk3399-adc"; io-channels = <&saradc 3>; };
這里申請的是SARADC通道3.
用戶驅(qū)動可參考Firefly adc demo :kernel/drivers/adc/adc-firefly-demo.c,這是一個偵測Firefly-rk3399風(fēng)扇狀態(tài)的驅(qū)動。 首先在驅(qū)動文件中定義 of_device_id 結(jié)構(gòu)體數(shù)組:
static const struct of_device_id firefly_adc_match[] = { { .compatible = "firefly,rk3399-adc" }, {}, };
然后將該結(jié)構(gòu)體數(shù)組填充到要使用 ADC 的 platform_driver 中:
static struct platform_driver firefly_adc_driver = { .probe = firefly_adc_probe, .remove = firefly_adc_remove, .driver = { .name = "firefly_adc", .owner = THIS_MODULE, .of_match_table = firefly_adc_match, }, };
接著在firefly_adc_probe中對DTS所添加的資源進(jìn)行解析:
static int firefly_adc_probe(struct platform_device *pdev) { printk("firefly_adc_probe!\n"); chan = iio_channel_get(&(pdev->dev), NULL); if (IS_ERR(chan)) { chan = NULL; printk("%s() have not set adc chan\n", __FUNCTION__); return -1; } fan_insert = false; if (chan) { INIT_DELAYED_WORK(&adc_poll_work, firefly_demo_adc_poll); schedule_delayed_work(&adc_poll_work,1000);}return 0;}
struct iio_channel *chan; //定義 IIO 通道結(jié)構(gòu)體chan = iio_channel_get(&pdev->dev, NULL); //獲取 IIO 通道結(jié)構(gòu)體
注:iio_channel_get 通過 probe 函數(shù)傳進(jìn)來的參數(shù) pdev 獲取 IIO 通道結(jié)構(gòu)體,probe 函數(shù)如下:
static int XXX_probe(struct platform_device *pdev);
int val,ret; ret = iio_read_channel_raw(chan, &val);
調(diào)用 iio_read_channel_raw 函數(shù)讀取 AD 采集的原始數(shù)據(jù)并存入 val 中。
使用標(biāo)準(zhǔn)電壓將 AD 轉(zhuǎn)換的值轉(zhuǎn)換為用戶所需要的電壓值。其計算公式如下:
Vref / (2^n-1) = Vresult / raw
注:
-
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,則:
Vresult = (1800mv * 568) / 1023;
struct iio_channel *iio_channel_get(struct device *dev, const char *consumer_channel);
-
功能:獲取 iio 通道描述
-
參數(shù):
-
dev: 使用該通道的設(shè)備描述指針
-
consumer_channel: 該設(shè)備所使用的 IIO 通道描述指針
-
void iio_channel_release(struct iio_channel *chan);
-
功能:釋放 iio_channel_get 函數(shù)獲取到的通道
-
參數(shù):
-
chan:要被釋放的通道描述指針
-
int iio_read_channel_raw(struct iio_channel *chan, int *val);
-
功能:讀取 chan 通道 AD 采集的原始數(shù)據(jù)。
-
參數(shù):
-
chan:要讀取的采集通道指針
-
val:存放讀取結(jié)果的指針
-
在kernel/arch/arm64/boot/dts/rockchip/rk3399-firefly-demo.dtsi中使能adc_demo,將”disabled” 改為 “okay”:
adc_demo: adc_demo{ status = "okay"; compatible = "firefly,rk3399-adc"; io-channels = <&saradc 3>; };
編譯內(nèi)核,燒錄內(nèi)核到Firefly-RK3399 開發(fā)板上,然后插拔風(fēng)扇時,會打印內(nèi)核log信息如下:
[ 85.158104] Fan insert! raw= 135 Voltage= 237mV [ 88.422124] Fan out! raw= 709 Voltage=1247mV
有個便捷的方法可以查詢到每個SARADC的值:
cat /sys/bus/iio/devices/iio\:device0/in_voltage*_raw
驅(qū)動需要獲取ADC通道來使用時,需要對驅(qū)動的加載時間進(jìn)行控制,必須要在saradc初始化之后。saradc是使用module_platform_driver()進(jìn)行平臺設(shè)備驅(qū)動注冊,最終調(diào)用的是module_init()。所以用戶的驅(qū)動加載函數(shù)只需使用比module_init()優(yōu)先級低的,例如:late_initcall(),就能保證驅(qū)動的加載的時間比saradc初始化時間晚,可避免出錯。
-
嵌入式主板
+關(guān)注
關(guān)注
7文章
6084瀏覽量
35154 -
Firefly
+關(guān)注
關(guān)注
2文章
538瀏覽量
6963
發(fā)布評論請先 登錄
相關(guān)推薦
評論