summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndre Marques <andre.lousa.marques@gmail.com>2015-07-27 17:01:44 +0100
committerGedare Bloom <gedare@rtems.org>2015-08-06 10:53:46 -0400
commit61e7c698a44137afbc1447ed328b14a0d9e55016 (patch)
treed253c7a028c02c17089283eab1078b8533fde4b8
parentRTEMS GPIO API definition and implementation. (diff)
downloadrtems-61e7c698a44137afbc1447ed328b14a0d9e55016.tar.bz2
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
-rw-r--r--c/src/lib/libbsp/arm/raspberrypi/Makefile.am5
-rw-r--r--c/src/lib/libbsp/arm/raspberrypi/gpio/gpio-interfaces-pi1-rev2.c136
-rw-r--r--c/src/lib/libbsp/arm/raspberrypi/gpio/rpi-gpio.c329
-rw-r--r--c/src/lib/libbsp/arm/raspberrypi/include/bsp.h4
-rw-r--r--c/src/lib/libbsp/arm/raspberrypi/include/raspberrypi.h79
-rw-r--r--c/src/lib/libbsp/arm/raspberrypi/include/rpi-gpio.h69
-rw-r--r--c/src/lib/libbsp/arm/raspberrypi/irq/irq.c105
-rw-r--r--c/src/lib/libbsp/arm/raspberrypi/preinstall.am4
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 c6133df707..03be7119c0 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 0000000000..a958e0dc8e
--- /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 0000000000..bd37e67765
--- /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 c05a4102a6..5379b13511 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 c33e22ab8e..ddcd4ffde9 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 0000000000..7f4d802b0f
--- /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 4132ef9693..0867b6b2f1 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 70259e2b9a..122bc003af 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