basics · beginner · ~15 min

Bitwise Hardware Control Register

Set, clear, toggle, and inspect hardware flag registers using bitwise logic.

Challenge

Embedded systems communicate with peripherals by reading and modifying individual bits within hardware control registers using bitwise operators (&, |, ^, ~).

Your Task

Given the bitmask definitions:

#define FLAG_POWER      (1u << 0) // 0x01
#define FLAG_TX_READY   (1u << 1) // 0x02
#define FLAG_RX_READY   (1u << 2) // 0x04
#define FLAG_ERROR      (1u << 3) // 0x08
#define FLAG_INTERRUPT  (1u << 4) // 0x10

Implement register manipulation functions:

uint8_t reg_set_flag(uint8_t reg, uint8_t mask);
uint8_t reg_clear_flag(uint8_t reg, uint8_t mask);
uint8_t reg_toggle_flag(uint8_t reg, uint8_t mask);
int reg_has_flag(uint8_t reg, uint8_t mask);

Rules

  1. reg_set_flag: sets all bits in mask using |.
  2. reg_clear_flag: clears all bits in mask using & ~mask.
  3. reg_toggle_flag: toggles all bits in mask using ^.
  4. reg_has_flag: returns 1 if all bits in mask are currently set in reg, or 0 otherwise. If mask == 0, return 0.

Example

uint8_t r = 0;
r = reg_set_flag(r, FLAG_POWER | FLAG_TX_READY); // 0x03
reg_has_flag(r, FLAG_POWER); // returns 1
reg_has_flag(r, FLAG_RX_READY); // returns 0
r = reg_clear_flag(r, FLAG_POWER); // 0x02

Input format

reg: 8-bit register state; mask: 8-bit flag mask.

Output format

Returns updated register value or boolean match flag.

Constraints

Bitwise operations only. No branches in set/clear/toggle.

Starter code

#include <stdint.h>

#define FLAG_POWER      (1u << 0)
#define FLAG_TX_READY   (1u << 1)
#define FLAG_RX_READY   (1u << 2)
#define FLAG_ERROR      (1u << 3)
#define FLAG_INTERRUPT  (1u << 4)

uint8_t reg_set_flag(uint8_t reg, uint8_t mask) {
    (void)reg; (void)mask;
    return 0;
}
uint8_t reg_clear_flag(uint8_t reg, uint8_t mask) {
    (void)reg; (void)mask;
    return 0;
}
uint8_t reg_toggle_flag(uint8_t reg, uint8_t mask) {
    (void)reg; (void)mask;
    return 0;
}
int reg_has_flag(uint8_t reg, uint8_t mask) {
    (void)reg; (void)mask;
    return 0;
}

Common mistakes

Using logical || instead of bitwise |; forgetting ~ when clearing bits.

Edge cases to handle

mask == 0 returns 0 in has_flag; multi-bit masks must all be present in has_flag.

Background lessons

Solve this exercise in the browser editor — compile and run against the test harness, no setup required.