2) double checked my multimeter (it was set on AC before!), retested VIO pins
3) all exhibit the same behaviour. Start out around 2.4V or so and each slowly rose up to 3.3V range. Takes ~5s or so when I probed. If I reprobe they are all at 3.3V right away. So it was like some cap was charging initially.
Well that probably saved things. It definitely was dead for a while after the short and I had tried unplugging and plugging back. So if it is a polyfuse it needs some time to recover.
Drama seems to be averted. Now I can get back to what I was trying to do, but I won't be touching pins for a while.
Now, it would be good to figure out what the funny P32..P39 problem is all about. I think it must be some kind of uninitialized data tied to port configuration code. Check RES-type variables.
Yeah. There might possibly be something in fastspin that looks at these pins and then leaves the startup state in a different condition but I would still need to find an uninitialised variable or hub memory access in my code that would cause this. Haven't got there yet... I don't access pin states. Maybe INB has overlapped one of my registers somewhere in block transfers.
There is a USB power switch, two in fact, on the Eval Board but I'm pretty certain it'll auto re-power on its own. The poly-fuse in the revA design was removed for the revB design.
What possibly happened was that whole branched USB bus was shut down at the Mac. It only gets powered up again after resocketing the cable to the computer. It's something I've learned about USB only since the prop2. It might have been Von who mentioned that that can occur.
Possible, although the LED was still lit on the board when I first removed the cable and then replugged to the Mac so it still had some power being delivered. The serial download attempted seemed to return right away so perhaps the Mac USB transfer was still shut off for a while afterwards and needed its own recovery time...? I also used a different device in the meantime so that may have reset things too.
There shouldn't be any slow rise of the VIO volts either. I suspect the meter wasn't showing real.
Only initially when I probed each pin did I see this, and the board may still have been in reset and not started up at this point. Once each of the pins were "charged" they then read 3.3V right away on later probing. The multimeter I used is a bit of a POS so it might have some of its own capacitance. I'll admit it seems strange.
...
I think I just fried my glob top board VIO supply with my latest test. :frown: I wanted to pull each pin high on each pin from 32-39 so I got two female jumper breakout board cables and put a 680 ohm resistor in the middle then jumpered VIO to each pin. At one point from the jumper cable spring the partially exposed resistor leg metal scraped over the nearby earthing pin post and looks like it shorted VIO very briefly. Now after power off and repower I measure the board supply VIO voltage and it is only 0.28V or so. Looks dead and nothing downloads to the board! Damn. It was not the 5V as that is off. It was the ground post...
Hmm, sounds ominous.
The LDOs should current limit, as well as have thermal shutdown, but a nastier mechanism here could be parasitic inductance and very sharp current edges causing ringing, triggering the P2 latch-up type failure.
A quick spice run, shows fast edges and even parasitic levels of L, can give significant ringing. I chose 10pF / 4nH+ 4.7uf of ideal C, and 300mA current impulse with a varying rise time
Hmm Weird!
On both of my boards the fault appears on pin group 32 & 40.
If I am plugged into pin group 40 I can get it working if I start the code with the monitor disconnected.
After loading the code I can plug the montor in and the text is Ok.
If I start with the monitor plugged in the text glitch appears.
I get the same results with two different monitors.
Switching to pin group 32 always has the text glitch regardless of monitor connection state.
IIt appears to be some sort of hardware glitch and not a software bug.
It's the software going astray. It's only the text regions that are affected - all of them. The screen mode timing is perfect and the bitmap regions are fine. Cursor and sprite rendering is fine within the text regions. It's like the the mode select is being flipped to bitmap and displaying the hubram text data as bitmap.
EDIT: The fact that it affects all text regions together says it's not due to region config data.
testb modedata, #9 wc 'determine mode type 1=gfx, 0=text
With the simple text only demo, when I replace that line with either MODC $0 WC or MODC $F WC then I get two differing results, neither the same as the issue. But the forced text mode does produce clean correctly rendered text. Just, oddly, not at the correct coordinates. And, leaving that hack in place, shifting back to pin group 48 the picture looks normal still.
EDIT: Smile, went back to pin group 32 and now the forced text hack doesn't work. It's like it's not there.
....
Switching to pin group 32 always has the text glitch regardless of monitor connection state.
It appears to be some sort of hardware glitch and not a software bug.
..
EDIT: Smile, went back to pin group 32 and now the forced text hack doesn't work. It's like it's not there.
Maybe it's a timing issue, where some pins are just that teensy bit faster/slower than others ?
An external load may droop VIO just enough to make a difference in those pins that come/go.
What is harder to explain, is the change/mode flip seems visually massive in timing terms ?
How much variation is possible in clocks here - can this be slowed down to less pixels, slower clock, but same video rates as a test ?
Found a bug in my patching code that sets up column widths used by text and graphics modes. It looks like your first hunch was correct @evanh. This will be it for sure. I'll test it out later when I get back to the board. Amazing what time away from a problem can do to help clear the mind.
sets p8, b 'patch columns/4 into code
sets p10, b
sub c, #1 'compute columns -1
setd p5, c 'patch columns - 1 into code subr c, $1ff setd p11, c
This $1ff on the red line is the inb register not the value of 511 because it is missing the #. Patching p11 controls the start address of text data in LUT RAM written back to hub. It all makes full sense now, but it was in an area of setup code I wasn't expecting or looking at. The fact the the behaviour was affected by real HW I/O states when devices were plugged into different port B pin groups confused the heck out of me and led me down another path altogether. Even my dumping of all state variables last night showed nothing wrong. I was planning to dump the entire COGRAM in the good and bad cases today and that would have ultimately caught this too, but I'm rather glad I won't have to do that. I believe it should also resolve the next issue I saw with text being off by one pixel on the left of screen at times. It's just another manifestation of the same bug.
mov ptrb, save 'restore ptrb
p5 setq2 #COLS-1 'write all column pixels to HUB RAM
p11 wrlong $200-COLS, ptrb 'from LUT storage
Yep. It sure was. It's unfortunate I couldn't catch it earlier. Those missing # bugs do happen from time to time and usually it results in failures right away so they can quickly be pinpointed during development. Unfortunately in this case to even trigger it, you needed real HW fitted at specific pins and I didn't have that environment to cause the problem until I moved the HDMI board up to pin 32. Also the very code that introduced that bug has also recently changed from something else which worked fine, after I found I had to reverse the order of data written into LUTRAM to fix another problem with pixel doubled text over 120 columns overwriting portions of LUTRAM.
These "#" problems can be pernicious. I get them now and then, myself.
The best way I can think to sufficiently differentiate immediate numbers from registers is to put registers in brackets:
loop add [outa],1
jmp loop
It would be a burden to always use brackets for registers, but it would be obvious and unmistakable. It would also solve the issue of needing a "#" in front of an immediate address.
Yes that would be somewhat of a burden. Certainly a warning in assemblers if any constants they see without using # (like $1ff) fall in the register range from $1f0-$1ff could be useful, even though that will only pick up a subset of the missing # bugs.
These "#" problems can be pernicious. I get them now and then, myself.
The best way I can think to sufficiently differentiate immediate numbers from registers is to put registers in brackets:
loop add [outa],1
jmp loop
It would be a burden to always use brackets for registers, but it would be obvious and unmistakable. It would also solve the issue of needing a "#" in front of an immediate address.
I suspect that would quickly lead to the opposite problem of forgetting to put the [] around a label when you intended it as a register rather than an immediate.
A simple heuristic would be to warn about any immediate integer in the source field that doesn't have a # in front of it, e.g. "add foo, 1" gets a warning, but "add foo, #1" or "add foo, bar" don't. Complex expressions also don't get a warning, so "add foo, 0-0" does not get a warning. I suspect that would catch many of these issues without producing too many false positives, and suppressing the warning would be easy (just add "+0" to the operand to make it an expression instead of a simple integer).
jmp destinations are a different matter (there we do want to check labels for #). I already have a check for those in fastspin, but it's mildly complicated: I actually look at what follows the label. If it's code I assume that a missing # is worth warning about, if it's data then I assume that an indirect jump is intended. The "+0" trick also works to suppress warnings.
These "#" problems can be pernicious. I get them now and then, myself.
The best way I can think to sufficiently differentiate immediate numbers from registers is to put registers in brackets:
loop add [outa],1
jmp loop
It would be a burden to always use brackets for registers, but it would be obvious and unmistakable. It would also solve the issue of needing a "#" in front of an immediate address.
I suspect that would quickly lead to the opposite problem of forgetting to put the [] around a label when you intended it as a register rather than an immediate.
A simple heuristic would be to warn about any immediate integer in the source field that doesn't have a # in front of it, e.g. "add foo, 1" gets a warning, but "add foo, #1" or "add foo, bar" don't. Complex expressions also don't get a warning, so "add foo, 0-0" does not get a warning. I suspect that would catch many of these issues without producing too many false positives, and suppressing the warning would be easy (just add "+0" to the operand to make it an expression instead of a simple integer).
Yes, you could also expand that some more, by checking if the name is a CONST or REG variable declared.
That catches most usages, and just leaves the case of needing to load the address of a REG var to handle - less common, maybe #ADR()can make that clear ?
then you expand to
"add foo, 1" gets a warning,
"add foo, #RegDecl" gets a warning, suggesting to use #ADR(RegVar)
"add foo, ConstDecl" gets a warning, suggesting to use #
"add foo, #1" is ok
"add foo, RegVar" is ok
"add foo, #ADR(RegVar)" is ok
"add foo, #ADR(RegVar)+3" is ok
I have been having a hell of a time in the last couple of days trying hard to get a PAL colour burst and the phase alternation working in my driver and outputting PAL on the P2. Here are my calculations if anyone wants to check my working to see what I might be doing wrong.
I am using these equations below to try to figure out the burst colour for the signal.
R=RED, G=GREEN, B=BLUE, Y=LUMA, C=CHROMA.
V=0.877(R-Y)
U=0.492(B-Y)
Y=0.3R + 0.59G + 0.114B
C=Usin(wt) +/- Vcos(wt), where C = colour phase & amplitude vector, alternating per PAL video line using the +/- operation.
If I solve the U, V equations for determining the PAL burst colour phase which I understand is meant to be 135 or 225 degrees and amplitude of 21.4 IRE units or (21.4/143 * 1V)= 150mV, this represents (U,V) co-ordinates of (-21.4/sqrt(2), +/- 21.4/sqrt(2)) which is (-0.15, +/- 0.15) in the U,V plane. The amplitude of C in theory should be sqrt(U*U + V*V) for these multiples of 45 degree angles and (abs(U) == abs(V)).
Solving for R,G with B=0. I get these colours..
U = -0.15 = 0.492 (B-Y)
so
Y= 0.15/0.492 = 0.305
When V= 0.15 = 0.877(R-Y)
R = 0.15/0.877 + Y
= 0.476
This corresponds to two colour burst colours of
RGB =(0.476, 0.275, 0) and (0.134, 0.449, 0), when RGB go from 0-1
or
RGB = (0.476*255, 0.275*255, 0) and (0.134*255, 0.449*255, 0)
= (121, 70, 0) and (34, 114, 0) when using an RGB DAC input range from 0-255.
The problem is that neither of these colour burst colours give me a good picture. It may have something to do with any remaining scaling in the colour space converter I am not considering or the fact that it may not be modulating both in-phase and quadrature terms on its colour output, just the quadrature component. That fact may possibly result in a phase angle offset of 45 degrees and another attenuation by a factor of sqrt(2). I am certainly seeing an large attenuation in the amplitude.
Unfortunately the P2 colour space converter adds its own complications with scaling. Firstly the video output range needs to be compressed to allow for sync tips to take up ~0.3V of the 1Vp-p video signal from the DAC (when terminated by 75 ohms). It turns out that 76/255 = ~0.3V which is probably a good value to use. This limits the video output to be from 0-179 (255-76) instead of 0-255 once the Y gets offset by 76 for the sync level. The two CY[7:0] and CI[7:0] values define the offsets for blanking and/or black levels (which I understand are the same for PAL, but not for some NTSC). I am using them with the same values for PAL.
To generate the Y signal we need to set co-efficients to scale the input colours to the right levels.
Y = 0.3R + 0.59G + 0.11B, where RGB go from 0-1
This should make it
Y = (0.3*128*R + 0.59*128*G + 0.114*128*B) / 128, where Y ranges from 0-1
or
Y = (38*DAC3 + 76*DAC2 + 15*DAC1) / 128, where Y now goes from 0-255, when R,G,B input DAC3,DAC2,DAC1 signals range from 0-255.
However this needs to be scaled data further to limit Y to be from 0-179, and also reduced a bit more to later allow for the colour signal to be added to Y and still not exceed 255 when fully saturated.
I believe Chip uses this "SAT" constant to indicate the amount of colour saturation gain/attenuation.
we should then get an output range reduction of (70/128 or 0.55) This means the Y voltage range is now 0.55V leaving 0.45 for sync and colour signal excursion combined. I don't know if it is optimal but SAT=70 will do for now until I can figure out the best way to compute it.
There is also another attenuation factor of 1000/1646 required for the CI/CQ components due to the gain of 1.646 in the CORDIC during the rotation step. That is the "r" parameter below. I have also included the factors of 0.492 and 0.877 in the "palu", "palv" constants also used in the CU_PAL/CV_PAL parameters below (here U is in-phase I, V is quadrature Q). This is needed to again scale the U,V outputs by the correct amount for generating the colour according to the first equations listed above.
r = SAT * 1000/1646
palu = 492
palv = 877
With U = 0.492 (B-Y)
this results in CI coefficients of
Here due to negation of Y, the red and green coefficients are negated while the blue coefficient becomes (1-0.114) or 0.886 of the the full value. It was 0.114 before so we need to re-scale and it becomes 0.886/0.114 of what it was, this is then 0.886/0.114 * 15 or 117.
With V = 0.877 (R-Y)
this results in CQ coefficients of these for the odd/even scan lines.
Here due to negation of Y, the green and blue coefficients are negated, while the red coefficient becomes (1-0.3) of 0.7 of the full value (1-0.59) or 0.41 of the full value. It was 0.59 before so we need to re-scale and it becomes 0.41/0.59 of what it was, this is then 0.41/0.59 * 38 = 26. It was 0.3 before so we need to re-scale and it becomes 0.7/0.3 of what it was, this is then 0.7/0.3 * 38 = 89.
Update: fixed data above, but now no PAL image appears on screen with new value. Scope looks okay. Not sure why.
I have two values for PAL_CV, odd and even, which are applied to the alternating PAL lines in the SETCQ argument.
The problem I have is this is still off. I've tried flipping the ODD/EVEN terms around in case I have started with the wrong one at the start of the frame, and this does affect the colour, but it is still bad. I've also tried both colour burst colours with this too. I still need to make a colour bar test pattern to see what is going on there and if the desired phase is off by another 45 degrees due to how the colour space converter works (it might be).
In the code I am flipping the CQ parameter every second line. Here "cqflip" is passed into the driver as the XOR of the odd/even PAL_CV values computed above. I'm pretty sure that both the phase of the colour burst on the scanline and its real coloured pixels should be getting flipped by 90 degrees by this (mirrored about the U axis), and the CQ change should take effect before the burst based on the streamer command sequence.
hsync xzero m_sn, hsync1 'generate the sync pulse
setcq cq
wrlong status, statusaddr 'update the sync status per line
dobreeze xcont m_br, hsync0 'do breezeway before colour burst
doburst xcont m_cb, colourburst 'do the PAL/NTSC colour burst
flipref xor cq, cqflip 'toggle PAL colour ref per scanline
bp _ret_ xcont m_bv, hsync0 'generate the back porch
Here is the rubbish PAL colour I am seeing (S-video output). Every alternate line is showing a different colour. Red and green text backgrounds seem to alternate per scanline when it should be either solid red or solid green. Looks worse on the LCD monitor than in the picture. I've tried resetting the cq parameter to the same state at the start of the field and also letting it continue from the previous state in case I had an odd/even line issue with interlacing but it didn't help.
Here is the colour burst. You can see it is low in amplitude relative to the -0.3V sync tip. It should be bigger.
I turned on persistence and you can see the 4 phases of the colour burst on a given scanline. This is expected with PAL as it has four different phases spread over an 8 field cycle with an interlaced scan image. Because it is not locked to the pixel rate it will drift over time and the "eyes" will fill up and the scope screen will then be solid yellow but this takes perhaps 30s or so as the colour signal frequency is rather close to the 1135/4 multiple of the horizontal line rate. For PAL the colour burst frequency is meant to be that value plus 25Hz. I'm not sure if the P2 will be able to get the 25Hz part added reliably, but perhaps close is good enough. NTSC is an exact ratio of 227.5 and this can be locked.
I think if I had some type of vector scope I might be able to figure out what the phase error is. Otherwise this is sort of trial and error for me. I wish I could derive it properly from the equations and my understanding, obviously my understanding is incorrect somewhere.
I would tweak those colorburst values by hand until they looked rightly sized, then I would make and look at a colorbar pattern for visual quality and level-correctness on the scope, tweaking overall scaling constants as necessary. There's maybe more going on than just that.
Is the PAL driver I made for the P1 in the OBEX? It worked all correctly.
Yeah I might have to resort to manual tweaking, Chip. I'd prefer to properly understand it all though but I fully realize now I don't have all the facts of how things work or know every little requirement of PAL to be able to do it right.
This line in your brief colorspace converter documentation
IQ[7:0] = Q of (I,Q) after being rotated by PHS and multiplied by 1.646
seems to imply that only the sine of the rotated co-ordinate (ie. the new Q) is used in the DAC output that gets added to the Y signal. When Q is maximum this is when V is maximum and the SINE of the phase angle is 1.
I guess the normal calculation of the colour component for PAL is Usin(wt) +/- Vcos(wt). So something could be different here, maybe it is introducing a problem the way I am doing it. I think the addition of a sine wave and a cosine wave at the same frequency is just another sine whose amplitude is sqrt(2) times larger (if they had the same magnitudes) and at 45 degrees to the original sine wave. So if you are only adding the new Q component to the Y in the P2 then this may generate an additional phase offset and attenuation to be handled.
Is the PAL driver I made for the P1 in the OBEX? It worked all correctly.
Ok, I think someone said PAL never worked properly on the P1. So that was my understanding. I know I tried it once here ages ago and it didn't work right but it might have been someone else's driver.
The P1 PAL driver is correctly written and works, but it just doesn't produce a very good quality image due to P1 hardware problems (it really depends on TV, too, it works as good as anything else on my little portable PAL TV, I've attached an image I've taken yesterday, because why not?).
Also, RE: chroma amplitude: Full saturation at full Y isn't a valid part of the colorspace and thus shouldn't ever come up when coverting from RGB input. Think of it as two cones glued together, white at the top, black at the bottom and full saturation colors around the circle where the cones meet.
When I used my equations above to recompute U, V with my colour burst colour I don't get 0.15V for each I, Q component I get 0.086V and 0.081V for RGB=(121,70,0) respectively. I think is due to the scaling with SAT parameter reducing the overall output scale of U/V by a factor of 70/128. Once I account for that factor it is quite close to the intended 0.15V for each component. I think the rest of the attenuation must be because in the P2 only Q (which for PAL is treated as V) is being used to generate the colour signal, not both the Usin(wt)+Vcos(wt) components, which would reduce things further by another factor of 1.414. So thats a total reduction from the desired amplitude of ~150mV down to 58mV which appears to be the ballpark of my colour burst amplitude captured in the scope trace above.
I was able to get the PAL signal fed into my plasma TV with colour bars even though my LCD refused to display it. The colours are off. Interestingly, and I'm not sure if this is a feature of the TV or not, but when I do this the incorrect colour bars are only shown for the top 10% or so of the screen, then proper colour bars are shown. The TV might be somehow adapting or this might be a diagnostic feature from Pioneer for tuning things.
It looks like red is coming out green, and green is coming out red. Yellow is close but not perfect. Blue is right but that was set to 0 in the colour bursts so didn't play a part in its calculation. Magenta and cyan look pretty ugly too. Of course black and white work as they don't need to send the colour signal.
Comments
1) replugged in the glob top board into my MAC
2) double checked my multimeter (it was set on AC before!), retested VIO pins
3) all exhibit the same behaviour. Start out around 2.4V or so and each slowly rose up to 3.3V range. Takes ~5s or so when I probed. If I reprobe they are all at 3.3V right away. So it was like some cap was charging initially.
4) Run my code. IT LIVES.
Yes, I think VonSzarvas has some kind of breaker.
Drama seems to be averted. Now I can get back to what I was trying to do, but I won't be touching pins for a while.
What possibly happened was that whole branched USB bus was shut down at the Mac. It only gets powered up again after resocketing the cable to the computer. It's something I've learned about USB only since the prop2. It might have been Von who mentioned that that can occur.
The LDOs should current limit, as well as have thermal shutdown, but a nastier mechanism here could be parasitic inductance and very sharp current edges causing ringing, triggering the P2 latch-up type failure.
A quick spice run, shows fast edges and even parasitic levels of L, can give significant ringing. I chose 10pF / 4nH+ 4.7uf of ideal C, and 300mA current impulse with a varying rise time
Those would add to the 3v3, for narrowest contact times, so it looks somewhat easy for a 'loose wire' to get into P2 damage territory ?
On both of my boards the fault appears on pin group 32 & 40.
If I am plugged into pin group 40 I can get it working if I start the code with the monitor disconnected.
After loading the code I can plug the montor in and the text is Ok.
If I start with the monitor plugged in the text glitch appears.
I get the same results with two different monitors.
Switching to pin group 32 always has the text glitch regardless of monitor connection state.
IIt appears to be some sort of hardware glitch and not a software bug.
EDIT: The fact that it affects all text regions together says it's not due to region config data.
With the simple text only demo, when I replace that line with either MODC $0 WC or MODC $F WC then I get two differing results, neither the same as the issue. But the forced text mode does produce clean correctly rendered text. Just, oddly, not at the correct coordinates. And, leaving that hack in place, shifting back to pin group 48 the picture looks normal still.
EDIT: Smile, went back to pin group 32 and now the forced text hack doesn't work. It's like it's not there.
Maybe it's a timing issue, where some pins are just that teensy bit faster/slower than others ?
An external load may droop VIO just enough to make a difference in those pins that come/go.
What is harder to explain, is the change/mode flip seems visually massive in timing terms ?
How much variation is possible in clocks here - can this be slowed down to less pixels, slower clock, but same video rates as a test ?
sets p8, b 'patch columns/4 into code
sets p10, b
sub c, #1 'compute columns -1
setd p5, c 'patch columns - 1 into code
subr c, $1ff
setd p11, c
This $1ff on the red line is the inb register not the value of 511 because it is missing the #. Patching p11 controls the start address of text data in LUT RAM written back to hub. It all makes full sense now, but it was in an area of setup code I wasn't expecting or looking at. The fact the the behaviour was affected by real HW I/O states when devices were plugged into different port B pin groups confused the heck out of me and led me down another path altogether. Even my dumping of all state variables last night showed nothing wrong. I was planning to dump the entire COGRAM in the good and bad cases today and that would have ultimately caught this too, but I'm rather glad I won't have to do that. I believe it should also resolve the next issue I saw with text being off by one pixel on the left of screen at times. It's just another manifestation of the same bug.
The best way I can think to sufficiently differentiate immediate numbers from registers is to put registers in brackets:
It would be a burden to always use brackets for registers, but it would be obvious and unmistakable. It would also solve the issue of needing a "#" in front of an immediate address.
I suspect that would quickly lead to the opposite problem of forgetting to put the [] around a label when you intended it as a register rather than an immediate.
A simple heuristic would be to warn about any immediate integer in the source field that doesn't have a # in front of it, e.g. "add foo, 1" gets a warning, but "add foo, #1" or "add foo, bar" don't. Complex expressions also don't get a warning, so "add foo, 0-0" does not get a warning. I suspect that would catch many of these issues without producing too many false positives, and suppressing the warning would be easy (just add "+0" to the operand to make it an expression instead of a simple integer).
jmp destinations are a different matter (there we do want to check labels for #). I already have a check for those in fastspin, but it's mildly complicated: I actually look at what follows the label. If it's code I assume that a missing # is worth warning about, if it's data then I assume that an indirect jump is intended. The "+0" trick also works to suppress warnings.
Yes, you could also expand that some more, by checking if the name is a CONST or REG variable declared.
That catches most usages, and just leaves the case of needing to load the address of a REG var to handle - less common, maybe #ADR()can make that clear ?
then you expand to
"add foo, 1" gets a warning,
"add foo, #RegDecl" gets a warning, suggesting to use #ADR(RegVar)
"add foo, ConstDecl" gets a warning, suggesting to use #
"add foo, #1" is ok
"add foo, RegVar" is ok
"add foo, #ADR(RegVar)" is ok
"add foo, #ADR(RegVar)+3" is ok
I am using these equations below to try to figure out the burst colour for the signal.
R=RED, G=GREEN, B=BLUE, Y=LUMA, C=CHROMA.
V=0.877(R-Y)
U=0.492(B-Y)
Y=0.3R + 0.59G + 0.114B
C=Usin(wt) +/- Vcos(wt), where C = colour phase & amplitude vector, alternating per PAL video line using the +/- operation.
If I solve the U, V equations for determining the PAL burst colour phase which I understand is meant to be 135 or 225 degrees and amplitude of 21.4 IRE units or (21.4/143 * 1V)= 150mV, this represents (U,V) co-ordinates of (-21.4/sqrt(2), +/- 21.4/sqrt(2)) which is (-0.15, +/- 0.15) in the U,V plane. The amplitude of C in theory should be sqrt(U*U + V*V) for these multiples of 45 degree angles and (abs(U) == abs(V)).
Solving for R,G with B=0. I get these colours..
U = -0.15 = 0.492 (B-Y)
so
Y= 0.15/0.492 = 0.305
When V= 0.15 = 0.877(R-Y)
R = 0.15/0.877 + Y
= 0.476
G= (Y-0.114B - 0.3R)/0.59
= (0.305 - 0 - 0.3*0.476)/0.59
= 0.275
When V = -0.15 = 0.877(R-Y)
R = Y - 0.15/0.877
= 0.305-0.171
= 0.134
G = (Y-0.114B-0.3R)/0.59
= (0.305 - 0 - 0.3*0.134)/0.59
= 0.449
This corresponds to two colour burst colours of
RGB =(0.476, 0.275, 0) and (0.134, 0.449, 0), when RGB go from 0-1
or
RGB = (0.476*255, 0.275*255, 0) and (0.134*255, 0.449*255, 0)
= (121, 70, 0) and (34, 114, 0) when using an RGB DAC input range from 0-255.
The problem is that neither of these colour burst colours give me a good picture. It may have something to do with any remaining scaling in the colour space converter I am not considering or the fact that it may not be modulating both in-phase and quadrature terms on its colour output, just the quadrature component. That fact may possibly result in a phase angle offset of 45 degrees and another attenuation by a factor of sqrt(2). I am certainly seeing an large attenuation in the amplitude.
Unfortunately the P2 colour space converter adds its own complications with scaling. Firstly the video output range needs to be compressed to allow for sync tips to take up ~0.3V of the 1Vp-p video signal from the DAC (when terminated by 75 ohms). It turns out that 76/255 = ~0.3V which is probably a good value to use. This limits the video output to be from 0-179 (255-76) instead of 0-255 once the Y gets offset by 76 for the sync level. The two CY[7:0] and CI[7:0] values define the offsets for blanking and/or black levels (which I understand are the same for PAL, but not for some NTSC). I am using them with the same values for PAL.
The P2 uses these equations for Y/I/Q:
Y[7:0] = (DAC3 * CY[31:24] + DAC2 * CY[23:16] + DAC1 * CY[15:8]) / 128
I[7:0] = (DAC3 * CI[31:24] + DAC2 * CI[23:16] + DAC1 * CI[15:8]) / 128
Q[7:0] = (DAC3 * CQ[31:24] + DAC2 * CQ[23:16] + DAC1 * CQ[15:8]) / 128
To generate the Y signal we need to set co-efficients to scale the input colours to the right levels.
Y = 0.3R + 0.59G + 0.11B, where RGB go from 0-1
This should make it
Y = (0.3*128*R + 0.59*128*G + 0.114*128*B) / 128, where Y ranges from 0-1
or
Y = (38*DAC3 + 76*DAC2 + 15*DAC1) / 128, where Y now goes from 0-255, when R,G,B input DAC3,DAC2,DAC1 signals range from 0-255.
However this needs to be scaled data further to limit Y to be from 0-179, and also reduced a bit more to later allow for the colour signal to be added to Y and still not exceed 255 when fully saturated.
I believe Chip uses this "SAT" constant to indicate the amount of colour saturation gain/attenuation.
With
SAT = 70
and CY parameter
CY_PAL = ((38*SAT/128) & $ff) << 24 + ((75*SAT/128) & $ff)<< 16 + ((15*SAT/128) & $ff) << 8 + 76
we should then get an output range reduction of (70/128 or 0.55) This means the Y voltage range is now 0.55V leaving 0.45 for sync and colour signal excursion combined. I don't know if it is optimal but SAT=70 will do for now until I can figure out the best way to compute it.
There is also another attenuation factor of 1000/1646 required for the CI/CQ components due to the gain of 1.646 in the CORDIC during the rotation step. That is the "r" parameter below. I have also included the factors of 0.492 and 0.877 in the "palu", "palv" constants also used in the CU_PAL/CV_PAL parameters below (here U is in-phase I, V is quadrature Q). This is needed to again scale the U,V outputs by the correct amount for generating the colour according to the first equations listed above.
r = SAT * 1000/1646
palu = 492
palv = 877
With U = 0.492 (B-Y)
this results in CI coefficients of
CU_PAL = ((-38*r*palu/(128*1000)) & $FF) << 24 + ((-75*r*palu/(128*1000)) & $FF) << 16 + ((117*r*palu/(128*1000)) & $FF) << 8 + 76
Here due to negation of Y, the red and green coefficients are negated while the blue coefficient becomes (1-0.114) or 0.886 of the the full value. It was 0.114 before so we need to re-scale and it becomes 0.886/0.114 of what it was, this is then 0.886/0.114 * 15 or 117.
With V = 0.877 (R-Y)
this results in CQ coefficients of these for the odd/even scan lines.
CV_PAL_ODD = ((26 89*r*palv/(128*1000)) & $FF) << 24 + ((-75*r*palv/(128*1000)) & $FF) << 16 + ((-15*r*palv/(128*1000)) & $FF) << 8 + 128
CV_PAL_EVEN = ((-26 -89*r*palv/(128*1000)) & $FF) << 24 + ((75*r*palv/(128*1000)) & $FF) << 16 + ((15*r*palv/(128*1000)) & $FF) << 8 + 128
Here due to negation of Y, the green and blue coefficients are negated, while the red coefficient becomes (1-0.3) of 0.7 of the full value (1-0.59) or 0.41 of the full value. It was 0.59 before so we need to re-scale and it becomes 0.41/0.59 of what it was, this is then 0.41/0.59 * 38 = 26. It was 0.3 before so we need to re-scale and it becomes 0.7/0.3 of what it was, this is then 0.7/0.3 * 38 = 89.
Update: fixed data above, but now no PAL image appears on screen with new value. Scope looks okay. Not sure why.
I have two values for PAL_CV, odd and even, which are applied to the alternating PAL lines in the SETCQ argument.
The problem I have is this is still off. I've tried flipping the ODD/EVEN terms around in case I have started with the wrong one at the start of the frame, and this does affect the colour, but it is still bad. I've also tried both colour burst colours with this too. I still need to make a colour bar test pattern to see what is going on there and if the desired phase is off by another 45 degrees due to how the colour space converter works (it might be).
In the code I am flipping the CQ parameter every second line. Here "cqflip" is passed into the driver as the XOR of the odd/even PAL_CV values computed above. I'm pretty sure that both the phase of the colour burst on the scanline and its real coloured pixels should be getting flipped by 90 degrees by this (mirrored about the U axis), and the CQ change should take effect before the burst based on the streamer command sequence.
Here is the rubbish PAL colour I am seeing (S-video output). Every alternate line is showing a different colour. Red and green text backgrounds seem to alternate per scanline when it should be either solid red or solid green. Looks worse on the LCD monitor than in the picture. I've tried resetting the cq parameter to the same state at the start of the field and also letting it continue from the previous state in case I had an odd/even line issue with interlacing but it didn't help.
Here is the colour burst. You can see it is low in amplitude relative to the -0.3V sync tip. It should be bigger.
I turned on persistence and you can see the 4 phases of the colour burst on a given scanline. This is expected with PAL as it has four different phases spread over an 8 field cycle with an interlaced scan image. Because it is not locked to the pixel rate it will drift over time and the "eyes" will fill up and the scope screen will then be solid yellow but this takes perhaps 30s or so as the colour signal frequency is rather close to the 1135/4 multiple of the horizontal line rate. For PAL the colour burst frequency is meant to be that value plus 25Hz. I'm not sure if the P2 will be able to get the 25Hz part added reliably, but perhaps close is good enough. NTSC is an exact ratio of 227.5 and this can be locked.
I think if I had some type of vector scope I might be able to figure out what the phase error is. Otherwise this is sort of trial and error for me. I wish I could derive it properly from the equations and my understanding, obviously my understanding is incorrect somewhere.
Is the PAL driver I made for the P1 in the OBEX? It worked all correctly.
This line in your brief colorspace converter documentation
IQ[7:0] = Q of (I,Q) after being rotated by PHS and multiplied by 1.646
seems to imply that only the sine of the rotated co-ordinate (ie. the new Q) is used in the DAC output that gets added to the Y signal. When Q is maximum this is when V is maximum and the SINE of the phase angle is 1.
I guess the normal calculation of the colour component for PAL is Usin(wt) +/- Vcos(wt). So something could be different here, maybe it is introducing a problem the way I am doing it. I think the addition of a sine wave and a cosine wave at the same frequency is just another sine whose amplitude is sqrt(2) times larger (if they had the same magnitudes) and at 45 degrees to the original sine wave. So if you are only adding the new Q component to the Y in the P2 then this may generate an additional phase offset and attenuation to be handled.
Ok, I think someone said PAL never worked properly on the P1. So that was my understanding. I know I tried it once here ages ago and it didn't work right but it might have been someone else's driver.
Yes, the rotated, magnified Q gets added to Y. Watch the amplitudes, because it can overflow and wrap at zero.
Also, RE: chroma amplitude: Full saturation at full Y isn't a valid part of the colorspace and thus shouldn't ever come up when coverting from RGB input. Think of it as two cones glued together, white at the top, black at the bottom and full saturation colors around the circle where the cones meet.
I was able to get the PAL signal fed into my plasma TV with colour bars even though my LCD refused to display it. The colours are off. Interestingly, and I'm not sure if this is a feature of the TV or not, but when I do this the incorrect colour bars are only shown for the top 10% or so of the screen, then proper colour bars are shown. The TV might be somehow adapting or this might be a diagnostic feature from Pioneer for tuning things.
It looks like red is coming out green, and green is coming out red. Yellow is close but not perfect. Blue is right but that was set to 0 in the colour bursts so didn't play a part in its calculation. Magenta and cyan look pretty ugly too. Of course black and white work as they don't need to send the colour signal.