The binary operator '|' is the bitwise-or operator; for each bit in the two input words, if either bit is a 1, then the corresponding bit in the result is a 1:
0001 | 0010 = 0011
The '|' operator is typically used to set individual bits in a word, such as in the code snippet you posted.
The binary operator '&' is the bitwise-and operator; for each bit in the two input words, if both bits are 1, then the corresponding bit in the result is a 1:
0101 & 0110 = 0100
The '&' operator can be used to test if a bit is set. For example, to test if the MSGINFO_ENABLE bit is set, you'd do something like
if (VirtBoard.msginfo_mask & MSGINFO_ENABLE != 0)
{
/* MSGINFO_ENABLE bit is set, do something interesting */
}
The expression
VirtBoard.msginfo_mask & MSGINFO_ENABLE
will evaluate to 1 (0x0001) if the MSGINFO_ENABLE bit was set,0 otherwise.
The unary operator '~' is the bitwise-not operator; for each bit in the input word, the corresponding bit in the result is set to the opposite value:
~ 0001 = 1110
You can use the '~' operator together with the '&' operator to clear an individual bit. For example, if we wanted to clear the MSGINFO_ENABLE bit, we'd do something like
VirtBoard.msginfo_mask = VirtBoard.msginfo_mask & ~MSGINFO_ENABLE;
which can be shortened to
VirtBoard.msginfo_mask &= ~MSGINFO_ENABLE;
Negating MSGINFO_ ENABLE gives us 1111111111111110 (assuming a 16-bit unsigned int); since the leading bits are all 1, and-ing this against the VirtBoard.msginfo_ mask preserves any bits that are already set; i.e., 0000000000001111 & 1111111111111110 = 0000000000001110.
If we wanted to clear both the MSGINFO _ENABLE and TRANSADDR _ENABLE bits, we'd combine all the operators like so:
VirtBoard.msginfo_mask &= ~(MSGINFO_ENABLE | TRANSADDER_ENABLE)