kopia lustrzana https://github.com/hoglet67/RGBtoHDMI
Pi Firmware: Added info feature
Change-Id: I135917438b8827c282e425af9d8d6239571061b1issue_1022
rodzic
72fb871bbb
commit
a65f4ac6e8
|
@ -25,6 +25,9 @@ typedef struct {
|
|||
param_t *(*get_params)();
|
||||
int (*get_value)(int num);
|
||||
void (*set_value)(int num, int value);
|
||||
// Support for info page
|
||||
void (*show_cal_summary)(int line);
|
||||
void (*show_cal_details)(int line);
|
||||
} cpld_t;
|
||||
|
||||
int *diff_N_frames(int n, int mode7, int elk, int chars_per_line);
|
||||
|
|
|
@ -29,6 +29,18 @@ static int mode7;
|
|||
// OSD message buffer
|
||||
static char message[80];
|
||||
|
||||
// Calibration metrics (i.e. errors) for mode 0..6
|
||||
static int metrics_default[8]; // Last two not used
|
||||
|
||||
// Calibration metrics (i.e. errors) for mode 7
|
||||
static int metrics_mode7[8];
|
||||
|
||||
// Error count for final calibration values for mode 0..6
|
||||
static int errors_default;
|
||||
|
||||
// Error count for final calibration values for mode 7
|
||||
static int errors_mode7;
|
||||
|
||||
// =============================================================
|
||||
// Param definitions for OSD
|
||||
// =============================================================
|
||||
|
@ -95,15 +107,24 @@ static void write_config(config_t *config) {
|
|||
RPI_SetGpioValue(SP_DATA_PIN, 0);
|
||||
}
|
||||
|
||||
static void osd_sp(config_t *config, int metric) {
|
||||
static void osd_sp(config_t *config, int line, int metric) {
|
||||
if (mode7) {
|
||||
osd_set(line, 0, " Mode: 7");
|
||||
} else {
|
||||
osd_set(line, 0, " Mode: 0..6");
|
||||
}
|
||||
sprintf(message, "Offsets: %d %d %d %d %d %d",
|
||||
config->sp_offset[0], config->sp_offset[1], config->sp_offset[2],
|
||||
config->sp_offset[3], config->sp_offset[4], config->sp_offset[5]);
|
||||
osd_set(1, 0, message);
|
||||
osd_set(line + 1, 0, message);
|
||||
sprintf(message, " Half: %d", config->half_px_delay);
|
||||
osd_set(2, 0, message);
|
||||
sprintf(message, " Errors: %d", metric);
|
||||
osd_set(3, 0, message);
|
||||
osd_set(line + 2, 0, message);
|
||||
if (metric < 0) {
|
||||
sprintf(message, " Errors: unknown");
|
||||
} else {
|
||||
sprintf(message, " Errors: %d", metric);
|
||||
}
|
||||
osd_set(line + 3, 0, message);
|
||||
}
|
||||
|
||||
static void log_sp(config_t *config) {
|
||||
|
@ -125,6 +146,12 @@ static void cpld_init() {
|
|||
default_config.half_px_delay = 0;
|
||||
mode7_config.half_px_delay = 0;
|
||||
config = &default_config;
|
||||
for (int i = 0; i < 8; i++) {
|
||||
metrics_default[i] = -1;
|
||||
metrics_mode7[i] = -1;
|
||||
}
|
||||
errors_default = -1;
|
||||
errors_mode7 = -1;
|
||||
}
|
||||
|
||||
static void cpld_calibrate(int elk, int chars_per_line) {
|
||||
|
@ -134,16 +161,23 @@ static void cpld_calibrate(int elk, int chars_per_line) {
|
|||
int win_metric; // this is a windowed value (over three sample offsets)
|
||||
int min_win_metric;
|
||||
int *rgb_metric;
|
||||
int metrics[8]; // offsets are 3-bit values
|
||||
|
||||
int range; // 0..5 in Modes 0..6, 0..7 in Mode 7
|
||||
int *metrics;
|
||||
int *errors;
|
||||
|
||||
if (mode7) {
|
||||
log_info("Calibrating mode 7");
|
||||
range = 8;
|
||||
metrics = metrics_mode7;
|
||||
errors = &errors_mode7;
|
||||
} else {
|
||||
log_info("Calibrating modes 0..6");
|
||||
range = 6;
|
||||
metrics = metrics_default;
|
||||
errors = &errors_default;
|
||||
}
|
||||
|
||||
range = mode7 ? 8 : 6;
|
||||
min_metric = INT_MAX;
|
||||
config->half_px_delay = 0;
|
||||
for (int i = 0; i < range; i++) {
|
||||
|
@ -154,7 +188,7 @@ static void cpld_calibrate(int elk, int chars_per_line) {
|
|||
rgb_metric = diff_N_frames(NUM_CAL_FRAMES, mode7, elk, chars_per_line);
|
||||
metric = rgb_metric[CHAN_RED] + rgb_metric[CHAN_GREEN] + rgb_metric[CHAN_BLUE];
|
||||
metrics[i] = metric;
|
||||
osd_sp(config, metric);
|
||||
osd_sp(config, 1, metric);
|
||||
log_info("offset = %d: metric = %5d", i, metric);
|
||||
if (metric < min_metric) {
|
||||
min_metric = metric;
|
||||
|
@ -198,7 +232,7 @@ static void cpld_calibrate(int elk, int chars_per_line) {
|
|||
write_config(config);
|
||||
rgb_metric = diff_N_frames(NUM_CAL_FRAMES, mode7, elk, chars_per_line);
|
||||
left = rgb_metric[CHAN_RED] + rgb_metric[CHAN_GREEN] + rgb_metric[CHAN_BLUE];
|
||||
osd_sp(config, left);
|
||||
osd_sp(config, 1, left);
|
||||
config->sp_offset[i]++;
|
||||
}
|
||||
if (config->sp_offset[i] < 7) {
|
||||
|
@ -206,7 +240,7 @@ static void cpld_calibrate(int elk, int chars_per_line) {
|
|||
write_config(config);
|
||||
rgb_metric = diff_N_frames(NUM_CAL_FRAMES, mode7, elk, chars_per_line);
|
||||
right = rgb_metric[CHAN_RED] + rgb_metric[CHAN_GREEN] + rgb_metric[CHAN_BLUE];
|
||||
osd_sp(config, right);
|
||||
osd_sp(config, 1, right);
|
||||
config->sp_offset[i]--;
|
||||
}
|
||||
if (left < right && left < ref) {
|
||||
|
@ -222,8 +256,8 @@ static void cpld_calibrate(int elk, int chars_per_line) {
|
|||
}
|
||||
write_config(config);
|
||||
rgb_metric = diff_N_frames(NUM_CAL_FRAMES, mode7, elk, chars_per_line);
|
||||
metric = rgb_metric[CHAN_RED] + rgb_metric[CHAN_GREEN] + rgb_metric[CHAN_BLUE];
|
||||
osd_sp(config, metric);
|
||||
*errors = rgb_metric[CHAN_RED] + rgb_metric[CHAN_GREEN] + rgb_metric[CHAN_BLUE];
|
||||
osd_sp(config, 1, *errors);
|
||||
log_info("Calibration complete");
|
||||
log_sp(config);
|
||||
}
|
||||
|
@ -299,6 +333,24 @@ static void cpld_set_value(int num, int value) {
|
|||
write_config(config);
|
||||
}
|
||||
|
||||
static void cpld_show_cal_summary(int line) {
|
||||
osd_sp(config, line, mode7 ? errors_mode7 : errors_default);
|
||||
}
|
||||
|
||||
static void cpld_show_cal_details(int line) {
|
||||
int *metrics = mode7 ? metrics_mode7 : metrics_default;
|
||||
int num = (*metrics < 0) ? 0 : mode7 ? 8 : 6;
|
||||
if (num == 0) {
|
||||
sprintf(message, "No calibration data for this mode");
|
||||
osd_set(line, 0, message);
|
||||
} else {
|
||||
for (int i = 0; i < num; i++) {
|
||||
sprintf(message, "Offset %d: Errors = %6d", i, metrics[i]);
|
||||
osd_set(line + i, 0, message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
cpld_t cpld_normal = {
|
||||
.name = "Normal",
|
||||
.init = cpld_init,
|
||||
|
@ -306,5 +358,7 @@ cpld_t cpld_normal = {
|
|||
.set_mode = cpld_set_mode,
|
||||
.get_params = cpld_get_params,
|
||||
.get_value = cpld_get_value,
|
||||
.set_value = cpld_set_value
|
||||
.set_value = cpld_set_value,
|
||||
.show_cal_summary = cpld_show_cal_summary,
|
||||
.show_cal_details = cpld_show_cal_details
|
||||
};
|
||||
|
|
80
src/osd.c
80
src/osd.c
|
@ -3,15 +3,16 @@
|
|||
#include <string.h>
|
||||
#include <inttypes.h>
|
||||
#include "defs.h"
|
||||
#include "osd.h"
|
||||
#include "cpld.h"
|
||||
#include "gitversion.h"
|
||||
#include "info.h"
|
||||
#include "logging.h"
|
||||
#include "osd.h"
|
||||
#include "rpi-gpio.h"
|
||||
#include "rpi-mailbox-interface.h"
|
||||
#include "saa5050_font.h"
|
||||
|
||||
#define NLINES 4
|
||||
#define NLINES 12
|
||||
#define LINELEN 40
|
||||
|
||||
static char buffer[LINELEN * NLINES];
|
||||
|
@ -27,8 +28,6 @@ static char message[80];
|
|||
|
||||
static int active = 0;
|
||||
|
||||
#define NUM_PALETTES 10
|
||||
|
||||
enum {
|
||||
PALETTE_DEFAULT,
|
||||
PALETTE_INVERSE,
|
||||
|
@ -39,7 +38,8 @@ enum {
|
|||
PALETTE_BLUE,
|
||||
PALETTE_NOT_RED,
|
||||
PALETTE_NOT_GREEN,
|
||||
PALETTE_NOT_BLUE
|
||||
PALETTE_NOT_BLUE,
|
||||
NUM_PALETTES
|
||||
};
|
||||
|
||||
static const char *palette_names[] = {
|
||||
|
@ -55,20 +55,34 @@ static const char *palette_names[] = {
|
|||
"Not Blue"
|
||||
};
|
||||
|
||||
enum {
|
||||
INFO_VERSION,
|
||||
INFO_CAL_SUMMARY,
|
||||
INFO_CAL_DETAILS,
|
||||
NUM_INFOS
|
||||
};
|
||||
|
||||
static const char *info_names[] = {
|
||||
"Firmware Version",
|
||||
"Calibration Summary",
|
||||
"Calibration Detail"
|
||||
};
|
||||
|
||||
// =============================================================
|
||||
// Feature definitions for OSD
|
||||
// =============================================================
|
||||
|
||||
enum {
|
||||
F_INFO,
|
||||
F_PALETTE,
|
||||
F_SCANLINES,
|
||||
F_MUX,
|
||||
F_ELK,
|
||||
F_DEBUG,
|
||||
F_DEBUG
|
||||
};
|
||||
|
||||
static param_t features[] = {
|
||||
{ "Info", 0, NUM_INFOS - 1 },
|
||||
{ "Color Palette", 0, NUM_PALETTES - 1 },
|
||||
{ "Scanlines", 0, 1 },
|
||||
{ "Input Mux", 0, 1 },
|
||||
|
@ -77,7 +91,7 @@ static param_t features[] = {
|
|||
{ NULL, 0, 0 },
|
||||
};
|
||||
|
||||
|
||||
static int info = INFO_VERSION;
|
||||
static int palette = PALETTE_DEFAULT;
|
||||
static int scanlines = 0;
|
||||
static int mux = 0;
|
||||
|
@ -158,13 +172,13 @@ static void update_palette() {
|
|||
|
||||
void osd_clear() {
|
||||
if (active) {
|
||||
memset(buffer, 0, sizeof(buffer));
|
||||
osd_update((uint32_t *)fb, pitch);
|
||||
osd_update((uint32_t *)(fb + SCREEN_HEIGHT * pitch), pitch);
|
||||
active = 0;
|
||||
RPI_SetGpioValue(LED1_PIN, active);
|
||||
update_palette();
|
||||
memset(buffer, 0, sizeof(buffer));
|
||||
}
|
||||
osd_update((uint32_t *)fb, pitch);
|
||||
osd_update((uint32_t *)(fb + SCREEN_HEIGHT * pitch), pitch);
|
||||
}
|
||||
|
||||
void osd_set(int line, int attr, char *text) {
|
||||
|
@ -209,9 +223,11 @@ static void show_param(int num) {
|
|||
|
||||
static int get_feature(int num) {
|
||||
switch (num) {
|
||||
case F_INFO:
|
||||
return info;
|
||||
case F_PALETTE:
|
||||
return palette;
|
||||
case F_SCANLINES:
|
||||
case F_SCANLINES:
|
||||
return scanlines;
|
||||
case F_MUX:
|
||||
return mux;
|
||||
|
@ -225,6 +241,9 @@ static int get_feature(int num) {
|
|||
|
||||
static void set_feature(int num, int value) {
|
||||
switch (num) {
|
||||
case F_INFO:
|
||||
info = value;
|
||||
break;
|
||||
case F_PALETTE:
|
||||
palette = value;
|
||||
update_palette();
|
||||
|
@ -249,9 +268,43 @@ static void set_feature(int num, int value) {
|
|||
}
|
||||
|
||||
static void show_feature(int num) {
|
||||
// Read the current value of the specified feature
|
||||
int value = get_feature(num);
|
||||
sprintf(message, "%s = %s", features[num].name, (num == F_PALETTE) ? palette_names[value] : value ? "On" : "Off");
|
||||
// Convert that to a human readable string
|
||||
const char *valstr =
|
||||
(num == F_INFO) ? info_names[value] :
|
||||
(num == F_PALETTE) ? palette_names[value] :
|
||||
value ? "On" : "Off";
|
||||
// Clear lines 2 onwards
|
||||
memset(buffer + 2 * LINELEN, 0, (NLINES - 2) * LINELEN);
|
||||
// Dispay the feature name and value in line 1
|
||||
sprintf(message, "%s = %s", features[num].name, valstr);
|
||||
osd_set(1, 0, message);
|
||||
// If the info screen, provide further info on lines 3 onwards
|
||||
if (num == F_INFO) {
|
||||
switch (info) {
|
||||
case INFO_VERSION:
|
||||
sprintf(message, "%s", GITVERSION);
|
||||
osd_set(3, 0, message);
|
||||
break;
|
||||
case INFO_CAL_SUMMARY:
|
||||
if (cpld->show_cal_summary) {
|
||||
cpld->show_cal_summary(3);
|
||||
} else {
|
||||
sprintf(message, "show_cal_summary() not implemented");
|
||||
osd_set(3, 0, message);
|
||||
}
|
||||
break;
|
||||
case INFO_CAL_DETAILS:
|
||||
if (cpld->show_cal_details) {
|
||||
cpld->show_cal_details(3);
|
||||
} else {
|
||||
sprintf(message, "show_cal_details() not implemented");
|
||||
osd_set(3, 0, message);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void osd_key(int key) {
|
||||
|
@ -473,6 +526,9 @@ void osd_init() {
|
|||
}
|
||||
|
||||
void osd_update(uint32_t *osd_base, int bytes_per_line) {
|
||||
if (!active) {
|
||||
return;
|
||||
}
|
||||
// SAA5050 character data is 12x20
|
||||
uint32_t *line_ptr = osd_base;
|
||||
int words_per_line = bytes_per_line >> 2;
|
||||
|
|
Ładowanie…
Reference in New Issue