Shop OBEX P1 Docs P2 Docs Learn Events
*Exact* µs output timing not possible with Propeller? Edit- Is possible! — Parallax Forums

*Exact* µs output timing not possible with Propeller? Edit- Is possible!

bill190bill190 Posts: 769
edited 2010-05-05 02:27 in Propeller 1
Is it correct that due to the nature of the Propeller hub, that *exact* µs (microsecond) timing is not possible with an output?

And there no way to·issue any instructions to the hub to alter what it does in any way? Say to stop and give exclusive I/O access to just one cog?

For example the following assembly language code is used·for a non-Parallax processor to generate a 38KHz carrier for a Sony·IR transmitter. The first half of the following code being on/mark and the second half being off/space...

IR_pulse···
··MOVWF·count··;· Pulses the IR led at 38KHz
irloop··BSF·IR_PORT,·IR_Out
··NOP···;
··NOP···;
··NOP···;
··NOP···;
··NOP···;
··NOP···;
··NOP···;
··BCF·IR_PORT,·IR_Out
··NOP···;
··NOP···;
··NOP···;
··NOP···;
··NOP···;
··NOP···;
··NOP···;
··NOP···;
··NOP···;
··NOP···;
··NOP
··NOP
··NOP···;
··NOP···;
··DECFSZ·count,F
··GOTO ·irloop
··RETLW·0

NO_pulse···
··MOVWF·count··;· Doesn't pulse the IR led
irloop2··BCF·IR_PORT,·IR_Out
··NOP···;
··NOP···;
··NOP···;
··NOP···;
··NOP···;
··NOP···;
··NOP···;
··NOP···;
··NOP···;
··NOP···;
··NOP···;
··BCF·IR_PORT,·IR_Out
··NOP···;
··NOP···;
··NOP···;
··NOP···;
··NOP···;
··NOP···;
··NOP
··NOP
··NOP···;
··NOP···;
··DECFSZ·count,F
··GOTO ·irloop2
··RETLW·0

...then ones or zeros are transmitted with the following code which calls the above...

TX_One··movlw·d'46'
··call·IR_pulse
··movlw·d'23'
··call·NO_pulse
··retlw·0x00

TX_Zero··movlw·d'23'
··call·IR_pulse
··movlw·d'23'
··call·NO_pulse
··retlw·0x00

...and from my reading of the Propeller documentation, I see that this would work in a cog, however there would be an unknown wait for the hub to come around correct?


Post Edited (bill190) : 5/4/2010 11:53:59 PM GMT

Comments

  • Graham StablerGraham Stabler Posts: 2,510
    edited 2010-05-04 08:49
    Access to IO does not go through the hub, all cogs can access PORTA all of the time directly. All the outa's from the cogs are ORed and the output of that is sent to the pins.

    You can also create carriers like this using the counters, check out the synth object.

    Graham
  • heaterheater Posts: 3,370
    edited 2010-05-04 08:50
    @bill190:

    "And there no way to issue any instructions to the hub to alter what it does in any way? Say to stop and give exclusive I/O access to just one cog?"

    No. The HUB access mechanism churns around continuously and there is no way to influence it. This is for the best as it ensures deterministic timing. Having the possibility of a COG to hog the HUB would starve the others and probably cause it to be impossible to mix and match objects so easily as we do now.

    Given that it is possible to transmit and receive serial data streams at 5MHz, 10MHz and above using just software "bit banging" of pins I'm sure what you want to do is not difficult. Then you can look into the timers for more oomph!

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    For me, the past is not over yet.

    Post Edited (heater) : 5/4/2010 8:59:19 AM GMT
  • BeanBean Posts: 8,129
    edited 2010-05-04 12:56
    The "wait for the hub to come around" is not random. After the first hub access it is pre-determined. I "think" it is every 16 clocks.

    And as Graham has mentioned, I/O does not go through the hub anyway.

    Bean

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    Use BASIC on the Propeller with the speed of assembly language.
    PropBASIC thread http://forums.parallax.com/showthread.php?p=867134

    March 2010 Nuts and Volts article·http://www.parallax.com/Portals/0/Downloads/docs/cols/nv/prop/col/nvp5.pdf
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    There are two rules in life:
    · 1) Never divulge all information
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    If you choose not to decide, you still have made a choice. [noparse][[/noparse]RUSH - Freewill]
  • RaymanRayman Posts: 14,887
    edited 2010-05-04 13:00
    Here's some more info on us level timing using the Prop:

    http://www.rayslogic.com/propeller/PulseGen.htm

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    My Prop Info&Apps: ·http://www.rayslogic.com/propeller/propeller.htm

    My Prop Products:· http://www.rayslogic.com/Propeller/Products/Products.htm
  • Mike GreenMike Green Posts: 23,101
    edited 2010-05-04 13:52
    Exact us timing is done all the time ... to the resolution of the system clock (12.5ns at 80MHz). The various video drivers are prime examples of this. You have to program in assembly and you have to count instructions (as in your non-Propeller example). A lot of other I/O drivers are not as exacting because they don't have to be. You can program timing sensitive-sensitive stuff in Spin, but not to that resolution because of the hard-to-predict overhead of the Spin interpreter. It's not that it's not possible, just that the timing analysis of the Spin interpreter code hasn't been done.
  • Cluso99Cluso99 Posts: 18,069
    edited 2010-05-04 14:44
    As has been said, you can get accuracy down to 12.5ns with an 80 MHz clock (5MHz xtal) although overclocking to 100MHz and beyond is done by a number of us.

    The easiest way to do what you require is to use a counter in a cog. I am sure there would be an IR object in the OBEX that already does this.

    However, if you want to do this in assembly in a cog, you can also do this. Almost all instructions are 4 clocks which is 50ns. You could also do this by using the CNT and the waitcnt instruction. The Prop is really good at doing things like this.

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

    · Home of the MultiBladeProps: TriBlade,·RamBlade,·SixBlade, website
    · Single Board Computer:·3 Propeller ICs·and a·TriBladeProp board (ZiCog Z80 Emulator)
    · Prop Tools under Development or Completed (Index)
    · Emulators: CPUs Z80 etc; Micros Altair etc;· Terminals·VT100 etc; (Index) ZiCog (Z80) , MoCog (6809)·
    · Prop OS: SphinxOS·, PropDos , PropCmd··· Search the Propeller forums·(uses advanced Google search)
    My cruising website is: ·www.bluemagic.biz·· MultiBlade Props: www.cluso.bluemagic.biz
  • KyeKye Posts: 2,200
    edited 2010-05-04 15:40
    Use the waitcnt instruction...

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Nyamekye,
  • bill190bill190 Posts: 769
    edited 2010-05-04 17:16
    Yeaaa!jumpin.gif

    That solves all my problems! (No hub timing problem.)

    I'll do this in assembly.

    I'm getting to be quite familiar with waitcnt. I've been reading about this a *lot* and experimenting as to how it can be used to get the same timing no matter what system clock speed is used.

    And that how you go about getting the current clock value...

    This·can introduce small delays depending on if cnt is on the left or right side of a statement (The "clock cycles" the statement on the left would take to execute and this time would pass and be added to the count).

    And I've been playing a little with the "wrap around" or "overflow" arithmetic. (Is that what you call it?)

    Being that the system clock only has one word size storage space for the clock count.

    As I understand this, the upper limit is 2_147_483_647 and the lower limit is -2_147_483_648?

    And that when you add 10 to 2_147_483_645, you don't get 2_147_483_655, rather you get -2_147_483_641

    So as I understand this,·it·counts up to the upper limit,·(2_147_483_647), then starts counting·up using negative numbers?

    So·the system clock when reaching the upper limit would count like this?

    2_147_483_645
    2_147_483_646 (+1)
    2_147_483_647 (+2)
    -2_147_483_648 (+3)
    -2_147_483_647 (+4)
    -2_147_483_646 (+5)
    -2_147_483_645 (+6)
    -2_147_483_644 (+7)
    -2_147_483_643 (+8)
    -2_147_483_642 (+9)
    -2_147_483_641 (+10)

    Then what happens when·the system clock·gets to 0?

    -3
    -2
    -1
    0
    1
    2
    3

    ???

    And I assume there would be a *maximum* number you could add to the count. Like·something around·double 2_147_483_647? As in it would "wrap around"·again and again?

    2_147_483_645 + 2_147_483_648 = -3

    -3 + 10 = 7

    So it would just keep going around in circles?

    ·
  • pgbpsupgbpsu Posts: 460
    edited 2010-05-04 18:31
    It doesn't really make sense (to me at least) to think of the counter going negative. If you treat it as an UNsigned int (values can only be between 0 and $FFFF_FFFF) things are much easier. The time it takes for that counter to reach $FFFF_FFFF and wrap back to zero depends on your system clock. At 80Mhz that about 53 seconds. If you want to know how many system clock a particular piece of code takes, you simply grab the counter before starting (startTime) the code in question, then grab the counter again when you are done (endTime). Subtract the two and you'll have the number of system clocks. endTime - startTime = elapsedTime. It's that simple. No need to worry about wrap around. If startTime is near the $FFFF_FFFF (say $FFFF_FF00) and the counter has wrapped before getting to endTime (say $0000_00A0) the difference is $FFFF_FFFF-$FFFF_FF00 + $0000_00A0 = $FF + $A0 = $19F (or 415 in base10). That the same answer you'd get if you do 32-bit math $0000_00A0-$FFFF_FFFF which is how the prop does it.
  • Graham StablerGraham Stabler Posts: 2,510
    edited 2010-05-04 18:59
    The assembly waitcnt has two arguments, one the target and the other a number that is added to the target to create the next target, once you are up and looping there are no problematic delays and no need to look at cnt again and it is quite happy with wrap around. Similarly you can get good results in spin after the first loop:

    delay := cnt
    repeat 
       delay := delay + 1000   ' This line is done during the delay effectively
       waitcnt(delay)  
    
    



    The counters also use overflow, they add the number in FRQA to PHSA on every clock cycle conditionally (for simple frequency generation it always adds), the overflow can be linked to an output pin.

    Graham
  • bill190bill190 Posts: 769
    edited 2010-05-04 23:25
    Graham Stabler said...
    The assembly waitcnt has two arguments...
    Thank you SO much for pointing that out!

    That is something I would not have caught and would have looked at the spin waitcnt documentation and never thought there would be another assembly waitcnt!

    And thank you everyone else for the tips!turn.gif
  • Cluso99Cluso99 Posts: 18,069
    edited 2010-05-05 01:07
    There are some great counter demo programs. Some are included in the latest PropTool download.

    What I think you are trying to do can most likely be done with a counter and once setup, requires no code to keep it going, so the cog is free to do other stuff and the counter runs in the background automatically.

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

    · Home of the MultiBladeProps: TriBlade,·RamBlade,·SixBlade, website
    · Single Board Computer:·3 Propeller ICs·and a·TriBladeProp board (ZiCog Z80 Emulator)
    · Prop Tools under Development or Completed (Index)
    · Emulators: CPUs Z80 etc; Micros Altair etc;· Terminals·VT100 etc; (Index) ZiCog (Z80) , MoCog (6809)·
    · Prop OS: SphinxOS·, PropDos , PropCmd··· Search the Propeller forums·(uses advanced Google search)
    My cruising website is: ·www.bluemagic.biz·· MultiBlade Props: www.cluso.bluemagic.biz
  • bill190bill190 Posts: 769
    edited 2010-05-05 02:19
    I just had an idea on what I want to try...

    Generate the carrier frequency with one cog and output that on one pin (actually 40KHz from the Sony IR specs I have read).

    Then with another cog, control the ones and zeros timing and output that on another pin. (The start bit would be 2400 µs on and 600 µs off. A "one" would be 1200 µs on and 600 µs off. And·a "zero" would be 600 µs on and 600 µs off.)

    (And connect the IR LED to both of the above pins.)

    Then with a 3rd cog and a 3rd pin, connect an IR sensor and with this read the IR LED signals to see that I have it right! (I already have this working and have been testing my different remotes to see what they do.)

    But first I have a bit of reading to do, might help to know what I am doing!burger.gif

    FYI - Sony SIRC protocol*...
    http://www.sbprojects.com/knowledge/ir/sirc.htm

    *Start bit, command, device. And the bits are backwards! Least significant bit first!
    ·
  • Peter JakackiPeter Jakacki Posts: 10,193
    edited 2010-05-05 02:27
    You don't need to waste a cog, use the cog's counter to generate the carrier and control/modulate it which you can do in Spin as the signaling speed is very slow (600us). The thing with the receiver is that you don't normally try to read the carrier as the whole purpose of the carrier is to overcome ambient light and interference by having the receiver amplify the carrier frequency thus filtering out the other junk. So the receiver is normally a complete unit that outputs the demodulated signal which is easy to handle. I believe there is something in the obex that covers this.

    Found a couple: obex.parallax.com/objects/94/ and obex.parallax.com/objects/95/

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    *Peter*

    Post Edited (Peter Jakacki) : 5/5/2010 2:32:39 AM GMT
Sign In or Register to comment.