Problem setting GPIO bits using PINSEL Registers

217 views Asked by At

Could someone please explain me how does this

LPC_PINCON->PINSEL1 &= ~(0x03 << 18);

clears bits 18 and 19 of Port 1? Would

LPC_PINCON->PINSEL1 &= ~(1 << 18);
LPC_PINCON->PINSEL1 &= ~(1 << 19);

give the same result?

2

There are 2 answers

0
0___________ On

Your question shoes that you need to learn logical and binary operations

From codescope.com\

Setting a bit. Use the bitwise OR operator ( | ) to set a bit. `number |= 1 << x;` That will set a bit x .
Clearing a bit. Use the bitwise AND operator ( & ) to clear a bit. `number &= ~(1 << x);` That will clear bit x . ...
Toggling a bit. The XOR operator ( ^ ) can be used to toggle a bit. `number ^= 1 << x;`

Same applies if instead of 1 you will use another number. 3 is in binary 11 and it will clear two bits.

0
Frant On

From a boolean point of view, yes, the two options are equivalent - using Qalculate for stating the obvious (it can evaluate expressions such as ~(0x03 << 18)):

~(0x03 << 18) = 1111 1111 1111 0011 1111 1111 1111 1111
~(1 << 18)    = 1111 1111 1111 1011 1111 1111 1111 1111
~(1 << 19)    = 1111 1111 1111 0111 1111 1111 1111 1111

The truth table for the and boolean operation being:

A   B   Q
0   0   0
0   1   0
1   0   0
1   1   1

All bits [0..31] in LPC_PINCON->PINSEL1 will stay unmodified when the bitwise and operation will be performed against the 1 value in the bit mask at the same position.

All bits [0..31] in LPC_PINCON->PINSEL1 will be set to zero when the bitwise and operation will be performed against the 0 value in the bit mask at the same position.

So yes, LPC_PINCON->PINSEL1 will ultimately contain the same value in both cases.

But performing the operation in two steps will result in changing two or three times in a row the functional role of your pin, depending on the value of LPC_PINCON->PINSEL1 at the time you will start modifying it.

This may affect the behavior of what is connected to your pin in the case you would already have set values in the corresponding LPC_GPIOn –> FIODIR for example, or other in registers configuring any of the possible alternate functions for this specific pin.

That means configuring the GPIO mode in a single operation is probably a better option, and the two options are therefore not equivalent from an hardware point of view.