dRonin  adbada4
dRonin firmware
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
frsky_packing.c
Go to the documentation of this file.
1 
17 /*
18  * This program is free software; you can redistribute it and/or modify
19  * it under the terms of the GNU General Public License as published by
20  * the Free Software Foundation; either version 3 of the License, or
21  * (at your option) any later version.
22  *
23  * This program is distributed in the hope that it will be useful, but
24  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
25  * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
26  * for more details.
27  *
28  * You should have received a copy of the GNU General Public License along
29  * with this program; if not, see <http://www.gnu.org/licenses/>
30  *
31  * Additional note on redistribution: The copyright and license notices above
32  * must be maintained in each individual source file that is a derivative work
33  * of this source file; otherwise redistribution is prohibited.
34  */
35 
36 #include "frsky_packing.h"
37 
38 #include "modulesettings.h"
39 #include "misc_math.h"
40 #include "physical_constants.h"
41 #include "attitudeactual.h"
42 #include "baroaltitude.h"
43 #include "positionactual.h"
44 #include "velocityactual.h"
45 #include "flightbatterystate.h"
46 #include "flightbatterysettings.h"
47 #include "gpstime.h"
48 #include "homelocation.h"
49 #include "accels.h"
50 #include "flightstatus.h"
51 #include "airspeedactual.h"
52 #include "nedaccel.h"
53 #include "velocityactual.h"
54 #include "attitudeactual.h"
62 bool frsky_encode_altitude(struct frsky_settings *frsky, uint32_t *value, bool test_presence_only, uint32_t arg)
63 {
64  if (!frsky->use_baro_sensor || (PositionActualHandle() == NULL))
65  return false;
66 
67  if (test_presence_only)
68  return true;
69  // instead of encoding baro altitude directly, we will use
70  // more accurate estimation in PositionActual UAVO
71  float down = 0;
72  PositionActualDownGet(&down);
73  int32_t alt = (int32_t)(-down * 100.0f);
74  *value = (uint32_t) alt;
75  return true;
76 }
77 
85 bool frsky_encode_gps_course(struct frsky_settings *frsky, uint32_t *value, bool test_presence_only, uint32_t arg)
86 {
87  if (AttitudeActualHandle() == NULL)
88  return false;
89 
90  if (test_presence_only)
91  return true;
92 
93  AttitudeActualData attitude;
94  AttitudeActualGet(&attitude);
95  float hdg = (attitude.Yaw >= 0) ? attitude.Yaw : (attitude.Yaw + 360.0f);
96  *value = (uint32_t)(hdg * 100.0f);
97 
98  return true;
99 }
100 
108 bool frsky_encode_vario(struct frsky_settings *frsky, uint32_t *value, bool test_presence_only, uint32_t arg)
109 {
110  if (!frsky->use_baro_sensor || VelocityActualHandle() == NULL)
111  return false;
112 
113  if (test_presence_only)
114  return true;
115 
116  float down = 0;
117  VelocityActualDownGet(&down);
118  int32_t vspeed = (int32_t)(-down * 100.0f);
119  *value = (uint32_t) vspeed;
120 
121  return true;
122 }
123 
131 bool frsky_encode_current(struct frsky_settings *frsky, uint32_t *value, bool test_presence_only, uint32_t arg)
132 {
133  if (!frsky->use_current_sensor || FlightBatteryStateHandle() == NULL)
134  return false;
135  if (test_presence_only)
136  return true;
137 
138  float current = 0;
139  FlightBatteryStateCurrentGet(&current);
140  int32_t current_frsky = (int32_t)(current * 10.0f);
141  *value = (uint32_t) current_frsky;
142 
143  return true;
144 }
145 
153 bool frsky_encode_cells(struct frsky_settings *frsky, uint32_t *value, bool test_presence_only, uint32_t arg)
154 {
155  if (FlightBatteryStateHandle() == NULL)
156  return false;
157 
158  uint8_t cellCount = 0;
159  FlightBatteryStateDetectedCellCountGet(&cellCount);
160  if(cellCount)
161  frsky->batt_cell_count = cellCount;
162 
163  if ((frsky->batt_cell_count == 0) || (frsky->batt_cell_count - 1) < (arg * 2))
164  return false;
165  if (test_presence_only)
166  return true;
167 
168  float voltage = 0;
169  FlightBatteryStateVoltageGet(&voltage);
170 
171  uint32_t cell_voltage = (uint32_t)((voltage * 500.0f) / frsky->batt_cell_count);
172  *value = ((cell_voltage & 0xfff) << 8) | ((arg * 2) & 0x0f) | ((frsky->batt_cell_count << 4) & 0xf0);
173  if (((int16_t)frsky->batt_cell_count - 1) >= (arg * 2 + 1))
174  *value |= ((cell_voltage & 0xfff) << 20);
175 
176  return true;
177 }
178 
192 bool frsky_encode_t1(struct frsky_settings *frsky, uint32_t *value, bool test_presence_only, uint32_t arg)
193 {
194  if (GPSPositionHandle() == NULL)
195  return false;
196 
197  if (test_presence_only)
198  return true;
199 
200  uint8_t hl_set = HOMELOCATION_SET_FALSE;
201 
202  if (HomeLocationHandle())
203  HomeLocationSetGet(&hl_set);
204 
205  int32_t t1 = 0;
206  switch (frsky->gps_position.Status) {
207  case GPSPOSITION_STATUS_NOGPS:
208  t1 = 100;
209  break;
210  case GPSPOSITION_STATUS_NOFIX:
211  t1 = 200;
212  break;
213  case GPSPOSITION_STATUS_FIX2D:
214  t1 = 300;
215  break;
216  case GPSPOSITION_STATUS_FIX3D:
217  case GPSPOSITION_STATUS_DIFF3D:
218  if (hl_set == HOMELOCATION_SET_TRUE)
219  t1 = 500;
220  else
221  t1 = 400;
222  break;
223  }
224  if (frsky->gps_position.Satellites > 0)
225  t1 += frsky->gps_position.Satellites;
226 
227  *value = (uint32_t)t1;
228 
229  return true;
230 }
231 
241 bool frsky_encode_t2(struct frsky_settings *frsky, uint32_t *value, bool test_presence_only, uint32_t arg)
242 {
243  if (GPSPositionHandle() == NULL)
244  return false;
245 
246  if (test_presence_only)
247  return true;
248 
249  uint32_t hdop = (uint32_t)(frsky->gps_position.HDOP * 100.0f);
250 
251  if (hdop > 255)
252  hdop = 255;
253 
254  uint32_t vdop = (uint32_t)(frsky->gps_position.VDOP * 100.0f);
255 
256  if (vdop > 255)
257  vdop = 255;
258 
259  *value = 256 * vdop + hdop;
260 
261  return true;
262 }
263 
271 bool frsky_encode_fuel(struct frsky_settings *frsky, uint32_t *value, bool test_presence_only, uint32_t arg)
272 {
273  if (!frsky->use_current_sensor || FlightBatteryStateHandle() == NULL)
274  return false;
275  if (test_presence_only)
276  return true;
277 
278  uint32_t capacity = frsky->battery_settings.Capacity;
279  float consumed_mahs = 0;
280  FlightBatteryStateConsumedEnergyGet(&consumed_mahs);
281 
282  float fuel = (uint32_t)(100.0f * (1.0f - consumed_mahs / capacity));
283  fuel = bound_min_max(fuel, 0.0f, 100.0f);
284  *value = (uint32_t) fuel;
285 
286  return true;
287 }
288 
296 bool frsky_encode_acc(struct frsky_settings *frsky, uint32_t *value, bool test_presence_only, uint32_t arg)
297 {
298  uint8_t accelDataSettings;
299  ModuleSettingsFrskyAccelDataGet(&accelDataSettings);
300 
301  float acc = 0;
302  switch(accelDataSettings) {
303  case MODULESETTINGS_FRSKYACCELDATA_ACCELS: {
304  if (AccelsHandle() == NULL)
305  return false;
306  else if (test_presence_only)
307  return true;
308 
309  switch (arg) {
310  case 0:
311  AccelsxGet(&acc);
312  break;
313  case 1:
314  AccelsyGet(&acc);
315  break;
316  case 2:
317  AccelszGet(&acc);
318  break;
319  }
320 
321  acc /= GRAVITY;
322  acc *= 100.0f;
323  break;
324  }
325 
326  case MODULESETTINGS_FRSKYACCELDATA_NEDACCELS: {
327  if (NedAccelHandle() == NULL)
328  return false;
329  else if (test_presence_only)
330  return true;
331 
332  switch (arg) {
333  case 0:
334  NedAccelNorthGet(&acc);
335  break;
336  case 1:
337  NedAccelEastGet(&acc);
338  break;
339  case 2:
340  NedAccelDownGet(&acc);
341  break;
342  }
343 
344  acc /= GRAVITY;
345  acc *= 100.0f;
346  break;
347  }
348 
349  case MODULESETTINGS_FRSKYACCELDATA_NEDVELOCITY: {
350  if (VelocityActualHandle() == NULL)
351  return false;
352  else if (test_presence_only)
353  return true;
354 
355  switch (arg) {
356  case 0:
357  VelocityActualNorthGet(&acc);
358  break;
359  case 1:
360  VelocityActualEastGet(&acc);
361  break;
362  case 2:
363  VelocityActualDownGet(&acc);
364  break;
365  }
366 
367  acc *= 100.0f;
368  break;
369  }
370 
372  if (AttitudeActualHandle() == NULL)
373  return false;
374  else if (test_presence_only)
375  return true;
376 
377  switch (arg) {
378  case 0:
379  AttitudeActualRollGet(&acc);
380  break;
381  case 1:
382  AttitudeActualPitchGet(&acc);
383  break;
384  case 2:
385  AttitudeActualYawGet(&acc);
386  break;
387  }
388 
389  acc *= 100.0f;
390  break;
391  }
392  }
393 
394  int32_t frsky_acc = (int32_t) acc;
395  *value = (uint32_t) frsky_acc;
396 
397  return true;
398 }
399 
407 bool frsky_encode_gps_coord(struct frsky_settings *frsky, uint32_t *value, bool test_presence_only, uint32_t arg)
408 {
409  if (GPSPositionHandle() == NULL)
410  return false;
411  if (frsky->gps_position.Status == GPSPOSITION_STATUS_NOFIX
412  || frsky->gps_position.Status == GPSPOSITION_STATUS_NOGPS)
413  return false;
414  if (test_presence_only)
415  return true;
416 
417  uint32_t frsky_coord = 0;
418  int32_t coord = 0;
419  if (arg == 0) {
420  // lattitude
421  coord = frsky->gps_position.Latitude;
422  if (coord >= 0)
423  frsky_coord = 0;
424  else
425  frsky_coord = 1 << 30;
426  } else {
427  // longitude
428  coord = frsky->gps_position.Longitude;
429  if (coord >= 0)
430  frsky_coord = 2 << 30;
431  else
432  frsky_coord = 3 << 30;
433  }
434  coord = abs(coord);
435  frsky_coord |= (((uint64_t)coord * 6ull) / 100);
436 
437  *value = frsky_coord;
438  return true;
439 }
440 
448 bool frsky_encode_gps_alt(struct frsky_settings *frsky, uint32_t *value, bool test_presence_only, uint32_t arg)
449 {
450  if (GPSPositionHandle() == NULL)
451  return false;
452  if (frsky->gps_position.Status != GPSPOSITION_STATUS_FIX3D
453  && frsky->gps_position.Status != GPSPOSITION_STATUS_DIFF3D)
454  return false;
455  if (test_presence_only)
456  return true;
457 
458  int32_t frsky_gps_alt = (int32_t)(frsky->gps_position.Altitude * 100.0f);
459  *value = (uint32_t)frsky_gps_alt;
460 
461  return true;
462 }
463 
471 bool frsky_encode_gps_speed(struct frsky_settings *frsky, uint32_t *value, bool test_presence_only, uint32_t arg)
472 {
473  if (GPSPositionHandle() == NULL)
474  return false;
475  if (frsky->gps_position.Status != GPSPOSITION_STATUS_FIX3D
476  && frsky->gps_position.Status != GPSPOSITION_STATUS_DIFF3D)
477  return false;
478  if (test_presence_only)
479  return true;
480 
481  int32_t frsky_speed = (int32_t)((frsky->gps_position.Groundspeed / KNOTS2M_PER_SECOND) * 1000);
482  *value = frsky_speed;
483  return true;
484 }
485 
493 bool frsky_encode_gps_time(struct frsky_settings *frsky, uint32_t *value, bool test_presence_only, uint32_t arg)
494 {
495  if (GPSPositionHandle() == NULL || GPSTimeHandle() == NULL)
496  return false;
497  if (frsky->gps_position.Status != GPSPOSITION_STATUS_FIX3D
498  && frsky->gps_position.Status != GPSPOSITION_STATUS_DIFF3D)
499  return false;
500  if (test_presence_only)
501  return true;
502 
503  GPSTimeData gps_time;
504  GPSTimeGet(&gps_time);
505  uint32_t frsky_time = 0;
506 
507  if (arg == 0) {
508  // encode date
509  frsky_time = 0x000000ff;
510  frsky_time |= gps_time.Day << 8;
511  frsky_time |= gps_time.Month << 16;
512  frsky_time |= (gps_time.Year % 100) << 24;
513  } else {
514  frsky_time = 0;
515  frsky_time |= gps_time.Second << 8;
516  frsky_time |= gps_time.Minute << 16;
517  frsky_time |= gps_time.Hour << 24;
518  }
519  *value = frsky_time;
520  return true;
521 }
522 
536 bool frsky_encode_rpm(struct frsky_settings *frsky, uint32_t *value, bool test_presence_only, uint32_t arg)
537 {
538  if (FlightStatusHandle() == NULL)
539  return false;
540  if (test_presence_only)
541  return true;
542 
543  FlightStatusData flight_status;
544  FlightStatusGet(&flight_status);
545 
546  *value = (flight_status.Armed == FLIGHTSTATUS_ARMED_ARMED) ? 200 : 100;
547  *value += flight_status.FlightMode;
548 
549  return true;
550 }
551 
559 bool frsky_encode_airspeed(struct frsky_settings *frsky, uint32_t *value, bool test_presence_only, uint32_t arg)
560 {
561  if (AirspeedActualHandle() == NULL)
562  return false;
563  if (test_presence_only)
564  return true;
565 
566  AirspeedActualData airspeed;
567  AirspeedActualGet(&airspeed);
568  int32_t frsky_speed = (int32_t)((airspeed.TrueAirspeed / KNOTS2M_PER_SECOND) * 10);
569  *value = (uint32_t)frsky_speed;
570 
571  return true;
572 }
573 
581 uint8_t frsky_insert_byte(uint8_t *obuff, uint16_t *chk, uint8_t byte)
582 {
583  /* checksum calculation is based on data before byte-stuffing */
584  *chk += byte;
585  *chk += (*chk) >> 8;
586  *chk &= 0x00ff;
587 
588  if (byte == 0x7e || byte == 0x7d) {
589  obuff[0] = 0x7d;
590  obuff[1] = byte &= ~0x20;
591  return 2;
592  }
593 
594  obuff[0] = byte;
595  return 1;
596 }
597 
603 int32_t frsky_send_frame(uintptr_t com, enum frsky_value_id id, uint32_t value,
604  bool send_prelude)
605 {
606  /* each call of frsky_insert_byte can add 2 bytes to the buffer at maximum
607  * and therefore the worst-case is 17 bytes total (the first byte 0x10 won't be
608  * escaped) */
609  uint8_t tx_data[17];
610  uint16_t chk = 0;
611  uint8_t cnt = 0;
612 
613  if (send_prelude) {
614  tx_data[0] = 0x7e;
615  tx_data[1] = 0x98;
616  cnt = 2;
617  }
618 
619  cnt += frsky_insert_byte(&tx_data[cnt], &chk, 0x10);
620  cnt += frsky_insert_byte(&tx_data[cnt], &chk, (uint16_t)id & 0xff);
621  cnt += frsky_insert_byte(&tx_data[cnt], &chk, ((uint16_t)id >> 8) & 0xff);
622  cnt += frsky_insert_byte(&tx_data[cnt], &chk, value & 0xff);
623  cnt += frsky_insert_byte(&tx_data[cnt], &chk, (value >> 8) & 0xff);
624  cnt += frsky_insert_byte(&tx_data[cnt], &chk, (value >> 16) & 0xff);
625  cnt += frsky_insert_byte(&tx_data[cnt], &chk, (value >> 24) & 0xff);
626  cnt += frsky_insert_byte(&tx_data[cnt], &chk, 0xff - chk);
627 
628  PIOS_COM_SendBuffer(com, tx_data, cnt);
629 
630  return cnt;
631 }
632 
uint8_t batt_cell_count
Definition: frsky_packing.h:47
uint8_t capacity[3]
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)
bool frsky_encode_fuel(struct frsky_settings *frsky, uint32_t *value, bool test_presence_only, uint32_t arg)
uint8_t frsky_insert_byte(uint8_t *obuff, uint16_t *chk, uint8_t byte)
bool frsky_encode_airspeed(struct frsky_settings *frsky, uint32_t *value, bool test_presence_only, uint32_t arg)
bool frsky_encode_gps_alt(struct frsky_settings *frsky, uint32_t *value, bool test_presence_only, uint32_t arg)
bool frsky_encode_gps_time(struct frsky_settings *frsky, uint32_t *value, bool test_presence_only, uint32_t arg)
bool frsky_encode_acc(struct frsky_settings *frsky, uint32_t *value, bool test_presence_only, uint32_t arg)
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 frsky_encode_gps_coord(struct frsky_settings *frsky, uint32_t *value, bool test_presence_only, uint32_t arg)
bool frsky_encode_t2(struct frsky_settings *frsky, uint32_t *value, bool test_presence_only, uint32_t arg)
struct _msp_pid_item alt
Definition: msp_messages.h:99
float bound_min_max(float val, float min, float max)
Bound input value between min and max.
Definition: misc_math.c:38
int32_t frsky_send_frame(uintptr_t com, enum frsky_value_id id, uint32_t value, bool send_prelude)
bool frsky_encode_gps_speed(struct frsky_settings *frsky, uint32_t *value, bool test_presence_only, uint32_t arg)
FlightBatterySettingsData battery_settings
Definition: frsky_packing.h:49
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
bool frsky_encode_t1(struct frsky_settings *frsky, uint32_t *value, bool test_presence_only, uint32_t arg)
uint16_t current
case MODULESETTINGS_FRSKYACCELDATA_ATTITUDEANGLES
PIOS_COM_SendBuffer(shub_global->frsky_port, shub_global->serial_buf, msg_length)
tuple f
Definition: px_mkfw.py:81
bool frsky_encode_altitude(struct frsky_settings *frsky, uint32_t *value, bool test_presence_only, uint32_t arg)
Definition: frsky_packing.c:62
GPSPositionData gps_position
Definition: frsky_packing.h:50
bool frsky_encode_gps_course(struct frsky_settings *frsky, uint32_t *value, bool test_presence_only, uint32_t arg)
Definition: frsky_packing.c:85
uint16_t voltage
bool use_current_sensor
Definition: frsky_packing.h:46
frsky_value_id
Definition: frsky_packing.h:53