[PATCH 2/2] Raspberry Pi implementation for the RTEMS GPIO API.

Gedare Bloom gedare at gwu.edu
Mon Jun 22 15:10:20 UTC 2015


On Mon, Jun 22, 2015 at 8:01 AM, Andre Marques
<andre.lousa.marques at gmail.com> wrote:
> Test cases can be found in https://github.com/asuol/RTEMS_rpi_testing
> ---
>  c/src/lib/libbsp/arm/raspberrypi/Makefile.am       |   7 +-
>  .../raspberrypi/gpio/gpio-interfaces-pi1-rev2.c    | 135 +++++++++
>  c/src/lib/libbsp/arm/raspberrypi/gpio/rpi-gpio.c   | 334 +++++++++++++++++++++
>  .../libbsp/arm/raspberrypi/include/raspberrypi.h   |  79 ++++-
>  .../lib/libbsp/arm/raspberrypi/include/rpi-gpio.h  |  76 +++++
>  c/src/lib/libbsp/arm/raspberrypi/irq/irq.c         | 105 ++++++-
>  c/src/lib/libbsp/arm/raspberrypi/preinstall.am     |   4 +
>  7 files changed, 722 insertions(+), 18 deletions(-)
>  create mode 100644 c/src/lib/libbsp/arm/raspberrypi/gpio/gpio-interfaces-pi1-rev2.c
>  create mode 100644 c/src/lib/libbsp/arm/raspberrypi/gpio/rpi-gpio.c
>  create mode 100644 c/src/lib/libbsp/arm/raspberrypi/include/rpi-gpio.h
>
> diff --git a/c/src/lib/libbsp/arm/raspberrypi/Makefile.am b/c/src/lib/libbsp/arm/raspberrypi/Makefile.am
> index c6133df..36a6f56 100644
> --- a/c/src/lib/libbsp/arm/raspberrypi/Makefile.am
> +++ b/c/src/lib/libbsp/arm/raspberrypi/Makefile.am
> @@ -44,6 +44,7 @@ include_bsp_HEADERS += include/irq.h
>  include_bsp_HEADERS += include/mmu.h
>  include_bsp_HEADERS += include/usart.h
>  include_bsp_HEADERS += include/raspberrypi.h
> +include_bsp_HEADERS += include/rpi-gpio.h
>
>  include_libcpu_HEADERS = ../../../libcpu/arm/shared/include/cache_.h \
>      ../../../libcpu/arm/shared/include/arm-cp15.h
> @@ -79,7 +80,6 @@ libbsp_a_SOURCES += ../../shared/bspclean.c
>  libbsp_a_SOURCES += ../../shared/bspgetworkarea.c
>  libbsp_a_SOURCES += ../../shared/bsplibc.c
>  libbsp_a_SOURCES += ../../shared/bsppost.c
> -libbsp_a_SOURCES += ../../shared/bsppredriverhook.c
>  libbsp_a_SOURCES += ../../shared/bsppretaskinghook.c
>  libbsp_a_SOURCES += ../../shared/cpucounterread.c
>  libbsp_a_SOURCES += ../../shared/cpucounterdiff.c
> @@ -88,6 +88,7 @@ libbsp_a_SOURCES += ../../shared/sbrk.c
>  libbsp_a_SOURCES += ../../shared/src/stackalloc.c
>  libbsp_a_SOURCES += ../shared/startup/bsp-start-memcpy.S
>  libbsp_a_SOURCES += ../shared/arm-cp15-set-ttb-entries.c
> +libbsp_a_SOURCES += ../../shared/gpio.c
>
>  # Startup
>  libbsp_a_SOURCES += ../../shared/bspreset_loop.c
> @@ -117,6 +118,10 @@ libbsp_a_SOURCES += clock/clockdrv.c ../../../shared/clockdrv_shell.h
>  # Timer
>  libbsp_a_SOURCES += misc/timer.c
>
> +# GPIO
> +
> +libbsp_a_SOURCES += gpio/rpi-gpio.c
> +
>  # RTC
>
>  # SSP
> diff --git a/c/src/lib/libbsp/arm/raspberrypi/gpio/gpio-interfaces-pi1-rev2.c b/c/src/lib/libbsp/arm/raspberrypi/gpio/gpio-interfaces-pi1-rev2.c
> new file mode 100644
> index 0000000..5699636
> --- /dev/null
> +++ b/c/src/lib/libbsp/arm/raspberrypi/gpio/gpio-interfaces-pi1-rev2.c
> @@ -0,0 +1,135 @@
> +/**
> + * @file gpio-interfaces.c
> + *
> + * @ingroup raspberrypi_gpio
> + *
> + * @brief Raspberry PI GPIO interface definitions.
> + */
> +
> +/*
> + *  Copyright (c) 2015 Andre Marques <andre.lousa.marques at gmail.com>
> + *
> + *  The license and distribution terms for this file may be
> + *  found in the file LICENSE in this distribution or at
> + *  http://www.rtems.org/license/LICENSE.
> + */
> +
> +rtems_gpio_pin_conf arm_tdi = {
> + pin_number: 4,
> + function: BSP_SPECIFIC,
> + pull_mode: NO_PULL_RESISTOR,
> + interrupt: NULL,
> + output_enabled: FALSE,
> + logic_invert: FALSE,
> + bsp_specific: &alt_func_def[5]
> +};
These can be made const, and : initializers should not be used as they
are non-standard, you can use . instead for designated initializers.

> +
> +rtems_gpio_pin_conf arm_trst = {
> + pin_number: 22,
> + function: BSP_SPECIFIC,
> + pull_mode: NO_PULL_RESISTOR,
> + interrupt: NULL,
> + output_enabled: FALSE,
> + logic_invert: FALSE,
> + bsp_specific: &alt_func_def[4]
> +};
> +
> +rtems_gpio_pin_conf arm_tdo = {
> + pin_number: 24,
> + function: BSP_SPECIFIC,
> + pull_mode: NO_PULL_RESISTOR,
> + interrupt: NULL,
> + output_enabled: FALSE,
> + logic_invert: FALSE,
> + bsp_specific: &alt_func_def[4]
> +};
> +
> +rtems_gpio_pin_conf arm_tck = {
> + pin_number: 25,
> + function: BSP_SPECIFIC,
> + pull_mode: NO_PULL_RESISTOR,
> + interrupt: NULL,
> + output_enabled: FALSE,
> + logic_invert: FALSE,
> + bsp_specific: &alt_func_def[4]
> +};
> +
> +rtems_gpio_pin_conf arm_tms = {
> + pin_number: 27,
> + function: BSP_SPECIFIC,
> + pull_mode: NO_PULL_RESISTOR,
> + interrupt: NULL,
> + output_enabled: FALSE,
> + logic_invert: FALSE,
> + bsp_specific: &alt_func_def[4]
> +};
> +
> +rtems_gpio_pin_conf spi_miso = {
> + pin_number: 7,
> + function: BSP_SPECIFIC,
> + pull_mode: NO_PULL_RESISTOR,
> + interrupt: NULL,
> + output_enabled: FALSE,
> + logic_invert: FALSE,
> + bsp_specific: &alt_func_def[0]
> +};
> +
> +rtems_gpio_pin_conf spi_mosi = {
> + pin_number: 8,
> + function: BSP_SPECIFIC,
> + pull_mode: NO_PULL_RESISTOR,
> + interrupt: NULL,
> + output_enabled: FALSE,
> + logic_invert: FALSE,
> + bsp_specific: &alt_func_def[0]
> +};
> +
> +rtems_gpio_pin_conf spi_sclk = {
> + pin_number: 9,
> + function: BSP_SPECIFIC,
> + pull_mode: NO_PULL_RESISTOR,
> + interrupt: NULL,
> + output_enabled: FALSE,
> + logic_invert: FALSE,
> + bsp_specific: &alt_func_def[0]
> +};
> +
> +rtems_gpio_pin_conf spi_ce_0 = {
> + pin_number: 10,
> + function: BSP_SPECIFIC,
> + pull_mode: NO_PULL_RESISTOR,
> + interrupt: NULL,
> + output_enabled: FALSE,
> + logic_invert: FALSE,
> + bsp_specific: &alt_func_def[0]
> +};
> +
> +rtems_gpio_pin_conf spi_ce_1 = {
> + pin_number: 11,
> + function: BSP_SPECIFIC,
> + pull_mode: NO_PULL_RESISTOR,
> + interrupt: NULL,
> + output_enabled: FALSE,
> + logic_invert: FALSE,
> + bsp_specific: &alt_func_def[0]
> +};
> +
> +rtems_gpio_pin_conf i2c_sda = {
> + pin_number: 2,
> + function: BSP_SPECIFIC,
> + pull_mode: PULL_UP,
> + interrupt: NULL,
> + output_enabled: FALSE,
> + logic_invert: FALSE,
> + bsp_specific: &alt_func_def[0]
> +};
> +
> +rtems_gpio_pin_conf i2c_scl = {
> + pin_number: 3,
> + function: BSP_SPECIFIC,
> + pull_mode: PULL_UP,
> + interrupt: NULL,
> + output_enabled: FALSE,
> + logic_invert: FALSE,
> + bsp_specific: &alt_func_def[0]
> +};
> diff --git a/c/src/lib/libbsp/arm/raspberrypi/gpio/rpi-gpio.c b/c/src/lib/libbsp/arm/raspberrypi/gpio/rpi-gpio.c
> new file mode 100644
> index 0000000..62d87ba
> --- /dev/null
> +++ b/c/src/lib/libbsp/arm/raspberrypi/gpio/rpi-gpio.c
> @@ -0,0 +1,334 @@
> +/**
> + * @file rpi-gpio.c
> + *
> + * @ingroup raspberrypi_gpio
> + *
> + * @brief Support for the Raspberry PI GPIO.
> + */
> +
> +/*
> + *  Copyright (c) 2014-2015 Andre Marques <andre.lousa.marques at gmail.com>
> + *
> + *  The license and distribution terms for this file may be
> + *  found in the file LICENSE in this distribution or at
> + *  http://www.rtems.org/license/LICENSE.
> + */
> +
> +#include <bsp/raspberrypi.h>
> +#include <bsp/irq-generic.h>
> +#include <bsp/gpio.h>
> +#include <bsp/rpi-gpio.h>
> +
> +#include <stdlib.h>
> +
> +/* Calculates a bitmask to assign an alternate function to a given pin. */
> +#define SELECT_PIN_FUNCTION(fn, pn) (fn << ((pn % 10) * 3))
> +
> +rtems_gpio_specific_data alt_func_def[] = {
> +  {io_function: RPI_ALT_FUNC_0, pin_data: NULL},
> +  {io_function: RPI_ALT_FUNC_1, pin_data: NULL},
> +  {io_function: RPI_ALT_FUNC_2, pin_data: NULL},
> +  {io_function: RPI_ALT_FUNC_3, pin_data: NULL},
> +  {io_function: RPI_ALT_FUNC_4, pin_data: NULL},
> +  {io_function: RPI_ALT_FUNC_5, pin_data: NULL}
> +};
> +
> +/* Raspberry Pi 1 Rev 2 gpio interface definitions. */
> +#include "gpio-interfaces-pi1-rev2.c"
> +
> +/* Waits a number of CPU cycles. */
> +static void arm_delay (int cycles)
> +{
> +  int i;
> +
> +  for ( i = 0; i < cycles; ++i ) {
> +    asm volatile ("nop");
> +  }
> +}
> +
> +static rtems_status_code rpi_select_pin_function(uint32_t bank, uint32_t pin, uint32_t type)
> +{
> +  /* Calculate the pin function select register address. */
> +  volatile unsigned int *pin_addr = (unsigned int *)BCM2835_GPIO_REGS_BASE +
> +                                    (pin / 10);
> +
> +  *(pin_addr) |= SELECT_PIN_FUNCTION(type, pin);
> +
> +  return RTEMS_SUCCESSFUL;
> +}
> +
> +rtems_gpio_layout rtems_bsp_gpio_initialize()
> +{
> +  rtems_gpio_layout rpi_layout;
> +
> +  rpi_layout.pin_count = GPIO_COUNT;
> +  rpi_layout.pins_per_bank = GPIO_COUNT;
> +
> +  return rpi_layout;
> +}
> +
> +rtems_status_code rtems_bsp_gpio_multi_set(uint32_t bank, uint32_t bitmask)
> +{
> +  BCM2835_REG(BCM2835_GPIO_GPSET0) |= bitmask;
> +
> +  return RTEMS_SUCCESSFUL;
> +}
> +
> +rtems_status_code rtems_bsp_gpio_multi_clear(uint32_t bank, uint32_t bitmask)
> +{
> +  BCM2835_REG(BCM2835_GPIO_GPCLR0) |= bitmask;
> +
> +  return RTEMS_SUCCESSFUL;
> +}
> +
> +rtems_status_code rtems_bsp_gpio_set(uint32_t bank, uint32_t pin)
> +{
> +  BCM2835_REG(BCM2835_GPIO_GPSET0) = (1 << pin);
> +
> +  return RTEMS_SUCCESSFUL;
> +}
> +
> +rtems_status_code rtems_bsp_gpio_clear(uint32_t bank, uint32_t pin)
> +{
> +  BCM2835_REG(BCM2835_GPIO_GPCLR0) = (1 << pin);
> +
> +  return RTEMS_SUCCESSFUL;
> +}
> +
> +int rtems_bsp_gpio_get_value(uint32_t bank, uint32_t pin)
> +{
> +  return (BCM2835_REG(BCM2835_GPIO_GPLEV0) & (1 << pin));
> +}
> +
> +rtems_status_code rtems_bsp_gpio_select_input(uint32_t bank, uint32_t pin, void* bsp_specific)
> +{
> +  /* Calculate the pin function select register address. */
> +  volatile unsigned int *pin_addr = (unsigned int *)BCM2835_GPIO_REGS_BASE +
> +                                    (pin / 10);
> +
> +  *(pin_addr) &= ~SELECT_PIN_FUNCTION(RPI_DIGITAL_IN, pin);
> +
> +  return RTEMS_SUCCESSFUL;
> +}
> +
> +rtems_status_code rtems_bsp_gpio_select_output(uint32_t bank, uint32_t pin, void* bsp_specific)
> +{
> +  return rpi_select_pin_function(bank, pin, RPI_DIGITAL_OUT);
> +}
> +
> +rtems_status_code rtems_bsp_select_specific_io(uint32_t bank, uint32_t pin, uint32_t function, void* pin_data)
> +{
> +  return rpi_select_pin_function(bank, pin, function);
> +}
> +
> +rtems_status_code rtems_bsp_gpio_set_resistor_mode(uint32_t bank, uint32_t pin, rtems_gpio_pull_mode mode)
> +{
> +  /* Set control signal. */
> +  switch ( mode ) {
> +    case PULL_UP:
> +      BCM2835_REG(BCM2835_GPIO_GPPUD) = (1 << 1);
> +      break;
> +    case PULL_DOWN:
> +      BCM2835_REG(BCM2835_GPIO_GPPUD) = (1 << 0);
> +      break;
> +    case NO_PULL_RESISTOR:
> +      BCM2835_REG(BCM2835_GPIO_GPPUD) = 0;
> +      break;
> +    default:
> +      return RTEMS_UNSATISFIED;
> +  }
> +
> +  /* Wait 150 cyles, as per BCM2835 documentation. */
> +  arm_delay(150);
> +
> +  /* Setup clock for the control signal. */
> +  BCM2835_REG(BCM2835_GPIO_GPPUDCLK0) = (1 << pin);
> +
> +  arm_delay(150);
> +
> +  /* Remove the control signal. */
> +  BCM2835_REG(BCM2835_GPIO_GPPUD) = 0;
> +
> +  /* Remove the clock. */
> +  BCM2835_REG(BCM2835_GPIO_GPPUDCLK0) = 0;
> +
> +  return RTEMS_SUCCESSFUL;
> +}
> +
> +rtems_vector_number rtems_bsp_gpio_get_vector(uint32_t bank)
> +{
> +  return BCM2835_IRQ_ID_GPIO_0;
> +}
> +
> +uint32_t rtems_bsp_gpio_interrupt_line(rtems_vector_number vector)
> +{
> +  return BCM2835_REG(BCM2835_GPIO_GPEDS0);
> +}
> +
> +void rtems_bsp_gpio_clear_interrupt_line(rtems_vector_number vector, uint32_t event_status)
> +{
> +  BCM2835_REG(BCM2835_GPIO_GPEDS0) = event_status;
> +}
> +
> +rtems_status_code rtems_bsp_enable_interrupt(uint32_t bank, uint32_t pin, rtems_gpio_interrupt interrupt)
> +{
> +  switch ( interrupt ) {
> +    case FALLING_EDGE:
> +      /* Enables asynchronous falling edge detection. */
> +      BCM2835_REG(BCM2835_GPIO_GPAFEN0) |= (1 << pin);
> +      break;
> +    case RISING_EDGE:
> +      /* Enables asynchronous rising edge detection. */
> +      BCM2835_REG(BCM2835_GPIO_GPAREN0) |= (1 << pin);
> +      break;
> +    case BOTH_EDGES:
> +      /* Enables asynchronous falling edge detection. */
> +      BCM2835_REG(BCM2835_GPIO_GPAFEN0) |= (1 << pin);
> +
> +      /* Enables asynchronous rising edge detection. */
> +      BCM2835_REG(BCM2835_GPIO_GPAREN0) |= (1 << pin);
> +      break;
> +    case LOW_LEVEL:
> +      /* Enables pin low level detection. */
> +      BCM2835_REG(BCM2835_GPIO_GPLEN0) |= (1 << pin);
> +      break;
> +    case HIGH_LEVEL:
> +      /* Enables pin high level detection. */
> +      BCM2835_REG(BCM2835_GPIO_GPHEN0) |= (1 << pin);
> +      break;
> +    case BOTH_LEVELS:
> +      /* Enables pin low level detection. */
> +      BCM2835_REG(BCM2835_GPIO_GPLEN0) |= (1 << pin);
> +
> +      /* Enables pin high level detection. */
> +      BCM2835_REG(BCM2835_GPIO_GPHEN0) |= (1 << pin);
> +      break;
> +    case NONE:
> +    default:
> +      return RTEMS_UNSATISFIED;
> +  }
> +
> +  return RTEMS_SUCCESSFUL;
> +}
> +
> +rtems_status_code rtems_bsp_disable_interrupt(uint32_t bank, uint32_t pin, rtems_gpio_interrupt enabled_interrupt)
> +{
> +  switch ( enabled_interrupt ) {
> +    case FALLING_EDGE:
> +      /* Disables asynchronous falling edge detection. */
> +      BCM2835_REG(BCM2835_GPIO_GPAFEN0) &= ~(1 << pin);
> +      break;
> +    case RISING_EDGE:
> +      /* Disables asynchronous rising edge detection. */
> +      BCM2835_REG(BCM2835_GPIO_GPAREN0) &= ~(1 << pin);
> +      break;
> +    case BOTH_EDGES:
> +      /* Disables asynchronous falling edge detection. */
> +      BCM2835_REG(BCM2835_GPIO_GPAFEN0) &= ~(1 << pin);
> +
> +      /* Disables asynchronous rising edge detection. */
> +      BCM2835_REG(BCM2835_GPIO_GPAREN0) &= ~(1 << pin);
> +      break;
> +    case LOW_LEVEL:
> +      /* Disables pin low level detection. */
> +      BCM2835_REG(BCM2835_GPIO_GPLEN0) &= ~(1 << pin);
> +      break;
> +    case HIGH_LEVEL:
> +      /* Disables pin high level detection. */
> +      BCM2835_REG(BCM2835_GPIO_GPHEN0) &= ~(1 << pin);
> +      break;
> +    case BOTH_LEVELS:
> +      /* Disables pin low level detection. */
> +      BCM2835_REG(BCM2835_GPIO_GPLEN0) &= ~(1 << pin);
> +
> +      /* Disables pin high level detection. */
> +      BCM2835_REG(BCM2835_GPIO_GPHEN0) &= ~(1 << pin);
> +      break;
> +    case NONE:
> +    default:
> +      return RTEMS_UNSATISFIED;
> +  }
> +
> +  return RTEMS_SUCCESSFUL;
> +}
> +
> +rtems_status_code rpi_gpio_select_jtag(void)
> +{
> +  rtems_status_code sc;
> +
> +  sc = rtems_gpio_request_conf(&arm_tdi);
> +
> +  if ( sc != RTEMS_SUCCESSFUL ) {
> +    return sc;
> +  }
> +
> +  sc = rtems_gpio_request_conf(&arm_trst);
> +
> +  if ( sc != RTEMS_SUCCESSFUL ) {
> +    return sc;
> +  }
> +
> +  sc = rtems_gpio_request_conf(&arm_tdo);
> +
> +  if ( sc != RTEMS_SUCCESSFUL ) {
> +    return sc;
> +  }
> +
> +  sc = rtems_gpio_request_conf(&arm_tck);
> +
> +  if ( sc != RTEMS_SUCCESSFUL ) {
> +    return sc;
> +  }
> +
> +  sc = rtems_gpio_request_conf(&arm_tms);
> +
> +  return sc;
> +}
> +
> +rtems_status_code rpi_gpio_select_spi(void)
> +{
> +  rtems_status_code sc;
> +
> +  sc = rtems_gpio_request_conf(&spi_miso);
> +
> +  if ( sc != RTEMS_SUCCESSFUL ) {
> +    return sc;
> +  }
> +
> +  sc = rtems_gpio_request_conf(&spi_mosi);
> +
> +  if ( sc != RTEMS_SUCCESSFUL ) {
> +    return sc;
> +  }
> +
> +  sc = rtems_gpio_request_conf(&spi_sclk);
> +
> +  if ( sc != RTEMS_SUCCESSFUL ) {
> +    return sc;
> +  }
> +
> +  sc = rtems_gpio_request_conf(&spi_ce_0);
> +
> +  if ( sc != RTEMS_SUCCESSFUL ) {
> +    return sc;
> +  }
> +
> +  sc = rtems_gpio_request_conf(&spi_ce_1);
> +
> +  return sc;
> +}
> +
> +rtems_status_code rpi_gpio_select_i2c(void)
> +{
> +  rtems_status_code sc;
> +
> +  sc = rtems_gpio_request_conf(&i2c_sda);
> +
> +  if ( sc != RTEMS_SUCCESSFUL ) {
> +    return sc;
> +  }
> +
> +  sc = rtems_gpio_request_conf(&i2c_scl);
> +
> +  return sc;
> +}
> diff --git a/c/src/lib/libbsp/arm/raspberrypi/include/raspberrypi.h b/c/src/lib/libbsp/arm/raspberrypi/include/raspberrypi.h
> index c33e22a..ddcd4ff 100644
> --- a/c/src/lib/libbsp/arm/raspberrypi/include/raspberrypi.h
> +++ b/c/src/lib/libbsp/arm/raspberrypi/include/raspberrypi.h
> @@ -1,6 +1,5 @@
> -
>  /**
> - * @file
> + * @file raspberrypi.h
>   *
>   * @ingroup raspberrypi_reg
>   *
> @@ -8,7 +7,8 @@
>   */
>
>  /*
> - * Copyright (c) 2013 Alan Cudmore.
> + *  Copyright (c) 2014 Andre Marques <andre.lousa.marques at gmail.com>
> + *  Copyright (c) 2013 Alan Cudmore.
>   *
>   *  The license and distribution terms for this file may be
>   *  found in the file LICENSE in this distribution or at
> @@ -93,8 +93,16 @@
>  #define BCM2835_GPIO_GPFSEL1     (BCM2835_GPIO_REGS_BASE+0x04)
>  #define BCM2835_GPIO_GPSET0      (BCM2835_GPIO_REGS_BASE+0x1C)
>  #define BCM2835_GPIO_GPCLR0      (BCM2835_GPIO_REGS_BASE+0x28)
> +#define BCM2835_GPIO_GPLEV0      (BCM2835_GPIO_REGS_BASE+0x34)
> +#define BCM2835_GPIO_GPEDS0      (BCM2835_GPIO_REGS_BASE+0x40)
> +#define BCM2835_GPIO_GPREN0      (BCM2835_GPIO_REGS_BASE+0x4C)
> +#define BCM2835_GPIO_GPFEN0      (BCM2835_GPIO_REGS_BASE+0x58)
> +#define BCM2835_GPIO_GPHEN0      (BCM2835_GPIO_REGS_BASE+0x64)
> +#define BCM2835_GPIO_GPLEN0      (BCM2835_GPIO_REGS_BASE+0x70)
> +#define BCM2835_GPIO_GPAREN0     (BCM2835_GPIO_REGS_BASE+0x7C)
> +#define BCM2835_GPIO_GPAFEN0     (BCM2835_GPIO_REGS_BASE+0x88)
>  #define BCM2835_GPIO_GPPUD       (BCM2835_GPIO_REGS_BASE+0x94)
> -#define BCM2835_GPIO_GPPUDCLK0   (BCM2835_GPIO_REGS_BASE+0x98)
> +#define BCM2835_GPIO_GPPUDCLK0   (BCM2835_GPIO_REGS_BASE+0x98)
>
>  /** @} */
>
> @@ -121,14 +129,12 @@
>
>  /** @} */
>
> -
>  /**
>   * @name UART 0 (PL011) Registers
>   *
>   * @{
>   */
>
> -
>  #define BCM2835_UART0_BASE       (RPI_PERIPHERAL_BASE + 0x201000)
>
>  #define BCM2835_UART0_DR         (BCM2835_UART0_BASE+0x00)
> @@ -159,9 +165,68 @@
>  #define BCM2835_UART0_ICR_RX    0x10
>  #define BCM2835_UART0_ICR_TX    0x20
>
> +/** @} */
> +
> +/**
> + * @name I2C (BSC) Registers
> + *
> + * @{
> + */
> +
> +#define BCM2835_I2C_BASE           (0x20804000)
> +
> +#define BCM2835_I2C_C              (BCM2835_I2C_BASE+0x00)
> +#define BCM2835_I2C_S              (BCM2835_I2C_BASE+0x04)
> +#define BCM2835_I2C_DLEN           (BCM2835_I2C_BASE+0x08)
> +#define BCM2835_I2C_A              (BCM2835_I2C_BASE+0x0C)
> +#define BCM2835_I2C_FIFO           (BCM2835_I2C_BASE+0x10)
> +#define BCM2835_I2C_DIV            (BCM2835_I2C_BASE+0x14)
> +#define BCM2835_I2C_DEL            (BCM2835_I2C_BASE+0x18)
> +#define BCM2835_I2C_CLKT           (BCM2835_I2C_BASE+0x1C)
>
>  /** @} */
>
> +/**
> + * @name SPI Registers
> + *
> + * @{
> + */
> +
> +#define BCM2835_SPI_BASE           (0x20204000)
> +
> +#define BCM2835_SPI_CS             (BCM2835_SPI_BASE+0x00)
> +#define BCM2835_SPI_FIFO           (BCM2835_SPI_BASE+0x04)
> +#define BCM2835_SPI_CLK            (BCM2835_SPI_BASE+0x08)
> +#define BCM2835_SPI_DLEN           (BCM2835_SPI_BASE+0x0C)
> +#define BCM2835_SPI_LTOH           (BCM2835_SPI_BASE+0x10)
> +#define BCM2835_SPI_DC             (BCM2835_SPI_BASE+0x14)
> +
> +/** @} */
> +
> +/**
> + * @name I2C/SPI slave BSC Registers
> + *
> + * @{
> + */
> +
> +#define BCM2835_I2C_SPI_BASE       (0x20214000)
> +
> +#define BCM2835_I2C_SPI_DR         (BCM2835_I2C_SPI_BASE+0x00)
> +#define BCM2835_I2C_SPI_RSR        (BCM2835_I2C_SPI_BASE+0x04)
> +#define BCM2835_I2C_SPI_SLV        (BCM2835_I2C_SPI_BASE+0x08)
> +#define BCM2835_I2C_SPI_CR         (BCM2835_I2C_SPI_BASE+0x0C)
> +#define BCM2835_I2C_SPI_FR         (BCM2835_I2C_SPI_BASE+0x10)
> +#define BCM2835_I2C_SPI_IFLS       (BCM2835_I2C_SPI_BASE+0x14)
> +#define BCM2835_I2C_SPI_IMSC       (BCM2835_I2C_SPI_BASE+0x18)
> +#define BCM2835_I2C_SPI_RIS        (BCM2835_I2C_SPI_BASE+0x1C)
> +#define BCM2835_I2C_SPI_MIS        (BCM2835_I2C_SPI_BASE+0x20)
> +#define BCM2835_I2C_SPI_ICR        (BCM2835_I2C_SPI_BASE+0x24)
> +#define BCM2835_I2C_SPI_DMACR      (BCM2835_I2C_SPI_BASE+0x28)
> +#define BCM2835_I2C_SPI_TDR        (BCM2835_I2C_SPI_BASE+0x2C)
> +#define BCM2835_I2C_SPI_GPUSTAT    (BCM2835_I2C_SPI_BASE+0x30)
> +#define BCM2835_I2C_SPI_HCTRL      (BCM2835_I2C_SPI_BASE+0x34)
> +
> +/** @} */
>
>  /**
>   * @name IRQ Registers
> @@ -184,7 +249,6 @@
>
>  /** @} */
>
> -
>  /**
>   * @name GPU Timer Registers
>   *
> @@ -208,7 +272,6 @@
>
>  /** @} */
>
> -
>  /** @} */
>
>  #endif /* LIBBSP_ARM_RASPBERRYPI_RASPBERRYPI_H */
> diff --git a/c/src/lib/libbsp/arm/raspberrypi/include/rpi-gpio.h b/c/src/lib/libbsp/arm/raspberrypi/include/rpi-gpio.h
> new file mode 100644
> index 0000000..be0dd86
> --- /dev/null
> +++ b/c/src/lib/libbsp/arm/raspberrypi/include/rpi-gpio.h
> @@ -0,0 +1,76 @@
> +/**
> + * @file rpi-gpio.h
> + *
> + * @ingroup raspberrypi_gpio
> + *
> + * @brief Raspberry Pi specific GPIO definitions.
> + */
> +
> +/*
> + *  Copyright (c) 2015 Andre Marques <andre.lousa.marques at gmail.com>
> + *
> + *  The license and distribution terms for this file may be
> + *  found in the file LICENSE in this distribution or at
> + *  http://www.rtems.org/license/LICENSE.
> + */
> +
> +#ifndef LIBBSP_ARM_RASPBERRYPI_RPI_GPIO_H
> +#define LIBBSP_ARM_RASPBERRYPI_RPI_GPIO_H
> +
> +#include <rtems.h>
> +
> +#ifdef __cplusplus
> +extern "C" {
> +#endif /* __cplusplus */
> +
> +/**
> + * @brief  Total number of GPIOs on the Raspberry Pi,
> + *         including physical GPIO pins (available on the board hardware)
> + *         and system GPIOs (only accessible to the system).
> + */
> +#define GPIO_COUNT 54
> +
> +/**
> + * @brief  Raspberry Pi GPIO functions.
> + */
> +#define RPI_DIGITAL_IN  7
> +#define RPI_DIGITAL_OUT 1
> +#define RPI_ALT_FUNC_0  4
> +#define RPI_ALT_FUNC_1  5
> +#define RPI_ALT_FUNC_2  6
> +#define RPI_ALT_FUNC_3  7
> +#define RPI_ALT_FUNC_4  3
> +#define RPI_ALT_FUNC_5  2
> +
> +/**
> + * @brief Setups a JTAG interface.
> + *
> + * @retval RTEMS_SUCCESSFUL JTAG interface successfully configured.
> + * @retval * At least one of the required pins is currently
> + *            occupied, @see rtems_gpio_request_conf().
> + */
> +extern rtems_status_code rpi_gpio_select_jtag(void);
> +
> +/**
> + * @brief Setups a SPI interface.
> + *
> + * @retval RTEMS_SUCCESSFUL SPI interface successfully configured.
> + * @retval * At least one of the required pins is currently
> + *            occupied, @see rtems_gpio_request_conf().
> + */
> +extern rtems_status_code rpi_gpio_select_spi(void);
> +
> +/**
> + * @brief Setups a I2C interface.
> + *
> + * @retval RTEMS_SUCCESSFUL I2C interface successfully configured.
> + * @retval * At least one of the required pins is currently
> + *            occupied, @see rtems_gpio_request_conf().
> + */
> +extern rtems_status_code rpi_gpio_select_i2c(void);
> +
> +#ifdef __cplusplus
> +}
> +#endif /* __cplusplus */
> +
> +#endif /* LIBBSP_ARM_RASPBERRYPI_RPI_GPIO_H */
> diff --git a/c/src/lib/libbsp/arm/raspberrypi/irq/irq.c b/c/src/lib/libbsp/arm/raspberrypi/irq/irq.c
> index 4132ef9..0867b6b 100644
> --- a/c/src/lib/libbsp/arm/raspberrypi/irq/irq.c
> +++ b/c/src/lib/libbsp/arm/raspberrypi/irq/irq.c
> @@ -1,5 +1,5 @@
>  /**
> - * @file
> + * @file irq.c
>   *
>   * @ingroup raspberrypi_interrupt
>   *
> @@ -7,6 +7,8 @@
>   */
>
>  /*
> + * Copyright (c) 2014 Andre Marques <andre.lousa.marques at gmail.com>
> + *
>   * Copyright (c) 2009
>   * embedded brains GmbH
>   * Obere Lagerstr. 30
> @@ -52,22 +54,47 @@ void bsp_interrupt_dispatch(void)
>    rtems_vector_number vector = 255;
>
>    /* ARM timer */
> -  if (BCM2835_REG(BCM2835_IRQ_BASIC) && 0x1)
> +  if ( BCM2835_REG(BCM2835_IRQ_BASIC) & 0x1 )
>    {
>        vector = BCM2835_IRQ_ID_TIMER_0;
> -
>    }
>    /* UART 0 */
> -  else if ( BCM2835_REG(BCM2835_IRQ_BASIC) && BCM2835_BIT(19))
> +  else if ( BCM2835_REG(BCM2835_IRQ_BASIC) & BCM2835_BIT(19) )
>    {
>        vector = BCM2835_IRQ_ID_UART;
>    }
> +  /* GPIO 0*/
> +  else if ( BCM2835_REG(BCM2835_IRQ_PENDING2) & BCM2835_BIT(17) )
> +  {
> +      vector = BCM2835_IRQ_ID_GPIO_0;
> +  }
> +  else if ( BCM2835_REG(BCM2835_IRQ_PENDING2) & BCM2835_BIT(18) )
> +  {
> +      vector = BCM2835_IRQ_ID_GPIO_1;
> +  }
> +  else if ( BCM2835_REG(BCM2835_IRQ_PENDING2) & BCM2835_BIT(19) )
> +  {
> +      vector = BCM2835_IRQ_ID_GPIO_2;
> +  }
> +  else if ( BCM2835_REG(BCM2835_IRQ_PENDING2) & BCM2835_BIT(20) )
> +  {
> +      vector = BCM2835_IRQ_ID_GPIO_3;
> +  }
> +  /* I2C */
> +  else if ( BCM2835_REG(BCM2835_IRQ_PENDING2) & BCM2835_BIT(21) )
> +  {
> +      vector = BCM2835_IRQ_ID_I2C;
> +  }
> +  /* SPI */
> +  else if ( BCM2835_REG(BCM2835_IRQ_PENDING2) & BCM2835_BIT(22) )
> +  {
> +      vector = BCM2835_IRQ_ID_SPI;
> +  }
>
>    if ( vector < 255 )
>    {
>        bsp_interrupt_handler_dispatch(vector);
>    }
> -
>  }
>
>  rtems_status_code bsp_interrupt_vector_enable(rtems_vector_number vector)
> @@ -75,8 +102,8 @@ rtems_status_code bsp_interrupt_vector_enable(rtems_vector_number vector)
>    rtems_interrupt_level  level;
>
>    rtems_interrupt_disable(level);
> -
> -   /* ARM Timer */
> +
> +  /* ARM Timer */
>    if ( vector == BCM2835_IRQ_ID_TIMER_0 )
>    {
>        BCM2835_REG(BCM2835_IRQ_ENABLE_BASIC) = 0x1;
> @@ -85,8 +112,38 @@ rtems_status_code bsp_interrupt_vector_enable(rtems_vector_number vector)
>    else if ( vector == BCM2835_IRQ_ID_UART )
>    {
>        BCM2835_REG(BCM2835_IRQ_ENABLE2) =  BCM2835_BIT(25);
> -
>    }
> +  /* GPIO 0 */
> +  else if ( vector == BCM2835_IRQ_ID_GPIO_0 )
> +  {
> +      BCM2835_REG(BCM2835_IRQ_ENABLE2) = BCM2835_BIT(17);
> +  }
> +  /* GPIO 1 */
> +  else if ( vector == BCM2835_IRQ_ID_GPIO_1 )
> +  {
> +      BCM2835_REG(BCM2835_IRQ_ENABLE2) = BCM2835_BIT(18);
> +  }
> +  /* GPIO 2 */
> +  else if ( vector == BCM2835_IRQ_ID_GPIO_2 )
> +  {
> +      BCM2835_REG(BCM2835_IRQ_ENABLE2) = BCM2835_BIT(19);
> +  }
> +  /* GPIO 3 */
> +  else if ( vector == BCM2835_IRQ_ID_GPIO_3 )
> +  {
> +      BCM2835_REG(BCM2835_IRQ_ENABLE2) = BCM2835_BIT(20);
> +  }
> +  /* I2C */
> +  else if ( vector == BCM2835_IRQ_ID_I2C )
> +  {
> +      BCM2835_REG(BCM2835_IRQ_ENABLE2) = BCM2835_BIT(21);
> +  }
> +  /* SPI */
> +  else if ( vector == BCM2835_IRQ_ID_SPI )
> +  {
> +      BCM2835_REG(BCM2835_IRQ_ENABLE2) = BCM2835_BIT(22);
> +  }
> +
>    rtems_interrupt_enable(level);
>
>    return RTEMS_SUCCESSFUL;
> @@ -106,12 +163,42 @@ rtems_status_code bsp_interrupt_vector_disable(rtems_vector_number vector)
>    {
>        BCM2835_REG(BCM2835_IRQ_DISABLE2) = BCM2835_BIT(25);
>    }
> +  /* GPIO 0 */
> +  else if ( vector == BCM2835_IRQ_ID_GPIO_0 )
> +  {
> +      BCM2835_REG(BCM2835_IRQ_DISABLE2) = BCM2835_BIT(17);
> +  }
> +  /* GPIO 1 */
> +  else if ( vector == BCM2835_IRQ_ID_GPIO_1 )
> +  {
> +      BCM2835_REG(BCM2835_IRQ_DISABLE2) = BCM2835_BIT(18);
> +  }
> +  /* GPIO 2 */
> +  else if ( vector == BCM2835_IRQ_ID_GPIO_2 )
> +  {
> +      BCM2835_REG(BCM2835_IRQ_DISABLE2) = BCM2835_BIT(19);
> +  }
> +  /* GPIO 3 */
> +  else if ( vector == BCM2835_IRQ_ID_GPIO_3 )
> +  {
> +      BCM2835_REG(BCM2835_IRQ_DISABLE2) = BCM2835_BIT(20);
> +  }
> +  /* I2C */
> +  else if ( vector == BCM2835_IRQ_ID_I2C )
> +  {
> +      BCM2835_REG(BCM2835_IRQ_DISABLE2) = BCM2835_BIT(21);
> +  }
> +  /* SPI */
> +  else if ( vector == BCM2835_IRQ_ID_SPI )
> +  {
> +      BCM2835_REG(BCM2835_IRQ_DISABLE2) = BCM2835_BIT(22);
> +  }
> +
>    rtems_interrupt_enable(level);
>
>    return RTEMS_SUCCESSFUL;
>  }
>
> -
>  void bsp_interrupt_handler_default(rtems_vector_number vector)
>  {
>      printk("spurious interrupt: %u\n", vector);
> diff --git a/c/src/lib/libbsp/arm/raspberrypi/preinstall.am b/c/src/lib/libbsp/arm/raspberrypi/preinstall.am
> index 70259e2..122bc00 100644
> --- a/c/src/lib/libbsp/arm/raspberrypi/preinstall.am
> +++ b/c/src/lib/libbsp/arm/raspberrypi/preinstall.am
> @@ -130,6 +130,10 @@ $(PROJECT_INCLUDE)/bsp/raspberrypi.h: include/raspberrypi.h $(PROJECT_INCLUDE)/b
>         $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/raspberrypi.h
>  PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/raspberrypi.h
>
> +$(PROJECT_INCLUDE)/bsp/rpi-gpio.h: include/rpi-gpio.h $(PROJECT_INCLUDE)/bsp/$(dirstamp)
> +       $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/rpi-gpio.h
> +PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/rpi-gpio.h
> +
>  $(PROJECT_INCLUDE)/libcpu/cache_.h: ../../../libcpu/arm/shared/include/cache_.h $(PROJECT_INCLUDE)/libcpu/$(dirstamp)
>         $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/libcpu/cache_.h
>  PREINSTALL_FILES += $(PROJECT_INCLUDE)/libcpu/cache_.h
> --
> 2.0.5
>
> _______________________________________________
> devel mailing list
> devel at rtems.org
> http://lists.rtems.org/mailman/listinfo/devel



More information about the devel mailing list