mirror of
https://github.com/iNavFlight/inav.git
synced 2025-07-24 16:55:29 +03:00
[OSD] Remove FrSky OSD dependency on MAX7456
Move local character grid buffer to drivers/osd.c and use it from both the FrSky OSD and the MAX7456 drivers.
This commit is contained in:
parent
51da88d26c
commit
a4187a58d4
6 changed files with 85 additions and 35 deletions
|
@ -44,6 +44,7 @@ COMMON_SRC = \
|
|||
drivers/io.c \
|
||||
drivers/io_pca9685.c \
|
||||
drivers/light_led.c \
|
||||
drivers/osd.c \
|
||||
drivers/resource.c \
|
||||
drivers/rx_nrf24l01.c \
|
||||
drivers/rx_spi.c \
|
||||
|
|
|
@ -176,10 +176,9 @@
|
|||
#define CHAR_MODE_EXT (1 << 2)
|
||||
#define CHAR_MODE_IS_EXT(m) ((m) & CHAR_MODE_EXT)
|
||||
|
||||
// we write everything in max7456ScreenBuffer and set a dirty bit
|
||||
// in screenIsDirty to upgrade only changed chars this solution
|
||||
// is faster than redrawing the whole screen on each frame
|
||||
uint16_t max7456ScreenBuffer[MAX7456_BUFFER_CHARS_PAL] ALIGNED(4);
|
||||
// we write everything in osdCharacterGridBuffer and set a dirty bit
|
||||
// in screenIsDirty to update only changed chars. This solution
|
||||
// is faster than redrawing the whole screen on each frame.
|
||||
static BITARRAY_DECLARE(screenIsDirty, MAX7456_BUFFER_CHARS_PAL);
|
||||
|
||||
//max chars to update in one idle
|
||||
|
@ -307,7 +306,7 @@ uint8_t max7456GetRowsCount(void)
|
|||
}
|
||||
|
||||
//because MAX7456 need some time to detect video system etc. we need to wait for a while to initialize it at startup
|
||||
//and in case of restart we need to reinitialize chip. Note that we can't touch max7456ScreenBuffer here, since
|
||||
//and in case of restart we need to reinitialize chip. Note that we can't touch osdCharacterGridBuffer here, since
|
||||
//it might already have some data by the first time this function is called.
|
||||
static void max7456ReInit(void)
|
||||
{
|
||||
|
@ -382,9 +381,9 @@ void max7456Init(const videoSystem_e videoSystem)
|
|||
state.registers.dmm = 0;
|
||||
state.videoSystem = videoSystem;
|
||||
|
||||
// Set max7456ScreenBuffer to all blanks
|
||||
for (uint_fast16_t ii = 0; ii < ARRAYLEN(max7456ScreenBuffer); ii++) {
|
||||
max7456ScreenBuffer[ii] = CHAR_BLANK;
|
||||
// Set screen buffer to all blanks
|
||||
for (uint_fast16_t ii = 0; ii < ARRAYLEN(osdCharacterGridBuffer); ii++) {
|
||||
osdCharacterGridBuffer[ii] = CHAR_BLANK;
|
||||
}
|
||||
|
||||
// Wait for software reset to finish
|
||||
|
@ -409,9 +408,9 @@ void max7456Init(const videoSystem_e videoSystem)
|
|||
|
||||
void max7456ClearScreen(void)
|
||||
{
|
||||
for (uint_fast16_t ii = 0; ii < ARRAYLEN(max7456ScreenBuffer); ii++) {
|
||||
if (max7456ScreenBuffer[ii] != CHAR_BLANK) {
|
||||
max7456ScreenBuffer[ii] = CHAR_BLANK;
|
||||
for (uint_fast16_t ii = 0; ii < ARRAYLEN(osdCharacterGridBuffer); ii++) {
|
||||
if (osdCharacterGridBuffer[ii] != CHAR_BLANK) {
|
||||
osdCharacterGridBuffer[ii] = CHAR_BLANK;
|
||||
bitArraySet(screenIsDirty, ii);
|
||||
}
|
||||
}
|
||||
|
@ -421,8 +420,8 @@ void max7456WriteChar(uint8_t x, uint8_t y, uint16_t c, uint8_t mode)
|
|||
{
|
||||
unsigned pos = y * MAX7456_CHARS_PER_LINE + x;
|
||||
uint16_t val = MAKE_CHAR_MODE(c, mode);
|
||||
if (max7456ScreenBuffer[pos] != val) {
|
||||
max7456ScreenBuffer[pos] = val;
|
||||
if (osdCharacterGridBuffer[pos] != val) {
|
||||
osdCharacterGridBuffer[pos] = val;
|
||||
bitArraySet(screenIsDirty, pos);
|
||||
}
|
||||
}
|
||||
|
@ -430,8 +429,8 @@ void max7456WriteChar(uint8_t x, uint8_t y, uint16_t c, uint8_t mode)
|
|||
bool max7456ReadChar(uint8_t x, uint8_t y, uint16_t *c, uint8_t *mode)
|
||||
{
|
||||
unsigned pos = y * MAX7456_CHARS_PER_LINE + x;
|
||||
if (pos < ARRAYLEN(max7456ScreenBuffer)) {
|
||||
uint16_t val = max7456ScreenBuffer[pos];
|
||||
if (pos < ARRAYLEN(osdCharacterGridBuffer)) {
|
||||
uint16_t val = osdCharacterGridBuffer[pos];
|
||||
*c = CHAR_BYTE(val);
|
||||
*mode = MODE_BYTE(val);
|
||||
if (CHAR_MODE_IS_EXT(*mode)) {
|
||||
|
@ -454,8 +453,8 @@ void max7456Write(uint8_t x, uint8_t y, const char *buff, uint8_t mode)
|
|||
break;
|
||||
}
|
||||
c = MAKE_CHAR_MODE_U8(*buff, mode);
|
||||
if (max7456ScreenBuffer[pos] != c) {
|
||||
max7456ScreenBuffer[pos] = c;
|
||||
if (osdCharacterGridBuffer[pos] != c) {
|
||||
osdCharacterGridBuffer[pos] = c;
|
||||
bitArraySet(screenIsDirty, pos);
|
||||
}
|
||||
}
|
||||
|
@ -482,8 +481,8 @@ static bool max7456DrawScreenPartial(void)
|
|||
uint8_t ph = pos >> 8;
|
||||
uint8_t pl = pos & 0xff;
|
||||
|
||||
charMode = MODE_BYTE(max7456ScreenBuffer[pos]);
|
||||
uint8_t chr = CHAR_BYTE(max7456ScreenBuffer[pos]);
|
||||
charMode = MODE_BYTE(osdCharacterGridBuffer[pos]);
|
||||
uint8_t chr = CHAR_BYTE(osdCharacterGridBuffer[pos]);
|
||||
if (CHAR_MODE_IS_EXT(charMode)) {
|
||||
if (!DMM_IS_8BIT_MODE(state.registers.dmm)) {
|
||||
state.registers.dmm |= DMM_8BIT_MODE;
|
||||
|
@ -621,8 +620,8 @@ void max7456RefreshAll(void)
|
|||
|
||||
// Mark non-blank characters as dirty
|
||||
BITARRAY_CLR_ALL(screenIsDirty);
|
||||
for (unsigned ii = 0; ii < ARRAYLEN(max7456ScreenBuffer); ii++) {
|
||||
if (!CHAR_IS_BLANK(max7456ScreenBuffer[ii])) {
|
||||
for (unsigned ii = 0; ii < ARRAYLEN(osdCharacterGridBuffer); ii++) {
|
||||
if (!CHAR_IS_BLANK(osdCharacterGridBuffer[ii])) {
|
||||
bitArraySet(screenIsDirty, ii);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -44,8 +44,6 @@ enum VIDEO_TYPES { AUTO = 0, PAL, NTSC };
|
|||
#define MAX7456_MODE_BLINK (1 << 4)
|
||||
#define MAX7456_MODE_SOLID_BG (1 << 5)
|
||||
|
||||
extern uint16_t max7456ScreenBuffer[MAX7456_BUFFER_CHARS_PAL] ALIGNED(4);
|
||||
|
||||
void max7456Init(const videoSystem_e videoSystem);
|
||||
void max7456Update(void);
|
||||
void max7456ReadNvm(uint16_t char_address, osdCharacter_t *chr);
|
||||
|
|
43
src/main/drivers/osd.c
Normal file
43
src/main/drivers/osd.c
Normal file
|
@ -0,0 +1,43 @@
|
|||
/*
|
||||
* This file is part of INAV.
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms
|
||||
* of the GNU General Public License Version 3, as described below:
|
||||
*
|
||||
* This file is free software: you may copy, redistribute and/or modify
|
||||
* it under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation, either version 3 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
* This file is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
|
||||
* Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see http://www.gnu.org/licenses/.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "drivers/osd.h"
|
||||
|
||||
uint16_t osdCharacterGridBuffer[OSD_CHARACTER_GRID_BUFFER_SIZE] ALIGNED(4);
|
||||
|
||||
void osdCharacterGridBufferClear(void)
|
||||
{
|
||||
uint32_t *ptr = (uint32_t *)osdCharacterGridBuffer;
|
||||
uint32_t *end = (uint32_t *)(ARRAYEND(osdCharacterGridBuffer));
|
||||
for (; ptr < end; ptr++) {
|
||||
*ptr = 0;
|
||||
}
|
||||
}
|
||||
|
||||
uint16_t *osdCharacterGridBufferGetEntryPtr(unsigned x, unsigned y)
|
||||
{
|
||||
unsigned pos = y * OSD_CHARACTER_GRID_MAX_WIDTH + x;
|
||||
return &osdCharacterGridBuffer[pos];
|
||||
}
|
|
@ -22,6 +22,8 @@
|
|||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "common/utils.h"
|
||||
|
||||
#define OSD_CHAR_WIDTH 12
|
||||
#define OSD_CHAR_HEIGHT 18
|
||||
#define OSD_CHAR_BITS_PER_PIXEL 2
|
||||
|
@ -57,3 +59,13 @@ typedef enum {
|
|||
typedef struct osdCharacter_s {
|
||||
uint8_t data[OSD_CHAR_BYTES];
|
||||
} osdCharacter_t;
|
||||
|
||||
#define OSD_CHARACTER_GRID_MAX_WIDTH 30
|
||||
#define OSD_CHARACTER_GRID_MAX_HEIGHT 16
|
||||
#define OSD_CHARACTER_GRID_BUFFER_SIZE (OSD_CHARACTER_GRID_MAX_WIDTH * OSD_CHARACTER_GRID_MAX_HEIGHT)
|
||||
|
||||
extern uint16_t osdCharacterGridBuffer[OSD_CHARACTER_GRID_BUFFER_SIZE] ALIGNED(4);
|
||||
|
||||
// Sets all buffer entries to 0
|
||||
void osdCharacterGridBufferClear(void);
|
||||
uint16_t *osdCharacterGridBufferGetEntryPtr(unsigned x, unsigned y);
|
||||
|
|
|
@ -13,7 +13,6 @@
|
|||
#include "common/utils.h"
|
||||
#include "common/uvarint.h"
|
||||
|
||||
#include "drivers/max7456.h"
|
||||
#include "drivers/time.h"
|
||||
|
||||
#include "io/frsky_osd.h"
|
||||
|
@ -25,7 +24,6 @@
|
|||
#define FRSKY_OSD_PREAMBLE_BYTE_0 '$'
|
||||
#define FRSKY_OSD_PREAMBLE_BYTE_1 'A'
|
||||
|
||||
#define FRSKY_OSD_GRID_BUFFER_POS(x, y) (y * MAX7456_CHARS_PER_LINE + x)
|
||||
#define FRSKY_OSD_GRID_BUFFER_CHAR_BITS 9
|
||||
#define FRSKY_OSD_GRID_BUFFER_CHAR_MASK ((1 << FRSKY_OSD_GRID_BUFFER_CHAR_BITS) - 1)
|
||||
#define FRSKY_OSD_GRID_BUFFER_ENCODE(chr, attr) ((chr & FRSKY_OSD_GRID_BUFFER_CHAR_MASK) | (attr << FRSKY_OSD_GRID_BUFFER_CHAR_BITS))
|
||||
|
@ -694,18 +692,18 @@ void frskyOSDDrawStringInGrid(unsigned x, unsigned y, const char *buff, textAttr
|
|||
{
|
||||
unsigned charsUpdated = 0;
|
||||
const char *updatedCharAt = NULL;
|
||||
unsigned pos = FRSKY_OSD_GRID_BUFFER_POS(x, y);
|
||||
uint16_t *entry = osdCharacterGridBufferGetEntryPtr(x, y);
|
||||
const char *p;
|
||||
unsigned xx;
|
||||
for (p = buff, xx = x; *p && xx < state.info.grid.columns; p++, pos++, xx++) {
|
||||
for (p = buff, xx = x; *p && xx < state.info.grid.columns; p++, entry++, xx++) {
|
||||
unsigned val = FRSKY_OSD_GRID_BUFFER_ENCODE(*p, attr);
|
||||
if (max7456ScreenBuffer[pos] != val) {
|
||||
if (*entry != val) {
|
||||
if (++charsUpdated == 1) {
|
||||
// First character that needs to be updated, save it
|
||||
// in case we can issue a single update.
|
||||
updatedCharAt = p;
|
||||
}
|
||||
max7456ScreenBuffer[pos] = val;
|
||||
*entry = val;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -728,22 +726,21 @@ void frskyOSDDrawStringInGrid(unsigned x, unsigned y, const char *buff, textAttr
|
|||
|
||||
void frskyOSDDrawCharInGrid(unsigned x, unsigned y, uint16_t chr, textAttributes_t attr)
|
||||
{
|
||||
unsigned pos = FRSKY_OSD_GRID_BUFFER_POS(x, y);
|
||||
uint16_t *entry = osdCharacterGridBufferGetEntryPtr(x, y);
|
||||
unsigned val = FRSKY_OSD_GRID_BUFFER_ENCODE(chr, attr);
|
||||
|
||||
if (max7456ScreenBuffer[pos] == val) {
|
||||
if (*entry == val) {
|
||||
return;
|
||||
}
|
||||
|
||||
frskyOSDSendCharInGrid(x, y, chr, attr);
|
||||
|
||||
max7456ScreenBuffer[pos] = val;
|
||||
*entry = val;
|
||||
}
|
||||
|
||||
bool frskyOSDReadCharInGrid(unsigned x, unsigned y, uint16_t *c, textAttributes_t *attr)
|
||||
{
|
||||
unsigned pos = FRSKY_OSD_GRID_BUFFER_POS(x, y);
|
||||
uint16_t val = max7456ScreenBuffer[pos];
|
||||
uint16_t val = *osdCharacterGridBufferGetEntryPtr(x, y);
|
||||
// We use the lower 10 bits for characters
|
||||
*c = val & FRSKY_OSD_GRID_BUFFER_CHAR_MASK;
|
||||
*attr = val >> FRSKY_OSD_GRID_BUFFER_CHAR_BITS;
|
||||
|
@ -752,7 +749,7 @@ bool frskyOSDReadCharInGrid(unsigned x, unsigned y, uint16_t *c, textAttributes_
|
|||
|
||||
void frskyOSDClearScreen(void)
|
||||
{
|
||||
memset(max7456ScreenBuffer, 0, sizeof(max7456ScreenBuffer));
|
||||
osdCharacterGridBufferClear();
|
||||
frskyOSDSendAsyncCommand(OSD_CMD_DRAWING_CLEAR_SCREEN, NULL, 0);
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue