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

Andre Marques andre.lousa.marques at gmail.com
Mon Jun 22 12:01:02 UTC 2015


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]
+};
+
+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




More information about the devel mailing list