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
This commit is contained in:
Andre Marques
2015-07-27 17:01:44 +01:00
committed by Gedare Bloom
parent 87f8b01f58
commit 61e7c698a4
8 changed files with 714 additions and 17 deletions

View File

@@ -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

View File

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

View File

@@ -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;
}

View File

@@ -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 */

View File

@@ -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 */

View File

@@ -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 */

View File

@@ -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);

View File

@@ -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