dRonin  adbada4
dRonin firmware
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
pios_adc.c
Go to the documentation of this file.
1 
14 /*
15  * This program is free software; you can redistribute it and/or modify
16  * it under the terms of the GNU General Public License as published by
17  * the Free Software Foundation; either version 3 of the License, or
18  * (at your option) any later version.
19  *
20  * This program is distributed in the hope that it will be useful, but
21  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
22  * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
23  * for more details.
24  *
25  * You should have received a copy of the GNU General Public License along
26  * with this program; if not, see <http://www.gnu.org/licenses/>
27  */
28 
29 #include "pios.h"
30 #ifdef PIOS_INCLUDE_ADC
31 
32 // Private types
33 enum pios_adc_dev_magic {
34  PIOS_ADC_DEV_MAGIC = 0x58375169,
35 };
36 
37 struct pios_adc_dev {
38  enum pios_adc_dev_magic magic;
39  uintptr_t lower_id;
40  const struct pios_adc_driver *driver;
41 };
42 
43 struct pios_adc_dev * pios_adc_dev;
44 
45 // Private functions
46 static struct pios_adc_dev * PIOS_ADC_Allocate(void);
47 static bool PIOS_ADC_validate(struct pios_adc_dev *);
48 
49 #ifndef PIOS_ADC_SUB_DRIVER_MAX_INSTANCES
50 #define PIOS_ADC_SUB_DRIVER_MAX_INSTANCES 2
51 #endif
52 
53 /* Local Variables */
54 static struct sub_device_list_ {
55  uint8_t number_of_devices;
56  struct pios_adc_dev * sub_device_pointers[PIOS_ADC_SUB_DRIVER_MAX_INSTANCES];
57 } sub_device_list;
58 
64 static bool PIOS_ADC_validate(struct pios_adc_dev *dev)
65 {
66  if (dev == NULL)
67  return false;
68 
69  return (dev->magic == PIOS_ADC_DEV_MAGIC);
70 }
71 
77 static struct pios_adc_dev *PIOS_ADC_Allocate(void)
78 {
79  struct pios_adc_dev *adc_dev;
80 
81  adc_dev = (struct pios_adc_dev *)PIOS_malloc_no_dma(sizeof(*adc_dev));
82  if (!adc_dev)
83  return (NULL );
84 
85  adc_dev->magic = PIOS_ADC_DEV_MAGIC;
86  return (adc_dev);
87 }
88 
96 int32_t PIOS_ADC_Init(uintptr_t *adc_id, const struct pios_adc_driver *driver, uintptr_t lower_id)
97 {
98  PIOS_Assert(adc_id);
99  PIOS_Assert(driver);
100  if (sub_device_list.number_of_devices >= PIOS_ADC_SUB_DRIVER_MAX_INSTANCES)
101  return -1;
102  struct pios_adc_dev * adc_dev;
103 
104  adc_dev = (struct pios_adc_dev *) PIOS_ADC_Allocate();
105 
106  if (!adc_dev)
107  return -1;
108 
109  adc_dev->driver = driver;
110  adc_dev->lower_id = lower_id;
111  *adc_id = (uintptr_t) adc_dev;
112  sub_device_list.sub_device_pointers[sub_device_list.number_of_devices] = adc_dev;
113  sub_device_list.number_of_devices++;
114  return 0;
115 }
116 
126 int32_t PIOS_ADC_GetChannelRaw(uint32_t channel)
127 {
128  uint32_t offset = 0;
129  for (uint8_t x = 0; x < sub_device_list.number_of_devices; ++x) {
130  struct pios_adc_dev * adc_dev = sub_device_list.sub_device_pointers[x];
131  if (!PIOS_ADC_validate(adc_dev)) {
133  continue;
134  } else if (adc_dev->driver->number_of_channels) {
135  uint32_t num_channels_for_this_device = adc_dev->driver->number_of_channels(adc_dev->lower_id);
136  if (adc_dev->driver->get_pin && (channel < offset + num_channels_for_this_device)) {
137  return (adc_dev->driver->get_pin)(adc_dev->lower_id, channel - offset);
138  } else
139  offset += num_channels_for_this_device;
140  }
141  }
142  return -1;
143 }
144 
154 float PIOS_ADC_GetChannelVolt(uint32_t channel)
155 {
156  uint32_t offset = 0;
157  for (uint8_t x = 0; x < sub_device_list.number_of_devices; ++x) {
158  struct pios_adc_dev * adc_dev = sub_device_list.sub_device_pointers[x];
159  if (!PIOS_ADC_validate(adc_dev)) {
161  continue;
162  } else if (adc_dev->driver->number_of_channels) {
163  uint32_t num_channels_for_this_device = adc_dev->driver->number_of_channels(adc_dev->lower_id);
164  if (adc_dev->driver->get_pin && (channel < offset + num_channels_for_this_device)) {
165  return (float)((adc_dev->driver->get_pin)(adc_dev->lower_id, channel - offset)) * (float)(adc_dev->driver->lsb_voltage)(adc_dev->lower_id);
166  } else
167  offset += num_channels_for_this_device;
168  }
169  }
170  return -1;
171 }
172 #endif
173 
Main PiOS header to include all the compiled in PiOS options.
uintptr_t adc_id
Definition: main.c:51
#define PIOS_DEBUG_Assert(test)
Definition: pios_debug.h:51
void * PIOS_malloc_no_dma(size_t size)
Definition: pios_heap.c:166
uint16_t number_of_devices
Definition: bl_messages.h:76
uint32_t magic
float PIOS_ADC_GetChannelVolt(uint32_t channel)
uint32_t offset
Definition: uavtalk_priv.h:51
int32_t PIOS_ADC_GetChannelRaw(uint32_t channel)
int32_t PIOS_ADC_Init(uintptr_t *adc_id, const struct pios_adc_driver *driver, uintptr_t lower_id)
#define PIOS_Assert(test)
Definition: pios_debug.h:52
#define PIOS_ADC_SUB_DRIVER_MAX_INSTANCES
Definition: pios_board.h:220