What's new

Worklog LumaDoub: An Open Source Line-Doubler and Transcoder

Shank

Moderator
Staff member
.
.
Joined
Jan 31, 2016
Messages
1,343
Likes
2,882
Portables
6
The ADV7390 has a "SD progressive" mode, which what us gamers refer to as "240p". As you can assume, when this is selected, it makes the chip output 240p, which is 480i without alternating fields. If you send a 240p signal into this chip, and do not enable this mode, the outgoing 240p signal will have many issues. So this bit must be enabled when the signal is receiving a 240p signal.

Prior to today, I was toggling this mode manually. Today, we were able to use a register in the ADV7280A to detect if the signal is progressive 240p or interlaced 480i, and toggle it automatically.

Additionally, if you send this chip 480i, and then enable this mode, the fields will not alternating, turning it into 240p. This "force 240p" is a neat feature useful for many niche circumstances, so I will keep it as a feature. It will enable automatically for 240p sources, but can be manually enabled for 480i sources.


Line doubling works, but currently looks like garbage. 240p signals bounce up and down; it looks like the chip is attempting to deinterlace the 240p signal. But the chip is supposed to use simple bob deinterlacing so I'm not really sure what's going on. I will have to explore flipping more bits.

I have yet to figure out how to toggle the 480p smoothing filter(s). This wouldn't be too tragic, except it is currently stuck in the "ON" position. I tried toggling the obvious registers the datasheet lays out, but none of them seem to do the trick. This one is proving much tricker than I anticipated. Fortunately, it only appears to affect 480p outputs; 240p and 480i look quite sharp.

The core transcoder portion of this project is pretty close to feature complete. The line doubling to 480p, on the other hand, still has a ways to go.

I do have some bad news: it appears my "RGB passthrough" idea will not work. The output is quite green, and my scope showed that the "Blue" (actually pb) and "Red" (actually pr) outputs have a .35v peak rather than the intended .7v peak that "Green" (actually Y) has. This makes sense though. There may be a way to attenuate or amplify the signal to correct for this, but we may just have to just throw a transcoder circuit on the input stage. PXL_20250214_095654795.jpg
 

1hedu

.
Joined
Sep 21, 2024
Messages
11
Likes
0
I hoped it wasn't too good to be true, regarding RGsB over YPbPr!

Still waiting on components myself so I can't test anything and just excitedly watch you... But OpAmp(s) with a gain of 2x should do it dont ya think?
 

Shank

Moderator
Staff member
.
.
Joined
Jan 31, 2016
Messages
1,343
Likes
2,882
Portables
6
I hoped it wasn't too good to be true, regarding RGsB over YPbPr!

Still waiting on components myself so I can't test anything and just excitedly watch you... But OpAmp(s) with a gain of 2x should do it dont ya think?
Potentially, but I worry it may be a -.35v to +.35v swing rather than a 0v to .7v swing at half amplitude, as pb/pr are differential signals. Would need to do something a little more complicated. Pretty tricky. All else fails, I can stick an analog transcoder circuit on the input stage.
 

1hedu

.
Joined
Sep 21, 2024
Messages
11
Likes
0
Ahhh I see. Right on, I'd always thought I was going to have to add a transcoder, until I learned of your trick idea.
 

Shank

Moderator
Staff member
.
.
Joined
Jan 31, 2016
Messages
1,343
Likes
2,882
Portables
6
After many late nights of troubleshooting to no success, the line doubled output still looked awful. So I reached out to the ADV7280A man himself: Mike Chi of RetroTink. I knew he would have the answers, but he's a busy man and I wanted to wait to reach out to him until I reached the end of what I could do on my own.

He was extremely friendly, and told me about a secret undocumented register on the chip. I flipped 2 bits, and the rounded edges of my N64 composite signal sharpened up.

Before:
PXL_20250227_232926913.jpg

After:
PXL_20250227_232916856.jpg

Ah-Ha! A huge improvement! This is what I had been looking for. But what you can't see in the photo is it was still treating the input signal like 480i instead of 240p; bobbing the image up and down. I asked Mike, and again he had the answer: Flip a bit to enable "Fast lock" mode. Once I did that, the 480p line doubled output was sharp and steady.

Fast Lock (smoothing disabled)
PXL_20250228_031721764.jpg


Fast lock (smoothing enabled)
PXL_20250228_032233020.jpg


Not bad for a stock N64 via composite! The output is 480p RGB into a BVM-D9.

And of course, for those of you like me concerned with latency...
PXL_20250228_040637500.jpg


And with that, the first iteration of lumadoub is near feature complete. I have a few more minor features I would like to do, then my partner and I shall (but mostly her because she's actually competent at writing code) overhaul the code to make it tidy, organized, and documented prior to release.

Excited to release this. Note that this release will be a toolkit to design and create your own lumadoub boards; not a standalone product you can buy or a ready-to-populate board.
 
Last edited:

Shank

Moderator
Staff member
.
.
Joined
Jan 31, 2016
Messages
1,343
Likes
2,882
Portables
6
I had an idea to implement artificial scanlines with no additional hardware by turning the DACs on and off every line. I ran the hsync line back to a gpio of the pico, and ran an interrupt to send an i2c command to toggle the red and blue DACs on and off every hsync pulse. (Note: I left the green dac on, as it carried sync, but muted it on the monitor.)

Here was the result:
PXL_20250301_090537339~2.jpg

I enjoy some thick scanlines, but not quite like this. My guess is the 400khz i2c bus just isn't fast enough to toggle the lines at 31khz, especially with overhead.

Seems this avenue was a dead end, but I'm not giving up on artificial scanlines just yet. I am going to explore additional methods, but unfortunately, they will likely require the use of additional components.
 

loopj

.
2024 2nd Place
Joined
Feb 24, 2020
Messages
99
Likes
439
Location
Bay Area, CA
My guess is the 400khz i2c bus just isn't fast enough to toggle the lines at 31khz
Unfortunately I think this is it. Even with zero overhead you won't be able to clock out the i2c commands fast enough. Assuming this is standard-ish 3 byte i2c payload of [target address][register address][register value], thats 29 bits of data (3 bytes + acks + starts and stops). Clocking this out 31k times per second adds up to ~900k bits per second. Someone check my math though :)

This project is still badass without the "extra credit" of onboard scanlines though :)
 

Shank

Moderator
Staff member
.
.
Joined
Jan 31, 2016
Messages
1,343
Likes
2,882
Portables
6
Artificial scanlines are proving to be much more difficult than I anticipated. Since pure software isn't an option, I have been experimenting with hardware solutions.

The principle of artificial scanlines is simple: every other line, the line is totally black. On paper, this should be simple, as in the analog video domain, 0v is minimum brightness, and .7v is maximum brightness. So if you had .7v on red, green, and blue, you would have white.

Easy, just short it to ground when we want the signal to be blacked out, right? That's what I suspected but, no, it's not that simple.
Here's is a test pattern I put up on the screen, and here is what each line looks like on the oscilloscope.
PXL_20250303_020808777.jpg

PXL_20250303_020202748.jpg

As you can see here, black is NOT at 0v. Because normally, a signal goes negative voltage to signify it is in a blanking period. However, this chip is only powered by a positive voltage source, and not a negative voltage source, so it can not generate a negative voltage. So instead, it offsets the entire signal, shifting the entire signal vertically on the scope.

So this means grounding the signals isn't an option. So what about switching them off entirely? I tried wiring up a ths7374, a popular video buffer/amplifier in the retro gaming world, that has a convenient disable pin. I used the rp2040 to toggle the disable pin (and therefore the output of the chip) every line.

PXL_20250302_035143138.MP.jpg

Hey that looks pretty good right? Unfortunately, there are still problems. The signal without artificial scanlines looked fine, but the brightness went crazy high when I turned on the artificial scanlines. I had to crank my monitors brightness way down to get this signal. The output was way too bright.

I put the test pattern from before through the ths7374 into the scope...
PXL_20250303_020303591~2.jpg

Looks fine. Same wave as before, with a DC bias.

Let's see the test pattern with artificial scanlines:
PXL_20250303_020643390.jpg

So the voltage during the "artificial scan line" (when the tha7374 is off) is much higher than the black level while it's on. I suspect this is the issue that's throwing the whole level completely off. My other suspicion is the timing of me cutting off the signal may be off, and is messing with the blanking interval when I'm cutting off the signal. There's als a pretty nasty transient spike on the transition, likely due to an impedance mismatch.

And finally, I did try AC coupling the signal to remove the DC bias, to no success.
PXL_20250303_021515882.jpg



This is a tricky one. I'm going to have to think on a solution to add this feature without substantially increasing the BOM.
 
Joined
Mar 6, 2025
Messages
1
Likes
0
After many late nights of troubleshooting to no success, the line doubled output still looked awful. So I reached out to the ADV7280A man himself: Mike Chi of RetroTink. I knew he would have the answers, but he's a busy man and I wanted to wait to reach out to him until I reached the end of what I could do on my own.

He was extremely friendly, and told me about a secret undocumented register on the chip. I flipped 2 bits, and the rounded edges of my N64 composite signal sharpened up.

Before:
View attachment 37739
After:
View attachment 37740
Ah-Ha! A huge improvement! This is what I had been looking for. But what you can't see in the photo is it was still treating the input signal like 480i instead of 240p; bobbing the image up and down. I asked Mike, and again he had the answer: Flip a bit to enable "Fast lock" mode. Once I did that, the 480p line doubled output was sharp and steady.

Fast Lock (smoothing disabled)
View attachment 37741

Fast lock (smoothing enabled)
View attachment 37742

Not bad for a stock N64 via composite! The output is 480p RGB into a BVM-D9.

And of course, for those of you like me concerned with latency...
View attachment 37743

And with that, the first iteration of lumadoub is near feature complete. I have a few more minor features I would like to do, then my partner and I shall (but mostly her because she's actually competent at writing code) overhaul the code to make it tidy, organized, and documented prior to release.

Excited to release this. Note that this release will be a toolkit to design and create your own lumadoub boards; not a standalone product you can buy or a ready-to-populate board.
That's really great, I'd like to ask you what the unrecorded registers are that you mentioned, if that's handy.
By the way, I would like to ask you a question, when outputting NTSC video with the I2P function turned off, a part of the screen is missing at the top, I don't know if you have encountered this problem.
Whether you answer or not, I would like to thank you.
 

Shank

Moderator
Staff member
.
.
Joined
Jan 31, 2016
Messages
1,343
Likes
2,882
Portables
6
That's really great, I'd like to ask you what the unrecorded registers are that you mentioned, if that's handy.
It is within the VPP map (0x42) of the ADV7280 and ADV7280A. The register is 0x5A. You want to set bits 3 and 4 to 0 to disable the smoothing filter and enable simple line doubling.

So as an example:
0x42, 0x5A, 0b00011010 - Default values for the register. "Smoothing" line doubling behavior
0x42, 0x5A, 0b00000010 - Simple line doubling with smoothing disabled

Additionally, for 240p (SD progressive) input to be recognized properly as 240p rather than 480i, you want to enable fast lock. It is in a register called "FL control" within the "User Sub Map 2" address. To enter Sub map 2, you need to set 0xE to 0x40. Then, after performing the command within sub map 2, you need to return to sub map 1 by changing 0x0E back to 0x84. So you would need to do the following commands:

0x20, 0x0E, 0x40 - Enter sub map 2
0x20, 0xE0, 0x01 - Enable fast lock mode to fix 240p (within sub map 2)
0x20, 0x0E, 0x84 - Leave sub map 2 (returns to sub map 1)

Shoutouts to Mike Chi of RetroTink for this information.

By the way, I would like to ask you a question, when outputting NTSC video with the I2P function turned off, a part of the screen is missing at the top, I don't know if you have encountered this problem.
I have not encountered this problem before.
 
Last edited:
Top