From a0be7cdab561007194bf95bfcd0bad4ce32ae147 Mon Sep 17 00:00:00 2001 From: William Vinnicombe Date: Tue, 10 Mar 2026 13:53:35 +0000 Subject: [PATCH] Add some doxygen to bitset.h, and tidy up some macros --- .../pico_util/include/pico/util/bitset.h | 91 +++++++++++++++++++ .../hardware_clocks/include/hardware/clocks.h | 4 +- .../hardware_powman/include/hardware/powman.h | 4 +- 3 files changed, 95 insertions(+), 4 deletions(-) diff --git a/src/common/pico_util/include/pico/util/bitset.h b/src/common/pico_util/include/pico/util/bitset.h index f8ab21d2..269d3142 100644 --- a/src/common/pico_util/include/pico/util/bitset.h +++ b/src/common/pico_util/include/pico/util/bitset.h @@ -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); diff --git a/src/rp2_common/hardware_clocks/include/hardware/clocks.h b/src/rp2_common/hardware_clocks/include/hardware/clocks.h index eb4ec4e4..5e93e11d 100644 --- a/src/rp2_common/hardware_clocks/include/hardware/clocks.h +++ b/src/rp2_common/hardware_clocks/include/hardware/clocks.h @@ -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); diff --git a/src/rp2_common/hardware_powman/include/hardware/powman.h b/src/rp2_common/hardware_powman/include/hardware/powman.h index b3c530cb..161764c1 100644 --- a/src/rp2_common/hardware_powman/include/hardware/powman.h +++ b/src/rp2_common/hardware_powman/include/hardware/powman.h @@ -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);