v2.0.0
Functions
hardware_base
Hardware APIs

Low-level types and (atomic) accessors for memory-mapped hardware registers. More...

## Functions
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 register. More...

## Detailed Description

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

RP-series 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.

## Function Documentation

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

Sets 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