[rtems commit] Raspberry Pi implementation for the RTEMS GPIO API.

Gedare Bloom gedare at rtems.org
Thu Aug 6 14:54:08 UTC 2015


Module:    rtems
Branch:    master
Commit:    61e7c698a44137afbc1447ed328b14a0d9e55016
Changeset: http://git.rtems.org/rtems/commit/?id=61e7c698a44137afbc1447ed328b14a0d9e55016

Author:    Andre Marques <andre.lousa.marques at gmail.com>
Date:      Mon Jul 27 17:01:44 2015 +0100

Raspberry Pi implementation for the RTEMS GPIO API.

Added support for the new RTEMS GPIO API functions.

Test cases can be found in https://github.com/asuol/RTEMS_rpi_testing/tree/master/GPIO

---

 c/src/lib/libbsp/arm/raspberrypi/Makefile.am       |   5 +
 .../raspberrypi/gpio/gpio-interfaces-pi1-rev2.c    | 136 +++++++++
 c/src/lib/libbsp/arm/raspberrypi/gpio/rpi-gpio.c   | 329 +++++++++++++++++++++
 c/src/lib/libbsp/arm/raspberrypi/include/bsp.h     |   4 +
 .../libbsp/arm/raspberrypi/include/raspberrypi.h   |  79 ++++-
 .../lib/libbsp/arm/raspberrypi/include/rpi-gpio.h  |  69 +++++
 c/src/lib/libbsp/arm/raspberrypi/irq/irq.c         | 105 ++++++-
 c/src/lib/libbsp/arm/raspberrypi/preinstall.am     |   4 +
 8 files changed, 714 insertions(+), 17 deletions(-)

diff --git a/c/src/lib/libbsp/arm/raspberrypi/Makefile.am b/c/src/lib/libbsp/arm/raspberrypi/Makefile.am
index c6133df..03be711 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
@@ -86,6 +87,7 @@ libbsp_a_SOURCES += ../../shared/cpucounterdiff.c
 libbsp_a_SOURCES += ../../shared/gnatinstallhandler.c
 libbsp_a_SOURCES += ../../shared/sbrk.c
 libbsp_a_SOURCES += ../../shared/src/stackalloc.c
+libbsp_a_SOURCES += ../../shared/gpio.c
 libbsp_a_SOURCES += ../shared/startup/bsp-start-memcpy.S
 libbsp_a_SOURCES += ../shared/arm-cp15-set-ttb-entries.c
 
@@ -117,6 +119,9 @@ 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..a958e0d
--- /dev/null
+++ b/c/src/lib/libbsp/arm/raspberrypi/gpio/gpio-interfaces-pi1-rev2.c
@@ -0,0 +1,136 @@
+/**
+ * @file gpio-interfaces-pi1-rev2.c
+ *
+ * @ingroup raspberrypi_gpio
+ *
+ * @brief Raspberry PI 1 rev2 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.
+ */
+
+#define JTAG_PIN_COUNT 5
+#define SPI_PIN_COUNT 5
+#define I2C_PIN_COUNT 2
+
+const rtems_gpio_pin_conf jtag_config[JTAG_PIN_COUNT] = {
+  { /*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]
+  },
+  { /* 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]
+  },
+  { /* 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]
+  },
+  { /* 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]
+  },
+  { /* 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]
+  }
+};
+
+const rtems_gpio_pin_conf spi_config[SPI_PIN_COUNT] = {
+  { /* 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]
+  },
+  { /* 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]
+  },
+  { /* 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]
+  },
+  { /* 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]
+  },
+  { /* 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]
+  }
+};
+
+const rtems_gpio_pin_conf i2c_config[I2C_PIN_COUNT] = {
+  { /* 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]
+  },
+  { /* 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..bd37e67
--- /dev/null
+++ b/c/src/lib/libbsp/arm/raspberrypi/gpio/rpi-gpio.c
@@ -0,0 +1,329 @@
+/**
+ * @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 Revision 2 gpio interface definitions. */
+#include "gpio-interfaces-pi1-rev2.c"
+
+/* Waits a number of CPU cycles. */
+static void arm_delay(uint8_t cycles)
+{
+  uint8_t 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);
+
+  if ( type == RPI_DIGITAL_IN ) {
+    *(pin_addr) &= ~SELECT_PIN_FUNCTION(RPI_DIGITAL_IN, pin);
+  }
+  else {
+    *(pin_addr) |= SELECT_PIN_FUNCTION(type, pin);
+  }
+
+  return RTEMS_SUCCESSFUL;
+}
+
+rtems_status_code rtems_gpio_bsp_multi_set(uint32_t bank, uint32_t bitmask)
+{
+  BCM2835_REG(BCM2835_GPIO_GPSET0) = bitmask;
+
+  return RTEMS_SUCCESSFUL;
+}
+
+rtems_status_code rtems_gpio_bsp_multi_clear(uint32_t bank, uint32_t bitmask)
+{
+  BCM2835_REG(BCM2835_GPIO_GPCLR0) = bitmask;
+
+  return RTEMS_SUCCESSFUL;
+}
+
+uint32_t rtems_gpio_bsp_multi_read(uint32_t bank, uint32_t bitmask)
+{
+  return (BCM2835_REG(BCM2835_GPIO_GPLEV0) & bitmask);
+}
+
+rtems_status_code rtems_gpio_bsp_set(uint32_t bank, uint32_t pin)
+{
+  BCM2835_REG(BCM2835_GPIO_GPSET0) = (1 << pin);
+
+  return RTEMS_SUCCESSFUL;
+}
+
+rtems_status_code rtems_gpio_bsp_clear(uint32_t bank, uint32_t pin)
+{
+  BCM2835_REG(BCM2835_GPIO_GPCLR0) = (1 << pin);
+
+  return RTEMS_SUCCESSFUL;
+}
+
+uint8_t rtems_gpio_bsp_get_value(uint32_t bank, uint32_t pin)
+{
+  return (BCM2835_REG(BCM2835_GPIO_GPLEV0) & (1 << pin));
+}
+
+rtems_status_code rtems_gpio_bsp_select_input(
+  uint32_t bank,
+  uint32_t pin,
+  void *bsp_specific
+) {
+  return rpi_select_pin_function(bank, pin, RPI_DIGITAL_IN);
+}
+
+rtems_status_code rtems_gpio_bsp_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_gpio_bsp_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_gpio_bsp_get_vector(uint32_t bank)
+{
+  return BCM2835_IRQ_ID_GPIO_0;
+}
+
+uint32_t rtems_gpio_bsp_interrupt_line(rtems_vector_number vector)
+{
+  uint32_t event_status;
+
+  /* Retrieve the interrupt event status. */
+  event_status = BCM2835_REG(BCM2835_GPIO_GPEDS0);
+
+  /* Clear the interrupt line. */
+  BCM2835_REG(BCM2835_GPIO_GPEDS0) = event_status;
+
+  return 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 interrupt
+) {
+  switch ( 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)
+{
+  return rtems_gpio_multi_select(jtag_config, JTAG_PIN_COUNT);
+}
+
+rtems_status_code rpi_gpio_select_spi(void)
+{
+  return rtems_gpio_multi_select(spi_config, SPI_PIN_COUNT);
+}
+
+rtems_status_code rpi_gpio_select_i2c(void)
+{
+  return rtems_gpio_multi_select(i2c_config, I2C_PIN_COUNT);
+}
+
+rtems_status_code rtems_gpio_bsp_multi_select(
+  rtems_gpio_multiple_pin_select *pins,
+  uint32_t pin_count,
+  uint32_t select_bank
+) {
+  uint32_t register_address;
+  uint32_t select_register;
+  uint8_t i;
+
+  register_address = BCM2835_GPIO_REGS_BASE + (select_bank * 0x04);
+
+  select_register = BCM2835_REG(register_address);
+
+  for ( i = 0; i < pin_count; ++i ) {
+    if ( pins[i].function == DIGITAL_INPUT ) {
+      select_register &=
+        ~SELECT_PIN_FUNCTION(RPI_DIGITAL_IN, pins[i].pin_number);
+    }
+    else if ( pins[i].function == DIGITAL_OUTPUT ) {
+      select_register |=
+        SELECT_PIN_FUNCTION(RPI_DIGITAL_OUT, pins[i].pin_number);
+    }
+    else { /* BSP_SPECIFIC function. */
+      select_register |=
+        SELECT_PIN_FUNCTION(pins[i].io_function, pins[i].pin_number);
+    }
+  }
+
+  BCM2835_REG(register_address) = select_register;
+
+  return RTEMS_SUCCESSFUL;
+}
+
+rtems_status_code rtems_gpio_bsp_specific_group_operation(
+  uint32_t bank,
+  uint32_t *pins,
+  uint32_t pin_count,
+  void *arg
+) {
+  return RTEMS_NOT_DEFINED;
+}
diff --git a/c/src/lib/libbsp/arm/raspberrypi/include/bsp.h b/c/src/lib/libbsp/arm/raspberrypi/include/bsp.h
index c05a410..5379b13 100644
--- a/c/src/lib/libbsp/arm/raspberrypi/include/bsp.h
+++ b/c/src/lib/libbsp/arm/raspberrypi/include/bsp.h
@@ -33,6 +33,10 @@ extern "C" {
 
 #define BSP_FEATURE_IRQ_EXTENSION
 
+#define BSP_GPIO_PIN_COUNT 32
+#define BSP_GPIO_PINS_PER_BANK 32
+#define BSP_GPIO_PINS_PER_SELECT_BANK 10
+
 #ifdef __cplusplus
 }
 #endif /* __cplusplus */
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..7f4d802
--- /dev/null
+++ b/c/src/lib/libbsp/arm/raspberrypi/include/rpi-gpio.h
@@ -0,0 +1,69 @@
+/**
+ * @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  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_pin_group().
+ */
+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_pin_group().
+ */
+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_pin_group().
+ */
+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



More information about the vc mailing list