dRonin  adbada4
dRonin firmware
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
uavohottbridge.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  * Additional note on redistribution: The copyright and license notices above
30  * must be maintained in each individual source file that is a derivative work
31  * of this source file; otherwise redistribution is prohibited.
32  */
33 
34 
35 // conditional compilation of the module
36 #include "pios.h"
37 #if defined(PIOS_INCLUDE_HOTT)
38 
39 #include "uavohottbridge.h"
40 #include "pios_thread.h"
41 #include "pios_modules.h"
42 
43 // Private constants
44 #define STACK_SIZE_BYTES 700
45 #define TASK_PRIORITY PIOS_THREAD_PRIO_NORMAL
46 
47 // Private variables
48 static struct pios_thread *uavoHoTTBridgeTaskHandle;
49 static uint32_t hott_port;
50 static bool module_enabled;
51 static struct telemetrydata *telestate;
52 
53 // Private functions
54 static void uavoHoTTBridgeTask(void *parameters);
55 static uint16_t build_VARIO_message(struct hott_vario_message *msg);
56 static uint16_t build_GPS_message(struct hott_gps_message *msg);
57 static uint16_t build_GAM_message(struct hott_gam_message *msg);
58 static uint16_t build_EAM_message(struct hott_eam_message *msg);
59 static uint16_t build_ESC_message(struct hott_esc_message *msg);
60 static uint16_t build_TEXT_message(struct hott_text_message *msg);
61 static uint8_t calc_checksum(uint8_t *data, uint16_t size);
62 static uint8_t generate_warning();
63 static void update_telemetrydata();
64 static void convert_long2gps(int32_t value, uint8_t *dir, uword_t *min, uword_t *sec);
65 static uint8_t scale_float2uint8(float value, float scale, float offset);
66 static int8_t scale_float2int8(float value, float scale, float offset);
67 static uword_t scale_float2uword(float value, float scale, float offset);
68 
74 static int32_t uavoHoTTBridgeStart(void)
75 {
76  if (module_enabled) {
77  // Start task
78  uavoHoTTBridgeTaskHandle = PIOS_Thread_Create(
79  uavoHoTTBridgeTask, "uavoHoTTBridge",
81  TaskMonitorAdd(TASKINFO_RUNNING_UAVOHOTTBRIDGE,
82  uavoHoTTBridgeTaskHandle);
83  return 0;
84  }
85  return -1;
86 }
87 
93 static int32_t uavoHoTTBridgeInitialize(void)
94 {
95  hott_port = PIOS_COM_HOTT;
96 
98  module_enabled = true;
99  // HoTT telemetry baudrate is fixed to 19200
100  PIOS_COM_ChangeBaud(hott_port, 19200);
101  if (HoTTSettingsInitialize() == -1) {
102  module_enabled = false;
103  return -1;
104  }
105 
106  // allocate memory for telemetry data
107  telestate = (struct telemetrydata *)PIOS_malloc(sizeof(*telestate));
108 
109  if (telestate == NULL) {
110  // there is not enough free memory. the module could not run.
111  module_enabled = false;
112  return -1;
113  }
114  } else {
115  module_enabled = false;
116  }
117  return 0;
118 }
119 MODULE_INITCALL( uavoHoTTBridgeInitialize, uavoHoTTBridgeStart)
120 
121 
124 static void uavoHoTTBridgeTask(void *parameters) {
125  uint8_t rx_buffer[2];
126  uint8_t tx_buffer[HOTT_MAX_MESSAGE_LENGTH];
127  uint16_t message_size;
128 
129  // clear all state values
130  memset(telestate, 0, sizeof(*telestate));
131 
132  // initialize timer variables
133  uint32_t lastSysTime = PIOS_Thread_Systime();
134  // idle delay between telemetry request and answer
135  uint32_t idledelay = IDLE_TIME;
136  // data delay between transmitted bytes
137  uint32_t datadelay = DATA_TIME;
138 
139  // work on hott telemetry. endless loop.
140  while (1) {
141  // clear message size on every loop before processing
142  message_size = 0;
143 
144  // shift receiver buffer. make room for one byte.
145  rx_buffer[1]= rx_buffer[0];
146 
147  // wait for a byte of telemetry request in data delay interval
148  while (PIOS_COM_ReceiveBuffer(hott_port, rx_buffer, 1, 0) == 0) {
149  PIOS_Thread_Sleep_Until(&lastSysTime, datadelay);
150  }
151  // set start trigger point
152  lastSysTime = PIOS_Thread_Systime();
153 
154  // examine received data stream
155  if (rx_buffer[1] == HOTT_BINARY_ID) {
156  // first received byte looks like a binary request. check second received byte for a sensor id.
157  switch (rx_buffer[0]) {
158  case HOTT_VARIO_ID:
159  message_size = build_VARIO_message((struct hott_vario_message *)tx_buffer);
160  break;
161  case HOTT_GPS_ID:
162  message_size = build_GPS_message((struct hott_gps_message *)tx_buffer);
163  break;
164  case HOTT_GAM_ID:
165  message_size = build_GAM_message((struct hott_gam_message *)tx_buffer);
166  break;
167  case HOTT_EAM_ID:
168  message_size = build_EAM_message((struct hott_eam_message *)tx_buffer);
169  break;
170  case HOTT_ESC_ID:
171  message_size = build_ESC_message((struct hott_esc_message *)tx_buffer);
172  break;
173  default:
174  message_size = 0;
175  }
176  }
177  else if (rx_buffer[1] == HOTT_TEXT_ID) {
178  // first received byte looks like a text request. check second received byte for a valid button.
179  switch (rx_buffer[0]) {
180  case HOTT_BUTTON_DEC:
181  case HOTT_BUTTON_INC:
182  case HOTT_BUTTON_SET:
183  case HOTT_BUTTON_NIL:
184  case HOTT_BUTTON_NEXT:
185  case HOTT_BUTTON_PREV:
186  message_size = build_TEXT_message((struct hott_text_message *)tx_buffer);
187  break;
188  default:
189  message_size = 0;
190  }
191  }
192 
193  // check if a message is in the transmit buffer.
194  if (message_size > 0) {
195  // check idle line before transmit. pause, then check receiver buffer
196  PIOS_Thread_Sleep_Until(&lastSysTime, idledelay);
197 
198  if (PIOS_COM_ReceiveBuffer(hott_port, rx_buffer, 1, 0) == 0) {
199  // nothing received means idle line. ready to transmit the requested message
200  for (int i = 0; i < message_size; i++) {
201  // send message content with pause between each byte
202  PIOS_COM_SendCharNonBlocking(hott_port, tx_buffer[i]);
203  // grab possible incoming loopback data and throw it away
204  PIOS_COM_ReceiveBuffer(hott_port, rx_buffer, sizeof(rx_buffer), 0);
205  PIOS_Thread_Sleep_Until(&lastSysTime, datadelay);
206  }
207 
208  // after transmitting the message, any loopback data needs to be cleaned up.
209  PIOS_Thread_Sleep_Until(&lastSysTime, idledelay);
210  PIOS_COM_ReceiveBuffer(hott_port, tx_buffer, message_size, 0);
211  }
212  }
213 
214  }
215 }
216 
221 uint16_t build_VARIO_message(struct hott_vario_message *msg) {
222  update_telemetrydata();
223 
224  if (telestate->Settings.Sensor[HOTTSETTINGS_SENSOR_VARIO] == HOTTSETTINGS_SENSOR_DISABLED)
225  return 0;
226 
227  // clear message buffer
228  memset(msg, 0, sizeof(*msg));
229 
230  // message header
231  msg->start = HOTT_START;
232  msg->stop = HOTT_STOP;
233  msg->sensor_id = HOTT_VARIO_ID;
234  msg->warning = generate_warning();
236 
237  // alarm inverse bits. invert display areas on limits
238  msg->alarm_inverse |= (telestate->Settings.Limit[HOTTSETTINGS_LIMIT_MINHEIGHT] > telestate->altitude) ? VARIO_INVERT_ALT : 0;
239  msg->alarm_inverse |= (telestate->Settings.Limit[HOTTSETTINGS_LIMIT_MAXHEIGHT] < telestate->altitude) ? VARIO_INVERT_ALT : 0;
240  msg->alarm_inverse |= (telestate->Settings.Limit[HOTTSETTINGS_LIMIT_MAXHEIGHT] < telestate->altitude) ? VARIO_INVERT_MAX : 0;
241  msg->alarm_inverse |= (telestate->Settings.Limit[HOTTSETTINGS_LIMIT_MINHEIGHT] > telestate->altitude) ? VARIO_INVERT_MIN : 0;
242  msg->alarm_inverse |= (telestate->Settings.Limit[HOTTSETTINGS_LIMIT_NEGDIFFERENCE1] > telestate->climbrate1s) ? VARIO_INVERT_CR1S : 0;
243  msg->alarm_inverse |= (telestate->Settings.Limit[HOTTSETTINGS_LIMIT_POSDIFFERENCE1] < telestate->climbrate1s) ? VARIO_INVERT_CR1S : 0;
244  msg->alarm_inverse |= (telestate->Settings.Limit[HOTTSETTINGS_LIMIT_NEGDIFFERENCE2] > telestate->climbrate3s) ? VARIO_INVERT_CR3S : 0;
245  msg->alarm_inverse |= (telestate->Settings.Limit[HOTTSETTINGS_LIMIT_POSDIFFERENCE2] < telestate->climbrate3s) ? VARIO_INVERT_CR3S : 0;
246  msg->alarm_inverse |= (telestate->Settings.Limit[HOTTSETTINGS_LIMIT_NEGDIFFERENCE2] > telestate->climbrate10s) ? VARIO_INVERT_CR10S : 0;
247  msg->alarm_inverse |= (telestate->Settings.Limit[HOTTSETTINGS_LIMIT_POSDIFFERENCE2] < telestate->climbrate10s) ? VARIO_INVERT_CR10S : 0;
248 
249  // altitude relative to ground
250  msg->altitude = scale_float2uword(telestate->altitude, 1, OFFSET_ALTITUDE);
251  msg->min_altitude = scale_float2uword(telestate->min_altitude, 1, OFFSET_ALTITUDE);
252  msg->max_altitude = scale_float2uword(telestate->max_altitude, 1, OFFSET_ALTITUDE);
253 
254  // climbrate
255  msg->climbrate = scale_float2uword(telestate->climbrate1s, M_TO_CM, OFFSET_CLIMBRATE);
256  msg->climbrate3s = scale_float2uword(telestate->climbrate3s, M_TO_CM, OFFSET_CLIMBRATE);
257  msg->climbrate10s = scale_float2uword(telestate->climbrate10s, M_TO_CM, OFFSET_CLIMBRATE);
258 
259  // compass
260  msg->compass = scale_float2int8(telestate->Attitude.Yaw, DEG_TO_UINT, 0);
261 
262  // statusline
263  memcpy(msg->ascii, telestate->statusline, sizeof(msg->ascii));
264 
265  // free display characters
266  msg->ascii1 = 0;
267  msg->ascii2 = 0;
268  msg->ascii3 = 0;
269 
270  msg->checksum = calc_checksum((uint8_t *)msg, sizeof(*msg));
271  return sizeof(*msg);
272 }
273 
274 uint16_t build_GPS_message(struct hott_gps_message *msg) {
275  update_telemetrydata();
276 
277  if (telestate->Settings.Sensor[HOTTSETTINGS_SENSOR_GPS] == HOTTSETTINGS_SENSOR_DISABLED)
278  return 0;
279 
280  // clear message buffer
281  memset(msg, 0, sizeof(*msg));
282 
283  // message header
284  msg->start = HOTT_START;
285  msg->stop = HOTT_STOP;
286  msg->sensor_id = HOTT_GPS_ID;
287  msg->warning = generate_warning();
289 
290  // alarm inverse bits. invert display areas on limits
291  msg->alarm_inverse1 |= (telestate->Settings.Limit[HOTTSETTINGS_LIMIT_MAXDISTANCE] < telestate->homedistance) ? GPS_INVERT_HDIST : 0;
292  msg->alarm_inverse1 |= (telestate->Settings.Limit[HOTTSETTINGS_LIMIT_MINSPEED] > telestate->GPS.Groundspeed) ? GPS_INVERT_SPEED : 0;
293  msg->alarm_inverse1 |= (telestate->Settings.Limit[HOTTSETTINGS_LIMIT_MAXSPEED] < telestate->GPS.Groundspeed) ? GPS_INVERT_SPEED : 0;
294  msg->alarm_inverse1 |= (telestate->Settings.Limit[HOTTSETTINGS_LIMIT_MINHEIGHT] > telestate->altitude) ? GPS_INVERT_ALT : 0;
295  msg->alarm_inverse1 |= (telestate->Settings.Limit[HOTTSETTINGS_LIMIT_MAXHEIGHT] < telestate->altitude) ? GPS_INVERT_ALT : 0;
296  msg->alarm_inverse1 |= (telestate->Settings.Limit[HOTTSETTINGS_LIMIT_NEGDIFFERENCE1] > telestate->climbrate1s) ? GPS_INVERT_CR1S : 0;
297  msg->alarm_inverse1 |= (telestate->Settings.Limit[HOTTSETTINGS_LIMIT_POSDIFFERENCE1] < telestate->climbrate1s) ? GPS_INVERT_CR1S : 0;
298  msg->alarm_inverse1 |= (telestate->Settings.Limit[HOTTSETTINGS_LIMIT_NEGDIFFERENCE2] > telestate->climbrate3s) ? GPS_INVERT_CR3S : 0;
299  msg->alarm_inverse1 |= (telestate->Settings.Limit[HOTTSETTINGS_LIMIT_POSDIFFERENCE2] < telestate->climbrate3s) ? GPS_INVERT_CR3S : 0;
300  msg->alarm_inverse2 |= (telestate->SysAlarms.Alarm[SYSTEMALARMS_ALARM_GPS] != SYSTEMALARMS_ALARM_OK) ? GPS_INVERT2_POS : 0;
301 
302  // gps direction, groundspeed and postition
303  msg->flight_direction = scale_float2uint8(telestate->GPS.Heading, DEG_TO_UINT, 0);
304  msg->gps_speed = scale_float2uword(telestate->GPS.Groundspeed, MS_TO_KMH, 0);
305  convert_long2gps(telestate->GPS.Latitude, &msg->latitude_ns, &msg->latitude_min, &msg->latitude_sec);
306  convert_long2gps(telestate->GPS.Longitude, &msg->longitude_ew, &msg->longitude_min, &msg->longitude_sec);
307 
308  // homelocation distance, course and state
309  msg->distance = scale_float2uword(telestate->homedistance, 1, 0);
310  msg->home_direction = scale_float2uint8(telestate->homecourse, DEG_TO_UINT, 0);
311  msg->ascii5 = (telestate->Home.Set ? 'H' : '-');
312 
313  // altitude relative to ground and climb rate
314  msg->altitude = scale_float2uword(telestate->altitude, 1, OFFSET_ALTITUDE);
315  msg->climbrate = scale_float2uword(telestate->climbrate1s, M_TO_CM, OFFSET_CLIMBRATE);
316  msg->climbrate3s = scale_float2uint8(telestate->climbrate3s, 1, OFFSET_CLIMBRATE3S);
317 
318  // number of satellites,gps fix and state
319  msg->gps_num_sat = telestate->GPS.Satellites;
320  switch (telestate->GPS.Status) {
321  case GPSPOSITION_STATUS_FIX2D:
322  msg->gps_fix_char = '2';
323  break;
324  case GPSPOSITION_STATUS_FIX3D:
325  case GPSPOSITION_STATUS_DIFF3D:
326  msg->gps_fix_char = '3';
327  break;
328  default:
329  msg->gps_fix_char = 0;
330  }
331  switch (telestate->SysAlarms.Alarm[SYSTEMALARMS_ALARM_GPS]) {
332  case SYSTEMALARMS_ALARM_UNINITIALISED:
333  msg->ascii6 = 0;
334  // if there is no gps, show compass flight direction
335  msg->flight_direction = scale_float2int8((telestate->Attitude.Yaw > 0) ? telestate->Attitude.Yaw : 360 + telestate->Attitude.Yaw , DEG_TO_UINT, 0);
336  break;
337  case SYSTEMALARMS_ALARM_OK:
338  msg->ascii6 = '.';
339  break;
340  case SYSTEMALARMS_ALARM_WARNING:
341  msg->ascii6 = '?';
342  break;
343  case SYSTEMALARMS_ALARM_ERROR:
344  case SYSTEMALARMS_ALARM_CRITICAL:
345  msg->ascii6 = '!';
346  break;
347  default:
348  msg->ascii6 = 0;
349  }
350 
351  // model angles
352  msg->angle_roll = scale_float2int8(telestate->Attitude.Roll, DEG_TO_UINT, 0);
353  msg->angle_nick = scale_float2int8(telestate->Attitude.Pitch, DEG_TO_UINT, 0);
354  msg->angle_compass = scale_float2int8(telestate->Attitude.Yaw, DEG_TO_UINT, 0);
355 
356  // gps time
357  msg->gps_hour = telestate->GPStime.Hour;
358  msg->gps_min = telestate->GPStime.Minute;
359  msg->gps_sec = telestate->GPStime.Second;
360  msg->gps_msec = 0;
361 
362  // gps MSL (NN) altitude MSL
363  msg->msl = scale_float2uword(telestate->GPS.Altitude, 1, 0);
364 
365  // free display chararacter
366  msg->ascii4 = 0;
367 
368  msg->checksum = calc_checksum((uint8_t *)msg, sizeof(*msg));
369  return sizeof(*msg);
370 }
371 
372 uint16_t build_GAM_message(struct hott_gam_message *msg) {
373  update_telemetrydata();
374 
375  if (telestate->Settings.Sensor[HOTTSETTINGS_SENSOR_GAM] == HOTTSETTINGS_SENSOR_DISABLED)
376  return 0;
377 
378  // clear message buffer
379  memset(msg, 0, sizeof(*msg));
380 
381  // message header
382  msg->start = HOTT_START;
383  msg->stop = HOTT_STOP;
384  msg->sensor_id = HOTT_GAM_ID;
385  msg->warning = generate_warning();
387 
388  // alarm inverse bits. invert display areas on limits
389  msg->alarm_inverse2 |= (telestate->Settings.Limit[HOTTSETTINGS_LIMIT_MAXCURRENT] < telestate->Battery.Current) ? GAM_INVERT2_CURRENT : 0;
390  msg->alarm_inverse2 |= (telestate->Settings.Limit[HOTTSETTINGS_LIMIT_MINPOWERVOLTAGE] > telestate->Battery.Voltage) ? GAM_INVERT2_VOLTAGE : 0;
391  msg->alarm_inverse2 |= (telestate->Settings.Limit[HOTTSETTINGS_LIMIT_MAXPOWERVOLTAGE] < telestate->Battery.Voltage) ? GAM_INVERT2_VOLTAGE : 0;
392  msg->alarm_inverse2 |= (telestate->Settings.Limit[HOTTSETTINGS_LIMIT_MINHEIGHT] > telestate->altitude) ? GAM_INVERT2_ALT : 0;
393  msg->alarm_inverse2 |= (telestate->Settings.Limit[HOTTSETTINGS_LIMIT_MAXHEIGHT] < telestate->altitude) ? GAM_INVERT2_ALT : 0;
394  msg->alarm_inverse2 |= (telestate->Settings.Limit[HOTTSETTINGS_LIMIT_NEGDIFFERENCE1] > telestate->climbrate1s) ? GAM_INVERT2_CR1S : 0;
395  msg->alarm_inverse2 |= (telestate->Settings.Limit[HOTTSETTINGS_LIMIT_POSDIFFERENCE1] < telestate->climbrate1s) ? GAM_INVERT2_CR1S : 0;
396  msg->alarm_inverse2 |= (telestate->Settings.Limit[HOTTSETTINGS_LIMIT_NEGDIFFERENCE2] > telestate->climbrate3s) ? GAM_INVERT2_CR3S : 0;
397  msg->alarm_inverse2 |= (telestate->Settings.Limit[HOTTSETTINGS_LIMIT_POSDIFFERENCE2] < telestate->climbrate3s) ? GAM_INVERT2_CR3S : 0;
398 
399  // temperatures
400  msg->temperature1 = scale_float2uint8(telestate->Gyro.temperature, 1, OFFSET_TEMPERATURE);
401  msg->temperature2 = scale_float2uint8(telestate->Baro.Temperature, 1, OFFSET_TEMPERATURE);
402 
403  // altitude
404  msg->altitude = scale_float2uword(telestate->altitude, 1, OFFSET_ALTITUDE);
405 
406  // climbrate
407  msg->climbrate = scale_float2uword(telestate->climbrate1s, M_TO_CM, OFFSET_CLIMBRATE);
408  msg->climbrate3s = scale_float2uint8(telestate->climbrate3s, 1, OFFSET_CLIMBRATE3S);
409 
410  // main battery
411  float voltage = (telestate->Battery.Voltage > 0) ? telestate->Battery.Voltage : 0;
412  float current = (telestate->Battery.Current > 0) ? telestate->Battery.Current : 0;
413  float energy = (telestate->Battery.ConsumedEnergy > 0) ? telestate->Battery.ConsumedEnergy : 0;
414  msg->voltage = scale_float2uword(voltage, 10, 0);
415  msg->current = scale_float2uword(current, 10, 0);
416  msg->capacity = scale_float2uword(energy, 0.1, 0);
417 
418  // pressure kPa to 0.1Bar
419  msg->pressure = scale_float2uint8(telestate->Baro.Pressure, 0.1, 0);
420 
421  msg->checksum = calc_checksum((uint8_t *)msg, sizeof(*msg));
422  return sizeof(*msg);
423 }
424 
425 uint16_t build_EAM_message(struct hott_eam_message *msg) {
426  update_telemetrydata();
427 
428  if (telestate->Settings.Sensor[HOTTSETTINGS_SENSOR_EAM] == HOTTSETTINGS_SENSOR_DISABLED)
429  return 0;
430 
431  // clear message buffer
432  memset(msg, 0, sizeof(*msg));
433 
434  // message header
435  msg->start = HOTT_START;
436  msg->stop = HOTT_STOP;
437  msg->sensor_id = HOTT_EAM_ID;
438  msg->warning = generate_warning();
440 
441  // alarm inverse bits. invert display areas on limits
442  msg->alarm_inverse1 |= (telestate->Settings.Limit[HOTTSETTINGS_LIMIT_MAXUSEDCAPACITY] < telestate->Battery.ConsumedEnergy) ? EAM_INVERT_CAPACITY : 0;
443  msg->alarm_inverse1 |= (telestate->Settings.Limit[HOTTSETTINGS_LIMIT_MAXCURRENT] < telestate->Battery.Current) ? EAM_INVERT_CURRENT : 0;
444  msg->alarm_inverse1 |= (telestate->Settings.Limit[HOTTSETTINGS_LIMIT_MINPOWERVOLTAGE] > telestate->Battery.Voltage) ? EAM_INVERT_VOLTAGE : 0;
445  msg->alarm_inverse1 |= (telestate->Settings.Limit[HOTTSETTINGS_LIMIT_MAXPOWERVOLTAGE] < telestate->Battery.Voltage) ? EAM_INVERT_VOLTAGE : 0;
446  msg->alarm_inverse2 |= (telestate->Settings.Limit[HOTTSETTINGS_LIMIT_MINHEIGHT] > telestate->altitude) ? EAM_INVERT2_ALT : 0;
447  msg->alarm_inverse2 |= (telestate->Settings.Limit[HOTTSETTINGS_LIMIT_MAXHEIGHT] < telestate->altitude) ? EAM_INVERT2_ALT : 0;
448  msg->alarm_inverse2 |= (telestate->Settings.Limit[HOTTSETTINGS_LIMIT_NEGDIFFERENCE1] > telestate->climbrate1s) ? EAM_INVERT2_CR1S : 0;
449  msg->alarm_inverse2 |= (telestate->Settings.Limit[HOTTSETTINGS_LIMIT_POSDIFFERENCE1] < telestate->climbrate1s) ? EAM_INVERT2_CR1S : 0;
450  msg->alarm_inverse2 |= (telestate->Settings.Limit[HOTTSETTINGS_LIMIT_NEGDIFFERENCE2] > telestate->climbrate3s) ? EAM_INVERT2_CR3S : 0;
451  msg->alarm_inverse2 |= (telestate->Settings.Limit[HOTTSETTINGS_LIMIT_POSDIFFERENCE2] < telestate->climbrate3s) ? EAM_INVERT2_CR3S : 0;
452 
453  // main battery
454  float voltage = (telestate->Battery.Voltage > 0) ? telestate->Battery.Voltage : 0;
455  float current = (telestate->Battery.Current > 0) ? telestate->Battery.Current : 0;
456  float energy = (telestate->Battery.ConsumedEnergy > 0) ? telestate->Battery.ConsumedEnergy : 0;
457  msg->voltage = scale_float2uword(voltage, 10, 0);
458  msg->current = scale_float2uword(current, 10, 0);
459  msg->capacity = scale_float2uword(energy, 0.1, 0);
460 
461  // temperatures
462  msg->temperature1 = scale_float2uint8(telestate->Gyro.temperature, 1, OFFSET_TEMPERATURE);
463  msg->temperature2 = scale_float2uint8(telestate->Baro.Temperature, 1, OFFSET_TEMPERATURE);
464 
465  // altitude
466  msg->altitude = scale_float2uword(telestate->altitude, 1, OFFSET_ALTITUDE);
467 
468  // climbrate
469  msg->climbrate = scale_float2uword(telestate->climbrate1s, M_TO_CM, OFFSET_CLIMBRATE);
470  msg->climbrate3s = scale_float2uint8(telestate->climbrate3s, 1, OFFSET_CLIMBRATE3S);
471 
472  // flight time
473  float flighttime = (telestate->Battery.EstimatedFlightTime <= 5999) ? telestate->Battery.EstimatedFlightTime : 5999;
474  msg->electric_min = flighttime / 60;
475  msg->electric_sec = flighttime - 60 * msg->electric_min;
476 
477  msg->checksum = calc_checksum((uint8_t *)msg, sizeof(*msg));
478  return sizeof(*msg);
479 }
480 
481 uint16_t build_ESC_message(struct hott_esc_message *msg) {
482  update_telemetrydata();
483 
484  if (telestate->Settings.Sensor[HOTTSETTINGS_SENSOR_ESC] == HOTTSETTINGS_SENSOR_DISABLED)
485  return 0;
486 
487  // clear message buffer
488  memset(msg, 0, sizeof(*msg));
489 
490  // message header
491  msg->start = HOTT_START;
492  msg->stop = HOTT_STOP;
493  msg->sensor_id = HOTT_ESC_ID;
494  msg->warning = 0;
496 
497  // main batterie
498  float voltage = (telestate->Battery.Voltage > 0) ? telestate->Battery.Voltage : 0;
499  float current = (telestate->Battery.Current > 0) ? telestate->Battery.Current : 0;
500  float max_current = (telestate->Battery.PeakCurrent > 0) ? telestate->Battery.PeakCurrent : 0;
501  float energy = (telestate->Battery.ConsumedEnergy > 0) ? telestate->Battery.ConsumedEnergy : 0;
502  msg->batt_voltage = scale_float2uword(voltage, 10, 0);
503  msg->current = scale_float2uword(current, 10, 0);
504  msg->max_current = scale_float2uword(max_current, 10, 0);
505  msg->batt_capacity = scale_float2uword(energy, 0.1, 0);
506 
507  // temperatures
508  msg->temperatureESC = scale_float2uint8(telestate->Gyro.temperature, 1, OFFSET_TEMPERATURE);
509  msg->max_temperatureESC = scale_float2uint8(0, 1, OFFSET_TEMPERATURE);
510  msg->temperatureMOT = scale_float2uint8(telestate->Baro.Temperature, 1, OFFSET_TEMPERATURE);
511  msg->max_temperatureMOT = scale_float2uint8(0, 1, OFFSET_TEMPERATURE);
512 
513  msg->checksum = calc_checksum((uint8_t *)msg, sizeof(*msg));
514  return sizeof(*msg);
515 }
516 
517 uint16_t build_TEXT_message(struct hott_text_message *msg) {
518  update_telemetrydata();
519 
520  // clear message buffer
521  memset(msg, 0, sizeof(*msg));
522 
523  // message header
524  msg->start = HOTT_START;
525  msg->stop = HOTT_STOP;
526  msg->sensor_id = HOTT_TEXT_ID;
527 
528  msg->checksum = calc_checksum((uint8_t *)msg, sizeof(*msg));
529  return sizeof(*msg);
530 }
531 
538 void update_telemetrydata () {
539  // update all available data
540  if (HoTTSettingsHandle() != NULL)
541  HoTTSettingsGet(&telestate->Settings);
542  if (AttitudeActualHandle() != NULL)
543  AttitudeActualGet(&telestate->Attitude);
544  if (BaroAltitudeHandle() != NULL)
545  BaroAltitudeGet(&telestate->Baro);
546  if (FlightBatteryStateHandle() != NULL)
547  FlightBatteryStateGet(&telestate->Battery);
548  if (FlightStatusHandle() != NULL)
549  FlightStatusGet(&telestate->FlightStatus);
550  if (GPSPositionHandle() != NULL)
551  GPSPositionGet(&telestate->GPS);
552  if (GPSTimeHandle() != NULL)
553  GPSTimeGet(&telestate->GPStime);
554  if (GyrosHandle() != NULL)
555  GyrosGet(&telestate->Gyro);
556  if (HomeLocationHandle() != NULL)
557  HomeLocationGet(&telestate->Home);
558  if (PositionActualHandle() != NULL)
559  PositionActualGet(&telestate->Position);
560  if (SystemAlarmsHandle() != NULL)
561  SystemAlarmsGet(&telestate->SysAlarms);
562  if (VelocityActualHandle() != NULL)
563  VelocityActualGet(&telestate->Velocity);
564 
565  // send actual climbrate value to ring buffer as mm per 0.2s values
566  uint8_t n = telestate->climbrate_pointer;
567  telestate->climbratebuffer[telestate->climbrate_pointer++] = -telestate->Velocity.Down * 200;
568  telestate->climbrate_pointer %= climbratesize;
569 
570  // calculate avarage climbrates in meters per 1, 3 and 10 second(s) based on 200ms interval
571  telestate->climbrate1s = 0;
572  telestate->climbrate3s = 0;
573  telestate->climbrate10s = 0;
574  for (uint8_t i = 0; i < climbratesize; i++) {
575  telestate->climbrate1s += (i < 5) ? telestate->climbratebuffer[n] : 0;
576  telestate->climbrate3s += (i < 15) ? telestate->climbratebuffer[n] : 0;
577  telestate->climbrate10s += (i < 50) ? telestate->climbratebuffer[n] : 0;
578  n += climbratesize - 1;
579  n %= climbratesize;
580  }
581  telestate->climbrate1s = telestate->climbrate1s / 1000;
582  telestate->climbrate3s = telestate->climbrate3s / 1000;
583  telestate->climbrate10s = telestate->climbrate10s / 1000;
584 
585  // set altitude offset and clear min/max values when arming
586  if ((telestate->FlightStatus.Armed == FLIGHTSTATUS_ARMED_ARMING) || ((telestate->last_armed != FLIGHTSTATUS_ARMED_ARMED) && (telestate->FlightStatus.Armed == FLIGHTSTATUS_ARMED_ARMED))) {
587  telestate->min_altitude = 0;
588  telestate->max_altitude = 0;
589  }
590  telestate->last_armed = telestate->FlightStatus.Armed;
591 
592  // calculate altitude relative to start position
593  telestate->altitude = -telestate->Position.Down;
594 
595  // check and set min/max values when armed.
596  if (telestate->FlightStatus.Armed == FLIGHTSTATUS_ARMED_ARMED) {
597  if (telestate->min_altitude > telestate->altitude)
598  telestate->min_altitude = telestate->altitude;
599  if (telestate->max_altitude < telestate->altitude)
600  telestate->max_altitude = telestate->altitude;
601  }
602 
603  // gps home position and course
604  telestate->homedistance = sqrtf(telestate->Position.North * telestate->Position.North + telestate->Position.East * telestate->Position.East);
605  telestate->homecourse = acosf(- telestate->Position.North / telestate->homedistance) / 3.14159265f * 180;
606  if (telestate->Position.East > 0)
607  telestate->homecourse = 360 - telestate->homecourse;
608 
609  // statusline
610  const char *txt_unknown = "unknown";
611  const char *txt_manual = "Manual";
612  const char *txt_acro = "Acro";
613  const char *txt_leveling = "Leveling";
614  const char *txt_virtualbar = "Virtualbar";
615  const char *txt_stabilized1 = "Stabilized1";
616  const char *txt_stabilized2 = "Stabilized2";
617  const char *txt_stabilized3 = "Stabilized3";
618  const char *txt_autotune = "Autotune";
619  const char *txt_altitudehold = "AltitudeHold";
620  const char *txt_positionhold = "PositionHold";
621  const char *txt_returntohome = "ReturnToHome";
622  const char *txt_pathplanner = "PathPlanner";
623  const char *txt_tabletcontrol = "TabletCtrl";
624  const char *txt_failsafe = "Failsafe";
625  const char *txt_disarmed = "Disarmed";
626  const char *txt_arming = "Arming";
627  const char *txt_armed = "Armed";
628 
629  const char *txt_flightmode;
630  switch (telestate->FlightStatus.FlightMode) {
631  case FLIGHTSTATUS_FLIGHTMODE_MANUAL:
632  txt_flightmode = txt_manual;
633  break;
634  case FLIGHTSTATUS_FLIGHTMODE_ACRO:
635  txt_flightmode = txt_acro;
636  break;
637  case FLIGHTSTATUS_FLIGHTMODE_LEVELING:
638  txt_flightmode = txt_leveling;
639  break;
640  case FLIGHTSTATUS_FLIGHTMODE_VIRTUALBAR:
641  txt_flightmode = txt_virtualbar;
642  break;
643  case FLIGHTSTATUS_FLIGHTMODE_STABILIZED1:
644  txt_flightmode = txt_stabilized1;
645  break;
646  case FLIGHTSTATUS_FLIGHTMODE_STABILIZED2:
647  txt_flightmode = txt_stabilized2;
648  break;
649  case FLIGHTSTATUS_FLIGHTMODE_STABILIZED3:
650  txt_flightmode = txt_stabilized3;
651  break;
652  case FLIGHTSTATUS_FLIGHTMODE_AUTOTUNE:
653  txt_flightmode = txt_autotune;
654  break;
655  case FLIGHTSTATUS_FLIGHTMODE_ALTITUDEHOLD:
656  txt_flightmode = txt_altitudehold;
657  break;
658  case FLIGHTSTATUS_FLIGHTMODE_POSITIONHOLD:
659  txt_flightmode = txt_positionhold;
660  break;
661  case FLIGHTSTATUS_FLIGHTMODE_RETURNTOHOME:
662  txt_flightmode = txt_returntohome;
663  break;
664  case FLIGHTSTATUS_FLIGHTMODE_PATHPLANNER:
665  txt_flightmode = txt_pathplanner;
666  break;
667  case FLIGHTSTATUS_FLIGHTMODE_TABLETCONTROL:
668  txt_flightmode = txt_tabletcontrol;
669  break;
670  case FLIGHTSTATUS_FLIGHTMODE_FAILSAFE:
671  txt_flightmode = txt_failsafe;
672  break;
673  default:
674  txt_flightmode = txt_unknown;
675  }
676 
677  const char *txt_armstate;
678  switch (telestate->FlightStatus.Armed) {
679  case FLIGHTSTATUS_ARMED_DISARMED:
680  txt_armstate = txt_disarmed;
681  break;
682  case FLIGHTSTATUS_ARMED_ARMING:
683  txt_armstate = txt_arming;
684  break;
685  case FLIGHTSTATUS_ARMED_ARMED:
686  txt_armstate = txt_armed;
687  break;
688  default:
689  txt_armstate = txt_unknown;
690  }
691 
692  snprintf(telestate->statusline, sizeof(telestate->statusline), "%12s,%8s", txt_flightmode, txt_armstate);
693 }
694 
698 uint8_t generate_warning() {
699  // set warning tone with hardcoded priority
700  if ((telestate->Settings.Warning[HOTTSETTINGS_WARNING_MINSPEED] == HOTTSETTINGS_WARNING_ENABLED) &&
701  (telestate->Settings.Limit[HOTTSETTINGS_LIMIT_MINSPEED] > telestate->GPS.Groundspeed * MS_TO_KMH))
702  return HOTT_TONE_A; // maximum speed
703 
704  if ((telestate->Settings.Warning[HOTTSETTINGS_WARNING_NEGDIFFERENCE2] == HOTTSETTINGS_WARNING_ENABLED) &&
705  (telestate->Settings.Limit[HOTTSETTINGS_LIMIT_NEGDIFFERENCE2] > telestate->climbrate3s))
706  return HOTT_TONE_B; // sink rate 3s
707 
708  if ((telestate->Settings.Warning[HOTTSETTINGS_WARNING_NEGDIFFERENCE1] == HOTTSETTINGS_WARNING_ENABLED) &&
709  (telestate->Settings.Limit[HOTTSETTINGS_LIMIT_NEGDIFFERENCE2] > telestate->climbrate1s))
710  return HOTT_TONE_C; // sink rate 1s
711 
712  if ((telestate->Settings.Warning[HOTTSETTINGS_WARNING_MAXDISTANCE] == HOTTSETTINGS_WARNING_ENABLED) &&
713  (telestate->Settings.Limit[HOTTSETTINGS_LIMIT_MAXDISTANCE] < telestate->homedistance))
714  return HOTT_TONE_D; // maximum distance
715 
716  if ((telestate->Settings.Warning[HOTTSETTINGS_WARNING_MINSENSOR1TEMP] == HOTTSETTINGS_WARNING_ENABLED) &&
717  (telestate->Settings.Limit[HOTTSETTINGS_LIMIT_MINSENSOR1TEMP] > telestate->Gyro.temperature))
718  return HOTT_TONE_F; // minimum temperature sensor 1
719 
720  if ((telestate->Settings.Warning[HOTTSETTINGS_WARNING_MINSENSOR2TEMP] == HOTTSETTINGS_WARNING_ENABLED) &&
721  (telestate->Settings.Limit[HOTTSETTINGS_LIMIT_MINSENSOR2TEMP] > telestate->Baro.Temperature))
722  return HOTT_TONE_G; // minimum temperature sensor 2
723 
724  if ((telestate->Settings.Warning[HOTTSETTINGS_WARNING_MAXSENSOR1TEMP] == HOTTSETTINGS_WARNING_ENABLED) &&
725  (telestate->Settings.Limit[HOTTSETTINGS_LIMIT_MAXSENSOR1TEMP] < telestate->Gyro.temperature))
726  return HOTT_TONE_H; // maximum temperature sensor 1
727 
728  if ((telestate->Settings.Warning[HOTTSETTINGS_WARNING_MAXSENSOR2TEMP] == HOTTSETTINGS_WARNING_ENABLED) &&
729  (telestate->Settings.Limit[HOTTSETTINGS_LIMIT_MAXSENSOR2TEMP] < telestate->Baro.Temperature))
730  return HOTT_TONE_I; // maximum temperature sensor 2
731 
732  if ((telestate->Settings.Warning[HOTTSETTINGS_WARNING_MAXSPEED] == HOTTSETTINGS_WARNING_ENABLED) &&
733  (telestate->Settings.Limit[HOTTSETTINGS_LIMIT_MAXSPEED] < telestate->GPS.Groundspeed * MS_TO_KMH))
734  return HOTT_TONE_L; // maximum speed
735 
736  if ((telestate->Settings.Warning[HOTTSETTINGS_WARNING_POSDIFFERENCE2] == HOTTSETTINGS_WARNING_ENABLED) &&
737  (telestate->Settings.Limit[HOTTSETTINGS_LIMIT_POSDIFFERENCE2] > telestate->climbrate3s))
738  return HOTT_TONE_M; // climb rate 3s
739 
740  if ((telestate->Settings.Warning[HOTTSETTINGS_WARNING_POSDIFFERENCE1] == HOTTSETTINGS_WARNING_ENABLED) &&
741  (telestate->Settings.Limit[HOTTSETTINGS_LIMIT_POSDIFFERENCE1] > telestate->climbrate1s))
742  return HOTT_TONE_N; // climb rate 1s
743 
744  if ((telestate->Settings.Warning[HOTTSETTINGS_WARNING_MINHEIGHT] == HOTTSETTINGS_WARNING_ENABLED) &&
745  (telestate->Settings.Limit[HOTTSETTINGS_LIMIT_MINHEIGHT] > telestate->altitude))
746  return HOTT_TONE_O; // minimum height
747 
748  if ((telestate->Settings.Warning[HOTTSETTINGS_WARNING_MINPOWERVOLTAGE] == HOTTSETTINGS_WARNING_ENABLED) &&
749  (telestate->Settings.Limit[HOTTSETTINGS_LIMIT_MINPOWERVOLTAGE] > telestate->Battery.Voltage))
750  return HOTT_TONE_P; // minimum input voltage
751 
752  if ((telestate->Settings.Warning[HOTTSETTINGS_WARNING_MAXUSEDCAPACITY] == HOTTSETTINGS_WARNING_ENABLED) &&
753  (telestate->Settings.Limit[HOTTSETTINGS_LIMIT_MAXUSEDCAPACITY] < telestate->Battery.ConsumedEnergy))
754  return HOTT_TONE_V; // capacity
755 
756  if ((telestate->Settings.Warning[HOTTSETTINGS_WARNING_MAXCURRENT] == HOTTSETTINGS_WARNING_ENABLED) &&
757  (telestate->Settings.Limit[HOTTSETTINGS_LIMIT_MAXCURRENT] < telestate->Battery.Current))
758  return HOTT_TONE_W; // maximum current
759 
760  if ((telestate->Settings.Warning[HOTTSETTINGS_WARNING_MAXPOWERVOLTAGE] == HOTTSETTINGS_WARNING_ENABLED) &&
761  (telestate->Settings.Limit[HOTTSETTINGS_LIMIT_MAXPOWERVOLTAGE] < telestate->Battery.Voltage))
762  return HOTT_TONE_X; // maximum input voltage
763 
764  if ((telestate->Settings.Warning[HOTTSETTINGS_WARNING_MAXHEIGHT] == HOTTSETTINGS_WARNING_ENABLED) &&
765  (telestate->Settings.Limit[HOTTSETTINGS_LIMIT_MAXHEIGHT] < telestate->altitude))
766  return HOTT_TONE_Z; // maximum height
767 
768  // altitude beeps when crossing altitude limits at 20,40,60,80,100,200,400,600,800 and 1000 meters
769  if (telestate->Settings.Warning[HOTTSETTINGS_WARNING_ALTITUDEBEEP] == HOTTSETTINGS_WARNING_ENABLED) {
770  // update altitude when checked for beeps
771  float last = telestate->altitude_last;
772  float actual = telestate->altitude;
773  telestate->altitude_last = telestate->altitude;
774  if (((last < 20) && (actual >= 20)) || ((last > 20) && (actual <= 20)))
775  return HOTT_TONE_20M;
776  if (((last < 40) && (actual >= 40)) || ((last > 40) && (actual <= 40)))
777  return HOTT_TONE_40M;
778  if (((last < 60) && (actual >= 60)) || ((last > 60) && (actual <= 60)))
779  return HOTT_TONE_60M;
780  if (((last < 80) && (actual >= 80)) || ((last > 80) && (actual <= 80)))
781  return HOTT_TONE_80M;
782  if (((last < 100) && (actual >= 100)) || ((last > 100) && (actual <= 100)))
783  return HOTT_TONE_100M;
784  if (((last < 200) && (actual >= 200)) || ((last > 200) && (actual <= 200)))
785  return HOTT_TONE_200M;
786  if (((last < 400) && (actual >= 400)) || ((last > 400) && (actual <= 400)))
787  return HOTT_TONE_400M;
788  if (((last < 600) && (actual >= 600)) || ((last > 600) && (actual <= 600)))
789  return HOTT_TONE_600M;
790  if (((last < 800) && (actual >= 800)) || ((last > 800) && (actual <= 800)))
791  return HOTT_TONE_800M;
792  if (((last < 1000) && (actual >= 1000)) || ((last > 1000) && (actual <= 1000)))
793  return HOTT_TONE_1000M;
794  }
795 
796  // there is no warning
797  return 0;
798 }
799 
803 uint8_t calc_checksum(uint8_t *data, uint16_t size) {
804  uint16_t sum = 0;
805  for(int i = 0; i < size; i++)
806  sum += data[i];
807  return sum;
808 }
809 
813 uint8_t scale_float2uint8(float value, float scale, float offset) {
814  uint16_t temp = (uint16_t)roundf(value * scale + offset);
815  uint8_t result;
816  result = (uint8_t)temp & 0xff;
817  return result;
818 }
819 
823 int8_t scale_float2int8(float value, float scale, float offset) {
824  int8_t result = (int8_t)roundf(value * scale + offset);
825  return result;
826 }
827 
831 uword_t scale_float2uword(float value, float scale, float offset) {
832  uint16_t temp = (uint16_t)roundf(value * scale + offset);
833  uword_t result;
834  result.l = (uint8_t)temp & 0xff;
835  result.h = (uint8_t)(temp >> 8) & 0xff;
836  return result;
837 }
838 
842 void convert_long2gps(int32_t value, uint8_t *dir, uword_t *min, uword_t *sec) {
843  //convert gps decigrad value into degrees, minutes and seconds
844  uword_t temp;
845  uint32_t absvalue = abs(value);
846  uint16_t degrees = (absvalue / 10000000);
847  uint32_t seconds = (absvalue - degrees * 10000000) * 6;
848  uint16_t minutes = seconds / 1000000;
849  seconds %= 1000000;
850  seconds = seconds / 100;
851  uint16_t degmin = degrees * 100 + minutes;
852  // write results
853  *dir = (value < 0) ? 1 : 0;
854  temp.l = (uint8_t)degmin & 0xff;
855  temp.h = (uint8_t)(degmin >> 8) & 0xff;
856  *min = temp;
857  temp.l = (uint8_t)seconds & 0xff;
858  temp.h = (uint8_t)(seconds >> 8) & 0xff;
859  *sec = temp;
860 }
861 
862 #endif /* PIOS_INCLUDE_HOTT */
863 
#define OFFSET_CLIMBRATE3S
#define HOTT_BUTTON_INC
uint32_t PIOS_Thread_Systime(void)
Definition: pios_thread.c:212
#define VARIO_INVERT_CR3S
#define VARIO_INVERT_CR10S
#define GAM_INVERT2_ALT
HomeLocationData Home
#define GAM_INVERT2_CURRENT
Main PiOS header to include all the compiled in PiOS options.
#define HOTT_GAM_ID
#define DEG_TO_UINT
#define HOTT_TONE_800M
#define HOTT_TONE_1000M
#define VARIO_INVERT_ALT
#define VARIO_INVERT_CR1S
bool PIOS_Modules_IsEnabled(enum pios_modules module)
Definition: pios_modules.c:41
PositionActualData Position
static float scale(float val, float inMin, float inMax, float outMin, float outMax)
Definition: txpid.c:444
uint8_t flight_direction
#define STACK_SIZE_BYTES
Definition: actuator.c:62
#define HOTT_BUTTON_DEC
sends telemery data on HoTT request
#define OFFSET_TEMPERATURE
#define HOTT_TONE_L
void * PIOS_malloc(size_t size)
Definition: pios_heap.c:125
#define GPS_INVERT2_POS
SystemAlarmsData SysAlarms
#define HOTT_EAM_ID
#define GPS_INVERT_SPEED
bool module_enabled
#define GPS_INVERT_HDIST
#define HOTT_ESC_TEXT_ID
uint8_t last_armed
#define EAM_INVERT2_CR1S
#define TASK_PRIORITY
Definition: actuator.c:65
#define HOTT_TONE_G
#define VARIO_INVERT_MAX
#define HOTT_BUTTON_NIL
#define HOTT_TONE_Z
uint8_t max_temperatureESC
#define GPS_INVERT_ALT
#define HOTT_BINARY_ID
#define M_TO_CM
uint8_t data[XFER_BYTES_PER_PACKET]
Definition: bl_messages.h:129
#define HOTT_TONE_80M
#define HOTT_TONE_N
HoTTSettingsData Settings
#define HOTT_TONE_M
GyrosData Gyro
#define HOTT_TONE_I
#define HOTT_STOP
char statusline[statussize]
#define MS_TO_KMH
#define MODULE_INITCALL(ifn, sfn)
Definition: pios_initcall.h:67
#define DATA_TIME
#define HOTT_TEXT_ID
uint16_t PIOS_COM_ReceiveBuffer(uintptr_t com_id, uint8_t *buf, uint16_t buf_len, uint32_t timeout_ms)
#define GPS_INVERT_CR1S
#define HOTT_TONE_A
#define HOTT_VARIO_TEXT_ID
#define HOTT_TONE_600M
#define EAM_INVERT_VOLTAGE
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
#define HOTT_TONE_D
GPSPositionData GPS
#define VARIO_INVERT_MIN
#define HOTT_TONE_V
#define OFFSET_CLIMBRATE
#define EAM_INVERT_CURRENT
#define HOTT_TONE_40M
int32_t TaskMonitorAdd(TaskInfoRunningElem task, struct pios_thread *threadp)
Definition: taskmonitor.c:67
uint8_t i
Definition: msp_messages.h:97
#define HOTT_VARIO_ID
#define HOTT_TONE_200M
FlightStatusData FlightStatus
#define EAM_INVERT_CAPACITY
#define HOTT_TONE_O
#define PIOS_COM_HOTT
Definition: pios_board.h:118
uint8_t climbrate_pointer
#define HOTT_GPS_TEXT_ID
#define HOTT_TONE_H
AttitudeActualData Attitude
#define HOTT_TONE_60M
#define HOTT_TONE_400M
uint16_t value
Definition: storm32bgc.c:155
uint16_t current
BaroAltitudeData Baro
void PIOS_Thread_Sleep_Until(uint32_t *previous_ms, uint32_t increment_ms)
Definition: pios_thread.c:255
uint8_t l
#define HOTT_EAM_TEXT_ID
#define EAM_INVERT2_CR3S
int32_t PIOS_COM_SendCharNonBlocking(uintptr_t com_id, char c)
#define HOTT_TONE_100M
#define HOTT_GPS_ID
uint32_t offset
Definition: uavtalk_priv.h:51
#define HOTT_TONE_20M
#define OFFSET_ALTITUDE
#define HOTT_TONE_X
int16_t climbratebuffer[climbratesize]
#define HOTT_BUTTON_SET
GPSTimeData GPStime
#define HOTT_ESC_ID
#define HOTT_BUTTON_PREV
#define HOTT_START
#define HOTT_MAX_MESSAGE_LENGTH
#define climbratesize
int snprintf(char *buf, size_t count, const char *format,...)
#define HOTT_TONE_B
#define HOTT_GAM_TEXT_ID
#define GAM_INVERT2_CR1S
#define GPS_INVERT_CR3S
FlightBatteryStateData Battery
uint16_t voltage
static uint32_t lastSysTime
#define HOTT_TONE_F
#define HOTT_TONE_P
#define IDLE_TIME
uint8_t max_temperatureMOT
#define HOTT_TONE_C
uint8_t h
#define HOTT_TONE_W
#define EAM_INVERT2_ALT
#define HOTT_BUTTON_NEXT
int32_t PIOS_COM_ChangeBaud(uintptr_t com_id, uint32_t baud)
uint16_t min
Definition: msp_messages.h:96
VelocityActualData Velocity
#define GAM_INVERT2_CR3S
#define GAM_INVERT2_VOLTAGE