ruuvi.drivers.c  ${PROJECT_VERSION}
Drivers for external sensors and peripherals on embedded systems.
ruuvi_interface_adc_photo.c
Go to the documentation of this file.
2 
3 #if (RI_ADC_PHOTO_ENABLED || DOXYGEN)
4 
5 #include "ruuvi_driver_error.h"
6 #include "ruuvi_driver_sensor.h"
10 
15 
26 #ifdef RI_ADC_PHOTO_CHANNEL
27 #define ADC_PHOTO_USE_CHANNEL RI_ADC_PHOTO_CHANNEL
28 #else
29 #define ADC_PHOTO_USE_CHANNEL 1
30 #endif
31 
32 #ifdef RI_ADC_PHOTO_DIVIDER
33 #define ADC_PHOTO_USE_DIVIDER RI_ADC_PHOTO_DIVIDER
34 #else
35 #define ADC_PHOTO_USE_DIVIDER 1.00f
36 #endif
37 
38 #ifdef RI_ADC_PHOTO_VDD
39 #define ADC_PHOTO_USE_VDD RI_ADC_PHOTO_VDD
40 #else
41 #define ADC_PHOTO_USE_VDD 3.60f
42 #endif
43 
44 #define ADC_PHOTO_DATA_COUNTER 1
45 #define ADC_PHOTO_DEFAULT_BITFIELD 0
46 #define ADC_PHOTO_ENABLE_BYTE 1
47 #define ADC_PHOTO_VOLTS_TO_LUX 1333.00f
48 
49 static ri_adc_pins_config_t adc_photo_pins_config =
50 {
52 #ifdef RI_ADC_ADV_CONFIG
53  .p_pin.resistor = RI_ADC_RESISTOR_DISABLED,
54 #endif
55 };
56 
57 static ri_adc_channel_config_t adc_photo_config =
58 {
60  .vref = RI_ADC_VREF_EXTERNAL,
61 #ifdef RI_ADC_ADV_CONFIG
62  .gain = RI_ADC_GAIN1_6,
63  .acqtime = RI_ADC_ACQTIME_10US,
64 #endif
65 };
66 
67 static ri_adc_get_data_t adc_photo_options =
68 {
70  .divider = ADC_PHOTO_USE_DIVIDER,
71 };
72 
73 static uint64_t m_tsample;
74 static bool m_autorefresh;
76 static bool m_is_init;
77 static const char m_sensor_name[] = "PHOTO";
78 
79 
80 static float volts_to_lux (const float * const data)
81 {
82  float result;
83  result = (float) (ADC_PHOTO_VOLTS_TO_LUX) * (*data);
84  return result;
85 }
86 
87 static rd_status_t get_data (void)
88 {
89  rd_status_t err_code = RD_SUCCESS;
90  float volts;
91  m_tsample = rd_sensor_timestamp_get();
92 
94  &adc_photo_options,
95  &volts))
96  {
97  m_luminosity = volts_to_lux (&volts);
98  }
99  else
100  {
101  err_code = RD_ERROR_INVALID_STATE;
102  }
103 
104  return err_code;
105 }
106 
108 {
109  uint8_t mode;
110  rd_status_t err_code = ri_adc_photo_mode_get (&mode);
111  return err_code | validate_default_input_set (samplerate, mode);
112 }
113 
115 {
116  uint8_t mode;
117  rd_status_t err_code = ri_adc_photo_mode_get (&mode);
118  return err_code | validate_default_input_set (resolution, mode);
119 }
120 
122 {
123  uint8_t mode;
124  rd_status_t err_code = ri_adc_photo_mode_get (&mode);
125  return err_code | validate_default_input_set (scale, mode);
126 }
127 
128 rd_status_t ri_adc_photo_dsp_set (uint8_t * dsp, uint8_t * parameter)
129 {
130  uint8_t mode;
131  rd_status_t err_code = ri_adc_photo_mode_get (&mode);
132  err_code |= validate_default_input_set (parameter, mode);
133 
134  if (RD_SUCCESS == err_code)
135  {
136  if (NULL == dsp)
137  {
138  err_code = RD_ERROR_NULL;
139  }
140  else
141  {
142  if (RD_SENSOR_DSP_LAST != (*dsp))
143  {
144  err_code = RD_ERROR_NOT_SUPPORTED;
145  }
146  }
147  }
148 
149  return RD_SUCCESS;
150 }
151 
152 rd_status_t ri_adc_photo_dsp_get (uint8_t * dsp, uint8_t * parameter)
153 {
154  uint8_t mode;
155  rd_status_t err_code = ri_adc_photo_mode_get (&mode);
156  err_code |= validate_default_input_get (dsp);
157  err_code |= validate_default_input_get (parameter);
158  return err_code;
159 }
160 
162  environmental_sensor, rd_bus_t bus, uint8_t handle)
163 {
164  rd_status_t err_code = RD_SUCCESS;
165 
166  if (NULL == environmental_sensor)
167  {
168  err_code = RD_ERROR_NULL;
169  }
170  else
171  {
172  if (m_is_init)
173  {
174  err_code = RD_ERROR_INVALID_STATE;
175  }
176  else
177  {
178  rd_sensor_initialize (environmental_sensor);
179  environmental_sensor->name = m_sensor_name;
180  err_code |= ri_adc_init (NULL);
181  adc_photo_pins_config.p_pin.channel = handle;
183  &adc_photo_pins_config,
184  &adc_photo_config);
185 
186  if (RD_SUCCESS == err_code)
187  {
188  environmental_sensor->init = ri_adc_photo_init;
189  environmental_sensor->uninit = ri_adc_photo_uninit;
190  environmental_sensor->samplerate_set = ri_adc_photo_samplerate_set;
191  environmental_sensor->samplerate_get = validate_default_input_get;
192  environmental_sensor->resolution_set = ri_adc_photo_resolution_set;
193  environmental_sensor->resolution_get = validate_default_input_get;
194  environmental_sensor->scale_set = ri_adc_photo_scale_set;
195  environmental_sensor->scale_get = validate_default_input_get;
196  environmental_sensor->dsp_set = ri_adc_photo_dsp_set;
197  environmental_sensor->dsp_get = ri_adc_photo_dsp_get;
198  environmental_sensor->mode_set = ri_adc_photo_mode_set;
199  environmental_sensor->mode_get = ri_adc_photo_mode_get;
200  environmental_sensor->data_get = ri_adc_photo_data_get;
201  environmental_sensor->configuration_set = rd_sensor_configuration_set;
202  environmental_sensor->configuration_get = rd_sensor_configuration_get;
203  environmental_sensor->provides.datas.luminosity = ADC_PHOTO_ENABLE_BYTE;
204  m_tsample = RD_UINT64_INVALID;
205  m_is_init = true;
206  }
207  }
208  }
209 
210  return err_code;
211 }
212 
214  rd_bus_t bus, uint8_t handle)
215 {
216  rd_status_t err_code = RD_SUCCESS;
217 
218  if (NULL == sensor)
219  {
220  err_code = RD_ERROR_NULL;
221  }
222  else
223  {
224  rd_sensor_uninitialize (sensor);
225  m_tsample = RD_UINT64_INVALID;
226  m_is_init = false;
227  m_autorefresh = false;
228  err_code |= ri_adc_stop (ADC_PHOTO_USE_CHANNEL);
229  }
230 
231  return err_code;
232 }
233 
235 {
236  rd_status_t err_code = RD_SUCCESS;
237 
238  if (NULL == mode)
239  {
240  err_code |= RD_ERROR_NULL;
241  }
242  else
243  {
244  if ( (RD_SENSOR_CFG_SLEEP == (*mode)) ||
245  (RD_SENSOR_CFG_DEFAULT == (*mode)))
246  {
247  m_autorefresh = false;
248  (*mode) = RD_SENSOR_CFG_SLEEP;
249  }
250  else if (RD_SENSOR_CFG_SINGLE == *mode)
251  {
252  uint8_t current_mode;
253  ri_adc_photo_mode_get (&current_mode);
254 
255  if (RD_SENSOR_CFG_CONTINUOUS == current_mode)
256  {
257  (*mode) = RD_SENSOR_CFG_CONTINUOUS;
258  err_code |= RD_ERROR_INVALID_STATE;
259  }
260  else
261  {
262  m_autorefresh = false;
263  (*mode) = RD_SENSOR_CFG_SLEEP;
264  err_code |= get_data();
265  }
266  }
267  else if (RD_SENSOR_CFG_CONTINUOUS == (*mode))
268  {
269  m_autorefresh = true;
270  }
271  else
272  {
273  err_code |= RD_ERROR_INVALID_PARAM;
274  }
275  }
276 
277  return err_code;
278 }
279 
281 {
282  rd_status_t err_code = RD_SUCCESS;
283 
284  if (NULL == mode)
285  {
286  err_code = RD_ERROR_NULL;
287  }
288  else
289  {
290  if (m_autorefresh)
291  {
292  (*mode) = RD_SENSOR_CFG_CONTINUOUS;
293  }
294 
295  if (!m_autorefresh)
296  {
297  (*mode) = RD_SENSOR_CFG_SLEEP;
298  }
299  }
300 
301  return err_code;
302 }
303 
305  p_data)
306 {
307  rd_status_t err_code = RD_SUCCESS;
308 
309  if (NULL == p_data)
310  {
311  err_code = RD_ERROR_NULL;
312  }
313  else
314  {
315  if (m_autorefresh)
316  {
317  err_code = get_data();
318  }
319 
320  if ( (RD_SUCCESS == err_code) &&
321  (RD_UINT64_INVALID != m_tsample))
322  {
323  rd_sensor_data_t d_environmental;
325  float env_values;
326  env_values = m_luminosity;
328  d_environmental.data = &env_values;
329  d_environmental.valid = env_fields;
330  d_environmental.fields = env_fields;
331  rd_sensor_data_populate (p_data,
332  &d_environmental,
333  p_data->fields);
334  p_data->timestamp_ms = m_tsample;
335  }
336  }
337 
338  return err_code;
339 }
340 
341 #endif
#define RD_ERROR_INVALID_PARAM
Invalid Parameter.
#define RD_ERROR_NULL
Null Pointer.
uint32_t rd_status_t
bitfield for representing errors
#define RD_ERROR_NOT_SUPPORTED
Not supported.
#define RD_SUCCESS
Internal Error.
#define RD_UINT64_INVALID
Signal that value should not be used.
#define RD_ERROR_INVALID_STATE
Invalid state, operation disallowed in this state.
#define RD_SENSOR_DSP_LAST
Return last value from sensor. Parameter: No effect. Use default.
#define RD_SENSOR_CFG_SLEEP
Sensor should go to sleep immediately.
#define RD_SENSOR_CFG_DEFAULT
Default value, always valid for the sensor.
void rd_sensor_uninitialize(rd_sensor_t *const p_sensor)
Mark sensor as uninitialized by calling the generic initialization. Will not clear the name of the se...
rd_status_t rd_sensor_configuration_get(const rd_sensor_t *sensor, rd_sensor_configuration_t *config)
Implementation of ref rd_configuration_fp.
void rd_sensor_initialize(rd_sensor_t *const p_sensor)
Initialize sensor struct with non-null pointers which return RD_ERROR_NOT_INITIALIZED.
rd_status_t validate_default_input_set(uint8_t *const input, const uint8_t mode)
Validate that given setting can be set on a sensor which supports only default value.
void rd_sensor_data_populate(rd_sensor_data_t *const target, const rd_sensor_data_t *const provided, const rd_sensor_data_fields_t requested)
Populate given target data with data provided by sensor as requested.
rd_status_t rd_sensor_configuration_set(const rd_sensor_t *sensor, rd_sensor_configuration_t *config)
Implementation of ref rd_configuration_fp.
#define RD_SENSOR_CFG_CONTINUOUS
Sensor will keep sampling at defined sample rate.
rd_bus_t
Type of bus sensor uses.
uint64_t rd_sensor_timestamp_get(void)
Calls the timestamp function and returns its value.
rd_status_t validate_default_input_get(uint8_t *const input)
Validate and get input when only allowed value is default.
#define RD_SENSOR_CFG_SINGLE
Sensor should go to sleep after single measurement.
Header to enable and disable module compilation.
Ruuvi error codes and error check function.
Ruuvi sensor interface Lifecycle: Beta
Interface for controlling ADC onboard MCU.
@ RI_ADC_MODE_SINGLE
Single ended mode.
@ RI_ADC_VREF_EXTERNAL
External voltage reference.
rd_status_t ri_adc_get_data_absolute(uint8_t channel_num, ri_adc_get_data_t *p_config, float *p_data)
Get ADC data in volts.
@ RI_ADC_GND
GND of device.
rd_status_t ri_adc_stop(uint8_t channel_num)
Stop use ADC channel.
rd_status_t ri_adc_configure(uint8_t channel_num, ri_adc_pins_config_t *p_pins, ri_adc_channel_config_t *p_config)
Configure ADC channel.
rd_status_t ri_adc_init(ri_adc_config_t *p_config)
Initialization of ADC.
rd_status_t ri_adc_photo_scale_set(uint8_t *scale)
rd_sensor_setup_fp
rd_status_t ri_adc_photo_mode_get(uint8_t *mode)
rd_sensor_setup_fp
rd_status_t ri_adc_photo_dsp_set(uint8_t *dsp, uint8_t *parameter)
rd_sensor_dsp_fp
#define ADC_PHOTO_USE_VDD
rd_status_t ri_adc_photo_init(rd_sensor_t *environmental_sensor, rd_bus_t bus, uint8_t handle)
rd_sensor_init_fp
rd_status_t ri_adc_photo_dsp_get(uint8_t *dsp, uint8_t *parameter)
rd_sensor_dsp_fp
#define ADC_PHOTO_VOLTS_TO_LUX
#define ADC_PHOTO_ENABLE_BYTE
float m_luminosity
#define ADC_PHOTO_USE_DIVIDER
rd_status_t ri_adc_photo_samplerate_set(uint8_t *samplerate)
rd_sensor_setup_fp
#define ADC_PHOTO_DEFAULT_BITFIELD
rd_status_t ri_adc_photo_resolution_set(uint8_t *resolution)
rd_sensor_setup_fp
rd_status_t ri_adc_photo_data_get(rd_sensor_data_t *const p_data)
rd_sensor_data_fp
#define ADC_PHOTO_USE_CHANNEL
#define ADC_PHOTO_DATA_COUNTER
rd_status_t ri_adc_photo_uninit(rd_sensor_t *sensor, rd_bus_t bus, uint8_t handle)
rd_sensor_init_fp
rd_status_t ri_adc_photo_mode_set(uint8_t *mode)
rd_sensor_setup_fp
unsigned int luminosity
Light level, dimensionless. Comparable only between identical devices.
Generic sensor data struct.
float * data
Data of sensor. Must contain as many elements as fields has bits set.
uint64_t timestamp_ms
Timestamp of the event, rd_sensor_timestamp_get.
rd_sensor_data_fields_t valid
Listing of valid data in this sample.
rd_sensor_data_fields_t fields
Description of datafields which may be contained in this sample.
Interface to sensor. Some sensors can implement additional functions. The additional functions are de...
rd_sensor_data_fp data_get
rd_sensor_data_fp
rd_configuration_fp configuration_set
rd_configuration_fp
rd_sensor_setup_fp samplerate_get
rd_sensor_setup_fp
rd_sensor_setup_fp resolution_get
rd_sensor_setup_fp
rd_sensor_init_fp uninit
rd_sensor_init_fp
rd_configuration_fp configuration_get
rd_configuration_fp
rd_sensor_dsp_fp dsp_get
rd_sensor_dsp_fp
rd_sensor_data_fields_t provides
Description of data fields the sensor is able to provide.
rd_sensor_dsp_fp dsp_set
rd_sensor_dsp_fp
rd_sensor_setup_fp mode_set
rd_sensor_setup_fp
const char * name
Sensor human-readable name. Should be at most 8 bytes long.
rd_sensor_setup_fp mode_get
rd_sensor_setup_fp
rd_sensor_setup_fp samplerate_set
rd_sensor_setup_fp
rd_sensor_init_fp init
rd_sensor_init_fp
rd_sensor_setup_fp scale_set
rd_sensor_setup_fp
rd_sensor_setup_fp resolution_set
rd_sensor_setup_fp
rd_sensor_setup_fp scale_get
rd_sensor_setup_fp
Union to access sensor data.
uint32_t bitfield
Bitfield used to access sensor data.
rd_sensor_data_bitfield_t datas
Structured data field.