Shop OBEX P1 Docs P2 Docs Learn Events
Use of getreg(addr_hub, addr_cog, cnt) and use of REG[addr] to access cog memory? — Parallax Forums

Use of getreg(addr_hub, addr_cog, cnt) and use of REG[addr] to access cog memory?

I am trying to improve my understanding of hub/cog memory addressing and am not getting the results I expect from these two spin2 routines. Can anyone help me with the rules of usage?

Comments

  • JonnyMacJonnyMac Posts: 9,102
    edited 2023-11-08 20:01

    I've only used the setregs() method, but it did what I needed. In this case I need to pass a bunch of hub variables into the cog. Instead of using locals in the method, I just copied them directly to the PR0..PR7 registers. This was faster than using locals and the routine works as before.

    pub show()
    
    '' Refresh pixels
    '' -- cog prX regs:
    ''    0:pin, 1:p_buf/color, 2:count, 3:reset, 4:zero ticks, 5:one ticks, 6:period ticks, 7:swap/timer
    
      setregs(@pixdat, $1D8, 8)                                     ' copy hub vars to cog regs pr0..pr7
    
      org
                            drvl      pr0                           ' make pin output/low
                            waitx     pr3                           ' allow reset
                            mov       ptrb, pr1                     ' point to start of buffer
                            or        pr7, pr7              wz      ' put swap flag in z
    
    .pixloop                rdlong    pr1, ptrb++                   ' get pixel data
            if_nz           movbyts   pr1, #%%2310                  ' swap red & green if z = 1
                            getct     pr7                           ' initialize bit timer
    
                            rep       #7, #24                       ' loop through 24 bits
                             shl      pr1, #1               wc      ' get MSB
                             drvh     pr0                           ' pin on
            if_nc            waitx    pr4                           ' hold for bit timing
            if_c             waitx    pr5
                             drvl     pr0                           ' pin off
                             addct1   pr7, pr6                      ' update bit timer
                             waitct1                                ' let bit timing finish
    
                            djnz      pr2, #.pixloop                ' update count, continue if more
      end
    

    You're not showing your code. Is your order of parameters correct? Are you using the correct cog address? (must be direct value, does not use @ or #)

    (French accent)A few moments later(/French Accent)

    I hate leaving things to theory -- so I did a very quick test. I hooked up a button board to the header that starts at P32 and ran a bit of code. The results are as expected. I did this capture while pressing my 0 button.

  • It is a bit circular, and broken.

    I think the thing I am missing is setreg/getreg only work within the actual cog ram that the spin interpreter is running in?

  • JonnyMacJonnyMac Posts: 9,102
    edited 2023-11-09 00:25

    I just remembered that Chip helped me with an OLED driver that I embedded in cog memory.

    The first line loads my driver code. The second line loads the pin numbers into the driver. As you can see, you need to change @my_var (which is a hub address) to #my_var which is a cog address.

    This is the code that gets loaded into the cog and updated.

    dat { spi driver }
    
    ' This code is loaded into the upper region of user RAM in the Spin2 interpreter cog
    ' -- not compatible with Spin compilers
    
                            org       $110
    
    ' pr0 = byte to write (preserved)
    ' pr1 = bit0 is state of DC line before SPI write (preserved)
    ' pr2 = work var (destroyed)
    
    spi_write               drvl      _cs                           ' select display
                            testb     pr1, #0               wc      ' get DC bit
                            drvc      _dc                           ' set DC
                            mov       pr2, pr0                      ' copy cmd/data byte
                            ror       pr2, #8                       ' prep byte for MSBFIRST
                            rev       pr2
                            wypin     pr2, _dout                    ' write to SPI smart pin
                            drvl      _dout                         ' ready to send
                            wypin     #8, _clk                      ' clock 8 bits
                            nop                                     ' let it start
                            testp     _clk                  wc      ' wait for it to finish
            if_nc           jmp       #$-1
                            fltl      _dout                         ' disable SPI out
            _ret_           drvh      _cs                           ' dispable display
    
    _cs                     res       1
    _dc                     res       1
    _dout                   res       1
    _clk                    res       1
    
    spi_end
    

    But now that I think about it for a minute, I believe setregs() and getregs() work with the interpreter's cog, not a custom cog. For the latter you would have to use some kind of flag command and use rdlong or wrlong to move into or out of the custom cog to the hub.

    I think the thing I am missing is setreg/getreg only work within the actual cog ram that the spin interpreter is running in?

    I think you're right.

  • evanhevanh Posts: 15,914
    edited 2023-11-09 00:58

    Correct. Launching machine code into a new cog is done with COGINIT().

  • The dim bulb is starting to glow a little brighter. Thanks for the help. The same scenario applies to the REG[addr] then?

  • evanhevanh Posts: 15,914

    @Phonos said:
    The same scenario applies to the REG[addr] then?

    Never used it but, yup, has to be a register of the currently executing cog.

Sign In or Register to comment.