source: rtems/cpukit/dev/i2c/ti-ads-16bit-adc.c

Last change on this file was 80cf60e, checked in by Sebastian Huber <sebastian.huber@…>, on 04/15/20 at 07:48:32

Canonicalize config.h include

Use the following variant which was already used by most source files:

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

  • Property mode set to 100644
File size: 6.3 KB
Line 
1/*
2 * Copyright (c) 2016-2016 Chris Johns <chrisj@rtems.org>
3 * All rights reserved.
4 *
5 * The license and distribution terms for this file may be
6 * found in the file LICENSE in this distribution or at
7 * http://www.rtems.org/license/LICENSE.
8 */
9
10#ifdef HAVE_CONFIG_H
11#include "config.h"
12#endif
13
14#include <unistd.h>
15
16#include <dev/i2c/i2c.h>
17#include <dev/i2c/ti-ads-16bit-adc.h>
18
19/*
20 * Registers.
21 */
22#define ADS_CONVERSION (0)
23#define ADS_CONFIG     (1)
24#define ADS_LO_THRESH  (2)
25#define ADS_HI_THRESH  (3)
26
27/*
28 * Configuration register.
29 */
30#define CFG_OS_NOT_CONVERTING     (1 << 15)   /* read */
31#define CFG_OS_START_SSHOT        (1 << 15)   /* write */
32#define CFG_MUX_BASE              (12)
33#define CFG_MUX_MASK              (7)
34#define CFG_PGA_BASE              (9)
35#define CFG_PGA_MASK              (7)
36#define CFG_MODE_BASE             (8)
37#define CFG_MODE_MASK             (1)
38#define CFG_DATA_RATE_BASE        (5)
39#define CFG_DATA_RATE_MASK        (7)
40#define CFG_COMP_BASE             (0)
41#define CFG_COMP_MASK             (0x1f)
42#define CFG_COMP_MODE_ACTIVE_LOW  (0 << 4)
43#define CFG_COMP_MODE_ACTIVE_HIGH (1 << 4)
44
45#define CFG_MODE_CONT             (0 << CFG_MODE_BASE)
46#define CFG_MODE_SSHOT            (1 << CFG_MODE_BASE)
47
48typedef struct {
49  i2c_dev    base;
50  ti_ads_adc device;
51  uint32_t   poll_wait_period;
52  int        reg;
53  uint16_t   config_shadow;
54} ti_ads;
55
56static int
57ti_ads_reg_write(ti_ads* dev, int reg, uint16_t value)
58{
59  uint8_t out[3];
60  i2c_msg msgs[1] = {
61    {
62      .addr = dev->base.address,
63      .flags = 0,
64      .len = (uint16_t) sizeof(out),
65      .buf = &out[0]
66    }
67  };
68  out[0] = (uint8_t) reg;
69  out[1] = (uint8_t) (value >> 8);
70  out[2] = (uint8_t) value;
71  return i2c_bus_transfer(dev->base.bus, &msgs[0], RTEMS_ARRAY_SIZE(msgs));
72}
73
74static int
75ti_ads_reg_read(ti_ads* dev, int reg, uint16_t* value)
76{
77  uint8_t in[2] = { 0, 0 };
78  uint8_t out[1] = { (uint8_t) reg };
79  i2c_msg msgs[2] = {
80    {
81      .addr = dev->base.address,
82      .flags = 0,
83      .len = (uint16_t) sizeof(out),
84      .buf = &out[0]
85    }, {
86      .addr = dev->base.address,
87      .flags = I2C_M_RD,
88      .len = (uint16_t) sizeof(in),
89      .buf = &in[0]
90    }
91  };
92  int err;
93  err = i2c_bus_transfer(dev->base.bus, &msgs[0], RTEMS_ARRAY_SIZE(msgs));
94  *value = (((uint16_t) in[0]) << 8) | in[1];
95  return err;
96}
97
98static int
99ti_ads_set_config(ti_ads* dev, uint16_t value, int base, uint16_t mask)
100{
101  int err;
102  dev->config_shadow &= ~(mask << base);
103  dev->config_shadow |= (value & mask) << base;
104  err = ti_ads_reg_write(dev, ADS_CONFIG, dev->config_shadow);
105  return err;
106}
107
108static int
109ti_ads_sample(ti_ads* dev, uint16_t* value)
110{
111  int err;
112  if ((dev->config_shadow & CFG_MODE_SSHOT) == CFG_MODE_SSHOT) {
113    i2c_bus_obtain(dev->base.bus);
114    err = ti_ads_reg_write(dev,
115                           ADS_CONFIG,
116                           dev->config_shadow | CFG_OS_START_SSHOT);
117    if (err == 0) {
118      uint16_t config = 0;
119      while (err == 0 && (config & CFG_OS_NOT_CONVERTING) == 0) {
120        err = ti_ads_reg_read(dev, ADS_CONFIG, &config);
121        if (dev->poll_wait_period && (config & CFG_OS_NOT_CONVERTING) == 0)
122          usleep(dev->poll_wait_period);
123      }
124      err = ti_ads_reg_read(dev, ADS_CONVERSION, value);
125    }
126    i2c_bus_release(dev->base.bus);
127  }
128  else {
129    err = ti_ads_reg_read(dev, ADS_CONVERSION, value);
130  }
131  return err;
132}
133
134static int
135ti_ads_ioctl(i2c_dev* iic_dev, ioctl_command_t command, void* arg)
136{
137  ti_ads*  dev = (ti_ads*) iic_dev;
138  uint16_t value;
139  int      err;
140
141  switch (command) {
142    case TI_ADS_ADC_GET_CONVERSION:
143      value = 0;
144      err = ti_ads_sample(dev, &value);
145      if (err == 0)
146        *((uint16_t*) arg) = value;
147      break;
148    case TI_ADS_ADC_SET_MUX:
149      if (dev->device == TI_ADS1115) {
150        value = (uint16_t)(uintptr_t) arg;
151        err = ti_ads_set_config(dev, value, CFG_MUX_BASE, CFG_MUX_MASK);
152      }
153      else {
154        err = -ENOTTY;
155      }
156      break;
157    case TI_ADS_ADC_SET_MODE:
158      value = (uint16_t)(uintptr_t) arg;
159      err = ti_ads_set_config(dev, value, CFG_MODE_BASE, CFG_MODE_MASK);
160      break;
161    case TI_ADS_ADC_SET_PGA:
162      if (dev->device == TI_ADS1114 || dev->device == TI_ADS1115) {
163        value = (uint16_t)(uintptr_t) arg;
164        err = ti_ads_set_config(dev, value, CFG_PGA_BASE, CFG_PGA_MASK);
165      }
166      else {
167        err = -ENOTTY;
168      }
169      break;
170    case TI_ADS_ADC_SET_COMP:
171      if (dev->device == TI_ADS1114 || dev->device == TI_ADS1115) {
172        value = (uint16_t)(uintptr_t) arg;
173        err = ti_ads_set_config(dev, value, CFG_COMP_BASE, CFG_COMP_MASK);
174      }
175      else {
176        err = -ENOTTY;
177      }
178      break;
179    case TI_ADS_ADC_SET_LO_THRESH:
180      value = (uint16_t)(uintptr_t) arg;
181      err = ti_ads_reg_write(dev, ADS_LO_THRESH, value);
182      break;
183    case TI_ADS_ADC_SET_HI_THRESH:
184      value = (uint16_t)(uintptr_t) arg;
185      err = ti_ads_reg_write(dev, ADS_HI_THRESH, value);
186      break;
187    case TI_ADS_ADC_SET_CONV_WAIT:
188      dev->poll_wait_period = (uint32_t)(uintptr_t) arg;
189      err = 0;
190      break;
191    default:
192      err = -ENOTTY;
193      break;
194  }
195
196  return err;
197}
198
199int
200i2c_dev_register_ti_ads_adc(const char* bus_path,
201                            const char* dev_path,
202                            uint16_t    address,
203                            ti_ads_adc  device)
204{
205  ti_ads* dev;
206
207  dev = (ti_ads*)
208    i2c_dev_alloc_and_init(sizeof(*dev), bus_path, address);
209  if (dev == NULL) {
210    return -1;
211  }
212
213  dev->base.ioctl = ti_ads_ioctl;
214  dev->device = device;
215  dev->config_shadow = 0;
216
217  switch (device) {
218    default:
219      errno = EIO;
220      return -1;
221    case TI_ADS1115:
222      dev->config_shadow |= ((TI_ADS_MUX_ApA0_AnA1 << CFG_MUX_BASE) |
223                             (TI_ADS_PGA_FS_2_048V << CFG_PGA_BASE) |
224                             ((TI_ADS_COMP_MODE_HYSTERESIS |
225                               TI_ADS_COMP_POL_ACTIVE_LOW |
226                               TI_ADS_COMP_LAT_NON_LATCHING |
227                               TI_ADS_COMP_QUE_DISABLE_COMP) << CFG_COMP_BASE));
228      /* FALLTHRU */
229    case TI_ADS1114:
230      dev->config_shadow |= TI_ADS_PGA_FS_2_048V << CFG_PGA_BASE;
231      /* FALLTHRU */
232    case TI_ADS1113:
233      dev->config_shadow |= (CFG_MODE_SSHOT |
234                             (TI_ADS_DATARATE_8SPS  << CFG_DATA_RATE_BASE));
235      break;
236  }
237
238  return i2c_dev_register(&dev->base, dev_path);
239}
Note: See TracBrowser for help on using the repository browser.