-
Notifications
You must be signed in to change notification settings - Fork 1.2k
Add pico_low_power library #2852
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: develop
Are you sure you want to change the base?
Changes from 100 commits
b8f699f
6dc06e6
727cabd
3a83dc7
4b1a3ec
ae97a22
3811e67
a20f86a
6bd9e5b
2bf8555
fe2d56b
1bd7089
72adb67
e47fe09
9c0ed0c
e44bdea
dc3a2e8
afbc07e
dffd4a5
c81b09f
1807c25
bcd2797
b62de58
abc6255
ed3716e
5a2677c
c3a3b7c
a1eb46f
26b0a66
fa1199e
1c65750
e2232d8
edb8838
0e27c5b
7bf2452
95eacfe
7e23f0b
0559a34
e65135f
7aa06f4
49d03aa
10aa674
1806da6
9cc19ed
c65b596
7293ceb
575617e
7ce8c6a
6509d94
9c1b67f
7fa5cbb
fe63e92
81a182b
fba2c74
f33d5a4
12c92b1
1bcfac3
609e666
5343b6e
59fe386
cacafe6
1deea52
89276fa
5ae8b76
b521c11
e464234
e51ca45
fa6064c
298fd2a
77e9e40
d249a90
b6589e7
50a241b
97705aa
8b9d9ec
91c3a9a
614f7f0
da23cf4
780c05e
2e7ca67
4180427
c122bf7
ea8320b
ad35ad8
8e3aca5
e9e9a09
519544e
3f0615d
a26a42b
df68b1e
41fd36e
ea9b114
7b040da
09e2857
b144c1a
df27c7b
b4d9929
500de3c
64639f7
d1cdadb
24d575f
79f74b2
34a6c3a
95e8a9c
925e79b
032be3f
bedcb64
eff5d81
c8f755a
42c5ae7
ff43214
b38af21
8e813f7
4c54ce3
61f1e45
633628f
5815ebf
24f7e77
81d2a2d
7157446
5b97da4
441e93f
2f3f420
355aea5
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,26 @@ | ||
| /* | ||
| * Copyright (c) 2026 Raspberry Pi (Trading) Ltd. | ||
| * | ||
| * SPDX-License-Identifier: BSD-3-Clause | ||
| */ | ||
|
|
||
| #include "include/pico/util/fixed_bitset.h" | ||
|
|
||
| fixed_bitset_t *fixed_bitset_flip_all(fixed_bitset_t *bitset) { | ||
| check_fixed_bitset(bitset); | ||
| for (uint i=0;i<bitset->word_size;i++) { | ||
| bitset->words[i] = ~bitset->words[i]; | ||
| } | ||
| return bitset; | ||
| } | ||
|
|
||
| bool fixed_bitset_is_empty(fixed_bitset_t *bitset) { | ||
| check_fixed_bitset(bitset); | ||
| int i=0; | ||
| for (i=0;i<bitset->word_size-1;i++) { | ||
| if (bitset->words[i]) return false; | ||
| } | ||
| // we don't guarantee that bits above the size aren't set, so mask them off | ||
| return !(i && (bitset->words[i] << (32u -(bitset->size & 31u)))); | ||
| } | ||
|
|
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,283 @@ | ||
| /* | ||
| * Copyright (c) 2026 Raspberry Pi (Trading) Ltd. | ||
| * | ||
| * SPDX-License-Identifier: BSD-3-Clause | ||
| */ | ||
|
|
||
| #ifndef _PICO_UTIL_FIXED_BITSET_H | ||
| #define _PICO_UTIL_FIXED_BITSET_H | ||
|
|
||
| #include "pico.h" | ||
|
|
||
| /** \file fixed_bitset.h | ||
| * \defgroup fixed_bitset fixed_bitset | ||
| * \brief Simple fixed-size bitset implementation | ||
| * | ||
| * \ingroup pico_util | ||
| */ | ||
|
|
||
| #ifdef __cplusplus | ||
| extern "C" { | ||
| #endif | ||
|
|
||
| typedef struct { | ||
| uint16_t size; \ | ||
| uint16_t word_size; \ | ||
| uint32_t words[]; | ||
| } fixed_bitset_t; | ||
|
|
||
| /*! \brief Macro used to define a fixed-size bitset of a given size | ||
| * \ingroup fixed_bitset | ||
| * This macro is used to declare the type of a fixed-size bitset. It is used as follows: | ||
| * ``` | ||
| * typedef fixed_bitset_type_t(17) my_bitset_t; | ||
| * ``` | ||
| * will define a new bitset type called `my_bitset_t` that can hold 17 boolean values. | ||
| * | ||
| * The type can be used as `my_bitset_t bitset;` to declare a new bitset. | ||
| * | ||
| * \param N the number of boolean values in the bitset | ||
| */ | ||
| #define fixed_bitset_type(N) union { \ | ||
| fixed_bitset_t bitset; \ | ||
| struct { \ | ||
| uint16_t size; \ | ||
| uint16_t word_size; \ | ||
| uint32_t words[((N) + 31) / 32]; \ | ||
| } sized_bitset; \ | ||
| } | ||
| #define fixed_bitset_sizeof_for(N) ((((N) + 63u) / 32u) * 4u) | ||
|
|
||
| /*! \brief Macro used to create a bitset with all bits set to a value | ||
| * \ingroup fixed_bitset | ||
| * \param type the type of the bitset | ||
| * \param N the number of bits in the bitset | ||
| * \param fill the value to set the bits to (0 or 1) | ||
| * \return the bitset | ||
| */ | ||
| #define fixed_bitset_with_fill(type, N, fill) ({ type bitset; fixed_bitset_init(&bitset, type, N, fill); bitset; }) | ||
|
|
||
| // Quick test that the bitset macros give the correct size | ||
| extern fixed_bitset_type(32) __not_real_bitset32; | ||
| extern fixed_bitset_type(33) __not_real_bitset33; | ||
| static_assert(sizeof(__not_real_bitset32) == fixed_bitset_sizeof_for(1),""); | ||
| static_assert(sizeof(__not_real_bitset33) == fixed_bitset_sizeof_for(37), ""); | ||
| static_assert(sizeof(__not_real_bitset33) != fixed_bitset_sizeof_for(1), ""); | ||
|
|
||
| /*! \brief Initialize a bitset | ||
| * \ingroup fixed_bitset | ||
| * \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 fixed_bitset_init(ptr, type, N, fill) ({ \ | ||
| assert(sizeof(type) == fixed_bitset_sizeof_for(N)); \ | ||
| __unused type *type_check = ptr; \ | ||
| (ptr)->bitset.size = N; \ | ||
| (ptr)->bitset.word_size = ((N) + 31u) / 32u; \ | ||
| __builtin_memset(&(ptr)->bitset.words, (fill) ? 0xff : 0, (ptr)->bitset.word_size * sizeof(uint32_t)); \ | ||
| }) | ||
|
|
||
| /*! \brief Get the size of the bitset | ||
| * \ingroup fixed_bitset | ||
| * \param bitset the bitset to get the size of | ||
| * \return the size of the bitset | ||
| */ | ||
| static inline uint fixed_bitset_size(const fixed_bitset_t *bitset) { | ||
| return bitset->size; | ||
| } | ||
|
|
||
| /*! \brief Get the size of the bitset in words | ||
| * \ingroup fixed_bitset | ||
| * \param bitset the bitset to get the size of | ||
| * \return the size of the bitset in words | ||
| */ | ||
| static inline uint fixed_bitset_word_size(const fixed_bitset_t *bitset) { | ||
| return bitset->word_size; | ||
| } | ||
|
|
||
| /*! \brief Check that the bitset is valid | ||
| * \ingroup fixed_bitset | ||
| * This function will assert if the bitset is not valid. | ||
| * \param bitset the bitset to check | ||
| */ | ||
| static inline void check_fixed_bitset(const fixed_bitset_t *bitset) { | ||
|
will-v-pi marked this conversation as resolved.
Outdated
|
||
| assert(bitset->word_size == (bitset->size + 31) / 32); | ||
| } | ||
|
|
||
| /*! \brief Write a word in the bitset | ||
| * \ingroup fixed_bitset | ||
| * \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 fixed_bitset_t *fixed_bitset_write_word(fixed_bitset_t *bitset, uint word_num, uint32_t value) { | ||
| check_fixed_bitset(bitset); | ||
| if (word_num < fixed_bitset_word_size(bitset)) { | ||
| bitset->words[word_num] = value; | ||
| } | ||
| return bitset; | ||
| } | ||
|
|
||
| /*! \brief Read a word in the bitset | ||
| * \ingroup fixed_bitset | ||
| * \param bitset the bitset | ||
| * \param word_num the word number to read from | ||
| * \return the value of the word | ||
| */ | ||
| static inline uint32_t fixed_bitset_read_word(const fixed_bitset_t *bitset, uint word_num) { | ||
| check_fixed_bitset(bitset); | ||
| if (word_num < fixed_bitset_word_size(bitset)) { | ||
| return bitset->words[word_num]; | ||
| } | ||
| return 0; | ||
| } | ||
|
|
||
| /*! \brief Clear all bits in the bitset | ||
| * \ingroup fixed_bitset | ||
| * \param bitset the bitset | ||
| * \return the bitset | ||
| */ | ||
| static inline fixed_bitset_t *fixed_bitset_clear_all(fixed_bitset_t *bitset) { | ||
| check_fixed_bitset(bitset); | ||
| __builtin_memset(bitset->words, 0, bitset->word_size * sizeof(uint32_t)); | ||
| return bitset; | ||
| } | ||
|
|
||
| /*! \brief Set all bits in the bitset | ||
| * \ingroup fixed_bitset | ||
| * \param bitset the bitset | ||
| * \return the bitset | ||
| */ | ||
| static inline fixed_bitset_t *fixed_bitset_set_all(fixed_bitset_t *bitset) { | ||
| check_fixed_bitset(bitset); | ||
| __builtin_memset(bitset->words, 0xff, bitset->word_size * sizeof(uint32_t)); | ||
| return bitset; | ||
| } | ||
|
|
||
| /*! \brief Flip all bits in the bitset | ||
| * \ingroup fixed_bitset | ||
| * \param bitset the bitset | ||
| * \return the bitset | ||
| */ | ||
| fixed_bitset_t *fixed_bitset_flip_all(fixed_bitset_t *bitset); | ||
|
|
||
| /*! \brief Determine if bitset is empty | ||
| * \ingroup fixed_bitset | ||
| * \param bitset the bitset | ||
| * \return true if not bits are set | ||
| */ | ||
| bool fixed_bitset_is_empty(fixed_bitset_t *bitset); | ||
|
|
||
| /*! \brief Set a single bit in the bitset | ||
| * \ingroup fixed_bitset | ||
| * \param bitset the bitset | ||
| * \param bit_index the bit to set | ||
| * \return the bitset | ||
| */ | ||
| static inline fixed_bitset_t *fixed_bitset_set(fixed_bitset_t *bitset, uint bit_index) { | ||
| check_fixed_bitset(bitset); | ||
| if (bit_index < bitset->size) { | ||
| bitset->words[bit_index / 32u] |= 1u << (bit_index % 32u); | ||
| } | ||
| return bitset; | ||
| } | ||
|
|
||
| /*! \brief Clear a single bit in the bitset | ||
| * \ingroup fixed_bitset | ||
| * \param bitset the bitset | ||
| * \param bit_index the bit to clear | ||
| * \return the bitset | ||
| */ | ||
| static inline fixed_bitset_t *fixed_bitset_clear(fixed_bitset_t *bitset, uint bit_index) { | ||
| check_fixed_bitset(bitset); | ||
| if (bit_index < bitset->size) { | ||
| bitset->words[bit_index / 32u] &= ~(1u << (bit_index % 32u)); | ||
| } | ||
| return bitset; | ||
| } | ||
|
|
||
| /*! \brief Flip a single bit in the bitset | ||
| * \ingroup fixed_bitset | ||
| * \param bitset the bitset | ||
| * \param bit_index the bit to flip | ||
| * \return the bitset | ||
| */ | ||
| static inline fixed_bitset_t *fixed_bitset_flip(fixed_bitset_t *bitset, uint bit_index) { | ||
| check_fixed_bitset(bitset); | ||
| if (bit_index < bitset->size) { | ||
| bitset->words[bit_index / 32u] ^= 1u << (bit_index % 32u); | ||
| } | ||
| return bitset; | ||
| } | ||
|
|
||
|
|
||
| /*! \brief Get the value of a single bit in the bitset | ||
| * \ingroup fixed_bitset | ||
| * \param bitset the bitset | ||
| * \param bit_index the bit to get the value of | ||
| * \return the value of the bit | ||
| */ | ||
| static inline bool fixed_bitset_get(const fixed_bitset_t *bitset, uint bit_index) { | ||
| check_fixed_bitset(bitset); | ||
| assert(bit_index < bitset->size); | ||
| // if (bit < bitset->size) { | ||
| return bitset->words[bit_index / 32u] & (1u << (bit_index % 32u)); | ||
| // } | ||
| return false; | ||
| } | ||
|
|
||
| /*! \brief Check if two bitsets are equal | ||
| * \ingroup fixed_bitset | ||
| * \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 fixed_bitset_equal(const fixed_bitset_t *bitset1, const fixed_bitset_t *bitset2) { | ||
| check_fixed_bitset(bitset1); | ||
| check_fixed_bitset(bitset2); | ||
| assert(bitset1->size == bitset2->size); | ||
| return __builtin_memcmp(bitset1->words, bitset2->words, bitset1->word_size * sizeof(uint32_t)) == 0; | ||
| } | ||
|
|
||
| #if 0 // not currently used | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. why is this here?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is a @kilograham question
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I wrote the code and didn’t want to lose it - perhaps better to copy it into a comment here and delete it from the code
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. typedef uint32_t tiny_ordinal_list_t; // ordinals must be 0->255
typedef uint64_t small_ordinal_list_t; // ordinals must be 0->255
#define ordinal_list_empty() 0
#define ordinal_list_of1(v) (1u | ((v) << 8))
#define ordinal_list_of2(v1, v2) (2u | ((v1) << 8) | ((v2) << 16))
#define ordinal_list_of3(v1, v2, v3) (3u | ((v1) << 8) | ((v2) << 16) | (((v3) << 24)))
#define ordinal_list_of4(v1, v2, v3, v4) (4u | ((v1) << 8) | ((v2) << 16) | (((v3) << 24)) | (((uint64_t)(v4)) << 32))
#define ordinal_list_of5(v1, v2, v3, v4, v5) (5u | ((v1) << 8) | ((v2) << 16) | (((v3) << 24)) | (((uint64_t)((v4) | ((v5)<<8u))) << 32))
#define small_ordinal_list_foreach(bitarray, x) ({ \
for(uint _i=1;_i<=((bitarray)&0xffu);_i++) { \
uint bit = (uint8_t)((bitarray) >> (8 * _i)); \
x; \
} \
})
static inline fixed_bitset_t *fixed_bitset_set_bits(fixed_bitset_t *bitset, small_ordinal_list_t list) {
small_ordinal_list_foreach(list, fixed_bitset_set(bitset, bit));
return bitset;
}
static inline fixed_bitset_t *fixed_bitset_clear_bits(fixed_bitset_t *bitset, small_ordinal_list_t list) {
small_ordinal_list_foreach(list, fixed_bitset_clear(bitset, bit));
return bitset;
}
#define fixed_bitset_init_with_bits(ptr, type, N, list) ({ \
/* not this performs checks */ \
fixed_bitset_init(ptr, type, N, 0); \
fixed_bitset_set_bits(&(ptr)->bitset, list); \
}) |
||
| typedef uint32_t tiny_ordinal_list_t; // ordinals must be 0->255 | ||
| typedef uint64_t small_ordinal_list_t; // ordinals must be 0->255 | ||
| #define ordinal_list_empty() 0 | ||
| #define ordinal_list_of1(v) (1u | ((v) << 8)) | ||
| #define ordinal_list_of2(v1, v2) (2u | ((v1) << 8) | ((v2) << 16)) | ||
| #define ordinal_list_of3(v1, v2, v3) (3u | ((v1) << 8) | ((v2) << 16) | (((v3) << 24))) | ||
| #define ordinal_list_of4(v1, v2, v3, v4) (4u | ((v1) << 8) | ((v2) << 16) | (((v3) << 24)) | (((uint64_t)(v4)) << 32)) | ||
| #define ordinal_list_of5(v1, v2, v3, v4, v5) (5u | ((v1) << 8) | ((v2) << 16) | (((v3) << 24)) | (((uint64_t)((v4) | ((v5)<<8u))) << 32)) | ||
|
|
||
| #define small_ordinal_list_foreach(bitarray, x) ({ \ | ||
| for(uint _i=1;_i<=((bitarray)&0xffu);_i++) { \ | ||
| uint bit = (uint8_t)((bitarray) >> (8 * _i)); \ | ||
| x; \ | ||
| } \ | ||
| }) | ||
|
|
||
| static inline fixed_bitset_t *fixed_bitset_set_bits(fixed_bitset_t *bitset, small_ordinal_list_t list) { | ||
| small_ordinal_list_foreach(list, fixed_bitset_set(bitset, bit)); | ||
| return bitset; | ||
| } | ||
|
|
||
| static inline fixed_bitset_t *fixed_bitset_clear_bits(fixed_bitset_t *bitset, small_ordinal_list_t list) { | ||
| small_ordinal_list_foreach(list, fixed_bitset_clear(bitset, bit)); | ||
| return bitset; | ||
| } | ||
|
|
||
|
|
||
| #define fixed_bitset_init_with_bits(ptr, type, N, list) ({ \ | ||
| /* not this performs checks */ \ | ||
| fixed_bitset_init(ptr, type, N, 0); \ | ||
| fixed_bitset_set_bits(&(ptr)->bitset, list); \ | ||
| }) | ||
|
|
||
| #endif | ||
| #ifdef __cplusplus | ||
| } | ||
| #endif | ||
| #endif | ||
Uh oh!
There was an error while loading. Please reload this page.