Shop OBEX P1 Docs P2 Docs Learn Events
AUGD and WAITX Syntax question — Parallax Forums

AUGD and WAITX Syntax question

I am trying to use WAITX in HUB Execute mode trying to point to "cntDelay" in the HUB memory using "AUGD #n" and "WAITX D" in COG Execute mode to have Dest_Register to be used. Below is code I have tried (have tried several different address qualifiers @,# forms with no Luck)

PS tried to use ~~ for indentation (didn't work)

~~
'*******************************************
'Using HUB Memory Execute
'*******************************************
CON
_clkfreq = 200_000_000
#0,P0
PUB main()
COGINIT(COGEXEC_NEW,@blink01,0) 'returns cog number started 1 PTRA set to 0
repeat 'processor clock speed
DAT ORGH 'HUBEXEC Ram

blink01 DIRH #P0
Loop OUTL #P0
'-----------------------------------------------------------------------------
waitLoop1 AUGD #(@cntDelay<<9)
waitx #(cntDelay & $1FF) 'Maximum 9 bit value not using register reference
debug("finnish waitLoop1")
OUTH #P0
'-----------------------------------------------------------------------------
waitLoop2 AUGD #(@cntDelay<<9)
waitx #(cntDelay & $1FF) 'Maximum 9 bit value not using register reference
debug("finnish waitLoop2")
jmp #Loop
'------------------------------------------------------------------------------
cntDelay long 2_0000_0000

'*********************************************
'using Cog memory Execute following program works
'*********************************************
CON {Processor Timing}
_clkfreq = 200_000_000
#0,P0
PUB main()
COGINIT(COGEXEC_NEW,@blink01,0) 'returns cog number started 1 PTRA set to 0
repeat 'processor clock speed
DAT ORG 0 'Cog1 Blink

blink01 DIRH #P0
Loop OUTL #P0
'-----------------------------------------------------------------------------
waitLoop1 waitx cntDelay 'Maximum 9 bit value not using register reference
debug("goto Loop2")
OUTH #P0
'-----------------------------------------------------------------------------
waitLoop2 waitx cntDelay 'Maximum 9 bit value not using register reference
debug("goto Loop1")
jmp #Loop
'------------------------------------------------------------------------------
cntDelay long 2_0000_0000

Comments

  • Cluso99Cluso99 Posts: 18,066
    edited 2021-10-25 06:37

    Registers can only be in cog ram.
    If you want to use hub you will need to use riling rdlong etc.

  • @Cluso99 said:
    Registers can only be in cog ram.
    If you want to use hub you will need to use riling etc.

    I think autocorrupt changed cluso’s rdlong to riling.

  • It takes three ~plus CR at the top and ~ plus CR at the bottom

  • Doesn't HUB Executing PASM code using 4 byte Memory in the HUB simulate Registers interperting the 32 bits as a PASM instrution? Wouldn't the code be 4 byte aligned in the HUB and the PC counter accesses this? I assumed (not a good way to start) that the PC in the cog accessed the HUB Memory and incremented by 4 bytes somehow. Wouldn't the HUB memory behave the same way cog memory does just with a larger address space. Both are actuall 8 bit word base?. What does riling mean?
    Regards and thanks for reply
    Bob (WRD)

  • A register reference is enough to get a 32 bit value, but as @Cluso99 has pointed out the registers are in the Cogram.

    If that value hasn’t been stored in Cogram yet, you’d need to either load it from hubram, or construct it once in the setup code.

    To construct it you would use something like an AUGS followed by a MOV to put the 32 bit literal into a cog register.

  • evanhevanh Posts: 15,126

    @Publison said:
    It takes three ~plus CR at the top and ~ plus CR at the bottom

    three back-ticks -> `

  • evanhevanh Posts: 15,126
    edited 2021-10-24 22:16

    @"Bob Drury" said:
    Doesn't HUB Executing PASM code using 4 byte Memory in the HUB simulate Registers interperting the 32 bits as a PASM instrution? Wouldn't the code be 4 byte aligned in the HUB and the PC counter accesses this? I assumed (not a good way to start) that the PC in the cog accessed the HUB Memory and incremented by 4 bytes somehow. Wouldn't the HUB memory behave the same way cog memory does just with a larger address space.

    Yes ... but that's only for instruction fetch. Data (operand) fetch is another story. Many RISC architectures are what's called load-and-store. Propeller is one of them. Data is loaded into the general register set (cogRAM) using explicit load instructions, and similarly written back out using explicit store/write instructions.

    Operands, excepting immediate data, otherwise have to be in cogRAM (the general register set).

  • Hub ram has the initial spin boot program and it holds the PASM program which can either be HUBEXEC code COGEXEC code. The rdlong instruction requires you to know the hub address. How do you know where to declare symbol address with reference to ORGH and how do you declare adresses to be reference in HUB ram. I have looked at document on HUB but I don't understand the
    organization of HUB ram. HUB Ram is 00400 to 7FFFF but Debug uses 16KB so really it is 00400 to 7BFFF . I believe there is 512KB in actual memory so the first hub memory is lost 00000 to 003FF? In any case how do declare hub ram address and then reference it in the PASM rdlong instructions.? Is there some info in documents I missed?
    Regards and Thanks
    Bob (WRD)

  • Again, there is a difference between execution and data access. Execution addresses between $00000 and $00400 will provide instructions from COG or LUT RAM.

    Looking at the HUB RAM section of the Parallax Propeller 2 Documentation v35, I'll give my understanding of how it works.

    Any of the hub memory access instructions (RDBYTE, RDWORD, RDLONG, WRBYTE, WRWORD, WRLONG, WMLONG, RDFAST, WRFAST, and the whole RFx and WFx family of instructions) will be able to access all of HUBRAM.
    The HUBRAM address is specified in the S register and can cover the range of $00000 to $FFFFF.
    In the current production chip the 512KB of HUBRAM appears twice: from $00000 to $7FFFF and again at $80000 to $FFFFF.
    The debug/ROM section at the top of the memory map ($FC000 to $FFFFF) will be locked for writing under certain circumstances, and is described as being hidden from the $7C000 region when locked.
    If a future version of the Prop2 with a full 1MB of HUBRAM is made then the HUBRAM won't repeat, and any code written to take advantage of the repetition will break.

    When a COGINIT is performed, the S register contents will be loaded into PTRB of the started Cog. An offset from this address can be used to find the Hub address of any variables declared in the code. Another option, useful you want to read a specific Hub address, is to perform a SETQ of that address prior to the COGINIT. This Q register value is loaded into PTRA of the started Cog.

    Has this addressed all of your questions?

  • evanhevanh Posts: 15,126
    edited 2021-10-25 03:19

    There is a full 512 kB of hubRAM, just not all is accessible to everything. HubRAM addresses from $0 to $3ff are data (RDLONG etc) accessible only.

    EDIT: Oh, and COGINIT can load cogexec code from there too. Pure Pasm programs are initially loaded at hubRAM $0 before COGINIT'd. Those are data accesses then.

  • evanhevanh Posts: 15,126
    edited 2021-10-25 03:44

    Here's an example rework of above attempt:

    '*******************************************
    'Using HUB Memory Execute
    '*******************************************
    CON
        _clkfreq = 200_000_000
        tpin = 56  ' LED on Eval Board
    
    PUB main()
        COGINIT(HUBEXEC_NEW,@blink01,@cntDelay) 'PTRA set to hubRAM address of cntDelay
        repeat 'processor clock speed
    
    
    DAT
    ORGH 'HUBEXEC Ram
    
    blink01
            DIRH #tpin
            rdlong pa, ptra
    Loop
            OUTL #tpin
    '-----------------------------------------------------------------------------
    waitLoop1
            waitx pa
            debug("finnish waitLoop1")
            OUTH #tpin
    '-----------------------------------------------------------------------------
    waitLoop2
            waitx pa
            debug("finnish waitLoop2")
            jmp #Loop
    '------------------------------------------------------------------------------
    cntDelay    long 200_000_000
    
  • AribaAriba Posts: 2,682

    And another example that answers the question in the title:

    '*******************************************
    'Using HUB Memory Execute
    '*******************************************
    CON
        _clkfreq = 200_000_000
        tpin      = 56  ' LED on Eval Board
        DELAYTIME = 200_000_000
    
    PUB main()
        COGINIT(HUBEXEC_NEW,@blink01,0)
        repeat
    
    
    DAT
            ORGH 'HUBEXEC Ram
    
    blink01
    Loop
            DRVL #tpin
    
            waitx ##DELAYTIME        'the easy way
            debug("finnish wait1")
    
            DRVH #tpin
    
            AUGD  #DELAYTIME         'with explicite augd
            waitx #DELAYTIME & 511
            debug("finnish wait2")
    
            jmp #Loop
    
  • Thanks . I think I follow . PTRA gets the top of Symbol Address @cntDelay . The programmer must now refer to any subsequent symbol address from that reference. So the symbol names
    cannot be used directly . If there was cntdelay2 long defined you cannot reference directly the address you would use ptra = @cntDelay +1. PTRA only gets the top of symbol variable at COGINIT execution.
    You can't use ptra = @cntDelay2 or rdlong pa,@cntDelay2 . Is that correct? I Will try this out.
    Regards
    Bob (WRD)

  • evanhevanh Posts: 15,126

    There might be other solutions but, yeah, I think Chip intentionally didn't wanted Spin2 programs having known load address at compile time.

  • @Ariba said:
    And another example that answers the question in the title:

    '*******************************************
    'Using HUB Memory Execute
    '*******************************************
    CON
        _clkfreq = 200_000_000
        tpin      = 56  ' LED on Eval Board
        DELAYTIME = 200_000_000
    
    PUB main()
        COGINIT(HUBEXEC_NEW,@blink01,0)
        repeat
    
    
    DAT
            ORGH 'HUBEXEC Ram
    
    blink01
    Loop
            DRVL #tpin
    
            waitx ##DELAYTIME        'the easy way
            debug("finnish wait1")
    
            DRVH #tpin
    
            AUGD  #DELAYTIME         'with explicite augd
            waitx #DELAYTIME & 511
            debug("finnish wait2")
    
            jmp #Loop
    

    That certainly works when you are after a 32-bit immediate parameter for WAITX, but the original example showed attempts to use a location in hubram to hold the delay value.

    As that wasn’t going to work alternatives that would work, but maintained the parameter as a variable, were offered. This may be important in situations where another part of the code adjusts the delay and modification of the AUGD + WAITX would be impractical.

  • AJLAJL Posts: 512
    edited 2021-10-25 22:19

    @"Bob Drury" said:
    Thanks . I think I follow . PTRA gets the top of Symbol Address @cntDelay . The programmer must now refer to any subsequent symbol address from that reference. So the symbol names
    cannot be used directly . If there was cntdelay2 long defined you cannot reference directly the address you would use ptra = @cntDelay +1. PTRA only gets the top of symbol variable at COGINIT execution.
    You can't use ptra = @cntDelay2 or rdlong pa,@cntDelay2 . Is that correct? I Will try this out.
    Regards
    Bob (WRD)

    Note that PTRA gets loaded with whatever parameter is specified in the COGINIT. In your first example that was 0. You might note that in @evanh code PTRA is used as an address to load the delay parameter into PA. It could just as easily have been used to load the parameter into another Cog address. If you had a series of long aligned data following cntdelay you could adjust the pointer value in PTRA to point to any of them.

    So, PTRA initially points to cntdelay and you have a few options to use it to access cntdelay2:

    1. Load a parameter block (blocksize needs to be calculated)
     SETQ blocksize-1
     RDLONG Cogcntdelay, PTRA
    
    1. Load parameters individually with auto increment of pointer
    RDLONG Cogcntdelay, PTRA++ ; auto-increment address by 4 bytes
    RDLONG Cogcntdelay2, PTRA++ ; auto-increment address by 4 bytes
    
    1. Load parameters individually with manual increment of pointer
     RDLONG Cogcntdelay, PTRA
     ADD PTRA, #4 ; manually increment addresses by 4 bytes
     RDLONG Cogcntdelay2, PTRA
    

    In each case
    Cogcntdelay would be cntdelay
    Cogcntdelay +1 would be cntdelay2
    etc.
    You can get nice names to work with by defining the addresses.

    The different options have different advantages.
    The block load maintains the order and spacing of the variables allowing a simple block write back to hubram, if that is needed. Edit: If you want to write back then it is safest to save a copy of PTRA somewhere before changing it.

    The auto increment allows the block to be broken up between locations in Cogram should that be needed.

    The manual increment allows parameters to be skipped if they aren’t needed in this cog.

    If you prefer to keep most of the variable names a bit shorter you can use the plain versions ( cntdelay, etc.) for the variables in Cogram, and use something like ‘Hubparams’ for the beginning of the block in hubram.

Sign In or Register to comment.