kopia lustrzana https://github.com/hoglet67/RGBtoHDMI
Test nudging sample points +- 1 in mode 7
Change-Id: I8ee9882e20f868cbfaec30dcc93bca2a2249e39dissue_1022
rodzic
ff99238861
commit
c9c7e5957e
|
|
@ -23,12 +23,7 @@
|
|||
#include "rpi-interrupts.h"
|
||||
#endif
|
||||
|
||||
static int sp_mode7_A = 3;
|
||||
static int sp_mode7_B = 3;
|
||||
static int sp_mode7_C = 3;
|
||||
static int sp_mode7_D = 3;
|
||||
static int sp_mode7_E = 3;
|
||||
static int sp_mode7_F = 3;
|
||||
static int sp_mode7[6] = {1, 1, 1, 1, 1, 1};
|
||||
static int sp_default = 4;
|
||||
|
||||
typedef void (*func_ptr)();
|
||||
|
|
@ -287,10 +282,13 @@ int calibrate_clock() {
|
|||
return a;
|
||||
}
|
||||
|
||||
void init_sampling_point_register(int mode7_a, int mode7_b, int mode7_c, int mode7_d, int mode7_e, int mode7_f, int def) {
|
||||
int sp = (mode7_a & 7) | ((mode7_b & 7) << 3) | ((mode7_c & 7) << 6) | ((mode7_d & 7) << 9) | ((mode7_e & 7) << 12) | ((mode7_f & 7) << 15) | ((def & 7) << 18);
|
||||
void init_sampling_point_register(int *sp_mode7, int def) {
|
||||
int i;
|
||||
int j;
|
||||
int sp = ((def & 7) << 18);
|
||||
for (i = 0; i <= 5; i++) {
|
||||
sp |= (sp_mode7[i] & 7) << (i * 3);
|
||||
}
|
||||
for (i = 0; i <= 20; i++) {
|
||||
RPI_SetGpioValue(SP_DATA_PIN, sp & 1);
|
||||
for (j = 0; j < 1000; j++);
|
||||
|
|
@ -333,7 +331,7 @@ void init_hardware() {
|
|||
RPI_SetGpioPinFunction(GPCLK_PIN, FS_ALT5);
|
||||
|
||||
// Initialize the sampling points
|
||||
init_sampling_point_register(sp_mode7_A, sp_mode7_B, sp_mode7_C, sp_mode7_D, sp_mode7_E, sp_mode7_F, sp_default);
|
||||
init_sampling_point_register(sp_mode7, sp_default);
|
||||
|
||||
// Initialise the info system with cached values (as we break the GPU property interface)
|
||||
init_info();
|
||||
|
|
@ -347,13 +345,12 @@ void init_hardware() {
|
|||
// TODO: Don't hardcode pitch!
|
||||
static char last[SCREEN_HEIGHT * 336] __attribute__((aligned(32)));
|
||||
|
||||
// TODO: Clean this up
|
||||
|
||||
int diff_N_frames(int sp, int n, int mode7, int chars_per_line) {
|
||||
|
||||
int diff_sum = 0;
|
||||
int diff_min = INT_MAX;
|
||||
int diff_max = INT_MIN;
|
||||
// int diff_sum2 = 0;
|
||||
int sum = 0;
|
||||
int min = INT_MAX;
|
||||
int max = INT_MIN;
|
||||
|
||||
#ifdef INSTRUMENT_CAL
|
||||
unsigned int t;
|
||||
|
|
@ -410,41 +407,93 @@ int diff_N_frames(int sp, int n, int mode7, int chars_per_line) {
|
|||
#endif
|
||||
|
||||
// Accumulate the result
|
||||
diff_sum += diff;
|
||||
if (diff < diff_min) {
|
||||
diff_min = diff;
|
||||
sum += diff;
|
||||
if (diff < min) {
|
||||
min = diff;
|
||||
}
|
||||
if (diff > diff_max) {
|
||||
diff_max = diff;
|
||||
if (diff > max) {
|
||||
max = diff;
|
||||
}
|
||||
// diff_sum2 += diff * diff;
|
||||
}
|
||||
|
||||
// TODO: Seeing regular random crashes with double version, suspect sqrt
|
||||
// double diff_mean = (double) diff_sum / (double) n;
|
||||
// double diff_stddev = sqrt((double) diff_sum2 / (double) n - diff_mean * diff_mean);
|
||||
int mean = sum / n;
|
||||
|
||||
int diff_mean = diff_sum / n;
|
||||
// int diff_stddev = diff_sum2 / n - diff_mean * diff_mean;
|
||||
|
||||
// Displaying as integers, as printing of doubles seems broken
|
||||
// log_debug("diff: mean = %d, variance = %d", (int) diff_mean, (int) diff_stddev);
|
||||
|
||||
log_debug("sample point %d: sum = %d mean = %d, min = %d, max = %d", sp, diff_sum, diff_mean, diff_min, diff_max);
|
||||
log_debug("sample point %d: diff: sum = %d mean = %d, min = %d, max = %d", sp, sum, mean, min, max);
|
||||
#ifdef INSTRUMENT_CAL
|
||||
log_debug("t_capture total = %d, mean = %d ", t_capture, t_capture / (n + 1));
|
||||
log_debug("t_compare total = %d, mean = %d ", t_compare, t_compare / n);
|
||||
log_debug("t_memcpy total = %d, mean = %d ", t_memcpy, t_memcpy / n);
|
||||
log_debug("total = %d", t_capture + t_compare + t_memcpy);
|
||||
#endif
|
||||
return diff_sum;
|
||||
return sum;
|
||||
}
|
||||
|
||||
int total_N_frames(int sp, int n, int mode7, int chars_per_line) {
|
||||
|
||||
int sum = 0;
|
||||
int min = INT_MAX;
|
||||
int max = INT_MIN;
|
||||
|
||||
#ifdef INSTRUMENT_CAL
|
||||
unsigned int t;
|
||||
unsigned int t_capture = 0;
|
||||
unsigned int t_compare = 0;
|
||||
#endif
|
||||
|
||||
// In mode 0..6, set BIT_CAL_COUNT to 1 (capture 1 field)
|
||||
// In mode 7, set BIT_CAL_COUNT to 0 (capture two fields, doesn't matter whether odd-even or even-odd)
|
||||
unsigned int flags = mode7 | BIT_CALIBRATE | (mode7 ? 0 : BIT_CAL_COUNT);
|
||||
|
||||
for (int i = 0; i < n; i++) {
|
||||
int total = 0;
|
||||
|
||||
// Grab the next frame
|
||||
rgb_to_fb(fb, chars_per_line, pitch, flags);
|
||||
#ifdef INSTRUMENT_CAL
|
||||
t_capture += _get_cycle_counter() - t;
|
||||
t = _get_cycle_counter();
|
||||
#endif
|
||||
// Compare the frames
|
||||
uint32_t *fbp = (uint32_t *)fb;
|
||||
for (int j = 0; j < SCREEN_HEIGHT * pitch; j += 4) {
|
||||
uint32_t f = *fbp++;
|
||||
while (f) {
|
||||
if (f & 0x0F) {
|
||||
total++;
|
||||
}
|
||||
f >>= 4;
|
||||
}
|
||||
}
|
||||
#ifdef INSTRUMENT_CAL
|
||||
t_compare += _get_cycle_counter() - t;
|
||||
#endif
|
||||
|
||||
// Accumulate the result
|
||||
sum += total;
|
||||
if (total < min) {
|
||||
min = total;
|
||||
}
|
||||
if (total > max) {
|
||||
max = total;
|
||||
}
|
||||
}
|
||||
|
||||
int mean = sum / n;
|
||||
log_debug("sample point %d: total: sum = %d mean = %d, min = %d, max = %d", sp, sum, mean, min, max);
|
||||
#ifdef INSTRUMENT_CAL
|
||||
log_debug("t_capture total = %d, mean = %d ", t_capture, t_capture / (n + 1));
|
||||
log_debug("t_compare total = %d, mean = %d ", t_compare, t_compare / n);
|
||||
log_debug("total = %d", t_capture + t_compare + t_memcpy);
|
||||
#endif
|
||||
return sum;
|
||||
}
|
||||
|
||||
void calibrate_sampling(int mode7, int chars_per_line) {
|
||||
int i;
|
||||
int j;
|
||||
int min_i;
|
||||
int min_diff;
|
||||
int diff;
|
||||
int min_metric;
|
||||
int metric;
|
||||
|
||||
// Wait for the cal button to be released
|
||||
int cal_bit = 0;
|
||||
|
|
@ -456,43 +505,73 @@ void calibrate_sampling(int mode7, int chars_per_line) {
|
|||
if (mode7) {
|
||||
log_info("Calibrating mode 7");
|
||||
|
||||
min_diff = INT_MAX;
|
||||
min_metric = INT_MAX;
|
||||
min_i = 0;
|
||||
for (i = 0; i <= 7; i++) {
|
||||
init_sampling_point_register(i, i, i, i, i, i, sp_default);
|
||||
diff = diff_N_frames(i, NUM_CAL_FRAMES, mode7, chars_per_line);
|
||||
if (diff < min_diff) {
|
||||
min_diff = diff;
|
||||
for (j = 0; j <= 5; j++) {
|
||||
sp_mode7[j] = i;
|
||||
}
|
||||
init_sampling_point_register(sp_mode7, sp_default);
|
||||
metric = diff_N_frames(i, NUM_CAL_FRAMES, mode7, chars_per_line);
|
||||
if (metric < min_metric) {
|
||||
min_metric = metric;
|
||||
min_i = i;
|
||||
}
|
||||
}
|
||||
sp_mode7_A = min_i;
|
||||
sp_mode7_B = min_i;
|
||||
sp_mode7_C = min_i;
|
||||
sp_mode7_D = min_i;
|
||||
sp_mode7_E = min_i;
|
||||
sp_mode7_F = min_i;
|
||||
log_debug("Setting sp_mode7 = %d", min_i);
|
||||
for (i = 0; i <= 5; i++) {
|
||||
sp_mode7[i] = min_i;
|
||||
}
|
||||
init_sampling_point_register(sp_mode7, sp_default);
|
||||
|
||||
|
||||
log_info("Calibration in progress: mode 7: %d %d %d %d %d %d",
|
||||
sp_mode7[0], sp_mode7[1], sp_mode7[2], sp_mode7[3], sp_mode7[4], sp_mode7[5]);
|
||||
int ref = min_metric;
|
||||
log_debug("ref = %d", ref);
|
||||
for (i = 0; i <= 5; i++) {
|
||||
int left = INT_MAX;
|
||||
int right = INT_MAX;
|
||||
if (sp_mode7[i] > 0) {
|
||||
sp_mode7[i]--;
|
||||
init_sampling_point_register(sp_mode7, sp_default);
|
||||
left = diff_N_frames(i, NUM_CAL_FRAMES, mode7, chars_per_line);
|
||||
sp_mode7[i]++;
|
||||
}
|
||||
if (sp_mode7[i] < 7) {
|
||||
sp_mode7[i]++;
|
||||
init_sampling_point_register(sp_mode7, sp_default);
|
||||
right = diff_N_frames(i, NUM_CAL_FRAMES, mode7, chars_per_line);
|
||||
sp_mode7[i]--;
|
||||
}
|
||||
if (left < right && left < ref) {
|
||||
sp_mode7[i]--;
|
||||
ref = left;
|
||||
log_debug("nudged %d left, metric = %d", i, ref);
|
||||
} else if (right < left && right < ref) {
|
||||
sp_mode7[i]++;
|
||||
ref = right;
|
||||
log_debug("nudged %d right, metric = %d", i, ref);
|
||||
}
|
||||
}
|
||||
init_sampling_point_register(sp_mode7, sp_default);
|
||||
log_info("Calibration complete: mode 7: %d %d %d %d %d %d",
|
||||
sp_mode7[0], sp_mode7[1], sp_mode7[2], sp_mode7[3], sp_mode7[4], sp_mode7[5]);
|
||||
} else {
|
||||
log_info("Calibrating modes 0..6");
|
||||
min_diff = INT_MAX;
|
||||
min_metric = INT_MAX;
|
||||
min_i = 0;
|
||||
for (i = 0; i <= 5; i++) {
|
||||
init_sampling_point_register(sp_mode7_A, sp_mode7_B, sp_mode7_C, sp_mode7_D, sp_mode7_E, sp_mode7_F, i);
|
||||
diff = diff_N_frames(i, NUM_CAL_FRAMES, mode7, chars_per_line);
|
||||
if (diff < min_diff) {
|
||||
min_diff = diff;
|
||||
init_sampling_point_register(sp_mode7, i);
|
||||
metric = diff_N_frames(i, NUM_CAL_FRAMES, mode7, chars_per_line);
|
||||
if (metric < min_metric) {
|
||||
min_metric = metric;
|
||||
min_i = i;
|
||||
}
|
||||
}
|
||||
sp_default = min_i;
|
||||
log_debug("Setting sp_default = %d", min_i);
|
||||
log_info("Setting sp_default = %d", min_i);
|
||||
init_sampling_point_register(sp_mode7, sp_default);
|
||||
}
|
||||
//
|
||||
log_info("Calibration complete: mode 7: %d %d %d %d %d %d; default: %d",
|
||||
sp_mode7_A, sp_mode7_B, sp_mode7_C, sp_mode7_D, sp_mode7_E, sp_mode7_F, sp_default);
|
||||
// Do a final update
|
||||
init_sampling_point_register(sp_mode7_A, sp_mode7_B, sp_mode7_C, sp_mode7_D, sp_mode7_E, sp_mode7_F, sp_default);
|
||||
}
|
||||
|
||||
void rgb_to_hdmi_main() {
|
||||
|
|
|
|||
Ładowanie…
Reference in New Issue