-
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 95 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
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,38 @@ | ||
| load("@bazel_tools//tools/cpp:toolchain_utils.bzl", "use_cpp_toolchain") | ||
|
|
||
| def _linker_scripts_impl(ctx): | ||
| link_flags = [] | ||
| for script in ctx.attr.include_scripts: | ||
| link_include_dir = script.label.package | ||
| if ctx.label.workspace_root: | ||
| link_include_dir = "/".join((ctx.label.workspace_root, link_include_dir)) | ||
| link_flag = "-L" + str(link_include_dir) | ||
| if not (link_flag in link_flags): | ||
| link_flags.append(link_flag) | ||
|
|
||
| for script in ctx.files.link_scripts: | ||
| link_flags.append("-T" + str(script.path)) | ||
|
|
||
| all_scripts = ctx.files.link_scripts + ctx.files.include_scripts | ||
|
|
||
| linking_inputs = cc_common.create_linker_input( | ||
| owner = ctx.label, | ||
| user_link_flags = depset( | ||
| direct = link_flags, | ||
| ), | ||
| additional_inputs = depset(direct = all_scripts), | ||
| ) | ||
| return [ | ||
| DefaultInfo(files = depset(direct = all_scripts)), | ||
| CcInfo(linking_context = cc_common.create_linking_context(linker_inputs = depset(direct = [linking_inputs]))), | ||
| ] | ||
|
|
||
| linker_scripts = rule( | ||
| implementation = _linker_scripts_impl, | ||
| attrs = { | ||
| "link_scripts": attr.label_list(allow_files = [".ld"], doc = "List of scripts to explicitly link"), | ||
| "include_scripts": attr.label_list(allow_files = [".incl"], doc = "List of scripts to include"), | ||
| }, | ||
| toolchains = use_cpp_toolchain(), | ||
| fragments = ["cpp"], | ||
| ) |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,234 @@ | ||
| /* | ||
| * Copyright (c) 2026 Raspberry Pi (Trading) Ltd. | ||
| * | ||
| * SPDX-License-Identifier: BSD-3-Clause | ||
| */ | ||
|
|
||
| #ifndef _PICO_UTIL_BITSET_H | ||
| #define _PICO_UTIL_BITSET_H | ||
|
|
||
| #include "pico.h" | ||
|
|
||
| /** \file bitset.h | ||
| * \defgroup bitset bitset | ||
| * \brief Simple bitset implementation | ||
will-v-pi marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| * | ||
| * \ingroup pico_util | ||
| */ | ||
|
|
||
| #ifdef __cplusplus | ||
| extern "C" { | ||
| #endif | ||
|
|
||
| typedef struct { | ||
| uint16_t size; \ | ||
| uint16_t word_size; \ | ||
| 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 { \ | ||
| uint16_t size; \ | ||
| uint16_t word_size; \ | ||
| uint32_t words[((N) + 31) / 32]; \ | ||
will-v-pi marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| } sized_bitset; \ | ||
| } | ||
| #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; \ | ||
| __builtin_memset(ptr, (fill) ? 0xff : 0, sizeof(type)); \ | ||
| (ptr)->bitset.size = N; \ | ||
| (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)) { | ||
|
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. Should this raise an error if
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 question for @kilograham, but given that the other functions don't throw any errors when you attempt to pass a value that is outside the range and just return 0/do nothing, I think this one should also not throw an error? |
||
| bitset->words[word_num] = value; | ||
| } | ||
| 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)) { | ||
| return bitset->words[word_num]; | ||
| } | ||
| 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) { | ||
| bitset->words[bit / 32u] |= 1u << (bit % 32u); | ||
| } | ||
| 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) { | ||
| bitset->words[bit / 32u] &= ~(1u << (bit % 32u)); | ||
| } | ||
| 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); | ||
| // if (bit < bitset->size) { | ||
| return bitset->words[bit / 32u] & (1u << (bit % 32u)); | ||
| // } | ||
| return false; | ||
| } | ||
will-v-pi marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| /*! \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); | ||
| assert(bitset1->size == bitset2->size); | ||
| return __builtin_memcmp(bitset1->words, bitset2->words, bitset1->word_size * sizeof(uint32_t)) == 0; | ||
| } | ||
|
|
||
| typedef uint32_t tiny_encoded_bitset_t; | ||
| typedef uint64_t encoded_bitset_t; | ||
|
|
||
| #define encoded_bitset_empty() 0 | ||
| #define encoded_bitset_of1(v) (1u | ((v) << 8)) | ||
| #define encoded_bitset_of2(v1, v2) (2u | ((v1) << 8) | ((v2) << 16)) | ||
| #define encoded_bitset_of3(v1, v2, v3) (3u | ((v1) << 8) | ((v2) << 16) | (((v3) << 24))) | ||
| #define encoded_bitset_of4(v1, v2, v3, v4) (4u | ((v1) << 8) | ((v2) << 16) | (((v3) << 24)) | (((uint64_t)(v4)) << 32)) | ||
| #define encoded_bitset_of5(v1, v2, v3, v4, v5) (5u | ((v1) << 8) | ((v2) << 16) | (((v3) << 24)) | (((uint64_t)((v4) | ((v5)<<8u))) << 32)) | ||
|
|
||
| #define encoded_bitset_foreach(bitset, x) ({ \ | ||
| for(uint _i=0;_i<((bitset)&0xffu);_i++) { \ | ||
| uint bit = (uint8_t)((bitset) >> (8 * _i)); \ | ||
| x; \ | ||
| } \ | ||
| }) | ||
|
Comment on lines
+215
to
+230
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. AFAICT it looks like this
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. That’ll be a question for @kilograham |
||
| #ifdef __cplusplus | ||
| } | ||
| #endif | ||
| #endif | ||
Uh oh!
There was an error while loading. Please reload this page.