kopia lustrzana https://github.com/hoglet67/RGBtoHDMI
Merge remote-tracking branch 'upstream/dev' into dev
commit
ad6f418079
|
@ -37,6 +37,7 @@ typedef struct {
|
|||
|
||||
int diff_N_frames(capture_info_t *capinfo, int n, int mode7, int elk);
|
||||
int *diff_N_frames_by_sample(capture_info_t *capinfo, int n, int mode7, int elk);
|
||||
int analyze_default_alignment(capture_info_t *capinfo);
|
||||
int analyze_mode7_alignment(capture_info_t *capinfo);
|
||||
|
||||
// These are global variables defined in rgb_to_hdmi
|
||||
|
|
|
@ -345,9 +345,13 @@ static void cpld_calibrate(capture_info_t *capinfo, int elk) {
|
|||
}
|
||||
|
||||
// Determine mode 7 alignment
|
||||
if (mode7 && supports_delay) {
|
||||
if (supports_delay) {
|
||||
log_info("Aligning characters to word boundaries");
|
||||
config->full_px_delay = analyze_mode7_alignment(capinfo);
|
||||
if (mode7) {
|
||||
config->full_px_delay = analyze_mode7_alignment(capinfo);
|
||||
} else {
|
||||
config->full_px_delay = analyze_default_alignment(capinfo);
|
||||
}
|
||||
write_config(config);
|
||||
}
|
||||
|
||||
|
|
|
@ -461,8 +461,8 @@ static void recalculate_hdmi_clock(int vlockmode) { // use local vsyncmode, not
|
|||
f2 /= error;
|
||||
double divisor = 1000.0;
|
||||
if (vlockmode == HDMI_SLOW_1000PPM || vlockmode == HDMI_FAST_1000PPM) {
|
||||
divisor = 2000.0; //workaround 1000PPM actually now 500PPM
|
||||
}
|
||||
divisor = 2000.0; //workaround 1000PPM actually now 500PPM
|
||||
}
|
||||
f2 /= 1.0 + ((double) (HDMI_EXACT - vlockmode)) / divisor;
|
||||
}
|
||||
|
||||
|
@ -947,7 +947,6 @@ int *diff_N_frames_by_sample(capture_info_t *capinfo, int n, int mode7, int elk)
|
|||
return sum;
|
||||
}
|
||||
|
||||
|
||||
#define MODE7_CHAR_WIDTH 12
|
||||
|
||||
int analyze_mode7_alignment(capture_info_t *capinfo) {
|
||||
|
@ -1007,7 +1006,7 @@ int analyze_mode7_alignment(capture_info_t *capinfo) {
|
|||
// INFO: counter 10 = 906
|
||||
// INFO: counter 11 = 1019
|
||||
|
||||
// There should be a two pixel minim, so look for
|
||||
// There should be a two pixel minima
|
||||
int min_count = INT_MAX;
|
||||
int min_i = -1;
|
||||
for (int i = 0; i < MODE7_CHAR_WIDTH; i++) {
|
||||
|
@ -1023,6 +1022,77 @@ int analyze_mode7_alignment(capture_info_t *capinfo) {
|
|||
return MODE7_CHAR_WIDTH - min_i;
|
||||
}
|
||||
|
||||
#define DEFAULT_CHAR_WIDTH 8
|
||||
|
||||
int analyze_default_alignment(capture_info_t *capinfo) {
|
||||
// mode 0 character is 8 pixels wide
|
||||
int counts[DEFAULT_CHAR_WIDTH];
|
||||
// bit offset pixels 0..7
|
||||
int px_offset_map[] = {4, 0, 12, 8, 20, 16, 28, 24};
|
||||
|
||||
unsigned int flags = BIT_CALIBRATE | BIT_OSD | (2 << OFFSET_NBUFFERS);
|
||||
|
||||
// Capture two fields
|
||||
capinfo->ncapture = 1;
|
||||
|
||||
// Grab a frame
|
||||
int ret = rgb_to_fb(capinfo, flags);
|
||||
|
||||
// Work out the base address of the frame buffer that was used
|
||||
uint32_t *fbp = (uint32_t *)(capinfo->fb + ((ret >> OFFSET_LAST_BUFFER) & 3) * capinfo->height * capinfo->pitch);
|
||||
|
||||
// Initialize the counters
|
||||
for (int i = 0; i < DEFAULT_CHAR_WIDTH; i++) {
|
||||
counts[i] = 0;
|
||||
}
|
||||
|
||||
// Count the pixels
|
||||
for (int line = 0; line < capinfo->height; line++) {
|
||||
int index = 0;
|
||||
for (int byte = 0; byte < capinfo->pitch; byte += 4) {
|
||||
uint32_t word = *fbp++;
|
||||
int *offset = px_offset_map;
|
||||
for (int i = 0; i < 8; i++) {
|
||||
int px = (word >> (*offset++)) & 7;
|
||||
if (px) {
|
||||
counts[index]++;
|
||||
}
|
||||
index = (index + 1) % DEFAULT_CHAR_WIDTH;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Log the raw counters
|
||||
for (int i = 0; i < DEFAULT_CHAR_WIDTH; i++) {
|
||||
log_info("counter %2d = %d", i, counts[i]);
|
||||
}
|
||||
|
||||
// A typical distribution looks like
|
||||
// INFO: counter 0 = 878
|
||||
// INFO: counter 1 = 740
|
||||
// INFO: counter 2 = 212
|
||||
// INFO: counter 3 = 2
|
||||
// INFO: counter 4 = 1036
|
||||
// INFO: counter 5 = 1224
|
||||
// INFO: counter 6 = 648
|
||||
// INFO: counter 7 = 706
|
||||
|
||||
// There should be a one pixel minima
|
||||
int min_count = INT_MAX;
|
||||
int min_i = -1;
|
||||
for (int i = 0; i < DEFAULT_CHAR_WIDTH; i++) {
|
||||
int c = counts[i];
|
||||
if (c < min_count) {
|
||||
min_count = c;
|
||||
min_i = i;
|
||||
}
|
||||
}
|
||||
log_info("minima at index: %d", min_i);
|
||||
|
||||
// That minima should occur in pixels 0 and 1, so compute a delay to make this so
|
||||
return DEFAULT_CHAR_WIDTH - min_i;
|
||||
}
|
||||
|
||||
#if 0
|
||||
int total_N_frames(capture_info_t *capinfo, int n, int mode7, int elk) {
|
||||
|
||||
|
|
1764
vhdl/RGBtoHDMI.jed
1764
vhdl/RGBtoHDMI.jed
Plik diff jest za duży
Load Diff
|
@ -52,7 +52,7 @@ architecture Behavorial of RGBtoHDMI is
|
|||
|
||||
-- Version number: Design_Major_Minor
|
||||
-- Design: 0 = Normal CPLD, 1 = Alternative CPLD
|
||||
constant VERSION_NUM : std_logic_vector(11 downto 0) := x"021";
|
||||
constant VERSION_NUM : std_logic_vector(11 downto 0) := x"022";
|
||||
|
||||
-- Measured values (leading edge of HS to active display)
|
||||
-- Mode 0: 15.478us
|
||||
|
@ -78,9 +78,9 @@ architecture Behavorial of RGBtoHDMI is
|
|||
-- == 96 * 16.25 == 1560 (must be a multiple of 8)
|
||||
|
||||
-- For Modes 0..6
|
||||
constant default_offset_A : unsigned(11 downto 0) := to_unsigned(4096 - 640, 12);
|
||||
constant default_offset_A : unsigned(11 downto 0) := to_unsigned(4096 - 832, 12);
|
||||
-- Offset B adds half a 16MHz pixel
|
||||
constant default_offset_B : unsigned(11 downto 0) := to_unsigned(4096 - 640 + 3, 12);
|
||||
constant default_offset_B : unsigned(11 downto 0) := to_unsigned(4096 - 832 + 3, 12);
|
||||
|
||||
-- For Mode 7
|
||||
constant mode7_offset_A : unsigned(11 downto 0) := to_unsigned(4096 - 768, 12);
|
||||
|
@ -205,23 +205,29 @@ begin
|
|||
if last = '1' and csync2 = '0' then
|
||||
if mode7 = '1' then
|
||||
if half = '1' then
|
||||
counter <= mode7_offset_A(11 downto 7) & delay & mode7_offset_A(2 downto 0);
|
||||
counter <= mode7_offset_A + (delay & "000");
|
||||
else
|
||||
counter <= mode7_offset_B(11 downto 7) & delay & mode7_offset_B(2 downto 0);
|
||||
counter <= mode7_offset_B + (delay & "000");
|
||||
end if;
|
||||
else
|
||||
if half = '1' then
|
||||
counter <= default_offset_A(11 downto 7) & delay & default_offset_A(2 downto 0);
|
||||
counter <= default_offset_A + (delay & "000");
|
||||
else
|
||||
counter <= default_offset_B(11 downto 7) & delay & default_offset_B(2 downto 0);
|
||||
counter <= default_offset_B + (delay & "000");
|
||||
end if;
|
||||
end if;
|
||||
elsif counter(11) = '1' then
|
||||
counter <= counter + 1;
|
||||
elsif mode7 = '1' or counter(2 downto 0) /= 5 then
|
||||
counter(5 downto 0) <= counter(5 downto 0) + 1;
|
||||
if counter(11) = '1' then
|
||||
counter <= counter + 1;
|
||||
else
|
||||
counter(5 downto 0) <= counter(5 downto 0) + 1;
|
||||
end if;
|
||||
else
|
||||
counter(5 downto 0) <= counter(5 downto 0) + 3;
|
||||
if counter(11) = '1' then
|
||||
counter <= counter + 3;
|
||||
else
|
||||
counter(5 downto 0) <= counter(5 downto 0) + 3;
|
||||
end if;
|
||||
end if;
|
||||
|
||||
-- Sample point offset index
|
||||
|
|
|
@ -355,3 +355,48 @@ FB3 18/18* 36/54 81/90 9/ 9*
|
|||
FB4 18/18* 52/54 70/90 5/ 7
|
||||
----- ----- ----- -----
|
||||
72/72 144/216 232/360 28/34
|
||||
|
||||
|
||||
32. Start sampling 8us earlier, delay applied to all modes
|
||||
|
||||
Function Mcells FB Inps Pterms IO
|
||||
Block Used/Tot Used/Tot Used/Tot Used/Tot
|
||||
FB1 18/18* 29/54 43/90 6/ 9
|
||||
FB2 18/18* 27/54 38/90 8/ 9
|
||||
FB3 18/18* 33/54 78/90 9/ 9*
|
||||
FB4 18/18* 49/54 69/90 5/ 7
|
||||
----- ----- ----- -----
|
||||
72/72 138/216 228/360 28/34
|
||||
|
||||
33. Corrected delay in 6 clocks/pixel mode
|
||||
|
||||
Function Mcells FB Inps Pterms IO
|
||||
Block Used/Tot Used/Tot Used/Tot Used/Tot
|
||||
FB1 18/18* 30/54 44/90 6/ 9
|
||||
FB2 18/18* 27/54 38/90 8/ 9
|
||||
FB3 18/18* 36/54 85/90 9/ 9*
|
||||
FB4 18/18* 49/54 74/90 5/ 7
|
||||
----- ----- ----- -----
|
||||
72/72 142/216 241/360 28/34
|
||||
|
||||
34. XOR in delay
|
||||
|
||||
Function Mcells FB Inps Pterms IO
|
||||
Block Used/Tot Used/Tot Used/Tot Used/Tot
|
||||
FB1 18/18* 30/54 44/90 6/ 9
|
||||
FB2 18/18* 27/54 38/90 8/ 9
|
||||
FB3 18/18* 38/54 85/90 9/ 9*
|
||||
FB4 18/18* 49/54 76/90 5/ 7
|
||||
----- ----- ----- -----
|
||||
72/72 144/216 243/360 28/34
|
||||
|
||||
35. Add in delay
|
||||
|
||||
Function Mcells FB Inps Pterms IO
|
||||
Block Used/Tot Used/Tot Used/Tot Used/Tot
|
||||
FB1 18/18* 30/54 44/90 6/ 9
|
||||
FB2 18/18* 27/54 38/90 8/ 9
|
||||
FB3 18/18* 38/54 85/90 9/ 9*
|
||||
FB4 18/18* 49/54 78/90 5/ 7
|
||||
----- ----- ----- -----
|
||||
72/72 144/216 245/360 28/34
|
||||
|
|
Ładowanie…
Reference in New Issue