Shop OBEX P1 Docs P2 Docs Learn Events
Convert spin2 to p2asm — Parallax Forums

Convert spin2 to p2asm

proppyproppy Posts: 7
edited 2024-03-04 19:39 in PASM2/Spin2 (P2)

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

  • AribaAriba Posts: 2,685

    You need to wait until the smartpin has done its job, before you send another character or terminate the program:

                ...
                wypin     #50, #62
                nop
    .waittx     testp     #62  wc
         if_nc  jmp       #.waittx
                akpin     #62
    

    Andy

  • You must always end a PASM program with an infinite loop or cogstop. Otherwise the program counter will run off into unexplored lands.

  • maccamacca Posts: 750

    @proppy said:
    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:
    I am trying to do the same in this bit of p2asm code, but it does not seem to print anything out:
    I should also mention I am using FlexProp, on Mac OS X with the P2 edge.

    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

    ' set the hub to the first cog
    hubset #0
    
    fltl      #63                                ' configure rx smart pin
    wrpin     #P_ASYNC_RX, #63
    wxpin     ##655367, #62
    drvl      #63
    
    fltl      #62                                ' configure tx smart pin
    wrpin     ##(P_ASYNC_TX | P_OE), #62
    wxpin     ##655367, #62
    drvl      #62
    
    ' loop forever and print a single character to the tx pin
    rep @endofloop, #0
        wypin     #52, #62
    nop
       .waittx     testp     #62  wc
            if_nc  jmp       #.waittx
        akpin     #62
    

    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.

  • evanhevanh Posts: 15,406
    edited 2024-03-06 00:18

    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 macro asmclk the assembler will insert the three instructions encoded for setting the crystal locked sysclock frequency then.

  • proppyproppy Posts: 7
    edited 2024-03-06 13:57

    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

    ' Set the clock mode
    asmclk  
    
    ' configure rx smart pin
    fltl      #63
    wrpin     #P_ASYNC_RX, #63
    wxpin     ##655367, #62
    drvl      #63
    
    ' configure tx smart pin
    fltl      #62
    wrpin     ##(P_ASYNC_TX | P_OE), #62
    wxpin     ##655367, #62
    drvl      #62
    
    wypin     #50, #62
    nop
       .waittx     testp     #62  wc
            if_nc  jmp       #.waittx
        akpin     #62
    

    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. :smiley: Thank you all so much for taking time out for this.

  • evanhevanh Posts: 15,406

    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.

  • evanhevanh Posts: 15,406

    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/

  • evanhevanh Posts: 15,406
    edited 2024-03-06 23:00

    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!

Sign In or Register to comment.