kopia lustrzana https://github.com/hoglet67/RGBtoHDMI
Extended calibration to detect Electron
Change-Id: I8893c014b18ac199ecc76d3cec4d89d23e13f76cissue_1022
rodzic
c9c7e5957e
commit
0db1745459
|
|
@ -27,11 +27,12 @@
|
|||
#define BIT_MODE7 0x01
|
||||
#define BIT_DRAW_BUFFER 0x02
|
||||
#define BIT_DISP_BUFFER 0x04
|
||||
#define BIT_FIELD_TYPE 0x08
|
||||
#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
|
||||
|
||||
// R0 return value bits
|
||||
#define BIT_CAL 0x02
|
||||
|
|
|
|||
|
|
@ -113,7 +113,7 @@ rgb_to_fb:
|
|||
bleq 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)
|
||||
bic r3, r3, #~(BIT_MODE7 | BIT_PROBE | BIT_CALIBRATE | BIT_CAL_COUNT | BIT_INITIALIZE | BIT_ELK)
|
||||
|
||||
// write to buffer 0, display buffer 1
|
||||
orr r3, r3, #BIT_DISP_BUFFER
|
||||
|
|
@ -190,6 +190,8 @@ frame:
|
|||
// Correct the relative positions of the odd and even frames
|
||||
// In Mode 0..6, reduce the number of active lines by one for the even frame
|
||||
// In Mode 7, increment the frame buffer pointer by one line for the even field
|
||||
tst r3, #BIT_ELK
|
||||
bne skip_line_loop
|
||||
tst r3, #BIT_FIELD_TYPE
|
||||
beq skip_line_loop
|
||||
tst r3, #BIT_MODE7
|
||||
|
|
|
|||
|
|
@ -346,7 +346,7 @@ void init_hardware() {
|
|||
static char last[SCREEN_HEIGHT * 336] __attribute__((aligned(32)));
|
||||
|
||||
|
||||
int diff_N_frames(int sp, int n, int mode7, int chars_per_line) {
|
||||
int diff_N_frames(int sp, int n, int mode7, int elk, int chars_per_line) {
|
||||
|
||||
int sum = 0;
|
||||
int min = INT_MAX;
|
||||
|
|
@ -361,11 +361,11 @@ int diff_N_frames(int sp, int n, int mode7, int chars_per_line) {
|
|||
|
||||
// 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);
|
||||
unsigned int flags = mode7 | BIT_CALIBRATE | (mode7 ? 0 : BIT_CAL_COUNT) | (elk ? BIT_ELK : 0);
|
||||
|
||||
#ifdef INSTRUMENT_CAL
|
||||
t = _get_cycle_counter();
|
||||
#endif
|
||||
#endif
|
||||
// Grab an initial frame
|
||||
rgb_to_fb(fb, chars_per_line, pitch, flags);
|
||||
#ifdef INSTRUMENT_CAL
|
||||
|
|
@ -428,7 +428,7 @@ int diff_N_frames(int sp, int n, int mode7, int chars_per_line) {
|
|||
return sum;
|
||||
}
|
||||
|
||||
int total_N_frames(int sp, int n, int mode7, int chars_per_line) {
|
||||
int total_N_frames(int sp, int n, int mode7, int elk, int chars_per_line) {
|
||||
|
||||
int sum = 0;
|
||||
int min = INT_MAX;
|
||||
|
|
@ -442,7 +442,7 @@ int total_N_frames(int sp, int n, int mode7, int chars_per_line) {
|
|||
|
||||
// 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);
|
||||
unsigned int flags = mode7 | BIT_CALIBRATE | (mode7 ? 0 : BIT_CAL_COUNT) | (elk ? BIT_ELK : 0);
|
||||
|
||||
for (int i = 0; i < n; i++) {
|
||||
int total = 0;
|
||||
|
|
@ -488,19 +488,21 @@ int total_N_frames(int sp, int n, int mode7, int chars_per_line) {
|
|||
return sum;
|
||||
}
|
||||
|
||||
void calibrate_sampling(int mode7, int chars_per_line) {
|
||||
int i;
|
||||
int j;
|
||||
int min_i;
|
||||
int min_metric;
|
||||
int metric;
|
||||
|
||||
// Wait for the cal button to be released
|
||||
// Wait for the cal button to be released
|
||||
void wait_for_cal_release() {
|
||||
int cal_bit = 0;
|
||||
do {
|
||||
cal_bit = ((*(volatile uint32_t *)(PERIPHERAL_BASE + 0x200034)) >> CAL_PIN) & 1;
|
||||
log_debug("cal_bit = %d", cal_bit);
|
||||
} while (cal_bit == 0);
|
||||
}
|
||||
|
||||
void calibrate_sampling(int mode7, int elk, int chars_per_line) {
|
||||
int i;
|
||||
int j;
|
||||
int min_i;
|
||||
int min_metric;
|
||||
int metric;
|
||||
|
||||
if (mode7) {
|
||||
log_info("Calibrating mode 7");
|
||||
|
|
@ -512,7 +514,7 @@ void calibrate_sampling(int mode7, int chars_per_line) {
|
|||
sp_mode7[j] = i;
|
||||
}
|
||||
init_sampling_point_register(sp_mode7, sp_default);
|
||||
metric = diff_N_frames(i, NUM_CAL_FRAMES, mode7, chars_per_line);
|
||||
metric = diff_N_frames(i, NUM_CAL_FRAMES, mode7, elk, chars_per_line);
|
||||
if (metric < min_metric) {
|
||||
min_metric = metric;
|
||||
min_i = i;
|
||||
|
|
@ -534,13 +536,13 @@ void calibrate_sampling(int mode7, int chars_per_line) {
|
|||
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);
|
||||
left = diff_N_frames(i, NUM_CAL_FRAMES, mode7, elk, 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);
|
||||
right = diff_N_frames(i, NUM_CAL_FRAMES, mode7, elk, chars_per_line);
|
||||
sp_mode7[i]--;
|
||||
}
|
||||
if (left < right && left < ref) {
|
||||
|
|
@ -562,7 +564,7 @@ void calibrate_sampling(int mode7, int chars_per_line) {
|
|||
min_i = 0;
|
||||
for (i = 0; i <= 5; i++) {
|
||||
init_sampling_point_register(sp_mode7, i);
|
||||
metric = diff_N_frames(i, NUM_CAL_FRAMES, mode7, chars_per_line);
|
||||
metric = diff_N_frames(i, NUM_CAL_FRAMES, mode7, elk, chars_per_line);
|
||||
if (metric < min_metric) {
|
||||
min_metric = metric;
|
||||
min_i = i;
|
||||
|
|
@ -574,7 +576,54 @@ void calibrate_sampling(int mode7, int chars_per_line) {
|
|||
}
|
||||
}
|
||||
|
||||
int test_for_elk(int mode7, int chars_per_line) {
|
||||
|
||||
// If mode 7, then assume the Beeb
|
||||
if (mode7) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsigned int flags = BIT_CALIBRATE | BIT_CAL_COUNT;
|
||||
unsigned char *fb1 = fb;
|
||||
unsigned char *fb2 = fb + SCREEN_HEIGHT * pitch;
|
||||
|
||||
// Grab one field
|
||||
rgb_to_fb(fb1, chars_per_line, pitch, flags);
|
||||
|
||||
// Grab second field
|
||||
rgb_to_fb(fb2, chars_per_line, pitch, flags);
|
||||
|
||||
unsigned int min_diff = INT_MAX;
|
||||
unsigned int min_offset = 0;
|
||||
|
||||
for (int offset = -2; offset <= 2; offset += 2) {
|
||||
|
||||
uint32_t *p1 = (uint32_t *)(fb1 + 2 * pitch);
|
||||
uint32_t *p2 = (uint32_t *)(fb2 + 2 * pitch + offset * pitch);
|
||||
unsigned int diff = 0;
|
||||
for (int i = 0; i < (SCREEN_HEIGHT - 4) * pitch; i += 4) {
|
||||
uint32_t d = (*p1++) ^ (*p2++);
|
||||
while (d) {
|
||||
if (d & 0x0F) {
|
||||
diff++;
|
||||
}
|
||||
d >>= 4;
|
||||
}
|
||||
}
|
||||
if (diff < min_diff) {
|
||||
min_diff = diff;
|
||||
min_offset = offset;
|
||||
}
|
||||
log_debug("offset = %d, diff = %u", offset, diff);
|
||||
|
||||
}
|
||||
log_debug("min offset = %d", min_offset);
|
||||
return min_offset != 0;
|
||||
}
|
||||
|
||||
|
||||
void rgb_to_hdmi_main() {
|
||||
int elk;
|
||||
int mode7;
|
||||
int last_mode7;
|
||||
int result;
|
||||
|
|
@ -586,6 +635,7 @@ void rgb_to_hdmi_main() {
|
|||
|
||||
// Determine initial mode
|
||||
mode7 = rgb_to_fb(fb, 0, 0, BIT_PROBE);
|
||||
elk = 0;
|
||||
|
||||
while (1) {
|
||||
log_debug("Setting mode7 = %d", mode7);
|
||||
|
|
@ -600,12 +650,15 @@ void rgb_to_hdmi_main() {
|
|||
do {
|
||||
|
||||
log_debug("Entering rgb_to_fb");
|
||||
result = rgb_to_fb(fb, chars_per_line, pitch, mode7 | BIT_INITIALIZE);
|
||||
result = rgb_to_fb(fb, chars_per_line, pitch, mode7 | BIT_INITIALIZE | (elk ? BIT_ELK : 0));
|
||||
log_debug("Leaving rgb_to_fb, result= %d", result);
|
||||
|
||||
if (result & BIT_CAL) {
|
||||
wait_for_cal_release();
|
||||
elk = test_for_elk(mode7, chars_per_line);
|
||||
log_debug("Elk mode = %d", elk);
|
||||
for (int c = 0; c < NUM_CAL_PASSES; c++) {
|
||||
calibrate_sampling(mode7, chars_per_line);
|
||||
calibrate_sampling(mode7, elk, chars_per_line);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Ładowanie…
Reference in New Issue