Shop OBEX P1 Docs P2 Docs Learn Events
PASM2 data sharing between cogs — Parallax Forums

PASM2 data sharing between cogs

I am reading through the assembler manual and trying to make some snippets of code to understand some things. So this may seem excessive for blinking an LED, but I am trying to create a new COG and flash the LED on pin 56. So far this way works where I use setq to pass the pin value where its stored in the PTRA register and I just move it to a general purpose register and use that. The way that doesn't work that I am confused about is if I define it where I have cog_id defined it does not blink. I am confused though because cog_id returns the proper cog_id for the print statement. Appreciate the help!

Working example:

con
      _clkfreq    = 100_000_000 

dat        org
asmclk

start
           setq     #56
           coginit  #COGEXEC_NEW, #@blink    wc
     if_c  jmp      #cog_err
           ' keep cog0 going
cogl       jmp      #cogl

' Blink code location
blink
           cogid    cog_id
           debug(`message Started code in: `(cog_id)')
           mov      pr0, ptra
loop
           drvnot   pr0
           waitx    ##clkfreq_/5 
           jmp      #loop

cog_err
           debug(`message Error starting cog, exiting')
           cogstop  #0

cog_id     res      4

Example that doesn't work (confused because cog_id returns right number):

con
      _clkfreq    = 100_000_000 

dat        org
asmclk

start
           coginit  #COGEXEC_NEW, #@blink    wc
     if_c  jmp      #cog_err
           ' keep cog0 going
cogl       jmp      #cogl

' Blink code location
blink
           cogid    cog_id
           debug(`message Started code in: `(cog_id)')
loop
           drvnot   LED_PIN
           waitx    ##clkfreq_/5 
           jmp      #loop

cog_err
           debug(`message Error starting cog, exiting')
           cogstop  #0

LED_PIN    long    56               
cog_id     res      4

Comments

  • evanhevanh Posts: 15,170
    edited 2024-03-27 08:32

    You're missing an ORG directive to correct for relative offset. The first program doesn't reference any relative labels, so works without. The second program does have relative labels so doesn't work.

    Register references are coded as absolute addressing, therefore relative labels in the source code have to be handled via ORG directives. COGINIT loads the target code to the start of target cog's cogRAM. For the assembler to calculate the correct absolute register addresses for each relative label, you need to tell the assembler where address zero is situated. It's generally always at the same address as COGINIT loads at.

    To fix it, add an ORG at the blink label. This then shifts the LED_PIN's register address from 15 to 6.

    con
          _clkfreq    = 100_000_000 
    
    dat        org
    asmclk
    
    start
               coginit  #COGEXEC_NEW, #@blink    wc
         if_c  jmp      #cog_err
               ' keep cog0 going
    cogl       jmp      #cogl
    
    ' Blink code location
                org
    blink
               cogid    cog_id
               debug(`message Started code in: `(cog_id)')
    loop
               drvnot   LED_PIN
               waitx    ##clkfreq_/5 
               jmp      #loop
    
    cog_err
               debug(`message Error starting cog, exiting')
               cogstop  #0
    
    LED_PIN    long    56               
    cog_id     res      4
    
  • evanhevanh Posts: 15,170
    edited 2024-03-27 08:47

    Another detail: Data addresses in cogRAM are always whole registers. Registers are 32-bit therefore each address covers four bytes of memory. This is something that ORG vs ORGH directives will affect.

    Also, data space is not code space. There is three data spaces, each begin at address zero.
    In code space, the three memories are in one map, with cogRAM first, beginning at 0, followed by lutRAM, beginning at $200, and finally hubRAM, beginning at $400. The first $400 bytes of hubRAM are not addressable in code space.

  • @evanh said:
    You're missing an ORG directive to correct for relative offset. The first program doesn't reference any relative labels, so works without. The second program does have relative labels so doesn't work.

    Register references are coded as absolute addressing, therefore relative labels in the source code have to be handled via ORG directives. COGINIT loads the target code to the start of target cog's cogRAM. For the assembler to calculate the correct absolute register addresses for each relative label, you need to tell the assembler where address zero is situated. It's generally always at the same address as COGINIT loads at.

    To fix it, add an ORG at the blink label. This then shifts the LED_PIN's register address from 15 to 6.

    con
          _clkfreq    = 100_000_000 
    
    dat        org
    asmclk
    
    start
               coginit  #COGEXEC_NEW, #@blink    wc
         if_c  jmp      #cog_err
               ' keep cog0 going
    cogl       jmp      #cogl
    
    ' Blink code location
                org
    blink
               cogid    cog_id
               debug(`message Started code in: `(cog_id)')
    loop
               drvnot   LED_PIN
               waitx    ##clkfreq_/5 
               jmp      #loop
    
    cog_err
               debug(`message Error starting cog, exiting')
               cogstop  #0
    
    LED_PIN    long    56               
    cog_id     res      4
    

    Wow, Thank you so much for the explanation and the information. Appreciate that. It makes a lot of sense now. I will need to study the datasheet and assembler manual more.

  • evanhevanh Posts: 15,170

    No problem, it's my first go at explaining it beyond just do it this way.
    Everyone's first experience of ORG is usually one of perplexity, then just follow the rule. ORG's purpose is not anything special to the Propeller chips, just experiencing a pure assembler environment has become rare these days.

    On that note, I presume you have a reason why you're diving straight in the deep end and not trying to work from a higher level first?

  • @evanh said:
    No problem, it's my first go at explaining it beyond just do it this way.
    Everyone's first experience of ORG is usually one of perplexity, then just follow the rule. ORG's purpose is not anything special to the Propeller chips, just experiencing a pure assembler environment has become rare these days.

    On that note, I presume you have a reason why you're diving straight in the deep end and not trying to work from a higher level first?

    I really like assembler. I write alot of x86_64 daily in fasm. Assembly for Propeller is kind of an oddball and has some nuances I am finding out, but I just enjoy writing in assembly so I tend to always lean towards learning it. I have written some stuff in spin2 though so off and on for both.

  • evanhevanh Posts: 15,170
    edited 2024-03-27 23:26

    Oh, a quick read of Fasm Wikipedia page tells me that it is probably the oddball case when it comes to assemblers. A multi-pass assembler is a new one on me. That implies it probably has some high-level language features.

    Err, that's wrong. But self-hosted on the PC is certainly weird. Booting a PC is fraught with legacy.

  • @evanh said:
    Oh, a quick read of Fasm Wikipedia page tells me that it is probably the oddball case when it comes to assemblers. A multi-pass assembler is a new one on me. That implies it probably has some high-level language features.

    Ha, yeah. It does. You can definitely use things the "old" way or choose to use higher level macros. The new fasmg is even more weird, but I tend to just stick to the original stuff tbh.

Sign In or Register to comment.