Pi Firmware: Added features menu: palette, scanlines, mux

Change-Id: Ica46c024d05abde2bfc7af10d5968b56778adddb
issue_1022
David Banks 2018-06-20 15:12:38 +01:00
rodzic 8f1c30e608
commit 5a5091590d
6 zmienionych plików z 228 dodań i 71 usunięć

Wyświetl plik

@ -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
Wyświetl plik

@ -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;
}
}

Wyświetl plik

@ -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

Wyświetl plik

@ -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

Wyświetl plik

@ -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;

Wyświetl plik

@ -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;