2.7 Hardware Register Interface (HRI)

The layer closest to the hardware is named HRI. This layer is a simple interface with very little logic that do register data content manipulation with a set of defined functions calls. The data manipulation operations can be performed on a bit, bit field, and complete register level.

Figure 2-8. HRI Example Data Manipulation of Bit and Bit Field Contents

This layer also abstracts special register access properties like data synchronization between clock domains. It also ensures that data integrity is kept within an interruptible system by inserting critical sections when it is not possible to do data manipulation atomically.

Using the HRI interfaces as access interface to the peripheral registers helps the compiler optimize the code towards targets like low code size or faster code. When targeting fast code, the compiler can choose to inline the function to be able to optimize the code in context and avoid call conventions. For low code size, the compiler can avoid in-lining the function and reuse the same copy of the function multiple times.

All functions in the HRI are defined as static inline. This gives the compiler the possibility to optimize the code within the context of where it is used. Using functions instead of pre-processor macros keeps the possibility to use the compiler for type checking and makes the code a bit safer compared to pre-processor macros.

There are three main categories of access functions; single-bit access functions (accesses one bit at the time), bit field access functions (accesses multiple bits with a common purpose), and register access functions (access the content of a full register).

Different operation types available for the access functions

  • get - Returns the value of the bit, bit field, or register (bit fields and registers are anded with a mask)
  • set - Sets the value to a high state (bit fields and registers are anded with a mask value)
  • clear - Sets the value to a low state (bit fields and registers are anded with a mask value)
  • toggle - Value is changed to the opposite (bit fields and registers are anded with a mask value)
  • write - Copy all bit states from the input data to the bit field or register
  • read - Copy all bit states from the register and return it to the application
Note: If shadow registers are detected for set, toggle, and clear they will be used instead of normal access.

These operations are available for single bit access

  • get - read state of bit
  • set - set bit state to high
  • clear - set bit state to low
  • toggle - change bit state to the opposite
  • write - change the state of the bit based on input, independent of the previous state
Note: Access to some registers, such as status and INTFLAG registers, only have get and clear access functions.

These operations are available for bit field access

  • get (read the state of bits defined by a mask)
  • set (set bit states to high for bits defined by a mask)
  • clear (set bit states to low for bits defined by a mask)
  • toggle (change bit states to opposite for bits defined by a mask)
  • write (set states of all bits to the state defined in the input data)
  • read (read the state of all bits)

These operations are available for register access

  • get (read the state of bits defined by a mask)
  • set (set bit states to high for bits defined by a mask)
  • clear (set bit states to low for bits defined by a mask)
  • toggle (change bit states to opposite for bits defined by a mask)
  • read (read the state of all bits in the register)
  • write (set the state of all bits in the register based on input data)

These operations are available for write-only register access

  • write register
Note: The bit and bitfield operations are not available for write-only register since they are based on the latest value in the register.

These operations are available for read-only register access

  • read/get register
  • read/get bit field
  • get bit

Shadow register access

The shadow registers are grouped registers that share data of named or virtual register value. They offer some atomic way to change this shared data value. As an example, in SAM D20 there is a register group of OUT, OUTCLR, OUTSET, and OUTTGL in PORT peripheral for port outputs. Writing to OUTCLR, OUTSET, and OUTTGL actually modifies the value in OUT register. In SAM V71, there is a similar register group of ODSR, CODR, and SODR in PIO peripheral for I/O outputs, where writing to CODR and SODR causes changes in ODSR and applies to the actual output pin levels.

Shadow registers have all possible operations for register, bit, and bit field access. The operations target the actual named or virtual register: There is register, bit, and bit field operations to access OUT register, but no operation to access OUTCLR, OUTSET, and OUTTGL.

Naming scheme

  • module name - The acronym used in the data sheet in lower case letters (e.g. adc) function
  • get, set, clear, toggle, write, read bit name - The register position name as written in the data sheet in upper case letters
  • bit field name – The register position name (multiple bits) as written in the data sheet in upper case letters register name - The register name as written in the data sheet in upper case letters

Single bit access

hri_[module name]_[function]_[REGISTER NAME]_[BIT NAME]
eg. adc_set_CTRLA_ENABLE(hw);

Bit field access

hri_[module name]_[function]_[REGISTER NAME]__[BIT FIELD NAME]
eg. adc_set_AVGCTRL_SAMPLENUM(hw, mask);

Register access

hri_[module name]_[function]_[REGISTER NAME]
eg. adc_set_CTRLA(hw, mask);
Note: Special naming rule for single bit access to an interrupt flag register. This applies only to interrupt status registers, not interrupt related registers for enabling, disabling, clearing, etc.
[module name]_[function]_interrupt_[BIT NAME]