Shop OBEX P1 Docs P2 Docs Learn Events
Spin & Win with Spin2 and Inline Assembly — Parallax Forums

Spin & Win with Spin2 and Inline Assembly

JonnyMacJonnyMac Posts: 8,918
edited 2020-08-14 23:58 in Propeller 2
There is no denying that the P2 is significantly faster than its predecessor, the P1, even running the same code at the same clock speed. Of the most exciting features of Spin2 -- in my opinion -- is the ability to add snippets of inline code. Though the requirement for inline assembly is neither frequent or usual, it can be very useful at achieving one's goals while conserving cogs (important resources). There is no longer a need to consume a cog to run a few lines of assembly code.

For example: You may want to design a convention badge that has a few WS2812b LEDs to use as indicators. If you don't need the features of a fully-fledged pixel driver, a simple inline routine can be used to update the LEDs -- this keeps a cog free for other, more important processes.

Please use this thread to share your Spin2/Inline Assembly success stories. I am well aware that some programmers think that inline assembly should be avoided. That's okay, this is a big forum and you can express your thoughts elsewhere. My intent is to use this thread to create a cookbook of useful inline assembly routines.

Suggestions:
-- keep your code neatly formatted
-- comment your code (more is better)
-- test before posting, and attach test code if possible

Comments

  • JonnyMacJonnyMac Posts: 8,918
    edited 2020-08-15 04:47
    I'll get things started with a method that can look for and measure an incoming pulse on a pin. This is similar in nature to the PBASIC PULSIN feature, but returns the value in microseconds. Also, there is no timeout -- so be careful; no pulse means the code will hang.
    pub pulsin(pin, state) : result | t0
    
    '' Measures pulse on pin in microseconds
    '' -- WARNING: Blocks and does not have timeout
    '' -- pin..... the io pin receving the pulse
    '' -- state... the target state of the pulse
    ''             * 0 for high-low-high
    ''             * 1 for low-high-low
    
      org
                    fltl      pin                                   ' make pin an input
                    testb     state, #0                     wc      ' state.0 is target
    
    .waitidle       testp     pin                           wz      ' sample pin into z
        if_z_eq_c   jmp       #.waitidle                            ' hold for idle state
    
    .delta1         getct     t0                                    ' time at change to state
                    testp     pin                           wz      ' sample pin into z     
        if_z_ne_c   jmp       #.delta1                              ' wait for pin to match state
    
    .delta2         getct     result                                ' time at change back to idle
                    testp     pin                           wz      ' sample pin into z     
        if_z_eq_c   jmp       #.delta2                              ' wait for pin to be idle
    
                    sub       result, t0                            ' difference is pulse width
      end 
    
      return (result + (US_001 >> 1)) / US_001                      ' round to nearest microsecond
    

    The test code creates a pulse generator in another cog. The program does not use a smart pin mode, which allows one cog to write to the pin while another reads from it.
Sign In or Register to comment.