ADC(Analog-to-Digital Converter),顾名思义就是模数转换器。i.MX6ULL有两组12位ADC,ADC1和ADC2,每一组ADC有10路输入引脚(ADC1和ADC2共同复用这10路,所以实际一共10路ADC)。ELF 1只用了一个ADC1引脚连接到可变电阻上,用来演示ADC功能。
硬件原理
使用的是ADC1_IN5,对应的PAD NAME是GPIO1_IO05。
IOMUX配置
在iomuxc节点下添加子节点:
pinctrl_adc1: adc1grp { fsl,pins = < MX6UL_PAD_GPIO1_IO05__GPIO1_IO05 0x00b0 >; }; |
添加设备节点
在arch/arm/boot/dts/imx6ull.dtsi文件中已经存在adc1节点:
在compatible属性中有两个驱动匹配项,"fsl,imx6ul-adc","fsl,vf610-adc",实际上在我们的内核源码中没有"fsl,imx6ul-adc"对应驱动,所以我们使用的是"fsl,vf610-adc"驱动。
reg是ADC1对应的一些寄存器的起始地址和这些寄存器所占用的长度;
interrupts = <GIC_SPI 100 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clks IMX6UL_CLK_ADC1>:开启时钟
num-channels = <2>:开启ADC的通道,这里默认设置的是开启ADC1_IN0和ADC1_IN1。
clock-names = "adc":时钟名称。
status = disable:默认是关闭状态。
我们需要在arch/arm/boot/dts/imx6ull-elf1-emmc.dts中,增加和修改adc1节点配置:
&adc1 { pinctrl-names = "default"; pinctrl-0 = <&pinctrl_adc1>; num-channels = <6>; vref-supply = <®_adc1_vref>; status = "okay"; }; |
num-channels = <6>:因为我们使用的是ADC1_IN5,所以,需要开启6路ADC通道。
vref-supply = <®_adc1_vref>;adc的参考电压,引用了reg_adc1_vref节点,我们还需要在regulators节点下添加reg_adc1_vref子节点:
reg_adc1_vref: regulator@2 { compatible = "regulator-fixed"; regulator-name = "vref-3v3"; regulator-min-microvolt = <3300000>; regulator-max-microvolt = <3300000>; }; |
添加驱动
使用make menuconfig打开图形化配置界面:
elf@ubuntu:~/work/linux-imx-imx_4.1.15_2.0.0_ga$ make menuconfig |
在Device Drivers菜单下添加:
Device Drivers -> Industrial I/O support -> Analog to digital converters |
路径下添加vf610驱动:
替换配置文件
通过make menuconfig修改的内容写入到了.config文件,当使用make imx6ull_elf1_defconfig配置内核源码时,.config文件会被覆盖,因此,需要替换原有的imx6ull_elf1_defconfig。
elf@ubuntu:~/work/linux-imx-imx_4.1.15_2.0.0_ga$ cp .config arch/arm/configs/imx6ull_elf1_defconfig |
编译测试
编译内核和设备树并拷贝到开发板:
elf@ubuntu:~/work/linux-imx-imx_4.1.15_2.0.0_ga$ ./build.sh elf@ubuntu:~/work/linux-imx-imx_4.1.15_2.0.0_ga$ scp arch/arm/boot/zImage root@172.16.0.175:/run/media/mmcblk1p1/ elf@ubuntu:~/work/linux-imx-imx_4.1.15_2.0.0_ga$ scp arch/arm/boot/dts/imx6ull-elf1-emmc.dtb root@172.16.0.175:/run/media/mmcblk1p1/ |
进行sync操作后重启开发板:
在/sys/bus/iio/devices/iio:device0下发现in_voltage5_raw:
root@ELF1:~# ls /sys/bus/iio/devices/iio:device0 |
使用cat in_voltage5_raw查看ADC1_IN5的值:
root@ELF1:~# cat /sys/bus/iio/devices/iio:device0/in_voltage5_raw 950 |
调节可变电阻,可观察该值的变化,因为ADC为12位精度,所以该值的范围为0~4095。