[PATCH 1/2] GPIO Driver

Ketul Shah ketulshah1993 at gmail.com
Wed Jul 1 08:39:23 UTC 2015


Hi Steve,

Yep I saw your code on user-ml. And yes It would be nice to see GPIO_IRQ to
be included in the patch.

And ya it would be great if you can help to modify the patch anyhow I will
also work on it (thanks for pulling our attention). And you can find the
sent patch working on my GitHub
<https://github.com/ketul93/rtems/tree/GPIO_API> repository.

Thanks.

Best Regards,
Ketul

On 1 July 2015 at 08:50, Steve B <sbattazzo at gmail.com> wrote:

> After this is sorted into the right place it would be great to see GPIO
> IRQs included. I got an IRQ working by just writing to the correct memory
> locations from application code (posted the source to users list last
> week), but I think Andre's API does have some hooks for that (seemed that
> way when I last looked). So it should not be too challenging to add that
> feature. If you don't have time to get to it then I will volunteer to do it
> once there is a patch that Gedare is happy with.
>
> Steve
>
>
> On Tue, Jun 30, 2015 at 9:53 AM, Gedare Bloom <gedare at gwu.edu> wrote:
>
>> I don't think we want the shared code in cpukit but rather in
>> libbsp/shared.. Also, I think Andre shall commit the shared code, so
>> perhaps you should focus on just getting a localized solution working
>> in the beagleboard BSP
>>
>> On Tue, Jun 30, 2015 at 5:46 AM, Ketul Shah <ketulshah1993 at gmail.com>
>> wrote:
>> > diff --git a/cpukit/include/rtems/gpio.h b/cpukit/include/rtems/gpio.h
>> > new file mode 100644
>> > index 0000000..3d68c39
>> > --- /dev/null
>> > +++ b/cpukit/include/rtems/gpio.h
>> > @@ -0,0 +1,64 @@
>> > +/**
>> > + * @file rtems/gpio.h
>> > + *
>> > + * @brief Global GPIO definitions.
>> > + *
>> > + * This include the generalized definitions for GPIO
>> > + */
>> > +
>> > +/**
>> > + * Copyright (c) 2015 Ketul Shah <ketulshah1993 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 _RTEMS_GPIO_H
>> > +#define _RTEMS_GPIO_H
>> > +
>> > +#ifdef __cplusplus
>> > +extern "C" {
>> > +#endif /* __cplusplus */
>> > +
>> > +/* Returned Error Codes by function */
>> > +#define GPIO_SUCCESSFUL        0 /* operation is OK */
>> > +#define GPIO_UNKNOWN_PIN       1 /* pin not known by bsp */
>> > +#define GPIO_UNCONFIGURED_PIN  2 /* pin unable to configure */
>> > +#define GPIO_MISCONFIGURED_PIN 3 /* pin configuration can't match
>> operation */
>> > +
>> > +/* Possible GPIO Pin States */
>> > +#define GPIO_PIN_STATE_UNCONFIGURED 0
>> > +#define GPIO_PIN_STATE_DIGITAL_OUT  1
>> > +#define GPIO_PIN_STATE_DIGITAL_IN   2
>> > +
>> > +/**
>> > + * @brief Structure contains all the required members for GPIO access.
>> > + */
>> > +typedef struct
>> > +{
>> > +  int   pin_number;/* The pin number. */
>> > +  void* platform;  /* Opaque hardware specific set up details. */
>> > +} gpio_pin_handle;
>> > +
>> > +/**
>> > + * @brief Initializes the GPIO API.
>> > + */
>> > +extern void rtems_gpio_initialize(void);
>> > +/**
>> > + * @brief Selects a GPIO pin for a digital output.
>> > + */
>> > +extern int rtems_gpio_configure_pin_digital_out(
>> > +       gpio_pin_handle *, unsigned int );
>> > +/**
>> > + * @brief Turns on the given pin.
>> > + */
>> > +extern int rtems_gpio_digital_set(gpio_pin_handle *);
>> > +/**
>> > + * @brief Turns off the given pin.
>> > + */
>> > +extern int rtems_gpio_digital_clear(gpio_pin_handle *);
>> > +/**
>> > + * @brief currently configured pin is released and made UNCONFIGURED.
>> > + */
>> > +extern int rtems_gpio_release_pin(gpio_pin_handle *);
>> > \ No newline at end of file
>> >
>> > diff --git a/c/src/lib/libbsp/arm/beagle/gpio/gpio.c
>> b/c/src/lib/libbsp/arm/beagle/gpio/gpio.c
>> > new file mode 100644
>> > index 0000000..541d456
>> > --- /dev/null
>> > +++ b/c/src/lib/libbsp/arm/beagle/gpio/gpio.c
>> > @@ -0,0 +1,210 @@
>> > +/**
>> > + * @file
>> > + *
>> > + * @ingroup arm_beagle
>> > + *
>> > + * @brief Global BSP definitions.
>> > + */
>> > +
>> > +/**
>> > + * Copyright (c) 2015 Ketul Shah <ketulshah1993 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 <libcpu/am335x.h>
>> > +#include <rtems.h>
>> > +#include <rtems/gpio.h>
>> > +#include <bsp/irq.h>
>> > +#include <bsp/beagleboneblack.h>
>> > +#include <bsp.h>
>> > +#include <stdlib.h>
>> > +#include <stdint.h>
>> > +#include <assert.h>
>> > +
>> > +/**
>> > + * @brief GPIO API mutex atributes.
>> > + */
>> > +#define MUTEX_ATRIBUTES                         \
>> > +  ( RTEMS_LOCAL                                 \
>> > +    | RTEMS_PRIORITY                            \
>> > +    | RTEMS_BINARY_SEMAPHORE                    \
>> > +    | RTEMS_INHERIT_PRIORITY                    \
>> > +    | RTEMS_NO_PRIORITY_CEILING                 \
>> > +    )
>> > +
>> > +#define OBTAIN_LOCK(s)  if(rtems_semaphore_obtain(s,
>>    \
>> > +                                                  RTEMS_WAIT,
>>   \
>> > +                                                  RTEMS_NO_TIMEOUT
>>    \
>> > +                                                  ) !=
>> RTEMS_SUCCESSFUL) \
>> > +                          printf("Semaphore not obtained\n");
>> > +
>> > +#define RELEASE_LOCK(s) if(rtems_semaphore_release(s) !=
>> RTEMS_SUCCESSFUL) \
>> > +                          printf("Semaphore not released\n");
>> > +
>> > +/* GPIO bank pin number as per TRM of AM335X */
>> > +static unsigned int gpio_bank_pin[GPIO_PIN_COUNT];
>> > +/* GPIO bank determines register of AM335X */
>> > +static unsigned int gpio_bank[GPIO_PIN_COUNT];
>> > +/* Pin states for all GPIO pins*/
>> > +static unsigned int gpio_pin_state[GPIO_PIN_COUNT];
>> > +/* Variable for gpio initialization */
>> > +static bool is_initialized = false;
>> > +/* Total number of gpio banks */
>> > +static int gpio_bank_count = GPIO_PIN_COUNT / GPIO_PINS_PER_BANK;
>> > +/* Semaphore for avoiding race condition */
>> > +static rtems_id bank_lock;
>> > +
>> > +static const uint32_t gpio_bank_addrs[] =
>> > +  { AM335X_GPIO0, AM335X_GPIO1, AM335X_GPIO2, AM335X_GPIO3 };
>> > +
>> > +static uint32_t inline get_pin_mask(unsigned int pin_number)
>> > +{
>> > +  return (1UL << gpio_bank_pin[pin_number]);
>> > +}
>> > +
>> > +static void inline reg_update_set(unsigned int pin_number,uint32_t reg)
>> > +{
>> > +  uint32_t gpioreg=gpio_bank[pin_number]+reg;
>> > +  uint32_t gpioreg_val=mmio_read(gpioreg);
>> > +  gpioreg_val |= get_pin_mask(pin_number);
>> > +  mmio_write(gpioreg, gpioreg_val);
>> > +}
>> > +
>> > +static void inline reg_update_unset(unsigned int pin_number,uint32_t
>> reg)
>> > +{
>> > +  uint32_t gpioreg=gpio_bank[pin_number]+reg;
>> > +  uint32_t gpioreg_val=mmio_read(gpioreg);
>> > +  gpioreg_val &= ~get_pin_mask(pin_number);
>> > +  mmio_write(gpioreg, gpioreg_val);
>> > +}
>> > +
>> > +/**
>> > + * @brief Initializes the GPIO API.
>> > + *        Allocates space to gpio_pin_state and sets pin state as
>> UNCONFIGURED.
>> > + *        Creates Semaphore for avoiding any race condition.
>> > + *        If the API has already been initialized silently exits.
>> > + */
>> > +void rtems_gpio_initialize(void)
>> > +{
>> > +  int i;
>> > +  rtems_status_code status;
>> > +  if ( is_initialized )
>> > +    return;
>> > +
>> > +  is_initialized = true;
>> > +  for ( i = 0; i < GPIO_PIN_COUNT; ++i ) {
>> > +    gpio_pin_state[i] = GPIO_PIN_STATE_UNCONFIGURED;
>> > +  }
>> > +  /* Create GPIO bank Semaphores */
>> > +  status = rtems_semaphore_create(
>> > +    rtems_build_name('G', 'L', 'C', 'K'),
>> > +    1,
>> > +    MUTEX_ATRIBUTES,
>> > +    0,
>> > +    &bank_lock
>> > +  );
>> > +  if (status != RTEMS_SUCCESSFUL){
>> > +    printf("Semaphore not created\n");
>> > +  }
>> > +}
>> > +
>> > +/**
>> > + * @brief Configures a GPIO pin to perform a digital output.
>> > + *
>> > + * @retval GPIO_SUCCESSFUL Pin was configured successfully as output.
>> > + * @retval GPIO_UNKNOWN_PIN Pin is invalid or unknown.
>> > + * @retval GPIO_MISCONFIGURED_PIN Pin is already configured for
>> another state.
>> > + */
>> > +int rtems_gpio_configure_pin_digital_out(
>> > +  gpio_pin_handle *gpio_pin_assign,unsigned int pin_number){
>> > +
>> > +  OBTAIN_LOCK(bank_lock);
>> > +  if (pin_number >= GPIO_PIN_COUNT || pin_number < 0){
>> > +    RELEASE_LOCK(bank_lock);
>> > +    return GPIO_UNKNOWN_PIN;
>> > +  }
>> > +  if (
>> > +  gpio_pin_state[gpio_pin_assign->pin_number] !=
>> GPIO_PIN_STATE_UNCONFIGURED &&
>> > +  gpio_pin_state[gpio_pin_assign->pin_number] !=
>> GPIO_PIN_STATE_DIGITAL_OUT){
>> > +    RELEASE_LOCK(bank_lock);
>> > +    return GPIO_MISCONFIGURED_PIN;
>> > +  }
>> > +
>> > +  gpio_pin_state[gpio_pin_assign->pin_number] =
>> GPIO_PIN_STATE_DIGITAL_OUT;
>> > +  gpio_pin_assign->pin_number = pin_number;
>> > +  gpio_bank_pin[pin_number] = pin_number % GPIO_PINS_PER_BANK;
>> > +  gpio_bank[pin_number] =
>> gpio_bank_addrs[pin_number/GPIO_PINS_PER_BANK];
>> > +
>> > +  reg_update_unset(gpio_pin_assign->pin_number,AM335X_GPIO_OE);
>> > +
>> > +  RELEASE_LOCK(bank_lock);
>> > +  return GPIO_SUCCESSFUL;
>> > +}
>> > +
>> > +/**
>> > + * @brief Gives an output GPIO pin the logical value of 1.
>> > + * @retval GPIO_SUCCESSFUL Pin was set successfully.
>> > + * @retval GPIO_MISCONFIGURED_PIN The received pin is not configured
>> > + *         for digital output.
>> > + */
>> > +int rtems_gpio_digital_set(gpio_pin_handle *gpio_pin_assign){
>> > +
>> > +  OBTAIN_LOCK(bank_lock);
>> > +  if (
>> > +  gpio_pin_state[gpio_pin_assign->pin_number] !=
>> GPIO_PIN_STATE_DIGITAL_OUT){
>> > +    RELEASE_LOCK(bank_lock);
>> > +    return GPIO_MISCONFIGURED_PIN;
>> > +  }
>> > +
>> > +  reg_update_set(gpio_pin_assign->pin_number,AM335X_GPIO_DATAOUT);
>> > +
>> > +  RELEASE_LOCK(bank_lock);
>> > +  return GPIO_SUCCESSFUL;
>> > +}
>> > +
>> > +/**
>> > + * @brief Gives an output GPIO pin the logical value of 0.
>> > + * @retval GPIO_SUCCESSFUL Pin was cleared successfully.
>> > + * @retval GPIO_MISCONFIGURED_PIN The received pin is not configured
>> > + *         for digital output.
>> > + */
>> > +int rtems_gpio_digital_clear(gpio_pin_handle *gpio_pin_assign){
>> > +
>> > +  OBTAIN_LOCK(bank_lock);
>> > +  if (
>> > +  gpio_pin_state[gpio_pin_assign->pin_number] ==
>> GPIO_PIN_STATE_DIGITAL_OUT){
>> > +    RELEASE_LOCK(bank_lock);
>> > +    return GPIO_MISCONFIGURED_PIN ;
>> > +  }
>> > +
>> > +  reg_update_unset(gpio_pin_assign->pin_number,AM335X_GPIO_DATAOUT);
>> > +
>> > +  RELEASE_LOCK(bank_lock);
>> > +  return GPIO_SUCCESSFUL;
>> > +}
>> > +/**
>> > + * @brief Releases currently configured pin and makes unused for
>> repurposing.
>> > + * @retval GPIO_SUCCESSFUL Pin was released successfully or it is
>> already
>> > + *         UNCONFIGURED state.
>> > + *
>> > + */
>> > +int rtems_gpio_release_pin(gpio_pin_handle *gpio_pin_assign){
>> > +
>> > +  OBTAIN_LOCK(bank_lock);
>> > +  if (
>> > +  gpio_pin_state[gpio_pin_assign->pin_number] ==
>> GPIO_PIN_STATE_UNCONFIGURED){
>> > +    RELEASE_LOCK(bank_lock);
>> > +    return GPIO_SUCCESSFUL;
>> > +  }
>> > +
>> > +  OBTAIN_LOCK(bank_lock);
>> > +
>> > +  gpio_pin_state[gpio_pin_assign->pin_number] =
>> GPIO_PIN_STATE_UNCONFIGURED;
>> > +  reg_update_set(gpio_pin_assign->pin_number,AM335X_GPIO_OE);
>> > +
>> > +  RELEASE_LOCK(bank_lock);
>> > +  return GPIO_SUCCESSFUL;
>> > +}
>> > \ No newline at end of file
>> > _______________________________________________
>> > devel mailing list
>> > devel at rtems.org
>> > http://lists.rtems.org/mailman/listinfo/devel
>> _______________________________________________
>> devel mailing list
>> devel at rtems.org
>> http://lists.rtems.org/mailman/listinfo/devel
>>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.rtems.org/pipermail/devel/attachments/20150701/f4d5ffe8/attachment-0001.html>


More information about the devel mailing list