Compose a 16‑bit Status Register with Bit‑Fields and Even Parity
Title: Pack Device Status into a 16‑bit Register (Bit‑Fields + Parity)
Level: Easy
Concepts: Struct with bit‑fields, packing/validation, parity computation, range checks, input validation
Scenario
An embedded peripheral exposes a 16‑bit status register. Some bits are individual flags, others encode small integers. The top bit enforces even parity over the lower 15 bits to detect single‑bit errors. You need to build a correct register value from inputs and validate argument ranges.
Problem Statement
Design and specify a function that packs discrete status inputs into a 16‑bit integer as per the layout below and computes even parity for bit 15. The function must validate inputs and return an error if any field is out of range.
Register layout (bit 15 is MSB, bit 0 is LSB):
[15] PAR [14:12] RETRIES [11:10] MODE [9] READY [8] BUSY [7] FAULT [6:1] RSV [0] RSV
PAR— parity bit (even parity over bits 0..14).RETRIES— 3‑bit value (0..7).MODE— 2‑bit value from enum (0..3).READY,BUSY,FAULT— single‑bit flags (0/1).RSV— reserved, must be0.
Requirements
- Use a bit‑field struct for clarity (members’ widths must sum to 16).
- Do not rely on implementation‑defined struct layout to produce the final integer; explicitly pack with shifts and masks to ensure portability.
- Inputs:
modein{0,1,2,3}(use anenum).retriesin[0..7].ready,busy,faultin{false,true}.
- Outputs:
*out_reg16— the complete 16‑bit status value in anint(lower 16 bits significant).
- Parity: compute even parity of bits 0..14 and place the result into bit 15 so the total number of 1s in bits 0..15 is even.
- Validation: on any invalid input or null output pointer, return error without modifying output.
Function Details
- Name:
build_status_reg16 - Arguments:
enum Mode mode//MODE0=0, MODE1=1, MODE2=2, MODE3=3int retries// 0..7bool readybool busybool faultint *out_reg16
- Return Value:
int—0on success;-1on invalid input (no output written). - Description:
Compose bits as: reg = 0; reg |= (retries & 0x7) << 12; reg |= (mode & 0x3) << 10; reg |= (ready ? 1 : 0) << 9; reg |= (busy ? 1 : 0) << 8; reg |= (fault ? 1 : 0) << 7; // reserved bits remain 0 // compute even parity over bits 0..14, place into bit 15 The bit‑field struct (withintwidths) documents the layout, but final packing must use shifts to avoid implementation‑defined layout and padding issues.
Solution Approach
- Validate
out_reg16 != NULL,0 ≤ retries ≤ 7,mode ∈ {0,1,2,3}. - Build the 15 lower bits via shifts and ORs.
- Compute even parity for bits 0..14 (e.g., xor‑fold then mask
& 1), set bit 15 accordingly. - Write result to
*out_reg16.
Tasks to Perform
- Define
enum Mode { MODE0=0, MODE1=1, MODE2=2, MODE3=3 };. - (For documentation) Define a
struct StatusBitswithintbit‑fields whose widths sum to 16, matching the map. - Implement packing using shifts/masks, not by casting the struct.
- Compute even parity over bits 0..14 and set bit 15.
- Validate ranges and pointer; return
-1on invalid input (no write). - On success, store the 16‑bit value into
*out_reg16and return0.
Test Cases
| # | Inputs / Precondition | Expected Output | Notes |
|---|---|---|---|
| 1 | mode=MODE0, retries=0, ready=false, busy=false, fault=false |
ret=0, reg16 has only parity bit possibly set |
Parity depends on zeros: even parity → PAR=0 |
| 2 | mode=MODE3, retries=7, ready=true, busy=true, fault=true |
ret=0, reg16 bits [14:12]=111, [11:10]=11, [9]=1, [8]=1, [7]=1, PAR set for even parity |
Dense case |
| 3 | mode=MODE1, retries=5, ready=true, busy=false, fault=false |
ret=0, correct fields packed, PAR adjusted |
Mixed flags |
| 4 | retries=-1 |
ret=-1 |
Invalid range |
| 5 | mode=(enum Mode)4 |
ret=-1 |
Invalid enum |
| 6 | out_reg16=NULL |
ret=-1 |
Invalid pointer |