| CMSIS-CORE Version 3.01 CMSIS-CORE support for Cortex-M processor-based devices

- CMSIS
- CORE
- DSP
- RTOS API
- SVD

- Main Page
- Usage and Description
- Reference

Peripheral Access

Describes naming conventions, requirements, and optional features for accessing peripherals. More...

Each peripheral provides a data type definition with a name that is composed of a prefix <device abbreviation>_ and the <peripheral name>_, for example LPC_UART for the device LPC and the peripheral UART. The intention is to avoid name collisions caused by short names. If more peripherals exist of the same type, identifiers have a postfix consisting of a digit or letter, for example LPC_UART0, LPC_UART1.

- The data type definition uses the standard C data types from the ANSI C header file <stdint.h>. IO Type Qualifiers are used to specify the access to peripheral variables. IO Type Qualifiers are indented to be used for automatic generation of debug information of peripheral registers and are defined as shown below:

        #define   __I     volatile const
        #define   __O     volatile
        #define   __IO    volatile

- The following typedef is an example for a UART. <device abbreviation>_UART_TypeDef: defines the generic register layout for all UART channels in a device.

      typedef struct
      {
        union {
        __I  uint8_t  RBR;                  /* Offset: 0x000 (R/ )  Receiver Buffer Register            */
        __O  uint8_t  THR;                  /* Offset: 0x000 ( /W)  Transmit Holding Register           */
        __IO uint8_t  DLL;                  /* Offset: 0x000 (R/W)  Divisor Latch LSB                   */
             uint32_t RESERVED0;
        };
        union {
        __IO uint8_t  DLM;                  /* Offset: 0x004 (R/W)  Divisor Latch MSB                   */
        __IO uint32_t IER;                  /* Offset: 0x004 (R/W)  Interrupt Enable Register           */
        };
        union {
        __I  uint32_t IIR;                  /* Offset: 0x008 (R/ )  Interrupt ID Register               */
        __O  uint8_t  FCR;                  /* Offset: 0x008 ( /W)  FIFO Control Register               */
        };
        __IO uint8_t  LCR;                  /* Offset: 0x00C (R/W)  Line Control Register               */
             uint8_t  RESERVED1[7];
        __I  uint8_t  LSR;                  /* Offset: 0x014 (R/ )  Line Status Register                */
             uint8_t  RESERVED2[7];
        __IO uint8_t  SCR;                  /* Offset: 0x01C (R/W)  Scratch Pad Register                */
             uint8_t  RESERVED3[3];
        __IO uint32_t ACR;                  /* Offset: 0x020 (R/W)  Autobaud Control Register           */
        __IO uint8_t  ICR;                  /* Offset: 0x024 (R/W)  IrDA Control Register               */
             uint8_t  RESERVED4[3];
        __IO uint8_t  FDR;                  /* Offset: 0x028 (R/W)  Fractional Divider Register         */
             uint8_t  RESERVED5[7];
        __IO uint8_t  TER;                  /* Offset: 0x030 (R/W)  Transmit Enable Register            */
             uint8_t  RESERVED6[39];
        __I  uint8_t  FIFOLVL;              /* Offset: 0x058 (R/ )  FIFO Level Register                 */
      } LPC_UART_TypeDef;

- To access the registers of the UART defined above, pointers to a register structure are defined. In this example <device abbreviation>_UART# are two pointers to UARTs defined with above register structure.

      #define LPC_UART2             ((LPC_UART_TypeDef      *) LPC_UART2_BASE    )
      #define LPC_UART3             ((LPC_UART_TypeDef      *) LPC_UART3_BASE    )

- The registers in the various UARTs can now be referred in the user code as shown below:

      LPC_UART1->DR   // is the data register of UART1.

## Minimal Requirements

To access the peripheral registers and related function in a device, the files device.h and core_cm#.h define as a minimum:

- The Register Layout Typedef for each peripheral that defines all register names. RESERVED is used to introduce space into the structure for adjusting the addresses of the peripheral registers.
  Example:

      typedef struct
      {
        __IO uint32_t CTRL;                 /* Offset: 0x000 (R/W)  SysTick Control and Status Register */
        __IO uint32_t LOAD;                 /* Offset: 0x004 (R/W)  SysTick Reload Value Register       */
        __IO uint32_t VAL;                  /* Offset: 0x008 (R/W)  SysTick Current Value Register      */
        __I  uint32_t CALIB;                /* Offset: 0x00C (R/ )  SysTick Calibration Register        */
      } SysTick_Type;

- Base Address for each peripheral (in case of multiple peripherals that use the same register layout typedef multiple base addresses are defined).
  Example:

      #define SysTick_BASE (SCS_BASE + 0x0010)            /* SysTick Base Address     */

- Access Definitions for each peripheral. In case of multiple peripherals that are using the same register layout typdef, multiple access definitions exist (LPC_UART0, LPC_UART2).
  Example:

      #define SysTick ((SysTick_Type *) Systick_BASE)    /* SysTick access definition */

These definitions allow accessing peripheral registers with simple assignments.

Example:

    SysTick->CTRL = 0;

## Optional Features

Optionally, the file device.h may define:

- #define constants, which simplify access to peripheral registers. These constants define bit-positions or other specific patterns that are required for programming peripheral registers. The identifiers start with <device abbreviation>_ and <peripheral name>_. It is recommended to use CAPITAL letters for such #define constants.

- More complex functions (i.e. status query before a sending register is accessed). Again, these functions start with <device abbreviation>_ and <peripheral name>_.