Shop OBEX P1 Docs P2 Docs Learn Events
Spin2 for P1 — Parallax Forums

Spin2 for P1

This is probably a very remote use case, but liking the idea of using Spin2 with P1.

Just tested this basic code using FlexProp (this is probably the only option) and it works.
Code just toggles two pins on and off:

PUB Main()
    repeat
        pinh(26)
        pinl(27)
        _waitms(1000)
        pinl(26)
        pinh(27)
        _waitms(1000)

Liking that Main() has parenthesis (forced to really). This makes complex code a lot more readable.

Also, nice to be able to use pinh() and pinl() without dealing with OUTA/DIRA.

Also nice to have built in _waitms() (and probably some other things like this).

I'll have to look up how to set the clock to 80 MHz...
Maybe it does this automatically, not sure...

Comments

  • RaymanRayman Posts: 16,010

    The problem is that there are years and years of Spin1 code built up. And also, the third party compiler.
    Still might look into this some more, just for fun...

  • JonnyMacJonnyMac Posts: 9,631

    More and more I find myself programming the P1 in the style of the P2 where I can. For example, I always use a named result variable if the method returns something. In my basic P` IO library I have added pinhigh(p), pinlow(p), pintoggle(p), and pinfloat(p).

  • RaymanRayman Posts: 16,010

    Think "pinh" was actually supposed to be "_pinh", and so forth. Not sure why that worked anyway...

    Debug seems to work in FlexProp, that is interesting:

    CON
        _clkfreq = 320_000_000
    
    PUB Main()|n
        repeat
            n++
            debug(udec(n))
            _pinh(26)
            _pinl(27)
            _waitms(1000)
            _pinl(26)
            _pinh(27)
            _waitms(1000)
    

    Don't seem to have a handle on clock control though, this shouldn't work at 320 MHz on P1, obviously....
    Can't find anything in the manual...

  • @Rayman said:
    The problem is that there are years and years of Spin1 code built up.

    Do note that nothing stops you from using Spin1 libraries in a Spin2 top file. It's all interoperable. You do need to explicitly add the ".spin" extension to the filenames in the OBJ section, it defaults to assuming libraries have the same extension as your top file.

  • RaymanRayman Posts: 16,010

    @Wuerfel_21 That is a good point.

  • RaymanRayman Posts: 16,010

    Guess have handle on clock now, it's just the regular P1 way:

    CON
      _clkmode = xtal1 + pll16x
      _clkfreq = 80_000_000
    
    PUB Main()|n
        repeat
            n++
            debug(udec(n))
            debug(udec(cnt))
            _pinh(26)
            _pinl(27)
            _waitms(1000)
            _pinl(26)
            _pinh(27)
            _waitms(1000)
    

    But, debug doesn't seem to work except at 80 MHz. Guess that means it was already defaulting to 80 MHz...

  • RaymanRayman Posts: 16,010

    Testing out some P2 accessories on P1 board with Eval style headers...

    First test is LED Matrix with CONTROL.

    Didn't take too much to make this Spin2 code and P2 accessories work on P1...
    Had to make some changes:

    • Change RX and TX for P1
    • Replace serial with fullduplexserial (as P1 does not have smartpins for serial)
    • In the matrix driver, just had to explicitly float the pins as Spin2 on P1 cannot apparently use pinfields
    • In the random driver, had to remove the P2 style random as P1 doesn't have that
    • In control, had to comment out the wrpin as P1 doesn't have smartpins

    Think that was pretty much it... Should remove the clock setting code, but FlexProp appears to be ignoring that, so not a big deal.
    Not actually sure if random driver is working, but maybe it is.

    The CONTROL buttons seem to work, except for the one that is supposed to show "2" on the display. Should look into how to better adapt the control board...

    The LED matrix looks dim to me, but also dim on P2. Think they should not have added all those 470 Ohm resistors...

    Anyway, this seems like a good sign that converting P2 code (at least simple things that don't use P2 specific hardware) to work on P1 is fairly easy.

  • JonnyMacJonnyMac Posts: 9,631

    Anyway, this seems like a good sign that converting P2 code (at least simple things that don't use P2 specific hardware) to work on P1 is fairly easy.

    Agreed. I make a lot of my own P2-type accessory boards, and as I have a FLiP board with P2 accessory headers, I'm careful with compatibility -- for example, adding pull-ups and pull-downs since the P1 does not have those internally.

  • RaymanRayman Posts: 16,010

    Here's another thing that could be useful... The Spin2 way of setting individual bits in any variable seems to work:

    PUB Main()|n,x
        repeat n from 0 to 31
            x.[n]~~
            debug(ubin(x))
            _waitms(1000)
        repeat
    
  • RaymanRayman Posts: 16,010

    Think have control accessory working now.
    Just doing the usual thing of pulling down the pin and then floating just before reading...

    This should work for P2 as well, but P2 has the internal pulldowns, which is better...

    pub rd_btn(ch) : result
    
    '' Return state of specified button
    '' -- returns 1 if pressed, 0 if not pressed or invalid
    
        'RJA:  For P1, pulling down first and then floating and then reading
        pinl(ch)
        pinf(ch)
    
      case ch
        0 : result := pinread(base+5)   
        1 : result := pinread(base+4)   
        2 : result := pinread(base+7)   
        3 : result := pinread(base+6)             
    
    
    pub rd_btns() : result
    
    '' Return state of control buttons as a 4-bit value
    
        pinl(0)
        pinf(0)
      result.[0] := pinread(base+5) 
      pinl(1)
        pinf(1)
      result.[1] := pinread(base+4) 
      pinl(2)
        pinf(2)
      result.[2] := pinread(base+7) 
      pinl(3)
        pinf(3)
      result.[3] := pinread(base+6) 
    
  • RaymanRayman Posts: 16,010

    Inline assembly seems to work, at least one form:

    PUB Main()|n,x
        x:=1<<26
        asm
            mov dira, x
            mov outa, x
        endasm
        repeat
    

    org/end doesn't seem to work. Have to read the docs some more to remind myself of the difference...

    Still, inline assembly for P1? Seems very nice.

  • ersmithersmith Posts: 6,248

    @Rayman said:
    Inline assembly seems to work, at least one form:
    org/end doesn't seem to work. Have to read the docs some more to remind myself of the difference...

    That's odd, org/end should work on P1 (as long as you use P2 assembly, and as long as you're compiling to P1 asm rather than bytecode). But I just tried and there's a fit 96 being inserted there that's messing something up. I'll look into it, thanks for noticing.

  • RaymanRayman Posts: 16,010

    Took a stab at something much more difficult, "Spinner Edge", a W6100 based ethernet board...
    Got it to compile to pasm, basically by commenting out all the inline assembly and also some smartpin things.

    But, can't convert pasm to executable. The error message doesn't say exactly, but I'm pretty sure this is well over the 32 kB that P1 has.

    There are some steps that could make this work though

    • convert FAT32 to P1 fsrw
    • convert spi driver to P1 spi driver (either slow spin one or faster asm one)
    • Adapt W6100 driver to work on P1.

    This last one is probably the majority of the work...

    An easier path might be to compile the C driver for P1 and try that.
    This will probably work, unless it comes out too big, which is possible...

    The Spin W6100 is probably a lot smaller than the C driver, from what I remember...

    Either way looks like some work, so I'll probably skip this and try some more hardware....

  • RaymanRayman Posts: 16,010
    edited 2026-02-04 18:04

    Just figured out how to compile and run Spin2 on P1 using SpinTools IDE.
    Took a while to figure things out, especially how to have debug() work...

    Anyway, this is enabled via the Preferences->Tools dialog, where you can enable external tools.
    This requires FlexProp to be installed somewhere too, in this case at C:\FlexProp

    So the first external tool (activated by alt+1 on keyboard) is rigged to compile for P1 (using flexspin.exe): -1 -O2 -g -D_BAUD=115200 -L C:\flexprop\include -o p1.binary ${file}
    The second tool (alt+2) is rigged to load P1 with the generated p1.binary file from first tool (using proploader.exe): -t -k -D baud-rate=115200 p1.binary
    The screenshots below show these external tool dialog settings.

    This is nice because I'm used to the colored background that SpinTools provides as well as some other niceties.

    I'm also really liking how can use debug.
    This isn't the real, interrupt driven, debug like on P2, think it's more like regular serial output.
    But, it can be useful. This is enabled by that "-g" flag for the compiler, shown above.

    733 x 633 - 34K
    426 x 396 - 16K
    426 x 396 - 14K
  • RaymanRayman Posts: 16,010

    After the above is all set up, you just do alt+1 to compile and then alt+2 to load.

    Looks like these could be combined into one step using multiple lines in the external tool command, but think this is good for now...

  • RaymanRayman Posts: 16,010

    Wow, floating point works automagically with Spin2 on P1.
    Really liking this. Didn't make program size explode too much either...
    Think there is a fixed point option that would presumably reduce the file size a lot...

    585 x 361 - 16K
  • JonnyMacJonnyMac Posts: 9,631

    Just a reminder that Spin Tools uses its own internal compiler to flag errors, and depending on differences between it and your external tool, you may get errors flagged that you can ignore when using the external tool to compiler your running code.

  • RaymanRayman Posts: 16,010

    Yes, removed some underscores to make it happy. I'm hoping it can work flag free...

  • RaymanRayman Posts: 16,010

    Seems like QWIIC accessories are a place where a common Spin2 file for P1 and P2 makes sense. Don't imaging smartpins help a whole lot with I2C. Although for best performance, maybe P1 needs an assembly driver...

    Anyway, got this Sparkfun SSD1306 based 128x32 OLED working with a hacked version of an OBEX code for 128x64 display. Guess I'll turn this into Spin2 and see if it really can work for both P1 and P2.

    Not actually happy with how this code is using a page system to define lines of text and doesn't have any graphics besides text.
    But, going to go with this for now.

    Also, the text is very small... Maybe will have to change it to larger font. Or, was reading somewhere about someone doing a 2X scaled font, that might be easier.

    But, P1 also has it's ROM font that might be perfect for this, or the "hidden" version for half size...
    So, maybe a universal driver is not going to be ideal... Going to look at it anyway...

  • RaymanRayman Posts: 16,010
    edited 2026-02-04 22:27

    Not really understanding the binary size implications for adding float in Spin2 when compiling for P1.
    P1 is much more sensitive to binary size of course...

    It seems like regular debug things add about 5kB to binary. Adding in float debug adds another ~5kB.
    But, with floating point being used and without debug the binary is only ~2kB.

    Think this must mean flexprop is automatically cutting code not being used.
    Have to imaging the full floating point library would be much bigger than that...

  • JonnyMacJonnyMac Posts: 9,631

    I have an SSD1306 driver in Spin1 that does use a cog to get the most of I2C (400kHz for SSD1306). It runs well enough for my app in byte code, but is pretty zippy when compiled with FlexProp. This driver has the standard 8x8 font but I have mechanism to scale x or y so you can have 8x8, 8x16, 16x8, or 16x16. I suggest you stick with the PASM I2C so that you don't overrun the speed of the display which could easily happen by compiling the simple Spin1 code to PASM.

    This is a little SSD1306 HMI that I built for Josh and me for some upcoming experiments we're doing for our laser tag products.

  • RaymanRayman Posts: 16,010

    thanks @JonnyMac , will take a look...

    If some part of the code really needs to be different between P1 and P2 versions, found this works inside SpinTools IDE when configured to compile with FlexProp:

    #ifdef __P1__
        debug("This is a P1")
    #endif
    #ifdef __P2__
        debug("This is a P2")
    #endif
    

    This may be the key to solving that problem...

  • RaymanRayman Posts: 16,010
    edited 2026-02-05 18:22

    Working on the @JonnyMac ssd1306 driver. Think liking this one better than the other one because has graphics... (and bigger font option).

    So far, have converted the driver into Spin2 in a way that should work on both P1 and P2.
    Working on P1 for now. Will test on P2 after the test file is also converted.

    With delays removed, the original loop took 1.9 seconds to complete.
    This version takes 1.2 seconds, and it is without any assembly. Compiling with FastSpin probably makes it fast enough to achieve 400 kHz without assembly.
    (although fastspin converts everything to assembly internally...)

    But, the driver is now not using the pullups exactly as should. Should only be pulling down pins and letting the pullups float them up high.
    A lot of older code did this, think an easy fix.
    Add in some delays to make it really 400 kHz and should be good.

  • RaymanRayman Posts: 16,010
    edited 2026-02-05 18:42

    Ok, main test file is now in Spin2 and works on both P1 and P2 :)

    The I2C driver here needs fixing up, but works anyway.

  • RaymanRayman Posts: 16,010

    Much happier with this version of i2c driver...
    Uses pullups instead of driving SDA/SCL high.

    Also, has a chip dependent delay that should be close to 400 kHz for both P1 and P2.

    One gotcha is that SpinTools IDE will use files that are updated in the editor. But, when invoking FlexProp as external tool, that will only use the version saved to disk.
    So, basically you need to save all before invoking FlexProp to compile for P1...

    All in all, this seems to have worked out nicely. Think have to try out some other QWIIC stuff...

    The only perhaps unfortunate thing is that this is only to work with FlexProp.
    Like to have multiple options.
    But, the niceties of Spin2 is tempting me to overlook that...

  • RaymanRayman Posts: 16,010

    Slightly improved version of I2C driver for P1 and P2:

  • RaymanRayman Posts: 16,010

    Hmm.. Just realized that the above was working on P2 only because the QWIIC Oled module has it's own i2c pullup resistors...
    Probably need to add option to enable P2 internal pullups just in case there's a module that doesn't have pullups...

  • RaymanRayman Posts: 16,010
    edited 2026-02-06 22:46

    Wow, just got a surprise...

    Was working on adapting an @JonnyMac debug I2C scanner to work on both P1 and P2 in Spin2...
    Doing this with the SpinTools IDE...

    Did not really expect the debug window to work at all in P1 mode.
    Instead it popped open a window and displayed the result just like on P2!

    This was definitely a welcome surprise. Might be some other debug things work as well...

  • @Rayman said:
    Wow, just got a surprise...

    Was working on adapting an @JonnyMac debug I2C scanner to work on both P1 and P2 in Spin2...
    Doing this with the SpinTools IDE...

    Did not really expect the debug window to work at all in P1 mode.
    Instead it popped open a window and displayed the result just like on P2!

    This was definitely a welcome surprise. Might be some other debug things work as well...

    @Rayman,

    I can't get the included archive zip file to unpack, it appears to be damaged. :-(

Sign In or Register to comment.