Shop OBEX P1 Docs P2 Docs Learn Events
HDMI discussion - Page 6 — Parallax Forums

HDMI discussion

1234689

Comments

  • roglohrogloh Posts: 5,786
    edited 2024-10-24 03:48

    @Wuerfel_21 said:

    @rogloh said:
    I haven't seen Tempest 2000 before, no, but in the meantime I'll try full NeoYume with this and report back.
    Update: played NeoYume first level of MSlug - audio survived fine.

    Well that doesn't mean much, there wasn't any change (dejitter enabled either way).
    T2K source is here: https://github.com/Wuerfel21/tempest2k/tree/video-nextgen

    Just downloaded and installed dependencies, built Tempest etc. Setup HyperRAM on pin 0 of P2 EVAL, USB board on P16, VGA/AV on P24, HDMI on P32.

    I was first able to run with VGA output to prove it actually worked, then reconfigured and built for HDMI by enabling this section below. Confusingly it still mentions a VGA_BASEPIN but this mode indicates and uses HDMI on this pin AFAICT when I dug into the code. I could hear analog audio on VGA board the but no video is shown on HDMI. Not sure my plasma TV accepts 800x480 like this. It's pretty restrictive and only likes HDTV resolutions and probably just 640x480, sorry.

    VIDEO_MODE = vconst.MODE_HDMI
    VIDEO_SUBMODE = 0
    
    VGA_BASEPIN = 32
    VGA_VSYNC   = 0
    
  • You're not using the new branch

  • roglohrogloh Posts: 5,786
    edited 2024-10-24 04:26

    Weird, I cloned the from the link above and it doesn't seem to have video-nextgen in the list of branches. git must be messed up there although I do see it listed on GitHub.

    ❯ pwd
    /Users/roger/Code/Propeller2/tempest2k
    ❯ git branch -l
    * p2port
    ❯ git pull
    Already up to date.
    

    3517 ls
    3518 git clone https://github.com/Wuerfel21/tempest2k.git
    3519 cd tempest2k
    3520 ls
    3521 git submodule init
    3522 git submodule update
    3523 cd mac
    3524 cd rmac
    3525 make

  • try checking it out anyways

  • roglohrogloh Posts: 5,786
    edited 2024-10-24 04:39

    @Wuerfel_21 said:
    try checking it out anyways

    Yeah doing that right now. It does appear to have different settings in the p2config.spin2 file now at least. Will retest and report in ~5mins.

    Update: yeah now audio works okay. Nice pretty colourful game. Can't really play it well though. My USB controller sucks with it.

  • roglohrogloh Posts: 5,786

    I've found I can easily get this test driver to output simple DVI instead of HDMI encoding format with the handful of following patches done at COG setup time. This is beneficial in that a DVI monitor can still be used to test timing changes and anything unrelated to audio - for me without a HDMI device handy on my desk this is a good thing. It should probably be part of a driver's feature set.

                orgh
    ' hubexec code
    dvi_override                sets    x1, #hsync0         ' use inactive hsync patterns instead of gaurds/preambles
                                sets    x2, #hsync0
                                sets    x3, #hsync0
                                sets    x4, #hsync0
                                sets    x5, #hsync0
                                sets    x6, #hsync0
                                mov     extrapkts, #0       ' no extra sync packets
                                sets    x8, #hsync0
                                sets    x9, #hsync0
                                mov     shrink, #0          ' no shrink of back porch for last vsync line
         _ret_                  setnib  m_hubpkt, #7, #7    ' send immediate mode hsync patterns
    

    Am going to look into VGA+DVI/HDMI output simultaneously now. I'd still kept the hsync1/hsync0 pattern flip and cmodval update or direct vsync pin flip capability in the instruction path for this purpose. This should allow both 4 pin (composite sync) and 5 pin VGA sync modes to be selected. 3 pin VGA (SyncOnGreen) is not going to be possible as the DAC0 channel value is not accessible in TMDS mode AFAIK. There appears to be no way to set that channel up in the streamer commands when immediate 10bit->8bit conversion is happening.

    vsyncon                     xor     cmodval, #1             'xor cmodval, #1 (4 pin VGA) or xor vsyncinstr, #1 (5 pin VGA)
                                decod   status, #31             'update status - in vertical sync
                                setbyte status, fieldcount, #2  '
                                mov     hsync0, sync_001        'vsync on, hsync off
                                mov     hsync1, sync_000        'vsync on, hsync on
    
    patchvsync                  callpa  #V_SYNC-0, #blank_vsync 'send vertical sync blanks
    vsyncoff                    xor     cmodval, #1             'vsync pin off
                                mov     hsync0, sync_003        'vsync & hsync off (neg polarity)
                                mov     hsync1, sync_002        'vsync off, hsync on
                                jmp     #fieldloop              'continue on to a new field/frame
    
  • Wuerfel_21Wuerfel_21 Posts: 5,049
    edited 2024-10-24 15:20

    @rogloh said:
    I've found I can easily get this test driver to output simple DVI instead of HDMI encoding format with the handful of following patches done at COG setup time. This is beneficial in that a DVI monitor can still be used to test timing changes and anything unrelated to audio - for me without a HDMI device handy on my desk this is a good thing. It should probably be part of a driver's feature set.

    On my end DVI just doesn't install all the HDMI overlay stuff :) It of course still needs all the scanfunc pixel doubling stuff.

    3 pin VGA (SyncOnGreen) is not going to be possible as the DAC0 channel value is not accessible in TMDS mode AFAIK. There appears to be no way to set that channel up in the streamer commands when immediate 10bit->8bit conversion is happening.

    Soggy sync isn't directly possible, yea. DAC0 is accessible (TMDS hooks into pin outputs, DAC outputs are unrelated), the problem is that when sending raw 10b TMDS codes, the bottom 6 bits thereof get sent to DAC0, which is not very useful. The "VGA" cmod mode only uses the LSB of DAC0, that's why it's compatible with the TMDS encoder (which ignores bit 0 in all cases). Note that for all commands that don't send visible color, you need to use X_DACS_X_X_X_0 so that the same problem doesn't happen to the other DAC channels. You also need to make sure that SETDACS is set to sane blanking levels (does this register reset to zero when rebooting the cog?). If you disable DAC output entirely during blanking, you could use carefully placed SETDACS to manually implement soggy sync. Note that obviously the full breadth of the color converter is still active, so if you can do sync-on-green, you can do YPbPr (which i both thus group as "soggy" formats).

  • roglohrogloh Posts: 5,786

    @Wuerfel_21 said:
    Soggy sync isn't directly possible, yea. DAC0 is accessible (TMDS hooks into pin outputs, DAC outputs are unrelated), the problem is that when sending raw 10b TMDS codes, the bottom 6 bits thereof get sent to DAC0, which is not very useful. The "VGA" cmod mode only uses the LSB of DAC0, that's why it's compatible with the TMDS encoder (which ignores bit 0 in all cases). Note that for all commands that don't send visible color, you need to use X_DACS_X_X_X_0 so that the same problem doesn't happen to the other DAC channels. You also need to make sure that SETDACS is set to sane blanking levels (does this register reset to zero when rebooting the cog?)

    Aha this might explain why I can't seem to get simultaneous DVI and VGA working right with the colours tonight. See this post and the page of discussions afterwards .. I'd sort of abandoned the idea back then but am intrigued again after you said it was doable. I might have to play with those DAC settings now during blanking streamer commands.

    https://forums.parallax.com/discussion/comment/1480497/#Comment_1480497

  • Yes, sending non-black during blanking WILL mess up the colors. It's very simple really, you use X_DACS_3_2_1_0 ONLY for active video, X_DACS_X_X_X_0 for everything else. The "X-ed out" channels get their value from the SETDACS register instead of the streamer.

  • (do note that the values from SETDACS will still pass through the color converter!)

  • roglohrogloh Posts: 5,786

    This is great news. I'm trying it right now before heading off to sleep.

  • roglohrogloh Posts: 5,786

    Wow, makes a difference. Colours look much better. Not sure if I've got the blanking level setup right below but I'm seeing a pic - will work on it more tomorrow.

    setdacs ##$4c4c4c00

  • roglohrogloh Posts: 5,786

    Much nicer colours with setdacs #0

  • Remaining work for the new HDMI driver to be merged into master branches, to my memory (TODO: check earlier post):

    • Add interlace mode for actual 1X modes (line multiply modes already work with bobbing) - only a blocker for MegaYume
    • double/triple check that line counter values are correct (on MD there's a useful test ROM for this)
    • variable framebuffer width - so you can get the full 384x240 buffer from Tempest 2000 when the output is wide enough (I don't know why it's so wide, but it is)
    • re-add LCD6 interface (only old video format not yet ported)

    Bonus:

    • whatever is needed to make MisoYume's 512x224 mode work (though that's still in beta so there's no branches - also in the future I need to support the 512x239 overscan mode)
  • Wuerfel_21Wuerfel_21 Posts: 5,049
    edited 2024-10-25 00:59

    LCD6 (for ILI9342 controller in 6 bit RGB+HVSync interface) is working again (in NeoYume)! I foolishly re-implemented the entire init sequence in ASM... Was confused for a while until I realized there was a typo and it wasn't actually setting IFMODE (not to be confused with IFCTL).

    Will double check that I didn't break other modes tomorrow, but that was the only thing really holding back the new video driver from merging into specifically NeoYume's master branch (and probably doing a new numbered release to celebrate)

  • Wuerfel_21Wuerfel_21 Posts: 5,049
    edited 2024-10-25 01:30

    actually, I just noticed that it doesn't seem like it can properly initialize the LCD from cold power up... Will need to be fixed still
    actually, I'm just beeg stupeed.

    Relatedly, I found a command that replaces the really objectionable column inversion on these LCDs with checkerboard inversion, which is less obnoxious. Really, the ideal way would be to properly calibrate the positve and negative voltages to match, but why don't they do it at the factory???

  • roglohrogloh Posts: 5,786

    @Wuerfel_21 I don't see any direct support for sync polarity stuff in your driver. I'm going to try to add it back into my own as that's a feature of my timing. Tried negative sync output for hsync and it's a bit messed up - I think I've got some inconsistencies between my own legacy driver code and the TERC pattern settings from your code. On the scope I see some weird hsync patterns coming out the analog VGA pin. Hsync positive was okay. I did try to flip some of the least significant bits of the patterns when I detect positive or negative hsync but I must have messed some up. For the VGA side I think it should be obtainable just by flipping the CMOD register lsb but it's encoded explicitly in the TERC and lsbs of different patterns. Will have to try flipping a few bits to see what happens.

  • Is a sync polarity a thing on HDMI? I think it's supposed to be only positive? For VGA only you should be able to flip it through the CMOD bit. In that case, don't change it anywhere else!!! It will get double inverted.

    Is there ever a need for specific sync polarities? I don't think it ever mattered in my years of video experimentation.

  • Wuerfel_21Wuerfel_21 Posts: 5,049
    edited 2024-10-25 01:48

    As for the TERC pattern table, the VGA sync bit in there is set such that it matches the encoded HSync bit on TMDS channel 0. (for the other two channels, only the upper bits are muxed in)

  • roglohrogloh Posts: 5,786

    @Wuerfel_21 said:
    Is a sync polarity a thing on HDMI? I think it's supposed to be only positive? For VGA only you should be able to flip it through the CMOD bit. In that case, don't change it anywhere else!!! It will get double inverted.

    Yeah I've already encountered some double flipping which confuses the matter more.

    Is there ever a need for specific sync polarities? I don't think it ever mattered in my years of video experimentation.

    If you want to replicate specific dedicated timing for some monitors it may be important. Most modern day monitors couldn't care less though I still like the idea of having control of it.

  • "Modern day" must stretch quite far back then, never had polarrity matter when comitting atrocities against my Fujitsu-Siemens multisync CRT monitor (the absolute limit is somewhere at 720x540 160Hz... Can also do oddballs like 320x240 120Hz - the OSD glitches because it foolishly asssumes there are at least 400 lines to superimpose on :) )

  • roglohrogloh Posts: 5,786

    I think the ancient non-multisync monitors are the problem ones. EGA might also need specific sync polarities. When I re-integrate my parallel RGB stuff for LCD panels into my driver I still want to try out this driver with old CGA/EGA TTL monitors for a laugh and some extreme nostalgia.

  • roglohrogloh Posts: 5,786
    edited 2024-10-25 07:37

    Oh man, just getting this combination HDMI and VGA sync polarity stuff working right is totally doing my head in!

    After multiple failed attempts I think I've sort of figured out the following:
    1) Analog hsync DAC output is controlled by the lsb of the pattern data sent to DAC[0] and also the lsb of CMOD register which flips it when this CMOD bit[0] is true.
    2) All displayed RGB video data forces the DAC[0] bit to zero and we can't control that - this is important as it defines the idle polarity state of the hsync output 0=idle, 1=active, irrespective of the desired hsync polarity . In the end we just need to set the CMOD bit[0] to select the hsync polarity emitted by the DAC0 channel on the pin.
    3) Immediate pattern data sent during blanking can control the value of this bit, but it should only ever be set to 1 during the hsync pattern and 0 otherwise.
    4) the TERC table 3x10 bit patterns + two bits, of which the LSB also controls this hsync state.
    5) the packet_extra register in Ada's code sets up which sync polarity the blue channel's TERC nibble emits, as the two lower bits of this nibble are defined for carrying the vsync and hsync state, however that TERC pattern state is only controlling what the HDMI sink sees, and not for VGA DAC[0]. The lsb of the 30+2 bit pattern in the TERC table is what is used for that.

    With this in mind I believe I now need to do the following for either hsync polarity to work right for both VGA and HDMI and will need to try this:
    1) Make all inactive hsync patterns (front porch, guard pixels, back porch, preambles) have a 0 in the lsb of the pattern to indicate idle sync state
    2) Set CMOD[0] bit to 1 if negative hsync and to 0 for positive hsync - this state is what will control polarity of hsync in the end.
    3) Setup the 16 TERC table entry lsb's to be 1 as the packets encoded to these values will be issued during the hsync portion of each line. Encode the first two packets (64 pixels) sent during hsync with the appropriate packet_extra field values for vsync/hsync polarity, with vsync state suitably flipped on VSYNC lines.
    4) Flip the TERC table entry pattern lsb's to 0 only for the third and fourth packets encoded and sent out on vsync lines after hsync completes. This will keep the size of the hysnc pulses the same on all lines - I might be able to get away without it but I don't like that. Takes ~68 clocks or so to flip and the same to restore back at the end. The code for this table flipping only ever needs to run on the first vsync lines when we send the Infoframe so there would be enough time to do it in a tight REP loop. It would be part of an overlay so doesn't need to fit in the COGRAM. EDIT: Actually these 3rd and fourth packets are pre-encoded so no need to table flip after startup - bonus!

    I'm hoping this will finally sort it out... fingers crossed.

  • TubularTubular Posts: 4,701

    Fingers crossed here too. Appreciate all the braincell burn going in to this...

  • @rogloh said:
    3) Setup the 16 TERC table entry lsb's to be 1 as the packets encoded to these values will be issued during the hsync portion of each line. Encode the first two packets (64 pixels) sent during hsync with the appropriate packet_extra field values for vsync/hsync polarity, with vsync state suitably flipped on VSYNC lines.
    4) Flip the TERC table entry pattern lsb's to 0 only for the third and fourth packets encoded and sent out on vsync lines after hsync completes. This will keep the size of the hysnc pulses the same on all lines - I might be able to get away without it but I don't like that. Takes ~68 clocks or so to flip and the same to restore back at the end. The code for this table flipping only ever needs to run on the first vsync lines when we send the Infoframe so there would be enough time to do it in a tight REP loop. It would be part of an overlay so doesn't need to fit in the COGRAM. EDIT: Actually these 3rd and fourth packets are pre-encoded so no need to table flip after startup - bonus!

    I'm hoping this will finally sort it out... fingers crossed.

    No! You don't ever have to change the TERC table dynamically! Remember, bit 0 is copied based on what's in channel 0, which gets the H/Vsync flags from packet_extra. My table is set so that the hsync flag ends up in bit 0. For CSync you just need to set it so that it's hsync xor vsync ONCE AT THE BEGINNING.

  • roglohrogloh Posts: 5,786

    Ok, am leaving the TERC table aspect until last. All the other changes will be done then I will see what's left to fix. There are too many competing combinations at play here and I need some sanity before I take the final step. I know if I feed packet_extra correctly I do see that it will select either high or low bit 0 output based on that but it will also impact the DVI's hsync state when I flip the input. With CSYNC I do have to flip the hsync output state on the vsync lines but this is done just for 4 bit VGA only and done using the CMOD register bit 0, the DVI/HDMI side should still sees its normal hsync/vsync conditions.

  • roglohrogloh Posts: 5,786
    edited 2024-10-25 10:47

    One other weird thing I noticed on the scope is that there is also some analog voltage variation coming out on DAC 0 pin on the scan lines during the active video line portion. Am wondering if somehow perhaps it's from data in the text palette's LSByte which I may not have cleared? Need to check that but it should be cleared. The other region of my screen is using 24 bit RGB data - actually maybe that's the problem, it's probably random data. Might need to drop the last DAC byte in active video portions, although I can't find a steamer command mode for the dddd bits that does X3 X2 X1 00.
    Update: Actually no it is meant to be zero on X0 according to the documentation...

  • If there's minor noise on it, that's probably just crosstalk. All the RGB modes send $00 to DAC0, but with immediate and LUT modes you need to take care.

  • roglohrogloh Posts: 5,786

    @Wuerfel_21 said:
    If there's minor noise on it, that's probably just crosstalk. All the RGB modes send $00 to DAC0, but with immediate and LUT modes you need to take care.

    Yeah I think it was crosstalk. When I tried again earlier tonight I noticed I could make this issue happen when I moved the scope's ground wire and had a dodgy connection at the grounding post on the P2-Eval. It certainly looked a lot like active video at the time.
    I am going to try this change again when I'm feeling more wide awake. There should be a way to get this to work correctly once I nail all the parts down. Am working with old code and new code somewhat hacked together and am taking some shortcuts without examining every little step and detail as I really need to.

  • roglohrogloh Posts: 5,786
    edited 2024-10-26 03:43

    Finally making some progress on the sync polarity stuff. I found a bug in my code with an instruction in the wrong place which was invalidating about half my tests yesterday. Fixed that and am now seeing good analog sync polarities for each case. I can now start testing out that the DVI/HDMI sync patterns are still correct too but this is a good foundation to work from. You were right Ada, you only have to set the TERC table once. Basically I xor each table entry's LSB with 1 if the hsync polarity is negative and only do it once at setup time before using the table from then on for encoding. Everything else gets controlled via packet_extra fields.

    One thing I did see was a small glitch in the 4 pin VGA (composite sync case) sync output while the guard pixels get sent at the end of the front porch and we change the DAC[0] output polarity. This is happening when the CMOD[0] bit flips at the start of the vsync line pair and back at the start of vertical back porch lines. You get a brief runt pulse at that point when zoomed (see below). I don't think the CMOD change line below can be fully synchronized with the streamer easily. I may have to tweak the position in the skipf sequence but it's tricky to align with the true start of hsync where we are sending TERC encoded hub packets. I wonder if all VGA monitors will like this pulse.

                                                                ' active   vsync   blank
    blank_vsync                 skipf   skipfmask_vsync         '                           do vsync line
    blank                       skipf   skipfmask_vblank        '            |              do other blanking line
    hsync                       skipf   skipfmask_active        '            |       |      do active line
                                xzero   m_hfp, hsync0           '   *        *       *      send shortened fp before preamble
                                cmp     pa, #1 wz               '   |        *       *      z=1 if pa=1 (last sync or blank line)
                                testb   status, #30 wc          '   |        |       *      c=1 if doing vertical front porch (VFP)
    syn1        if_z_and_c      alts    alt0, #$00              '   |        |       *      last VFP line builds packet for 1st vsync line 
    syn2        if_z            setbyte packet_extra, #$ff, #1  '   |        *       *      last sync line builds packet for 1st VBP line
                                cmpsub  hdmi_regen_counter, hdmi_regen_period wc 
                                                                '   *        *       *      c=1 if time to send a clock regen pkt
                                mov     pb, pktbuf              '   *        *       *      setup base packet buffer address
                                add     pb, #256                '   |        *       |      offset to send in vsync line
                if_c            add     pb, #128                '   *        *       *      offset to send clock regen pkt (c=1)
    x3                          xcont   m_imm8, preamble        '   *        |       *      send preamble before island
    x4                          xcont   m_imm8, preamble_vsync  '   |        *       |      send preamble before island (vsync line)
                                call    #audio_poll_repo_start  '   *        *       *      poll audio now and latch start time
    
                                rdfast  #2, pb                  '   *        *       *      prepare fifo data for reading
                                wrlong  status, statusaddr      '   *        *       *      update clients with scan status
                                fblock  #0, pktbuf_audio        '   *        *       *      setup next packet start address
    x5                          xcont   m_imm2, dataguard       '   *        |       *      send leading guard band
    x6                          xcont   m_imm2, dataguard_vsync '   |        *       |      send leading guard band (vsync)
    x7                          xcont   m_hubpkt, hsync1        '   *        *       *      send two packets
    vsyncinstr                  setcmod cmodval                 '   *        *       *      patched to drvl/drvh or setcmod cmodval
    extrapkts   if_z            xcont   m_hubpkt, #0            '   |        *       |      send two more packets
                                call    #load_mouse_palette     '   *        |       |      read mouse code & large palette
    x8                          xcont   m_imm2, dataguard       '   *        |       *      trailing guard band  
                                xcont   m_hbp2, hsync0          '   *        |       |      send shortened back porch before preamble+gb
                                ret     wcz                     '   *        |       |      return with flags restored for sprite render
    x9                          xcont   m_imm2, dataguard_vsync '            *       |      trailing guard band sync encoded
                                xcont   m_hbp, hsync0           '            *       *      only control, no pre+gb for blank/sync lines
    shrink      if_z            altd    alt0, #m_vi2            '            *       |      shrink vsync vis line for extra 64 pixel pkts
                                xcont   m_vi, hsync0            '            *       *      generate blank line pixels
    encode                      call    #\loadencoder           '            *       *      encode next audio pkt & poll audio
               _ret_            djnz    pa, #blank_vsync        '            *       |      repeat
               _ret_            djnz    pa, #blank              '                    *      repeat
    
Sign In or Register to comment.