Shop OBEX P1 Docs P2 Docs Learn Events
Explanation of Cog processor working in parallel — Parallax Forums

Explanation of Cog processor working in parallel

guili_23guili_23 Posts: 11
edited 2010-09-25 16:18 in Propeller 1
Hi,

Could anybody explain me the basic function of Cogs working in parallel ?? I have read the propeller manual but when I tried to make a simple Spin application with two Cogs it didn´t work.

1.- Why this code doesn´t work properly:
CON
  LED=21
VAR
  long Stack[10]

PUB Main  
  dira[LED]~~                                          
  outa[LED]~
  <more code>
  cognew(Test, @Stack)
  <more code>
PUB Test
  repeat
      Delay(1_000)  'Delay of one second
      !outa[LED]

And this code does:
CON
  LED=21
VAR
  long Stack[10]

PUB Main  
  <more code>
  cognew(Test, @Stack)
  <more code>
PUB Test
  dira[LED]~~
  repeat
      Delay(1_000)  'Delay of one second
      !outa[LED]

I read that the I/O registers are common for the Cogs, Why should I define the I/O every time I start a Cog ???


2.- Other question, when I add a combination of Spin and Assembly code it doesn´t work in the way I want it to work, for example:
  <definition of CON and VAR>
PUB Main
  <code>
  cognew(@mfmWordReader, @mfmWord) 
  <more code>

<definition of others PUBs>

DAT
    org 0
mfmWordReader
    <assembly code>

it stops running when I call to the new Cog.

I think that is something related to the memory space between Cogs and Main RAM but I can´t understand it very well.

Thanks in advance.

Comments

  • ratronicratronic Posts: 1,451
    edited 2010-09-23 20:13
    guili - all 32 i/o pins are common for all 8 cogs but you have to specify the dira register in that cog for the i/o pin you want. You didn't show the code for the assembly example you posted.
  • Mike GreenMike Green Posts: 23,101
    edited 2010-09-23 20:20
    1) Each cog has its own set of I/O registers (DIRA and OUTA) which are combined in the hardware (logically OR'd together) to produce the actual state of the I/O pins. Any cog with a 1 bit in its DIRA register forces that corresponding I/O pin into output mode. Any cog with a 1 bit in its OUTA register and a 1 bit in its DIRA register (same bit numbers) forces that output pin to high. Each cog also has an INA register, but all of these read the current state of the 32 I/O pins regardless of whether they're set as inputs or outputs.

    You need to set the I/O mode in the cog that sets the sense (low / high) of the I/O pin.

    2) How do you want the Spin / Assembler combination to work? What you wrote should start up another cog with the assembly routine you wrote and pass it the address of mfmWord.
  • guili_23guili_23 Posts: 11
    edited 2010-09-25 10:35
    Hi Mike/ratronic,

    thank you for your response.

    Regarding the second point I will try to explain a little better.
    In the Main PUB (Cog 0) I define the I/O of the Propeller. One of these Inputs defined in Main (called INDEX) will be used to increment a counter of NEGEDGE monitored by other Cog (Cog 1)
    But when I call to the new Cog (1) the programs stops (I realise through the visualization of a led).
    Here is the code, Could you find where the error is ??
    CON
      LED_ON       = 22 
      INDEX         = 1                                       
      MOTOR_A    = 2                                       
      DRIVE_B      = 3
    
      PINCON_IN     = %000001
    
    VAR
      long mfmWord
    
    PUB Main
      dira[LED_ON]~~                'Test Led                        
      outa[LED_ON]~
    
      In_Out                             'PUB to define I/O
    
     cognew(@mfmWordReader, @mfmWord)
    
    DAT
            org 0
    mfmWordReader
            mov     dira, Inputs 
    
            mov     mfmWordAddr, par                         
            mov     temp, PINCON_IN
            or      ctrb_conf, temp
            mov     ctrb, ctrb_conf                            
            mov     frqb, #1                                  
            
            mov     state, #0
            waitpeq INDX, INDX                    
            waitpeq state, INDX                                  
    
            wrlong  phsb, mfmWordAddr  
               
    mfmWordAddr      long  0                              
    ctrb_conf           long  %01110_111 << 23               
    temp                  long  0                            
    INDX                  long  |< INDEX                      
    Inputs                long  %000                           'Pin 1 (INDEX) as Input
    
    state                 res   1                                                                    
    
  • Mike GreenMike Green Posts: 23,101
    edited 2010-09-25 12:15
    Your program is doing exactly what you've written it to do.

    Once things are initialized, you do the first WAITPEQ which waits for I/O pin 1 to be high (1), then the second WAITPEQ waits for I/O pin 1 to be low (0). It then writes PHSB to mfmWord and who knows what happens next? The program will begin to execute the data that follows the WRLONG most of which is zeros which won't do anything, but it's anyone's guess what will happen once it finishes executing the zero stored in the state location.

    I suggest you put something like "hangHere JMP #hangHere" after the WRLONG to make the cog hang there or a " COGID temp" followed by a " COGSTOP temp" to make the cog stop (and reset it).

    Some simplifying hints:

    I often declare a "Zero LONG 0" in my programs, then use " WAITPEQ Zero,IOmask" or " WAITPNE Zero,IOmask" to wait for a zero or one respectively. To me this is clearer than putting anything else in the destination field and it doesn't matter which I/O pin I'm using.

    You can use PAR in the source field of both a WRxxxx and RDxxxx. If you're only passing a single value, this is much easier than moving PAR to a temporary location, then using that.
  • guili_23guili_23 Posts: 11
    edited 2010-09-25 15:39
    Thank you Mike.

    the hints were very helpfull !!

    Best Regards
  • kuronekokuroneko Posts: 3,623
    edited 2010-09-25 16:18
    [COLOR="Red"]mov     phsb, phsb[/color]         ' shadow[phsb] := counter[phsb]
    wrlong  phsb, mfmWordAddr
    

    The wrlong on its own doesn't do what you think it does. If phsx is used in the destination slot of an instruction its shadow location is used (not the counter register). So at least move the counter value to the shadow location (red) then store the value.

    Also, you use mov temp, PINCON_IN but all this does is assign register $001 to temp. What you want is the immediate value of that constant, i.e. mov temp, #PINCON_IN. That said, you could do the whole counter setup including pin assignment like this
                mov     ctrb, ctrb_conf                            
                ...
    ctrb_conf   long  %01110_111 << 23 | PINCON_IN
    
    But when I call to the new Cog (1) the programs stops (I realise through the visualization of a led).

    After cognew returns the main cog exits (LED switches off). If you want to keep it alive you have to take action (endless loop, infinite wait etc).
Sign In or Register to comment.