Question: Are you sure your video output pattern you are generating actually covers the video output. Could there be a bug in your FPGA code. Have you tried sending your video output to another screen. If it's analog VGA, it should work on other monitors for testing...
Can you provide us a scope-shot from v-sync to v-sync of your video out and h-sync.
Arrrg, on your scope shots, your missing a trace with the analog video. I am unable to tell if when your actual picture starts vertically and ends vertically...
Ok, found it on your website link...
Now, your sync is only 3.3v. A lot of monitors will fail to lock on this unless it is 5v level. Of, they might manage to occasionally sync in and out...
Also, especially for trying to get the native mode on your main screen, sometimes the sync polarity needs to be positive (inverted). Some monitors demand this if you want to access a preset mode. This may mean inverting just the horizontal, or vertical, or both syncs.
As for your sync pattern, it looks fine, but, to improve it a little, latch the VS signal with each initial HS signal transition. This will make the VS activate and de-activate at the same time as next HS signal transition. This is not important for CRTs, but may affect some more modern LCD screen's power saving sleep mode...
Ok, I see what's going on on your website, your scope's video output has an astronomically huge equal v-front/back_porch of 87 lines each! The v-sync pulse of 3 lines is normal.
However, your scope-shot from the source doesn't seem to reflect this figure. Can you do me the favor and look at the video output and count the number of h-syncs between the last line of video and the beginning of the V-sync, then, the number of h-syncs during the v-sync, then, the number of h-syncs between the end of the v-sync and the first line with active video.
BrianHG is right. You need to get a better idea of the original video signal.
For starters, it is NOT OK to arbitrarily guess the pixel clock frequency. Getting an accurate pixel clock is vital for a properly sampled original video and will in turn significantly affect the quality of converted video. Your final solution doesn't tap into the pixel clock from the original circuit, that doesn't mean you don't need to know its exact frequency. In other word, to get an accurate H_TOTAL is as important as H_VISIBLE.
And everything else should be measured in pixel clock counts. Don't guess, measure. How do you know the exact pixel count of front and back porch? You need to find the DE (data enable) signal in the original circuit, sometimes disguised as 'Blanking'. Compare DE with hsync you get accurate count of H front and back porch, and same for V front and back porch. From the scope capture it doesn't seem that you have a symmetrical V front and back porch, how can you assume they have the same line count?
Another big misconception: Line doubler doesn't mean you have half the pixel count per line and double the line count while keeping the pixel clock the same. It means you double the pixel clock and line count while maintaining the same pixel count per line.
I am NOT guessing. I measured the video signal and divided it by the horizontal resolution (from the service manual) to get the pixel clock. Don't know why you think I guessed it. 17.375MHz.
If you're being confused by the article, that was using an arbitrary clock frequency because there is no need to be exact when im not actually sending any video signal.
It turns out that we don’t actually care what the pixel clock is as long as the v-sync and h-sync pulses are the correct length and at the correct intervals. This is because the display locks onto a signal using only the h-sync and v-sync pulses.
I am using a chip (TVP7002) that is designed for pixel clock reconstruction from the sync signals. You don't need to tap into the original clock - computer monitors/tvs manage not to.
I know. To get double the lines I use double the pixel frequency and then double all of the vertical timings.
The input video is fully characterized(you are right about the porches not being totally equal - overlooked that).The problem is transforming it to a signal that the LCD will recognize and display reasonably. (although at this point I still plan to just use a frame buffer and two separate clock domains).
Since your measured active line count (378 lines) is much more than the datasheet stated 240, why don't you suspect that the datasheet stated 500 pixels may not be correct, either?
It is worth noting that the video image may have black borders around the display image. Comparing the video signal to the sync is not a bullet-prof method to determine the front and back porches. As a result the H_total could be off. My advise would be to find the actual, physical pixel clock and DE signals in your machine. That way you can be sure. There may or may not be surprises, but it is better to find out earlier than later.
Ignore that article except for the captures that I referenced - I am going to update it with newer information.... I really messed up a lot of these measurements So here I will go through characterising the signal. Attached are the 8 measurements I took.
1. Measured line video time = 28.8016us. Assuming 500px visible as stated in the datasheet (also look about right by measuring) -> pixel clock = 17.36MHz
2. Measured horizontal front porch = 1.0312us -> h-front-porch = 18
3. Measured horizontal back porch = 6.9776us -> h-back-porch = 121
4. Measured horizontal sync = 3.202us -> h-sync = 56 (although this doesn't divide well)
H_TOTAL = 695 or 40us
5. Measured frame video time = 15.1093 -> 378 lines (this is much more than the datasheet stated 240!)
6. Measured vertical front porch = 441.04us -> v-front-porch = 11
7. Measured vertical back porch = 1.01021ms -> v-back-porch = 25
8. Measured v-sync = 120.002us -> v-sync = 3
V_TOTAL = 417 or 16.68ms
The reason I suspect that the 500 pixels is correct is that when I measure pixels per mm, and measure the whole screen, it comes out as ~500 pixels. I agree its not a very accurate method.
The black borders (whether or not they are there) would be present all the time (the size of the screen never changes and always has a white background), so it's not really any different to having larger porches. I agree this is an assumption that could theoretically not be true, but for now I am willing to risk it.
Ignore that article except for the captures that I referenced - I am going to update it with newer information.... I really messed up a lot of these measurements So here I will go through characterising the signal. Attached are the 8 measurements I took.
1. Measured line video time = 28.8016us. Assuming 500px visible as stated in the datasheet (also look about right by measuring) -> pixel clock = 17.36MHz
2. Measured horizontal front porch = 1.0312us -> h-front-porch = 18
3. Measured horizontal back porch = 6.9776us -> h-back-porch = 121
4. Measured horizontal sync = 3.202us -> h-sync = 56 (although this doesn't divide well)
H_TOTAL = 695 or 40us
5. Measured frame video time = 15.1093 -> 378 lines (this is much more than the datasheet stated 240!)
6. Measured vertical front porch = 441.04us -> v-front-porch = 11
7. Measured vertical back porch = 1.01021ms -> v-back-porch = 25
8. Measured v-sync = 120.002us -> v-sync = 3
V_TOTAL = 417 or 16.68ms
This is beginning to make more sense. However, 417 line total -3 (normal) -11 (normal) -25 (normal) = 378. This is still not standard vertical video mode, however, 423 lines -3 -11 -25 = 384. This is a standard and still 59hz. In fact, both 512x384@60hz and 640x384@60hz is an old, but standard Vesa VGA mode from the 80s... You have obviously timed your syncs on your scope. (These nasty things time better with a real frequency counter...) I am not saying there is an error here, may this weird video mode is correct, but, do you have the ability to count the h-syncs from vs-vs through a counter?
Updating your video output raster specs, to double these new ones, do you fill your LCD more completely?
Also, when doing this, you don't need to yet, but, should clock at double frequency.
512x384 doubled to 1024x768 should fill your display completely.
The reason I suspect that the 500 pixels is correct is that when I measure pixels per mm, and measure the whole screen, it comes out as ~500 pixels. I agree its not a very accurate method.
The black borders (whether or not they are there) would be present all the time (the size of the screen never changes and always has a white background), so it's not really any different to having larger porches. I agree this is an assumption that could theoretically not be true, but for now I am willing to risk it.
I guess you still don't get it why it is so important to nail down the actual pixel clock, H_ACTIVE and H_TOTAL to the last bit of accuracy (perfect integer multiples of pixel clock cycle that is). You have realized that the measured HSYNC width doesn't divide well by the calculated pixel clock cycle. That's a sign. You either measured the HSYNC wrong, or calculated the pixel clock wrong, or both.
In case this might help you reconsider: I've done some video conversion from CRT to LCD on old HP gear, and am in the process of doing more (not including the 166x series, though).
I assumed you would have the TVP chip by now. Yes, for a pixel perfect 1:1 pixel capture, you need the true H-pixel clock values. However, since you will be squeezing or stretching the picture horizontally, we might cheat here by oversampling with the TVP and using it's low pass filter to create an approximate analog display. I was going to guide you on the trick to getting these values out of the chip...
But, this wont work for the vertical. You need the exact active lines, and their positions. Unless you already have the hardware to measure this down to the dot, you cannot rely on the scope's timing here. Even my 25k$ Techtronix scopes fails at these tasks compared to a frequency counter which is why frequency counters still sell.
Yes, @simmconn is correct, assuming you need the perfect dot-dot capture, but, you can cheat a little here and still get a perfectly good looking picture since your source is low res and we can oversample enough and have enough shades of grey to make a smooth final result. This still doesn't mean you can go for perfection, you just may not fill your panel horizontally perfectly. This will be up to you since trying both is easy enough.
Note that you can adjust you horizontal and vertical position by changing the front and back porch on you FPGA video output. This is safe as long as the total number of lines/pixels from front to back remains constant. Do not worry about the alignment in the scopes video output. The TVP has a programmable active video sampling window region which you set to shift it's picture coming into your line buffer and you will generate your video output sync based on an offset of that signal.
In case this might help you reconsider: I've done some video conversion from CRT to LCD on old HP gear, and am in the process of doing more (not including the 166x series, though).
I tried moving pixels from the back porch to the front porch to see if that would let me move the image, but the screen would not lock if I changed it even by one.
I sort of disagree with BrianHG in that I think sharpness (clarity) is more important in the line-art type of image from the test equipment, rather than smoothness. So I'd rather get the original picture as accurately as possible, and let the scaling process mess up the sharpness as little as possible.
I am not talking about doing a fancy full bi-cubic X-Y 16 to 256 tap filtering with an adaptive filter radius making a nice soft broadcast video production style scale. He doesn't have the gate-count for that anyways, well,,, maybe since it is monochrome and so low res, but this is not the point.
We still don't know if his scope's output is truly 500 pixels VS 512 or even 640 (perfect 2:1 for this guy, no fancy filtering...). I have a funny feeling that the quoted specs he used from the scope's user manual may just be the scope grid and center video output while the extra spare space listed in the back&front porch may contains the menu text items as we seen the video goes beyond the original specs found in MattHollands latest scope shots.
Can I see the source code of your sync generator....
module vga_control( CLK, //CLK input
ENABLE, //enable module
RESET, //resets device
VGA_CLK, //pixel clock for vga
VGA_X, //x position of vga
VGA_Y, //y position of vga
VGA_HS, //horizontal sync
VGA_VS, //vertical sync
VGA_VISIBLE, //are we in visible region
VGA_RED, //4 bit red colour
VGA_BLUE, //4 bit blue colour
VGA_GREEN); //4 bit green colour
input wire CLK, ENABLE, RESET;
wire VGA_HS, VGA_VS, VGA_VISIBLE;
output wire VGA_CLK, VGA_HS, VGA_VS, VGA_VISIBLE;
output reg [11:0] VGA_X, VGA_Y;
output wire [3:0] VGA_RED, VGA_BLUE, VGA_GREEN;
//HP1662AS PARAMETERS (17.36MHz clock)
parameter H_TOTAL = 695;
parameter H_SYNC_PULSE = 56;
parameter H_VISIBLE = 500;
parameter H_FRONT_PORCH = 18;
parameter H_BACK_PORCH = 121;
parameter V_TOTAL = 417;
parameter V_VISIBLE = 378;
parameter V_SYNC_PULSE = 3;
parameter V_FRONT_PORCH = 11;
parameter V_BACK_PORCH = 25;
//Line doubled (34.720MHz clock)
/*parameter H_TOTAL = 695;
parameter H_SYNC_PULSE = 56;
parameter H_VISIBLE = 500;
parameter H_FRONT_PORCH = 18;
parameter H_BACK_PORCH = 121;
parameter V_TOTAL = 834;
parameter V_VISIBLE = 756;
parameter V_SYNC_PULSE = 6;
parameter V_FRONT_PORCH = 22;
parameter V_BACK_PORCH = 50;*/
//generate clock (change clock for different display modes)
wire PLL_LOCKED;
//generate vga clock
clk_wiz_17360 vga_clk( .clk_out1(VGA_CLK),
.reset(RESET),
.locked(PLL_LOCKED),
.clk_in1(CLK));
//set VGA_VISIBLE high when we are in the visible portion of the image
assign VGA_VISIBLE = (VGA_X >= H_SYNC_PULSE + H_BACK_PORCH) && (VGA_X < H_VISIBLE + H_BACK_PORCH + H_SYNC_PULSE) && (VGA_Y >= V_SYNC_PULSE + V_BACK_PORCH) && (VGA_Y < V_VISIBLE + V_SYNC_PULSE + V_BACK_PORCH);
assign VGA_HS = ~(VGA_X < H_SYNC_PULSE);
assign VGA_VS = ~(VGA_Y < V_SYNC_PULSE);
assign VGA_RED = (VGA_VISIBLE ? 15 : 0); //red whenever we are in visible region
assign VGA_GREEN = ((VGA_VISIBLE && ((VGA_X == H_SYNC_PULSE + H_BACK_PORCH) || (VGA_X == H_VISIBLE + H_BACK_PORCH + H_SYNC_PULSE - 1))) ? 15 : 0); //green/red vertical edges
assign VGA_BLUE = ((VGA_VISIBLE && ((VGA_Y == V_SYNC_PULSE + V_BACK_PORCH) || (VGA_Y == V_VISIBLE + V_SYNC_PULSE + V_BACK_PORCH - 1))) ? 15 : 0); //blue/red horizontal edges
//at every clock edge
always @(posedge VGA_CLK)
begin
//if enabled
if(ENABLE) begin
//increment VGA_X and VGA_Y
if(VGA_X < H_TOTAL - 1) begin
VGA_X <= VGA_X + 1;
end else begin
VGA_X = 0;
if(VGA_Y < V_TOTAL - 1) begin
VGA_Y <= VGA_Y + 1;
end else begin
VGA_Y <= 0;
end
end
end
if(RESET) begin
VGA_Y <= 0;
VGA_X <= 0;
end
end
endmodule
Yes, but scaling still must be done if you want to project the original scope's 500 X-pixels onto a panel with 1280 X-pixels. Unless you want a black border of 140 pixels on the left and right. Converting 500 to 1280 is not a fixed multiple by 2.
Thanks for the pointers (re: LM1882CM). It turns out the 166xC uses BT475 RAMDAC, which is theoretically supported by my existing design. Not sure about the 166xAs, though. HP often has significantly different display subsystems between the A, B and Cs of the same product family.
Can I see the source code of your sync generator....Code: [Select]module vga_control( CLK, //CLK input
ENABLE, //enable module
RESET, //resets device
VGA_CLK, //pixel clock for vga
VGA_X, //x position of vga
VGA_Y, //y position of vga
VGA_HS, //horizontal sync
VGA_VS, //vertical sync
VGA_VISIBLE, //are we in visible region
VGA_RED, //4 bit red colour
VGA_BLUE, //4 bit blue colour
VGA_GREEN); //4 bit green colour
input wire CLK, ENABLE, RESET;
wire VGA_HS, VGA_VS, VGA_VISIBLE;
output wire VGA_CLK, VGA_HS, VGA_VS, VGA_VISIBLE;
output reg [11:0] VGA_X, VGA_Y;
output wire [3:0] VGA_RED, VGA_BLUE, VGA_GREEN;
//HP1662AS PARAMETERS (17.36MHz clock)
parameter H_TOTAL = 695;
parameter H_SYNC_PULSE = 56;
parameter H_VISIBLE = 500;
parameter H_FRONT_PORCH = 18;
parameter H_BACK_PORCH = 121;
parameter V_TOTAL = 417;
parameter V_VISIBLE = 378;
parameter V_SYNC_PULSE = 3;
parameter V_FRONT_PORCH = 11;
parameter V_BACK_PORCH = 25;
//Line doubled (34.720MHz clock)
/*parameter H_TOTAL = 695;
parameter H_SYNC_PULSE = 56;
parameter H_VISIBLE = 500;
parameter H_FRONT_PORCH = 18;
parameter H_BACK_PORCH = 121;
parameter V_TOTAL = 834;
parameter V_VISIBLE = 756;
parameter V_SYNC_PULSE = 6;
parameter V_FRONT_PORCH = 22;
parameter V_BACK_PORCH = 50;*/
//generate clock (change clock for different display modes)
wire PLL_LOCKED;
//generate vga clock
clk_wiz_17360 vga_clk( .clk_out1(VGA_CLK),
.reset(RESET),
.locked(PLL_LOCKED),
.clk_in1(CLK));
//set VGA_VISIBLE high when we are in the visible portion of the image
assign VGA_VISIBLE = (VGA_X >= H_SYNC_PULSE + H_BACK_PORCH) && (VGA_X < H_VISIBLE + H_BACK_PORCH + H_SYNC_PULSE) && (VGA_Y >= V_SYNC_PULSE + V_BACK_PORCH) && (VGA_Y < V_VISIBLE + V_SYNC_PULSE + V_BACK_PORCH);
assign VGA_HS = ~(VGA_X < H_SYNC_PULSE);
assign VGA_VS = ~(VGA_Y < V_SYNC_PULSE);
assign VGA_RED = (VGA_VISIBLE ? 15 : 0); //red whenever we are in visible region
assign VGA_GREEN = ((VGA_VISIBLE && ((VGA_X == H_SYNC_PULSE + H_BACK_PORCH) || (VGA_X == H_VISIBLE + H_BACK_PORCH + H_SYNC_PULSE - 1))) ? 15 : 0); //green/red vertical edges
assign VGA_BLUE = ((VGA_VISIBLE && ((VGA_Y == V_SYNC_PULSE + V_BACK_PORCH) || (VGA_Y == V_VISIBLE + V_SYNC_PULSE + V_BACK_PORCH - 1))) ? 15 : 0); //blue/red horizontal edges
//at every clock edge
always @(posedge VGA_CLK)
begin
//if enabled
if(ENABLE) begin
//increment VGA_X and VGA_Y
if(VGA_X < H_TOTAL - 1) begin
VGA_X <= VGA_X + 1;
end else begin
VGA_X = 0;
if(VGA_Y < V_TOTAL - 1) begin
VGA_Y <= VGA_Y + 1;
end else begin
VGA_Y <= 0;
end
end
end
if(RESET) begin
VGA_Y <= 0;
VGA_X <= 0;
end
end
endmodule
if (VGA_X = HS_start) begin
VGA_HS <= 1;
end else if (VGA_X = HS_stop) begin
VGA_HS <= 0;
end
The reason for not placing all the adds and sums inside the '(VGA_X = HS_start)' is since these are no longer constants for the compiler to figure out before wiring logic, any math performed gets converted into gates, versus a simple equality comparator. Same goes for the adding a latched reg input for H_TOTAL and H_VISIBLE and of course all the Vertical factors. Having input latched regs gives you that 1 input 14 bit data buss with 3 bit address & WE making 8 internal regs to be latched to create any video format you like.