EmbeddedRelated.com
Memfault Beyond the Launch

GPIO library

Niels Tjørnhøj-Thomsen March 23, 2013 Coded in C for the NXP LPC17xx series
//---------------------------------------------------------
// start of header file (gpio.h)
//---------------------------------------------------------

#if !defined(_GPIO_H_)
#define _GPIO_H_

typedef unsigned long dword;

typedef struct tGPIOpinTag
{
  dword dwReg;
  dword dwClr;
  dword dwSet;
  int iBit;
  dword dwFunction;
} tGPIOpin;

#define REG32                volatile dword *

//
// bit patterns for alternate pin functions.
//
#define PINFUNC_GPIO         ( 0x00000000 )
#define PINFUNC_ALT1         ( 0x55555555 )
#define PINFUNC_ALT2         ( 0xAAAAAAAA )
#define PINFUNC_ALT3         ( 0xFFFFFFFF )

//
// Active high and low works by swapping the SET and CLR register offsets round
//
#define GPIO_ACTIVE_L        FIO_SET_OFS, FIO_CLR_OFS
#define GPIO_ACTIVE_H        FIO_CLR_OFS, FIO_SET_OFS

//
// Start addresses of GPIO blocks of registers
//
#define LPC_GPIO_BASE        ( 0x2009C000UL )
#define LPC_GPIO0_BASE       ( LPC_GPIO_BASE + 0x00000 )
#define LPC_GPIO1_BASE       ( LPC_GPIO_BASE + 0x00020 )
#define LPC_GPIO2_BASE       ( LPC_GPIO_BASE + 0x00040 )
#define LPC_GPIO3_BASE       ( LPC_GPIO_BASE + 0x00060 )
#define LPC_GPIO4_BASE       ( LPC_GPIO_BASE + 0x00080 )

//
// Offsets to the direction register and PIN register
//
#define FIO_SET_OFS          ( 0x00000018 )
#define FIO_CLR_OFS          ( 0x0000001C )
#define FIO_DIR_OFS          ( 0x00000000 )
#define FIO_PIN_OFS          ( 0x00000014 )
#define FIO_MASK_OFS         ( 0x00000010 )

// Parameters for vGPIODDsetDirection
#define   PIN_IN             ( FALSE )
#define   PIN_OUT            ( TRUE )

//
// Macro for pin definition structure
//
#ifdef _INSIDE_GPIODD_
//
// this version is for use inside the gpio module
//
#define PINFUNC_DEF( name, port, bit, act, func )   \
  const tGPIOpin t##name = {                        \
    LPC_GPIO##port##_BASE,                          \
    GPIO_ACTIVE_##act,                              \
    bit,                                            \
    PINFUNC_##func                                  \
  };                                                \
  const tGPIOpin * const name = &t##name;
#else
//
// and this is how external modules see the pin definition
//
#define PINFUNC_DEF( name, port, bit, act, func )   \
  extern const tGPIOpin * const name;
#endif

//
// include the hardware pin allocations from another file
// (see example below)
//
#include "gpio_pindefs.h"

extern void vGPIODDsetPinFunction( const tGPIOpin * const psPin );
extern void vGPIODDsetPinDirection( const tGPIOpin * const psPin, 
                                    const bool boOutput );
extern void vGPIODDconfigurePin( const tGPIOpin * const psPin, 
                                 const bool boOutput );
extern void vGPIODDsetActive( const tGPIOpin * const psPin );
extern void vGPIODDsetInactive( const tGPIOpin * const psPin );
extern bool boGPIODDgetPin( const tGPIOpin * const psPin );

#endif // _GPIO_H_

//---------------------------------------------------------
// end of header file (gpio.h)
//---------------------------------------------------------

//---------------------------------------------------------
// start of example gpio_pindefs.h
//---------------------------------------------------------
 
#if !defined(_GPIO_PINDEFS_H_)
#define _GPIO_PINDEFS_H_

// LEDs
PINFUNC_DEF( GPIO_LED_GREEN,          1, 25, L, GPIO )

// USB interface
PINFUNC_DEF( GPIO_USB_VBUS,           1, 30, H, ALT1 )
PINFUNC_DEF( GPIO_USB_CONNECT,        2,  9, L, ALT1 )

// Serial Ports
PINFUNC_DEF( UART0_RX,                0,  3, H, ALT1 )
PINFUNC_DEF( UART0_TX,                0,  2, H, ALT1 )

PINFUNC_DEF( UART1_RX,                0, 16, H, ALT1 )
PINFUNC_DEF( UART1_TX,                0, 15, H, ALT1 )

// SPI port
PINFUNC_DEF( SPI_MOSI,                0,  9, H, ALT2 )
PINFUNC_DEF( SPI_MISO,                0,  8, H, ALT2 )
PINFUNC_DEF( SPI_SCK,                 0,  7, H, ALT2 )
PINFUNC_DEF( SPI_SSEL,                0,  6, L, ALT2 )

#endif // _GPIO_PINDEFS_H_

//---------------------------------------------------------
// end of example gpio_pindefs.h
//---------------------------------------------------------

//---------------------------------------------------------
// start of gpio.c
//---------------------------------------------------------

#define   _INSIDE_GPIODD_             ( 1 )
#include "gpio.h"

/* --------------------------------------------------------
   vGPIODDsetPinFunction
   ........................................................
   Description  : Set the pin connect block from a pin 
                  definition 

   Params : psPin - pin definition

   Returns : Nothing
   ----------------------------------------------------- */

void vGPIODDsetPinFunction( const tGPIOpin * const psPin )
{
  if ( psPin )
  {
    // Each PINSELXX register contains the settings 
    // for 16 port pins.  Each PINSEL register is 4 bytes 
    // above the previous one.  Base addresses for ports 
    // are 32 bytes apart.
    dword dwPinSel = LPC_PINCON_BASE + 
                     ((psPin->dwReg - LPC_GPIO0_BASE) / 4) + 
                     ((psPin->iBit / 16) * 4);
    dword dwMask = ( 0x00000003 << ( 2 * ( psPin->iBit % 16 ) ) );
    REG32 pdwPinSel = (REG32)dwPinSel;

    *pdwPinSel = ( *pdwPinSel & ~dwMask ) | 
                 ( psPin->dwFunction & dwMask );
  }
}

/* --------------------------------------------------------
   vGPIODDsetPinDirection
   ........................................................
   Description  : Sets the pin direction from a pin 
                  definition

   Params : psPin - pin definition
            boOutput - set to TRUE to turn the pin into an 
                       output

   Returns : Nothing
   ----------------------------------------------------- */

void vGPIODDsetPinDirection( const tGPIOpin * const psPin, 
                             const bool boOutput )
{
  if ( psPin )
  {
    if( boOutput )
    {
      (*((REG32) (psPin->dwReg + FIO_DIR_OFS))) |= ( 1 << psPin->iBit );
    }
    else
    {
      (*((REG32) (psPin->dwReg + FIO_DIR_OFS))) &= ~( 1 << psPin->iBit );
    }
  }
}

/* --------------------------------------------------------
   vGPIODDconfigurePin
   ........................................................
   Description  : Combination function to configure and set 
                  direction of GPIO pin

   Params : psPin - pin definition
            boOutput - set to TRUE to turn the pin into an 
                       output

   Returns : Nothing
   ----------------------------------------------------- */

void vGPIODDconfigurePin( const tGPIOpin * const psPin, 
                          const bool boOutput )
{
  if ( psPin )
  {
    vGPIODDsetInactive( psPin );
    vGPIODDsetPinFunction( psPin );
    vGPIODDsetPinDirection( psPin, boOutput );
  }
}

/* --------------------------------------------------------
   vGPIODDsetActive
   ........................................................
   Description  : Sets a pin to its active state

   Params : psPin - pin definition

   Returns : Nothing
   ----------------------------------------------------- */

void vGPIODDsetActive( const tGPIOpin * const psPin )
{
  if ( psPin )
  {
    // use the Set register to set a single bit
    (*((REG32) (psPin->dwReg + psPin->dwSet))) = ( 1 << psPin->iBit );
  }
}

/* --------------------------------------------------------
   vGPIODDsetInactive
   ........................................................
   Description  : Sets a pin to its inactive state

   Params : psPin - pin definition

   Returns : Nothing
   ----------------------------------------------------- */

void vGPIODDsetInactive( const tGPIOpin * const psPin )
{
  if ( psPin )
  {
    // use the Clr register to clear a single bit
    (*((REG32) (psPin->dwReg + psPin->dwClr))) = ( 1 << psPin->iBit );
  }
}

/* --------------------------------------------------------
   boGPIODDgetPin
   ........................................................
   Description  : Gets the current state of a pin

   Params : psPin - pin definition

   Returns : TRUE if the pin is in its active state, 
             FALSE otherwise.
   ----------------------------------------------------- */

bool boGPIODDgetPin( const tGPIOpin * const psPin )
{
  if ( psPin )
  {
    dword dwPins = *((REG32) (psPin->dwReg + FIO_PIN_OFS));

    if ( psPin->dwSet > psPin->dwClr )
    {
      dwPins = ~dwPins;
    }

    return ((dwPins & ( 1 << psPin->iBit )) != 0 );
  }
  else
  {
    return FALSE;
  }
}

//---------------------------------------------------------
// end of gpio.c
//---------------------------------------------------------

Memfault Beyond the Launch