Set Baud Rate Field in Control Register

Code

#include <stdio.h>
#include <stdint.h>
#include <limits.h>

#define BUAD_RATE_CONST     0xFU
#define BAUD_RATE_START_BIT 8U
#define BAUD_RATE_END_BIT   11U

#define BAUD_RATE_MASK(start, end)  (((1ULL << (end + 1)) - 1) >> start) << start

uint32_t set_baud_rate(uint32_t reg, uint8_t baud) 
{
    baud &= BUAD_RATE_CONST;
    reg &= ~((uint32_t) BAUD_RATE_MASK(BAUD_RATE_START_BIT, BAUD_RATE_END_BIT));
    reg |= (baud << BAUD_RATE_START_BIT);
    return reg;
}

int main() 
{
    uint32_t reg;
    uint8_t baud;
    scanf("%u %hhu", &reg, &baud);
    printf("%u", set_baud_rate(reg, baud));
    return 0;
}

Solving Approach

This code is a practical implementation of a register configuration function, specifically designed to set a "Baud Rate" field within a 32-bit control register. It uses a Clear-and-Set strategy to ensure that only the intended bits are modified.

1. The Memory Map

In many hardware systems, a single 32-bit register controls multiple features. In this specific code, the "Baud Rate" is mapped to a 4-bit field located at bits 8, 9, 10, and 11.

  • BAUD_RATE_START_BIT (8): The beginning of the field.

  • BAUD_RATE_END_BIT (11): The end of the field.

  • BUAD_RATE_CONST (0xF): A safety mask (binary 1111) ensuring the baud rate value does not exceed 4 bits.

2. How the Function Works

The set_baud_rate function follows three precise steps:

Step A: Sanitize the Input

baud &= BUAD_RATE_CONST;

Before doing anything, the code masks the baud input. This is a "fail-safe" measure. If a user accidentally passes a value like 255, this line trims it down to fit within 4 bits (max value 15), preventing it from corrupting other parts of the register.

Step B: Clear the "Slot"

reg &= ~((uint32_t) BAUD_RATE_MASK(...));

The code generates a mask of 1s for bits 8–11 and then inverts it (using ~). By performing a bitwise AND, it "zeros out" the existing baud rate bits while preserving all other settings in the register (like parity, stop bits, or flow control).

Step C: Insert the New Value

reg |= (baud << BAUD_RATE_START_BIT);

Finally, the sanitized baud value is shifted left by 8 positions to align with the "slot" and merged into the register using a bitwise OR.

Step-by-Step Example

Suppose the register is currently set to 0x00000F00 (Baud Rate is maxed out) and you want to change the Baud Rate to 5 (0101 in binary).

Step

Operation

Result (Hex)

Result (Binary bits 11-8)

Initial

reg

0x00000F00

1111

Clear

reg &= ~0xF00

0x00000000

0000

Align

5 << 8

0x00000500

0101

Merge

reg | 0x500

0x00000500

0101

Key Takeaways for Others

  • Safety First: The use of 1ULL in the macro and the BUAD_RATE_CONST mask makes this code robust against "buffer overflows" of bit-fields.

  • Maintainability: By using #define for the start and end bits, a developer can change the hardware mapping in one place without rewriting the logic.

  • Non-Destructive: This is a "surgical" update. It changes exactly 4 bits and leaves the other 28 bits of the register completely untouched.

Upvote
Downvote
Loading...

Input

0 10

Expected Output

2560