Loading...
Searching...
No Matches
io_reg.h File Reference

RP2040 atomic register access macros. More...

Detailed Description

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>
+ Include dependency graph for io_reg.h:
+ This graph shows which files directly or indirectly include this file:

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.
 

Macro Definition Documentation

◆ REG_ATOMIC_CLEAR

#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.

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.

Function Documentation

◆ 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
regRegister address
maskMask 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
regRegister address
maskMask 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
regRegister address
maskMask 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
regRegister address
valuebits to set in the register (e.g. the new value shifted to the right position)
maskbits 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:

io_reg_write_dont_corrupt(&CLOCKS->CLK_SYS_CTRL, source << CLOCKS_CLK_SYS_CTRL_SRC_Pos,
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 io_reg.h:128

Definition at line 128 of file io_reg.h.