2 ******************************************************************************
3 * @addtogroup OpenPilotModules OpenPilot Modules
5 * @addtogroup OSDOUTPUTModule OSDOutput Module
6 * @brief On screen display support
10 * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
11 * @brief Interfacing with OSD module
12 * @see The GNU Public License (GPL) Version 3
14 *****************************************************************************/
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.
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
26 * You should have received a copy of the GNU General Public License along
27 * with this program; if not, write to the Free Software Foundation, Inc.,
28 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
31 #include "openpilot.h"
33 #if FLIGHTBATTERYSTATE_SUPPORTED
34 #include "flightbatterystate.h"
37 #if POSITIONACTUAL_SUPPORTED
38 #include "positionstate.h"
41 #include "systemalarms.h"
42 #include "attitudestate.h"
43 #include "hwsettings.h"
44 #include "flightstatus.h"
46 static bool osdoutputEnabled
;
49 OSD_HK_SYNC_A
= 0xCB, OSD_HK_SYNC_B
= 0x34,
52 enum osd_hk_pkt_type
{
53 OSD_HK_PKT_TYPE_MISC
= 0, OSD_HK_PKT_TYPE_NAV
= 1, OSD_HK_PKT_TYPE_MAINT
= 2, OSD_HK_PKT_TYPE_ATT
= 3, OSD_HK_PKT_TYPE_MODE
= 4,
56 enum osd_hk_control_mode
{
57 OSD_HK_CONTROL_MODE_MANUAL
= 0, OSD_HK_CONTROL_MODE_STABILIZED
= 1, OSD_HK_CONTROL_MODE_AUTO
= 2,
60 struct osd_hk_blob_misc
{
61 uint8_t type
; /* Always OSD_HK_PKT_TYPE_MISC */
64 // uint16_t home; /* Big Endian */
65 enum osd_hk_control_mode control_mode
;
67 uint16_t current
; /* Big Endian */
68 } __attribute__((packed
));
70 struct osd_hk_blob_att
{
71 uint8_t type
; /* Always OSD_HK_PKT_TYPE_ATT */
75 int16_t speed
; /* Big Endian */
76 } __attribute__((packed
));
78 struct osd_hk_blob_nav
{
79 uint8_t type
; /* Always OSD_HK_PKT_TYPE_NAV */
80 uint32_t gps_lat
; /* Big Endian */
81 uint32_t gps_lon
; /* Big Endian */
82 } __attribute__((packed
));
84 struct osd_hk_blob_maint
{
85 uint8_t type
; /* Always OSD_HK_PKT_TYPE_MAINT */
87 uint16_t gps_alt
; /* Big Endian */
88 uint16_t gps_dis
; /* Big Endian */
92 } __attribute__((packed
));
94 struct osd_hk_blob_mode
{
95 uint8_t type
; /* Always OSD_HK_PKT_TYPE_MODE */
97 uint16_t gps_alt
; /* Big Endian */
98 uint16_t gps_dis
; /* Big Endian */
102 } __attribute__((packed
));
104 union osd_hk_pkt_blobs
{
105 struct osd_hk_blob_misc misc
;
106 struct osd_hk_blob_nav nav
;
107 struct osd_hk_blob_maint maint
;
108 struct osd_hk_blob_att att
;
109 struct osd_hk_blob_mode mode
;
110 } __attribute__((packed
));
113 enum osd_hk_sync sync
;
114 enum osd_hk_pkt_type t
;
115 union osd_hk_pkt_blobs v
;
116 } __attribute__((packed
));
118 static struct osd_hk_msg osd_hk_msg_buf
;
120 static volatile bool newPositionStateData
= false;
121 static volatile bool newBattData
= false;
122 static volatile bool newAttitudeData
= false;
123 static volatile bool newAlarmData
= false;
125 static uint32_t osd_hk_com_id
;
126 static uint8_t osd_hk_msg_dropped
;
127 static uint8_t osd_packet
;
129 static void send_update(__attribute__((unused
)) UAVObjEvent
*ev
)
131 static enum osd_hk_sync sync
= OSD_HK_SYNC_A
;
133 struct osd_hk_msg
*msg
= &osd_hk_msg_buf
;
134 union osd_hk_pkt_blobs
*blob
= &(osd_hk_msg_buf
.v
);
136 /* Make sure we have a COM port bound */
137 if (!osd_hk_com_id
) {
141 FlightStatusData flightStatus
;
148 switch (osd_packet
) {
149 case OSD_HK_PKT_TYPE_MISC
:
151 case OSD_HK_PKT_TYPE_NAV
:
153 case OSD_HK_PKT_TYPE_MAINT
:
155 case OSD_HK_PKT_TYPE_ATT
:
156 msg
->t
= OSD_HK_PKT_TYPE_ATT
;
158 AttitudeStateRollGet(&roll
);
159 blob
->att
.roll
= (int16_t)(roll
* 10);
162 AttitudeStatePitchGet(&pitch
);
163 blob
->att
.pitch
= (int16_t)(pitch
* 10);
166 AttitudeStateYawGet(&yaw
);
167 blob
->att
.yaw
= (int16_t)(yaw
* 10);
169 case OSD_HK_PKT_TYPE_MODE
:
170 msg
->t
= OSD_HK_PKT_TYPE_MODE
;
171 FlightStatusGet(&flightStatus
);
172 blob
->mode
.fltmode
= flightStatus
.FlightMode
;
173 blob
->mode
.armed
= flightStatus
.Armed
;
179 /* Field not supported yet */
180 // blob->misc.control_mode = 0;
181 /*if (newAlarmData) {
182 SystemAlarmsData alarms;
183 SystemAlarmsGet(&alarms);
185 switch (alarms.Alarm[SYSTEMALARMS_ALARM_BATTERY]) {
186 case SYSTEMALARMS_ALARM_UNINITIALISED:
187 case SYSTEMALARMS_ALARM_OK:
188 blob->misc.low_battery = 0;
190 case SYSTEMALARMS_ALARM_WARNING:
191 case SYSTEMALARMS_ALARM_ERROR:
192 case SYSTEMALARMS_ALARM_CRITICAL:
194 blob->misc.low_battery = 1;
198 newAlarmData = false;
201 #if FLIGHTBATTERYSUPPORTED
203 float consumed_energy
;
204 FlightBatteryStateConsumedEnergyGet(&consumed_energy
);
206 uint16_t current
= (uint16_t)(consumed_energy
* 10);
208 /* convert to big endian */
209 blob
->misc
.current
= (
210 (current
& 0xFF00 >> 8) |
211 (current
& 0x00FF << 8));
216 // blob->misc.current = 0;
219 #if POSITIONACTUAL_SUPPORTED
220 if (newPositionStateData
) {
221 PositionStateData position
;
222 PositionStateGet(&position
);
224 /* compute 3D distance */
226 pow(position
.North
, 2) +
227 pow(position
.East
, 2) +
228 pow(position
.Down
, 2));
229 /* convert from cm to dm (10ths of m) */
230 uint16_t home
= (uint16_t)(d
/ 10);
232 /* convert to big endian */
234 (home
& 0xFF00 >> 8) |
235 (home
& 0x00FF << 8));
237 newPositionStateData
= false;
240 // blob->misc.home = 0;
241 #endif /* if POSITIONACTUAL_SUPPORTED */
243 if (!PIOS_COM_SendBufferNonBlocking(osd_hk_com_id
, (uint8_t *)&osd_hk_msg_buf
, sizeof(osd_hk_msg_buf
))) {
244 /* Sent a packet, flip to the opposite sync */
245 if (sync
== OSD_HK_SYNC_A
) {
246 sync
= OSD_HK_SYNC_B
;
248 sync
= OSD_HK_SYNC_A
;
251 /* Failed to send this update */
252 osd_hk_msg_dropped
++;
255 if (osd_packet
> OSD_HK_PKT_TYPE_MODE
) {
256 osd_packet
= OSD_HK_PKT_TYPE_MISC
;
260 static UAVObjEvent ev
;
262 static int32_t osdoutputStart(void)
264 if (osdoutputEnabled
) {
265 /* Start a periodic timer to kick sending of an update */
266 EventPeriodicCallbackCreate(&ev
, send_update
, 25 / portTICK_RATE_MS
);
272 static int32_t osdoutputInitialize(void)
274 osd_hk_com_id
= PIOS_COM_OSDHK
;
275 #ifdef MODULE_OSDOUTPUT_BUILTIN
276 osdoutputEnabled
= 1;
278 HwSettingsInitialize();
279 HwSettingsOptionalModulesData optionalModules
;
280 HwSettingsOptionalModulesGet(&optionalModules
);
281 if (optionalModules
.OsdHk
== HWSETTINGS_OPTIONALMODULES_ENABLED
) {
282 osdoutputEnabled
= 1;
284 osdoutputEnabled
= 0;
289 MODULE_INITCALL(osdoutputInitialize
, osdoutputStart
);