|
static __force_inline void | hw_set_bits (io_rw_32 *addr, uint32_t mask) |
| Atomically set the specified bits to 1 in a HW register. More...
|
|
static __force_inline void | hw_clear_bits (io_rw_32 *addr, uint32_t mask) |
| Atomically clear the specified bits to 0 in a HW register. More...
|
|
static __force_inline void | hw_xor_bits (io_rw_32 *addr, uint32_t mask) |
| Atomically flip the specified bits in a HW register. More...
|
|
static __force_inline void | hw_write_masked (io_rw_32 *addr, uint32_t values, uint32_t write_mask) |
| Set new values for a sub-set of the bits in a HW registerSets destination bits to values specified in values , if and only if corresponding bit in write_mask is set. More...
|
|
Low-level types and (atomic) accessors for memory-mapped hardware registers
hardware_base
defines the low level types and access functions for memory mapped hardware registers. It is included by default by all other hardware libraries.
The following register access typedefs codify the access type (read/write) and the bus size (8/16/32) of the hardware register. The register type names are formed by concatenating one from each of the 3 parts A, B, C
A | B | C | Meaning |
io_ | | | A Memory mapped IO register |
| ro_ | | read-only access |
| rw_ | | read-write access |
| wo_ | | write-only access (can't actually be enforced via C API) |
| | 8 | 8-bit wide access |
| | 16 | 16-bit wide access |
| | 32 | 32-bit wide access |
When dealing with these types, you will always use a pointer, i.e. io_rw_32 *some_reg
is a pointer to a read/write 32 bit register that you can write with *some_reg = value
, or read with value = *some_reg
.
RP2040 hardware is also aliased to provide atomic setting, clear or flipping of a subset of the bits within a hardware register so that concurrent access by two cores is always consistent with one atomic operation being performed first, followed by the second.
See hw_set_bits(), hw_clear_bits() and hw_xor_bits() provide for atomic access via a pointer to a 32 bit register
Additionally given a pointer to a structure representing a piece of hardware (e.g. dma_hw_t *dma_hw
for the DMA controller), you can get an alias to the entire structure such that writing any member (register) within the structure is equivalent to an atomic operation via hw_set_alias(), hw_clear_alias() or hw_xor_alias()...
For example hw_set_alias(dma_hw)->inte1 = 0x80;
will set bit 7 of the INTE1 register of the DMA controller, leaving the other bits unchanged.
◆ hw_clear_bits()
static __force_inline void hw_clear_bits |
( |
io_rw_32 * |
addr, |
|
|
uint32_t |
mask |
|
) |
| |
|
static |
Atomically clear the specified bits to 0 in a HW register.
- Parameters
-
addr | Address of writable register |
mask | Bit-mask specifying bits to clear |
◆ hw_set_bits()
static __force_inline void hw_set_bits |
( |
io_rw_32 * |
addr, |
|
|
uint32_t |
mask |
|
) |
| |
|
static |
Atomically set the specified bits to 1 in a HW register.
- Parameters
-
addr | Address of writable register |
mask | Bit-mask specifying bits to set |
◆ hw_write_masked()
static __force_inline void hw_write_masked |
( |
io_rw_32 * |
addr, |
|
|
uint32_t |
values, |
|
|
uint32_t |
write_mask |
|
) |
| |
|
static |
Set new values for a sub-set of the bits in a HW registerSets destination bits to values specified in values
, if and only if corresponding bit in write_mask
is set.
Note: this method allows safe concurrent modification of different bits of a register, but multiple concurrent access to the same bits is still unsafe.
- Parameters
-
addr | Address of writable register |
values | Bits values |
write_mask | Mask of bits to change |
◆ hw_xor_bits()
static __force_inline void hw_xor_bits |
( |
io_rw_32 * |
addr, |
|
|
uint32_t |
mask |
|
) |
| |
|
static |
Atomically flip the specified bits in a HW register.
- Parameters
-
addr | Address of writable register |
mask | Bit-mask specifying bits to invert |