vtx: fix VTX_SETTINGS_POWER_COUNT and add dummy entries to saPowerNames
[inav.git] / src / main / io / displayport_frsky_osd.c
blob487cfa5f52c9dbfb2435e051987a3042a7816671
1 /*
2 * This file is part of Cleanflight.
4 * Cleanflight is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation, either version 3 of the License, or
7 * (at your option) any later version.
9 * Cleanflight is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with Cleanflight. If not, see <http://www.gnu.org/licenses/>.
18 #include <stdbool.h>
19 #include <stdint.h>
21 #include "platform.h"
23 #if defined(USE_OSD) && defined(USE_FRSKYOSD)
25 #include "common/maths.h"
26 #include "common/utils.h"
28 #include "drivers/display.h"
29 #include "drivers/display_canvas.h"
30 #include "drivers/display_font_metadata.h"
31 #include "drivers/display_widgets.h"
33 #include "io/displayport_frsky_osd.h"
34 #include "io/frsky_osd.h"
36 static displayPort_t frskyOSDDisplayPort;
38 static int grab(displayPort_t *displayPort)
40 UNUSED(displayPort);
41 return 0;
44 static int release(displayPort_t *displayPort)
46 UNUSED(displayPort);
47 return 0;
50 static int clearScreen(displayPort_t *displayPort)
52 UNUSED(displayPort);
53 frskyOSDClearScreen();
54 return 0;
57 static int drawScreen(displayPort_t *displayPort)
59 UNUSED(displayPort);
60 frskyOSDUpdate();
62 return 0;
65 static int screenSize(const displayPort_t *displayPort)
67 UNUSED(displayPort);
68 return frskyOSDGetGridRows() * frskyOSDGetGridCols();
71 static int writeString(displayPort_t *displayPort, uint8_t x, uint8_t y, const char *s, textAttributes_t attr)
73 UNUSED(displayPort);
75 frskyOSDDrawStringInGrid(x, y, s, attr);
76 return 0;
79 static int writeChar(displayPort_t *displayPort, uint8_t x, uint8_t y, uint16_t c, textAttributes_t attr)
81 UNUSED(displayPort);
83 frskyOSDDrawCharInGrid(x, y, c, attr);
84 return 0;
87 static bool readChar(displayPort_t *displayPort, uint8_t x, uint8_t y, uint16_t *c, textAttributes_t *attr)
89 UNUSED(displayPort);
91 return frskyOSDReadCharInGrid(x, y, c, attr);
94 static bool isTransferInProgress(const displayPort_t *displayPort)
96 UNUSED(displayPort);
97 return false;
100 static void updateGridSize(displayPort_t *displayPort)
102 displayPort->rows = frskyOSDGetGridRows();
103 displayPort->cols = frskyOSDGetGridCols();
106 static void resync(displayPort_t *displayPort)
108 UNUSED(displayPort);
109 // TODO(agh): Do we need to flush the screen here?
110 // MAX7456's driver does a full redraw in resync(),
111 // so some callers might be expecting that.
112 updateGridSize(displayPort);
115 static int heartbeat(displayPort_t *displayPort)
117 UNUSED(displayPort);
118 return 0;
121 static uint32_t txBytesFree(const displayPort_t *displayPort)
123 UNUSED(displayPort);
124 return UINT32_MAX;
127 static textAttributes_t supportedTextAttributes(const displayPort_t *displayPort)
129 UNUSED(displayPort);
131 textAttributes_t attr = TEXT_ATTRIBUTES_NONE;
132 TEXT_ATTRIBUTES_ADD_INVERTED(attr);
133 TEXT_ATTRIBUTES_ADD_SOLID_BG(attr);
134 return attr;
137 static bool getFontMetadata(displayFontMetadata_t *metadata, const displayPort_t *displayPort)
139 UNUSED(displayPort);
141 osdCharacter_t chr;
143 metadata->charCount = 512;
144 return frskyOSDReadFontCharacter(FONT_METADATA_CHR_INDEX, &chr) &&
145 displayFontMetadataUpdateFromCharacter(metadata, &chr);
149 static int writeFontCharacter(displayPort_t *instance, uint16_t addr, const osdCharacter_t *chr)
151 UNUSED(instance);
153 frskyOSDWriteFontCharacter(addr, chr);
154 return 0;
157 static bool isReady(displayPort_t *instance)
159 if (frskyOSDIsReady()) {
160 updateGridSize(instance);
161 return true;
163 return false;
166 static void beginTransaction(displayPort_t *instance, displayTransactionOption_e opts)
168 UNUSED(instance);
170 frskyOSDTransactionOptions_e frskyOpts = 0;
171 if (opts & DISPLAY_TRANSACTION_OPT_PROFILED) {
172 frskyOpts |= FRSKY_OSD_TRANSACTION_OPT_PROFILED;
174 if (opts & DISPLAY_TRANSACTION_OPT_RESET_DRAWING) {
175 frskyOpts |= FRSKY_OSD_TRANSACTION_OPT_RESET_DRAWING;
178 frskyOSDBeginTransaction(frskyOpts);
181 static void commitTransaction(displayPort_t *instance)
183 UNUSED(instance);
185 frskyOSDCommitTransaction();
188 static frskyOSDColor_e frskyOSDGetColor(displayCanvasColor_e color)
190 switch (color)
192 case DISPLAY_CANVAS_COLOR_BLACK:
193 return FRSKY_OSD_COLOR_BLACK;
194 case DISPLAY_CANVAS_COLOR_TRANSPARENT:
195 return FRSKY_OSD_COLOR_TRANSPARENT;
196 case DISPLAY_CANVAS_COLOR_WHITE:
197 return FRSKY_OSD_COLOR_WHITE;
198 case DISPLAY_CANVAS_COLOR_GRAY:
199 return FRSKY_OSD_COLOR_GRAY;
201 return FRSKY_OSD_COLOR_BLACK;
204 static void setStrokeColor(displayCanvas_t *displayCanvas, displayCanvasColor_e color)
206 UNUSED(displayCanvas);
208 frskyOSDSetStrokeColor(frskyOSDGetColor(color));
211 static void setFillColor(displayCanvas_t *displayCanvas, displayCanvasColor_e color)
213 UNUSED(displayCanvas);
215 frskyOSDSetFillColor(frskyOSDGetColor(color));
218 static void setStrokeAndFillColor(displayCanvas_t *displayCanvas, displayCanvasColor_e color)
220 UNUSED(displayCanvas);
222 frskyOSDSetStrokeAndFillColor(frskyOSDGetColor(color));
225 static void setColorInversion(displayCanvas_t *displayCanvas, bool inverted)
227 UNUSED(displayCanvas);
229 frskyOSDSetColorInversion(inverted);
232 static void setPixel(displayCanvas_t *displayCanvas, int x, int y, displayCanvasColor_e color)
234 UNUSED(displayCanvas);
236 frskyOSDSetPixel(x, y, frskyOSDGetColor(color));
239 static void setPixelToStrokeColor(displayCanvas_t *displayCanvas, int x, int y)
241 UNUSED(displayCanvas);
243 frskyOSDSetPixelToStrokeColor(x, y);
246 static void setPixelToFillColor(displayCanvas_t *displayCanvas, int x, int y)
248 UNUSED(displayCanvas);
250 frskyOSDSetPixelToFillColor(x, y);
253 static void setStrokeWidth(displayCanvas_t *displayCanvas, unsigned w)
255 UNUSED(displayCanvas);
257 frskyOSDSetStrokeWidth(w);
260 static void setLineOutlineType(displayCanvas_t *displayCanvas, displayCanvasOutlineType_e outlineType)
262 UNUSED(displayCanvas);
264 frskyOSDSetLineOutlineType((frskyOSDLineOutlineType_e)outlineType);
267 static void setLineOutlineColor(displayCanvas_t *displayCanvas, displayCanvasColor_e outlineColor)
269 UNUSED(displayCanvas);
271 frskyOSDSetLineOutlineColor((frskyOSDColor_e)outlineColor);
274 static void clipToRect(displayCanvas_t *displayCanvas, int x, int y, int w, int h)
276 UNUSED(displayCanvas);
278 frskyOSDClipToRect(x, y, w, h);
281 static void clearRect(displayCanvas_t *displayCanvas, int x, int y, int w, int h)
283 UNUSED(displayCanvas);
285 frskyOSDClearRect(x, y, w, h);
288 static void resetDrawingState(displayCanvas_t *displayCanvas)
290 UNUSED(displayCanvas);
292 frskyOSDResetDrawingState();
295 static void drawCharacter(displayCanvas_t *displayCanvas, int x, int y, uint16_t chr, displayCanvasBitmapOption_t opts)
297 UNUSED(displayCanvas);
299 frskyOSDDrawCharacter(x, y, chr, opts);
302 static void drawCharacterMask(displayCanvas_t *displayCanvas, int x, int y, uint16_t chr, displayCanvasColor_e color, displayCanvasBitmapOption_t opts)
304 UNUSED(displayCanvas);
306 frskyOSDDrawCharacterMask(x, y, chr, frskyOSDGetColor(color), opts);
309 static void drawString(displayCanvas_t *displayCanvas, int x, int y, const char *s, displayCanvasBitmapOption_t opts)
311 UNUSED(displayCanvas);
313 frskyOSDDrawString(x, y, s, opts);
316 static void drawStringMask(displayCanvas_t *displayCanvas, int x, int y, const char *s, displayCanvasColor_e color, displayCanvasBitmapOption_t opts)
318 UNUSED(displayCanvas);
320 frskyOSDDrawStringMask(x, y, s, frskyOSDGetColor(color), opts);
323 static void moveToPoint(displayCanvas_t *displayCanvas, int x, int y)
325 UNUSED(displayCanvas);
327 frskyOSDMoveToPoint(x, y);
330 static void strokeLineToPoint(displayCanvas_t *displayCanvas, int x, int y)
332 UNUSED(displayCanvas);
334 frskyOSDStrokeLineToPoint(x, y);
337 static void strokeTriangle(displayCanvas_t *displayCanvas, int x1, int y1, int x2, int y2, int x3, int y3)
339 UNUSED(displayCanvas);
341 frskyOSDStrokeTriangle(x1, y1, x2, y2, x3, y3);
344 static void fillTriangle(displayCanvas_t *displayCanvas, int x1, int y1, int x2, int y2, int x3, int y3)
346 UNUSED(displayCanvas);
348 frskyOSDFillTriangle(x1, y1, x2, y2, x3, y3);
351 static void fillStrokeTriangle(displayCanvas_t *displayCanvas, int x1, int y1, int x2, int y2, int x3, int y3)
353 UNUSED(displayCanvas);
355 frskyOSDFillStrokeTriangle(x1, y1, x2, y2, x3, y3);
358 static void strokeRect(displayCanvas_t *displayCanvas, int x, int y, int w, int h)
360 UNUSED(displayCanvas);
362 frskyOSDStrokeRect(x, y, w, h);
365 static void fillRect(displayCanvas_t *displayCanvas, int x, int y, int w, int h)
367 UNUSED(displayCanvas);
369 frskyOSDFillRect(x, y, w, h);
372 static void fillStrokeRect(displayCanvas_t *displayCanvas, int x, int y, int w, int h)
374 UNUSED(displayCanvas);
376 frskyOSDFillStrokeRect(x, y, w, h);
379 static void strokeEllipseInRect(displayCanvas_t *displayCanvas, int x, int y, int w, int h)
381 UNUSED(displayCanvas);
383 frskyOSDStrokeEllipseInRect(x, y, w, h);
386 static void fillEllipseInRect(displayCanvas_t *displayCanvas, int x, int y, int w, int h)
388 UNUSED(displayCanvas);
390 frskyOSDFillEllipseInRect(x, y, w, h);
393 static void fillStrokeEllipseInRect(displayCanvas_t *displayCanvas, int x, int y, int w, int h)
395 UNUSED(displayCanvas);
397 frskyOSDFillStrokeEllipseInRect(x, y, w, h);
400 static void ctmReset(displayCanvas_t *displayCanvas)
402 UNUSED(displayCanvas);
404 frskyOSDCtmReset();
407 static void ctmSet(displayCanvas_t *displayCanvas, float m11, float m12, float m21, float m22, float m31, float m32)
409 UNUSED(displayCanvas);
411 frskyOSDCtmSet(m11, m12, m21, m22, m31, m32);
414 static void ctmTranslate(displayCanvas_t *displayCanvas, float tx, float ty)
416 UNUSED(displayCanvas);
418 frskyOSDCtmTranslate(tx, ty);
421 static void ctmScale(displayCanvas_t *displayCanvas, float sx, float sy)
423 UNUSED(displayCanvas);
425 frskyOSDCtmScale(sx, sy);
428 static void ctmRotate(displayCanvas_t *displayCanvas, float r)
430 UNUSED(displayCanvas);
432 frskyOSDCtmRotate(r);
435 static void contextPush(displayCanvas_t *displayCanvas)
437 UNUSED(displayCanvas);
439 frskyOSDContextPush();
442 static void contextPop(displayCanvas_t *displayCanvas)
444 UNUSED(displayCanvas);
446 frskyOSDContextPop();
449 static int supportedInstances(displayWidgets_t *widgets, displayWidgetType_e widgetType)
451 UNUSED(widgets);
453 if (frskyOSDSupportsWidgets()) {
454 switch (widgetType) {
455 case DISPLAY_WIDGET_TYPE_AHI:
456 return 1;
457 case DISPLAY_WIDGET_TYPE_SIDEBAR:
458 return FRSKY_OSD_WIDGET_ID_SIDEBAR_LAST - FRSKY_OSD_WIDGET_ID_SIDEBAR_FIRST + 1;
461 return 0;
464 static bool configureAHI(displayWidgets_t *widgets, unsigned instance, const widgetAHIConfiguration_t *config)
466 UNUSED(widgets);
468 if (frskyOSDSupportsWidgets() && instance == 0) {
469 frskyOSDWidgetAHIConfig_t cfg = {
470 .rect.origin.x = config->rect.x,
471 .rect.origin.y = config->rect.y,
472 .rect.size.w = config->rect.w,
473 .rect.size.h = config->rect.h,
474 .style = config->style,
475 .options = config->options,
476 .crosshairMargin = config->crosshairMargin,
477 .strokeWidth = config->strokeWidth,
479 return frskyOSDSetWidgetConfig(FRSKY_OSD_WIDGET_ID_AHI, &cfg, sizeof(cfg));
481 return false;
484 static bool drawAHI(displayWidgets_t *widgets, unsigned instance, const widgetAHIData_t *data)
486 UNUSED(widgets);
488 if (frskyOSDSupportsWidgets() && instance == 0) {
489 frskyOSDWidgetAHIData_t ahiData = {
490 .pitch = frskyOSDQuantize(data->pitch, 0, 2 * M_PIf, 12),
491 .roll = frskyOSDQuantize(data->roll, 0, 2 * M_PIf, 12),
493 return frskyOSDDrawWidget(FRSKY_OSD_WIDGET_ID_AHI, &ahiData, sizeof(ahiData));
495 return false;
498 static bool configureSidebar(displayWidgets_t *widgets, unsigned instance, const widgetSidebarConfiguration_t *config)
500 UNUSED(widgets);
502 if (frskyOSDSupportsWidgets()) {
503 frskyOSDWidgetID_e id = FRSKY_OSD_WIDGET_ID_SIDEBAR_FIRST + instance;
504 if (id <= FRSKY_OSD_WIDGET_ID_SIDEBAR_LAST) {
505 frskyOSDWidgetSidebarConfig_t cfg = {
506 .rect.origin.x = config->rect.x,
507 .rect.origin.y = config->rect.y,
508 .rect.size.w = config->rect.w,
509 .rect.size.h = config->rect.h,
510 .options = config->options,
511 .divisions = config->divisions,
512 .counts_per_step = config->counts_per_step,
513 .unit = config->unit,
515 return frskyOSDSetWidgetConfig(id, &cfg, sizeof(cfg));
518 return false;
521 static bool drawSidebar(displayWidgets_t *widgets, unsigned instance, int32_t data)
523 UNUSED(widgets);
525 if (frskyOSDSupportsWidgets()) {
526 frskyOSDWidgetID_e id = FRSKY_OSD_WIDGET_ID_SIDEBAR_FIRST + instance;
527 if (id <= FRSKY_OSD_WIDGET_ID_SIDEBAR_LAST) {
528 frskyOSDWidgetSidebarData_t sidebarData = {
529 .value = data,
531 return frskyOSDDrawWidget(id, &sidebarData, sizeof(sidebarData));
534 return false;
537 static const displayWidgetsVTable_t frskyOSDWidgetsVTable = {
538 .supportedInstances = supportedInstances,
539 .configureAHI = configureAHI,
540 .drawAHI = drawAHI,
541 .configureSidebar = configureSidebar,
542 .drawSidebar = drawSidebar,
545 static bool getWidgets(displayWidgets_t *widgets, const displayCanvas_t *displayCanvas)
547 if (frskyOSDSupportsWidgets()) {
548 widgets->device = displayCanvas->device;
549 widgets->vTable = &frskyOSDWidgetsVTable;
550 return true;
552 return false;
555 static const displayCanvasVTable_t frskyOSDCanvasVTable = {
556 .setStrokeColor = setStrokeColor,
557 .setFillColor = setFillColor,
558 .setStrokeAndFillColor = setStrokeAndFillColor,
559 .setColorInversion = setColorInversion,
560 .setPixel = setPixel,
561 .setPixelToStrokeColor = setPixelToStrokeColor,
562 .setPixelToFillColor = setPixelToFillColor,
563 .setStrokeWidth = setStrokeWidth,
564 .setLineOutlineType = setLineOutlineType,
565 .setLineOutlineColor = setLineOutlineColor,
567 .clipToRect = clipToRect,
568 .clearRect = clearRect,
569 .resetDrawingState = resetDrawingState,
570 .drawCharacter = drawCharacter,
571 .drawCharacterMask = drawCharacterMask,
572 .drawString = drawString,
573 .drawStringMask = drawStringMask,
574 .moveToPoint = moveToPoint,
575 .strokeLineToPoint = strokeLineToPoint,
576 .strokeTriangle = strokeTriangle,
577 .fillTriangle = fillTriangle,
578 .fillStrokeTriangle = fillStrokeTriangle,
579 .strokeRect = strokeRect,
580 .fillRect = fillRect,
581 .fillStrokeRect = fillStrokeRect,
582 .strokeEllipseInRect = strokeEllipseInRect,
583 .fillEllipseInRect = fillEllipseInRect,
584 .fillStrokeEllipseInRect = fillStrokeEllipseInRect,
586 .ctmReset = ctmReset,
587 .ctmSet = ctmSet,
588 .ctmTranslate = ctmTranslate,
589 .ctmScale = ctmScale,
590 .ctmRotate = ctmRotate,
592 .contextPush = contextPush,
593 .contextPop = contextPop,
595 .getWidgets = getWidgets,
598 static bool getCanvas(displayCanvas_t *canvas, const displayPort_t *instance)
600 canvas->device = instance->device;
601 canvas->vTable = &frskyOSDCanvasVTable;
602 canvas->width = frskyOSDGetPixelWidth();
603 canvas->height = frskyOSDGetPixelHeight();
604 return true;
607 static const displayPortVTable_t frskyOSDVTable = {
608 .grab = grab,
609 .release = release,
610 .clearScreen = clearScreen,
611 .drawScreen = drawScreen,
612 .screenSize = screenSize,
613 .writeString = writeString,
614 .writeChar = writeChar,
615 .readChar = readChar,
616 .isTransferInProgress = isTransferInProgress,
617 .heartbeat = heartbeat,
618 .resync = resync,
619 .txBytesFree = txBytesFree,
620 .supportedTextAttributes = supportedTextAttributes,
621 .getFontMetadata = getFontMetadata,
622 .writeFontCharacter = writeFontCharacter,
623 .isReady = isReady,
624 .beginTransaction = beginTransaction,
625 .commitTransaction = commitTransaction,
626 .getCanvas = getCanvas,
629 displayPort_t *frskyOSDDisplayPortInit(const videoSystem_e videoSystem)
631 if (frskyOSDInit(videoSystem)) {
632 displayInit(&frskyOSDDisplayPort, &frskyOSDVTable);
633 resync(&frskyOSDDisplayPort);
634 frskyOSDDisplayPort.displayPortType = "FrSky PixelOSD";
635 return &frskyOSDDisplayPort;
637 return NULL;
640 #endif // USE_FRSKYOSD