dRonin  adbada4
dRonin firmware
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
UAVOTaranis.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 /*
30  * This module is derived from UAVOFrSKYSportPort but differs
31  * in a number of ways. Specifically the SPort code is expected
32  * to listen for sensor requests and respond appropriately. This
33  * code simply can spew data to the Taranis (since it is talking
34  * to different harware). The scheduling system is reused between
35  * the two, but duplicated because it isn't really part of the
36  * packing, and touches on the private state of the state machine
37  * code in the module
38  */
39 
40 #include "frsky_packing.h"
41 #include "pios_thread.h"
42 
43 #include "openpilot.h"
44 #include "physical_constants.h"
45 #include "modulesettings.h"
46 #include "flightbatterysettings.h"
47 #include "flightbatterystate.h"
48 #include "gpsposition.h"
49 #include "airspeedactual.h"
50 #include "baroaltitude.h"
51 #include "accels.h"
52 #include "positionactual.h"
53 #include "velocityactual.h"
54 #include "flightstatus.h"
55 
56 #if defined(PIOS_INCLUDE_TARANIS_SPORT)
57 
58 static void uavoTaranisTask(void *parameters);
59 
60 static bool frsky_encode_rssi(struct frsky_settings *frsky, uint32_t *value, bool test_presence_only, uint32_t arg);
61 static bool frsky_encode_swr(struct frsky_settings *frsky, uint32_t *value, bool test_presence_only, uint32_t arg);
62 static bool frsky_encode_battery(struct frsky_settings *frsky, uint32_t *value, bool test_presence_only, uint32_t arg);
63 
64 #define FRSKY_POLL_REQUEST 0x7e
65 #define FRSKY_MINIMUM_POLL_INTERVAL 10000
66 
67 #define VOLT_RATIO (20)
68 
69 enum frsky_state {
70  FRSKY_STATE_WAIT_POLL_REQUEST,
71  FRSKY_STATE_WAIT_SENSOR_ID,
72  FRSKY_STATE_WAIT_TX_DONE,
73 };
74 
75 static const struct frsky_value_item frsky_value_items[] = {
76  {FRSKY_CURR_ID, 300, frsky_encode_current, 0}, // battery current
77  {FRSKY_BATT_ID, 200, frsky_encode_battery, 0}, // send battery voltage
78  {FRSKY_FUEL_ID, 200, frsky_encode_fuel, 0}, // consumed battery energy
79  {FRSKY_RSSI_ID, 100, frsky_encode_rssi, 0}, // send RSSI information
80  {FRSKY_SWR_ID, 100, frsky_encode_swr, 0}, // send RSSI information
81  {FRSKY_ALT_ID, 100, frsky_encode_altitude, 0}, // altitude estimate
82  {FRSKY_VARIO_ID, 100, frsky_encode_vario, 0}, // vertical speed
83  {FRSKY_RPM_ID, 1500, frsky_encode_rpm, 0}, // encodes flight status!
84  {FRSKY_CELLS_ID, 850, frsky_encode_cells, 0}, // battery cells 1-2
85  {FRSKY_CELLS_ID, 850, frsky_encode_cells, 1}, // battery cells 3-4
86  {FRSKY_CELLS_ID, 850, frsky_encode_cells, 2}, // battery cells 5-6
87  {FRSKY_CELLS_ID, 850, frsky_encode_cells, 3}, // battery cells 7-8
88  {FRSKY_CELLS_ID, 850, frsky_encode_cells, 4}, // battery cells 9-10
89  {FRSKY_CELLS_ID, 850, frsky_encode_cells, 5}, // battery cells 11-12
90 };
91 
92 struct frsky_sport_telemetry {
93  enum frsky_state state;
94  int32_t scheduled_item;
95  uint32_t last_poll_time;
96  uint8_t ignore_rx_chars;
97  uintptr_t com;
99  uint32_t item_last_triggered[NELEMENTS(frsky_value_items)];
100 };
101 
102 #define FRSKY_SPORT_BAUDRATE 57600
103 
104 #if defined(PIOS_FRSKY_SPORT_TELEMETRY_STACK_SIZE)
105 #define STACK_SIZE_BYTES PIOS_FRSKY_SPORT_TELEMETRY_STACK_SIZE
106 #else
107 #define STACK_SIZE_BYTES 672
108 #endif
109 #define TASK_PRIORITY PIOS_THREAD_PRIO_LOW
110 
111 static struct pios_thread *uavoTaranisTaskHandle;
112 static bool module_enabled;
113 static struct frsky_sport_telemetry *frsky;
114 
122 static bool frsky_encode_rssi(struct frsky_settings *frsky, uint32_t *value, bool test_presence_only, uint32_t arg)
123 {
124 #if 0
125  uint8_t local_link_quality = 0, local_link_connected = 0; /* XXX */
126 
127  RFM22BStatusLinkStateGet(&local_link_connected);
128  RFM22BStatusLinkQualityGet(&local_link_quality);
129 
130  RFM22BStatusData rfm22bStatus;
131  RFM22BStatusInstGet(1, &rfm22bStatus);
132 #endif
133 
134  *value = 0;
135 
136  return true;
137 }
138 
139 static bool frsky_encode_swr(struct frsky_settings *frsky, uint32_t *value, bool test_presence_only, uint32_t arg)
140 {
141  *value = 1;
142  return true;
143 }
144 
145 static bool frsky_encode_battery(struct frsky_settings *frsky, uint32_t *value, bool test_presence_only, uint32_t arg)
146 {
147  float voltage = 0;
148  FlightBatteryStateVoltageGet(&voltage);
149  *value = (uint8_t) (voltage * VOLT_RATIO);
150 
151  return true;
152 }
153 
154 
159 static void frsky_schedule_next_item(void)
160 {
161  uint32_t i = 0;
162  int32_t max_exp_time = INT32_MIN;
163  int32_t most_exp_item = -1;
164  for (i = 0; i < NELEMENTS(frsky_value_items); i++) {
165  if (frsky_value_items[i].encode_value(&frsky->frsky_settings, 0, true, frsky_value_items[i].fn_arg)) {
166  int32_t exp_time = PIOS_DELAY_GetuSSince(frsky->item_last_triggered[i]) -
167  (frsky_value_items[i].period_ms * 1000);
168  if (exp_time > max_exp_time) {
169  max_exp_time = exp_time;
170  most_exp_item = i;
171  }
172  }
173  }
174  frsky->scheduled_item = most_exp_item;
175 }
180 static bool frsky_send_scheduled_item(void)
181 {
182  int32_t item = frsky->scheduled_item;
183  if ((item >= 0) && (item < NELEMENTS(frsky_value_items))) {
184  frsky->item_last_triggered[item] = PIOS_DELAY_GetuS();
185  uint32_t value = 0;
186  if (frsky_value_items[item].encode_value(&frsky->frsky_settings, &value, false,
187  frsky_value_items[item].fn_arg)) {
188  frsky_send_frame(frsky->com, (uint16_t)(frsky_value_items[item].id), value, true);
189  return true;
190  }
191  }
192 
193  return false;
194 }
195 
201 static int32_t uavoTaranisStart(void)
202 {
203  if (module_enabled) {
204  // Start tasks
205  uavoTaranisTaskHandle = PIOS_Thread_Create(
206  uavoTaranisTask, "uavoFrSKYSensorHubBridge",
208  TaskMonitorAdd(TASKINFO_RUNNING_UAVOFRSKYSENSORHUBBRIDGE,
209  uavoTaranisTaskHandle);
210  return 0;
211  }
212  return -1;
213 }
214 
220 static int32_t uavoTaranisInitialize(void)
221 {
222  uint32_t sport_com = PIOS_COM_FRSKY_SPORT;
223 
224  if (sport_com) {
225 
226 
227  frsky = PIOS_malloc(sizeof(struct frsky_sport_telemetry));
228  if (frsky != NULL) {
229  memset(frsky, 0x00, sizeof(struct frsky_sport_telemetry));
230 
231  // These objects are registered on the TLM so it
232  // can intercept them from the telemetry stream
233  if (FlightBatteryStateInitialize() == -1 \
234  || FlightStatusInitialize() == -1 \
235  || PositionActualInitialize() == -1 \
236  || VelocityActualInitialize()) {
237  module_enabled = false;
238  return -1;
239  }
240 
241  frsky->frsky_settings.use_current_sensor = false;
242  frsky->frsky_settings.batt_cell_count = 0;
243  frsky->frsky_settings.use_baro_sensor = false;
244  frsky->state = FRSKY_STATE_WAIT_POLL_REQUEST;
245  frsky->last_poll_time = PIOS_DELAY_GetuS();
246  frsky->ignore_rx_chars = 0;
247  frsky->scheduled_item = -1;
248  frsky->com = sport_com;
249 
250  uint8_t i;
251  for (i = 0; i < NELEMENTS(frsky_value_items); i++)
252  frsky->item_last_triggered[i] = PIOS_DELAY_GetuS();
253  PIOS_COM_ChangeBaud(frsky->com, FRSKY_SPORT_BAUDRATE);
254  module_enabled = true;
255  return 0;
256  }
257 
258  module_enabled = true;
259 
260  return 0;
261  }
262 
263  module_enabled = false;
264 
265  return -1;
266 }
267 MODULE_INITCALL(uavoTaranisInitialize, uavoTaranisStart)
268 
269 
272 static void uavoTaranisTask(void *parameters)
273 {
274  while(1) {
275 
276  if (true) {
277 
278  // for some reason, only first four messages are sent.
279  for (uint32_t i = 0; i < sizeof(frsky_value_items) / sizeof(frsky_value_items[0]); i++) {
280  frsky->scheduled_item = i;
281  frsky_send_scheduled_item();
283  }
284 
285  }
286 
287  if (false) {
288 
289  // fancier schedlued message sending. doesn't appear to work
290  // currently.
292  frsky_schedule_next_item();
293  frsky_send_scheduled_item();
294  }
295 
296  }
297 }
298 
299 #endif /* PIOS_INCLUDE_TARANIS_SPORT */
300 
uint8_t batt_cell_count
Definition: frsky_packing.h:47
Packs UAVObjects into FrSKY Smart Port frames.
bool frsky_encode_vario(struct frsky_settings *frsky, uint32_t *value, bool test_presence_only, uint32_t arg)
uint32_t PIOS_DELAY_GetuS()
Query the Delay timer for the current uS.
Definition: pios_delay.c:173
bool frsky_encode_fuel(struct frsky_settings *frsky, uint32_t *value, bool test_presence_only, uint32_t arg)
#define NELEMENTS(x)
Definition: pios.h:192
#define STACK_SIZE_BYTES
Definition: actuator.c:62
void * PIOS_malloc(size_t size)
Definition: pios_heap.c:125
bool frsky_encode_current(struct frsky_settings *frsky, uint32_t *value, bool test_presence_only, uint32_t arg)
bool frsky_encode_rpm(struct frsky_settings *frsky, uint32_t *value, bool test_presence_only, uint32_t arg)
bool module_enabled
uint32_t PIOS_DELAY_GetuSSince(uint32_t t)
Calculate time in microseconds since a previous time.
Definition: pios_delay.c:183
#define TASK_PRIORITY
Definition: actuator.c:65
uint16_t period_ms
Definition: frsky_packing.h:83
enum frsky_value_id id
Definition: frsky_packing.h:82
#define MODULE_INITCALL(ifn, sfn)
Definition: pios_initcall.h:67
struct pios_thread * PIOS_Thread_Create(void(*fp)(void *), const char *namep, size_t stack_bytes, void *argp, enum pios_thread_prio_e prio)
Definition: pios_thread.c:89
int32_t TaskMonitorAdd(TaskInfoRunningElem task, struct pios_thread *threadp)
Definition: taskmonitor.c:67
uint8_t i
Definition: msp_messages.h:97
int32_t frsky_send_frame(uintptr_t com, enum frsky_value_id id, uint32_t value, bool send_prelude)
bool frsky_encode_cells(struct frsky_settings *frsky, uint32_t *value, bool test_presence_only, uint32_t arg)
uint16_t value
Definition: storm32bgc.c:155
void PIOS_Thread_Sleep(uint32_t time_ms)
Definition: pios_thread.c:229
bool frsky_encode_altitude(struct frsky_settings *frsky, uint32_t *value, bool test_presence_only, uint32_t arg)
Definition: frsky_packing.c:62
Includes PiOS and core architecture components.
uint16_t voltage
bool use_current_sensor
Definition: frsky_packing.h:46
#define PIOS_COM_FRSKY_SPORT
Definition: pios_board.h:121
int32_t PIOS_COM_ChangeBaud(uintptr_t com_id, uint32_t baud)
enum arena_state state