In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-04-09 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Internet Technology >
Share
Shulou(Shulou.com)06/02 Report--
This article introduces FS4412 development board how to use Linux IIO driver framework to achieve ADC driver, the content is very detailed, interested friends can refer to, hope to be helpful to you.
1. Overview
The FS4412 development board has an ADC with 4 channels (0max 1max 2) and 10ax 12 bit precision, where:
1) ADCIN0: lead out in the core board
2) ADCIN1: lead out in the core board
3) ADCIN2: lead out in the core board
4) ADCIN3: VR1 potentiometer connected to the development board
This paper mainly introduces the simple implementation method of ADC based on IIO driver framework.
Configure the DTS nod
The DTS node of FS4412 ADC adds the following definition to the kernel/arch/arm/boot/dts/exynos4412-fs4412.dts file:
Adc: adc@12C60000 {compatible = "samsung,exynos-adc-fs4412"; reg =,; clocks =; clock-names = "adc"; # io-channel-cells =; io-channel-ranges Status = "okay";}; author driver
The driver source code of ADC is fs4412_adc.c
Define ADC channel
The list of available channels is defined in fs4412_adc.c:
# define ADC_CHANNEL (_ index, _ id) {\ .type = IIO_VOLTAGE,\ .indexed = 1,\ .channel = _ index,\ .address = _ index \ .info _ mask_separate = BIT (IIO_CHAN_INFO_RAW),\ .datasheet _ name = _ id,\} / * Channel information * / static const struct iio_chan_spec fs4412_adc_iio_channels [] = {ADC_CHANNEL (0, "adc0"), ADC_CHANNEL (1, "adc1"), ADC_CHANNEL (2 Adc2), ADC_CHANNEL (3, "adc3"),} The principle of collecting original data by ADC
According to the information provided in the official user manual of the Exynos4412 processor, the basic usage of ADC can be summarized as follows:
Initialization process
1) initialize ADC_CFG (0x0x10010118) [16] = 0 set ADC to normal mode 2) initialize ADCCON (0x126C0000) [16] = 1 use 12-bit ADC [14] = 1 allow frequency division [13:6] = 0xFF frequency division factor to control the operating frequency of ADC within 5MHz 3) Select input pin ADCMUX (0x126C001C) [3:0] = 0x03 Select AIN3 as input pin
Perform the acquisition conversion process
1) start conversion ADCCON (0x126C0000) [0] = 1 ADC start conversion 2) determine whether the conversion is complete ADCCON (0x126C0000) read [15] bit status = 1 indicates that the conversion is complete 3) read the conversion result ADCDAT (0x126C000C) read the conversion result of ADC
Calculate the collected voltage
Use the standard voltage to convert the value of the AD conversion to the voltage value required by the user. The calculation formula is as follows: Vref / (2 ^ n-1) = Vresult / raw Note:
Vref is the standard voltage n is the number of digits converted by AD Vresult is the acquisition voltage required by the user raw is the original data collected by AD
For example, if the standard voltage is 1.8 V and the number of bits collected by AD is 10 bits, and the original data collected by AD is 568, then: Vresult = (1800mv * 568) / 1023 * * the following driver test routine is the complete driver routine for reading ADC:
# include # include
MODULE_AUTHOR ("LvXin lvx_sy@farsight.com.cn"); MODULE_DESCRIPTION ("FS4412 ADC driver"); MODULE_LICENSE ("GPL v2")
# define CON (x) ((x) + 0x00) # define DLY (x) ((x) + 0x08) # define DATX (x) ((x) + 0x0C) # define INTCLR (x) ((x) + 0x18) # define MUX (x) ((x) + 0x1c)
# define CON_RES (1U regs); / * waiting for the conversion to be completed * / while ((readl (CON (info- > regs)) & (1regs)) & ADC_DATX_MASK;*val = info- > value;mutex_unlock (& indio_dev- > mlock); return IIO_VAL_INT
}
Static int fs4412_adc_reg_access (struct iio_dev * indio_dev, unsigned reg, unsigned writeval, unsigned * readval) {struct fs4412_adc * info = iio_priv (indio_dev)
If (readval = = NULL) return-EINVAL;*readval = readl (info- > regs + reg); return 0
}
/ * IIO information object * / static const struct iio_info fs4412_adc_iio_info = {.read _ raw = & exynos_read_raw, .debugfs _ reg_access = & fs4412_adc_reg_access, .driver _ module = THIS_MODULE,}
# define ADC_CHANNEL (_ index, _ id) {
.type = IIO_VOLTAGE
.indexed = 1
.channel = _ index
.address = _ index
.info _ mask_separate = BIT (IIO_CHAN_INFO_RAW)
.datasheet _ name = _ id
}
/ * Channel information * / static const struct iio_chan_spec fs4412_adc_iio_channels [] = {ADC_CHANNEL (0, "adc0"), ADC_CHANNEL (1, "adc1"), ADC_CHANNEL (2, "adc2"), ADC_CHANNEL (3, "adc3"),}
/ * ADC hardware initialization * / static void fs4412_adc_hw_init (struct fs4412_adc * info) {U32 con
/ * set pre-division value * / con = CON_PRSCLV (49) | CON_PRSCEN;/* 12-bit AD conversion * / con | = CON_RES;writel (con, CON (info- > regs))
}
/ * device matching function * / static int fs4412_adc_probe (struct platform_device * pdev) {struct fs4412_adc * info = NULL; struct device_node * np = pdev- > dev.of_node; struct iio_dev * indio_dev = NULL; struct resource * mem; int ret =-ENODEV
If (! np) return ret;/* dynamic request iio device * / indio_dev = devm_iio_device_alloc (& pdev- > dev, sizeof (struct fs4412_adc)); if (! indio_dev) {dev_err (& pdev- > dev, "failed allocating iio device\ n"); return-ENOMEM;} info = iio_priv (indio_dev); / * obtain ADC register address * / mem = platform_get_resource (pdev, IORESOURCE_MEM, 0) Info- > regs = devm_ioremap_resource (& pdev- > dev, mem); if (IS_ERR (info- > regs)) return PTR_ERR (info- > regs); / * set private data * / platform_set_drvdata (pdev, indio_dev); indio_dev- > name = dev_name (& pdev- > dev); indio_dev- > dev.parent = & pdev- > dev;indio_dev- > dev.of_node = pdev- > dev.of_node;indio_dev- > info = & fs4412_adc_iio_info Indio_dev- > modes = INDIO_DIRECT_MODE;indio_dev- > channels = fs4412_adc_iio_channels; / * Channel data * / indio_dev- > num_channels = MAX_CHANNELS;/* Registration iio device * / ret = iio_device_register (indio_dev); if (ret) return ret;/* ADC hardware initialization * / fs4412_adc_hw_init (info); return 0
}
/ * device removal * / static int fs4412_adc_remove (struct platform_device * pdev) {struct iio_dev * indio_dev = platform_get_drvdata (pdev)
/ * Log out of iio devices * / iio_device_unregister (indio_dev); return 0
}
/ * platform device object * / static struct platform_driver fs4412_adc_driver = {.probe = fs4412_adc_probe, .remove = fs4412_adc_remove, .driver = {.name = "exynos-adc", .owner = THIS_MODULE, .of _ match_table = fs4412_adc_match,},}
/ * platform device module * / module_platform_driver (fs4412_adc_driver)
Save the above source code as drivers/iio/adc/fs4412_adc.c, and add the following after drivers/iio/adc/Makefile:
Obj-$ (CONFIG_FS4412_ADC) + = fs4412_adc.o
Compile and burn the kernel. After startup, you can run the following command under the terminal to read the value of ADC3: while true
Do cat / sys/devices/126c0000.adc/iio:device0/in_voltage3_raw; sleep 1; done
In the process of data acquisition, rotating the knob of the potentiometer and changing the resistance voltage of the potentiometer will change the result of the conversion. On the FS4412 development board how to use the Linux IIO driver framework to achieve ADC driver sharing here, I hope that the above content can be of some help to you, can learn more knowledge. If you think the article is good, you can share it for more people to see.
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 0
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.