On November 4, 2014 5:27:51 PM CST, Andre Marques <andre.lousa.marq...@gmail.com> wrote: >On 11/04/14 23:16, Joel Sherrill wrote: >> On 11/4/2014 5:01 PM, Andre Marques wrote: >>> Hi gedare, >>> >>> will send a new version of this patch in the next few days. >>> >>> Replies to your comments below. >>> >> I am too overwhelmed to remember but are there example >> and/or test programs for the IO pins? > >Yes I have put the test cases and the device drivers I used during >development in github: > >https://github.com/asuol/RTEMS_rpi_testing
Gedare.. Any suggestions for a home on git.rtems.org? The best idea I have is a subdirectory in examples >> >> FWIW I have a Pinewood Derby application that uses 3 discrete >> inputs to time two wooden cars on a race track. I need to move >> it to my personal git repo. It was developed to use a parallel >> port on a PC as input but moving to a Raspberry Pi for it would >> be cool! >> >> --joel >>> --André Marques. >>> >>> On 10/31/14 14:25, Gedare Bloom wrote: >>>> Thanks, I'll leave detailed comments to the experts but noticed a >few things. >>>> >>>> On Fri, Oct 31, 2014 at 7:56 AM, Andre Marques >>>> <andre.lousa.marq...@gmail.com> wrote: >>>>> Aditional documentation can be found in the RTEMS wiki >>>>> >>>>> http://www.rtems.org/wiki/index.php/Raspberry_Pi_BSP_Peripherals >>>>> >>>>> and on my GSOC development blog >>>>> >>>>> http://asuolgsoc2014.wordpress.com/2014/08/18/testing-the-project/ >>>>> >>>>> Device drivers and test cases used to test this work were moved to >a github repository >>>>> >>>>> https://github.com/asuol/RTEMS_rpi_testing >>>>> --- >>>>> c/src/lib/libbsp/arm/raspberrypi/Makefile.am | 11 +- >>>>> c/src/lib/libbsp/arm/raspberrypi/configure.ac | 12 + >>>>> c/src/lib/libbsp/arm/raspberrypi/gpio/gpio.c | 745 >+++++++++++++++++++++ >>>>> c/src/lib/libbsp/arm/raspberrypi/i2c/i2c.c | 427 >++++++++++++ >>>>> c/src/lib/libbsp/arm/raspberrypi/i2c/i2c_init.c | 78 +++ >>>>> c/src/lib/libbsp/arm/raspberrypi/i2c/spi.c | 564 >++++++++++++++++ >>>>> c/src/lib/libbsp/arm/raspberrypi/i2c/spi_init.c | 83 +++ >>>>> c/src/lib/libbsp/arm/raspberrypi/include/gpio.h | 198 ++++++ >>>>> c/src/lib/libbsp/arm/raspberrypi/include/i2c.h | 166 +++++ >>>>> c/src/lib/libbsp/arm/raspberrypi/include/irq.h | 6 +- >>>>> .../libbsp/arm/raspberrypi/include/raspberrypi.h | 79 ++- >>>>> c/src/lib/libbsp/arm/raspberrypi/irq/irq.c | 103 ++- >>>>> c/src/lib/libbsp/arm/raspberrypi/preinstall.am | 8 + >>>>> .../lib/libbsp/arm/raspberrypi/startup/bspstart.c | 17 +- >>>>> 14 files changed, 2475 insertions(+), 22 deletions(-) >>>>> create mode 100644 c/src/lib/libbsp/arm/raspberrypi/gpio/gpio.c >>>>> create mode 100644 c/src/lib/libbsp/arm/raspberrypi/i2c/i2c.c >>>>> create mode 100644 >c/src/lib/libbsp/arm/raspberrypi/i2c/i2c_init.c >>>>> create mode 100644 c/src/lib/libbsp/arm/raspberrypi/i2c/spi.c >>>>> create mode 100644 >c/src/lib/libbsp/arm/raspberrypi/i2c/spi_init.c >>>>> create mode 100644 >c/src/lib/libbsp/arm/raspberrypi/include/gpio.h >>>>> create mode 100644 >c/src/lib/libbsp/arm/raspberrypi/include/i2c.h >>>>> >>>>> diff --git a/c/src/lib/libbsp/arm/raspberrypi/Makefile.am >b/c/src/lib/libbsp/arm/raspberrypi/Makefile.am >>>>> index 839c8de..81dc196 100644 >>>>> --- a/c/src/lib/libbsp/arm/raspberrypi/Makefile.am >>>>> +++ b/c/src/lib/libbsp/arm/raspberrypi/Makefile.am >>>>> @@ -44,6 +44,8 @@ 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/gpio.h >>>>> +include_bsp_HEADERS += include/i2c.h >>>>> >>>>> include_libcpu_HEADERS = >../../../libcpu/arm/shared/include/cache_.h \ >>>>> ../../../libcpu/arm/shared/include/arm-cp15.h >>>>> @@ -79,7 +81,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 >>>>> @@ -119,11 +120,19 @@ libbsp_a_SOURCES += clock/clockdrv.c >../../../shared/clockdrv_shell.h >>>>> # Timer >>>>> libbsp_a_SOURCES += misc/timer.c >>>>> >>>>> +# GPIO >>>>> + >>>>> +libbsp_a_SOURCES += gpio/gpio.c >>>>> + >>>>> # RTC >>>>> >>>>> # SSP >>>>> >>>>> # I2C >>>>> +libbsp_a_SOURCES += i2c/i2c.c >>>>> +libbsp_a_SOURCES += i2c/i2c_init.c >>>>> +libbsp_a_SOURCES += i2c/spi.c >>>>> +libbsp_a_SOURCES += i2c/spi_init.c >>>>> >>>>> # Cache >>>>> libbsp_a_SOURCES += ../../../libcpu/shared/src/cache_manager.c >>>>> diff --git a/c/src/lib/libbsp/arm/raspberrypi/configure.ac >b/c/src/lib/libbsp/arm/raspberrypi/configure.ac >>>>> index 9bd6883..ef83c9d 100644 >>>>> --- a/c/src/lib/libbsp/arm/raspberrypi/configure.ac >>>>> +++ b/c/src/lib/libbsp/arm/raspberrypi/configure.ac >>>>> @@ -24,6 +24,18 @@ AM_CONDITIONAL(HAS_NETWORKING,test >"$HAS_NETWORKING" = "yes") >>>>> RTEMS_BSPOPTS_SET([BSP_START_RESET_VECTOR],[*],[]) >>>>> RTEMS_BSPOPTS_HELP([BSP_START_RESET_VECTOR],[reset vector >address for BSP start]) >>>>> >>>>> +RTEMS_BSPOPTS_SET([I2C_IO_MODE],[*],[1]) >>>>> +RTEMS_BSPOPTS_HELP([I2C_IO_MODE],[Define to 1 to use >interrupt-driven I/O with the Raspberry Pi I2C bus. If defined to other >value the access will be polled-driven.]) >>>>> + >>>>> +RTEMS_BSPOPTS_SET([SPI_IO_MODE],[*],[1]) >>>>> +RTEMS_BSPOPTS_HELP([SPI_IO_MODE],[Define to 1 to use >interrupt-driven I/O with the Raspberry Pi SPI bus. If defined to other >value the access will be polled-driven.]) >>>>> + >>>>> +RTEMS_BSPOPTS_SET([BSP_ENABLE_SPI],[*],[0]) >>>>> +RTEMS_BSPOPTS_HELP([BSP_ENABLE_SPI],[Define to 1 to use the SPI >bus. This will register the bus in /dev/spi and also any device driver >mentioned in i2c/spi_init.c .]) >>>>> + >>>>> +RTEMS_BSPOPTS_SET([BSP_ENABLE_I2C],[*],[1]) >>>>> +RTEMS_BSPOPTS_HELP([BSP_ENABLE_I2C],[Define to 1 to use the I2C >bus. This will register the bus in /dev/i2c and also any device driver >mentioned in i2c/i2c_init.c .]) >>>>> + >>>>> RTEMS_BSP_CLEANUP_OPTIONS(0, 0) >>>>> RTEMS_BSP_LINKCMDS >>>>> >>>>> diff --git a/c/src/lib/libbsp/arm/raspberrypi/gpio/gpio.c >b/c/src/lib/libbsp/arm/raspberrypi/gpio/gpio.c >>>>> new file mode 100644 >>>>> index 0000000..d245339 >>>>> --- /dev/null >>>>> +++ b/c/src/lib/libbsp/arm/raspberrypi/gpio/gpio.c >>>>> @@ -0,0 +1,745 @@ >>>>> +/** >>>>> + * @file gpio.c >>>>> + * >>>>> + * @ingroup raspberrypi_gpio >>>>> + * >>>>> + * @brief Support for the Raspberry PI GPIO. >>>>> + * >>>>> + */ >>>>> + >>>>> +/* >>>>> + * Copyright (c) 2014 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.h> >>>>> +#include <bsp/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)) >>>>> + >>>>> +static bool is_initialized = false; >>>>> + >>>>> +rpi_gpio_pin *gpio_pin; >>>>> + >>>>> +/** >>>>> + * @brief Waits a number of CPU cycles. >>>>> + * >>>>> + * @param[in] cycles The number of CPU cycles to wait. >>>>> + * >>>>> + */ >>>>> +static void arm_delay (int cycles) >>>>> +{ >>>>> + int i; >>>>> + >>>>> + for (i = 0; i < cycles; i++) >>>>> + asm volatile ("nop"); >>>> We prefer to see nested scopes within a function (even with just >one >>>> line) have explicit braces { }. >>> Will review the code against the coding conventions. On a side note >the >>> explicit braces convention does not seem to be in the wiki page (I >am >>> looking it through the google cache since the wiki is down). >>> >>>>> +} >>>>> + >>>>> +/** >>>>> + * @brief Initializes the GPIO API. >>>>> + * Allocates space to the gpio_pin array and sets every >pin as NOT_USED. >>>>> + * If the API has already been initialized silently exits. >>>>> + */ >>>>> +void gpio_initialize(void) >>>>> +{ >>>>> + int i; >>>>> + >>>>> + if ( is_initialized ) >>>>> + return; >>>>> + >>>>> + is_initialized = true; >>>>> + >>>>> + gpio_pin = (rpi_gpio_pin *) malloc(GPIO_PIN_COUNT * >sizeof(rpi_gpio_pin)); >>>>> + >>>>> + for ( i = 0; i < GPIO_PIN_COUNT; i++ ) { >>>>> + gpio_pin[i].pin_type = NOT_USED; >>>>> + gpio_pin[i].enabled_interrupt = NONE; >>>>> + >>>>> + gpio_pin[i].h_args.debouncing_tick_count = 0; >>>>> + } >>>> This entire function can be eliminated, dynamic allocation and >>>> initialization are unnecessary since you know the size and initial >>>> values to use. >>>> >>> The allocation can indeed become static. As for the initialization >of >>> the array this function is to be called by any application that >intends >>> to use digital I/O capabilities. The alternative is to have this >>> initialization on startup/bspstart.c (as I2C/SPI which are activated >>> through configure.ac). >>> >>> When changing the alocation from dynamic to static I found that some >>> pins were not getting the pull-up resistors to work, which I traced >to >>> the rpi_gpio_input_mode enumerator in include/gpio.h (for some >reason if >>> PULL_UP is 0 the resistor is not activated when the gpio_pin array >is >>> staticly-allocated): >>> >>> typedef enum >>> { >>> PULL_UP, >>> PULL_DOWN, >>> NO_PULL_RESISTOR >>> } rpi_gpio_input_mode; >>> >>> Will initialize every first value on the enumerators there to 1. >>> >>>>> +} >>>>> + >>>>> +/** >>>>> + * @brief Gives an output GPIO pin the logical value of 1. >>>>> + * >>>>> + * @param[in] pin The Raspberry Pi GPIO pin label number (not is >position >>>>> + * on the header). >>>>> + * >>>>> + * @retval 0 Pin was set successfully. >>>>> + * @retval -1 The received pin is not configured as an digital >output. >>>>> + */ >>>>> +int gpio_set(int pin) >>>>> +{ >>>> I'd add some asserts here and in other places that use 'pin', >like.. >>>> assert(pin > 0); >>>> assert(pin < =PIN_COUNT); >>>> Or whatever is sensible. >>> Will do. >>> >>>>> + if (gpio_pin[pin-1].pin_type != DIGITAL_OUTPUT) >>>>> + return -1; >>>>> + >>>>> + BCM2835_REG(BCM2835_GPIO_GPSET0) = (1 << pin); >>>>> + >>>>> + return 0; >>>>> +} >>>>> + >>>>> +/** >>>>> + * @brief Gives an output GPIO pin the logical value of 0. >>>>> + * >>>>> + * @param[in] pin The Raspberry Pi GPIO pin label number (not is >position >>>>> + * on the header). >>>>> + * >>>>> + * @retval 0 Pin was cleared successfully. >>>>> + * @retval -1 The received pin is not configured as an digital >output. >>>>> + */ >>>>> +int gpio_clear(int pin) >>>>> +{ >>>>> + if (gpio_pin[pin-1].pin_type != DIGITAL_OUTPUT) >>>>> + return -1; >>>>> + >>>>> + BCM2835_REG(BCM2835_GPIO_GPCLR0) = (1 << pin); >>>>> + >>>>> + return 0; >>>>> +} >>>>> + >>>>> +/** >>>>> + * @brief Gets the value (level) of a GPIO input pin. >>>>> + * >>>>> + * @param[in] pin The Raspberry Pi GPIO pin label number (not is >position >>>>> + * on the header). >>>>> + * >>>>> + * @retval The function returns 0 or 1 depending on the pin >current >>>>> + * logical value. >>>>> + */ >>>>> +int gpio_get_val(int pin) >>>> avoid abbreviations >>> This one should become gpio_get_value or gpio_read. >>> >>>>> +{ >>>>> + return BCM2835_REG(BCM2835_GPIO_GPLEV0) &= (1 << (pin)); >>>> Do you intend for the assignment as a side-effect? If so, it should >be >>>> documented. >>> Actually the assignment is not needed. There is also too many >parenthesis. >>> >>>>> +} >>>>> + >>>>> +/** >>>>> + * @brief Configures a GPIO pin to perform a certain function. >>>>> + * >>>>> + * @param[in] pin The Raspberry Pi GPIO pin label number (not is >position >>>>> + * on the header). >>>>> + * @param[in] type The new function of the pin. >>>>> + * >>>>> + * @retval 0 Pin was configured successfully. >>>>> + * @retval -1 The received pin is already being used, or unknown >function. >>>>> + */ >>>>> +int gpio_select_pin(int pin, rpi_pin type) >>>>> +{ >>>>> + /* Calculate the pin function select register address. */ >>>>> + volatile unsigned int *pin_addr = (unsigned int >*)BCM2835_GPIO_REGS_BASE + (pin / 10); >>>>> + >>>>> + /* If the pin is already being used returns with an error. */ >>>>> + if ( gpio_pin[pin-1].pin_type != NOT_USED ) >>>>> + return -1; >>>>> + >>>> You could simplify the following by defining the enum rpi_pin >like... >>>> DIGITAL_OUTPUT = 1, >>>> ALT_FUNC_5, >>>> ALT_FUNC_4, >>>> ALT_FUNC_0, >>>> ... >>>> >>>> Then use >>>> *(pin_addr) |= SELECT_PIN_FUNCTION(type, pin); >>>> >>>> >>>> Also, is ALT_FUNC_3 identical to DIGITAL_INPUT? >>> DIGITAL_INPUT uses the &~ operators instead of |, but the switch may >be >>> simplified through the enumerator. >>> >>>>> + /* Sets pin function select bits as zero (DIGITAL_INPUT).*/ >>>>> + *(pin_addr) &= ~SELECT_PIN_FUNCTION(7, pin); >>>>> + >>>>> + switch ( type ) { >>>>> + case DIGITAL_INPUT: >>>>> + >>>>> + /* Digital input is set by default before this switch. */ >>>>> + >>>>> + break; >>>>> + >>>>> + case DIGITAL_OUTPUT: >>>>> + >>>>> + *(pin_addr) |= SELECT_PIN_FUNCTION(1, pin); >>>>> + >>>>> + break; >>>>> + >>>>> + case ALT_FUNC_0: >>>>> + >>>>> + *(pin_addr) |= SELECT_PIN_FUNCTION(4, pin); >>>>> + >>>>> + break; >>>>> + >>>>> + case ALT_FUNC_1: >>>>> + >>>>> + *(pin_addr) |= SELECT_PIN_FUNCTION(5, pin); >>>>> + >>>>> + break; >>>>> + >>>>> + case ALT_FUNC_2: >>>>> + >>>>> + *(pin_addr) |= SELECT_PIN_FUNCTION(6, pin); >>>>> + >>>>> + break; >>>>> + >>>>> + case ALT_FUNC_3: >>>>> + >>>>> + *(pin_addr) |= SELECT_PIN_FUNCTION(7, pin); >>>>> + >>>>> + break; >>>>> + >>>>> + case ALT_FUNC_4: >>>>> + >>>>> + *(pin_addr) |= SELECT_PIN_FUNCTION(3, pin); >>>>> + >>>>> + break; >>>>> + >>>>> + case ALT_FUNC_5: >>>>> + >>>>> + *(pin_addr) |= SELECT_PIN_FUNCTION(2, pin); >>>>> + >>>>> + break; >>>>> + >>>>> + default: >>>>> + return -1; >>>>> + } >>>>> + >>>>> + /* If the alternate function was successfuly assigned to the >pin, >>>>> + * record that information on the gpio_pin structure. */ >>>>> + gpio_pin[pin-1].pin_type = type; >>>>> + >>>>> + return 0; >>>>> +} >>>>> + >>>>> +/** >>>>> + * @brief Configures the pull resistor setting of an array of >GPIO pins. >>>>> + * >>>>> + * @param[in] pins Array of Raspberry Pi GPIO pin label numbers >(not their position >>>>> + * on the header). >>>>> + * @param[in] pin_count Number of pins on the @var pins array. >>>>> + * @param[in] mode The pull resistor mode. >>>>> + * >>>>> + * @retval 0 Pull resistor successfully configured. >>>>> + * @retval -1 Unknown pull resistor mode. >>>>> + */ >>>>> +static int >>>>> +set_input_mode(int *pins, int pin_count, int pin_mask, >rpi_gpio_input_mode mode) >>>>> +{ >>>>> + int i; >>>>> + >>>>> + /* 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 -1; >>>>> + } >>>>> + >>>>> + /* Wait 150 cyles, as per BCM2835 documentation. */ >>>>> + arm_delay(150); >>>>> + >>>>> + /* Setup clock for the control signal. */ >>>>> + BCM2835_REG(BCM2835_GPIO_GPPUDCLK0) = pin_mask; >>>>> + >>>>> + arm_delay(150); >>>>> + >>>>> + /* Remove the control signal. */ >>>>> + BCM2835_REG(BCM2835_GPIO_GPPUD) = 0; >>>>> + >>>>> + /* Remove the clock. */ >>>>> + BCM2835_REG(BCM2835_GPIO_GPPUDCLK0) = 0; >>>>> + >>>>> + /* If the operation was successful, record that information >>>>> + * on the gpio_pin structure so it can be recalled later. */ >>>>> + for ( i = 0; i < pin_count; i++ ) >>>>> + gpio_pin[pins[i]-1].input_mode = mode; >>>>> + >>>>> + return 0; >>>>> +} >>>>> + >>>>> +/** >>>>> + * @brief Configures a single GPIO pin pull resistor. >>>>> + * >>>>> + * @param[in] pin Raspberry Pi GPIO pin label number (not its >position >>>>> + * on the header). >>>>> + * @param[in] mode The pull resistor mode. >>>>> + * >>>>> + * @retval 0 Pull resistor successfully configured. >>>>> + * @retval -1 @see set_input_mode(). >>>>> + */ >>>>> +int gpio_input_mode(int pin, rpi_gpio_input_mode mode) >>>>> +{ >>>>> + int pin_mask = (1 << pin); >>>>> + int pins[1]; >>>>> + >>>>> + /* If the desired actuation mode is already set, silently >exits. */ >>>>> + if ( gpio_pin[pin-1].input_mode == mode ) >>>>> + return 0; >>>>> + >>>>> + pins[0] = pin; >>>>> + >>>>> + return set_input_mode(pins, 1, pin_mask, mode); >>>>> +} >>>>> + >>>>> +/** >>>>> + * @brief Sets the same pull-up/down resistors actuation mode to >multiple GPIO input pins. >>>>> + * There is a maximum number of 32 pins per call, which is >enough for >>>>> + * Raspberry Pi models A and B (17 GPIOs on P1 GPIO >header) >>>>> + * and also model B+ (28 GPIOs on J8 GPIO header). >>>>> + * >>>>> + * @param[in] pins Array of Raspberry Pi GPIO pin label numbers >(not their position >>>>> + * on the header). >>>>> + * @param[in] pin_count Number of pins on the @var pins array. >>>>> + * @param[in] mode The pull resistor mode. >>>>> + * >>>>> + * @retval 0 Pull resistor successfully configured. >>>>> + * @retval -1 Unknown pull resistor mode. >>>>> + */ >>>>> +int gpio_setup_input_mode(int *pins, int pin_count, >rpi_gpio_input_mode mode) >>>>> +{ >>>>> + uint32_t pin_mask = 0; >>>>> + int diff_mode_counter = 0; >>>>> + int i; >>>>> + >>>>> + if ( pin_count > 32 ) >>>> Use the max macro instead of literal 32 >>> Will create a macro for it. >>> >>>>> + return -1; >>>> Consider using more informative error codes. >>> Should I print something before the return? >>> >>>>> + >>>>> + /* Cycle through the given pins to check if this operation will >have an effect >>>>> + * on the resistor actuation mode of any one of the pins. >>>>> + * Every pin that currently uses a different pull resistor mode >sets a bit >>>>> + * in its corresponding place on a bitmask. If the mode for a >pin will not change >>>>> + * then the diff_mode_counter variable is increased. */ >>>>> + for ( i = 0; i < pin_count; i++ ) { >>>>> + if ( gpio_pin[pins[i] - 1].input_mode != mode ) >>>>> + pin_mask |= (1 << pins[i]); >>>>> + >>>>> + else >>>>> + diff_mode_counter++; >>>>> + } >>>>> + >>>>> + /* If no pin will have its resistor mode changed silently >exits, avoiding an >>>>> + * unnecessary access to the Rasberry Pi memory registers. */ >>>>> + if ( diff_mode_counter == 0 ) >>>>> + return 0; >>>>> + >>>>> + return set_input_mode(pins, pin_count, pin_mask, mode); >>>>> +} >>>>> + >>>>> +/** >>>>> + * @brief Disables a GPIO pin on the APiI, making it available to >be used >>>>> + * by anyone on the system. >>>>> + * >>>>> + * @param[in] dev_pin Raspberry Pi GPIO pin label number (not its >position >>>>> + * on the header). >>>>> + * >>>>> + * @retval 0 Pin successfully disabled on the API. >>>>> + * @retval -1 Could not disable an ative interrupt on this pin. >>>>> + */ >>>>> +int gpio_disable_pin(int dev_pin) >>>>> +{ >>>>> + rtems_status_code sc; >>>>> + rpi_gpio_pin *pin; >>>>> + >>>>> + pin = &gpio_pin[dev_pin-1]; >>>>> + >>>>> + pin->pin_type = NOT_USED; >>>>> + >>>>> + /* If the pin has an enabled interrupt then remove the handler. >*/ >>>>> + if ( pin->enabled_interrupt != NONE ) { >>>>> + sc = gpio_disable_interrupt(dev_pin); >>>>> + >>>>> + if ( sc != RTEMS_SUCCESSFUL ) >>>>> + return -1; >>>>> + } >>>>> + >>>>> + return sc; >>>>> +} >>>>> + >>>>> +/** >>>>> + * @brief Setups a JTAG interface using the P1 GPIO pin header >>>>> + * for the models A/B and J8 header on the B+. >>>>> + * The following pins should be unused before calling this >function: >>>>> + * GPIO 4, 22, 24, 25 and 27. >>>>> + * >>>>> + * @param[in] dev_pin Raspberry Pi GPIO pin label number (not its >position >>>>> + * on the header). >>>>> + * >>>>> + * @retval 0 JTAG interface successfully configured. >>>>> + * @retval -1 At least one of the required pins is currently >occupied. >>>>> + */ >>>>> +int gpio_select_jtag(void) >>>>> +{ >>>>> + /* Setup gpio 4 alt5 ARM_TDI. */ >>>>> + if ( gpio_select_pin(4, ALT_FUNC_5) < 0 ) >>>>> + return -1; >>>>> + >>>>> + /* Setup gpio 22 alt4 ARM_TRST. */ >>>>> + if ( gpio_select_pin(22, ALT_FUNC_4) < 0 ) >>>>> + return -1; >>>>> + >>>>> + /* Setup gpio 24 alt4 ARM_TDO. */ >>>>> + if ( gpio_select_pin(24, ALT_FUNC_4) < 0 ) >>>>> + return -1; >>>>> + >>>>> + /* Setup gpio 25 alt4 ARM_TCK. */ >>>>> + if ( gpio_select_pin(25, ALT_FUNC_4) < 0 ) >>>>> + return -1; >>>>> + >>>>> + /* Setup gpio 27 alt4 ARM_TMS. */ >>>>> + if ( gpio_select_pin(27, ALT_FUNC_4) < 0 ) >>>>> + return -1; >>>>> + >>>>> + return 0; >>>>> +} >>>>> + >>>>> +/** >>>>> + * @brief Setups a SPI interface using the P1 GPIO pin header >>>>> + * for the models A/B and J8 header on the B+. >>>>> + * The following pins should be unused before calling this >function: >>>>> + * GPIO 7, 8, 9, 10 and 11. >>>>> + * >>>>> + * @param[in] dev_pin Raspberry Pi GPIO pin label number (not its >position >>>>> + * on the header). >>>>> + * >>>>> + * @retval 0 SPI interface successfully configured. >>>>> + * @retval -1 At least one of the required pins is currently >occupied. >>>>> + */ >>>>> +int gpio_select_spi_p1(void) >>>>> +{ >>>>> + /* SPI master 0 MISO data line. */ >>>>> + if ( gpio_select_pin(9, ALT_FUNC_0) < 0 ) >>>>> + return -1; >>>>> + >>>>> + /* SPI master 0 MOSI data line. */ >>>>> + if ( gpio_select_pin(10, ALT_FUNC_0) < 0 ) >>>>> + return -1; >>>>> + >>>>> + /* SPI master 0 SCLK clock line. */ >>>>> + if ( gpio_select_pin(11, ALT_FUNC_0) < 0 ) >>>>> + return -1; >>>>> + >>>>> + /* SPI master 0 CE_0 chip enable line. */ >>>>> + if ( gpio_select_pin(8, ALT_FUNC_0) < 0 ) >>>>> + return -1; >>>>> + >>>>> + /* SPI master 0 CE_1 chip enable line. */ >>>>> + if ( gpio_select_pin(7, ALT_FUNC_0) < 0 ) >>>>> + return -1; >>>>> + >>>>> + return 0; >>>>> +} >>>>> + >>>>> +/** >>>>> + * @brief Setups a I2C interface using the P1 GPIO pin header >>>>> + * for the models A/B and J8 header on the B+. >>>>> + * The following pins should be unused before calling this >function: >>>>> + * GPIO 2 and 3. >>>>> + * >>>>> + * @param[in] dev_pin Raspberry Pi GPIO pin label number (not its >position >>>>> + * on the header). >>>>> + * >>>>> + * @retval 0 JTAG interface successfully configured. >>>>> + * @retval -1 At least one of the required pins is currently >occupied. >>>>> + */ >>>>> +int gpio_select_i2c_p1_rev2(void) >>>>> +{ >>>>> + int pins[] = {2,3}; >>>>> + >>>>> + /* I2C BSC1 SDA data line. */ >>>>> + if ( gpio_select_pin(2, ALT_FUNC_0) < 0 ) >>>>> + return -1; >>>>> + >>>>> + /* I2C BSC1 SCL clock line. */ >>>>> + if ( gpio_select_pin(3, ALT_FUNC_0) < 0 ) >>>>> + return -1; >>>>> + >>>> Does it make sense to have gpio_select_pins(int[], type[])? >>> It may make sense in some scenarios, but probably is easier to read >if >>> each call assigns a type to all pins on a given array instead of >having >>> to visually match each pin with a type. >>> >>>>> + /* Enable pins 2 and 3 pull-up resistors. */ >>>>> + if ( gpio_setup_input_mode(pins, 2, PULL_UP) < 0 ) >>>>> + return -1; >>>>> + >>>>> + return 0; >>>>> +} >>>>> + >>>>> +/** >>>>> _______________________________________________ devel mailing list devel@rtems.org http://lists.rtems.org/mailman/listinfo/devel