Add 8 bit and 4 level RGB/YUV support

pull/154/head
IanSB 2020-07-20 05:49:42 +01:00
rodzic 141168b938
commit f39e17e2ec
13 zmienionych plików z 485 dodań i 112 usunięć

Wyświetl plik

@ -65,10 +65,13 @@ file( GLOB core_files
capture_line_mode7_4bpp.S
capture_line_default_4bpp_8bpp.S
capture_line_default_sixbits_4bpp_8bpp.S
capture_line_default_eightbits_8bpp.S
capture_line_default_double_4bpp_8bpp.S
capture_line_default_sixbits_double_4bpp_8bpp.S
capture_line_default_eightbits_double_8bpp.S
capture_line_fast_4bpp_8bpp.S
capture_line_fast_sixbits_4bpp_8bpp.S
capture_line_fast_eightbits_8bpp.S
capture_line_ntsc_sixbits_8bpp.S
capture_line_inband_4bpp_8bpp.S
capture_line_oddeven_4bpp_8bpp.S

Wyświetl plik

@ -0,0 +1,85 @@
#include "rpi-base.h"
#include "defs.h"
#include "macros.S"
.text
.global capture_line_default_eightbits_8bpp
// The capture line function is provided the following:
// r0 = pointer to current line in frame buffer
// r1 = number of complete psync cycles to capture (=param_chars_per_line)
// r2 = frame buffer line pitch in bytes (=param_fb_pitch)
// r3 = flags register
// r4 = GPLEV0 constant
// r5 = line number count down to 0 (initial value =param_nlines)
// r6 = scan line count modulo 10
// r7 = number of psyncs to skip
// r8 = frame buffer height (=param_fb_height)
//
// All registers are available as scratch registers (i.e. nothing needs to be preserved)
.ltorg
// *** 8 bit ***
b preload_capture_line_default_eightbits_8bpp
capture_line_default_eightbits_8bpp:
push {lr}
SETUP_VSYNC_DEBUG_R11_R12
SKIP_PSYNC_NO_OLD_CPLD
push {r14}
SETUP_MASK_R14
loop_8bpp:
WAIT_FOR_PSYNC_EDGE_FAST // expects GPLEV0 in r4, result in r8
CAPTURE_EIGHT_BITS_8BPP_0 r11 // input in r8
WAIT_FOR_PSYNC_EDGE_FAST // expects GPLEV0 in r4, result in r8
CAPTURE_EIGHT_BITS_8BPP_1 // input in r8
WAIT_FOR_PSYNC_EDGE_FAST // expects GPLEV0 in r4, result in r8
CAPTURE_EIGHT_BITS_8BPP_2 // input in r8
WAIT_FOR_PSYNC_EDGE_FAST // expects GPLEV0 in r4, result in r8
CAPTURE_EIGHT_BITS_8BPP_3 r5 // input in r8
WAIT_FOR_PSYNC_EDGE_FAST // expects GPLEV0 in r4, result in r8
CAPTURE_EIGHT_BITS_8BPP_0 r12 // input in r8
WAIT_FOR_PSYNC_EDGE_FAST // expects GPLEV0 in r4, result in r8
CAPTURE_EIGHT_BITS_8BPP_1 // input in r8
WAIT_FOR_PSYNC_EDGE_FAST // expects GPLEV0 in r4, result in r8
CAPTURE_EIGHT_BITS_8BPP_2 // input in r8
WAIT_FOR_PSYNC_EDGE_FAST // expects GPLEV0 in r4, result in r8
CAPTURE_EIGHT_BITS_8BPP_3 r6 // input in r8
WRITE_R5_R6_IF_LAST
cmp r1, #1
popeq {r0, pc}
WAIT_FOR_PSYNC_EDGE_FAST // expects GPLEV0 in r4, result in r8
CAPTURE_EIGHT_BITS_8BPP_0 r11 // input in r8
WAIT_FOR_PSYNC_EDGE_FAST // expects GPLEV0 in r4, result in r8
CAPTURE_EIGHT_BITS_8BPP_1 // input in r8
WAIT_FOR_PSYNC_EDGE_FAST // expects GPLEV0 in r4, result in r8
CAPTURE_EIGHT_BITS_8BPP_2 // input in r8
WAIT_FOR_PSYNC_EDGE_FAST // expects GPLEV0 in r4, result in r8
CAPTURE_EIGHT_BITS_8BPP_3 r7 // input in r8
WAIT_FOR_PSYNC_EDGE_FAST // expects GPLEV0 in r4, result in r8
CAPTURE_EIGHT_BITS_8BPP_0 r12 // input in r8
WAIT_FOR_PSYNC_EDGE_FAST // expects GPLEV0 in r4, result in r8
CAPTURE_EIGHT_BITS_8BPP_1 // input in r8
WAIT_FOR_PSYNC_EDGE_FAST // expects GPLEV0 in r4, result in r8
CAPTURE_EIGHT_BITS_8BPP_2 // input in r8
WAIT_FOR_PSYNC_EDGE_FAST // expects GPLEV0 in r4, result in r8
CAPTURE_EIGHT_BITS_8BPP_3 r10 // input in r8
WRITE_R5_R6_R7_R10
subs r1, r1, #2
bne loop_8bpp
pop {r0, pc}
preload_capture_line_default_eightbits_8bpp:
SETUP_DUMMY_PARAMETERS
b capture_line_default_eightbits_8bpp

Wyświetl plik

@ -0,0 +1,67 @@
#include "rpi-base.h"
#include "defs.h"
#include "macros.S"
.text
.global capture_line_default_eightbits_double_8bpp
// The capture line function is provided the following:
// r0 = pointer to current line in frame buffer
// r1 = number of complete psync cycles to capture (=param_chars_per_line)
// r2 = frame buffer line pitch in bytes (=param_fb_pitch)
// r3 = flags register
// r4 = GPLEV0 constant
// r5 = line number count down to 0 (initial value =param_nlines)
// r6 = scan line count modulo 10
// r7 = number of psyncs to skip
// r8 = frame buffer height (=param_fb_height)
//
// All registers are available as scratch registers (i.e. nothing needs to be preserved)
.ltorg
// *** 8 bit ***
b preload_capture_line_default_eightbits_double_8bpp
capture_line_default_eightbits_double_8bpp:
push {lr}
SETUP_VSYNC_DEBUG_R11_R12_DOUBLE
SKIP_PSYNC_NO_OLD_CPLD
push {r14}
SETUP_MASK_R14
loop_8bpp:
WAIT_FOR_PSYNC_EDGE_FAST // expects GPLEV0 in r4, result in r8
CAPTURE_EIGHT_BITS_DOUBLE_8BPP_LO r11 // input in r8
WAIT_FOR_PSYNC_EDGE_FAST // expects GPLEV0 in r4, result in r8
CAPTURE_EIGHT_BITS_DOUBLE_8BPP_HI r5 // input in r8
WAIT_FOR_PSYNC_EDGE_FAST // expects GPLEV0 in r4, result in r8
CAPTURE_EIGHT_BITS_DOUBLE_8BPP_LO r12 // input in r8
WAIT_FOR_PSYNC_EDGE_FAST // expects GPLEV0 in r4, result in r8
CAPTURE_EIGHT_BITS_DOUBLE_8BPP_HI r6 // input in r8
WRITE_R5_R6_IF_LAST
cmp r1, #1
popeq {r0, pc}
WAIT_FOR_PSYNC_EDGE_FAST // expects GPLEV0 in r4, result in r8
CAPTURE_EIGHT_BITS_DOUBLE_8BPP_LO r11 // input in r8
WAIT_FOR_PSYNC_EDGE_FAST // expects GPLEV0 in r4, result in r8
CAPTURE_EIGHT_BITS_DOUBLE_8BPP_HI r7 // input in r8
WAIT_FOR_PSYNC_EDGE_FAST // expects GPLEV0 in r4, result in r8
CAPTURE_EIGHT_BITS_DOUBLE_8BPP_LO r12 // input in r8
WAIT_FOR_PSYNC_EDGE_FAST // expects GPLEV0 in r4, result in r8
CAPTURE_EIGHT_BITS_DOUBLE_8BPP_HI r10 // input in r8
WRITE_R5_R6_R7_R10
subs r1, r1, #2
bne loop_8bpp
pop {r0, pc}
preload_capture_line_default_eightbits_double_8bpp:
SETUP_DUMMY_PARAMETERS
b capture_line_default_eightbits_double_8bpp

Wyświetl plik

@ -0,0 +1,84 @@
#include "rpi-base.h"
#include "defs.h"
#include "macros.S"
.text
.global capture_line_fast_eightbits_8bpp
// The capture line function is provided the following:
// r0 = pointer to current line in frame buffer
// r1 = number of complete psync cycles to capture (=param_chars_per_line)
// r2 = frame buffer line pitch in bytes (=param_fb_pitch)
// r3 = flags register
// r4 = GPLEV0 constant
// r5 = line number count down to 0 (initial value =param_nlines)
// r6 = scan line count modulo 10
// r7 = number of psyncs to skip
// r8 = frame buffer height (=param_fb_height)
//
// All registers are available as scratch registers (i.e. nothing needs to be preserved)
.ltorg
// *** 8 bit ***
b preload_capture_line_fast_eightbits_8bpp
capture_line_fast_eightbits_8bpp:
push {lr}
SETUP_VSYNC_DEBUG_R11_R12
SKIP_PSYNC_NO_H_SCROLL
push {r14}
SETUP_MASK_R14
loop_8bpp:
WAIT_FOR_PSYNC_EDGE_FAST // expects GPLEV0 in r4, result in r8
CAPTURE_EIGHT_BITS_8BPP_0 r11 // input in r8
WAIT_FOR_PSYNC_EDGE_FAST // expects GPLEV0 in r4, result in r8
CAPTURE_EIGHT_BITS_8BPP_1 // input in r8
WAIT_FOR_PSYNC_EDGE_FAST // expects GPLEV0 in r4, result in r8
CAPTURE_EIGHT_BITS_8BPP_2 // input in r8
WAIT_FOR_PSYNC_EDGE_FAST // expects GPLEV0 in r4, result in r8
CAPTURE_EIGHT_BITS_8BPP_3 r5 // input in r8
WAIT_FOR_PSYNC_EDGE_FAST // expects GPLEV0 in r4, result in r8
CAPTURE_EIGHT_BITS_8BPP_0 r12 // input in r8
WAIT_FOR_PSYNC_EDGE_FAST // expects GPLEV0 in r4, result in r8
CAPTURE_EIGHT_BITS_8BPP_1 // input in r8
WAIT_FOR_PSYNC_EDGE_FAST // expects GPLEV0 in r4, result in r8
CAPTURE_EIGHT_BITS_8BPP_2 // input in r8
WAIT_FOR_PSYNC_EDGE_FAST // expects GPLEV0 in r4, result in r8
CAPTURE_EIGHT_BITS_8BPP_3 r6 // input in r8
cmp r1, #1
stmeqia r0, {r5, r6}
popeq {r0, pc}
WAIT_FOR_PSYNC_EDGE_FAST // expects GPLEV0 in r4, result in r8
CAPTURE_EIGHT_BITS_8BPP_0 r11 // input in r8
WAIT_FOR_PSYNC_EDGE_FAST // expects GPLEV0 in r4, result in r8
CAPTURE_EIGHT_BITS_8BPP_1 // input in r8
WAIT_FOR_PSYNC_EDGE_FAST // expects GPLEV0 in r4, result in r8
CAPTURE_EIGHT_BITS_8BPP_2 // input in r8
WAIT_FOR_PSYNC_EDGE_FAST // expects GPLEV0 in r4, result in r8
CAPTURE_EIGHT_BITS_8BPP_3 r7 // input in r8
WAIT_FOR_PSYNC_EDGE_FAST // expects GPLEV0 in r4, result in r8
CAPTURE_EIGHT_BITS_8BPP_0 r12 // input in r8
WAIT_FOR_PSYNC_EDGE_FAST // expects GPLEV0 in r4, result in r8
CAPTURE_EIGHT_BITS_8BPP_1 // input in r8
WAIT_FOR_PSYNC_EDGE_FAST // expects GPLEV0 in r4, result in r8
CAPTURE_EIGHT_BITS_8BPP_2 // input in r8
WAIT_FOR_PSYNC_EDGE_FAST // expects GPLEV0 in r4, result in r8
CAPTURE_EIGHT_BITS_8BPP_3 r10 // input in r8
stmia r0!, {r5, r6, r7, r10}
subs r1, r1, #2
bne loop_8bpp
pop {r0, pc}
preload_capture_line_fast_eightbits_8bpp:
SETUP_DUMMY_PARAMETERS
b capture_line_fast_eightbits_8bpp

Wyświetl plik

@ -59,4 +59,9 @@ signed int analyze_mode7_alignment(capture_info_t *capinfo);
extern cpld_t *cpld;
extern capture_info_t *capinfo;
enum {
WIDTH_3,
WIDTH_6,
WIDTH_8
};
#endif

Wyświetl plik

@ -189,7 +189,7 @@ static void cpld_update_capture_info(capture_info_t *capinfo) {
// Update the capture info stucture, if one was passed in
if (capinfo) {
// Update the sample width
capinfo->sample_width = 1; // 1 = 6 bits
capinfo->sample_width = WIDTH_6;
// Update the line capture function
capinfo->capture_line = capture_line_normal_6bpp_table;
}

Wyświetl plik

@ -89,7 +89,7 @@ static int supports_separate;
static int supports_analog;
// Indicates the Analog frontent interface supports 4 level RGB
static int supports_four_level;
static int supports_8bit;
// invert state (not part of config)
static int invert = 0;
@ -124,6 +124,13 @@ enum {
DAC_H
};
enum {
RGB_RATE_3,
RGB_RATE_6,
RGB_RATE_6_LEVEL_4,
RGB_RATE_8
};
static const char *rate_names[] = {
"3 Bits Per Pixel",
"6 Bits Per Pixel",
@ -131,10 +138,12 @@ static const char *rate_names[] = {
"Half-Even (3BPP)"
};
static const char *four_level_rate_names[] = {
static const char *eight_bit_rate_names[] = {
"3 Bits Per Pixel",
"6 Bits Per Pixel",
"6 Bits (4 Level)",
"8 Bits Per Pixel"
};
@ -181,7 +190,7 @@ static param_t params[] = {
{ MUX, "Sync on G/V", "input_mux", 0, 1, 1 },
{ RATE, "Sample Mode", "sample_mode", 0, 3, 1 },
{ TERMINATE, "75R Termination", "termination", 0, NUM_RGB_TERM-1, 1 },
{ COUPLING, "G Input Coupling", "coupling", 0, NUM_RGB_COUPLING-1, 1 },
{ COUPLING, "G Coupling", "coupling", 0, NUM_RGB_COUPLING-1, 1 },
{ DAC_A, "DAC-A: G Hi", "dac_a", 0, 255, 1 },
{ DAC_B, "DAC-B: G Lo", "dac_b", 0, 255, 1 },
{ DAC_C, "DAC-C: RB Hi", "dac_c", 0, 255, 1 },
@ -363,12 +372,7 @@ static void write_config(config_t *config) {
scan_len += supports_delay; // 2 or 4 depending on the CPLD version
}
if (supports_rate) {
if (supports_four_level && config->rate >= 2) {
sp |= (3 << scan_len);
} else {
sp |= (config->rate << scan_len);
}
sp |= (config->rate << scan_len);
scan_len += supports_rate; // 1 or 2 depending on the CPLD version
}
if (supports_invert) {
@ -409,7 +413,7 @@ static void write_config(config_t *config) {
int dac_g = config->dac_g;
if (dac_g == 255) {
if (supports_four_level && config->rate >= 2) {
if (supports_8bit && config->rate == RGB_RATE_6_LEVEL_4) {
dac_g = dac_c;
} else {
dac_g = 0;
@ -444,7 +448,7 @@ static void write_config(config_t *config) {
RPI_SetGpioValue(SP_DATA_PIN, 0); //ac-dc
break;
case RGB_INPUT_AC:
RPI_SetGpioValue(SP_DATA_PIN, (config->rate < 2) || !supports_four_level); // only allow clamping in 3 level mode or old cpld or 6 bit board
RPI_SetGpioValue(SP_DATA_PIN, (config->rate != RGB_RATE_6_LEVEL_4) || !supports_8bit); // only allow clamping in 3 level mode or old cpld or 6 bit board
break;
}
@ -581,15 +585,14 @@ static void cpld_init(int version) {
if (major >= 8) {
if (eight_bit_detected()) {
supports_four_level = 1;
params[RATE].max = 2;
supports_8bit = 1;
} else {
supports_four_level = 0;
params[RATE].max = 1; // running on a 6 bit board so hide the 4 level option
supports_8bit = 0;
params[RATE].max = 1; // running on a 6 bit board so hide the 8 bit options
params[DAC_H].hidden = 1;
}
} else {
supports_four_level = 0;
supports_8bit = 0;
params[DAC_H].hidden = 1; // hide spare DAC as will only be useful with new 8 bit CPLDs with new drivers (hiding maintains compatible save format)
}
@ -865,52 +868,46 @@ static int cpld_analyse(int selected_sync_state, int analyse) {
static void cpld_update_capture_info(capture_info_t *capinfo) {
// Update the capture info stucture, if one was passed in
if (capinfo) {
if (capinfo) {
// Update the sample width
if (supports_four_level) {
capinfo->sample_width = (config->rate >= 1);
if (supports_8bit) {
capinfo->sample_width = config->rate;
if (capinfo->sample_width >= RGB_RATE_6_LEVEL_4) {
capinfo->sample_width--; //4 level analog option is actually 6bpp
}
} else {
capinfo->sample_width = (config->rate == 1); // 1 = 6bpp, everything else 3bpp
capinfo->sample_width = (config->rate == RGB_RATE_6); // 1 = 6bpp, everything else 3bpp
}
// Update the line capture function
if (capinfo->sample_width) {
switch (capinfo->px_sampling) {
case PS_NORMAL:
switch (capinfo->sample_width) {
case 0:
switch (capinfo->px_sampling) {
case PS_NORMAL:
capinfo->capture_line = capture_line_normal_3bpp_table;
break;
case PS_NORMAL_O:
capinfo->capture_line = capture_line_odd_3bpp_table;
break;
case PS_NORMAL_E:
capinfo->capture_line = capture_line_even_3bpp_table;
break;
case PS_HALF_O:
capinfo->capture_line = capture_line_half_odd_3bpp_table;
break;
case PS_HALF_E:
capinfo->capture_line = capture_line_half_even_3bpp_table;
break;
}
break;
case 1 :
capinfo->capture_line = capture_line_normal_6bpp_table;
break;
case PS_NORMAL_O:
capinfo->capture_line = capture_line_odd_6bpp_table;
break;
case PS_NORMAL_E:
capinfo->capture_line = capture_line_even_6bpp_table;
break;
case PS_HALF_O:
capinfo->capture_line = capture_line_half_odd_6bpp_table;
break;
case PS_HALF_E:
capinfo->capture_line = capture_line_half_even_6bpp_table;
break;
}
} else {
switch (capinfo->px_sampling) {
case PS_NORMAL:
capinfo->capture_line = capture_line_normal_3bpp_table;
break;
case PS_NORMAL_O:
capinfo->capture_line = capture_line_odd_3bpp_table;
break;
case PS_NORMAL_E:
capinfo->capture_line = capture_line_even_3bpp_table;
break;
case PS_HALF_O:
capinfo->capture_line = capture_line_half_odd_3bpp_table;
break;
case PS_HALF_E:
capinfo->capture_line = capture_line_half_even_3bpp_table;
break;
}
}
}
break;
case 2 :
capinfo->capture_line = capture_line_normal_8bpp_table;
break;
}
}
}
static param_t *cpld_get_params() {
@ -978,8 +975,8 @@ static int cpld_get_value(int num) {
static const char *cpld_get_value_string(int num) {
if (num == RATE) {
if (supports_four_level) {
return four_level_rate_names[config->rate];
if (supports_8bit) {
return eight_bit_rate_names[config->rate];
} else {
return rate_names[config->rate];
}
@ -1043,21 +1040,22 @@ static void cpld_set_value(int num, int value) {
break;
case RATE:
config->rate = value;
if (supports_four_level) {
if (config->rate >= 2) {
// params[DAC_H].hidden = 0;
// params[COUPLING].hidden = 0;
if (supports_8bit) {
if (config->rate == RGB_RATE_6_LEVEL_4) {
params[DAC_H].hidden = 0;
params[COUPLING].hidden = 1;
params[DAC_F].label = "DAC-F: G Mid";
params[DAC_G].label = "DAC-G: R Mid";
params[DAC_H].label = "DAC-H: B Mid";
} else {
// params[DAC_H].hidden = 1;
// params[COUPLING].hidden = 1;
params[DAC_H].hidden = 1;
params[COUPLING].hidden = 0;
params[DAC_F].label = "DAC-F: G V Sync";
params[DAC_G].label = "DAC-G: G Clamp";
params[DAC_H].label = "DAC-H: Unused";
}
}
osd_refresh();
break;
case MUX:
config->mux = value;

Wyświetl plik

@ -43,7 +43,10 @@ typedef struct {
int dac_h;
} config_t;
enum {
YUV_RATE_6,
YUV_RATE_6_LEVEL_4,
};
// Current calibration state for mode 0..6
static config_t default_config;
@ -124,12 +127,19 @@ static const char *clamptype_names[] = {
"Back Porch Auto"
};
static const char *level_names[] = {
"3 Level YUV",
"3 Lvl Y, 4 Lvl UV",
"4 Lvl Y, 3 Lvl UV",
"4 Level YUV",
"Auto 4 Level YUV"
};
static const char *rate_names[] = {
"6 Bits Per Pixel",
"6 Bits (4 Level)",
};
static const char *coupling_names[] = {
"DC",
"AC With Clamp"
@ -330,12 +340,16 @@ static void write_config(config_t *config) {
if (supports_clamptype) {
int clamptype = config->clamptype;
if (clamptype == CLAMPTYPE_AUTO) {
clamptype = CLAMPTYPE_SHORT;
if (geometry_get_value(CLOCK) >= 6750000) {
clamptype = CLAMPTYPE_MEDIUM;
}
if (geometry_get_value(CLOCK) >= 9750000) {
clamptype = CLAMPTYPE_LONG;
if (config->rate == YUV_RATE_6) {
clamptype = CLAMPTYPE_SHORT;
if (geometry_get_value(CLOCK) >= 6750000) {
clamptype = CLAMPTYPE_MEDIUM;
}
if (geometry_get_value(CLOCK) >= 9750000) {
clamptype = CLAMPTYPE_LONG;
}
} else {
clamptype = CLAMPTYPE_LONG; // force 4 level YUV in four level mode
}
}
sp |= clamptype << scan_len;
@ -374,7 +388,7 @@ static void write_config(config_t *config) {
int dac_g = config->dac_g;
if (dac_g == 255) {
if (supports_four_level && config->rate >= 2) {
if (supports_four_level && config->rate >= YUV_RATE_6_LEVEL_4) {
dac_g = dac_c;
} else {
dac_g = 0;
@ -384,6 +398,13 @@ static void write_config(config_t *config) {
int dac_h = config->dac_h;
if (dac_h == 255) dac_h = dac_c;
if (params[DAC_G].hidden == 1) {
dac_g = dac_c;
}
if (params[DAC_H].hidden == 1) {
dac_h = dac_c;
}
sendDAC(0, dac_a);
sendDAC(1, dac_b);
sendDAC(2, dac_c);
@ -409,7 +430,7 @@ static void write_config(config_t *config) {
RPI_SetGpioValue(SP_DATA_PIN, 0); //ac-dc
break;
case YUV_INPUT_AC:
RPI_SetGpioValue(SP_DATA_PIN, (config->rate < 2) || !supports_four_level); // only allow clamping in 3 level mode or old cpld or 6 bit board
RPI_SetGpioValue(SP_DATA_PIN, (config->rate < YUV_RATE_6_LEVEL_4) || !supports_four_level); // only allow clamping in 3 level mode or old cpld or 6 bit board
break;
}
@ -441,7 +462,7 @@ static void log_sp(config_t *config) {
static void cpld_init(int version) {
cpld_version = version;
config->sp_offset = 0;
config->rate = 0;
config->rate = YUV_RATE_6;
config->filter_l = 1;
for (int i = 0; i < RANGE_MAX; i++) {
sum_metrics[i] = -1;
@ -608,7 +629,7 @@ static void cpld_update_capture_info(capture_info_t *capinfo) {
// Update the capture info stucture, if one was passed in
if (capinfo) {
// Update the sample width
capinfo->sample_width = 1; // 1 = 6 bits
capinfo->sample_width = WIDTH_6;
// Update the line capture function
capinfo->capture_line = capture_line_normal_6bpp_table;
}
@ -669,10 +690,16 @@ static const char *cpld_get_value_string(int num) {
return edge_names[config->edge];
}
if (num == RATE) {
return rate_names[config->rate];
if ((cpld_version & 0xff) >= 0x82) {
return rate_names[config->rate];
}
}
if (num == CLAMPTYPE) {
return clamptype_names[config->clamptype];
if ((cpld_version & 0xff) >= 0x82 && config->rate == YUV_RATE_6_LEVEL_4) {
return level_names[config->clamptype];
} else {
return clamptype_names[config->clamptype];
}
}
if (num == CPLD_SETUP_MODE) {
return cpld_setup_names[config->cpld_setup_mode];
@ -704,22 +731,36 @@ static void cpld_set_value(int num, int value) {
case RATE:
config->rate = value;
if (supports_four_level) {
if (config->rate == 0) {
params[DAC_B].label = "DAC-B: Y Lo";
params[DAC_D].label = "DAC-D: UV Lo";
params[DAC_F].label = "DAC-F: Y V Sync";
params[DAC_G].label = "DAC-G: Y Clamp";
params[DAC_H].label = "DAC-H: Unused";
params[DAC_G].hidden = 0;
params[DAC_H].hidden = 1;
if (config->rate == YUV_RATE_6) {
params[CLAMPTYPE].label = "Clamp Type";
params[DAC_H].hidden = 1;
params[COUPLING].hidden = 0;
params[DAC_B].label = "DAC-B: Y Lo";
params[DAC_D].label = "DAC-D: UV Lo";
params[DAC_F].label = "DAC-F: Y V Sync";
params[DAC_G].label = "DAC-G: Y Clamp";
params[DAC_H].label = "DAC-H: Unused";
} else {
params[DAC_H].hidden = 0;
params[CLAMPTYPE].label = "Level Type";
params[COUPLING].hidden = 1;
params[DAC_B].label = "DAC-B: Y Mid";
params[DAC_D].label = "DAC-D: UV Mid";
params[DAC_F].label = "DAC-F: Y Lo";
params[DAC_G].label = "DAC-G: V Lo";
params[DAC_H].label = "DAC-H: U Lo";
int levels = config->clamptype;
if (levels > 3) {
levels = 3;
}
params[DAC_G].hidden = 1;
if (levels & 2) {
params[DAC_B].label = "DAC-B: Y Mid";
params[DAC_F].label = "DAC-F: Y Lo";
}
if (levels & 1) {
params[DAC_G].hidden = 0;
params[DAC_H].hidden = 0;
params[DAC_D].label = "DAC-D: UV Mid";
params[DAC_G].label = "DAC-G: V Lo";
params[DAC_H].label = "DAC-H: U Lo";
}
}
osd_refresh();
}
@ -770,6 +811,7 @@ static void cpld_set_value(int num, int value) {
break;
case CLAMPTYPE:
config->clamptype = value;
cpld_set_value(RATE, config->rate);
break;
case TERMINATE:
config->terminate = value;

Wyświetl plik

@ -373,11 +373,19 @@ void set_setup_mode(int mode) {
}
void geometry_get_fb_params(capture_info_t *capinfo) {
capinfo->bpp = geometry->fb_bpp;
capinfo->sync_type = geometry->sync_type;
capinfo->vsync_type = geometry->vsync_type;
capinfo->video_type = geometry->video_type;
capinfo->sizex2 = geometry->fb_sizex2;
capinfo->bpp = geometry->fb_bpp;
if (capinfo->video_type == VIDEO_TELETEXT) {
capinfo->bpp = 4; //force 4bpp for teletext
} else {
if (capinfo->sample_width >= WIDTH_8) {
capinfo->bpp = 8; //force 8bpp in 8 bit modes
}
}
#ifdef INHIBIT_DOUBLE_HEIGHT
if (capinfo->video_type != VIDEO_TELETEXT) {
capinfo->sizex2 &= 2;

Wyświetl plik

@ -486,6 +486,56 @@ wait_wr\@:
orr \reg2, r10, r10, lsl #8
.endm
.macro SETUP_MASK_R14
tst r3, #BIT_OSD
movne r14, #(0x7f << PIXEL_BASE)
moveq r14, #(0xff << PIXEL_BASE)
.endm
.macro CAPTURE_EIGHT_BITS_8BPP_0 reg
// Pixel 0 in GPIO 9.. 2 -> 7.. 0
and r9, r8, r14
eor r10, \reg, r9, lsr #PIXEL_BASE
.endm
.macro CAPTURE_EIGHT_BITS_8BPP_1
// Pixel 0 in GPIO 9.. 2 -> 15.. 8
and r9, r8, r14
eor r10, r10, r9, lsl #(8 - PIXEL_BASE)
.endm
.macro CAPTURE_EIGHT_BITS_8BPP_2
// Pixel 0 in GPIO 9.. 2 -> 23.. 16
and r9, r8, r14
eor r10, r10, r9, lsl #(16 - PIXEL_BASE)
.endm
.macro CAPTURE_EIGHT_BITS_8BPP_3 reg
// Pixel 0 in GPIO 9.. 2 -> 31.. 24
and r9, r8, r14
eor \reg, r10, r9, lsl #(24 - PIXEL_BASE)
.endm
.macro CAPTURE_EIGHT_BITS_DOUBLE_8BPP_LO reg
// Pixel 0 in GPIO 9.. 2 -> 7.. 0
and r9, r8, r14
eor r10, \reg, r9, lsr #PIXEL_BASE
.endm
.macro CAPTURE_EIGHT_BITS_DOUBLE_8BPP_HI reg
// Pixel 0 in GPIO 9.. 2 -> 7.. 0
and r9, r8, r14
eor r10, r10, r9, lsl #(16 - PIXEL_BASE)
// Pixel double
orr \reg, r10, r10, lsl #8
.endm
.macro CAPTURE_LOW_BITS_8BPP_WIDE reg
// Pixel 0 in GPIO 7.. 2 -> 7.. 0
// Pixel 1 in GPIO 13.. 8 -> 15.. 8

Wyświetl plik

@ -65,11 +65,7 @@
.global capture_line_half_even_3bpp_table
.global capture_line_normal_6bpp_table
.global capture_line_odd_6bpp_table
.global capture_line_even_6bpp_table
.global capture_line_double_6bpp_table
.global capture_line_half_odd_6bpp_table
.global capture_line_half_even_6bpp_table
.global capture_line_normal_8bpp_table
rgb_to_fb:
@ -206,8 +202,7 @@ skip_swap:
ldr r8, param_h_offset
ldr r7, param_sample_width
ands r7, r7, #1
movne r8, r8, lsl #1
mov r8, r8, lsl r7
add r8, r8, #1 // first psync test is wait for a zero after csync
str r8, param_h_offset
@ -486,6 +481,7 @@ no_sync_loss:
cmp r9, #4 //flywheel vsync
bne skip_fix_vsync_jitter
SHOW_VSYNC
WAIT_FOR_CSYNC_0_LONG
WAIT_FOR_CSYNC_1_LONG
@ -494,10 +490,18 @@ no_sync_loss:
movmi r5, #0
READ_CYCLE_COUNTER r9
tst r3, #BIT_OSD | BIT_CALIBRATE | BIT_PROBE
bne skip_fix_vsync_jitter_saving_timestamp
ldr r10, sync_detected
ldr r8, last_sync_detected
ands r8, r8, r10
beq skip_fix_vsync_jitter_saving_timestamp
ldr r10, first_hsync_timestamp
subs r6, r9, r10
rsbmi r6, r6, #0
ldr r0, required_vsync_period
add r10, r0, r0, lsr #1
fixvloop:
@ -530,7 +534,7 @@ addsloop:
// sub r8, r8, r10, lsr #1 // remove rounding leaving remainder
continue:
// add r9, r9, r8 // adjust timestamp by remainder to compensate for rounding
str r9, first_hsync_timestamp
cmp r0, r7
streq r6, required_vsync_period // update vertical period timing if no jitter detected.
@ -543,6 +547,9 @@ continue:
movmi r5, #0
str r0, jitter_offset
skip_fix_vsync_jitter_saving_timestamp:
str r9, first_hsync_timestamp
skip_fix_vsync_jitter:
// Correct the relative positions of the odd and even frames
@ -1802,6 +1809,36 @@ capture_line_normal_6bpp_table:
.word capture_line_fast_sixbits_8bpp
capture_line_normal_8bpp_table:
.word capture_line_default_4bpp //never called
.word capture_line_default_eightbits_8bpp
.word capture_line_default_4bpp //never called
.word capture_line_default_eightbits_8bpp
.word capture_line_default_4bpp //never called
.word capture_line_default_eightbits_8bpp
.word capture_line_default_4bpp //never called
.word capture_line_default_eightbits_8bpp
.word capture_line_default_4bpp //never called
.word capture_line_default_eightbits_8bpp
.word capture_line_default_4bpp //never called
.word capture_line_default_eightbits_double_8bpp
.word capture_line_default_4bpp //never called
.word capture_line_default_eightbits_double_8bpp
.word capture_line_default_4bpp //never called
.word capture_line_default_eightbits_double_8bpp
.word capture_line_default_4bpp //never called
.word capture_line_default_eightbits_double_8bpp
.word capture_line_default_4bpp //never called
.word capture_line_default_eightbits_double_8bpp
.word capture_line_default_4bpp //never called
.word capture_line_fast_eightbits_8bpp
// tables below are deprecated and will be removed in future
capture_line_odd_3bpp_table:
@ -1860,7 +1897,6 @@ capture_line_even_6bpp_table: //no six bit versions
.word capture_line_even_8bpp
capture_line_half_odd_3bpp_table:
capture_line_half_odd_6bpp_table: //no six bit versions
.word capture_line_half_odd_4bpp
.word capture_line_half_odd_8bpp
.word capture_line_half_odd_4bpp
@ -1887,7 +1923,6 @@ capture_line_half_odd_6bpp_table: //no six bit versions
.word capture_line_half_odd_8bpp
capture_line_half_even_3bpp_table:
capture_line_half_even_6bpp_table: //no six bit versions
.word capture_line_half_even_4bpp
.word capture_line_half_even_8bpp
.word capture_line_half_even_4bpp

Wyświetl plik

@ -37,11 +37,7 @@ extern int capture_line_half_odd_3bpp_table();
extern int capture_line_half_even_3bpp_table();
extern int capture_line_normal_6bpp_table();
extern int capture_line_odd_6bpp_table();
extern int capture_line_even_6bpp_table();
extern int capture_line_double_6bpp_table();
extern int capture_line_half_odd_6bpp_table();
extern int capture_line_half_even_6bpp_table();
extern int capture_line_normal_8bpp_table();
extern int vsync_line;
extern int total_lines;

Wyświetl plik

@ -2371,6 +2371,7 @@ void setup_profile(int profile_changed) {
log_info("Detected screen size = %dx%d",get_hdisplay(), get_vdisplay());
set_scaling(scaling, 1);
cpld->update_capture_info(capinfo);
geometry_get_fb_params(capinfo);
if (autoswitch == AUTOSWITCH_MODE7) {
@ -2380,7 +2381,6 @@ void setup_profile(int profile_changed) {
}
log_info("Detected polarity state = %X, %s (%s)", capinfo->detected_sync_type, sync_names[capinfo->detected_sync_type & SYNC_BIT_MASK], mixed_names[(capinfo->detected_sync_type & SYNC_BIT_MIXED_SYNC) ? 1 : 0]);
cpld->update_capture_info(capinfo);
calculate_fb_adjustment();
rgb_to_fb(capinfo, extra_flags() | BIT_PROBE); // dummy mode7 probe to setup sync type from capinfo
@ -2698,7 +2698,7 @@ void rgb_to_hdmi_main() {
capinfo->palette_control = PALETTECONTROL_OFF;
}
fb_size_changed = (capinfo->width != last_capinfo.width) || (capinfo->height != last_capinfo.height) || (capinfo->bpp != last_capinfo.bpp);
fb_size_changed = (capinfo->width != last_capinfo.width) || (capinfo->height != last_capinfo.height) || (capinfo->bpp != last_capinfo.bpp) || (capinfo->sample_width != last_capinfo.sample_width);
active_size_changed = (capinfo->chars_per_line != last_capinfo.chars_per_line) || (capinfo->nlines != last_capinfo.nlines);
geometry_get_clk_params(&clkinfo);
@ -2713,7 +2713,7 @@ void rgb_to_hdmi_main() {
}
mode_changed = mode7 != last_mode7 || capinfo->vsync_type != last_capinfo.vsync_type || capinfo->sync_type != last_capinfo.sync_type || capinfo->border != last_capinfo.border
|| capinfo->video_type != last_capinfo.video_type|| capinfo->px_sampling != last_capinfo.px_sampling
|| capinfo->video_type != last_capinfo.video_type || capinfo->px_sampling != last_capinfo.px_sampling
|| profile != last_profile || last_subprofile != subprofile || (result & RET_SYNC_TIMING_CHANGED);
if (active_size_changed) {