Shop OBEX P1 Docs P2 Docs Learn Events
[resolved][puzzle] connection terminated — Parallax Forums

[resolved][puzzle] connection terminated

kuronekokuroneko Posts: 3,623
edited 2011-02-16 16:15 in Propeller 1
Devise a way of communicatingA between two PASM cogs which
  • doesn't use/access hub RAM
  • doesn't use/access external pins
Working sample code - initially - into my PM box please.

A For the purpose of this exercise let's say I want to transfer an arbitrary long between them.

Comments

  • Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 23,514
    edited 2011-02-14 08:36
    For the sake of clarification, I assume these conditions are true?

    1. The cogs are already running; i.e. the communication doesn't take place upon a coginit/cognew by one cog of the other.

    2. The two cogs are already aware of each other's cog ID.

    3. The solution has to work between cogs having any pair of cog IDs.

    -Phil
  • potatoheadpotatohead Posts: 10,261
    edited 2011-02-14 08:52
    ??

    Well, I'm eager to see this one.
  • Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 23,514
    edited 2011-02-14 09:08
    potatohead, I think you've said too much. -Phil

    Technically, though, ??? is hub RAM, so it would not be allowed by the rules. :)
  • potatoheadpotatohead Posts: 10,261
    edited 2011-02-14 09:46
    Smile. Sorry
  • AribaAriba Posts: 2,690
    edited 2011-02-14 15:48
    Sent my solution by PM...

    Andy
  • kuronekokuroneko Posts: 3,623
    edited 2011-02-14 16:14
    For the sake of clarification, I assume these conditions are true?

    1. The cogs are already running; i.e. the communication doesn't take place upon a coginit/cognew by one cog of the other.

    2. The two cogs are already aware of each other's cog ID.

    3. The solution has to work between cogs having any pair of cog IDs.
    1. Correct.
    2. No.
    3. Yes.

    Will I ever get it right first time?
  • kuronekokuroneko Posts: 3,623
    edited 2011-02-14 16:16
    Ariba wrote: »
    Sent my solution by PM...
    10/10

    Total solutions sent so far 4 (+2 idea).
  • RossHRossH Posts: 5,519
    edited 2011-02-15 12:32
    Hi kuroneko,

    Are all the solutions submitted so far essentially the same? Or do they use different mechanisms?

    Ross.
  • kuronekokuroneko Posts: 3,623
    edited 2011-02-15 15:59
    RossH wrote: »
    Are all the solutions submitted so far essentially the same? Or do they use different mechanisms?
    Yup, they all center around the same theme so far. That said, there is one more (unrelated) - heavy weight - option to achieve the same effect but it's really ugly if you ask me and uses undocumented features (which are not the ugly bit).

    Let's open this discussion.
  • Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 23,514
    edited 2011-02-15 16:44
    I can think of one really ugly way to do it. It involves starting a PWM counter in the receiving cog and modulating the system clock from the sending cog in such a way that the receiving cog's PLL goes in and out of lock. This can be detected in the receiving cog by the instruction vs. counter timing being off. How's that for ugly? :)

    Potatohead's [redacted] method is probably the best, although it technically violates the "no hub RAM" rule, since the ????s rely on one bit of hub RAM each.

    I was trying to come up with something involving the audio subcarrier, but it always uses a pin and doesn't seem to have a less visible path between two cogs.

    Another technique, similar to Potatohead's, but pretty ugly in its own right, is to pick an unused cog to start and stop. The transmitting cog would start and stop it, corresponding to the data bits being sent. The receiving cog would try to start it and read a bit that depended on the success or failure of the coginit. 'Wouldn't work: coginit does not return status.

    -Phil
  • kuronekokuroneko Posts: 3,623
    edited 2011-02-15 16:51
    Potatohead's [redacted] method is probably the best, although it technically violates the "no hub RAM" rule, since the ????s rely on one bit of hub RAM each.
    Sorry, hub resource (e.g. lock) is not hub RAM (I assume/know you're going to argue).
    Another technique, similar to Potatohead's, but pretty ugly in its own right, is to pick an unused cog to start and stop. The receiving cog would try to start it and read a bit that depended on the result of the coginit.
    Which bit would that be? IIRC that'd only work if there is one cog left (and then inspect carry). I mean if the receiving cog starts a particular cog then it starts a particular cog, period. Any history this cog may have is gone. Starting the next available looks different (but needs the 0/1 left condition). In which case I'd stick with cogid $ wc,nr.
  • Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 23,514
    edited 2011-02-15 17:00
    Kuroneko,

    True, locks are not in the hub RAM address space, but they do constitute flip-flops (i.e. one-bit memory that's randomly accessible) in the hub. That's all. 'Not enough of a technicality for disqualification. :)

    Yes, I realized my error with coginit and corrected my post before your reply. It could still be done, though, by starting all but one cog and getting status from cognew for the last one. But yuck!

    -Phil
  • agsags Posts: 386
    edited 2011-02-15 18:30
    Yuck to all. Here I was all excited that I was going to have revealed, by the Propeller intelligentsia, the magic potion I've been looking/hoping for which would allow single- (or actually 4-) clock communication between cogs (of data, i.e. longs) instead of the dreaded 7-22 cycles (x2) of hub RAM r/w.

    Well, it was a fun exercise, nonetheless. :-)
  • kuronekokuroneko Posts: 3,623
    edited 2011-02-15 18:42
    ags wrote: »
    Yuck to all. Here I was all excited that I was going to have revealed, by the Propeller intelligentsia, the magic potion I've been looking/hoping for which would allow single- (or actually 4-) clock communication between cogs (of data, i.e. longs) instead of the dreaded 7-22 cycles (x2) of hub RAM r/w.
    What's your exact requirement for communication (new thread maybe)? If you have enough to do hub access can always be 8 cycles provided you don't mess up your hub windows artificially (yes, the manual is wrong).
  • agsags Posts: 386
    edited 2011-02-15 20:11
    I'm looking at a potential need (which may or may not materialize in the near future - but I feel this would be a good bit of knowledge to add to my Propeller-toolbelt for use some time, certainly) to have one cog acting as "executive", receiving input and dispatching it to other cogs for processing and output (take a pipe with high raw data rate, minimally processed by a the executive cog, and multiplexed to several other cogs in parallel for more elaborate processing before output in pins (divided equally among the "slave cogs"). It's a rough idea at the moment, and I won't have time to get into it much now. If there are some techniques that might be helpful, I'll keep that in mind and ping later on.

    Thanks. The depth of knowledge on this forum is truly impressive.
  • kuronekokuroneko Posts: 3,623
    edited 2011-02-15 21:53
    OK, lets wrap this up (but feel free to continue the discussion). What people came up with so far:
    • locks (set/clear)
    • cog availability
    • lock availability
    • system clock modulation (not sure I want to see this)
    Let me know if there is more and I add it to the list. Surprisingly - despite looking like black magicA - you can still get a fairly decent 5Mbit/s out of the lock approach (clkfreq/16). Same holds true for #2 above but that relies on consuming all cogs in the system, NG.

    Here is an example for using locks (courtesy of Andrey Demenev):
    [COLOR="blue"]CON
      _clkmode = XTAL1|PLL16X
      _xinfreq = 5_000_000[/COLOR]
      
    VAR
        long    l
    
    OBJ
        ser : "FullDuplexSerial"
        
    PUB main
        ser.start(31, 30, 0, 115200)
        [COLOR="blue"]waitcnt(clkfreq*3 + cnt)[/COLOR]
        l := 0
        cognew(@entry, @l)
        cognew(@entry, @l | $8000)
        waitcnt(CNT + CLKFREQ / 2)
        ser.hex(l, 8)
        ser.tx($0A)
        
    DAT
    
    entry       mov     addr, PAR
                andn    addr, flag
                test    flag, PAR           wz
        if_z    jmp     #tx
    
    
    rx          mov     data, #0
                mov     ctr, #32
    :loop       lockset txlock              wc
        if_c    jmp     #:loop
                shl     data, #1
                lockset datalock            wc
                muxc    data, #1
                lockclr rxlock
                djnz    ctr, #:loop
                wrlong  data, addr
                cogid   data
                cogstop data
    
    tx          lockset txlock
                lockset rxlock
                mov     data, number
                mov     ctr, #32
    :loop       shl     data, #1            wc
        if_c    lockset datalock
        if_nc   lockclr datalock
                lockclr txlock
    :sync       lockset rxlock              wc
        if_c    jmp     #:sync
                djnz    ctr, #:loop
                cogid   data
                cogstop data
    
    flag        long    $8000
    txlock      long    0
    rxlock      long    1
    dataLock    long    2
    number      long    $1234_5678
    
    ctr         res     1
    data        res     1
    addr        res     1
    

    A just kidding
  • kuronekokuroneko Posts: 3,623
    edited 2011-02-15 22:20
    kuroneko wrote: »
    Any history this cog may have is gone.
    Actually that's a lie. The video frame counter keeps it's value across cogstops. But it's only 12 bits so sending a long may become a bit of a challenge. Nevertheless, I like the idea of passing a cog's ID to identify a dead-letter-box :)
  • mparkmpark Posts: 1,305
    edited 2011-02-16 07:10
    kuroneko wrote: »
    If you have enough to do hub access can always be 8 cycles provided you don't mess up your hub windows artificially (yes, the manual is wrong).

    Wait, what??
  • Andrey DemenevAndrey Demenev Posts: 377
    edited 2011-02-16 07:19
    Yes, manual is wrong saying that HUB operations (WRxxxx, RDxxxx, LOCKxxx, etc) take 7 to 22 cycles - actually they are 8 to 23
  • Dave HeinDave Hein Posts: 6,347
    edited 2011-02-16 07:52
    Does the initial delay depend on which cog starts up another cog? That is, would cog 5 come up in a different phase if it was started by cog 0 versus cog1, or do all cogs start up in the same phase relative to cog 0's access window? Also, if its the latter case, then one of the cogs would startup in phase with its access window, and each successive cog would be off by 2 to 14 cycles.

    So if the first hub access is done at some "random" time after the cog starts up, wouldn't the delay be somewhere between 8 and 22 cycles for the first hub access, and 8 to 20 cycles for any hub accesses after that? Why would there ever be an odd number of cycles? I know, I should look at the timing data and it will reveal all the answers.
  • kuronekokuroneko Posts: 3,623
    edited 2011-02-16 16:15
    Did the title change to topic disconnected? :)

    All cogs start up with the first instruction being -4 relative to their hub window (which effectively translates to same phase relative to cog 0). Meaning the following (start) sequence doesn't have any penalty:
    DAT             org     0
    
    entry           mov     dira, mask              '  -4
                    rdlong  data, par               '  +0 =
    
    The relationship between the cog starting and the one being started only manifests in the startup time. The textual description can also be found [post=864343]here[/post] (halfway down). The example shows cog 0 (re)starting cog 4.

    attachment.php?attachmentid=78367&d=1297900981
    Dave Hein wrote: »
    So if the first hub access is done at some "random" time after the cog starts up, wouldn't the delay be somewhere between 8 and 22 cycles for the first hub access, and 8 to 20 cycles for any hub accesses after that? Why would there ever be an odd number of cycles?
    Let's start with odd cycles, waitcnt/waitpxx/waitvid. Those can get you successfully out of the 4n raster. Provided you only use 4 cycle instructions and hub access then you'll only encounter 0/4/8/12 penalty (additionally to the 8 cycles it takes for hub access) for the first random hub accessA. Subsequent hub ops are your responsibility but follow the same pattern unless you throw in some wait* stuff. HTH

    A the first penalty is actually predictable if you stay clear of wait*
    795 x 245 - 16K
Sign In or Register to comment.