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"
36 static displayPort_t frskyOsdDisplayPort
;
38 static int grab(displayPort_t
*displayPort
)
44 static int release(displayPort_t
*displayPort
)
50 static int clearScreen(displayPort_t
*displayPort
)
53 frskyOsdClearScreen();
57 static bool drawScreen(displayPort_t
*displayPort
)
65 static int screenSize(const displayPort_t
*displayPort
)
68 return frskyOsdGetGridRows() * frskyOsdGetGridCols();
71 static int writeString(displayPort_t
*displayPort
, uint8_t x
, uint8_t y
, uint8_t attr
, const char *s
)
76 frskyOsdDrawStringInGrid(x
, y
, s
);
80 static int writeChar(displayPort_t
*displayPort
, uint8_t x
, uint8_t y
, uint8_t attr
, uint8_t c
)
85 frskyOsdDrawCharInGrid(x
, y
, c
);
89 static bool isTransferInProgress(const displayPort_t
*displayPort
)
95 static void updateGridSize(displayPort_t
*displayPort
)
97 displayPort
->rows
= frskyOsdGetGridRows();
98 displayPort
->cols
= frskyOsdGetGridCols();
101 static void redraw(displayPort_t
*displayPort
)
104 // TODO(agh): Do we need to flush the screen here?
105 // MAX7456's driver does a full redraw in redraw(),
106 // so some callers might be expecting that.
110 static int heartbeat(displayPort_t
*displayPort
)
116 static uint32_t txBytesFree(const displayPort_t
*displayPort
)
122 static bool writeFontCharacter(displayPort_t
*instance
, uint16_t addr
, const osdCharacter_t
*chr
)
126 return frskyOsdWriteFontCharacter(addr
, chr
);
129 static bool checkReady(displayPort_t
*instance
, bool rescan
)
133 if (frskyOsdIsReady()) {
134 updateGridSize(instance
);
140 static void beginTransaction(displayPort_t
*instance
, displayTransactionOption_e opts
)
144 frskyOsdTransactionOptions_e frskyOpts
= 0;
145 if (opts
& DISPLAY_TRANSACTION_OPT_PROFILED
) {
146 frskyOpts
|= FRSKY_OSD_TRANSACTION_OPT_PROFILED
;
148 if (opts
& DISPLAY_TRANSACTION_OPT_RESET_DRAWING
) {
149 frskyOpts
|= FRSKY_OSD_TRANSACTION_OPT_RESET_DRAWING
;
152 frskyOsdBeginTransaction(frskyOpts
);
155 static void commitTransaction(displayPort_t
*instance
)
159 frskyOsdCommitTransaction();
162 static frskyOsdColor_e
frskyOsdGetColor(displayCanvasColor_e color
)
166 case DISPLAY_CANVAS_COLOR_BLACK
:
167 return FRSKY_OSD_COLOR_BLACK
;
168 case DISPLAY_CANVAS_COLOR_TRANSPARENT
:
169 return FRSKY_OSD_COLOR_TRANSPARENT
;
170 case DISPLAY_CANVAS_COLOR_WHITE
:
171 return FRSKY_OSD_COLOR_WHITE
;
172 case DISPLAY_CANVAS_COLOR_GRAY
:
173 return FRSKY_OSD_COLOR_GRAY
;
175 return FRSKY_OSD_COLOR_BLACK
;
178 static void setStrokeColor(displayCanvas_t
*displayCanvas
, displayCanvasColor_e color
)
180 UNUSED(displayCanvas
);
182 frskyOsdSetStrokeColor(frskyOsdGetColor(color
));
185 static void setFillColor(displayCanvas_t
*displayCanvas
, displayCanvasColor_e color
)
187 UNUSED(displayCanvas
);
189 frskyOsdSetFillColor(frskyOsdGetColor(color
));
192 static void setStrokeAndFillColor(displayCanvas_t
*displayCanvas
, displayCanvasColor_e color
)
194 UNUSED(displayCanvas
);
196 frskyOsdSetStrokeAndFillColor(frskyOsdGetColor(color
));
199 static void setColorInversion(displayCanvas_t
*displayCanvas
, bool inverted
)
201 UNUSED(displayCanvas
);
203 frskyOsdSetColorInversion(inverted
);
206 static void setPixel(displayCanvas_t
*displayCanvas
, int x
, int y
, displayCanvasColor_e color
)
208 UNUSED(displayCanvas
);
210 frskyOsdSetPixel(x
, y
, frskyOsdGetColor(color
));
213 static void setPixelToStrokeColor(displayCanvas_t
*displayCanvas
, int x
, int y
)
215 UNUSED(displayCanvas
);
217 frskyOsdSetPixelToStrokeColor(x
, y
);
220 static void setPixelToFillColor(displayCanvas_t
*displayCanvas
, int x
, int y
)
222 UNUSED(displayCanvas
);
224 frskyOsdSetPixelToFillColor(x
, y
);
227 static void setStrokeWidth(displayCanvas_t
*displayCanvas
, unsigned w
)
229 UNUSED(displayCanvas
);
231 frskyOsdSetStrokeWidth(w
);
234 static void setLineOutlineType(displayCanvas_t
*displayCanvas
, displayCanvasOutlineType_e outlineType
)
236 UNUSED(displayCanvas
);
238 frskyOsdSetLineOutlineType((frskyOsdLineOutlineType_e
)outlineType
);
241 static void setLineOutlineColor(displayCanvas_t
*displayCanvas
, displayCanvasColor_e outlineColor
)
243 UNUSED(displayCanvas
);
245 frskyOsdSetLineOutlineColor((frskyOsdColor_e
)outlineColor
);
248 static void clipToRect(displayCanvas_t
*displayCanvas
, int x
, int y
, int w
, int h
)
250 UNUSED(displayCanvas
);
252 frskyOsdClipToRect(x
, y
, w
, h
);
255 static void clearRect(displayCanvas_t
*displayCanvas
, int x
, int y
, int w
, int h
)
257 UNUSED(displayCanvas
);
259 frskyOsdClearRect(x
, y
, w
, h
);
262 static void resetDrawingState(displayCanvas_t
*displayCanvas
)
264 UNUSED(displayCanvas
);
266 frskyOsdResetDrawingState();
269 static void drawCharacter(displayCanvas_t
*displayCanvas
, int x
, int y
, uint16_t chr
, displayCanvasBitmapOption_t opts
)
271 UNUSED(displayCanvas
);
273 frskyOsdDrawCharacter(x
, y
, chr
, opts
);
276 static void drawCharacterMask(displayCanvas_t
*displayCanvas
, int x
, int y
, uint16_t chr
, displayCanvasColor_e color
, displayCanvasBitmapOption_t opts
)
278 UNUSED(displayCanvas
);
280 frskyOsdDrawCharacterMask(x
, y
, chr
, frskyOsdGetColor(color
), opts
);
283 static void drawString(displayCanvas_t
*displayCanvas
, int x
, int y
, const char *s
, displayCanvasBitmapOption_t opts
)
285 UNUSED(displayCanvas
);
287 frskyOsdDrawString(x
, y
, s
, opts
);
290 static void drawStringMask(displayCanvas_t
*displayCanvas
, int x
, int y
, const char *s
, displayCanvasColor_e color
, displayCanvasBitmapOption_t opts
)
292 UNUSED(displayCanvas
);
294 frskyOsdDrawStringMask(x
, y
, s
, frskyOsdGetColor(color
), opts
);
297 static void moveToPoint(displayCanvas_t
*displayCanvas
, int x
, int y
)
299 UNUSED(displayCanvas
);
301 frskyOsdMoveToPoint(x
, y
);
304 static void strokeLineToPoint(displayCanvas_t
*displayCanvas
, int x
, int y
)
306 UNUSED(displayCanvas
);
308 frskyOsdStrokeLineToPoint(x
, y
);
311 static void strokeTriangle(displayCanvas_t
*displayCanvas
, int x1
, int y1
, int x2
, int y2
, int x3
, int y3
)
313 UNUSED(displayCanvas
);
315 frskyOsdStrokeTriangle(x1
, y1
, x2
, y2
, x3
, y3
);
318 static void fillTriangle(displayCanvas_t
*displayCanvas
, int x1
, int y1
, int x2
, int y2
, int x3
, int y3
)
320 UNUSED(displayCanvas
);
322 frskyOsdFillTriangle(x1
, y1
, x2
, y2
, x3
, y3
);
325 static void fillStrokeTriangle(displayCanvas_t
*displayCanvas
, int x1
, int y1
, int x2
, int y2
, int x3
, int y3
)
327 UNUSED(displayCanvas
);
329 frskyOsdFillStrokeTriangle(x1
, y1
, x2
, y2
, x3
, y3
);
332 static void strokeRect(displayCanvas_t
*displayCanvas
, int x
, int y
, int w
, int h
)
334 UNUSED(displayCanvas
);
336 frskyOsdStrokeRect(x
, y
, w
, h
);
339 static void fillRect(displayCanvas_t
*displayCanvas
, int x
, int y
, int w
, int h
)
341 UNUSED(displayCanvas
);
343 frskyOsdFillRect(x
, y
, w
, h
);
346 static void fillStrokeRect(displayCanvas_t
*displayCanvas
, int x
, int y
, int w
, int h
)
348 UNUSED(displayCanvas
);
350 frskyOsdFillStrokeRect(x
, y
, w
, h
);
353 static void strokeEllipseInRect(displayCanvas_t
*displayCanvas
, int x
, int y
, int w
, int h
)
355 UNUSED(displayCanvas
);
357 frskyOsdStrokeEllipseInRect(x
, y
, w
, h
);
360 static void fillEllipseInRect(displayCanvas_t
*displayCanvas
, int x
, int y
, int w
, int h
)
362 UNUSED(displayCanvas
);
364 frskyOsdFillEllipseInRect(x
, y
, w
, h
);
367 static void fillStrokeEllipseInRect(displayCanvas_t
*displayCanvas
, int x
, int y
, int w
, int h
)
369 UNUSED(displayCanvas
);
371 frskyOsdFillStrokeEllipseInRect(x
, y
, w
, h
);
374 static void ctmReset(displayCanvas_t
*displayCanvas
)
376 UNUSED(displayCanvas
);
381 static void ctmSet(displayCanvas_t
*displayCanvas
, float m11
, float m12
, float m21
, float m22
, float m31
, float m32
)
383 UNUSED(displayCanvas
);
385 frskyOsdCtmSet(m11
, m12
, m21
, m22
, m31
, m32
);
388 static void ctmTranslate(displayCanvas_t
*displayCanvas
, float tx
, float ty
)
390 UNUSED(displayCanvas
);
392 frskyOsdCtmTranslate(tx
, ty
);
395 static void ctmScale(displayCanvas_t
*displayCanvas
, float sx
, float sy
)
397 UNUSED(displayCanvas
);
399 frskyOsdCtmScale(sx
, sy
);
402 static void ctmRotate(displayCanvas_t
*displayCanvas
, float r
)
404 UNUSED(displayCanvas
);
406 frskyOsdCtmRotate(r
);
409 static void contextPush(displayCanvas_t
*displayCanvas
)
411 UNUSED(displayCanvas
);
413 frskyOsdContextPush();
416 static void contextPop(displayCanvas_t
*displayCanvas
)
418 UNUSED(displayCanvas
);
420 frskyOsdContextPop();
424 static const displayCanvasVTable_t frskyOsdCanvasVTable
= {
425 .setStrokeColor
= setStrokeColor
,
426 .setFillColor
= setFillColor
,
427 .setStrokeAndFillColor
= setStrokeAndFillColor
,
428 .setColorInversion
= setColorInversion
,
429 .setPixel
= setPixel
,
430 .setPixelToStrokeColor
= setPixelToStrokeColor
,
431 .setPixelToFillColor
= setPixelToFillColor
,
432 .setStrokeWidth
= setStrokeWidth
,
433 .setLineOutlineType
= setLineOutlineType
,
434 .setLineOutlineColor
= setLineOutlineColor
,
436 .clipToRect
= clipToRect
,
437 .clearRect
= clearRect
,
438 .resetDrawingState
= resetDrawingState
,
439 .drawCharacter
= drawCharacter
,
440 .drawCharacterMask
= drawCharacterMask
,
441 .drawString
= drawString
,
442 .drawStringMask
= drawStringMask
,
443 .moveToPoint
= moveToPoint
,
444 .strokeLineToPoint
= strokeLineToPoint
,
445 .strokeTriangle
= strokeTriangle
,
446 .fillTriangle
= fillTriangle
,
447 .fillStrokeTriangle
= fillStrokeTriangle
,
448 .strokeRect
= strokeRect
,
449 .fillRect
= fillRect
,
450 .fillStrokeRect
= fillStrokeRect
,
451 .strokeEllipseInRect
= strokeEllipseInRect
,
452 .fillEllipseInRect
= fillEllipseInRect
,
453 .fillStrokeEllipseInRect
= fillStrokeEllipseInRect
,
455 .ctmReset
= ctmReset
,
457 .ctmTranslate
= ctmTranslate
,
458 .ctmScale
= ctmScale
,
459 .ctmRotate
= ctmRotate
,
461 .contextPush
= contextPush
,
462 .contextPop
= contextPop
,
465 static bool getCanvas(displayCanvas_t
*canvas
, const displayPort_t
*instance
)
469 canvas
->vTable
= &frskyOsdCanvasVTable
;
470 canvas
->width
= frskyOsdGetPixelWidth();
471 canvas
->height
= frskyOsdGetPixelHeight();
475 static const displayPortVTable_t frskyOsdVTable
= {
478 .clearScreen
= clearScreen
,
479 .drawScreen
= drawScreen
,
480 .screenSize
= screenSize
,
481 .writeString
= writeString
,
482 .writeChar
= writeChar
,
483 .isTransferInProgress
= isTransferInProgress
,
484 .heartbeat
= heartbeat
,
486 .txBytesFree
= txBytesFree
,
487 .writeFontCharacter
= writeFontCharacter
,
488 .checkReady
= checkReady
,
489 .beginTransaction
= beginTransaction
,
490 .commitTransaction
= commitTransaction
,
491 .getCanvas
= getCanvas
,
494 displayPort_t
*frskyOsdDisplayPortInit(const videoSystem_e videoSystem
)
496 if (frskyOsdInit(videoSystem
)) {
497 displayInit(&frskyOsdDisplayPort
, &frskyOsdVTable
, DISPLAYPORT_DEVICE_TYPE_FRSKYOSD
);
498 redraw(&frskyOsdDisplayPort
);
499 return &frskyOsdDisplayPort
;
504 #endif // USE_FRSKYOSD