// lesson: bits-and-masks
Bits, Masks, and Read-Modify-Write
A register is rarely one value โ it is 32 independent switches packed into a word. GPIO_OUT bit 25 is the Pico's LED; bit 16 might be your I2C bus. Driving hardware means changing your bits without disturbing anyone else's, which is done with masks:
reg |= mask; /* set every bit that is 1 in mask */
reg &= ~mask; /* clear every bit that is 1 in mask */
reg ^= mask; /* flip every bit that is 1 in mask */
A mask for a single pin is built by shifting: 1u << pin. Note the u โ
shifting a plain (signed) int left into bit 31 is undefined behavior. The
RP2040's GPIO pins only go up to 29, so GPIO_OUT never actually needs bit
31, but plenty of other 32-bit registers use every bit: the SIO has 32
hardware spinlocks, and SIO_SPINLOCK_ST reports all of them as a bitmap,
one bit per spinlock, straight through to bit 31. Use 1u, not 1, and
which register you're shifting into stops mattering.
Each of those compound assignments is really three steps: read the register, modify the copy, write it back. Keep that shape in mind โ it works, but the next lesson shows why on the RP2040 you often want the hardware to do the modify step for you.
โบ Set, Clear, Toggle
10 ptsImplement the three classic read-modify-write helpers. Each takes a pointer to a register and a mask, and must leave every bit outside the mask exactly as it found it.
Log in to submit a solution and earn points.