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 _______________________________________________ devel mailing list devel@rtems.org http://lists.rtems.org/mailman/listinfo/devel