ADC 使用
簡介
AIO-3399C 開發板上的 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 轉換的傳感器設計。
AIO-3399C 只提供一路外接的ADC(ADC_IN0)給客戶使用。
下面以SAR-ADC使用ADC風扇為例子,介紹 ADC 的基本配置方法。
DTS配置
配置DTS節點
AIO-3399C SAR-ADC 的 DTS 節點在 kernel/arch/arm64/boot/dts/rockchip/rk3399.dtsi 文件中定義,如下所示:
saradc: saradc@ff100000 { compatible = “rockchip,rk3399-saradc”; reg = 《0x0 0xff100000 0x0 0x100》; interrupts = 《GIC_SPI 62 IRQ_TYPE_LEVEL_HIGH 0》; #io-channel-cells = 《1》; clocks = 《&cru SCLK_SARADC》, 《&cru PCLK_SARADC》; clock-names = “saradc”, “apb_pclk”; status = “disabled”; };
用戶首先需在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,在AIOC-3399中是不提供給客戶外部使用的,而且也沒有風扇接口,這里只是提供一個參考, 客戶可自行參考這個例子 運用SARADC通道0 去做自己的一些開發。
在驅動文件中匹配 DTS 節點
用戶驅動可參考Firefly adc demo :kernel/drivers/adc/adc-firefly-demo.c,這是一個偵測Firefly-rk3399風扇狀態的驅動。 首先在驅動文件中定義 of_device_id 結構體數組:
static const struct of_device_id firefly_adc_match[] = { { .compatible = “firefly,rk3399-adc” }, {}, };
然后將該結構體數組填充到要使用 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所添加的資源進行解析:
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; }
驅動說明
獲取 AD 通道
struct iio_channel *chan; //定義 IIO 通道結構體chan = iio_channel_get(&pdev-》dev, NULL); //獲取 IIO 通道結構體
注:iio_channel_get 通過 probe 函數傳進來的參數 pdev 獲取 IIO 通道結構體,probe 函數如下:
static int XXX_probe(struct platform_device *pdev);
讀取 AD 采集到的原始數據
int val,ret; ret = iio_read_channel_raw(chan, &val);
調用 iio_read_channel_raw 函數讀取 AD 采集的原始數據并存入 val 中。
計算采集到的電壓
使用標準電壓將 AD 轉換的值轉換為用戶所需要的電壓值。其計算公式如下:
Vref / (2^n-1) = Vresult / raw
注:
Vref 為標準電壓
n 為 AD 轉換的位數
Vresult 為用戶所需要的采集電壓
raw 為 AD 采集的原始數據
例如,標準電壓為 1.8V,AD 采集位數為 10 位,AD 采集到的原始數據為 568,則:
Vresult = (1800mv * 568) / 1023;
接口說明
struct iio_channel *iio_channel_get(struct device *dev, const char *consumer_channel);
功能:獲取 iio 通道描述
參數:
dev: 使用該通道的設備描述指針
consumer_channel: 該設備所使用的 IIO 通道描述指針
void iio_channel_release(struct iio_channel *chan);
功能:釋放 iio_channel_get 函數獲取到的通道
參數:
chan:要被釋放的通道描述指針
int iio_read_channel_raw(struct iio_channel *chan, int *val);
功能:讀取 chan 通道 AD 采集的原始數據。
參數:
chan:要讀取的采集通道指針
val:存放讀取結果的指針
調試方法
Demo程序使用
在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》; };
編譯內核,燒錄內核到Firefly-RK3399 開發板上,然后插拔風扇時,會打印內核log信息如下:
[ 85.158104] Fan insert! raw= 135 Voltage= 237mV [ 88.422124] Fan out! raw= 709 Voltage=1247mV
獲取所有ADC值
有個便捷的方法可以查詢到每個SARADC的值:
cat /sys/bus/iio/devices/iio\:device0/in_voltage*_raw
FAQs
為何按上面的步驟申請SARADC,會出現申請報錯的情況?
驅動需要獲取ADC通道來使用時,需要對驅動的加載時間進行控制,必須要在saradc初始化之后。saradc是使用module_platform_driver()進行平臺設備驅動注冊,最終調用的是module_init()。所以用戶的驅動加載函數只需使用比module_init()優先級低的,例如:late_initcall(),就能保證驅動的加載的時間比saradc初始化時間晚,可避免出錯。
-
嵌入式主板
+關注
關注
7文章
6085瀏覽量
35342 -
Firefly
+關注
關注
2文章
538瀏覽量
7046
發布評論請先 登錄
相關推薦
評論