Shop OBEX P1 Docs P2 Docs Learn Events
Anyway to reset the video HW's timers? — Parallax Forums

Anyway to reset the video HW's timers?

lonesocklonesock Posts: 917
edited 2009-10-05 23:13 in Propeller 1
Hi, All.

I'm trying to write a full-duplex serial driver that works at 2Mbps and fits in one cog. I was hoping to use the video hardware for the outgoing data. I can set up the baud-rate and data structures pretty easily, but I can _not_ find a way to "reset" the internal countdown timers (specifically the one used for "FrameClocks" in the video scale register) so that an initial waitvid is guaranteed to be less than a single bit width.

Setting vcfg to zero doesn't reset them. Changing vscl only get's updated whenever the current data is done (i.e. when FrameClocks counter expires, which is where the next waitvid would happen). Disabling the Counter A only pauses the countdown. Right after I do a waitvid I can set vscl to 1 (the fastest possible turn around time because it sets "FrameClocks" to 1...0 is interpreted as 4096). As soon as my data frame is done shifting out, then it starts reloading every pixel, but that is still much too long a time to be out of the loop since I may need to be scanning for incoming bits.

Does anyone know a way to do this?

Jonathan

P.S. In case anyone is interested, here is my code for setting up the video register values to a specific frequency. I use it to set the values of some longs in the DAT region before my cognew call.
{{
  calc_video_timing
  * frequency must be greater than 2kHz
  * the propeller's clock should be greater than 8MHz, to insure proper PLL functionality
}} 
PUB calc_video_timing( frequency, pixels ) | drive_freq, PLLDIV
  ' drive at our clock rate
  drive_freq := frequency
  ' but within the limits of the PLL
  repeat while drive_freq > 8_000_000
    drive_freq >>= 1
  repeat while drive_freq < 4_000_000
    drive_freq <<= 1
  ' compute the divider
  frqa_val := ratio( drive_freq, clkfreq )
  ' now compute PLLDIV
  PLLDIV := 7
  drive_freq <<= 4 ' the PLL makes it 16x higher
  repeat while PLLDIV and ( drive_freq > (frequency + (frequency>>1)) )
    PLLDIV--
    drive_freq >>= 1
  ctra_val |= PLLDIV << 23
  ' now compute the pixel-clock
  vscl_val := (drive_freq + (frequency>>1)) / frequency
  ' limit it to 1 to 255
  vscl_val := vscl_val #> 1 <# 255
  vscl_val := (vscl_val << 12) + (vscl_val * pixels)
  

PRI ratio( num, denom) : r
  ' compute the 32-bit fixed-point representation of num / denom (so num must be =< denom)
  repeat 32                      
    num <<= 1
    r <<= 1
    if num => denom    '  
      num -= denom
      r++

▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
lonesock
Piranha are people too.

Comments

  • ericballericball Posts: 774
    edited 2009-10-05 20:28
    The internal VSCL counters (FrameClocks & PixelClocks) are reloaded when FrameClocks transitions from 1 to 0. Unfortunately, because VSCL is reset on cog load, the first load is after 4096 PLLA clocks. So if you set VSCL to 4097 then do a WAITVID, then the code will be released when VSCL expires and the next VSCL update will be immediately picked up.

    Note: FrameClocks 1 to 0 also reloads the internal pixel and color registers from the current values of D & S. So if your code isn't halted on WAITVID when FrameClocks hits zero then you will be outputing garbage data. movi vcfg, #0 will stop the vscl counters if you want.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Composite NTSC sprite driver: Forum
    NTSC & PAL driver templates: ObEx Forum
    OnePinTVText driver: ObEx Forum
  • lonesocklonesock Posts: 917
    edited 2009-10-05 20:45
    Understood. What I was hoping to do was something like this:

    Set FrameClocks to 0 (4096)
    Enable the video HW
    use waitvid to send out a data byte (with trailing 1's, for serial busy)
    Now the video HW will clock out my 9 bits (one start, 8 data) and up to 4087 stop & busy bits (giving me time to do other things)
    When I need to send out the next data byte, I'd like to reset the counters so I can send out the data using a waitvid immediately (5 clocks minimum, right?)

    Since I can not figure out a way to reset the FrameClocks countdown register, I would have to know precisely when it expires to make sure that the data on the src and dest buses are correct, or use a waitvid before then, which means I can not be using that cog to do any serial receiving.

    Jonathan

    edit: On re-reading, sorry I sounded like a jerk! I learned what I know from you and others on this forum, then a bit of experimentation thrown in for good measure, so thanks for all your help and input!

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    lonesock
    Piranha are people too.

    Post Edited (lonesock) : 10/5/2009 9:00:22 PM GMT
  • Cluso99Cluso99 Posts: 18,069
    edited 2009-10-05 22:53
    There are a few others - Beau is one, kuroneco may be the other·- that understand the VCL better. I have not played/understood at all.

    However, someone was experimenting with using the counters to shift data out automatically. I would consider letting the counters shift out continuously and just let it shift out 1's (stop bits) when no characters are available. As soon as characters are ready, just send them out. No need for waitvid. However, IIRC, the downside to this is a wasted pin (and we do not have any :-( ) for doing the shifting out. This would leave the counters free to also shift data in. Once again, 1's indicate stop bits until a new 0 for start bit is seen.

    Take a good look at Beau's Ultra High Speed code. It is a fantastic start of where we want to be for prop-prop comms, and it can send >8bit codes.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Links to other interesting threads:

    · Home of the MultiBladeProps: TriBlade,·RamBlade, RetroBlade,·TwinBlade,·SixBlade, website
    · Single Board Computer:·3 Propeller ICs·and a·TriBladeProp board (ZiCog Z80 Emulator)
    · Prop Tools under Development or Completed (Index)
    · Emulators: Micros eg Altair, and Terminals eg VT100 (Index) ZiCog (Z80) , MoCog (6809)
    · Search the Propeller forums·(uses advanced Google search)
    My cruising website is: ·www.bluemagic.biz·· MultiBladeProp is: www.bluemagic.biz/cluso.htm

    Post Edited (Cluso99) : 10/5/2009 11:01:21 PM GMT
  • ericballericball Posts: 774
    edited 2009-10-05 23:13
    Unfortunately, it doesn't work that way. WAITVID has zero impact on the internal video registers. It's everything to do with halting the cog until the video registers have been reloaded.

    And I can't think of a way of doing what you want. The closest I can think of is:
    • Set FrameClocks to 10 times PixelClocks (10 bits)
    • use OUTA to hold the output high
    • WAITVID to load the data to be shifted out, with the a high dummy first bit
    • clear OUTA
    • short processing window
    • WAITVID to wait for the bits to be shifted out & to load all 1s
    • set OUTA
    • long processing window until you're ready to send out the next byte
    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Composite NTSC sprite driver: Forum
    NTSC & PAL driver templates: ObEx Forum
    OnePinTVText driver: ObEx Forum
Sign In or Register to comment.