kopia lustrzana https://github.com/hoglet67/RGBtoHDMI
Pi Firmware: use configurable half-pixel delay where appropriate in calibration, also introduce config struct
Change-Id: I2fd47a8baff531b3a2743079950811afbef10bcbissue_1022
rodzic
18ab9c084e
commit
b74f86964c
|
@ -10,25 +10,32 @@
|
||||||
// The number of frames to compute differences over
|
// The number of frames to compute differences over
|
||||||
#define NUM_CAL_FRAMES 10
|
#define NUM_CAL_FRAMES 10
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
int sp_base[NUM_CHANNELS];
|
||||||
|
int sp_offset[NUM_OFFSETS];
|
||||||
|
int half_px_delay;
|
||||||
|
} config_t;
|
||||||
|
|
||||||
// Current calibration state for mode 0..6
|
// Current calibration state for mode 0..6
|
||||||
static int default_sp_base[NUM_CHANNELS];
|
static config_t default_config;
|
||||||
static int default_sp_offset[NUM_OFFSETS];
|
|
||||||
|
|
||||||
// Current calibration state for mode 7
|
// Current calibration state for mode 7
|
||||||
static int mode7_sp_base[NUM_CHANNELS];
|
static config_t mode7_config;
|
||||||
static int mode7_sp_offset[NUM_OFFSETS];
|
|
||||||
|
|
||||||
// =============================================================
|
// =============================================================
|
||||||
// Private methods
|
// Private methods
|
||||||
// =============================================================
|
// =============================================================
|
||||||
|
|
||||||
static void write_config(int *sp_base, int *sp_offset) {
|
static void write_config(config_t *config) {
|
||||||
int sp = 0;
|
int sp = 0;
|
||||||
for (int i = 0; i < NUM_CHANNELS; i++) {
|
for (int i = 0; i < NUM_CHANNELS; i++) {
|
||||||
sp |= (sp_base[i] & 7) << (i * 3);
|
sp |= (config->sp_base[i] & 7) << (i * 3);
|
||||||
|
}
|
||||||
|
if (config->half_px_delay) {
|
||||||
|
sp |= (1 << 21);
|
||||||
}
|
}
|
||||||
for (int i = 0; i < NUM_OFFSETS; i++) {
|
for (int i = 0; i < NUM_OFFSETS; i++) {
|
||||||
switch (sp_offset[i]) {
|
switch (config->sp_offset[i]) {
|
||||||
case -1:
|
case -1:
|
||||||
sp |= 3 << (i * 2 + 9);
|
sp |= 3 << (i * 2 + 9);
|
||||||
break;
|
break;
|
||||||
|
@ -37,7 +44,7 @@ static void write_config(int *sp_base, int *sp_offset) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (int i = 0; i < 21; i++) {
|
for (int i = 0; i < 22; i++) {
|
||||||
RPI_SetGpioValue(SP_DATA_PIN, sp & 1);
|
RPI_SetGpioValue(SP_DATA_PIN, sp & 1);
|
||||||
for (int j = 0; j < 1000; j++);
|
for (int j = 0; j < 1000; j++);
|
||||||
RPI_SetGpioValue(SP_CLKEN_PIN, 1);
|
RPI_SetGpioValue(SP_CLKEN_PIN, 1);
|
||||||
|
@ -52,10 +59,12 @@ static void write_config(int *sp_base, int *sp_offset) {
|
||||||
RPI_SetGpioValue(SP_DATA_PIN, 0);
|
RPI_SetGpioValue(SP_DATA_PIN, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void log_sp(int *sp_base, int *sp_offset) {
|
static void log_sp(config_t *config) {
|
||||||
log_info("sp_base = %d %d %d, sp_offset = %d %d %d %d %d %d",
|
log_info("sp_base = %d %d %d; sp_offset = %d %d %d %d %d %d; half = %d",
|
||||||
sp_base[CHAN_RED], sp_base[CHAN_GREEN], sp_base[CHAN_BLUE],
|
config->sp_base[CHAN_RED], config->sp_base[CHAN_GREEN], config->sp_base[CHAN_BLUE],
|
||||||
sp_offset[0], sp_offset[1], sp_offset[2], sp_offset[3], sp_offset[4], sp_offset[5]);
|
config->sp_offset[0], config->sp_offset[1], config->sp_offset[2],
|
||||||
|
config->sp_offset[3], config->sp_offset[4], config->sp_offset[5],
|
||||||
|
config->half_px_delay);
|
||||||
}
|
}
|
||||||
|
|
||||||
// =============================================================
|
// =============================================================
|
||||||
|
@ -64,29 +73,29 @@ static void log_sp(int *sp_base, int *sp_offset) {
|
||||||
|
|
||||||
static void cpld_init() {
|
static void cpld_init() {
|
||||||
for (int i = 0; i < NUM_CHANNELS; i++) {
|
for (int i = 0; i < NUM_CHANNELS; i++) {
|
||||||
mode7_sp_base[i] = 0;
|
default_config.sp_base[i] = 0;
|
||||||
|
mode7_config.sp_base[i] = 0;
|
||||||
}
|
}
|
||||||
for (int i = 0; i < NUM_OFFSETS; i++) {
|
for (int i = 0; i < NUM_OFFSETS; i++) {
|
||||||
default_sp_offset[i] = 0;
|
default_config.sp_offset[i] = 0;
|
||||||
mode7_sp_offset[i] = 0;
|
mode7_config.sp_offset[i] = 0;
|
||||||
}
|
}
|
||||||
|
default_config.half_px_delay = 0;
|
||||||
|
mode7_config.half_px_delay = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void cpld_calibrate(int mode7, int elk, int chars_per_line) {
|
static void cpld_calibrate(int mode7, int elk, int chars_per_line) {
|
||||||
int min_i[NUM_CHANNELS];
|
int min_i[NUM_CHANNELS];
|
||||||
int min_metric[NUM_CHANNELS];
|
int min_metric[NUM_CHANNELS];
|
||||||
int *metric;
|
int *metric;
|
||||||
int *sp_base;
|
config_t *config;
|
||||||
int *sp_offset;
|
|
||||||
|
|
||||||
if (mode7) {
|
if (mode7) {
|
||||||
log_info("Calibrating mode 7");
|
log_info("Calibrating mode 7");
|
||||||
sp_base = mode7_sp_base;
|
config = &mode7_config;
|
||||||
sp_offset = mode7_sp_offset;
|
|
||||||
} else {
|
} else {
|
||||||
log_info("Calibrating modes 0..6");
|
log_info("Calibrating modes 0..6");
|
||||||
sp_base = default_sp_base;
|
config = &default_config;
|
||||||
sp_offset = default_sp_offset;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < NUM_CHANNELS; i++) {
|
for (int i = 0; i < NUM_CHANNELS; i++) {
|
||||||
|
@ -95,16 +104,17 @@ static void cpld_calibrate(int mode7, int elk, int chars_per_line) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < NUM_OFFSETS; i++) {
|
for (int i = 0; i < NUM_OFFSETS; i++) {
|
||||||
sp_offset[i] = 0;
|
config->sp_offset[i] = 0;
|
||||||
}
|
}
|
||||||
|
config->half_px_delay = 0;
|
||||||
|
|
||||||
for (int i = 0; i <= (mode7 ? 7 : 5); i++) {
|
for (int i = 0; i <= (mode7 ? 7 : 5); i++) {
|
||||||
for (int j = 0; j < NUM_CHANNELS; j++) {
|
for (int j = 0; j < NUM_CHANNELS; j++) {
|
||||||
sp_base[j] = i;
|
config->sp_base[j] = i;
|
||||||
}
|
}
|
||||||
write_config(sp_base, sp_offset);
|
write_config(config);
|
||||||
metric = diff_N_frames(i, NUM_CAL_FRAMES, mode7, elk, chars_per_line);
|
metric = diff_N_frames(i, NUM_CAL_FRAMES, mode7, elk, chars_per_line);
|
||||||
log_info("offset = %d: metric = %d %d %d\n", i, metric[CHAN_RED], metric[CHAN_GREEN], metric[CHAN_BLUE]);
|
log_info("offset = %d: metric = %d %d %d", i, metric[CHAN_RED], metric[CHAN_GREEN], metric[CHAN_BLUE]);
|
||||||
for (int j = 0; j < NUM_CHANNELS; j++) {
|
for (int j = 0; j < NUM_CHANNELS; j++) {
|
||||||
if (metric[j] < min_metric[j]) {
|
if (metric[j] < min_metric[j]) {
|
||||||
min_metric[j] = metric[j];
|
min_metric[j] = metric[j];
|
||||||
|
@ -112,77 +122,96 @@ static void cpld_calibrate(int mode7, int elk, int chars_per_line) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (mode7) {
|
||||||
|
// If the min metric is at the limit, make use of the half pixel delay
|
||||||
|
int toggle = 0;
|
||||||
|
if (min_i[CHAN_RED] <= 1 || min_i[CHAN_GREEN] <= 1 || min_i[CHAN_BLUE] <= 1) {
|
||||||
|
if (min_i[CHAN_RED] <= 2 && min_i[CHAN_GREEN] <= 2 && min_i[CHAN_BLUE] <= 2) {
|
||||||
|
toggle = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (min_i[CHAN_RED] >= 6 || min_i[CHAN_GREEN] >= 6 || min_i[CHAN_BLUE] >= 6) {
|
||||||
|
if (min_i[CHAN_RED] >= 5 && min_i[CHAN_GREEN] >= 5 && min_i[CHAN_BLUE] >= 5) {
|
||||||
|
toggle = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (toggle) {
|
||||||
|
log_info("Enabling half pixel delay");
|
||||||
|
config->half_px_delay = 1;
|
||||||
|
min_i[CHAN_RED] ^= 4;
|
||||||
|
min_i[CHAN_GREEN] ^= 4;
|
||||||
|
min_i[CHAN_BLUE] ^= 4;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for (int j = 0; j < NUM_CHANNELS; j++) {
|
for (int j = 0; j < NUM_CHANNELS; j++) {
|
||||||
sp_base[j] = min_i[j];
|
config->sp_base[j] = min_i[j];
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the metric is non zero, there is scope for further optimiation in mode 7
|
// If the metric is non zero, there is scope for further optimiation in mode 7
|
||||||
int ref = min_metric[CHAN_RED] + min_metric[CHAN_GREEN] + min_metric[CHAN_BLUE];
|
int ref = min_metric[CHAN_RED] + min_metric[CHAN_GREEN] + min_metric[CHAN_BLUE];
|
||||||
if (mode7 && ref > 0) {
|
if (mode7 && ref > 0) {
|
||||||
log_info("Optimizing calibration: sp_base = %d %d %d",
|
log_info("Optimizing calibration");
|
||||||
sp_base[CHAN_RED], sp_base[CHAN_GREEN], sp_base[CHAN_BLUE]);
|
log_sp(config);
|
||||||
log_debug("ref = %d", ref);
|
log_debug("ref = %d", ref);
|
||||||
for (int i = 0; i < NUM_OFFSETS; i++) {
|
for (int i = 0; i < NUM_OFFSETS; i++) {
|
||||||
int left = INT_MAX;
|
int left = INT_MAX;
|
||||||
int right = INT_MAX;
|
int right = INT_MAX;
|
||||||
if (sp_base[CHAN_RED] > 0 && sp_base[CHAN_GREEN] > 0 && sp_base[CHAN_BLUE] > 0) {
|
if (config->sp_base[CHAN_RED] > 0 && config->sp_base[CHAN_GREEN] > 0 && config->sp_base[CHAN_BLUE] > 0) {
|
||||||
sp_offset[i] = -1;
|
config->sp_offset[i] = -1;
|
||||||
write_config(sp_base, sp_offset);
|
write_config(config);
|
||||||
metric = diff_N_frames(i, NUM_CAL_FRAMES, mode7, elk, chars_per_line);
|
metric = diff_N_frames(i, NUM_CAL_FRAMES, mode7, elk, chars_per_line);
|
||||||
left = metric[CHAN_RED] + metric[CHAN_GREEN] + metric[CHAN_BLUE];
|
left = metric[CHAN_RED] + metric[CHAN_GREEN] + metric[CHAN_BLUE];
|
||||||
}
|
}
|
||||||
if (sp_base[CHAN_RED] < 7 && sp_base[CHAN_GREEN] < 7 && sp_base[CHAN_BLUE] < 7) {
|
if (config->sp_base[CHAN_RED] < 7 && config->sp_base[CHAN_GREEN] < 7 && config->sp_base[CHAN_BLUE] < 7) {
|
||||||
sp_offset[i] = 1;
|
config->sp_offset[i] = 1;
|
||||||
write_config(sp_base, sp_offset);
|
write_config(config);
|
||||||
metric = diff_N_frames(i, NUM_CAL_FRAMES, mode7, elk, chars_per_line);
|
metric = diff_N_frames(i, NUM_CAL_FRAMES, mode7, elk, chars_per_line);
|
||||||
right = metric[CHAN_RED] + metric[CHAN_GREEN] + metric[CHAN_BLUE];
|
right = metric[CHAN_RED] + metric[CHAN_GREEN] + metric[CHAN_BLUE];
|
||||||
}
|
}
|
||||||
if (left < right && left < ref) {
|
if (left < right && left < ref) {
|
||||||
sp_offset[i] = -1;
|
config->sp_offset[i] = -1;
|
||||||
ref = left;
|
ref = left;
|
||||||
log_info("nudged %d left, metric = %d", i, ref);
|
log_info("nudged %d left, metric = %d", i, ref);
|
||||||
} else if (right < left && right < ref) {
|
} else if (right < left && right < ref) {
|
||||||
sp_offset[i] = 1;
|
config->sp_offset[i] = 1;
|
||||||
ref = right;
|
ref = right;
|
||||||
log_info("nudged %d right, metric = %d", i, ref);
|
log_info("nudged %d right, metric = %d", i, ref);
|
||||||
} else {
|
} else {
|
||||||
sp_offset[i] = 0;
|
config->sp_offset[i] = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
log_info("Calibration complete");
|
log_info("Calibration complete");
|
||||||
log_sp(sp_base, sp_offset);
|
log_sp(config);
|
||||||
write_config(sp_base, sp_offset);
|
write_config(config);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void cpld_change_mode(int mode7) {
|
static void cpld_change_mode(int mode7) {
|
||||||
if (mode7) {
|
if (mode7) {
|
||||||
write_config(mode7_sp_base, mode7_sp_offset);
|
write_config(&mode7_config);
|
||||||
} else {
|
} else {
|
||||||
write_config(default_sp_base, default_sp_offset);
|
write_config(&default_config);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void cpld_inc_sampling_base(int mode7) {
|
static void cpld_inc_sampling_base(int mode7) {
|
||||||
int *sp_base = mode7 ? mode7_sp_base : default_sp_base;
|
config_t *config = mode7 ? &mode7_config : &default_config;
|
||||||
int *sp_offset = mode7 ? mode7_sp_offset : default_sp_offset;
|
|
||||||
int limit = mode7 ? 8 : 6;
|
int limit = mode7 ? 8 : 6;
|
||||||
for (int i = 0; i < NUM_CHANNELS; i++) {
|
for (int i = 0; i < NUM_CHANNELS; i++) {
|
||||||
sp_base[i] = (sp_base[i] + 1) % limit;
|
config->sp_base[i] = (config->sp_base[i] + 1) % limit;
|
||||||
}
|
}
|
||||||
log_sp(sp_base, sp_offset);
|
log_sp(config);
|
||||||
write_config(sp_base, sp_offset);
|
write_config(config);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void cpld_inc_sampling_offset(int mode7) {
|
static void cpld_inc_sampling_offset(int mode7) {
|
||||||
int *sp_base = mode7 ? mode7_sp_base : default_sp_base;
|
config_t *config = mode7 ? &mode7_config : &default_config;
|
||||||
int *sp_offset = mode7 ? mode7_sp_offset : default_sp_offset;
|
|
||||||
for (int i = 0; i < NUM_OFFSETS; i++) {
|
for (int i = 0; i < NUM_OFFSETS; i++) {
|
||||||
sp_offset[i] = ((sp_offset[i] + 2) % 3) - 1;
|
config->sp_offset[i] = ((config->sp_offset[i] + 2) % 3) - 1;
|
||||||
}
|
}
|
||||||
log_sp(sp_base, sp_offset);
|
log_sp(config);
|
||||||
write_config(sp_base, sp_offset);
|
write_config(config);
|
||||||
}
|
}
|
||||||
|
|
||||||
cpld_t cpld_alternative = {
|
cpld_t cpld_alternative = {
|
||||||
|
|
|
@ -10,22 +10,30 @@
|
||||||
// The number of frames to compute differences over
|
// The number of frames to compute differences over
|
||||||
#define NUM_CAL_FRAMES 10
|
#define NUM_CAL_FRAMES 10
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
int sp_offset[NUM_OFFSETS];
|
||||||
|
int half_px_delay;
|
||||||
|
} config_t;
|
||||||
|
|
||||||
// Current calibration state for mode 0..6
|
// Current calibration state for mode 0..6
|
||||||
static int default_sp_offset[NUM_OFFSETS];
|
static config_t default_config;
|
||||||
|
|
||||||
// Current calibration state for mode 7
|
// Current calibration state for mode 7
|
||||||
static int mode7_sp_offset[NUM_OFFSETS];
|
static config_t mode7_config;
|
||||||
|
|
||||||
// =============================================================
|
// =============================================================
|
||||||
// Private methods
|
// Private methods
|
||||||
// =============================================================
|
// =============================================================
|
||||||
|
|
||||||
static void write_config(int *sp_offset) {
|
static void write_config(config_t *config) {
|
||||||
int sp = 0;
|
int sp = 0;
|
||||||
for (int i = 0; i < NUM_OFFSETS; i++) {
|
for (int i = 0; i < NUM_OFFSETS; i++) {
|
||||||
sp |= (sp_offset[i] & 7) << (i * 3);
|
sp |= (config->sp_offset[i] & 7) << (i * 3);
|
||||||
}
|
}
|
||||||
for (int i = 0; i < 18; i++) {
|
if (config->half_px_delay) {
|
||||||
|
sp |= (1 << 18);
|
||||||
|
}
|
||||||
|
for (int i = 0; i < 19; i++) {
|
||||||
RPI_SetGpioValue(SP_DATA_PIN, sp & 1);
|
RPI_SetGpioValue(SP_DATA_PIN, sp & 1);
|
||||||
for (int j = 0; j < 1000; j++);
|
for (int j = 0; j < 1000; j++);
|
||||||
RPI_SetGpioValue(SP_CLKEN_PIN, 1);
|
RPI_SetGpioValue(SP_CLKEN_PIN, 1);
|
||||||
|
@ -40,9 +48,11 @@ static void write_config(int *sp_offset) {
|
||||||
RPI_SetGpioValue(SP_DATA_PIN, 0);
|
RPI_SetGpioValue(SP_DATA_PIN, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void log_sp(int *sp_offset) {
|
static void log_sp(config_t *config) {
|
||||||
log_info("sp_offset = %d %d %d %d %d %d",
|
log_info("sp_offset = %d %d %d %d %d %d; half = %d",
|
||||||
sp_offset[0], sp_offset[1], sp_offset[2], sp_offset[3], sp_offset[4], sp_offset[5]);
|
config->sp_offset[0], config->sp_offset[1], config->sp_offset[2],
|
||||||
|
config->sp_offset[3], config->sp_offset[4], config->sp_offset[5],
|
||||||
|
config->half_px_delay);
|
||||||
}
|
}
|
||||||
|
|
||||||
// =============================================================
|
// =============================================================
|
||||||
|
@ -51,9 +61,11 @@ static void log_sp(int *sp_offset) {
|
||||||
|
|
||||||
static void cpld_init() {
|
static void cpld_init() {
|
||||||
for (int i = 0; i < NUM_OFFSETS; i++) {
|
for (int i = 0; i < NUM_OFFSETS; i++) {
|
||||||
default_sp_offset[i] = 0;
|
default_config.sp_offset[i] = 0;
|
||||||
mode7_sp_offset[i] = 0;
|
mode7_config.sp_offset[i] = 0;
|
||||||
}
|
}
|
||||||
|
default_config.half_px_delay = 0;
|
||||||
|
mode7_config.half_px_delay = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void cpld_calibrate(int mode7, int elk, int chars_per_line) {
|
static void cpld_calibrate(int mode7, int elk, int chars_per_line) {
|
||||||
|
@ -61,80 +73,86 @@ static void cpld_calibrate(int mode7, int elk, int chars_per_line) {
|
||||||
int min_metric;
|
int min_metric;
|
||||||
int *rgb_metric;
|
int *rgb_metric;
|
||||||
int metric;
|
int metric;
|
||||||
int *sp_offset;
|
config_t *config;
|
||||||
|
|
||||||
if (mode7) {
|
if (mode7) {
|
||||||
log_info("Calibrating mode 7");
|
log_info("Calibrating mode 7");
|
||||||
sp_offset = mode7_sp_offset;
|
config = &mode7_config;
|
||||||
} else {
|
} else {
|
||||||
log_info("Calibrating modes 0..6");
|
log_info("Calibrating modes 0..6");
|
||||||
sp_offset = default_sp_offset;
|
config = &default_config;
|
||||||
}
|
}
|
||||||
|
|
||||||
min_metric = INT_MAX;
|
min_metric = INT_MAX;
|
||||||
min_i = 0;
|
min_i = 0;
|
||||||
|
config->half_px_delay = 0;
|
||||||
for (int i = 0; i <= (mode7 ? 7 : 5); i++) {
|
for (int i = 0; i <= (mode7 ? 7 : 5); i++) {
|
||||||
for (int j = 0; j < NUM_OFFSETS; j++) {
|
for (int j = 0; j < NUM_OFFSETS; j++) {
|
||||||
sp_offset[j] = i;
|
config->sp_offset[j] = i;
|
||||||
}
|
}
|
||||||
write_config(sp_offset);
|
write_config(config);
|
||||||
rgb_metric = diff_N_frames(i, NUM_CAL_FRAMES, mode7, elk, chars_per_line);
|
rgb_metric = diff_N_frames(i, NUM_CAL_FRAMES, mode7, elk, chars_per_line);
|
||||||
metric = rgb_metric[CHAN_RED] + rgb_metric[CHAN_GREEN] + rgb_metric[CHAN_BLUE];
|
metric = rgb_metric[CHAN_RED] + rgb_metric[CHAN_GREEN] + rgb_metric[CHAN_BLUE];
|
||||||
log_info("offset = %d: metric = %d\n", i, metric);
|
log_info("offset = %d: metric = %d", i, metric);
|
||||||
if (metric < min_metric) {
|
if (metric < min_metric) {
|
||||||
min_metric = metric;
|
min_metric = metric;
|
||||||
min_i = i;
|
min_i = i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (int i = 0; i < NUM_OFFSETS; i++) {
|
// If the min metric is at the limit, make use of the half pixel delay
|
||||||
sp_offset[i] = min_i;
|
if (mode7 && (min_i <= 1 || min_i >= 6)) {
|
||||||
|
log_info("Enabling half pixel delay");
|
||||||
|
config->half_px_delay = 1;
|
||||||
|
min_i ^= 4;
|
||||||
|
}
|
||||||
|
for (int i = 0; i < NUM_OFFSETS; i++) {
|
||||||
|
config->sp_offset[i] = min_i;
|
||||||
}
|
}
|
||||||
write_config(sp_offset);
|
|
||||||
|
|
||||||
// If the metric is non zero, there is scope for further optimiation in mode7
|
// If the metric is non zero, there is scope for further optimiation in mode7
|
||||||
int ref = min_metric;
|
int ref = min_metric;
|
||||||
if (mode7 && ref > 0) {
|
if (mode7 && ref > 0) {
|
||||||
log_info("Optimizing calibration");
|
log_info("Optimizing calibration");
|
||||||
log_sp(sp_offset);
|
log_sp(config);
|
||||||
log_debug("ref = %d", ref);
|
log_debug("ref = %d", ref);
|
||||||
for (int i = 0; i < NUM_CHANNELS; i++) {
|
for (int i = 0; i < NUM_CHANNELS; i++) {
|
||||||
int left = INT_MAX;
|
int left = INT_MAX;
|
||||||
int right = INT_MAX;
|
int right = INT_MAX;
|
||||||
if (sp_offset[i] > 0) {
|
if (config->sp_offset[i] > 0) {
|
||||||
sp_offset[i]--;
|
config->sp_offset[i]--;
|
||||||
write_config(sp_offset);
|
write_config(config);
|
||||||
rgb_metric = diff_N_frames(i, NUM_CAL_FRAMES, mode7, elk, chars_per_line);
|
rgb_metric = diff_N_frames(i, NUM_CAL_FRAMES, mode7, elk, chars_per_line);
|
||||||
left = rgb_metric[CHAN_RED] + rgb_metric[CHAN_GREEN] + rgb_metric[CHAN_BLUE];
|
left = rgb_metric[CHAN_RED] + rgb_metric[CHAN_GREEN] + rgb_metric[CHAN_BLUE];
|
||||||
sp_offset[i]++;
|
config->sp_offset[i]++;
|
||||||
}
|
}
|
||||||
if (sp_offset[i] < 7) {
|
if (config->sp_offset[i] < 7) {
|
||||||
sp_offset[i]++;
|
config->sp_offset[i]++;
|
||||||
write_config(sp_offset);
|
write_config(config);
|
||||||
rgb_metric = diff_N_frames(i, NUM_CAL_FRAMES, mode7, elk, chars_per_line);
|
rgb_metric = diff_N_frames(i, NUM_CAL_FRAMES, mode7, elk, chars_per_line);
|
||||||
right = rgb_metric[CHAN_RED] + rgb_metric[CHAN_GREEN] + rgb_metric[CHAN_BLUE];
|
right = rgb_metric[CHAN_RED] + rgb_metric[CHAN_GREEN] + rgb_metric[CHAN_BLUE];
|
||||||
sp_offset[i]--;
|
config->sp_offset[i]--;
|
||||||
}
|
}
|
||||||
if (left < right && left < ref) {
|
if (left < right && left < ref) {
|
||||||
sp_offset[i]--;
|
config->sp_offset[i]--;
|
||||||
ref = left;
|
ref = left;
|
||||||
log_info("nudged %d left, metric = %d", i, ref);
|
log_info("nudged %d left, metric = %d", i, ref);
|
||||||
} else if (right < left && right < ref) {
|
} else if (right < left && right < ref) {
|
||||||
sp_offset[i]++;
|
config->sp_offset[i]++;
|
||||||
ref = right;
|
ref = right;
|
||||||
log_info("nudged %d right, metric = %d", i, ref);
|
log_info("nudged %d right, metric = %d", i, ref);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
log_info("Calibration complete:");
|
log_info("Calibration complete");
|
||||||
log_sp(sp_offset);
|
log_sp(config);
|
||||||
write_config(sp_offset);
|
write_config(config);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void cpld_change_mode(int mode7) {
|
static void cpld_change_mode(int mode7) {
|
||||||
if (mode7) {
|
if (mode7) {
|
||||||
write_config(mode7_sp_offset);
|
write_config(&mode7_config);
|
||||||
} else {
|
} else {
|
||||||
write_config(default_sp_offset);
|
write_config(&default_config);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -143,13 +161,13 @@ static void cpld_inc_sampling_base(int mode7) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static void cpld_inc_sampling_offset(int mode7) {
|
static void cpld_inc_sampling_offset(int mode7) {
|
||||||
int *sp_offset = mode7 ? mode7_sp_offset : default_sp_offset;
|
config_t *config = mode7 ? &mode7_config : &default_config;
|
||||||
int limit = mode7 ? 8 : 6;
|
int limit = mode7 ? 8 : 6;
|
||||||
for (int i = 0; i < NUM_OFFSETS; i++) {
|
for (int i = 0; i < NUM_OFFSETS; i++) {
|
||||||
sp_offset[i] = (sp_offset[i] + 1) % limit;
|
config->sp_offset[i] = (config->sp_offset[i] + 1) % limit;
|
||||||
}
|
}
|
||||||
log_sp(sp_offset);
|
log_sp(config);
|
||||||
write_config(sp_offset);
|
write_config(config);
|
||||||
}
|
}
|
||||||
|
|
||||||
cpld_t cpld_normal = {
|
cpld_t cpld_normal = {
|
||||||
|
|
Ładowanie…
Reference in New Issue