Shop OBEX P1 Docs P2 Docs Learn Events
Fastest way to flip a bit... — Parallax Forums

Fastest way to flip a bit...

dkemppaidkemppai Posts: 315
edited 2009-07-08 01:45 in General Discussion
OK, I'm having a mental block...

What's the fastest way in ASM to toggle an I/O pin or register bit, knowing only the pin or bit·in question.

For example, RA.4 needs to be toggled every time I run a sub. What's the least amount of·code to do this.
I can read the state of the pin from the I/O registers or register.· The pin/bit·doesn't change often, but when I need
to change it·I need to conserve clock cycles...

Also, Jitter is not a concern.

Thanks,
Dan


▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔

"A saint-like quantity of patience is a help, if this is unavailable, a salty vocabulary works nearly as well." - A. S. Weaver

Comments

  • dkemppaidkemppai Posts: 315
    edited 2009-07-02 19:52
    ·This is what I have:

    jb···· MyBit,$+4
    setb MyBit
    skip
    clrb· MyBit


    Anyone have anything faster/shorter...

    Thanks,
    Dan


    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔

    "A saint-like quantity of patience is a help, if this is unavailable, a salty vocabulary works nearly as well." - A. S. Weaver
  • Peter VerkaikPeter Verkaik Posts: 3,956
    edited 2009-07-02 20:01
    If the bitposition is known,

    mov w,#1<<bitpos
    xor targetvar,w

    This is assumed the bank is already set, or targetvar is global,
    as ports are.

    regards peter
  • JonnyMacJonnyMac Posts: 9,412
    edited 2009-07-02 20:31
    Since you know it's RA.4 that you want to toggle you can hard-code Peter's example:

    mov w, #%0001_0000
    xor ra, w
  • dkemppaidkemppai Posts: 315
    edited 2009-07-03 00:17
    Peter Verkaik said...
    If the bitposition is known,

    mov w,#1<<bitpos
    xor targetvar,w

    This is assumed the bank is already set, or targetvar is global,
    as ports are.

    regards peter
    I didn't think of xoring...·· ...I'll have to remember that. (Although, I do use XOR gates to buffer/invert data streams via logic control...)

    The problem is that the pin/bit is an assigned name·variable, and may move depending on where I use this code. For example:

    MyPin· equ·· RA.1 in one example...
    MyPin· equ·· RE.3 the next time I use it.

    I good example would be a macro called "FlipBit", where I call the macro, and pass·"MyPin" to the macro...

    Is there any way to determine the bit position of a bit in a variable in the macro language?

    Thanks!
    Dan

    P.S. I'm really starting to like macros...· [noparse]:)[/noparse]


    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔

    "A saint-like quantity of patience is a help, if this is unavailable, a salty vocabulary works nearly as well." - A. S. Weaver
  • ZootZoot Posts: 2,227
    edited 2009-07-03 01:36
    
    MyPinPort PIN RA ' could be RA through RE
    MyPinNum CON 3 ' could be 0 through 7, will be pin num on pin port
    MyLed PIN MyPinPort.MyPinNum OUTPUT
    
    
    ' now to flip the bit....
    
    ASM
    MOV W, #1<<MyPinNum
    XOR MyPinPort, W
    ENDASM
    
    'and some pin var stuff:
    MyLed = 1
    PAUSE 100
    MYLed = 0
    
    



    So you can change the pin assignment to any pin any port w/o rewriting code.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    When the going gets weird, the weird turn pro. -- HST

    1uffakind.com/robots/povBitMapBuilder.php
    1uffakind.com/robots/resistorLadder.php
  • CounterRotatingPropsCounterRotatingProps Posts: 1,132
    edited 2009-07-03 17:15
    > For example, RA.4 needs to be toggled every time I run a sub.
    The code sample is a near call, but I'm wondering about the below·for my own thing... should just hook it up and see...

    If that were·a far call instead, wouldn't that force the pipeline to flush, and increase the toggle cycles, decreasing the toggle speed?

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
  • dkemppaidkemppai Posts: 315
    edited 2009-07-08 00:57
    CounterRotatingProps said...
    > For example, RA.4 needs to be toggled every time I run a sub.

    The code sample is a near call, but I'm wondering about the below·for my own thing... should just hook it up and see...

    If that were·a far call instead, wouldn't that force the pipeline to flush, and increase the toggle cycles, decreasing the toggle speed?
    Guys,

    All I'm after is as short a command as possible to flip the current state of a bit. It would be really nice to have an assembly instruction that was 'toggle x' where x is the bit. We have setb and clrb, but no way to just toggle the bit, so it must be done with some sort of a branch. I'd really like as short a chunk of code to be placed in a macro ·so it could be called without having to think about the garbage invoved in flipping the bit. (Trying to reduce the mundane tasks to simple macros...)

    I assign logical pin names. Such as "RunLED" to the pin. That way, if I end up moving the·physical location of·"RunLED", then I don't have to recode everythig in the program, and I don't have to think about what's mapped where. I just know that "RunLED" is my·Run LED...

    Unless there is a way to get the port and pin number from only the logical name "RunLED", I don't think there is anything shorter than what I currently use. (Is there a way in the macro language to get the register and bit number?) Also, I believe the XOR option may set you up for the read/write pipeline bug, no?

    Again, I like the xor option, as it reduces clock cycles and is short, but is a little harder to apply in a macro as I would like to do...

    Thanks!
    Dan




    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔

    "A saint-like quantity of patience is a help, if this is unavailable, a salty vocabulary works nearly as well." - A. S. Weaver
  • ZootZoot Posts: 2,227
    edited 2009-07-08 01:45
    If you want a ready "macro" that tracks any bit/pin by name, then just use SX/B:

    ASM
    ' lots of assembly
    ENDASM
    RunLed PIN RA.3 OUTPUT
    ASM
    ' lots of assembly
    ENDASM
    RunLed = ~RunLed ' this will generate code automatically
    ASM
    ' lots of assembly
    ENDASM
    
    



    Not sure where you get a "branch" with a MOV W, #1<<x, XOR Port, W, it's two instructions every time. The r/w/m pipeline error only kicks in with SETB and CLRB, not on a whole port instruction, like the XOR Port. Macro:

    MACRO TOGGLE_BIT ' use: TOGGLE_BIT PinNum, PinPort
         MOV W, #1<<\1
         XOR \2, W
         ENDM
    
    

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    When the going gets weird, the weird turn pro. -- HST

    1uffakind.com/robots/povBitMapBuilder.php
    1uffakind.com/robots/resistorLadder.php


    Post Edited (Zoot) : 7/8/2009 1:51:14 AM GMT
Sign In or Register to comment.