kopia lustrzana https://github.com/hoglet67/RGBtoHDMI
Add 8 bit and 4 level RGB/YUV support
rodzic
141168b938
commit
f39e17e2ec
|
@ -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
|
||||
|
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
|
||||
|
@ -867,31 +870,18 @@ 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
|
||||
if (supports_four_level) {
|
||||
capinfo->sample_width = (config->rate >= 1);
|
||||
} else {
|
||||
capinfo->sample_width = (config->rate == 1); // 1 = 6bpp, everything else 3bpp
|
||||
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 == RGB_RATE_6); // 1 = 6bpp, everything else 3bpp
|
||||
}
|
||||
|
||||
// Update the line capture function
|
||||
if (capinfo->sample_width) {
|
||||
switch (capinfo->px_sampling) {
|
||||
case PS_NORMAL:
|
||||
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->sample_width) {
|
||||
case 0:
|
||||
switch (capinfo->px_sampling) {
|
||||
case PS_NORMAL:
|
||||
capinfo->capture_line = capture_line_normal_3bpp_table;
|
||||
|
@ -909,6 +899,13 @@ static void cpld_update_capture_info(capture_info_t *capinfo) {
|
|||
capinfo->capture_line = capture_line_half_even_3bpp_table;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 1 :
|
||||
capinfo->capture_line = capture_line_normal_6bpp_table;
|
||||
break;
|
||||
case 2 :
|
||||
capinfo->capture_line = capture_line_normal_8bpp_table;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
|
|
|
@ -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,6 +340,7 @@ static void write_config(config_t *config) {
|
|||
if (supports_clamptype) {
|
||||
int clamptype = config->clamptype;
|
||||
if (clamptype == CLAMPTYPE_AUTO) {
|
||||
if (config->rate == YUV_RATE_6) {
|
||||
clamptype = CLAMPTYPE_SHORT;
|
||||
if (geometry_get_value(CLOCK) >= 6750000) {
|
||||
clamptype = CLAMPTYPE_MEDIUM;
|
||||
|
@ -337,6 +348,9 @@ static void write_config(config_t *config) {
|
|||
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;
|
||||
scan_len += 2;
|
||||
|
@ -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,11 +690,17 @@ static const char *cpld_get_value_string(int num) {
|
|||
return edge_names[config->edge];
|
||||
}
|
||||
if (num == RATE) {
|
||||
if ((cpld_version & 0xff) >= 0x82) {
|
||||
return rate_names[config->rate];
|
||||
}
|
||||
}
|
||||
if (num == 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,23 +731,37 @@ static void cpld_set_value(int num, int value) {
|
|||
case RATE:
|
||||
config->rate = value;
|
||||
if (supports_four_level) {
|
||||
if (config->rate == 0) {
|
||||
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";
|
||||
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;
|
||||
} else {
|
||||
params[DAC_H].hidden = 0;
|
||||
params[CLAMPTYPE].label = "Level Type";
|
||||
params[COUPLING].hidden = 1;
|
||||
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_D].label = "DAC-D: UV 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();
|
||||
}
|
||||
break;
|
||||
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
50
src/macros.S
50
src/macros.S
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
Ładowanie…
Reference in New Issue