Convert spin2 to p2asm
Hello!
I am working on a program to print a number. I am able to do this in spin2 using the following code which prints the number 2:
con
_clkfreq = 20000000
_clkmode = 16779595
dat
pub main()
org
' configure rx smart pin fltl #63 wrpin #P_ASYNC_RX, #63 wxpin ##655367, #63 drvl #63 ' configure tx smart pin fltl #62 wrpin ##(P_ASYNC_TX | P_OE), #62 wxpin ##655367, #62 drvl #62 wypin #50, #62
end
return
main()
I am trying to do the same in this bit of p2asm code, but it does not seem to print anything out:
con
_clkfreq = 20000000
_clkmode = 16779595
dat
org
fltl #63 ' configure rx smart pin wrpin #P_ASYNC_RX, #63 wxpin ##655367, #63 drvl #63 fltl #62 ' configure tx smart pin wrpin ##(P_ASYNC_TX | P_OE), #62 wxpin ##655367, #62 drvl #62 wypin #50, #62
I noticed, for the p2asm code, if i sent the wypin #50, #62 back to back i get output but it's the letter X. Not sure if i need to flush anything or if the assembly code is just running too fast.
I should also mention I am using FlexProp, on Mac OS X with the P2 edge.
Comments
You need to wait until the smartpin has done its job, before you send another character or terminate the program:
Andy
You must always end a PASM program with an infinite loop or cogstop. Otherwise the program counter will run off into unexplored lands.
Pure PASM programs needs to setup the system clock, usually this was done with the asmclk pseudo-instruction that traslated to the appropriate hubset instructions, then deprecated in favor of the clocksetter pre-loader in PNut. Does FlexProp do the same or requires asmclk in these cases ? I don't know... worth checking, looks to me the clock is not set appropriately.
Hi everyone!
Thank you all for such good information. I was able to get much further! Right now it prints a single character. Here is the code in case someone else is also getting started in p2asm and runs into a similar head scratcher on flexprop:
con
dat
org
endofloop
The looping forever was straightforward but i didn't think about waiting for the smart pin to finish or checking if it had finished. Right now it prints a single character but I am going to have to figure out how to print specific characters using wypin. Again thank you all!
if you do any branch while REP is active, REP is cancelled. So you want to use a regular JMP-based loop here.
The
hubset #0
is extraneous too. That selects RCFAST as the sysclock source, but RCFAST is the power-up clock source already. Which means your serial bit rate, at sysclock/10, is around 2.4 Mbit/s!You can make use of the Spin2 CONstants, _xtlfreq, _xinfreq and _clkfreq, for precomputed clock setting. By replacing the
hubset #0
with the special macroasmclk
the assembler will insert the three instructions encoded for setting the crystal locked sysclock frequency then.Wow! This was super helpful!
I edited the p2asm program a bit. What i noticed is now i get the value I am supposed to after adding asmclk. Before I replaced hubset got an odd accented character but now I get the number 2 after using asmclk. Here is the current code:
con
_clkfreq = 20000000
_clkmode = 16779595
dat
org
I noticed that if i remove everything below wypin #50, #62 everything still works. But, I am curious if it just happens to work without the last 4 lines and i need to include the last four just to make sure I don't run into some kind of race condition with the pin or not?
On a side note, i felt this was way better than a blinking light for learning p2asm. I was able to pick up spin2 pretty well, event with mixing assembly a bit but pure p2asm forced me to really learn this microcontroller.
Thank you all so much for taking time out for this.
Good stuff.
It's generally better to leave _clkmode alone. That gets computed, by the assembler, from the provided _clkfreq. If the two don't match then you'll get more of those timing issues.
What can be needed is a _xtlfreq or _xinfreq. The assumed default by the assembler/compiler is
_xtlfreq = 20_000_000
but if the board design is not using a 20 MHz crystal then this assumption is incorrect and more timing issues will ensue. So, getting into the habit of always specifying the external clock frequency is good practice. This applies equally to the various compilers too.Of course, if you are fully aware of all this then coding your own _clkmode to force the correct ratio between external and internal clocks also works.
There is a couple more related symbols that get generated too: clkfreq_ and clkmode_. These can be referenced at runtime to examine what the assembler/compiler decided to use. eg: I've used them in pllset() - https://obex.parallax.com/obex/pllset/
As for your question, the last four lines just controls the cog execution path. The smartpin you've loaded the byte of data into, with the WYPIN, will happily knock out those bits at its configured bit rate quite independently of what the cog does. You won't notice if the cog crashes afterward unless it happens to also make further changes to the tx pin.
Thank you for the answer for wypin. I did test it and yeah that matches up with some of the code i've been running to see what breaks and what it does.
I had a look at the link you posted. My spin2 isn't too bad but i think i'll need to read the manual a bit on p2asm. Some of the commands I have not run into. But just from that code and this thread alone I am creating variables and adding and subtracting them. Along with the decision branching introduced earlier in the thread I think i have a good starting point to learn p2asm properly. Thank you!