From 61e7c698a44137afbc1447ed328b14a0d9e55016 Mon Sep 17 00:00:00 2001 From: Andre Marques Date: Mon, 27 Jul 2015 17:01:44 +0100 Subject: 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(-) 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 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 + * + * 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 + * + * 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 +#include +#include +#include + +#include + +/* 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 + * 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 + * + * 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 + +#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 + * * 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 -- cgit v1.2.3