[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