rk3288 ADC調式

tt7643066發表於2019-09-14

sunychip-RK3288 開發板上的 AD 介面分為:高速 ADC 流介面 (High-speed ADC Stream Interface)、溫度感測器 (Temperature Sensor)、 逐次逼近ADC (Successive Approximation Register)。本文主要介紹 ADC 的基本配置方法。核心採用工業 I/O 子系統來控制 ADC, 該子系統主要為 AD 轉換或者 DA 轉換的感測器設計。其相關資料結構以及配置方法如下:

資料結構

  • iio_channel 結構體
struct iio_channel {
    struct iio_dev *indio_dev;//工業 I/O裝置
    const struct iio_chan_spec *channel;//I/O通道
    void *data;};
  • iio_dev 結構體 該結構體主要用於描述 IO 口所屬的裝置,其具體定義如下:
struct iio_dev {
    int             id;
    int             modes;
    int             currentmode;
    struct device           dev;
    struct iio_event_interface  *event_interface;
    struct iio_buffer       *buffer;
    struct list_head        buffer_list;
    int             scan_bytes;
    struct mutex            mlock;
    const unsigned long     *available_scan_masks;
    unsigned            masklength;
    const unsigned long     *active_scan_mask;
    bool                scan_timestamp;
    unsigned            scan_index_timestamp;
    struct iio_trigger      *trig;
    struct iio_poll_func        *pollfunc;
    struct iio_chan_spec const  *channels;
    int             num_channels;
    struct list_head        channel_attr_list;
    struct attribute_group      chan_attr_group;
    const char          *name;
    const struct iio_info       *info;
    struct mutex            info_exist_lock;
    const struct iio_buffer_setup_ops   *setup_ops;
    struct cdev         chrdev;
    #define IIO_MAX_GROUPS 6
    const struct attribute_group    *groups[IIO_MAX_GROUPS + 1];
    int             groupcounter;
    unsigned long           flags;
    #if defined(CONFIG_DEBUG_FS)
    struct dentry           *debugfs_dentry;
    unsigned            cached_reg_addr;
    #endif};
  • iio_chan_spec結構體
struct iio_chan_spec {
    enum iio_chan_type  type; //描述通道型別
    int  channel; //通道號
    int  channel2; //通道號
    unsigned long  address; //通道地址
    int  scan_index;
    struct {
        char    sign;
        u8  realbits;
        u8  storagebits;
        u8  shift;
        enum iio_endian endianness;
    } scan_type;
    long            info_mask;
    long            info_mask_separate;
    long            info_mask_shared_by_type;
    long            event_mask;
    const struct iio_chan_spec_ext_info *ext_info;
    const char      *extend_name;
    const char      *datasheet_name;
    unsigned        modified:1;
    unsigned        indexed:1;
    unsigned        output:1;
    unsigned        differential:1;};

配置步驟

配置DTS節點

 ADC的 DTS 節點在 kernel/arch/arm/boot/dts/rk3288.dtsi 檔案中定義,如下所示:

adc: adc@ff100000 {
     compatible = "rockchip,saradc";
     reg = <0xff100000 0x100>;
     interrupts = <GIC_SPI 36 IRQ_TYPE_LEVEL_HIGH>;
     #io-channel-cells = <1>;
     io-channel-ranges;rockchip,adc-vref = <1800>;
     clock-frequency = <1000000>;
     clocks = <&clk_saradc>, <&clk_gates7 1>;
     clock-names = "saradc", "pclk_saradc";
     status = "disabled";
 };

使用者只需在 firefly-rk3288.dts 檔案中新增通道定義,並將其 status 改為 “okay” 即可:

&adc {
    status = "okay";
    adc_test{
        compatible = "rockchip,adc_test";
        io-channels = <&adc 0>;
    };};

在驅動檔案中匹配 DTS 節點

在驅動檔案中定義 of_device_id 結構體陣列:

static const struct of_device_id of_XXX_match[] = { 
    { .compatible = "rockchip,adc_test" },
    { /* Sentinel */ }};

將該結構體陣列填充到要使用 ADC 的 platform_driver 中。

static struct platform_driver XXX_driver = { 
    .probe      = ...,
    .remove     = ...,
    .driver     = { 
        .name   = "..",
        .owner  = THIS_MODULE,
    #ifdef CONFIG_OF
        .of_match_table = of_XXX_match,
    #endif
    },  };

獲取 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;

ADC 常用函式介面

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:存放讀取結果的指標


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/69948385/viewspace-2657000/,如需轉載,請註明出處,否則將追究法律責任。

相關文章