Shop OBEX P1 Docs P2 Docs Learn Events
Setting bits in DIRA, OUTA, etc. — Parallax Forums

Setting bits in DIRA, OUTA, etc.

RaymanRayman Posts: 14,665
edited 2013-03-30 14:31 in Propeller 1
Looking for the best way to tidy up my spin2cpp'd code...

The original spin looked like this:
outa[FlashEnable]~~ 
dira[FlashEnable]~~

After spin2cpp, it works, but looks like this:
OUTA = ((OUTA & 0xfffffdff) | 0x200);
DIRA = ((DIRA & 0xfffffdff) | 0x200);

I did notice that PropGCC has added setpin, but I don't think this will help for DIRA...
Was looking at this page: http://www.coranac.com/documents/working-with-bits-and-bitfields/
and think I like the bit macros there:
#define BIT(n)                  ( 1<<(n) )
#define BIT_SET(y, mask)        ( y |=  (mask) )
#define BIT_CLEAR(y, mask)      ( y &= ~(mask) )
#define BIT_FLIP(y, mask)       ( y ^=  (mask) )


So, now my code looks like this:
BIT_SET(OUTA,BIT(Flashenable));
BIT_SET(DIRA,BIT(Flashenable));

Anybody know a more clear way?

Comments

  • RaymanRayman Posts: 14,665
    edited 2013-03-29 12:40
    Actually, I think I like it better without the macro, like this:
    OUTA|=1<<Flashenable;
    DIRA|=1<<Flashenable;
    
  • David BetzDavid Betz Posts: 14,516
    edited 2013-03-29 12:42
    Rayman wrote: »
    Actually, I think I like it better without the macro, like this:
    OUTA|=1<<Flashenable;
    DIRA|=1<<Flashenable;
    
    Well, that's perfectly readable to a C programmer. However, I think you're unlikely to do it that way on the P2 which has setp, clrp, etc instructions that don't require the mask.
  • RaymanRayman Posts: 14,665
    edited 2013-03-29 13:06
    Actually, I think I'd like the PropGCC version if it were more like the P2 commands... Perhaps:

    setpin(pin)
    clearpin(pin)

    instead of:

    setpin(pin,value)


    Wouldn't that make the inline assembly 2X faster too?
  • RaymanRayman Posts: 14,665
    edited 2013-03-29 13:27
    feeling adventurous, I've added this to Propeller2.h:

    static __inline__ void setp(int pin)
    {
        __asm__ volatile (
            "setp %[_pin]"
        : /* outputs */
        : /* inputs */
            [_pin]"r" (pin)
        : /* no clobbered registers */
        );
    }
    static __inline__ void clrp(int pin)
    {
        __asm__ volatile (
            "clrp %[_pin]"
        : /* outputs */
        : /* inputs */
            [_pin]"r" (pin)
        : /* no clobbered registers */
        );
    }
    
    
  • David BetzDavid Betz Posts: 14,516
    edited 2013-03-29 13:45
    Rayman wrote: »
    Actually, I think I'd like the PropGCC version if it were more like the P2 commands... Perhaps:

    setpin(pin)
    clearpin(pin)

    instead of:

    setpin(pin,value)


    Wouldn't that make the inline assembly 2X faster too?
    If you pass constant values into the setpin inline function it will generate exactly the same code as your setp function since the GCC optimizer will get rid of the if statement.

    Also, if you're going to add something to propeller2.h, you should add the same thing to propeller1.h. The whole idea of these functions is to allow writing code that works on both chips.
  • SRLMSRLM Posts: 5,045
    edited 2013-03-29 14:01
    Rayman wrote: »
    Actually, I think I like it better without the macro, like this:
    OUTA|=1<<Flashenable;
    DIRA|=1<<Flashenable;
    


    If you wanted to be really creative, you could define a new "operator" :)
    #define $= |=1<<
    
    ...
    OUTA $= FlashPin;
    

    :)
  • RaymanRayman Posts: 14,665
    edited 2013-03-29 14:17
    David, I'm not really planning on adding anything to Propeller*.h... Just playing around...

    SRLM, I like that!

    But, I guess I should get in line and use setpin...
  • RaymanRayman Posts: 14,665
    edited 2013-03-29 14:46
    Can the optimizer really turn a rcl, setpc into one setp instruction?
  • David BetzDavid Betz Posts: 14,516
    edited 2013-03-29 17:54
    Rayman wrote: »
    Can the optimizer really turn a rcl, setpc into one setp instruction?
    Hmmm... Maybe not. I had forgotten how I defined the setpin inline function. Sorry.
  • RaymanRayman Posts: 14,665
    edited 2013-03-30 10:34
    In that case, I think it would be useful to have offp, notp, clrp, and setp instructions.
    I'm not sure I like offp though because it sounds like it toggles DIR instead of actually turning it off...
  • David BetzDavid Betz Posts: 14,516
    edited 2013-03-30 10:38
    Rayman wrote: »
    In that case, I think it would be useful to have offp, notp, clrp, and setp instructions.
    I'm not sure I like offp though because it sounds like it toggles DIR instead of actually turning it off...
    togglep maybe? We should first try setpin with a constant pin number to see what gcc does with it.
  • RaymanRayman Posts: 14,665
    edited 2013-03-30 10:42
    It just seems to me that setting and clearing a pin is one of the first things that people are going to know how to do.
    And so, making that as simple and clear as possible (and fast too) should be important...
  • David BetzDavid Betz Posts: 14,516
    edited 2013-03-30 11:01
    Rayman wrote: »
    It just seems to me that setting and clearing a pin is one of the first things that people are going to know how to do.
    And so, making that as simple and clear as possible (and fast too) should be important...
    If we do this, I'm wondering what should be done with setpin(). It might be confusing to have both setpin and setp. They sound like synonyms. Maybe need a better name for setpin.
  • RaymanRayman Posts: 14,665
    edited 2013-03-30 13:37
    Can it just be overloaded?
  • ersmithersmith Posts: 6,054
    edited 2013-03-30 14:21
    David Betz wrote: »
    togglep maybe? We should first try setpin with a constant pin number to see what gcc does with it.

    As it's currently written it will be two instructions, but there are other ways to write it. I'm sure we could re-work it so that it'll come out to 1 instruction on constants and 2 on unknown quantities. I think this would be preferable to introducing a bunch of additional macros.

    Eric
  • RaymanRayman Posts: 14,665
    edited 2013-03-30 14:31
    I've just read in the P2 forum that setp also affects the DIR register and so does offp. So, these behave differently than I thought...
    Now, I think they should be kept seperate from setpin, if you want P1 and P2 code to do the same things...

    never mind...

    Actually, after looking at Propeller1.h, I see you've already made it so setpin works the same for P1 and P2.

    getpin can't really work the same because the hardware is different.
    The P2 version returns the output state, not the actual input state. But, I suppose these would
    usually be the same.
    The prop1 version makes the pin an output too, maybe the real P2 does this too.

    I think it'd be nice if there were a P2 command to return the input state of any pin.
    If I'm reading it right, that only comes from reading the PINX registers...

    Update: pedward just said I have getpin wrong and it returns the input state.
    In this case, I think the P1 version of getpin shouldn't be setting OUTA...
Sign In or Register to comment.