2 * This file is part of Cleanflight, Betaflight and INAV
4 * Cleanflight, Betaflight and INAV are free software. You can
5 * redistribute this software and/or modify this software under
6 * the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 3 of the License,
8 * or (at your option) any later version.
10 * Cleanflight, Betaflight and INAV are distributed in the hope that
11 * they will be useful, but WITHOUT ANY WARRANTY; without even the
12 * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
13 * PURPOSE. See the GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this software.
18 * If not, see <http://www.gnu.org/licenses/>.
26 #if defined(USE_FRSKYOSD)
28 #include "common/utils.h"
30 #include "drivers/display.h"
31 #include "drivers/display_canvas.h"
33 #include "io/displayport_frsky_osd.h"
34 #include "io/frsky_osd.h"
38 static displayPort_t frskyOsdDisplayPort
;
40 static int grab(displayPort_t
*displayPort
)
46 static int release(displayPort_t
*displayPort
)
52 static int clearScreen(displayPort_t
*displayPort
, displayClearOption_e options
)
56 frskyOsdClearScreen();
60 static bool drawScreen(displayPort_t
*displayPort
)
68 static int screenSize(const displayPort_t
*displayPort
)
71 return frskyOsdGetGridRows() * frskyOsdGetGridCols();
74 static int writeString(displayPort_t
*displayPort
, uint8_t x
, uint8_t y
, uint8_t attr
, const char *s
)
79 frskyOsdDrawStringInGrid(x
, y
, s
);
83 static int writeChar(displayPort_t
*displayPort
, uint8_t x
, uint8_t y
, uint8_t attr
, uint8_t c
)
88 frskyOsdDrawCharInGrid(x
, y
, c
);
92 static bool isTransferInProgress(const displayPort_t
*displayPort
)
98 static void updateGridSize(displayPort_t
*displayPort
)
100 displayPort
->rows
= frskyOsdGetGridRows();
101 displayPort
->cols
= frskyOsdGetGridCols();
104 static void redraw(displayPort_t
*displayPort
)
107 // TODO(agh): Do we need to flush the screen here?
108 // MAX7456's driver does a full redraw in redraw(),
109 // so some callers might be expecting that.
113 static int heartbeat(displayPort_t
*displayPort
)
119 static uint32_t txBytesFree(const displayPort_t
*displayPort
)
125 static bool writeFontCharacter(displayPort_t
*instance
, uint16_t addr
, const osdCharacter_t
*chr
)
129 return frskyOsdWriteFontCharacter(addr
, chr
);
132 static bool checkReady(displayPort_t
*instance
, bool rescan
)
136 if (frskyOsdIsReady()) {
137 updateGridSize(instance
);
143 static void beginTransaction(displayPort_t
*instance
, displayTransactionOption_e opts
)
147 frskyOsdTransactionOptions_e frskyOpts
= 0;
148 if (opts
& DISPLAY_TRANSACTION_OPT_PROFILED
) {
149 frskyOpts
|= FRSKY_OSD_TRANSACTION_OPT_PROFILED
;
151 if (opts
& DISPLAY_TRANSACTION_OPT_RESET_DRAWING
) {
152 frskyOpts
|= FRSKY_OSD_TRANSACTION_OPT_RESET_DRAWING
;
155 frskyOsdBeginTransaction(frskyOpts
);
158 static void commitTransaction(displayPort_t
*instance
)
162 frskyOsdCommitTransaction();
165 static frskyOsdColor_e
frskyOsdGetColor(displayCanvasColor_e color
)
169 case DISPLAY_CANVAS_COLOR_BLACK
:
170 return FRSKY_OSD_COLOR_BLACK
;
171 case DISPLAY_CANVAS_COLOR_TRANSPARENT
:
172 return FRSKY_OSD_COLOR_TRANSPARENT
;
173 case DISPLAY_CANVAS_COLOR_WHITE
:
174 return FRSKY_OSD_COLOR_WHITE
;
175 case DISPLAY_CANVAS_COLOR_GRAY
:
176 return FRSKY_OSD_COLOR_GRAY
;
178 return FRSKY_OSD_COLOR_BLACK
;
181 static void setStrokeColor(displayCanvas_t
*displayCanvas
, displayCanvasColor_e color
)
183 UNUSED(displayCanvas
);
185 frskyOsdSetStrokeColor(frskyOsdGetColor(color
));
188 static void setFillColor(displayCanvas_t
*displayCanvas
, displayCanvasColor_e color
)
190 UNUSED(displayCanvas
);
192 frskyOsdSetFillColor(frskyOsdGetColor(color
));
195 static void setStrokeAndFillColor(displayCanvas_t
*displayCanvas
, displayCanvasColor_e color
)
197 UNUSED(displayCanvas
);
199 frskyOsdSetStrokeAndFillColor(frskyOsdGetColor(color
));
202 static void setColorInversion(displayCanvas_t
*displayCanvas
, bool inverted
)
204 UNUSED(displayCanvas
);
206 frskyOsdSetColorInversion(inverted
);
209 static void setPixel(displayCanvas_t
*displayCanvas
, int x
, int y
, displayCanvasColor_e color
)
211 UNUSED(displayCanvas
);
213 frskyOsdSetPixel(x
, y
, frskyOsdGetColor(color
));
216 static void setPixelToStrokeColor(displayCanvas_t
*displayCanvas
, int x
, int y
)
218 UNUSED(displayCanvas
);
220 frskyOsdSetPixelToStrokeColor(x
, y
);
223 static void setPixelToFillColor(displayCanvas_t
*displayCanvas
, int x
, int y
)
225 UNUSED(displayCanvas
);
227 frskyOsdSetPixelToFillColor(x
, y
);
230 static void setStrokeWidth(displayCanvas_t
*displayCanvas
, unsigned w
)
232 UNUSED(displayCanvas
);
234 frskyOsdSetStrokeWidth(w
);
237 static void setLineOutlineType(displayCanvas_t
*displayCanvas
, displayCanvasOutlineType_e outlineType
)
239 UNUSED(displayCanvas
);
241 frskyOsdSetLineOutlineType((frskyOsdLineOutlineType_e
)outlineType
);
244 static void setLineOutlineColor(displayCanvas_t
*displayCanvas
, displayCanvasColor_e outlineColor
)
246 UNUSED(displayCanvas
);
248 frskyOsdSetLineOutlineColor((frskyOsdColor_e
)outlineColor
);
251 static void clipToRect(displayCanvas_t
*displayCanvas
, int x
, int y
, int w
, int h
)
253 UNUSED(displayCanvas
);
255 frskyOsdClipToRect(x
, y
, w
, h
);
258 static void clearRect(displayCanvas_t
*displayCanvas
, int x
, int y
, int w
, int h
)
260 UNUSED(displayCanvas
);
262 frskyOsdClearRect(x
, y
, w
, h
);
265 static void resetDrawingState(displayCanvas_t
*displayCanvas
)
267 UNUSED(displayCanvas
);
269 frskyOsdResetDrawingState();
272 static void drawCharacter(displayCanvas_t
*displayCanvas
, int x
, int y
, uint16_t chr
, displayCanvasBitmapOption_t opts
)
274 UNUSED(displayCanvas
);
276 frskyOsdDrawCharacter(x
, y
, chr
, opts
);
279 static void drawCharacterMask(displayCanvas_t
*displayCanvas
, int x
, int y
, uint16_t chr
, displayCanvasColor_e color
, displayCanvasBitmapOption_t opts
)
281 UNUSED(displayCanvas
);
283 frskyOsdDrawCharacterMask(x
, y
, chr
, frskyOsdGetColor(color
), opts
);
286 static void drawString(displayCanvas_t
*displayCanvas
, int x
, int y
, const char *s
, displayCanvasBitmapOption_t opts
)
288 UNUSED(displayCanvas
);
290 frskyOsdDrawString(x
, y
, s
, opts
);
293 static void drawStringMask(displayCanvas_t
*displayCanvas
, int x
, int y
, const char *s
, displayCanvasColor_e color
, displayCanvasBitmapOption_t opts
)
295 UNUSED(displayCanvas
);
297 frskyOsdDrawStringMask(x
, y
, s
, frskyOsdGetColor(color
), opts
);
300 static void moveToPoint(displayCanvas_t
*displayCanvas
, int x
, int y
)
302 UNUSED(displayCanvas
);
304 frskyOsdMoveToPoint(x
, y
);
307 static void strokeLineToPoint(displayCanvas_t
*displayCanvas
, int x
, int y
)
309 UNUSED(displayCanvas
);
311 frskyOsdStrokeLineToPoint(x
, y
);
314 static void strokeTriangle(displayCanvas_t
*displayCanvas
, int x1
, int y1
, int x2
, int y2
, int x3
, int y3
)
316 UNUSED(displayCanvas
);
318 frskyOsdStrokeTriangle(x1
, y1
, x2
, y2
, x3
, y3
);
321 static void fillTriangle(displayCanvas_t
*displayCanvas
, int x1
, int y1
, int x2
, int y2
, int x3
, int y3
)
323 UNUSED(displayCanvas
);
325 frskyOsdFillTriangle(x1
, y1
, x2
, y2
, x3
, y3
);
328 static void fillStrokeTriangle(displayCanvas_t
*displayCanvas
, int x1
, int y1
, int x2
, int y2
, int x3
, int y3
)
330 UNUSED(displayCanvas
);
332 frskyOsdFillStrokeTriangle(x1
, y1
, x2
, y2
, x3
, y3
);
335 static void strokeRect(displayCanvas_t
*displayCanvas
, int x
, int y
, int w
, int h
)
337 UNUSED(displayCanvas
);
339 frskyOsdStrokeRect(x
, y
, w
, h
);
342 static void fillRect(displayCanvas_t
*displayCanvas
, int x
, int y
, int w
, int h
)
344 UNUSED(displayCanvas
);
346 frskyOsdFillRect(x
, y
, w
, h
);
349 static void fillStrokeRect(displayCanvas_t
*displayCanvas
, int x
, int y
, int w
, int h
)
351 UNUSED(displayCanvas
);
353 frskyOsdFillStrokeRect(x
, y
, w
, h
);
356 static void strokeEllipseInRect(displayCanvas_t
*displayCanvas
, int x
, int y
, int w
, int h
)
358 UNUSED(displayCanvas
);
360 frskyOsdStrokeEllipseInRect(x
, y
, w
, h
);
363 static void fillEllipseInRect(displayCanvas_t
*displayCanvas
, int x
, int y
, int w
, int h
)
365 UNUSED(displayCanvas
);
367 frskyOsdFillEllipseInRect(x
, y
, w
, h
);
370 static void fillStrokeEllipseInRect(displayCanvas_t
*displayCanvas
, int x
, int y
, int w
, int h
)
372 UNUSED(displayCanvas
);
374 frskyOsdFillStrokeEllipseInRect(x
, y
, w
, h
);
377 static void ctmReset(displayCanvas_t
*displayCanvas
)
379 UNUSED(displayCanvas
);
384 static void ctmSet(displayCanvas_t
*displayCanvas
, float m11
, float m12
, float m21
, float m22
, float m31
, float m32
)
386 UNUSED(displayCanvas
);
388 frskyOsdCtmSet(m11
, m12
, m21
, m22
, m31
, m32
);
391 static void ctmTranslate(displayCanvas_t
*displayCanvas
, float tx
, float ty
)
393 UNUSED(displayCanvas
);
395 frskyOsdCtmTranslate(tx
, ty
);
398 static void ctmScale(displayCanvas_t
*displayCanvas
, float sx
, float sy
)
400 UNUSED(displayCanvas
);
402 frskyOsdCtmScale(sx
, sy
);
405 static void ctmRotate(displayCanvas_t
*displayCanvas
, float r
)
407 UNUSED(displayCanvas
);
409 frskyOsdCtmRotate(r
);
412 static void contextPush(displayCanvas_t
*displayCanvas
)
414 UNUSED(displayCanvas
);
416 frskyOsdContextPush();
419 static void contextPop(displayCanvas_t
*displayCanvas
)
421 UNUSED(displayCanvas
);
423 frskyOsdContextPop();
427 static const displayCanvasVTable_t frskyOsdCanvasVTable
= {
428 .setStrokeColor
= setStrokeColor
,
429 .setFillColor
= setFillColor
,
430 .setStrokeAndFillColor
= setStrokeAndFillColor
,
431 .setColorInversion
= setColorInversion
,
432 .setPixel
= setPixel
,
433 .setPixelToStrokeColor
= setPixelToStrokeColor
,
434 .setPixelToFillColor
= setPixelToFillColor
,
435 .setStrokeWidth
= setStrokeWidth
,
436 .setLineOutlineType
= setLineOutlineType
,
437 .setLineOutlineColor
= setLineOutlineColor
,
439 .clipToRect
= clipToRect
,
440 .clearRect
= clearRect
,
441 .resetDrawingState
= resetDrawingState
,
442 .drawCharacter
= drawCharacter
,
443 .drawCharacterMask
= drawCharacterMask
,
444 .drawString
= drawString
,
445 .drawStringMask
= drawStringMask
,
446 .moveToPoint
= moveToPoint
,
447 .strokeLineToPoint
= strokeLineToPoint
,
448 .strokeTriangle
= strokeTriangle
,
449 .fillTriangle
= fillTriangle
,
450 .fillStrokeTriangle
= fillStrokeTriangle
,
451 .strokeRect
= strokeRect
,
452 .fillRect
= fillRect
,
453 .fillStrokeRect
= fillStrokeRect
,
454 .strokeEllipseInRect
= strokeEllipseInRect
,
455 .fillEllipseInRect
= fillEllipseInRect
,
456 .fillStrokeEllipseInRect
= fillStrokeEllipseInRect
,
458 .ctmReset
= ctmReset
,
460 .ctmTranslate
= ctmTranslate
,
461 .ctmScale
= ctmScale
,
462 .ctmRotate
= ctmRotate
,
464 .contextPush
= contextPush
,
465 .contextPop
= contextPop
,
468 static bool getCanvas(displayCanvas_t
*canvas
, const displayPort_t
*instance
)
472 canvas
->vTable
= &frskyOsdCanvasVTable
;
473 canvas
->width
= frskyOsdGetPixelWidth();
474 canvas
->height
= frskyOsdGetPixelHeight();
478 static const displayPortVTable_t frskyOsdVTable
= {
481 .clearScreen
= clearScreen
,
482 .drawScreen
= drawScreen
,
483 .screenSize
= screenSize
,
484 .writeString
= writeString
,
485 .writeChar
= writeChar
,
486 .isTransferInProgress
= isTransferInProgress
,
487 .heartbeat
= heartbeat
,
489 .txBytesFree
= txBytesFree
,
490 .writeFontCharacter
= writeFontCharacter
,
491 .checkReady
= checkReady
,
492 .beginTransaction
= beginTransaction
,
493 .commitTransaction
= commitTransaction
,
494 .getCanvas
= getCanvas
,
497 displayPort_t
*frskyOsdDisplayPortInit(const videoSystem_e videoSystem
)
499 if (frskyOsdInit(videoSystem
)) {
500 displayInit(&frskyOsdDisplayPort
, &frskyOsdVTable
, DISPLAYPORT_DEVICE_TYPE_FRSKYOSD
);
501 frskyOsdDisplayPort
.cols
= OSD_SD_COLS
;
502 frskyOsdDisplayPort
.rows
= OSD_SD_ROWS
;
503 redraw(&frskyOsdDisplayPort
);
504 return &frskyOsdDisplayPort
;
509 #endif // USE_FRSKYOSD