Shop OBEX P1 Docs P2 Docs Learn Events
How could I get a 3.58 MHz frequency from an internal counter? — Parallax Forums

How could I get a 3.58 MHz frequency from an internal counter?

cbmeekscbmeeks Posts: 634
edited 2015-04-30 09:37 in Propeller 1
I'm reading the documentation on counters but it seems a little scarce on how to actually do certain things. Maybe I'm just missing it.

Anyway, I'd like to generate a frequency that I can control (for a Z80 CPU) that is 3.58 MHz using either the CTRA or CTRB.

I say 3.58 MHz but it would be awesome to get it more granular than that and match the NTSC colorburst frequency of 3.57954.

Could someone point me to a tutorial that explains how to get such a specific frequency? I'd need to output that frequency on a pin, BTW.

Thanks!

Comments

  • potatoheadpotatohead Posts: 10,261
    edited 2015-04-29 11:37
    You can find this in most video drivers.

    https://www.parallax.com/sites/default/files/downloads/AN001-P8X32ACounters-v2.0.pdf

    That one explains all the counter mode detail.

    Here's a page that shows how to compute and output a given frequency:

    http://wardyprojects.blogspot.com/2015/02/propeller-high-frequency-output-using.html
  • cbmeekscbmeeks Posts: 634
    edited 2015-04-29 12:09
    Once again, you've proven to be very helpful.

    You REALLY need to write a book. :-)

    Thanks!
  • Mike GreenMike Green Posts: 23,101
    edited 2015-04-29 12:09
    Keep in mind that, unless your system clock is a multiple of the frequency you want, your counter output will have jitter ... the instantaneous frequency (time from one pulse to the next) will vary although the average will come out correctly. You could run the Propeller off a colorburst crystal and a clock multiplier of 16x to get a system clock of 57.27264 MHz ... about 3/4 the speed of the usual system clock (80 MHz). This will divide down evenly to produce the clock needed for the Z80.
  • cbmeekscbmeeks Posts: 634
    edited 2015-04-29 12:29
    AH, that's an excellent point.

    How would that affect video generation on other cogs?
  • potatoheadpotatohead Posts: 10,261
    edited 2015-04-29 13:07
    To minimize jitter, reduce the number of one's in your FRQA value.

    Each counter does what it does independently. Same for the cogs.

    If you run off a crystal, a clean multiple of it will have low jitter. Not many ones in play.

    Video generation just needs to be adjusted for the non standard clockspeed.

    For most drivers, this is easy, and many are written to work off any clock fast enough. If you want, mooch that part and drop it in your driver.
  • potatoheadpotatohead Posts: 10,261
    edited 2015-04-29 13:10
    57 Mhz is slow for video. A higher multiple would be better.

    We will have to see what is possible at that speed. Video is for sure. But it might take more cogs to get what you want done.

    Good news is TV is the slowest signal, so there is the most time and more is possible at lower clocks.
  • cbmeekscbmeeks Posts: 634
    edited 2015-04-29 13:21
    I have many 14.31818 MHz crystals (4x NTSC).

    So, if I used one of those and a PLL8x that's over 114 MHz. PLL4x is still 57.27272 MHz.

    What other frequencies and PLL values could we use to get close to the 80 MHz?
  • ercoerco Posts: 20,256
    edited 2015-04-29 13:50
    Of course, at 10 for $1.51, a real 3.579 mhz crystal is hard to beat: http://www.ebay.com/itm/Lot-of-10PCS-3-579M-3-579MHz-3-579545M-3-579545MHZ-Crystal-Oscillator-HC-49S-/231249992035

    I have some. If you like, PM me your address and I'll mail you one.
  • cbmeekscbmeeks Posts: 634
    edited 2015-04-29 13:53
    Oh, that's not the issue. I have MANY crystals of different frequencies. Including 3.579 MHz.

    What I meant by the 14.31818 was that it was the next level up from my 3.579 (of course, you couldn't have known that) that was a multiple of NTSC (I have plenty of 8 MHz too).

    But, after reading a bit, I see that 14.31818 is way out of spec for an external crystal. The ideal crystal would be a 7.15908 MHz. It *seems* that the 114.54528 MHz (PLL16x) might be possible and reliable?? That's assuming such a crystal exists.

    If so, then the NTSC colorbust clock for the Z80 would have an even split.

    Also, I was thinking of using the prop to control the clock of the Z80 which is why I'm not using a real crystal. But, maybe I could still do that and use an external one too?

    Oh, and thank you for offering to send me some crystals.


    ** EDIT **

    Hmm, it appears that pushing the prop beyond 100 MHz is simply not a good idea. Especially if all I want to do is control a Z80. So, it would probably be better if I found another way. I just don't know enough about the Z80 to know how to do that yet. I was thinking if the prop could freeze the clock, then I can do certain things like convert SPI RAM, etc.

    Also, what I might do is just run the Z80 at the NTSC clock and see how bad the jitter is. This is for a homebrew ColecoVision. So I don't know how accurate the clock needs to be for games to work (and work reliably).

    Perhaps the ColecoVision game can live with a little jitter. :-)
  • jmgjmg Posts: 15,173
    edited 2015-04-29 15:09
    cbmeeks wrote: »
    Perhaps the ColecoVision game can live with a little jitter. :-)
    Do you expect Colour ?
    To get colour decoded, then frequency and phase are very important, and XTAL will be needed.
    To get just a raster and old TV can sync to, in B&W. that's a little more tolerant.

    You could try a divide by 4 from 14,xx for 3.57 and /3 for a 4.772726667MHz prop CLK
    (not sure if the prop tolerates 33:66 clock ratio, but I'd guess an edge PLL would be ok .
  • cbmeekscbmeeks Posts: 634
    edited 2015-04-29 16:57
    Yes, color is a must.
  • jmgjmg Posts: 15,173
    edited 2015-04-29 17:23
    cbmeeks wrote: »
    Yes, color is a must.

    I found an interesting link here
    https://www.eecis.udel.edu/~mills/database/memos/TV.TXT

    Claims Transmit stability of
    ["The frequency tolerance of the color burst is specified as 10 Hz or about 2.8 PPM."]
    - but I think the TV PLLs can pull their crystals by some tens of ppm so you probably do not need to chase single-digit ppm, but you should check and trim any crystal.
  • Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 23,514
    edited 2015-04-29 17:55
    Your 4x NTSC crystal will not work with PLL, since the lock range specs say 4-8 Mhz, although 10 MHz does work reliably. 14+ MHz is too close to 1/16th of the VCO's free-running frequency for phase locking to be effective.

    -Phil
  • cbmeekscbmeeks Posts: 634
    edited 2015-04-29 18:05
    OK, so I'm trying the code located at http://wardyprojects.blogspot.com/2015/02/propeller-high-frequency-output-using.html

    Here is my code:
    CON
        _clkmode = xtal1 + pll16x      '80Mhz cpu speed
        _xinfreq = 5_000_000
       
    
    PUB main
        coginit(0, @ASM_ENTRY_POINT, 0)
    
    '----------------------------------------------
    DAT
                  org       0
                  
    ASM_ENTRY_POINT
                  or        dira, HF_PIN        'set pin as output
                  mov       FRQA, FREQ          'set up the desired frequency
                  mov       PHSA, #0            'set the phase back to 0 (optional)
                  mov       CTRA, CTRA_MODE     'begin output of the HF signal
    
                  waitpeq   $, #0 'sleep forever
    
    '----------------------------------------------
    HF_PIN        long      |< 23          'output on pin P23
    FREQ          long      12010943       '3.57954 MHz (NTSC)
    
    '                          CTRMD PLD          BPIN       APIN |
    CTRA_MODE     long      %0_00010_111_00000000_000000_000_001111
    
    
                  FIT
    

    But I get nothing. I am using the C3. When I run the following C code using the same pin, it works:
    #include "simpletools.h"
    
    
    int main() {
    
      square_wave(23, 0, 3579540);
    
      while(1) {
      }    
      
    }
    
    

    Any idea why the ASM code give me nothing on the scope?

    Thanks
  • jmgjmg Posts: 15,173
    edited 2015-04-29 18:30
    cbmeeks wrote: »
    Hmm, it appears that pushing the prop beyond 100 MHz is simply not a good idea. Especially if all I want to do is control a Z80. So, it would probably be better if I found another way.

    A more prop-zoned crystal value is 3.579 x 1.5 = 5.3693 MHz, & google finds a mention of running games/Z80's at that.
    It also finds that Digikey has stocks of the related 21.47727MHZ, (from 2 vendors even)

    A HC6323 would divide that by 4 for the Prop 5.3693 MHz, and then the PLL/24 gives Burst.and could also give Colour phase modulation to 24 steps in 360'
    Prop cannot divide by exactly 24 in HW without some SW help - it divides by 24+25/3e8
  • AribaAriba Posts: 2,690
    edited 2015-04-29 18:45
    cbmeeks wrote: »
    OK, so I'm trying the code located at http://wardyprojects.blogspot.com/2015/02/propeller-high-frequency-output-using.html

    Here is my code:
    CON
        _clkmode = xtal1 + pll16x      '80Mhz cpu speed
        _xinfreq = 5_000_000
       
    
    PUB main
        coginit(0, @ASM_ENTRY_POINT, 0)
    
    '----------------------------------------------
    DAT
                  org       0
                  
    ASM_ENTRY_POINT
                  or        dira, HF_PIN        'set pin as output
                  mov       FRQA, FREQ          'set up the desired frequency
                  mov       PHSA, #0            'set the phase back to 0 (optional)
                  mov       CTRA, CTRA_MODE     'begin output of the HF signal
    
                  waitpeq   $, #0 'sleep forever
    
    '----------------------------------------------
    HF_PIN        long      |< 23          'output on pin P23
    FREQ          long      12010943       '3.57954 MHz (NTSC)
    
    '                          CTRMD PLD          BPIN       APIN |
    CTRA_MODE     long      %0_00010_111_00000000_000000_000_001111
    
    
                  FIT
    

    But I get nothing. I am using the C3. When I run the following C code using the same pin, it works:
    #include "simpletools.h"
    
    
    int main() {
    
      square_wave(23, 0, 3579540);
    
      while(1) {
      }    
      
    }
    
    

    Any idea why the ASM code give me nothing on the scope?

    Thanks

    You need to set pin23 in the CTRA_MODE as APIN (now it's pin15):
    CTRA_MODE     long      %0_00010_111_00000000_000000_000_000000 + 23
    
    But it makes not much sense to do this in Assembler and waste a full cog just to setup a counter. The same in C (untested):
    #include <propeller.h>
      DIRA |= 1<<23;
      FRQA = 12010943;
      CTRA = (0x17<<23) + 23;
      while(1) ;
    

    Andy

    BTW: The Prop video generator shows colors fine (in NTSC mode) with a 80MHz clockfreq, so the jitter can not be a big probem.
  • potatoheadpotatohead Posts: 10,261
    edited 2015-04-29 18:59
    It's not for NTSC. PAL, on the other hand, hates it.
  • Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 23,514
    edited 2015-04-29 18:59
    jmg,

    The Prop's frqx registers don't act like dividers, but multipliers. So I think a crystal around 2/3 * N * NTSC, rather than one of 3/2 * N * NTSC would work better.

    -Phil
  • kwinnkwinn Posts: 8,697
    edited 2015-04-29 19:26
    You could always use an external oscillator with a 14.31818MHz xtal and FF to get 7.15....MHz, but that should not really be necessary. The tv or monitor will lock on the color burst frequency of the input signal during the horizontal synch time so it does not really matter if the frequency is not quite dead on. If you are using a VGA monitor this is a moot point since R, G, and B are separate signals.
  • jmgjmg Posts: 15,173
    edited 2015-04-29 19:29
    The Prop's frqx registers don't act like dividers, but multipliers. So I think a crystal around 2/3 * N * NTSC, rather than one of 3/2 * N * NTSC would work better.

    I visualize the Counters as adders, which is how they actually work.
    Using my numbers, I get (NTSC*3/2)*16/24 = 3579545, and the adder-effect SW correction is needed less than once per frame.

    However NSTC *2/3 is too low for the PLL Lock range, but 2 * NSTC *2/3 is ok, but when that is PLL'd x16 it gives
    21.333333 * NTSC, removing the option of phase-steps for Colour.

    This shifts the problem from low-frequency correction, to high frequency jitter, and it will generate jitter out by giving 21.21.22.21.21.22... Clocks - it may be that the PLL mode in counter block can filter that jitter well enough, but I would expect to still see some phase modulation at the 1.193MHz jitter rate. Maybe the OP can tolerate that ?
  • Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 23,514
    edited 2015-04-29 20:00
    jmg wrote:
    I visualize the Counters as adders, which is how they actually work.
    True, but my point was that frequency is proportional to frqx, not to 1/frqx. So to have only two conterminous one-bits, you're multiplying by a factor of 3 somewhere. And that means that the base (crystal) frequency should be a multiple of 1/3 the desired output frequency, not 3 / 2n times the base frequency.

    -Phil
  • ericballericball Posts: 774
    edited 2015-04-30 06:17
    Just remember that all of the existing TV demos use standard 5MHz crystals to generate 16x colorburst (57,272,727 Hz for NTSC, 70,937,900 Hz for PAL) which works fine in the majority of cases. So unless you have something which is very timing / frequency sensitive then it likely won't make a huge difference.
  • cbmeekscbmeeks Posts: 634
    edited 2015-04-30 08:27
    Thanks everyone for the great responses.

    I've certainly got some studying to do. Mainly just learning how the Z80 works and how the propeller work. Daunting sometimes.

    I'm more familiar with 6502 and Arduino.

    Thanks
  • lonesocklonesock Posts: 917
    edited 2015-04-30 09:37
    Sorry that this is in Spin, but here is some code I use to setup a pin's counter. It will use PLL mode if possible (>= 500 kHz), or fallback to the NCO mode if below that.
    VAR
      long frq_val, ctr_val  
    
    PUB setup_clock( Hz, pin ) : something | sc
      ' PLL is preferable to NCO for jitter, but only goes from 500 kHz to 128 MHz
      if Hz < 500_000
        ' NCO mode (easier, but possibly more jitter)
        ctr_val := constant( %00100 << 26 ) | pin
      else
        ' PLL mode, harder to set up but reduces jitter
        sc := %011 ' maps to /16, exactly offsetting the PLL's *16
        repeat while (Hz < 4_000_000) and (sc > 0)
          Hz <<= 1
          --sc
        repeat while (Hz > 8_000_000) and (sc < 7)
          Hz >>= 1
          ++sc
        ' set it up the counter, and match the integer period
        ctr_val := constant( %00010 << 26 ) | (sc << 23) | pin
      ' either way, now set up the frequency control
      frq_val := frac32( Hz, clkfreq )
        
    PUB frac32( num, den )
      repeat 32
        num += num
        result += result
        if num => den
          result |= 1
          num -= den
    
    Jonathan
Sign In or Register to comment.