Shop OBEX P1 Docs P2 Docs Learn Events
Nanosecond frequency for an output pin — Parallax Forums

Nanosecond frequency for an output pin

Jeffrey KaneJeffrey Kane Posts: 48
edited 2013-02-22 18:36 in General Discussion
Hello,

I am new to this, but i have an application that needs a frequency of 30 ns (nanoseconds), your viewport monitor seems to have the ability to get to 50 ns, , but the best i can get is 200 microseconds, do you have an example of code that would generate a frequency of 30ns? Sorry about the unsolved status, i'm sure this has been addressed before.

regards

Jeff :smile:

Comments

  • tonyp12tonyp12 Posts: 1,951
    edited 2013-01-31 08:48
    A square wave Freq?
    With a 5mhz crystal, it's easy to create a 12.5ns high with a 12.5 ns low by using one of cogs counter.
    Is that good?, if not could go with a 4mhz crystal for 15.6ns+15.6ns

    Though you could adjust the values in software, getting no jitter will be harder.
  • Mike GreenMike Green Posts: 23,101
    edited 2013-01-31 09:07
    With an 80MHz system clock, the granularity of the Propeller's clock is 12.5ns. If you use a 4.167MHz crystal instead (custom ordered), you can get a system clock granularity of 15ns. The counters in each cog can be set up to produce a pulse on an output pin that's a submultiple of the clock. One of these counters could easily divide the system clock by 2 to produce the 30ns pulses you need. The 50ns timing for ViewPort is based on the 80MHz system clock. Each Propeller instruction takes 4 system clock cycles to execute and 50ns = 4 x 12.5ns.

    Producing pulses this short is problematic with the Propeller and other microcontrollers. You're trying to produce pulses on the order of the system clock time. You need to adjust the system clock frequency to be the same as your desired pulse frequency or related by an integer factor. Once you start dealing with custom crystal frequencies, you might as well just make an oscillator / counter to produce exactly what you need.
  • Jeffrey KaneJeffrey Kane Posts: 48
    edited 2013-01-31 09:22
    I have the 5Mhz crystal attachedl, my code is extremely simple, probably why it doesn't work,

    CON
    _clkmode = xtal1 + pll16x
    _clkfreq = 80_000_000

    PUB main|hz,frame[6400]
    dira[LEDs_START..LEDs_END]~~ ' Set entire pin group to output
    repeat ' Endless loop
    ! outa[LEDs_START..LEDs_END] ' Change the state of pin group
    ' waitcnt(clkfreq /1000 'should give 1 millisecond
    ' waitcnt(clkfreq /1000000 + cnt) 'should give 1 microsecond
    waitcnt(clkfreq /10000000 + cnt) 'should give 100 nanoseconds

    so i used a scope and the best i get off the pin is about 200 microseconds

    regards

    Jeff
  • Mike GreenMike Green Posts: 23,101
    edited 2013-01-31 09:50
    First of all ... Spin is an interpreted language. It compiles into instructions for a stack-oriented instruction set that's interpreted by an interpreter stored in the on-chip ROM. The only way you're going to get execution speeds on the order of hundreds of nanoseconds is to write code in assembly language. With a 5MHz crystal and 80MHz system clock frequency, you get one instruction executing in 50ns (4 clock cycles). It takes several instructions to do anything useful, so the minimum generated pulse timing would be 5MHz (a 200ns cycle). The two cog counters (in each cog) can count at the system clock frequency and, using a built-in phase locked loop, can count at twice that speed, although may have a little (or a lot of) jitter depending on the numerical relationship between the desired frequency and the system clock frequency. AN001 goes into detail on the use of the counters. If you use the counters, you don't have to use assembly language since the counter control registers are accessible from Spin.
  • HannoHanno Posts: 1,130
    edited 2013-01-31 11:00
    Here is the code for one of ViewPort's sample tutorials. It uses the "synth" object to output high frequency square waves to a pin. You select the frequency using a graphical knob within ViewPort. The QuickSample object samples all 32 io pins every single clock cycle- 12.5 ns with the standard clock settings. The data is then displayed in real time on a simulated LSA screen with configurable timescale/triggers/measuring tools. The code includes several "configuration strings" which are used to configure ViewPort. For your use you can set the frequency to your desired value in the code.

    CON
    _clkmode = xtal1 + pll16x
    _xinfreq = 5_000_000
    OBJ
    vp : "Conduit" 'transfers data to/from PC
    synth : "Synth"
    qs : "QuickSample" 'samples INA up to 80Mhz
    pub demoADC|freq,frame[1600] 'frame stores 1600 samples+configuration
    vp.register(qs.sampleINA(@frame,4 )) 'sample INA with 4 cogs up to 80Mhz
    vp.config(string("var:io(bits=[data[0],30tx,31rx]),freq(min=1,max=10000,unit=kHz),adc(min=-5,max=5,decode=io[0..0])"))
    vp.config(string("spectrum:logx=false,bgnd=yellow"))
    vp.config(string("dso:view=adc,timescale=200ns"))
    vp.config(string("lsa:view=io,timescale=200ns"))
    vp.config(string("edit:freq(default=2000,mode=dial)"))
    vp.config(string("start:analog"))
    vp.share(@freq,@freq)
    repeat
    synth.Synth("A",0, 1_000*freq)

    Hanno
  • frank freedmanfrank freedman Posts: 1,983
    edited 2013-01-31 15:59
    Hello,

    I am new to this, but i have an application that needs a frequency of 30 ns (nanoseconds), your viewport monitor seems to have the ability to get to 50 ns, , but the best i can get is 200 microseconds, do you have an example of code that would generate a frequency of 30ns? Sorry about the unsolved status, i'm sure this has been addressed before.

    regards

    Jeff :smile:

    You could use assembly or spin to set up the counter output freq and output pin to get Fclk/2 or about 25.0ns as a fixed free running output. Then your code could change the counter parameters if a different freq was needed. Somewhere I have read you can clock over 100mhz using the pll function, but not guaranteed. If wrong, someone will be sure to put us right on this...... I use the counters for ADC/DAC timebase generator.

    Frank.
  • Jeffrey KaneJeffrey Kane Posts: 48
    edited 2013-01-31 17:37
    well, I still have to look at the counter but there was some code that got me to 100ns

    'Propeller Programming Tutorial (from Propeller Manual Chapter 3)
    {{FastestLed - was Output10.spin}}
    '' 20080517 Ray Rodrick "Cluso99"
    '' Pulses a pin at 100nS (5MHz xtal)
    '' PulsePin_100nS.spin
    CON
    _clkmode = xtal1 + pll16x
    _xinfreq = 5_000_000
    VAR
    long Stack[9] 'stack space for new cog
    byte Cog 'hold ID of cog in use, if any
    PUB Main
    Start(3) 'flash LED on Pin (0-31)

    PUB Start(Pin): Success
    {{Start new toggling process in a new cog; return TRUE if successful.}}
    Stop
    ' Success := (Cog := cognew(FastestLed,Pin), @Stack) + 1)
    Success := cog := cognew(@entry, @Pin) + 1
    PUB Stop
    {{Stop toggling process, if any.}}
    if Cog
    cogstop(Cog~ -1)
    DAT
    org
    entry rdlong :pin,par 'get pin no. (0-31)
    mov :pinmask,#1
    shl :pinmask,:pin
    mov dira, :pinmask
    :wloop xor outa, :pinmask
    jmp #:wloop
    :pin res
    :pinmask res

    from my understanding, limited at best, each instruction takes 4 clocks, 50 ns so the loop uses two instructions therefore 100ns. I'll continue since i need to get to 25 ns square wave.

    note: I used a scope on it and it is a very strange signal. the 100ns was correct but i expected a clean square wave, 0 to 3.3 volts but this was different, in the area where the voltage is usually a straight line this one had a lot of variance. probably +/- 1/4 volts, produced a rather fuzzy line. .

    I was wondering if it would be easier to simply build a clock pulse generator circuit, since the clock is permanent and does not vary, the main work of this project is sending signal for varing control of a device (data channels) vs handling clock data, and to get where i think i need to go 25ns, i think i have to commit two cogs to the clock processing.
  • jmgjmg Posts: 15,173
    edited 2013-01-31 22:18
    Hello,
    I am new to this, but i have an application that needs a frequency of 30 ns (nanoseconds),

    That is a strange spec that asks for a frequency of 30 ns - what exactly is it that, needs this ?
  • Mike GreenMike Green Posts: 23,101
    edited 2013-01-31 22:27
    You would be better off building or buying a clock at the frequency you want.
  • GadgetmanGadgetman Posts: 2,436
    edited 2013-02-01 00:49
    What's the resolution of your scope?

    Analogs need a 10x speed to properly display a given square wave.
    (A square wave consists of the original frequency and a whole lot of harmonics. Bl***dy noisy signal, really)
  • LoopyBytelooseLoopyByteloose Posts: 12,537
    edited 2013-02-01 01:08
    The GreenArrays GA144 Forth chip might do it nicely. Schmartboard has them with a board for $34.95.
    Admittedly, this is an odd approach with its own learning curve, but it is possible.

    http://www.schmartboard.com/index.asp?page=products_csp&id=532
  • Jeffrey KaneJeffrey Kane Posts: 48
    edited 2013-02-01 04:51
    Gadgetman wrote: »
    What's the resolution of your scope?

    Analogs need a 10x speed to properly display a given square wave.
    (A square wave consists of the original frequency and a whole lot of harmonics. Bl***dy noisy signal, really)

    old, dusty scope, i have a new logic analyzer coming in, i'll check it again when it arrives. i'll implement the use of the counters today, see what i get.

    the project needs, 30ns clock, 200 ns data lines (2), three 1 ms pulses (1 as a reference for data, 2 for hor and vert sync) some 3.3 power and ground.

    i might end up with 2 propeller processors on the board, one will do clock related work, one will do data. I do alot of distributed work with multiprocessors, in the old days we used snoop line to interface between both processors, to sync the processors together, although there are other ways to do it. you could set up a small data channel with a few io pins. but i'll figure that out later.

    everyone has been very helpful.

    regards

    Jeff Kane
  • Jeffrey KaneJeffrey Kane Posts: 48
    edited 2013-02-02 07:14
    Hello,

    The counters work as designed, interesting, a very powerful, flexable processor, Thank you for directing me in the correct direction.

    This thread can be posted "solved", not sure I do this or the forum administrator.

    regards

    Jeff Kane
  • Ding-BattyDing-Batty Posts: 302
    edited 2013-02-05 13:21
    This thread can be posted "solved", not sure I do this or the forum administrator.

    I believe you can just go to the first post in the thread, which you created, and edit it -- then you should be able to change the status to "solved".
  • jmgjmg Posts: 15,173
    edited 2013-02-05 13:58
    The counters work as designed, interesting, a very powerful, flexable processor, Thank you for directing me in the correct direction.

    You could also summarize what finally worked - ie what frequencies you created, with what precision and jitter, so that others reading this later can learn more ?
  • Jeffrey KaneJeffrey Kane Posts: 48
    edited 2013-02-22 06:25
    jmg wrote: »
    You could also summarize what finally worked - ie what frequencies you created, with what precision and jitter, so that others reading this later can learn more ?

    The work i am doing is all in the 25ns to 500us range, I'm stil working with the counters and perhaps a higher frequency clock. 6-8mhz, the only issue i am having currently is that viewport does not seem to accurately record at these speeds, so i have to go to aTLA5202 scope to validate the timings which slows down the testing.

    vp.config(string("var:io(bits=[cntr[16..17],30tx,31rx]),counter(decode=io[16..17])"))
    vp.config(string("lsa:view=io,timescale=1ms,trigger=io[16]r"))
    vp.config(string("dso:view=counter,timescale=1ms/div"))
    vp.config(string("start:lsa"))

    but I do have one question on the resolution of the clock, although the clock runs at say, 80,000,000 (external 5mhz *16) which gives me a resolution of 0.0000000125, 12.5 ns, so each clock change adds 12.5, therfore i can get 25, 37.5, 50 ns and so on, but what if i need 33.3 ns? is there a way to slice the clock, or offset it, something like phases.

    currently I can create an accurate 25ns, 200ns, 500ns 100us, and 200us with spin for the microsecond work and assembler for ns work.

    for example:

    cognew(@Toggle, @swStack[256]) ' timing markerscognew(@Toggle, @swStack[256]) ' timing markers

    DAT
    {Toggle P16}
    org 0 'Begin at Cog RAM addr 0
    Toggle mov dira, Pin16_17 'Set Pin to output
    mov outa, Pin16_17 'Toggle Pin to high
    mov Time, cnt 'Calculate delay time
    add Time, #9 'Set minimum delay here
    :loop waitcnt Time, Delay2 'Wait 125 us
    xor outa, Pin16 'Toggle Pin
    waitcnt Time, Delay1 'Wait 200 us
    xor outa, Pin16 'Toggle Pin
    waitcnt Time, Delay3 'Wait 100 us
    xor outa, Pin17 'Toggle Pin
    waitcnt Time, Delay1 'Wait 200 us
    xor outa, Pin17 'Toggle Pin
    waitcnt Time, Delay2 'Wait 125 us
    jmp #:loop 'Loop endlessly

    Pin16_17 long %00000000_00000011_00000000_00000000
    Pin16 long %00000000_00000001_00000000_00000000
    Pin17 long %00000000_00000010_00000000_00000000
    Delay1 long 16_000 'Clock cycles to delay 200 us
    Delay2 long 10_000 'Clock cycles to wait 250 us
    Delay3 long 8_000 'Clock cycles to wait 100 us
    Time res 1 'System Counter Workspace

    it should look like

    500us 200us 100us 200us

    pin 16
    |_____|

    pin 17
    |______|

    regards

    Jeff
  • Mike GreenMike Green Posts: 23,101
    edited 2013-02-22 07:38
    "12.5ns" ... "what if i need 33.3ns?"

    If you only needed 33.3ns or a few other discrete frequencies, you could have multiple external clocks for the Propeller and some kind of multiplexor. The Propeller could switch to its internal clock long enough to change its external clock and allow that to stabilize, then switch to that.

    If you need more variability than a few base timings and their multiples, you're not going to be able to do it with the Propeller. You'll need a well-designed digital signal generator, possibly with the Propeller acting as a controller.
  • Jeffrey KaneJeffrey Kane Posts: 48
    edited 2013-02-22 08:02
    Mike Green wrote: »
    "12.5ns" ... "what if i need 33.3ns?"

    If you only needed 33.3ns or a few other discrete frequencies, you could have multiple external clocks for the Propeller and some kind of multiplexor. The Propeller could switch to its internal clock long enough to change its external clock and allow that to stabilize, then switch to that.

    If you need more variability than a few base timings and their multiples, you're not going to be able to do it with the Propeller. You'll need a well-designed digital signal generator, possibly with the Propeller acting as a controller.

    do you have any suggestions (digital signal generator), I think i was heading that way, i have about 10 signals, mostly clocking, but fairly defined, what i am really doing is sending data, which is usually between 1ms and 500us, and it is variable, so the really task is the data, not the clocks, so moving it somewhere else if fine by me, and letting the propeller only deal with the control of the discrete signals and the data signals.

    regards

    Jeff
  • tonyp12tonyp12 Posts: 1,951
    edited 2013-02-22 08:59
    >currently I can create an accurate 25ns, 200ns, 500ns 100us, and 200us with spin for the microsecond work and assembler for ns work.
    Are you taking in account the setup overhead every time you wait, better use interval waits instead.
  • jmgjmg Posts: 15,173
    edited 2013-02-22 14:27
    what i am really doing is sending data, which is usually between 1ms and 500us

    What granularity and precision do you actually need.?
    I have seen serial protocols that reduce the number of edges, by sending defined pulse widths and then they measure the widths to so many bits of precision. (eg 16 width steps can encode 4 bits etc )
  • HumanoidoHumanoido Posts: 5,770
    edited 2013-02-22 18:36
Sign In or Register to comment.