dRonin  adbada4
dRonin firmware
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
charonscreendisplay.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  * Additional note on redistribution: The copyright and license notices above
29  * must be maintained in each individual source file that is a derivative work
30  * of this source file; otherwise redistribution is prohibited.
31  */
32 
33 #include <openpilot.h>
34 #include <pios_board_info.h>
35 #include "pios_thread.h"
36 #include "misc_math.h"
37 #include "pios_modules.h"
38 #include "pios_sensors.h"
39 
40 #include "modulesettings.h"
41 
42 #include "physical_constants.h"
43 
44 #include "accels.h"
45 #include "attitudeactual.h"
46 #include "baroaltitude.h"
47 #include "flightstatus.h"
48 #include "flightbatterystate.h"
49 #include "flightbatterysettings.h"
50 #include "flightstats.h"
51 #include "gpsposition.h"
52 #include "positionactual.h"
53 #include "gpstime.h"
54 #include "gpssatellites.h"
55 #include "gpsvelocity.h"
56 #include "homelocation.h"
57 #include "magnetometer.h"
58 #include "manualcontrolcommand.h"
59 #include "modulesettings.h"
60 #include "stabilizationdesired.h"
61 #include "stabilizationsettings.h"
62 #include "stateestimation.h"
63 #include "systemalarms.h"
64 #include "systemstats.h"
65 #include "tabletinfo.h"
66 #include "taskinfo.h"
67 #include "velocityactual.h"
68 #include "vtxinfo.h"
69 #include "waypoint.h"
70 #include "waypointactive.h"
71 
72 #include "charosd.h"
73 
74 #define STACK_SIZE_BYTES 3072
75 #define TASK_PRIORITY PIOS_THREAD_PRIO_LOW
76 
77 #define SPLASH_TIME_MS (5*1000)
78 
80 
81 static void panel_draw(charosd_state_t state, uint8_t panel, uint8_t x, uint8_t y)
82 {
83  if (panel <= CHARONSCREENDISPLAYSETTINGS_PANELTYPE_MAXOPTVAL) {
84  if (panels[panel].update &&
85  HAS_SENSOR(state->available, panels[panel].requirements)) {
86  panels[panel].update(state, x, y);
87  }
88  }
89 }
90 
91 static void screen_draw(charosd_state_t state, CharOnScreenDisplaySettingsData *page)
92 {
93  PIOS_MAX7456_clear (state->dev);
94 
95  for (uint8_t i = 0; i < CHARONSCREENDISPLAYSETTINGS_PANELTYPE_NUMELEM;
96  i++) {
97  panel_draw(state, page->PanelType[i], page->X[i], page->Y[i]);
98  }
99 }
100 
101 static const uint8_t charosd_font_data[] = {
102 #include "charosd-font.h"
103 };
104 
105 #ifndef CHAROSD_FONT_MINIMAL
106 static const uint8_t charosd_font_small_data[] = {
107 #include "charosd-font-small.h"
108 };
109 
110 static const uint8_t charosd_font_thin_data[] = {
111 #include "charosd-font-thin.h"
112 };
113 #endif
114 
115 static void set_mode(charosd_state_t state, uint8_t video_std)
116 {
117  state->video_standard = video_std;
118 
119  switch (video_std) {
120  case CHARONSCREENDISPLAYSETTINGS_VIDEOSTANDARD_AUTODETECTPREFERPAL:
121  PIOS_MAX7456_set_mode(state->dev, false,
123  break;
124  case CHARONSCREENDISPLAYSETTINGS_VIDEOSTANDARD_AUTODETECTPREFERNTSC:
125  PIOS_MAX7456_set_mode(state->dev, false,
127  break;
128  case CHARONSCREENDISPLAYSETTINGS_VIDEOSTANDARD_FORCEPAL:
129  PIOS_MAX7456_set_mode(state->dev, true,
131  break;
132  case CHARONSCREENDISPLAYSETTINGS_VIDEOSTANDARD_FORCENTSC:
133  PIOS_MAX7456_set_mode(state->dev, true,
135  break;
136  default:
137  PIOS_Assert(0);
138  break;
139  }
140 }
141 
142 /* 12 x 18 x 2bpp */
143 #define FONT_CHAR_SIZE ((12 * 18 * 2) / 8)
144 
146 {
147  const char *loaded_txt = "";
148 
149  const uint8_t *font_data = charosd_font_data;
150  bool changed = false;
151 
152  switch (font) {
153  case CHARONSCREENDISPLAYSETTINGS_FONT_THIN:
154 #ifndef CHAROSD_FONT_MINIMAL
155  font_data = charosd_font_thin_data;
156  loaded_txt = "loaded thin font";
157  break;
158 #endif
159  case CHARONSCREENDISPLAYSETTINGS_FONT_SMALL:
160 #ifndef CHAROSD_FONT_MINIMAL
161  font_data = charosd_font_small_data;
162  loaded_txt = "loaded small font";
163  break;
164 #endif
165  case CHARONSCREENDISPLAYSETTINGS_FONT_REGULAR:
166  font_data = charosd_font_data;
167  loaded_txt = "loaded regular font";
168  break;
169  }
170 
171  /* Check on font data, replacing chars as appropriate. */
172  for (int i = 0; i < 256; i++) {
173  const uint8_t *this_char = &font_data[i * FONT_CHAR_SIZE];
174  /* Every 8 characters, take a break, let other lowprio
175  * tasks run */
176  if ((i & 0x7) == 0) {
178  }
179 
180  uint8_t nvm_char[FONT_CHAR_SIZE];
181 
182  PIOS_MAX7456_download_char(state->dev, i, nvm_char);
183 
184  /* Only do this when necessary, because it's slow and wears
185  * NVRAM. */
186  if (memcmp(nvm_char, this_char, FONT_CHAR_SIZE)) {
188  this_char);
189  changed = true;
190  }
191  }
192  if (changed) {
194  6, loaded_txt, 0);
195  PIOS_Thread_Sleep(1000);
196  }
197  state->prev_font = font;
198 }
199 
201 {
202  state->available = 0;
203 
204  ModuleSettingsData module_settings;
205  ModuleSettingsGet(&module_settings);
206 
207  // TODO(dsal): Figure out how to determine whether this is
208  // configured meaningfully
209  state->available |= HAS_RSSI;
210 
212  state->available |= HAS_ALT;
213  }
215  state->available |= HAS_COMPASS;
216  }
218  state->available |= HAS_GPS;
219  }
220  if (module_settings.AdminState[MODULESETTINGS_ADMINSTATE_BATTERY] &&
221  FlightBatteryStateHandle()) {
222  state->available |= HAS_BATT;
223  }
224  if (module_settings.AdminState[MODULESETTINGS_ADMINSTATE_AIRSPEED]) {
225  state->available |= HAS_PITOT;
226  }
227 
228  uint8_t filter;
229  StateEstimationNavigationFilterGet(&filter);
230  if (filter != STATEESTIMATION_NAVIGATIONFILTER_NONE) {
231  state->available |= HAS_NAV;
232  }
233 
234 }
235 
237 {
238  SystemStatsFlightTimeGet(&state->telemetry.system.flight_time);
239  AttitudeActualGet(&state->telemetry.attitude_actual);
240  PositionActualGet(&state->telemetry.position_actual);
241  StabilizationDesiredThrustGet(&state->telemetry.manual.thrust);
242  FlightStatusArmedGet(&state->telemetry.flight_status.arm_status);
243  FlightStatusFlightModeGet(&state->telemetry.flight_status.mode);
244 
245  if (HAS_SENSOR(state->available, HAS_BATT)) {
246  FlightBatteryStateGet(&state->telemetry.battery);
247  }
248  if (HAS_SENSOR(state->available, HAS_GPS)) {
249  GPSPositionGet(&state->telemetry.gps_position);
250  }
251  if (HAS_SENSOR(state->available, HAS_RSSI)) {
252  ManualControlCommandRssiGet(&state->telemetry.manual.rssi);
253  }
254  if (HAS_SENSOR(state->available, HAS_ALT)
255  || HAS_SENSOR(state->available, HAS_GPS)) {
256  VelocityActualGet(&state->telemetry.velocity_actual);
257  }
258 }
259 
261 {
262  PIOS_MAX7456_clear (state->dev);
263 
264  const char *welcome_msg = "Welcome to dRonin";
265 
266  SystemAlarmsData alarm;
267  SystemAlarmsGet(&alarm);
268  const char *boot_reason = AlarmBootReason(alarm.RebootCause);
269  PIOS_MAX7456_puts(state->dev, MAX7456_FMT_H_CENTER, 4, welcome_msg, 0);
270  PIOS_MAX7456_puts(state->dev, MAX7456_FMT_H_CENTER, 6, boot_reason, 0);
271 
273 }
274 
278 static void CharOnScreenDisplayTask(void *parameters)
279 {
280  (void) parameters;
281 
283 
284  state = PIOS_malloc(sizeof(*state));
285  state->dev = pios_max7456_id;
286  state->prev_font = 0xff;
287 
288  state->video_standard = 0xff;
289 
290  bzero(&state->telemetry, sizeof(state->telemetry));
291 
292  CharOnScreenDisplaySettingsData page;
293  CharOnScreenDisplaySettingsGet(&page);
294 
295  program_characters(state, page.Font);
296 
297  splash_screen(state);
298 
299  while (1) {
300  update_availability(state);
301  update_telemetry(state);
302 
303  CharOnScreenDisplaySettingsGet(&page);
304 
305  if (state->prev_font != page.Font) {
306  program_characters(state, page.Font);
307  }
308 
309  if (state->video_standard != page.VideoStandard) {
310  set_mode(state, page.VideoStandard);
311  }
312 
313  state->custom_text = (char*)page.CustomText;
314 
315  screen_draw(state, &page);
316 
317  if (PIOS_MAX7456_stall_detect(state->dev)) {
318  PIOS_MAX7456_puts(state->dev, MAX7456_FMT_H_CENTER, 6, "... STALLED ...", 0);
319  PIOS_Thread_Sleep(10000);
320  }
321 
323  }
324 }
325 
330 {
331  CharOnScreenDisplaySettingsInitialize();
332 
333  if (pios_max7456_id) {
334  module_enabled = true;
335  }
336 
337  return 0;
338 }
339 
341 {
342  if (module_enabled) {
343  struct pios_thread *taskHandle;
344 
345  taskHandle = PIOS_Thread_Create(CharOnScreenDisplayTask, "OnScreenDisplay", STACK_SIZE_BYTES, NULL, TASK_PRIORITY);
346  TaskMonitorAdd(TASKINFO_RUNNING_ONSCREENDISPLAY, taskHandle);
347 
348  return 0;
349  }
350  return -1;
351 }
352 
354 
static void program_characters(charosd_state_t state, uint8_t font)
update_t update
Definition: charosd.h:80
static struct pios_thread * taskHandle
Definition: actuator.c:83
#define STACK_SIZE_BYTES
telemetry_t telemetry
Definition: charosd.h:68
struct telemetry_t::@9 system
static const uint8_t charosd_font_thin_data[]
struct telemetry_t::@7 manual
static void splash_screen(charosd_state_t state)
bool PIOS_MAX7456_stall_detect(max7456_dev_t dev)
Detects whether the OSD chip has stalled and attempts to restart it.
VelocityActualData velocity_actual
Definition: charosd.h:50
bool PIOS_Modules_IsEnabled(enum pios_modules module)
Definition: pios_modules.c:41
#define MAX7456_MODE_PAL
Definition: pios_max7456.h:40
max7456_dev_t dev
Definition: charosd.h:66
#define TASK_PRIORITY
AttitudeActualData attitude_actual
Definition: charosd.h:48
#define FONT_CHAR_SIZE
static void CharOnScreenDisplayTask(void *parameters)
GPSPositionData gps_position
Definition: charosd.h:51
#define HAS_NAV
Definition: charosd.h:90
#define HAS_RSSI
Definition: charosd.h:89
void * PIOS_malloc(size_t size)
Definition: pios_heap.c:125
FlightStatusArmedOptions arm_status
Definition: charosd.h:57
bool module_enabled
int32_t CharOnScreenDisplayInitialize(void)
static const uint8_t charosd_font_small_data[]
uint32_t flight_time
Definition: charosd.h:61
MODULE_INITCALL(CharOnScreenDisplayInitialize, CharOnScreenDisplayStart)
static void update_availability(charosd_state_t state)
uint8_t video_standard
Definition: charosd.h:71
uint8_t prev_font
Definition: charosd.h:70
PositionActualData position_actual
Definition: charosd.h:49
#define HAS_PITOT
Definition: charosd.h:86
#define SPLASH_TIME_MS
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
void PIOS_MAX7456_set_mode(max7456_dev_t dev, bool force, uint8_t fallback)
Allows overriding the video mode used by OSD.
void PIOS_MAX7456_puts(max7456_dev_t dev, uint8_t col, uint8_t row, const char *s, uint8_t attr)
Sets a string into character memory.
#define HAS_BATT
Definition: charosd.h:85
#define MAX7456_MODE_NTSC
Definition: pios_max7456.h:41
struct telemetry_t::@8 flight_status
static const uint8_t charosd_font_data[]
static void set_mode(charosd_state_t state, uint8_t video_std)
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 HAS_GPS
Definition: charosd.h:84
void PIOS_MAX7456_clear(max7456_dev_t dev)
Clear the screen.
int32_t TaskMonitorAdd(TaskInfoRunningElem task, struct pios_thread *threadp)
Definition: taskmonitor.c:67
uint8_t i
Definition: msp_messages.h:97
float thrust
Definition: charosd.h:54
const char * AlarmBootReason(uint8_t reason)
static void panel_draw(charosd_state_t state, uint8_t panel, uint8_t x, uint8_t y)
static void update_telemetry(charosd_state_t state)
void PIOS_MAX7456_download_char(max7456_dev_t dev, uint8_t char_index, uint8_t *data)
Download a character from the device.
int16_t rssi
Definition: charosd.h:53
void PIOS_Thread_Sleep(uint32_t time_ms)
Definition: pios_thread.c:229
#define HAS_ALT
Definition: charosd.h:87
const panel_t panels[]
Definition: panel.c:485
#define HAS_SENSOR(available, required)
Definition: charosd.h:93
#define MAX7456_FMT_H_CENTER
Definition: pios_max7456.h:63
Includes PiOS and core architecture components.
void PIOS_MAX7456_upload_char(max7456_dev_t dev, uint8_t char_index, const uint8_t *data)
Upload a character to the device.
uint8_t update
Definition: msp_messages.h:98
Generic interface for sensors.
static void screen_draw(charosd_state_t state, CharOnScreenDisplaySettingsData *page)
#define HAS_COMPASS
Definition: charosd.h:91
SharedDefsFlightModeOptions mode
Definition: charosd.h:58
char * custom_text
Definition: charosd.h:69
#define PIOS_Assert(test)
Definition: pios_debug.h:52
void PIOS_MAX7456_wait_vsync()
FlightBatteryStateData battery
Definition: charosd.h:47
int32_t CharOnScreenDisplayStart(void)
enum arena_state state
int requirements
Definition: charosd.h:81