58. ADC Config Flags

In embedded systems, peripheral configuration registers commonly use bit flags to enable or disable features.

Your task is to declare a scoped enum class named AdcConfig that represents configuration flags for an ADC peripheral. Each flag occupies a single bit in an 8-bit configuration register.

The enum must contain the following values:

  • ChannelEnable → bit 0 (value 1)
  • InterruptEnable → bit 1 (value 2)
  • DMAEnable → bit 2 (value 4)

You must also implement a helper function:

void printConfig(uint8_t cfg);

This function examines the configuration word and prints which features are enabled.

The program reads three integers, each being either 0 or 1, indicating whether the corresponding feature is enabled:

  1. Channel enable
  2. Interrupt enable
  3. DMA enable

These inputs must be combined into a single 8-bit configuration word using bitwise operations, then passed to printConfig().

If no flags are enabled, print None.

Input Format

  • Three space-separated integers: ch intr dma
  • Each value is guaranteed to be either 0 or 1
  • Input order corresponds to:
    • ch → ChannelEnable
    • intr → InterruptEnable
    • dma → DMAEnable

Output Format

  • Print enabled feature names in the following fixed order:
    1. ChannelEnable
    2. InterruptEnable
    3. DMAEnable
  • Separate multiple names with a single space.
  • If no features are enabled, output exactly:
    • None 

 

Example 1

Input:

1 0 1

Output:

ChannelEnable DMAEnable

 

Example 2

Input:

0 0 0

Output:

None

 

 

 

 

 

 

Need Help? Refer to the Quick Guide below

In C, a standard enum is essentially a set of named integers. These names leak into the global scope (causing naming collisions) and implicitly convert to int (causing logical bugs).

In C++, enum class (also called a Scoped Enum) solves these issues.

  1. Scoped: Enum values are local to the enum (accessed via EnumName::Value).
  2. Strongly Typed: They do not implicitly convert to integer.
  3. Fixed Size: You can explicitly define the underlying integer type (e.g., uint8_t) to save memory.

Syntax & Usage

1. Basic Declaration

// C-Style (Unsafe)
enum Color { RED, GREEN, BLUE }; 
// int x = RED; // ✅ Valid but dangerous

// C++ Style (Safe)
enum class Status { 
    OK, 
    ERROR, 
    BUSY 
};

// Status s = OK;          // ❌ Error: Unknown identifier 'OK'
Status s = Status::OK;     // ✅ Correct

2. Specifying Underlying Type (Crucial for Embedded)

You can force the enum to use a specific integer size instead of the compiler default (usually int / 4 bytes).

// Force use of 8-bit integer (1 byte)
enum class State : uint8_t {
    IDLE = 0,
    RUNNING = 1,
    FAULT = 2
};

// sizeof(State) is now guaranteed to be 1 byte.

Comparison: Old vs New

FeatureC-Style enumC++ enum class
ScopeLeaks names to surrounding scope.Namespaces names (Enum::Value).
Type SafetyImplicitly converts to int.No implicit conversion.
ComparisonCan compare different enums (COLOR_RED == STATE_OFF).Compile Error (Safe).
SizeImplementation defined (usually int).User defined (default int).

Relevance in Embedded/Firmware

1. Saving RAM & Flash

By defining enum class State : uint8_t, you ensure that variables of this type only consume 1 byte. Standard enums often default to 32-bit (4 bytes), wasting memory in struct layouts or arrays.

2. Preventing State Machine Bugs

In C, if you have enum Motor { OFF, ON } and enum LED { OFF, ON }, the compiler errors because OFF is defined twice.

With enum class Motor and enum class LED, Motor::OFF and LED::OFF are distinct. You can never accidentally assign a Motor state to an LED variable.

3. Switch-Case Safety

Modern compilers can warn you if a switch statement on an enum class does not handle all possible cases, ensuring you don't miss a new state added later.

Common Pitfalls (Practical Tips)

PitfallDetails
❌ Implicit Int Casting

int x = State::IDLE; fails. You must use explicit casting:

int x = static_cast<int>(State::IDLE);

❌ Bitwise Flagsenum class does not support `
✅ Usage RuleUse enum class for distinct states (State Machines, Error Codes). Use old enum or namespace constants for bitmasks.
✅ Validating Inputs

Just because it's an enum class doesn't mean the value is valid.

State s = static_cast<State>(99); is valid code but undefined logic. Always validate raw data before casting to an enum.