Shop OBEX P1 Docs P2 Docs Learn Events
Can I send XINFREQ directly to a pin? — Parallax Forums

Can I send XINFREQ directly to a pin?

brianm734brianm734 Posts: 29
edited 2012-07-18 22:57 in Propeller 1
Hello,
I'm new to Spin. Is it possible to send the XINFREQ or CLKFREQ directly to a pin? So if I have a 5MHz crystal, I could get a 5MHz square wave output on a pin? I know I can have a cog synthesize this frequency and output it on a pin, but I'm interested in using clock sources other than a crystal, like a rubidium reference, or modelocked laser oscillator, and I need (along with a synthesized frequency) a pass-through clock signal with known phase delay.

Thanks

Comments

  • Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 23,514
    edited 2012-07-16 20:07
    If you have an external clock source driving XIN, why not just use it directly?

    -Phil
  • brianm734brianm734 Posts: 29
    edited 2012-07-16 20:32
    I guess I can, but it would be neat to just send it straight through to 1 pin, and then have a frequency divided and /or phase controlled signal on another pin controlled by the Spin code.

    Does anyone have experience with using an external XIN clock source, and then using the PLL and a cog to synthesize harmonics / sub-harmonics of the XIN frequency? How stable is the signal generated? What phase jitter can I expect?
    Thanks.
  • Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 23,514
    edited 2012-07-16 20:48
    You can certainly produce harmonics and sub-harmonics of the system clock on an output pin using one of the counters in NCO or PLL mode. Once you deviate from a power-of two multiple or sub-multiple of the system clock frequency, though, you will encounter phase jitter in the output. What frequencies were you hoping to generate?

    -Phil
  • brianm734brianm734 Posts: 29
    edited 2012-07-16 21:07
    I'm interested in sub-harmonics of xin only. Normally dividing down is not a problem in terms of phase jitter if the PLL is not used. Multiplying a frequency up is a problem since the phase noise multiplies by 20log(n), so the phase noise gets out of hand pretty quickly.

    It appears I can just set the _clkmode = xinput and use my external clock from DC to 80MHz (possibly up to 100MHz) without the PLL.

    I would like to do a simple 16 bit divider (divide by 1,2,3...65535) for my first project (other than the Propeller Education Kit projects). I would start with a simple 16 IO line parallel dip switch setup at first, and go from there.
    Thanks.
  • jmgjmg Posts: 15,193
    edited 2012-07-16 21:13
    brianm734 wrote: »
    What phase jitter can I expect?

    In the context of but I'm interested in using clock sources other than a crystal, like a rubidium reference, or modelocked laser oscillator probably more than you would like.
    This will depend on the PLL jitter, and also what else the COGs are doing and driving & if the Video PLL is active too...

    You are probably best measuring it.

    You can get a buffered x1 Output on XOUT pin, if you configure as a Crystal but still drive externally.
  • Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 23,514
    edited 2012-07-16 21:17
    NCO clock generation in the Prop is not done on a divide-by basis. It's done by selecting an adder (frqa) which gets added on each system clock tick to an accumulator (phsa), whose high-order bit determines the output state. You can "divide" by 2, 4, 8, 16, ..., without encountering phase jitter. But once you deviate from those values, jitter becomes an issue.

    -Phil
  • brianm734brianm734 Posts: 29
    edited 2012-07-16 22:06
    I thought "The FRQA register contains the value that is accumulated into the [FONT=Parallax,Parallax][FONT=Parallax,Parallax]PHSA [/FONT][/FONT]register.",
    [FONT=Times New Roman,Times New Roman][FONT=Times New Roman,Times New Roman]and "PHSA and [/FONT][/FONT][FONT=Parallax,Parallax][FONT=Parallax,Parallax]PHSB [/FONT][/FONT][FONT=Times New Roman,Times New Roman][FONT=Times New Roman,Times New Roman]can be read/written like other registers or pre-defined variables." (From Propeller manual)
    [/FONT][/FONT]So, if _clkmode = xinput , and _xinfreq = 25_000_000 (for example), then I can set PHSA := clkfreq , and since clkfreq now equals xinput. I should be able to use, copy, and modify the copy of the FRQA register value to anything I need it to be, correct?

    I am new at this, so forgive any dumb questions.
  • Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 23,514
    edited 2012-07-16 22:37
    phsa is an accumulator that's constantly being incremented by the value in frqa. The higher the latter value is, the more often the high-order bit of phsa will toggle, and hence, the higher its output frequency. For example, with an 80 MHz clock, setting frqa to $8000_0000 will cause the high-order bit to toggle on every other cycle and will give you a 40 MHz output. Setting it to $4000_0000, you get a 20 MHz output, and so on. When frqa is not a power of two, the average frequency output from the counter will be what you might expect, but there will be phase jitter manifest as spurious sidebands on either side of the fundamental (and its odd harmonics, since it's a square wave). This is because the high-order bit of phsa does not toggle with exactly the same period in each clock cycle under these circumstances, as it would if frqa were a power of two.

    -Phil
  • brianm734brianm734 Posts: 29
    edited 2012-07-17 15:23
    Ok, so I can't do what I want directly to the xin signal. But I could send my clock signal into my xin and one of the IO pins, and then do my counting scheme on the signal on that IO pin . Perhaps I can do divide-by-n (2,3,4,5.... ) in that way. Or maybe I could do something as simple as:
    repeat
    outa[pin] := 1
    waitcnt(clkfreq/wordvariable + cnt)
    outa[pin] := 0
    waitcnt(clkfreq/wordvariable + cnt)

    Remember - I'm new at this.

    Right now I'm using four 74LS163's and some NAND gates to do my 16bit divider. This is trivially implemented in an FPGA, but I would like to see if it possible to do in Spin on the Prop.
  • Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 23,514
    edited 2012-07-17 16:41
    No, the Prop's counters do not have a divide-by-n mode, even for input on a pin. You have to use either NCO mode or NCO driving a PLL. Of course, you could do the division in software and avoid the jitter that way. But Spin is too slow; you will have to use PASM. Dividing 5 MHz by two, for example, would amount to four instructions per phase:
    loop          or        outa,pinmask
                  nop
                  nop
                  nop
                  andn      outa,pinmask
                  nop
                  nop
                  jmp       #loop
    
    pinmask       long      1 << PIN_NUMBER
    

    That would be the worst case for an integer divide.

    In any event, you don't need to involve an external pin. Just use the system clock as your reference.

    -Phil
  • jmgjmg Posts: 15,193
    edited 2012-07-17 17:46
    brianm734 wrote: »
    ..Or maybe I could do something as simple as:
    repeat
    outa[pin] := 1
    waitcnt(clkfreq/wordvariable + cnt)
    outa[pin] := 0
    waitcnt(clkfreq/wordvariable + cnt)

    Yes, that would work, but as Phil cautions, it has a software-speed determined frequency ceiling.

    There is another thread on precise timing that may give some info :

    http://forums.parallax.com/showthread.php?138461-200kHz-5kHz-pulse-output

    The adder topology of the Prop counter has high precision, but it does have a jitter/rounding error.

    Because you can access both registers, you can do some software fixups. I think I've seen examples on here, but forget the headings.

    I think you may be able to use two counters, one in NCO mode, and another to manage the creep-correction.

    If we take an example, of 80MHz / 20,000, that is going to need an ideal adder of
    2^32/20000 = 214748.3648
    but you can add only integers, so get
    2^32/214748 = 20000.0339747 adds per overflow, or a Fo long term average of 3999.993205070
    ie most cycles will be 80e6/20000, but every ~29 output cycles, one more add will be needed, so instead of the 4000.00Hz,
    that cycle will be 3999.80000999Hz, for a long term average 3999.993205070

    The creep value is
    2^32-(20000 * 214748) = 7296 - this is how much the adder is 'short' by, and this drives the occasional /20001
    7296/214748 = 0.0339747 1/ans = 29.433662280 output cycles repeat rate.

    If you can manually add 7296 counts per output cycle, (and you have 29 cycles to do this, for this example) then you can correct the creep and you will get 250us outputs.
    If a second counter collects cycles, you can wait for (say) 10 cycles, and then add 72960 ( minus a small delay fix, plus whatever add's would have occurred in that time).

    At the other end of the scale, look at /5, this is close, but gives average of
    80e6*round(2^32/5)/2^32 = 15999999.99627Hz
    2^32-5*round(2^32/5) = 1, so you need to add one rarely, to avoid the rare case where one /6 occurs.

    Hopefully this can reduce to a general case

    Edit : I had time for a deeper search and there are some caveats in 'correcting the adder'
    - examples
    http://forums.parallax.com/showthread.php?105652-Read-modify-write-on-PHSx-not-supposed-to-work-but-does.&p=742808&viewfull=1#post742808

    - but because this adder-fix is not needed that often, in a time sense, (and not needed at all in the 2^N cases) I think this avoids the Ceiling issues of a software-paced divide. You do need a second counter to track how many cycles have gone, to pace your correction. Not trivial.
  • brianm734brianm734 Posts: 29
    edited 2012-07-17 18:53
    I'll just use an FPGA. It's easier. Thanks guys.
  • jmgjmg Posts: 15,193
    edited 2012-07-17 18:56
    brianm734 wrote: »
    I'll just use an FPGA. It's easier. Thanks guys.

    Or a CPLD ?
    This might be easier in a Prop 2...
    If you want general frequency control, look at the Silabs Si5351A
  • brianm734brianm734 Posts: 29
    edited 2012-07-17 19:20
    jmg wrote: »
    Or a CPLD ?
    This might be easier in a Prop 2...
    If you want general frequency control, look at the Silabs Si5351A


    That's not quite what I need. My clock source is a modelocked laser. It's frequency drifts with temperature, and I have no control of its phase. So I need two synchronous pre-settable binary counters in series (like On-Semi / Micrel SY10E016), or a DDS (like Analog Devices AD9851) with my laser's photo-diode signal as the master clock. In this case I could only select exact sub-harmonics of the master clock because the divided master clock rate drives my acousto-optic modulator, which picks optical pulses out of my laser pulse train. The DDS signal phase can be controlled to to allow AOM RF to optical timing adjustment.

    The PLL's in the Prop won't work in this case because my clock frequency is too high to use with the Prop PLL. I can't divide the laser clock down first, because it would limit my maximum optical rep-rate.

    Anyway, I can control some other device with the Propeller to get the job done.

    Thanks.
  • jmgjmg Posts: 15,193
    edited 2012-07-17 19:32
    brianm734 wrote: »
    Anyway, I can control some other device with the Propeller to get the job done.

    Probably a good idea, to at least get something working.
    If you are all done, and find you have a spare COG, someone on here may have worked out a general case (or remembered a link to exactly the right answer)

    - the link I've added above show Phil was working on similar 'live adder adjustments' in 2008.
  • Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 23,514
    edited 2012-07-17 19:33
    As a UM alum and loyal Parallaxian, I feel it my duty to prevent the emigration to the FPGA darkside, when it's so easy with a Propeller. Although the Prop's counters won't do what you want, as pointed out above, here's a program that will, using a PASM loop:
    CON
    
      _clkmode      = xtal1 + pll16x
      _xinfreq      = 5_000_000
    
      PIN_NUMBER    = 1
      N             = 10             'N must be greater than 2.  
    
    PUB start
    
      n0 := (N - 2) * 2
      cognew(@div_by_n, 0)
    
    DAT
    
    div_by_n      or        dira,pinmask
    
    loop          or        outa,pinmask
                  mov       acc,n0
                  djnz      acc,#$
                  nop
                  andn      outa,pinmask
                  mov       acc,n0
                  djnz      acc,#$
                  jmp       #loop
    
    pinmask       long      1 << PIN_NUMBER
    n0            long      0-0
    
    acc           res       1
    

    For N == 2, use the example code I gave above.

    -Phil
  • jmgjmg Posts: 15,193
    edited 2012-07-17 19:48
    Although the Prop's counters won't do what you want, as pointed out above, here's a program that will, using a PASM loop:

    The PASM loop uses the PLL, and divides after a x16. That may be enough ?

    Did you get any further with the example I found from you ~ 2008, of doing :
    (renamed for clarity)

    add frqa, NudgeValue_Div4 ' 4 adds will occur in the time of this opcode
    sub frqa, NudgeValue_Div4 ' back to dominant adder value

    I think such an approach should allow external clock to 80MHz, divide by 3,5,7.. as well as the 2^N cases HW supported.
    So 40MHz, 26666666.66' MHz , 20MHz, 16MHz, 10MHz, 13333333.333'MHz , 11428571.428MHz etc ?

    If there is no general case, then perhaps a SW loop for large N, (>= 48) and Sw assisted HW for low values of N ?
  • brianm734brianm734 Posts: 29
    edited 2012-07-17 20:05
    Very cool Phil. I will need to read more about PASM to figure out how it works, but I tried it, and it works very well. I tried it with the 5MHz crystal (as you wrote it) and noticed the divided xin frequency on pin 1 will change when I change the PLL setting to 1,2,4,or 8. Does this mean I could not just use _clkmode = xinput and send my 25MHz clock in without requiring the PLL?

    Thanks.
  • Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 23,514
    edited 2012-07-17 20:05
    jmg,

    That example was meant more for phase shifting/modulation than for frequency setting. The example I gave above will divide the system clock/16 by any integer from 3 on up. (I'm sure Kuroneko will be able to generalize it to 2 on up. :) ) Moreover, the video hardware does accommodate divide-by-n-type timings through vscl, and it could be used to advantage for higher fundamental frequencies than just _XINFREQ.

    -Phil
  • Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 23,514
    edited 2012-07-17 20:11
    brianm734 wrote:
    Does this mean I could not just use _clkmode = xinput and send my 25MHz clock in without requiring the PLL?
    Yes, you could do that. Remember, though, that the system clock in that case, would be 25 MHz. So the PASM instruction rate would only be 6.25 MHz. That means that the highest frequency obtainable with that program would be about 520 kHz.

    Is the PLL something that you need to avoid for some reason?

    -Phil
  • kuronekokuroneko Posts: 3,623
    edited 2012-07-17 20:13
    @PhiPi: Are you referring to this thread [thread=133741][FYI] clkfreq/2n[/thread]? Last post has the rules for dividers 2..27, after that waitcnt is easier.
  • Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 23,514
    edited 2012-07-17 20:18
    I'd already forgotten about that one, but yeah: that's the idea!

    Cripes, there's a lot of uncatalogued knowledge on this forum!

    -Phil
  • jmgjmg Posts: 15,193
    edited 2012-07-17 20:26
    kuroneko wrote: »
    @PhiPi: Are you referring to this thread [thread=133741][FYI] clkfreq/2n[/thread]? Last post has the rules for dividers 2..27, after that waitcnt is easier.

    Ah.. That was one I was trying to find...
  • brianm734brianm734 Posts: 29
    edited 2012-07-17 20:28
    "Is the PLL something that you need to avoid for some reason?" - Phil


    I don't really need to avoid the Prop PLL other than the Prop data sheet says the maximum xin frequency is "4-8MHz" when the PLL is used. I imagine I can push that to 10 or 12MHz, but I think 25MHz would be too high. Otherwise I would just set PLL4X, and my clkfreq would be 100MHz.

    Thanks
  • Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 23,514
    edited 2012-07-17 20:44
    Yeah, 10 MHz works okay, 12 would probably work, too. But the VCO's open-loop frequency is about 14-some MHz * 16 ~ 224 MHz, so 25 driving it would be out of the question.

    -Phil
  • jmgjmg Posts: 15,193
    edited 2012-07-18 01:28
    That example was meant more for phase shifting/modulation than for frequency setting.

    Yes, but it can also be used to remove the creep offset from the Adder.

    Result is quite similar to the looping-re-load of PHSA that kuroneko outlines here :

    http://forums.parallax.com/showthread.php?133741-FYI-clkfreq-2n&p=1027071&viewfull=1#post1027071

    That also removes phase creep, by virtue of the hard reset per loop, but because the FRQx adder fix in your example does not need to be applied at high speeds, you effectively get part of a COG back - ie it uses less resource.

    To some users, that may be important.

    At low divide ratios, because the larger adder values can be quite close to ideal, it takes quite a while for the error phase to hit the bonus-swallow case.
    The first /2../27 for example, I find no creep times under 2.440 seconds.
    Even up to /512, there is no creep time under ~ 111ms, and up to /100, not under 559ms.

    As in the other threads, usually you flip to software waits at lower output rates, but as there is now 'room for other code' that cross-over may not be the around /27 of a tight PASM loop.

    I wonder what the cycle count of this in Spin is ?
    add frqa, NudgeValue_Div4 ' 4 adds will occur in the time of this opcode
    sub frqa, NudgeValue_Div4 ' back to dominant adder value
  • pik33pik33 Posts: 2,413
    edited 2012-07-18 09:14
    brianm734 wrote: »
    "Is the PLL something that you need to avoid for some reason?" - Phil


    I don't really need to avoid the Prop PLL other than the Prop data sheet says the maximum xin frequency is "4-8MHz" when the PLL is used. I imagine I can push that to 10 or 12MHz, but I think 25MHz would be too high. Otherwise I would just set PLL4X, and my clkfreq would be 100MHz.

    Thanks

    It works (in my experiments) even with 14 MHz quartz. PLL was 14x16=224 MHz and the Propeller was overclocked to 112 MHz. And you can find my experimenal audio driver which uses pll @ 224 MHz, too, with non-overclocked Propeller

    I tried 16 MHz with no success. 256MHz was too much for Propeller's PLL

    Xin=25 and clkfreq=100 will not work, because xin is as default multiplied by 16, and then divided by 4. So when xin=25, pll will try to work @ 400 MHz, which is impossible. Its real maximum available frequency is something about 240 MHz.
  • pik33pik33 Posts: 2,413
    edited 2012-07-18 22:57
    PLL multiplier is always x16. There is a divider after this 16x multiplier to get lower multiply coefficient.

    This limits crystal frequency to 14..15 MHz if you want to use xin+pll as a clock source. With higher frequency crystals you have to switch pll off.

    And because of this, combination like this:
    _clkmode=xtal1+pll4x
    _clkfreq = 80_000_000
    
    

    using 20 MHz crystal, will not work, because pll4x is in reality pll16x/4 and pll cannot run at 320 MHz.
Sign In or Register to comment.