Moving From Spin1 to Spin2
JonnyMac
Posts: 9,157
In another thread I saw a person with P1 experience wishing for a guide to moving code to the P2. I'm not suggesting that is is that guide, but I'd like it be a place where we can share what we've learned moving from Spin on the P1 to the Spin on the P2.
Please...
-- keep the tips focused on Spin1 to Spin2 (there are plenty of places to discuss BASIC, C, Forth, etc.)
-- when possible, show the Spin1 version and the equivalent Spin2 version
-- please restrict examples to that which will run in the official Parallax tools, PNut and Propeller Tool (some compilers have extensions that aren't back-compatible with Parallax tools)
I've been porting my P1 objects to the P2 for the past couple months, so I'll share my mental list and the things I've learned here.
Please...
-- keep the tips focused on Spin1 to Spin2 (there are plenty of places to discuss BASIC, C, Forth, etc.)
-- when possible, show the Spin1 version and the equivalent Spin2 version
-- please restrict examples to that which will run in the official Parallax tools, PNut and Propeller Tool (some compilers have extensions that aren't back-compatible with Parallax tools)
I've been porting my P1 objects to the P2 for the past couple months, so I'll share my mental list and the things I've learned here.
Comments
Now... this hasn't been implemented yet, but it will be. No doubt those of you using Propeller Tool have written P2 code only to have the compiler complain because it defaults to the P1. For the moment the fix is to save the file with a .spin2 extension. In the future, though, Parallax will implement a feature used in the BASIC Stamp editor that allows the same tool to deal with the differences between the Stamp 1 and the Stamp 2, and even extensions in PBASIC 2.
This is my programming header; note the comment with {$P2} in it. This modelled after the way the BASIC Stamp editor works. Down the line, we should be able to compile and check code before saving.
Spin1
Spin2
Note that neither my main nor setup methods use parameters, but in Spin2 must have empty parenthesis.
Spin1 The initial configuration of an IO pin requires setting the outa (output register) and dira (direction register) bits.
Spin2
Both languages accommodate multiple contiguous pins.
Spin1
Spin2
Warning: In the P2, the group created by addpins cannot span the pin 31 / pin 32 boundary.
P2 IO keywords:
-- pinhigh(n), pinh(n)
-- pinlow(n), pinl(n)
-- pintoggle(n), pint(n)
-- pinfloat(n), pinf(n)
-- pinwrite(n, value), pinw(n, value)
-- value := pinread(n), value := pinr(n)
Consult the official P2 documentation for keyword details.
-- https://docs.google.com/document/d/16qVkmA6Co5fUNKJHF6pBfGfDupuRwDtf-wyieh_fbqw/edit#heading=h.1h0sz9w9bl25
P1 cnt becomes getct() in the P2.
P1 waitcnt() becomes waitct() in the P2.
Spin1
Spin2
Spin
Spin2
Note 1: The advantage of having to declare return values allows the P2 to return multiple values from the same method.
Spin2
Note 2: The calling code does not have to accept multiple return values. Use the underscore character in the assignment expression to ignore a specific result.
Spin2
Note 3: The P2 can use return without declaring a variable if no value is returned -- you can use an empty return as an early escape mechanism.
Spin2
thank you Jon
Mike
Spin 1 (start PASM cog)
Spin 2 (start PASM cog) In the P2, coginit replaces cognew for PASM cogs. The new first parameter selects the cog; using COGEXEC_NEW will select the next available cog as was the case with cognew.
Note: The P2 is able to run PASM code within a cog or from the hub; see the Spin2 documentation for details of coginit().
Spin 1 (start Spin cog)
Spin 2 (start Spin cog) In the P2, cogspin replaces cognew for Spin cogs.
Jon, I started to learn Spin2 and trying out examples from Spin 1 I found out that apparently there is an important difference in the way bits are accessed and referenced in the code.
In Spin 1:
But in Spin 2 the corresponding syntax would be
In the P1, we only have one output register (outa) and its associated direction register (dira), but in the P2 we have double (outa and outb, dira and dirb), but each is only 32 bits -- while our pint #s are from 0 to 63. In my mind, programs should be clear, so it's best to avoid direct use of these registers for simple IO manipulation.
Interestingly, this actually works in the P2 -- even those the dirb and outb are 32-bit registers:
It works because the interpreter limits the pin number to five bits, so that corrects the value for dirb/outb. Still, this code is easily broken. If you want to toggle a pin in the range of 0..31, you have to change the pin constant and update the code for dira and outa (as you pointed out in your code comments).
This is why I suggest the built-in pin methods available in Spin2 for basic IO control. We don't have those in the P1, so we're forced to use the direction and output registers. For simplicity of updates, and for clarity for ourselves and others, this little blinker is best (in my opinion) as It's simple, self explanatory, and works with any IO pin with a single edit of the LED constant.
When moving from P1 to P2, strive to work alike, even if line-by-line you don't look alike. Spin2 is blessed with more power and features, often simplifying code we wrote for the P1.
Follow-up: Even PASM2 is simpler in this regard. There are single instructions to drive a pin high, low, or make it float, and will accept a pin number from 0 to 63 -- the microcode for each instruction handles the specifics of which register group to use. This makes programs cleaner and easier to write, read, and debug.
Follow-up #2: I will sometimes allow less-than-clear code when it runs a lot faster. For grins, I used the Propeller to measure the duration of the two mechanisms discussed here. The results are interesting. I was surprised, but happy. The pintoggle() instruction is 3x faster, while being easier to read and maintain.
I totally understand the new pin methods are way better for readability and makes cleaner code, and frankly I find it (Spin 2) better to learn from scratch than Spin 1.
I wrote that reply because as a newbie, I am using as a reference a book I have had for about 6 years and I was a bit confused as to why I couldnt make the simple examples (in Spin1) work in Spin 2 using the dir and out instructions used by the book. Fortunately I came across this thread and have cleared so far most of my confusion while reading the Google Docs on Spin2 vs the book I have.
I am just trying to learn and this forum has proven to be great! Btw, thank you for your breakout board!!! I can't believe I have a signed Jon McPhalen board to learn P2!!!!
Perhaps in the near future this thread could be the basis for an updated book on Propeller?
If you haven't seen it, I wrote an article for Nuts & Volts about the P2 (note that this was early on and there have been a couple changes).
-- https://www.nutsvolts.com/magazine/article/an-introduction-to-the-parallax-propeller-2
I also did an early-adopter seminar which is about the Propeller family, with a bit of focus on the P2:
--
Thank Parallax for the breakout board -- they did all the hard work. It was something I wanted, so I "sketched" the idea with a PCB program and put it up in the forums. Luckily, my practical development needs are similar to others and the idea kind of took off. My signature on the bottom is a bit of a goof because I am not a famous actor (though I am a member of SAG/AFTRA). I guess if do get famous it will be a good story to tell -- how many actors have their signature on an electronic development board?
I'm sure the future holds lots of books about the Propeller family. The first step is to let Parallax get the P2 manual out (the P1 manual is really good, I trust the P2 manual will follow suit).
You have to become famous so that these boards become collectors items like guitars, clothes, etc. Collectors items usually surge in value when the person passes away, but I expect I'll be long gone before you!
Have you seen the value of the Apple 1 boards? Ouch! Jobs is gone but Woz is still here.
Actually this toggles the LED on pin 56, but it also toggles pin 57. The bits higher than 5 are used to define additional bits (=pins in this case), so dirb.[56] means the same as dirb.[24 addbits 1].
Just another reason to use the built in pin functions, like pinw / pinwrite or pint / pintoggle.
Andy
Not many I hope!!! That will make my board even more valuable!!!
This syntax.. ... treats the pin parameter as a bit field. A bit field is a 10-bit value (%00000_00000) with lower five bits (0..31) defining the base bit, and the upper five bits defining the number of bits used to extend the group (0..31). In the case of having the LED constant set to 56, that bit field becomes %00001_11000. What this does is create a mask that starts at bit 24 and extends by one to bit 25. Applying this mask to outb affects IO pins 56 and 57, which correspond to bits 24 and 25 of the outb register. As Andy pointed out, it's equivalent to 24 addbits 1.
This syntax... ... treats the pin parameter as a pin field. A pin field is an 11-bit value (%00000_000000) with the lower six bits (0..63) defining the base pin, and the upper five bits defining the number of pins used to extend the group. In our example, pin 56 fits into six bits which leaves the upper portion of the pin field 0; so we only affect one pin.
See pages 6 and 7 of the Spin2 documentation for more details and examples.
-- https://docs.google.com/document/d/16qVkmA6Co5fUNKJHF6pBfGfDupuRwDtf-wyieh_fbqw/
@"Ken Gracey"
@cgracey
This is where I asked about a tutorial similar to the PE Kit manual. There are so many differences from P1 to P2 that it is difficult to convert.
I am not asking for a Kit. Just a manual that gives the basic explanations. The spin2 documentation as I have searched them does not address the differences.
Thanks
If I had more of the above the transition would be more smooth.
Again thanks for listening.
Semper Fi to Parallax.
@JonnyMac
Is there an update for the Jm_serial? I have the fullduplexserial one but I am getting the fdec error on the serial version.
Thanks
jm_serial.spin2 has been retired because it is not buffered. Once I got comfortable with PASM2 I upgraded it to jm_fullduplexserial.spin2. The latest version of that is attached. Please, for the love of all that's holy, get rid of jm_serial.spin2 on your system, as well as old versions of jm_fullduplexserial.spin2, and put this code (it has a child object called jm_nstr.spin2 for numeric formatting) in your global library. In my case that is here:
C:\Users\jmcph\Documents\Propeller Tool\Library
If you did a custom installation of Propeller Tool, yours may be in a different location. Note that both Flex Prop and Spin Tools allow you to point at this folder as a library location, so you don't actually have to use Propeller Tool unless you want to.
(Repeating myself) If any of your apps use the old method names: fdec(), fhex(), foct(), fqrt(), or fbin() you need to add "x" after the "f" so they become fxdec(), fxhex(), fxoct(), fxqrt(), and fxbin(). Just so you understand, Chip made an update to the debugging features of Spin2 which stomped on the method names I was using. This stuff sometimes happens, so we have to contend with it.
I remember the change Chip made that caused a lot of confusion.
Just wanted to keep this thread alive, unfortunately I have nothing to add. Thanks JonnyMac!
Rob.
Bobby,
You can make a post linking to here in the pinned links topic - https://forums.parallax.com/discussion/169542/p2-links-for-where-to-obtain-tools-sample-test-code-reference-only
It hasn't been contributed to in a while but new additions to it are still helpful.