RP2040 atomic register access macros.
More...
RP2040 atomic register access macros.
This allows individual fields of a control register to be modified without performing a read-modify-write sequence. See section "2.1.2. Atomic Register Access" in https://datasheets.raspberrypi.org/rpx0xx/rpx0xx-datasheet.pdf
- Warning
- The Single-cycle IO block (SIO), which contains the GPIO, does not support atomic access using these aliases.
- Author
- Marian Buschsieweke maria.nosp@m.n.bu.nosp@m.schsi.nosp@m.ewek.nosp@m.e@ovg.nosp@m.u.de
-
Fabian Hüßler fabia.nosp@m.n.hu.nosp@m.essle.nosp@m.r@ov.nosp@m.gu.de
Definition in file io_reg.h.
#include <stdint.h>
Go to the source code of this file.
#define | REG_ATOMIC_XOR_BIT (0x1000U) |
| Bit to be set if an atomic XOR operation shall be done.
|
|
#define | REG_ATOMIC_SET_BIT (0x2000U) |
| Bit to be set if an atomic set operation shall be done.
|
|
#define | REG_ATOMIC_CLEAR_BIT (0x3000U) |
| Bits to be set if an atomic clear operation shall be done.
|
|
#define | REG_ATOMIC_XOR(reg) ((volatile uint32_t *)(((uintptr_t)(reg)) | REG_ATOMIC_XOR_BIT)) |
| The operation to be performed to the register at address reg will be an atomic XOR of the bits of the right-hand-side operand.
|
|
#define | REG_ATOMIC_SET(reg) ((volatile uint32_t *)(((uintptr_t)(reg)) | REG_ATOMIC_SET_BIT)) |
| The operation to be performed to the register at address reg will be an atomic set of the bits of the right-hand-side operand.
|
|
#define | REG_ATOMIC_CLEAR(reg) ((volatile uint32_t *)(((uintptr_t)(reg)) | REG_ATOMIC_CLEAR_BIT)) |
| The operation to be performed to the register at address reg will be an atomic clear of the bits of the right-hand-side operand.
|
|
static void | io_reg_atomic_xor (volatile uint32_t *reg, uint32_t mask) |
| Performed an atomic XOR of the set bits in op with the bits in the register at address reg .
|
|
static void | io_reg_atomic_set (volatile uint32_t *reg, uint32_t mask) |
| Set the bits in the register at address reg as given by the set bits in operand op .
|
|
static void | io_reg_atomic_clear (volatile uint32_t *reg, uint32_t mask) |
| Clear the bits in the register at address reg as given by the set bits in operand op .
|
|
static void | io_reg_write_dont_corrupt (volatile uint32_t *reg, uint32_t value, uint32_t mask) |
| Updates part of an I/O register without corrupting its contents.
|
|
◆ REG_ATOMIC_CLEAR
The operation to be performed to the register at address reg
will be an atomic clear of the bits of the right-hand-side operand.
Definition at line 67 of file io_reg.h.
◆ REG_ATOMIC_CLEAR_BIT
#define REG_ATOMIC_CLEAR_BIT (0x3000U) |
Bits to be set if an atomic clear operation shall be done.
Definition at line 49 of file io_reg.h.
◆ REG_ATOMIC_SET
#define REG_ATOMIC_SET |
( |
|
reg | ) |
((volatile uint32_t *)(((uintptr_t)(reg)) | REG_ATOMIC_SET_BIT)) |
The operation to be performed to the register at address reg
will be an atomic set of the bits of the right-hand-side operand.
Definition at line 61 of file io_reg.h.
◆ REG_ATOMIC_SET_BIT
#define REG_ATOMIC_SET_BIT (0x2000U) |
Bit to be set if an atomic set operation shall be done.
Definition at line 44 of file io_reg.h.
◆ REG_ATOMIC_XOR
#define REG_ATOMIC_XOR |
( |
|
reg | ) |
((volatile uint32_t *)(((uintptr_t)(reg)) | REG_ATOMIC_XOR_BIT)) |
The operation to be performed to the register at address reg
will be an atomic XOR of the bits of the right-hand-side operand.
Definition at line 55 of file io_reg.h.
◆ REG_ATOMIC_XOR_BIT
#define REG_ATOMIC_XOR_BIT (0x1000U) |
Bit to be set if an atomic XOR operation shall be done.
Definition at line 39 of file io_reg.h.
◆ io_reg_atomic_clear()
static void io_reg_atomic_clear |
( |
volatile uint32_t * |
reg, |
|
|
uint32_t |
mask |
|
) |
| |
|
inlinestatic |
Clear the bits in the register at address reg
as given by the set bits in operand op
.
- Parameters
-
reg | Register address |
mask | Mask of bits to be cleared |
Definition at line 100 of file io_reg.h.
◆ io_reg_atomic_set()
static void io_reg_atomic_set |
( |
volatile uint32_t * |
reg, |
|
|
uint32_t |
mask |
|
) |
| |
|
inlinestatic |
Set the bits in the register at address reg
as given by the set bits in operand op
.
- Parameters
-
reg | Register address |
mask | Mask of bits to be set |
Definition at line 88 of file io_reg.h.
◆ io_reg_atomic_xor()
static void io_reg_atomic_xor |
( |
volatile uint32_t * |
reg, |
|
|
uint32_t |
mask |
|
) |
| |
|
inlinestatic |
Performed an atomic XOR of the set bits in op
with the bits in the register at address reg
.
- Parameters
-
reg | Register address |
mask | Mask of bits to be XORed |
Definition at line 76 of file io_reg.h.
◆ io_reg_write_dont_corrupt()
static void io_reg_write_dont_corrupt |
( |
volatile uint32_t * |
reg, |
|
|
uint32_t |
value, |
|
|
uint32_t |
mask |
|
) |
| |
|
inlinestatic |
Updates part of an I/O register without corrupting its contents.
- Parameters
-
reg | Register address |
value | bits to set in the register (e.g. the new value shifted to the right position) |
mask | bits to clear in the register (e.g. bitmask indicating the part to update with one bits, and everything else with zero bits) |
The RP2040 only correctly implements 32 bit writes to I/O register. When updating parts of an I/O register using the structs in the CMSIS header, the C compiler might implement those updates e.g. using 8-bit writes, especially when the part to update is 8-bit in size and byte-aligned. The RP2040 will then sneakily corrupt the I/O register, rather than triggering a hard fault. This hard to debug silent corruption issue is NOT a bug, but an intentional feature, obviously.
- Precondition
value & (~mask) == 0
Example use:
CLOCKS_CLK_SYS_CTRL_SRC_Msk);
static void io_reg_write_dont_corrupt(volatile uint32_t *reg, uint32_t value, uint32_t mask)
Updates part of an I/O register without corrupting its contents.
Definition at line 128 of file io_reg.h.