cmake_cpputest_template/inc/extralibs/register_debug_utilities.h
2025-12-23 14:33:54 -08:00

142 lines
3.3 KiB
C

#include <stdio.h>
//! ####################################
//! PRINT BITS
//! ####################################
// eg: UTIL_PRINT_BITS(reg, 32, 16);
void UTIL_PRINT_BITS(u32 val, u8 len, u8 divider_len) {
const char* separator = "\n";
for (int i = (len)-1; i >= 0; i--) {
printf("%d| ", i);
if (i > 0) printf(i % divider_len ? "" : "%s", separator);
}
printf("\n");
for (int i = (len)-1; i >= 0; i--) {
printf(i < 10 ? "%2d" : "%3d", ((val) >> i) & 1);
if (i > 0) printf(i % divider_len ? " " : " %s", separator);
}
}
//! ####################################
//! PRINT BITS VALUES
//! ####################################
// eg: UTIL_PRINT_BITS_VALUES(
// reg,
// "a", 0,
// "b", 1,
// "c", 2,
// );
void UTIL_PRINT_BITS_VALUES(u32 reg, ...) {
struct BitPair { const char* name; int pos; };
va_list args;
va_start(args, reg);
// Count how many pairs were passed (until NULL name)
int pair_count = 0;
va_list count_args;
va_copy(count_args, args);
while (1) {
const char* name = va_arg(count_args, const char*);
if (name == NULL) break;
int pos = va_arg(count_args, int);
(void)pos;
pair_count++;
}
va_end(count_args);
// Read all the pairs
struct BitPair pairs[pair_count];
for (int i = 0; i < pair_count; i++) {
pairs[i].name = va_arg(args, const char*);
pairs[i].pos = va_arg(args, int);
}
va_end(args);
// Print the pairs
for (int i = 0; i < pair_count; i++) {
if (i > 0) printf(", ");
printf("%s=%d", pairs[i].name, (unsigned int)((reg >> pairs[i].pos) & 1));
}
}
//! ####################################
//! PRINT BITS RANGE
//! ####################################
// eg: UTIL_PRINT_BIT_RANGE(
// reg,
// "FIELD3", 5, 3,
// "FIELD2", 2, 1,
// "FIELD1", 0, 0,
// NULL
// );
// NOTE: NULL terminated REQUIRED
void UTIL_PRINT_BIT_RANGE(u32 reg, ...) {
// Define the struct
typedef struct { const char* name; int end; int start; } BitField;
va_list args;
va_start(args, reg);
// Count how many fields were passed (until NULL name)
int field_count = 0;
va_list count_args;
va_copy(count_args, args);
while (1) {
const char* name = va_arg(count_args, const char*);
if (name == NULL) break;
int start = va_arg(count_args, int);
(void)start;
int end = va_arg(count_args, int);
(void)end;
field_count++;
}
va_end(count_args);
// Read all the fields
BitField fields[field_count];
for (int i = 0; i < field_count; i++) {
fields[i].name = va_arg(args, const char*);
fields[i].end = va_arg(args, int); // get end first
fields[i].start = va_arg(args, int); // then get start
}
va_end(args);
// Print the fields
for (int i = 0; i < field_count; i++) {
if (i > 0) printf(", ");
int start = fields[i].start;
int end = fields[i].end;
if (end == start) {
// Single bit
printf("%s = %d [%d]", fields[i].name, (reg >> start) & 1, start);
} else {
// Multiple bits
int mask = ((1 << (end - start + 1)) - 1);
printf("%s = 0x%02X [%d:%d]", fields[i].name, (reg >> start) & mask, end, start);
}
}
printf("\n");
}
//! ####################################
//! PRINT REGS
//! ####################################
#define UTIL_PRINT_REG8(reg, label) printf("%s: 0x%02X\n", label, (unsigned int)(reg));
#define UTIL_PRINT_REG16(reg, label) printf("%s: 0x%04X\n", label, (unsigned int)(reg));
#define UTIL_PRINT_REG32(reg, label) printf("%s: 0x%08X\n", label, (unsigned int)(reg));