karra
karra

Reputation: 378

Identifying a specific binary number with bitmask

I am trying to identify states in a CANopen motor controller using the following bit masks.

//x means that the value of the bit doesn't matter and is set to 0
NOT_READY_TO_SWITCH_ON = 0,    //xxxx xxxx x0xx 0000 - Not ready to switch on (decimal value = 0)
SWITCH_ON_DISABLED = 64,       //xxxx xxxx x1xx 0000 - Switch on disabled (decimal value = 64)
READY_TO_SWITCH_ON = 33,       //xxxx xxxx x01x 0001 - Ready to switch on (33)
SWITCHED_ON = 35,              //xxxx xxxx x01x 0011 - Switched on (35)
OPERATION_ENABLED = 39,        //xxxx xxxx x01x 0111 - Operation enabled (39)
QUICK_STOP_ACTIVE = 7,         //xxxx xxxx x00x 0111 - Quick stop active (7)
FAULT_REACTION_ACTIVE = 15,    //xxxx xxxx x0xx 1111 - Fault reaction active (15)
FAULT = 8,                     //xxxx xxxx x0xx 1000 - Fault (8)

I am receiving a number on which I apply the bit mask to try to identify the states above but I can't wrap my head around how it should be done.

The following code is my attempt to implement it in C#:

foreach (State s in (State[]) Enum.GetValues(typeof(State))) //State[] contains all bitmasks above
{  
   var v = valToCheck & (ushort)s; //valToCheck is the number to apply the bitmask to
   if ((valToCheck & (ushort)s) == (ushort)s) //Apply the bitmask and compare it to bitmask
   {
      stateList.Add(s); //Add to list for trouble. shooting
   }
}

But doing it this way I end up with, instead of one, a bunch of states which is, I guess, expected since applying for example, the bitmask 0 (NOT_READY_TO_SWITCH_ON) will always yield true for any number (when using and).

Am I doing something fundamentally wrong or is this simply not possible using bit masks? I am also unsure if it is correct to set the bits marked with x to 0 in the masks.

Upvotes: 1

Views: 201

Answers (1)

Marc Gravell
Marc Gravell

Reputation: 1064294

You're right - you can't test for 0 with masks; presumably the intent is that all zero has special meaning that only matches this flag, so you would special case it by testing for equality with zero instead:

if (thingToLookFor == 0) return value == 0;

Upvotes: 1

Related Questions