kopia lustrzana https://github.com/hoglet67/RGBtoHDMI
Pi Firmware: Added features menu: palette, scanlines, mux
Change-Id: Ica46c024d05abde2bfc7af10d5968b56778adddbissue_1022
rodzic
8f1c30e608
commit
5a5091590d
19
src/defs.h
19
src/defs.h
|
@ -25,15 +25,16 @@
|
|||
// bit 3 is the field type (0 = odd, 1 = even) of the last field
|
||||
|
||||
#define BIT_MODE7 0x01
|
||||
#define BIT_DRAW_BUFFER 0x02
|
||||
#define BIT_DISP_BUFFER 0x04
|
||||
#define BIT_ELK 0x08
|
||||
#define BIT_PROBE 0x10
|
||||
#define BIT_CALIBRATE 0x20
|
||||
#define BIT_CAL_COUNT 0x40
|
||||
#define BIT_INITIALIZE 0x80
|
||||
#define BIT_FIELD_TYPE 0x100
|
||||
#define BIT_CLEAR 0x200
|
||||
#define BIT_PROBE 0x02
|
||||
#define BIT_CALIBRATE 0x04
|
||||
#define BIT_CAL_COUNT 0x08
|
||||
#define BIT_INITIALIZE 0x10
|
||||
#define BIT_ELK 0x20
|
||||
#define BIT_SCANLINES 0x40
|
||||
#define BIT_FIELD_TYPE 0x80
|
||||
#define BIT_CLEAR 0x100
|
||||
#define BIT_DRAW_BUFFER 0x200
|
||||
#define BIT_DISP_BUFFER 0x400
|
||||
|
||||
// R0 return value bits
|
||||
#define RET_SW1 0x02
|
||||
|
|
211
src/osd.c
211
src/osd.c
|
@ -25,6 +25,122 @@ static char message[80];
|
|||
|
||||
static int active = 0;
|
||||
|
||||
#define NUM_PALETTES 10
|
||||
|
||||
enum {
|
||||
PALETTE_DEFAULT,
|
||||
PALETTE_INVERSE,
|
||||
PALETTE_MONO1,
|
||||
PALETTE_MONO2,
|
||||
PALETTE_RED,
|
||||
PALETTE_GREEN,
|
||||
PALETTE_BLUE,
|
||||
PALETTE_NOT_RED,
|
||||
PALETTE_NOT_GREEN,
|
||||
PALETTE_NOT_BLUE
|
||||
};
|
||||
|
||||
static const char *palette_names[] = {
|
||||
"Default",
|
||||
"Inverse",
|
||||
"Mono 1",
|
||||
"Mono 2",
|
||||
"Just Red",
|
||||
"Just Green",
|
||||
"Just Blue",
|
||||
"Not Red",
|
||||
"Not Green",
|
||||
"Not Blue"
|
||||
};
|
||||
|
||||
|
||||
// =============================================================
|
||||
// Feature definitions for OSD
|
||||
// =============================================================
|
||||
|
||||
enum {
|
||||
PALETTE,
|
||||
SCANLINE,
|
||||
MUX
|
||||
};
|
||||
|
||||
static param_t features[] = {
|
||||
{ "Color Palette", 0, NUM_PALETTES - 1 },
|
||||
{ "Scanlines", 0, 1 },
|
||||
{ "Input Mux", 0, 1 },
|
||||
{ NULL, 0, 0 },
|
||||
};
|
||||
|
||||
|
||||
static int palette = PALETTE_DEFAULT;
|
||||
|
||||
static int mux = 0;
|
||||
|
||||
static int scanline = 0;
|
||||
|
||||
uint32_t *osd_get_palette() {
|
||||
int m;
|
||||
static uint32_t palette_data[16];
|
||||
for (int i = 0; i < 16; i++) {
|
||||
int r = (i & 1) ? 255 : 0;
|
||||
int g = (i & 2) ? 255 : 0;
|
||||
int b = (i & 4) ? 255 : 0;
|
||||
switch (palette) {
|
||||
case PALETTE_INVERSE:
|
||||
r = 255 - r;
|
||||
g = 255 - g;
|
||||
b = 255 - b;
|
||||
break;
|
||||
case PALETTE_MONO1:
|
||||
m = 0.299 * r + 0.587 * g + 0.114 * b;
|
||||
r = m; g = m; b = m;
|
||||
break;
|
||||
case PALETTE_MONO2:
|
||||
m = (i & 7) * 255 / 7;
|
||||
r = m; g = m; b = m;
|
||||
break;
|
||||
case PALETTE_RED:
|
||||
m = (i & 7) * 255 / 7;
|
||||
r = m; g = 0; b = 0;
|
||||
break;
|
||||
case PALETTE_GREEN:
|
||||
m = (i & 7) * 255 / 7;
|
||||
r = 0; g = m; b = 0;
|
||||
break;
|
||||
case PALETTE_BLUE:
|
||||
m = (i & 7) * 255 / 7;
|
||||
r = 0; g = 0; b = m;
|
||||
break;
|
||||
case PALETTE_NOT_RED:
|
||||
r = 0;
|
||||
g = (i & 3) * 255 / 3;
|
||||
b = ((i >> 2) & 1) * 255;
|
||||
break;
|
||||
case PALETTE_NOT_GREEN:
|
||||
r = (i & 3) * 255 / 3;
|
||||
g = 0;
|
||||
b = ((i >> 2) & 1) * 255;
|
||||
break;
|
||||
case PALETTE_NOT_BLUE:
|
||||
r = ((i >> 2) & 1) * 255;
|
||||
g = (i & 3) * 255 / 3;
|
||||
b = 0;
|
||||
break;
|
||||
}
|
||||
if (active) {
|
||||
if (i >= 8) {
|
||||
palette_data[i] = 0xFFFFFFFF;
|
||||
} else {
|
||||
r >>= 1; g >>= 1; b >>= 1;
|
||||
palette_data[i] = 0xFF000000 | (b << 16) | (g << 8) | r;
|
||||
}
|
||||
} else {
|
||||
palette_data[i] = 0xFF000000 | (b << 16) | (g << 8) | r;
|
||||
}
|
||||
}
|
||||
return palette_data;
|
||||
}
|
||||
|
||||
void osd_init() {
|
||||
// Precalculate character->screen mapping table
|
||||
//
|
||||
|
@ -94,13 +210,17 @@ void osd_init() {
|
|||
}
|
||||
}
|
||||
|
||||
static void update_palette() {
|
||||
RPI_PropertyInit();
|
||||
RPI_PropertyAddTag( TAG_SET_PALETTE, osd_get_palette());
|
||||
RPI_PropertyProcess();
|
||||
}
|
||||
|
||||
void osd_clear() {
|
||||
if (active) {
|
||||
active = 0;
|
||||
RPI_SetGpioValue(LED1_PIN, active);
|
||||
RPI_PropertyInit();
|
||||
RPI_PropertyAddTag( TAG_SET_PALETTE );
|
||||
RPI_PropertyProcess();
|
||||
update_palette();
|
||||
memset(buffer, 0, sizeof(buffer));
|
||||
}
|
||||
osd_update((uint32_t *)fb, pitch);
|
||||
|
@ -111,9 +231,7 @@ void osd_set(int line, int attr, char *text) {
|
|||
if (!active) {
|
||||
active = 1;
|
||||
RPI_SetGpioValue(LED1_PIN, active);
|
||||
RPI_PropertyInit();
|
||||
RPI_PropertyAddTag( TAG_SET_PALETTE );
|
||||
RPI_PropertyProcess();
|
||||
update_palette();
|
||||
}
|
||||
attributes[line] = attr;
|
||||
memset(buffer + line * LINELEN, 0, LINELEN);
|
||||
|
@ -134,7 +252,8 @@ int osd_active() {
|
|||
|
||||
enum {
|
||||
IDLE,
|
||||
MANUAL
|
||||
MANUAL,
|
||||
FEATURE,
|
||||
};
|
||||
|
||||
|
||||
|
@ -148,10 +267,45 @@ static void show_param(int num) {
|
|||
osd_set(1, 0, message);
|
||||
}
|
||||
|
||||
static int get_feature(int num) {
|
||||
switch (num) {
|
||||
case PALETTE:
|
||||
return palette;
|
||||
case MUX:
|
||||
return mux;
|
||||
case SCANLINE:
|
||||
return scanline;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
static void set_feature(int num, int value) {
|
||||
switch (num) {
|
||||
case PALETTE:
|
||||
palette = value;
|
||||
update_palette();
|
||||
break;
|
||||
case MUX:
|
||||
mux = value;
|
||||
RPI_SetGpioValue(MUX_PIN, mux);
|
||||
break;
|
||||
case SCANLINE:
|
||||
scanline = value;
|
||||
action_scanlines(value);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void show_feature(int num) {
|
||||
int value = get_feature(num);
|
||||
sprintf(message, "%s = %s", features[num].name, (num == PALETTE) ? palette_names[value] : value ? "On" : "Off");
|
||||
osd_set(1, 0, message);
|
||||
}
|
||||
|
||||
void osd_key(int key) {
|
||||
static int osd_state = IDLE;
|
||||
static int param_num = 0;
|
||||
static int mux = 0;
|
||||
static int feature_num = 0;
|
||||
|
||||
int value;
|
||||
param_t *params = cpld->get_params();
|
||||
|
@ -163,18 +317,14 @@ void osd_key(int key) {
|
|||
case OSD_SW1:
|
||||
// Manual Calibration
|
||||
osd_set(0, ATTR_DOUBLE_SIZE, "Manual Calibration");
|
||||
param_num = 0;
|
||||
show_param(param_num);
|
||||
osd_state = MANUAL;
|
||||
break;
|
||||
case OSD_SW2:
|
||||
// Input Mux toggle
|
||||
mux = 1 - mux;
|
||||
RPI_SetGpioValue(MUX_PIN, mux);
|
||||
sprintf(message, "Input Mux = %d", mux);
|
||||
osd_set(0, ATTR_DOUBLE_SIZE, message);
|
||||
delay();
|
||||
osd_clear();
|
||||
// Feature Selection
|
||||
osd_set(0, ATTR_DOUBLE_SIZE, "Feature Selection");
|
||||
show_feature(feature_num);
|
||||
osd_state = FEATURE;
|
||||
break;
|
||||
case OSD_SW3:
|
||||
// Auto Calibration
|
||||
|
@ -214,6 +364,35 @@ void osd_key(int key) {
|
|||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case FEATURE:
|
||||
switch (key) {
|
||||
case OSD_SW1:
|
||||
// exit feature selection
|
||||
osd_state = IDLE;
|
||||
osd_clear();
|
||||
break;
|
||||
case OSD_SW2:
|
||||
// next feature
|
||||
feature_num++;
|
||||
if (features[feature_num].name == NULL) {
|
||||
feature_num = 0;
|
||||
}
|
||||
show_feature(feature_num);
|
||||
break;
|
||||
case OSD_SW3:
|
||||
// next value
|
||||
value = get_feature(feature_num);
|
||||
if (value < features[feature_num].max) {
|
||||
value++;
|
||||
} else {
|
||||
value = features[feature_num].min;
|
||||
}
|
||||
set_feature(feature_num, value);
|
||||
show_feature(feature_num);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -13,8 +13,9 @@ void osd_set(int line, int attr, char *text);
|
|||
void osd_update(uint32_t *osd_base, int bytes_per_line);
|
||||
int osd_active();
|
||||
void osd_key(int key);
|
||||
uint32_t *osd_get_palette();
|
||||
|
||||
void action_calibrate();
|
||||
void action_toggle_mux();
|
||||
void action_scanlines(int on);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -113,7 +113,7 @@ rgb_to_fb:
|
|||
blne clear_screen
|
||||
|
||||
// clear all the state bits apart from the following:
|
||||
bic r3, r3, #~(BIT_MODE7 | BIT_PROBE | BIT_CALIBRATE | BIT_CAL_COUNT | BIT_INITIALIZE | BIT_ELK)
|
||||
bic r3, r3, #~(BIT_MODE7 | BIT_PROBE | BIT_CALIBRATE | BIT_CAL_COUNT | BIT_INITIALIZE | BIT_ELK | BIT_SCANLINES)
|
||||
|
||||
// write to buffer 0, display buffer 1
|
||||
orr r3, r3, #BIT_DISP_BUFFER
|
||||
|
@ -281,9 +281,10 @@ process_chars_loop:
|
|||
// Line double always in Modes 0-6 regardless of interlace
|
||||
// On the multi core Pi this introduces stalling artefacts
|
||||
#ifndef HAS_MULTICORE
|
||||
tst r3, #BIT_MODE7
|
||||
tst r3, #(BIT_MODE7 | BIT_SCANLINES)
|
||||
streq r10, [r12, r2]
|
||||
#endif
|
||||
tst r3, #(BIT_MODE7)
|
||||
ldrne r0, [r12]
|
||||
bicne r0, #0x77000000
|
||||
bicne r0, #0x00770000
|
||||
|
|
|
@ -53,6 +53,8 @@ static uint32_t cpld_version_id;
|
|||
static int delay;
|
||||
static int elk;
|
||||
static int mode7;
|
||||
static int clear;
|
||||
static int scanlines = 0;
|
||||
static int last_mode7;
|
||||
static int result;
|
||||
static int chars_per_line;
|
||||
|
@ -154,7 +156,7 @@ static void init_framebuffer(int mode7) {
|
|||
#endif
|
||||
RPI_PropertyAddTag( TAG_SET_DEPTH, SCREEN_DEPTH );
|
||||
if (SCREEN_DEPTH <= 8) {
|
||||
RPI_PropertyAddTag( TAG_SET_PALETTE );
|
||||
RPI_PropertyAddTag( TAG_SET_PALETTE, osd_get_palette());
|
||||
}
|
||||
RPI_PropertyAddTag( TAG_GET_PITCH );
|
||||
RPI_PropertyAddTag( TAG_GET_PHYSICAL_SIZE );
|
||||
|
@ -253,7 +255,7 @@ static void init_framebuffer(int mode7) {
|
|||
// Initialize the palette
|
||||
if (SCREEN_DEPTH <= 8) {
|
||||
RPI_PropertyInit();
|
||||
RPI_PropertyAddTag( TAG_SET_PALETTE );
|
||||
RPI_PropertyAddTag( TAG_SET_PALETTE, osd_get_palette());
|
||||
RPI_PropertyProcess();
|
||||
}
|
||||
|
||||
|
@ -651,6 +653,15 @@ void swapBuffer(int buffer) {
|
|||
}
|
||||
#endif
|
||||
|
||||
void action_scanlines(int on) {
|
||||
if (on) {
|
||||
scanlines = BIT_SCANLINES;
|
||||
} else {
|
||||
scanlines = 0;
|
||||
}
|
||||
clear = BIT_CLEAR;
|
||||
}
|
||||
|
||||
void action_calibrate() {
|
||||
elk = test_for_elk(mode7, chars_per_line);
|
||||
log_debug("Elk mode = %d", elk);
|
||||
|
@ -687,12 +698,12 @@ void rgb_to_hdmi_main() {
|
|||
|
||||
chars_per_line = mode7 ? MODE7_CHARS_PER_LINE : DEFAULT_CHARS_PER_LINE;
|
||||
|
||||
int clear = BIT_CLEAR;
|
||||
clear = BIT_CLEAR;
|
||||
|
||||
do {
|
||||
|
||||
log_debug("Entering rgb_to_fb");
|
||||
result = rgb_to_fb(fb, chars_per_line, pitch, mode7 | BIT_INITIALIZE | (elk ? BIT_ELK : 0) | clear);
|
||||
result = rgb_to_fb(fb, chars_per_line, pitch, mode7 | BIT_INITIALIZE | (elk ? BIT_ELK : 0) | clear | scanlines);
|
||||
log_debug("Leaving rgb_to_fb, result= %d", result);
|
||||
clear = 0;
|
||||
|
||||
|
|
|
@ -16,11 +16,6 @@ static int pt_index ;
|
|||
|
||||
//#define PRINT_PROP_DEBUG 1
|
||||
|
||||
#ifdef ___DEBUG
|
||||
#define BLACK 0x00202020
|
||||
#else
|
||||
#define BLACK 0x00000000
|
||||
#endif
|
||||
|
||||
void RPI_PropertyInit( void )
|
||||
{
|
||||
|
@ -207,40 +202,9 @@ void RPI_PropertyAddTag( rpi_mailbox_tag_t tag, ... )
|
|||
pt[pt_index++] = 0; /* Request */
|
||||
pt[pt_index++] = 0; // Offset to first colour
|
||||
pt[pt_index++] = 16; // Number of colours
|
||||
if (osd_active()) {
|
||||
pt[pt_index++] = 0xFF000000; // Colour 0 - Black
|
||||
pt[pt_index++] = 0xFF00007F; // Colour 1 - Red
|
||||
pt[pt_index++] = 0xFF007F00; // Colour 2 - Green
|
||||
pt[pt_index++] = 0xFF007F7F; // Colour 3 - Yellow
|
||||
pt[pt_index++] = 0xFF7F0000; // Colour 4 - Blue
|
||||
pt[pt_index++] = 0xFF7F007F; // Colour 5 - Magenta
|
||||
pt[pt_index++] = 0xFF7F7F00; // Colour 6 - Cyan
|
||||
pt[pt_index++] = 0xFF7F7F7F; // Colour 7 - White
|
||||
pt[pt_index++] = 0xFFFFFFFF; // Colour 8 - White
|
||||
pt[pt_index++] = 0xFFFFFFFF; // Colour 9 - White
|
||||
pt[pt_index++] = 0xFFFFFFFF; // Colour 10 - White
|
||||
pt[pt_index++] = 0xFFFFFFFF; // Colour 11 - White
|
||||
pt[pt_index++] = 0xFFFFFFFF; // Colour 12 - White
|
||||
pt[pt_index++] = 0xFFFFFFFF; // Colour 13 - White
|
||||
pt[pt_index++] = 0xFFFFFFFF; // Colour 14 - White
|
||||
pt[pt_index++] = 0xFFFFFFFF; // Colour 15 - White
|
||||
} else {
|
||||
pt[pt_index++] = 0xFF000000 | BLACK; // Colour 0 - Black
|
||||
pt[pt_index++] = 0xFF0000FF | BLACK; // Colour 1 - Red
|
||||
pt[pt_index++] = 0xFF00FF00 | BLACK; // Colour 2 - Green
|
||||
pt[pt_index++] = 0xFF00FFFF | BLACK; // Colour 3 - Yellow
|
||||
pt[pt_index++] = 0xFFFF0000 | BLACK; // Colour 4 - Blue
|
||||
pt[pt_index++] = 0xFFFF00FF | BLACK; // Colour 5 - Magenta
|
||||
pt[pt_index++] = 0xFFFFFF00 | BLACK; // Colour 6 - Cyan
|
||||
pt[pt_index++] = 0xFFFFFFFF | BLACK; // Colour 7 - White
|
||||
pt[pt_index++] = 0xFF000000 | BLACK; // Colour 8 - Black
|
||||
pt[pt_index++] = 0xFF0000FF | BLACK; // Colour 9 - Red
|
||||
pt[pt_index++] = 0xFF00FF00 | BLACK; // Colour 10 - Green
|
||||
pt[pt_index++] = 0xFF00FFFF | BLACK; // Colour 11 - Yellow
|
||||
pt[pt_index++] = 0xFFFF0000 | BLACK; // Colour 12 - Blue
|
||||
pt[pt_index++] = 0xFFFF00FF | BLACK; // Colour 13 - Magenta
|
||||
pt[pt_index++] = 0xFFFFFF00 | BLACK; // Colour 14 - Cyan
|
||||
pt[pt_index++] = 0xFFFFFFFF | BLACK; // Colour 15 - White
|
||||
uint32_t *palette = va_arg( vl, uint32_t *);
|
||||
for (int i = 0; i < 16; i++) {
|
||||
pt[pt_index++] = palette[i];
|
||||
}
|
||||
break;
|
||||
|
||||
|
|
Ładowanie…
Reference in New Issue