Add some doxygen to bitset.h, and tidy up some macros

This commit is contained in:
William Vinnicombe 2026-03-10 13:53:35 +00:00
parent 6e1b122c36
commit a0be7cdab5
3 changed files with 95 additions and 4 deletions

View file

@ -26,6 +26,18 @@ typedef struct {
uint32_t words[];
} generic_bitset_t;
/*! \brief Macro used to define a bitset type
* \ingroup pico_util
* This macro is used to define a bitset type. It is used as follows:
* ```
* typedef bitset_type_t(32) my_bitset_t;
* ```
* will define a new bitset type called `my_bitset_t` that can hold 32 bits.
*
* The type can be used as `my_bitset_t bitset;` to declare a new bitset.
*
* \param N the number of bits in the bitset
*/
#define bitset_type_t(N) union { \
generic_bitset_t bitset; \
struct { \
@ -36,11 +48,28 @@ typedef struct {
}
#define bitset_sizeof_for(N) ((((N) + 63u) / 32u) * 4u)
/*! \brief Macro used to create a bitset with all bits set to a value
* \ingroup pico_util
* \param type the type of the bitset
* \param N the number of bits in the bitset
* \param value the value to set the bits to (0 or 1)
* \return the bitset
*/
#define bitset_with_value(type, N, value) ({ type bitset; bitset_init(&bitset, type, N, value); bitset; })
// Quick test that the bitset macros give the correct size
extern bitset_type_t(32) __not_real_bitset32;
extern bitset_type_t(33) __not_real_bitset33;
static_assert(sizeof(__not_real_bitset32) == bitset_sizeof_for(1),"");
static_assert(sizeof(__not_real_bitset33) == bitset_sizeof_for(37), "");
/*! \brief Initialize a bitset
* \ingroup pico_util
* \param ptr the bitset to initialize
* \param type the type of the bitset
* \param N the number of bits in the bitset
* \param fill the value to fill the bitset with (0 or 1)
*/
#define bitset_init(ptr, type, N, fill) ({ \
assert(sizeof(type) == bitset_sizeof_for(N)); \
__unused type *type_check = ptr; \
@ -49,18 +78,40 @@ static_assert(sizeof(__not_real_bitset33) == bitset_sizeof_for(37), "");
(ptr)->bitset.word_size = ((N) + 31u) / 32u; \
})
/*! \brief Get the size of the bitset
* \ingroup pico_util
* \param bitset the bitset to get the size of
* \return the size of the bitset
*/
static inline uint bitset_size(const generic_bitset_t *bitset) {
return bitset->size;
}
/*! \brief Get the size of the bitset in words
* \ingroup pico_util
* \param bitset the bitset to get the size of
* \return the size of the bitset in words
*/
static inline uint bitset_word_size(const generic_bitset_t *bitset) {
return bitset->word_size;
}
/*! \brief Check that the bitset is valid
* \ingroup pico_util
* This function will assert if the bitset is not valid.
* \param bitset the bitset to check
*/
static inline void check_bitset(const generic_bitset_t *bitset) {
assert(bitset->word_size == (bitset->size + 31) / 32);
}
/*! \brief Write a word in the bitset
* \ingroup pico_util
* \param bitset the bitset to write to
* \param word_num the word number to write to
* \param value the value to write to the word
* \return the bitset
*/
static inline generic_bitset_t *bitset_write_word(generic_bitset_t *bitset, uint word_num, uint32_t value) {
check_bitset(bitset);
if (word_num < bitset_word_size(bitset)) {
@ -69,6 +120,12 @@ static inline generic_bitset_t *bitset_write_word(generic_bitset_t *bitset, uint
return bitset;
}
/*! \brief Read a word in the bitset
* \ingroup pico_util
* \param bitset the bitset to read from
* \param word_num the word number to read from
* \return the value of the word
*/
static inline uint32_t bitset_read_word(const generic_bitset_t *bitset, uint word_num) {
check_bitset(bitset);
if (word_num < bitset_word_size(bitset)) {
@ -77,18 +134,34 @@ static inline uint32_t bitset_read_word(const generic_bitset_t *bitset, uint wor
return 0;
}
/*! \brief Clear all bits in the bitset
* \ingroup pico_util
* \param bitset the bitset to clear
* \return the bitset
*/
static inline generic_bitset_t *bitset_clear(generic_bitset_t *bitset) {
check_bitset(bitset);
__builtin_memset(bitset->words, 0, bitset->word_size * sizeof(uint32_t));
return bitset;
}
/*! \brief Set all bits in the bitset
* \ingroup pico_util
* \param bitset the bitset to set
* \return the bitset
*/
static inline generic_bitset_t *bitset_set_all(generic_bitset_t *bitset) {
check_bitset(bitset);
__builtin_memset(bitset->words, 0xff, bitset->word_size * sizeof(uint32_t));
return bitset;
}
/*! \brief Set a single bit in the bitset
* \ingroup pico_util
* \param bitset the bitset to set
* \param bit the bit to set
* \return the bitset
*/
static inline generic_bitset_t *bitset_set_bit(generic_bitset_t *bitset, uint bit) {
check_bitset(bitset);
if (bit < bitset->size) {
@ -97,6 +170,12 @@ static inline generic_bitset_t *bitset_set_bit(generic_bitset_t *bitset, uint bi
return bitset;
}
/*! \brief Clear a single bit in the bitset
* \ingroup pico_util
* \param bitset the bitset to clear
* \param bit the bit to clear
* \return the bitset
*/
static inline generic_bitset_t *bitset_clear_bit(generic_bitset_t *bitset, uint bit) {
check_bitset(bitset);
if (bit < bitset->size) {
@ -105,6 +184,12 @@ static inline generic_bitset_t *bitset_clear_bit(generic_bitset_t *bitset, uint
return bitset;
}
/*! \brief Get the value of a single bit in the bitset
* \ingroup pico_util
* \param bitset the bitset to get the value of
* \param bit the bit to get the value of
* \return the value of the bit
*/
static inline bool bitset_get_bit(generic_bitset_t *bitset, uint bit) {
check_bitset(bitset);
assert(bit < bitset->size);
@ -114,6 +199,12 @@ static inline bool bitset_get_bit(generic_bitset_t *bitset, uint bit) {
return false;
}
/*! \brief Check if two bitsets are equal
* \ingroup pico_util
* \param bitset1 the first bitset to check
* \param bitset2 the second bitset to check
* \return true if the bitsets are equal, false otherwise
*/
static inline bool bitset_equal(const generic_bitset_t *bitset1, const generic_bitset_t *bitset2) {
check_bitset(bitset1);
check_bitset(bitset2);

View file

@ -580,8 +580,8 @@ static inline bool set_sys_clock_khz(uint32_t freq_khz, bool required) {
#include "pico/util/bitset.h"
typedef bitset_type_t(NUM_CLOCK_DESTINATIONS) clock_dest_set_t;
#define clock_dest_set_none() ({ clock_dest_set_t bitset; bitset_init(&bitset, clock_dest_set_t, NUM_CLOCK_DESTINATIONS, 0); bitset; })
#define clock_dest_set_all() ({ clock_dest_set_t bitset; bitset_init(&bitset, clock_dest_set_t, NUM_CLOCK_DESTINATIONS, 1); bitset; })
#define clock_dest_set_none() bitset_with_value(clock_dest_set_t, NUM_CLOCK_DESTINATIONS, 0)
#define clock_dest_set_all() bitset_with_value(clock_dest_set_t, NUM_CLOCK_DESTINATIONS, 1)
static inline clock_dest_set_t *clock_dest_set_clear(clock_dest_set_t *dests) {
bitset_clear(&dests->bitset);

View file

@ -173,8 +173,8 @@ typedef enum powman_power_domains powman_power_domain_t;
typedef uint32_t powman_power_state;
typedef bitset_type_t(POWMAN_POWER_DOMAIN_COUNT) pstate_bitset_t;
#define pstate_bitset_none() ({ pstate_bitset_t bitset; bitset_init(&bitset, pstate_bitset_t, POWMAN_POWER_DOMAIN_COUNT, 0); bitset; })
#define pstate_bitset_all() ({ pstate_bitset_t bitset; bitset_init(&bitset, pstate_bitset_t, POWMAN_POWER_DOMAIN_COUNT, 1); bitset; })
#define pstate_bitset_none() bitset_with_value(pstate_bitset_t, POWMAN_POWER_DOMAIN_COUNT, 0)
#define pstate_bitset_all() bitset_with_value(pstate_bitset_t, POWMAN_POWER_DOMAIN_COUNT, 1)
static inline pstate_bitset_t *pstate_bitset_clear(pstate_bitset_t *domains) {
bitset_clear(&domains->bitset);