Shop OBEX P1 Docs P2 Docs Learn Events
HUB RAM code location (?) — Parallax Forums

HUB RAM code location (?)

I have a quick question on executing code from HUB. The following code does not work when I begin cog execution from HUB memory $1600. I do not understand this. If I run from HUB @start ($1498) it works.

What am I not seeing here?

CON
  _clkfreq = 297_000_000                
  CLK_FREQ = 297_000_000                

  ctreg = $100

PUB main()  | addr

        'addr := @start
        addr := $1600
        org
        coginit #%1_0_0010, addr
        end
        debug(uhex(addr))


DAT
        orgh $1600
start   getct ctreg
.loop   drvnot #56
        addct1 ctreg, ##CLK_FREQ
        waitct1
        jmp #.loop

Does not work:

Works:

Comments

  • Wuerfel_21Wuerfel_21 Posts: 5,105
    edited 2023-12-16 20:40

    This doesn't work because Spin memory layout just doesn't work that way. You need to get the address at runtime using the @ operator. Just is like that. The compiler accepting ORGH with a parameter looks like a bug.

    Also, why are you using inline assembly for coginit? There's a perfectly good coginit function. Also, there are symbols for cog startup modes, such as HUBEXEC_NEW, see Spin2 manual.

  • PhonosPhonos Posts: 45
    edited 2023-12-16 20:51

    So, stick with the following:

    CON
      _clkfreq = 297_000_000                
      CLK_FREQ = 297_000_000                
    
      ctreg = $100
    
    PUB main()  | addr
    
            addr := @start        
            coginit(1, addr, 0)
    DAT
            orgh $1600
    start   getct ctreg
    .loop   drvnot #56
            addct1 ctreg, ##CLK_FREQ
            waitct1
            jmp #.loop
    

    I assume this loads COG RAM?

  • Wuerfel_21Wuerfel_21 Posts: 5,105
    edited 2023-12-16 20:56

    Well, if we're at it:

    CON
      _clkfreq = 297_000_000                    
    
    PUB main()
    
            coginit(COGEXEC_NEW, @start, 0)
    DAT
            org
    start   getct ctreg
    .loop   drvnot #56
            addct1 ctreg, ##_clkfreq
            waitct1
            jmp #.loop
    
    ctreg   res 1
    
    

    I assume this loads COG RAM?

    Yes. You need to use plain ORG for cog-mode assembly, otherwise strange things will happen to you

  • PhonosPhonos Posts: 45
    edited 2023-12-16 21:14

    All very good.

    I guess I am at a loss on how to execute code from HUB.

    This is wrong:

    CON
      _clkfreq = 297_000_000                
      CLK_FREQ = 297_000_000                
    
      ctreg = $100
    
    PUB main()  
    
    
            coginit(1, @cog1, 0)
    DAT
            org
    cog1    drvl #57
            jmp #start        
    
            orgh $1600
    start   getct ctreg
    .loop   drvnot #56
            addct1 ctreg, ##CLK_FREQ
            waitct1
            jmp #.loop
    
  • You use HUBEXEC_NEW. But that raises the issue that you need to define some Cog RAM locations to use as registers.

  • evanhevanh Posts: 16,023
    edited 2023-12-16 22:50
    CON
      _xtlfreq = 20_000_000     'The external crystal frequency. Use "_xinfreq" if a buffered oscillator
      _clkfreq = 100_000_000    'PLL to be used to set sysclock frequency
    
    PUB main()
            coginit(HUBEXEC_NEW, @start, 0)
    
    DAT
            orgh
    start   getct ctreg
    .loop   drvnot #56
            addct1 ctreg, ##clkfreq_
            waitct1
            jmp #.loop
    
            org
    ctreg   res 1
    

    EDIT: Doh! put in HUBEXEC_NEW

  • That is sort of getting back to the point where I started the post. I had specified a HUB address for the code and it was not behaving the way I expected. Is it possible to load HUB code into other locations besides orgh $400? Or, similarly, to load different code sections into non-continuous HUB RAM locations and execute from either one or more cogs?

  • evanhevanh Posts: 16,023

    If you don't require Spin2 there then it can be bypassed and built directly to Pasm2. The Spin2 VM is an optional extra. To do this just remove all PUB/PRI methods and add any desired setup like setting the PLL. eg:

    CON
      _xtlfreq = 20_000_000     'The external crystal frequency. Use "_xinfreq" if a buffered oscillator
      _clkfreq = 100_000_000    'PLL to be used to set sysclock frequency
    
    DAT
            org
            HUBSET ##clkmode_ & !%11   'start external clock, stay in RCFAST mode
            WAITX ##20_000_000/100     'allow 10ms for external clock to stabilize
            HUBSET ##clkmode_          'switch to external clock mode
            coginit #HUBEXEC_NEW, ##@start
    .idle
            waitx #500
            jmp #.idle
    
    
            orgh $1600
    start   getct ctreg
    .loop   drvnot #56
            addct1 ctreg, ##clkfreq_
            waitct1
            jmp #.loop
    
            org
    ctreg   res 1
    
  • evanhevanh Posts: 16,023
    edited 2023-12-16 22:57

    You'll note the use of clkfreq_. This is the correct symbol to always use in both Spin2 and Pasm2 code sections. Only use _clkfreq to specify the desired clock frequency in the CON section.

    PS: Those HUBSETs I've cut'n'pasted from Chip's documentation.

  • @evanh said:
    PS: Those HUBSETs I've cut'n'pasted from Chip's documentation.

    You can also just use the ASMCLK macro

  • evanhevanh Posts: 16,023
    edited 2023-12-16 23:22

    Oops, yes. Been a long time.

    CON
      _xtlfreq = 20_000_000     'The external crystal frequency. Use "_xinfreq" if a buffered oscillator
      _clkfreq = 100_000_000    'PLL to be used to set sysclock frequency
    
    DAT
            org
            asmclk
            coginit #HUBEXEC_NEW, ##@start
    .idle
            waitx #500
            jmp #.idle
    
    
            orgh $1600
    start   getct ctreg
    .loop   drvnot #56
            addct1 ctreg, ##clkfreq_
            waitct1
            jmp #.loop
    
            org
    ctreg   res 1
    
  • evanhevanh Posts: 16,023

    The other thing to mention, for Spin2 programs, it's better to forgo use of clkfreq_ even. Instead the clkfreq system variable should be used there.

  • Very helpful. Thank you both.

    I will continue exploring.

  • Possibly the most important factor here that hasn’t been specifically stated:
    Using orgh only gives information to the compiler (assembler) for calculation of addresses. It doesn’t actually automatically place the code at that address.

    In your original example, start is at $1498, so to get it to run at $1600 you’d need to add $168 bytes of data between your existing PUB and DAT sections (safer option) or include another block of code to move the code to be executed into the desired position (danger of overwriting something important this way)

    The question I have is why are you trying to force a particular code location?

  • evanhevanh Posts: 16,023
    edited 2023-12-17 23:26

    @AJL said:
    Using orgh only gives information to the compiler (assembler) for calculation of addresses. It doesn’t actually automatically place the code at that address.

    In pure Pasm2 programs the ORGH address does mean it is located at that address - the binary file is null filled to suit. It assumes all binaries are built for and loaded to address zero.

    I'm not sure how an arbitrary address hubRAM loadable module could be done without avoiding hard coded absolute addresses. Pnut's assembler has no support for that I don't think. I haven't tried looking to be honest.

  • @evanh said:

    @AJL said:
    Using orgh only gives information to the compiler (assembler) for calculation of addresses. It doesn’t actually automatically place the code at that address.

    In pure Pasm2 programs the ORGH address does mean it is located at that address - the binary file is null filled to suit. It assumes all binaries are built for and loaded to address zero.

    Ok, but the original question involved the use of Spin2 also, so no padding and therefore what I said was correct in the context.

    I'm not sure how an arbitrary address hubRAM loadable module could be done without avoiding hard coded absolute addresses. Pnut's assembler has no support for that I don't think. I haven't tried looking to be honest.

Sign In or Register to comment.