Pi Firmware: Added info feature

Change-Id: I135917438b8827c282e425af9d8d6239571061b1
issue_1022
David Banks 2018-07-13 12:10:52 +01:00
rodzic 72fb871bbb
commit a65f4ac6e8
3 zmienionych plików z 138 dodań i 25 usunięć

Wyświetl plik

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

Wyświetl plik

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

Wyświetl plik

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