PDA

View Full Version : Bit fiddling in ICCV7



Q*bert
03-31-2009, 06:09 AM
I have been writing some stuff in Imagecraft C lately and found myself fumbling around when
doing all the bit fiddling required when programming a microcontroller.

I remembered some macros I had found when i was doing AVR C programming, so I blew the
dust off of them and here they are!

// macros for bit fiddling in C (from AVR tech notes and AVRfreaks.com forum discussions)

#define SETBIT(ADDRESS,BIT) (ADDRESS |= (1<<BIT))
#define CLEARBIT(ADDRESS,BIT) (ADDRESS &= ~(1<<BIT))
#define FLIPBIT(ADDRESS,BIT) (ADDRESS ^= (1<<BIT))
#define CHECKBIT(ADDRESS,BIT) (ADDRESS & (1<<BIT))

#define SETBITMASK(x,y) (x |= (y))
#define CLEARBITMASK(x,y) (x &= (~y))
#define FLIPBITMASK(x,y) (x ^= (y))
#define CHECKBITMASK(x,y) (x & (y))

#define VARFROMCOMB(x, y) x
#define BITFROMCOMB(x, y) y

#define C_SETBIT(comb) SETBIT(VARFROMCOMB(comb), BITFROMCOMB(comb))
#define C_CLEARBIT(comb) CLEARBIT(VARFROMCOMB(comb), BITFROMCOMB(comb))
#define C_FLIPBIT(comb) FLIPBIT(VARFROMCOMB(comb), BITFROMCOMB(comb))
#define C_CHECKBIT(comb) CHECKBIT(VARFROMCOMB(comb), BITFROMCOMB(comb))


These can be really handy as you don't need to recall the bit logic over and over again.

The last four macros deserve an example to show how they can be used:

/******* C_ macros usage example *********/
#define Status_LED OUTA, 3

C_SETBIT(Status_LED);
C_CLEARBIT(Status_LED);


I hope these help someone simplify their C programming. I know my aging mind appreciates
the help!

BTW, I am really enjoying the Imagecraft compiler. Watch for some new libraries soon!

jazzed
03-31-2009, 06:20 AM
Nice work. Have a look at this for other macros: <your icc path>/include/propeller.h

▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
--Steve


Propalyzer: Propeller PC Logic Analyzer (http://www.brouhaha.com/~sdenson/Propalyzer)
http://forums.parallax.com/showthread.php?p=788230 (http://forums.parallax.com/showthread.php?p=788230)

Q*bert
03-31-2009, 08:05 AM
jazzed said...
Nice work. Have a look at this for other macros: <your icc path>/include/propeller.h


Thanks jazzed. I didn't notice the bit macros in there.

Below are some of the same macros I showed earlier. Any idea why they surround them in a do {} while(0) loop?

/**
* Clear a bit in val
* @param val variable where bit will be cleared
* @param bit is bit number to clear.
*/
#define CLR(val,bit) do { (val) &= ~(1 << (bit)); } while (0)

/**
* Set a bit in val
* @param val variable where bit will be set
* @param bit is bit number to set.
*/
#define SET(val,bit) do { (val) |= (1 << (bit)); } while (0)

/**
* Flip a bit in val
* @param val variable where bit will be toggled
* @param bit is bit number to toggle.
*/
#define FLIP(val,bit) do { (val) ^= (1 << (bit)); } while (0)

ImageCraft
03-31-2009, 08:24 AM
Surrounding an expression in a do while (0) "loop" means that the macro can be used almost anywhere (as part of if body etc.)

TJHJ
03-31-2009, 11:14 PM
Want to turn this thread into a handy list of macros?

SET, CLR, FLIP work well for all the outbound stuff, but no way in read the input pins for the predefined macro's.

This one has been the handiest one Ive got so far. Thanks Forum peeps.

#define PinState(pin) ( (INA >> pin) & 1) )// pin >= 0 and pin <= 31

TJ

▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
I owe everyone here a bunch, So thanks again for answering my dumb questions.
Projects. RG500 ECU system. PropCopter. Prop CanSat. Prop Paste Gun.
Suzuki RG500 in a RGV 250 frame.
Bimota V-Due (Running on the fuel injection system)
Aprilia RS250

jazzed
04-01-2009, 12:53 AM
TJHJ,

Yes, you're right I forgot "GET". Maybe Richard can fix that for the next release.

(warning: untested generic GET macro)
/**
* Get a bit from a val
* @param val variable where bit will be fetched.
* @param bit is bit number to get.
* @return binary value (1 or 0) of the selected bit.
*/
#define GET(val,bit) ( ((val) & (1 << (bit))) >> bit )

Being picky to avoid corner case problems, one should always surround the incoming parameter symbol(s) for a macro with parenthesis. In yours and some other macros "pin" is "expanded" as part of the statement.

For example, this does not do what you might think because of C order of operation rules (which are different from spin ... what a pain):

#define PinState(pin) ((INA >> pin) & 1))

int foo(void)
{
int a,b,c;
a = 7;
b = 2;
c = PinState(a & b);
return c;
}

Here PinState is translated as:
(INA >> a & b) & 1 --> ((INA >> 7) & 2) & 1

Using (pin) instead
#define PinState(pin) ((INA >> (pin)) & 1))
(INA >> (a & b)) & 1 --> (INA >> 2) & 1

BTW: do { ...; ...; } while(0) is not needed here because the macro definition is a single self contained expression.

▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
--Steve


Propalyzer: Propeller PC Logic Analyzer (http://www.brouhaha.com/~sdenson/Propalyzer)
http://forums.parallax.com/showthread.php?p=788230 (http://forums.parallax.com/showthread.php?p=788230)