dRonin  adbada4
dRonin firmware
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
pios_sensors.c
Go to the documentation of this file.
1 
15 /*
16  * This program is free software; you can redistribute it and/or modify
17  * it under the terms of the GNU General Public License as published by
18  * the Free Software Foundation; either version 3 of the License, or
19  * (at your option) any later version.
20  *
21  * This program is distributed in the hope that it will be useful, but
22  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
23  * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
24  * for more details.
25  *
26  * You should have received a copy of the GNU General Public License along
27  * with this program; if not, see <http://www.gnu.org/licenses/>
28  */
29 
30 #include "pios_sensors.h"
31 #include <stddef.h>
32 #include <pios_thread.h>
33 
34 #ifdef FLIGHT_POSIX
35 #include <unistd.h>
36 #endif
37 
39 static struct PIOS_Sensor {
41  void *getdata_ctx;
42 
43  uint32_t next_time;
44 
45  uint16_t sample_rate;
46  uint16_t missing : 1;
48 
49 static int32_t max_gyro_rate;
50 
52 {
53  /* sensors array is on BSS and pre-zero'd */
54 
55  return 0;
56 }
57 
58 static bool PIOS_SENSORS_QueueCallback(void *ctx, void *buf,
59  int ms_to_wait, int *next_call)
60 {
61  struct pios_queue *q = ctx;
62 
63  *next_call = 0; /* May immediately have data on next call */
64 
65  return PIOS_Queue_Receive(q, buf, ms_to_wait);
66 }
67 
69  PIOS_SENSOR_Callback_t callback, void *ctx)
70 {
72 
73  struct PIOS_Sensor *sensor = &sensors[type];
74 
75  sensor->getdata_ctx = ctx;
76  sensor->getdata_cb = callback;
77  sensor->missing = 0;
78 
79  return 0;
80 }
81 
83 {
86 }
87 
89 {
90  if (type >= PIOS_SENSOR_NUM) {
91  return false;
92  }
93 
94  struct PIOS_Sensor *sensor = &sensors[type];
95 
96  if (sensor->missing) {
97  return false;
98  }
99 
100  return sensor->getdata_cb != NULL;
101 }
102 
103 bool PIOS_SENSORS_GetData(enum pios_sensor_type type, void *buf, int ms_to_wait)
104 {
105  if (type >= PIOS_SENSOR_NUM) {
106  return false;
107  }
108 
109  struct PIOS_Sensor *sensor = &sensors[type];
110 
111  if (!sensor->getdata_cb) {
112  return false;
113  }
114 
115  if (sensor->next_time) {
116  uint32_t now = PIOS_Thread_Systime();
117  int32_t time_until = sensor->next_time - now;
118 
119  if (time_until > ms_to_wait) {
120  return false;
121  }
122 
123  if (time_until > 0) {
124 #ifdef FLIGHT_POSIX
126  while (!PIOS_Thread_Period_Elapsed(now,
127  time_until)) {
128  usleep(1000);
129  PIOS_Thread_FakeClock_Tick();
130  }
131  } else {
132  PIOS_Thread_Sleep(time_until);
133  }
134 #else
135  PIOS_Thread_Sleep(time_until);
136 #endif
137  }
138 
139  /* TODO: could use elapsed time to properly adjust */
140  ms_to_wait -= time_until;
141  }
142 
143  int next_time;
144 
145  bool ret = sensor->getdata_cb(sensor->getdata_ctx, buf, ms_to_wait,
146  &next_time);
147 
148  /* Keep track of next time it *could* have data. Ensure we
149  * don't call before then.
150  */
151  if (next_time) {
152  uint32_t now = PIOS_Thread_Systime();
153 
154  sensor->next_time = now + next_time;
155  } else {
156  sensor->next_time = 0;
157  }
158 
159  return ret;
160 }
161 
163 {
165 }
166 
168 {
169  return max_gyro_rate;
170 }
171 
173 {
175 
176  struct PIOS_Sensor *sensor = &sensors[type];
177 
178  sensor->sample_rate = sample_rate;
179 }
180 
182 {
183  if (type >= PIOS_SENSOR_NUM)
184  return 0;
185 
186  struct PIOS_Sensor *sensor = &sensors[type];
187 
188  return sensor->sample_rate;
189 }
190 
192 {
194 
195  struct PIOS_Sensor *sensor = &sensors[type];
196 
197  sensor->missing = true;
198 }
199 
201 {
203 
204  struct PIOS_Sensor *sensor = &sensors[type];
205 
206  return sensor->missing;
207 }
uint32_t PIOS_Thread_Systime(void)
Definition: pios_thread.c:212
void PIOS_SENSORS_SetMaxGyro(int32_t rate)
Set the maximum gyro rate in deg/s.
Definition: pios_sensors.c:162
uint16_t missing
Definition: pios_sensors.c:46
uint16_t sample_rate
Definition: pios_sensors.c:45
int32_t PIOS_SENSORS_GetMaxGyro()
Get the maximum gyro rate in deg/s.
Definition: pios_sensors.c:167
The list of queue handles / callbacks.
Definition: pios_sensors.c:39
bool PIOS_Queue_Receive(struct pios_queue *queuep, void *itemp, uint32_t timeout_ms)
Definition: pios_queue.c:213
uint32_t PIOS_SENSORS_GetSampleRate(enum pios_sensor_type type)
Get the sample rate of a sensor (Hz)
Definition: pios_sensors.c:181
uint16_t sensor
Definition: msp_messages.h:98
pios_sensor_type
The types of sensors this module supports.
Definition: pios_sensors.h:85
bool PIOS_SENSORS_IsRegistered(enum pios_sensor_type type)
Checks if a sensor type is registered with the PIOS_SENSORS interface.
Definition: pios_sensors.c:88
static struct PIOS_Sensor sensors[PIOS_SENSOR_NUM]
int32_t PIOS_SENSORS_Register(enum pios_sensor_type type, struct pios_queue *queue)
Register a queue-based sensor with the PIOS_SENSORS interface.
Definition: pios_sensors.c:82
int32_t PIOS_SENSORS_Init()
Initialize the PIOS_SENSORS interface.
Definition: pios_sensors.c:51
static bool PIOS_SENSORS_QueueCallback(void *ctx, void *buf, int ms_to_wait, int *next_call)
Definition: pios_sensors.c:58
int32_t PIOS_SENSORS_RegisterCallback(enum pios_sensor_type type, PIOS_SENSOR_Callback_t callback, void *ctx)
Register a callback-based sensor with the PIOS_SENSORS interface.
Definition: pios_sensors.c:68
PIOS_SENSOR_Callback_t getdata_cb
Definition: pios_sensors.c:40
bool PIOS_Thread_Period_Elapsed(const uint32_t prev_systime, const uint32_t increment_ms)
Determine if a period has elapsed since a datum.
Definition: pios_thread.c:281
void PIOS_Thread_Sleep(uint32_t time_ms)
Definition: pios_thread.c:229
uint8_t rate
Definition: msp_messages.h:99
uint8_t type
void PIOS_SENSORS_SetSampleRate(enum pios_sensor_type type, uint32_t sample_rate)
Set the sample rate of a sensor (Hz)
Definition: pios_sensors.c:172
bool PIOS_SENSORS_GetMissing(enum pios_sensor_type type)
Determine if an optional but expected sensor is missing.
Definition: pios_sensors.c:200
bool PIOS_SENSORS_GetData(enum pios_sensor_type type, void *buf, int ms_to_wait)
Get the data for a sensor type.
Definition: pios_sensors.c:103
static int32_t max_gyro_rate
Definition: pios_sensors.c:49
static struct pios_queue * queue
Definition: actuator.c:82
Generic interface for sensors.
bool(* PIOS_SENSOR_Callback_t)(void *ctx, void *output, int ms_to_wait, int *next_call)
Function that calls into sensor to get data.
Definition: pios_sensors.h:97
#define PIOS_Assert(test)
Definition: pios_debug.h:52
uint32_t next_time
Definition: pios_sensors.c:43
void * getdata_ctx
Definition: pios_sensors.c:41
bool PIOS_Thread_FakeClock_IsActive(void)
Definition: pios_thread.c:207
void PIOS_SENSORS_SetMissing(enum pios_sensor_type type)
Assert that an optional (non-accel/gyro), but expected sensor is missing.
Definition: pios_sensors.c:191