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
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?
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 you're right.
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?
Never used it but, yup, has to be a register of the currently executing cog.