IO Configuration and GPIO

Before being able to do anything with the board we will needto know how all the internal blocks of the LPC1xxx are connected to the outside world (and to what devices the lpc1xxx connects).

The internal blocks (e.g. GPIO, SPI, I2C) are called "peripherals". It is important to note that although peripherals may have the same name on different LPC1xxx versions, these must not necessarily mean they are the same blocks.

This already starts with the IO Configuration. In the lpc111x and 13xx user manual you will find a section called "IO Configuration", here you will find a lot of different tegisters to specify for each I/O pin how it will be used.
Both devices have similar registers but some pins will contain different options.

The lpc17xx uses a different way of configuring I/O pins and in the user manual this is called "Pin connect block".

The lpc17xx uses a set of 11 registers, called PINSEL0 to PINSEL11, with each register specifying for up to 16 pins to which peripheral and which function of a peripheral they connect.

the lpc111x and 13xx have registers per pin with the name of the register describing which port and which bit of a port is being configured. These register have names like IOCON_PIO2_6.
Some of those register have a different name, like the IOCON_SWDIO_PIO1_3 register. This is done to make very clear that this pin has a special function - in this case the SWDIO signal that connects to the (LPC-Link) debugger. If you reprogram this pin to a different function then you will loose the connection with your debugger.

Just have a look at the section in the user manual but don't worry if you do not understand this completely. IO Configuration will be discussed when needed. For now just note that almost all pins connect to the GPIO block (except for some special pins like the SWD or JTAG debugger pins and the reset pin on the lpc111x/13xx (the lpc17xx has separate pins for reset and debugger interface).

GPIO

Most of the boards contain one or more LEDs that connect to a pin. For the LPCXpresso1114 and LPCXpresso1343 modules the LED is connected to GPIO0.7, on the LPCXpresso1769 it is connected to GPIO0.22.

A description of the GPIO block is in the user manual. Of interest to us now are just the data direction register, to specify that a pin should be an output pin, and the data register, to program a pin to 0 or 1.

LPC111x and LPC113x

Both the lpc111x and the 13xx have a data direction register called GPIO0DIR with one bit per GPIO pin, program each bit with a 0 to be used as input or 1 to be used as output.
It is important to understand the concept of the registers and their names as given in the user manual and the names in the LPCXpresso environment.

Have a look at the lpc11xx.h or the lpc13xx.h include files in the CMSISv2p00 project for your controller.
I've copied the sections we have to look at below:


typedef struct
{
  union {
    __IO uint32_t MASKED_ACCESS[4096];  /*!< Port data Register for pins PIOn_0 to PIOn_11 (R/W) */
    struct {
         uint32_t RESERVED0[4095];
    __IO uint32_t DATA;                 /*!< Port data Register (R/W) */
    };
  };
       uint32_t RESERVED1[4096];
  __IO uint32_t DIR;                    /*!< Data direction Register (R/W) */
  __IO uint32_t IS;                     /*!< Interrupt sense Register (R/W) */
  __IO uint32_t IBE;                    /*!< Interrupt both edges Register (R/W) */
  __IO uint32_t IEV;                    /*!< Interrupt event Register  (R/W) */
  __IO uint32_t IE;                     /*!< Interrupt mask Register (R/W) */
  __IO uint32_t RIS;                    /*!< Raw interrupt status Register (R/ ) */
  __IO uint32_t MIS;                    /*!< Masked interrupt status Register (R/ ) */
  __IO uint32_t IC;                     /*!< Interrupt clear Register (R/W) */
} LPC_GPIO_TypeDef;

#define LPC_GPIO_BASE         (LPC_AHB_BASE  + 0x00000)
#define LPC_GPIO0_BASE        (LPC_AHB_BASE  + 0x00000)
#define LPC_GPIO1_BASE        (LPC_AHB_BASE  + 0x10000)
#define LPC_GPIO2_BASE        (LPC_AHB_BASE  + 0x20000)
#define LPC_GPIO3_BASE        (LPC_AHB_BASE  + 0x30000)

The structure LPC_GPIO_TypeDef defines the registers inside the GPIO peripherals with the #defines defining the base addresses of those peripherals.

In this way we can easily access those registers from our program.
To define GPIO0.7 as output pin and set this pin to 1 (switching the LED on) you just have to do the following:

LPC_GPIO0->DIR |= 1<<7;
LPC_GPIO0->DATA |= 1<<7;

So the register name GPIO0DIR from the use manual translates into LPC_GPIO0->DIR into C code. Walking through the rest of this manual you will notice that other registers translate in a similar way.

From the LPC_GPIO_TypeDef structure you will notice there is a set of MASKED_ACCESS registers. These allow you to address only certain bits in the GPIO ports, allowing you to use a simple assignment instead of a read modify write sequence using the "|=" operator:

LPC_GPIO0->MASKED_ACCESS[1<<7] = 1<<7;

will just set bit 7 and leave all other bits unchanged.

LPC17XX

The GPIO on the LPC17xx is different, yet similar, but the MASKED_ACCESS registers are replaced by SET and CLR registers and the GPIO interrupts (not discussed here) has moved to a different peripheral.

To set the LED on the LPCXpresso1769 module (looking at the schematics you will notice that the LED is placed at GPIO0.22) is done in the following way:

LPC_GPIO0->FIODIR |= 1<<22;
LPC_GPIO0-FIOPIN |= 1<<22;

Alternatively, set GPIO0.22 to 1 using:

LPC_GPIO0->FIOSET = 1<<22;

And clear GPIO0.22 using:

LPC_GPIO0->FIOCLR = 1<<22;