<div dir="ltr"><div>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.<br><br></div>Steve<br><br></div><div class="gmail_extra"><br><div class="gmail_quote">On Tue, Jun 30, 2015 at 9:53 AM, Gedare Bloom <span dir="ltr"><<a href="mailto:gedare@gwu.edu" target="_blank">gedare@gwu.edu</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">I don't think we want the shared code in cpukit but rather in<br>
libbsp/shared.. Also, I think Andre shall commit the shared code, so<br>
perhaps you should focus on just getting a localized solution working<br>
in the beagleboard BSP<br>
<div class="HOEnZb"><div class="h5"><br>
On Tue, Jun 30, 2015 at 5:46 AM, Ketul Shah <<a href="mailto:ketulshah1993@gmail.com">ketulshah1993@gmail.com</a>> wrote:<br>
> diff --git a/cpukit/include/rtems/gpio.h b/cpukit/include/rtems/gpio.h<br>
> new file mode 100644<br>
> index 0000000..3d68c39<br>
> --- /dev/null<br>
> +++ b/cpukit/include/rtems/gpio.h<br>
> @@ -0,0 +1,64 @@<br>
> +/**<br>
> + * @file rtems/gpio.h<br>
> + *<br>
> + * @brief Global GPIO definitions.<br>
> + *<br>
> + * This include the generalized definitions for GPIO<br>
> + */<br>
> +<br>
> +/**<br>
> + * Copyright (c) 2015 Ketul Shah <ketulshah1993 at <a href="http://gmail.com" rel="noreferrer" target="_blank">gmail.com</a>><br>
> + *<br>
> + * The license and distribution terms for this file may be<br>
> + * found in the file LICENSE in this distribution or at<br>
> + * <a href="http://www.rtems.org/license/LICENSE" rel="noreferrer" target="_blank">http://www.rtems.org/license/LICENSE</a>.<br>
> + */<br>
> +<br>
> +#ifndef _RTEMS_GPIO_H<br>
> +#define _RTEMS_GPIO_H<br>
> +<br>
> +#ifdef __cplusplus<br>
> +extern "C" {<br>
> +#endif /* __cplusplus */<br>
> +<br>
> +/* Returned Error Codes by function */<br>
> +#define GPIO_SUCCESSFUL 0 /* operation is OK */<br>
> +#define GPIO_UNKNOWN_PIN 1 /* pin not known by bsp */<br>
> +#define GPIO_UNCONFIGURED_PIN 2 /* pin unable to configure */<br>
> +#define GPIO_MISCONFIGURED_PIN 3 /* pin configuration can't match operation */<br>
> +<br>
> +/* Possible GPIO Pin States */<br>
> +#define GPIO_PIN_STATE_UNCONFIGURED 0<br>
> +#define GPIO_PIN_STATE_DIGITAL_OUT 1<br>
> +#define GPIO_PIN_STATE_DIGITAL_IN 2<br>
> +<br>
> +/**<br>
> + * @brief Structure contains all the required members for GPIO access.<br>
> + */<br>
> +typedef struct<br>
> +{<br>
> + int pin_number;/* The pin number. */<br>
> + void* platform; /* Opaque hardware specific set up details. */<br>
> +} gpio_pin_handle;<br>
> +<br>
> +/**<br>
> + * @brief Initializes the GPIO API.<br>
> + */<br>
> +extern void rtems_gpio_initialize(void);<br>
> +/**<br>
> + * @brief Selects a GPIO pin for a digital output.<br>
> + */<br>
> +extern int rtems_gpio_configure_pin_digital_out(<br>
> + gpio_pin_handle *, unsigned int );<br>
> +/**<br>
> + * @brief Turns on the given pin.<br>
> + */<br>
> +extern int rtems_gpio_digital_set(gpio_pin_handle *);<br>
> +/**<br>
> + * @brief Turns off the given pin.<br>
> + */<br>
> +extern int rtems_gpio_digital_clear(gpio_pin_handle *);<br>
> +/**<br>
> + * @brief currently configured pin is released and made UNCONFIGURED.<br>
> + */<br>
> +extern int rtems_gpio_release_pin(gpio_pin_handle *);<br>
> \ No newline at end of file<br>
><br>
> diff --git a/c/src/lib/libbsp/arm/beagle/gpio/gpio.c b/c/src/lib/libbsp/arm/beagle/gpio/gpio.c<br>
> new file mode 100644<br>
> index 0000000..541d456<br>
> --- /dev/null<br>
> +++ b/c/src/lib/libbsp/arm/beagle/gpio/gpio.c<br>
> @@ -0,0 +1,210 @@<br>
> +/**<br>
> + * @file<br>
> + *<br>
> + * @ingroup arm_beagle<br>
> + *<br>
> + * @brief Global BSP definitions.<br>
> + */<br>
> +<br>
> +/**<br>
> + * Copyright (c) 2015 Ketul Shah <ketulshah1993 at <a href="http://gmail.com" rel="noreferrer" target="_blank">gmail.com</a>><br>
> + *<br>
> + * The license and distribution terms for this file may be<br>
> + * found in the file LICENSE in this distribution or at<br>
> + * <a href="http://www.rtems.org/license/LICENSE" rel="noreferrer" target="_blank">http://www.rtems.org/license/LICENSE</a>.<br>
> + */<br>
> +<br>
> +#include <libcpu/am335x.h><br>
> +#include <rtems.h><br>
> +#include <rtems/gpio.h><br>
> +#include <bsp/irq.h><br>
> +#include <bsp/beagleboneblack.h><br>
> +#include <bsp.h><br>
> +#include <stdlib.h><br>
> +#include <stdint.h><br>
> +#include <assert.h><br>
> +<br>
> +/**<br>
> + * @brief GPIO API mutex atributes.<br>
> + */<br>
> +#define MUTEX_ATRIBUTES \<br>
> + ( RTEMS_LOCAL \<br>
> + | RTEMS_PRIORITY \<br>
> + | RTEMS_BINARY_SEMAPHORE \<br>
> + | RTEMS_INHERIT_PRIORITY \<br>
> + | RTEMS_NO_PRIORITY_CEILING \<br>
> + )<br>
> +<br>
> +#define OBTAIN_LOCK(s) if(rtems_semaphore_obtain(s, \<br>
> + RTEMS_WAIT, \<br>
> + RTEMS_NO_TIMEOUT \<br>
> + ) != RTEMS_SUCCESSFUL) \<br>
> + printf("Semaphore not obtained\n");<br>
> +<br>
> +#define RELEASE_LOCK(s) if(rtems_semaphore_release(s) != RTEMS_SUCCESSFUL) \<br>
> + printf("Semaphore not released\n");<br>
> +<br>
> +/* GPIO bank pin number as per TRM of AM335X */<br>
> +static unsigned int gpio_bank_pin[GPIO_PIN_COUNT];<br>
> +/* GPIO bank determines register of AM335X */<br>
> +static unsigned int gpio_bank[GPIO_PIN_COUNT];<br>
> +/* Pin states for all GPIO pins*/<br>
> +static unsigned int gpio_pin_state[GPIO_PIN_COUNT];<br>
> +/* Variable for gpio initialization */<br>
> +static bool is_initialized = false;<br>
> +/* Total number of gpio banks */<br>
> +static int gpio_bank_count = GPIO_PIN_COUNT / GPIO_PINS_PER_BANK;<br>
> +/* Semaphore for avoiding race condition */<br>
> +static rtems_id bank_lock;<br>
> +<br>
> +static const uint32_t gpio_bank_addrs[] =<br>
> + { AM335X_GPIO0, AM335X_GPIO1, AM335X_GPIO2, AM335X_GPIO3 };<br>
> +<br>
> +static uint32_t inline get_pin_mask(unsigned int pin_number)<br>
> +{<br>
> + return (1UL << gpio_bank_pin[pin_number]);<br>
> +}<br>
> +<br>
> +static void inline reg_update_set(unsigned int pin_number,uint32_t reg)<br>
> +{<br>
> + uint32_t gpioreg=gpio_bank[pin_number]+reg;<br>
> + uint32_t gpioreg_val=mmio_read(gpioreg);<br>
> + gpioreg_val |= get_pin_mask(pin_number);<br>
> + mmio_write(gpioreg, gpioreg_val);<br>
> +}<br>
> +<br>
> +static void inline reg_update_unset(unsigned int pin_number,uint32_t reg)<br>
> +{<br>
> + uint32_t gpioreg=gpio_bank[pin_number]+reg;<br>
> + uint32_t gpioreg_val=mmio_read(gpioreg);<br>
> + gpioreg_val &= ~get_pin_mask(pin_number);<br>
> + mmio_write(gpioreg, gpioreg_val);<br>
> +}<br>
> +<br>
> +/**<br>
> + * @brief Initializes the GPIO API.<br>
> + * Allocates space to gpio_pin_state and sets pin state as UNCONFIGURED.<br>
> + * Creates Semaphore for avoiding any race condition.<br>
> + * If the API has already been initialized silently exits.<br>
> + */<br>
> +void rtems_gpio_initialize(void)<br>
> +{<br>
> + int i;<br>
> + rtems_status_code status;<br>
> + if ( is_initialized )<br>
> + return;<br>
> +<br>
> + is_initialized = true;<br>
> + for ( i = 0; i < GPIO_PIN_COUNT; ++i ) {<br>
> + gpio_pin_state[i] = GPIO_PIN_STATE_UNCONFIGURED;<br>
> + }<br>
> + /* Create GPIO bank Semaphores */<br>
> + status = rtems_semaphore_create(<br>
> + rtems_build_name('G', 'L', 'C', 'K'),<br>
> + 1,<br>
> + MUTEX_ATRIBUTES,<br>
> + 0,<br>
> + &bank_lock<br>
> + );<br>
> + if (status != RTEMS_SUCCESSFUL){<br>
> + printf("Semaphore not created\n");<br>
> + }<br>
> +}<br>
> +<br>
> +/**<br>
> + * @brief Configures a GPIO pin to perform a digital output.<br>
> + *<br>
> + * @retval GPIO_SUCCESSFUL Pin was configured successfully as output.<br>
> + * @retval GPIO_UNKNOWN_PIN Pin is invalid or unknown.<br>
> + * @retval GPIO_MISCONFIGURED_PIN Pin is already configured for another state.<br>
> + */<br>
> +int rtems_gpio_configure_pin_digital_out(<br>
> + gpio_pin_handle *gpio_pin_assign,unsigned int pin_number){<br>
> +<br>
> + OBTAIN_LOCK(bank_lock);<br>
> + if (pin_number >= GPIO_PIN_COUNT || pin_number < 0){<br>
> + RELEASE_LOCK(bank_lock);<br>
> + return GPIO_UNKNOWN_PIN;<br>
> + }<br>
> + if (<br>
> + gpio_pin_state[gpio_pin_assign->pin_number] != GPIO_PIN_STATE_UNCONFIGURED &&<br>
> + gpio_pin_state[gpio_pin_assign->pin_number] != GPIO_PIN_STATE_DIGITAL_OUT){<br>
> + RELEASE_LOCK(bank_lock);<br>
> + return GPIO_MISCONFIGURED_PIN;<br>
> + }<br>
> +<br>
> + gpio_pin_state[gpio_pin_assign->pin_number] = GPIO_PIN_STATE_DIGITAL_OUT;<br>
> + gpio_pin_assign->pin_number = pin_number;<br>
> + gpio_bank_pin[pin_number] = pin_number % GPIO_PINS_PER_BANK;<br>
> + gpio_bank[pin_number] = gpio_bank_addrs[pin_number/GPIO_PINS_PER_BANK];<br>
> +<br>
> + reg_update_unset(gpio_pin_assign->pin_number,AM335X_GPIO_OE);<br>
> +<br>
> + RELEASE_LOCK(bank_lock);<br>
> + return GPIO_SUCCESSFUL;<br>
> +}<br>
> +<br>
> +/**<br>
> + * @brief Gives an output GPIO pin the logical value of 1.<br>
> + * @retval GPIO_SUCCESSFUL Pin was set successfully.<br>
> + * @retval GPIO_MISCONFIGURED_PIN The received pin is not configured<br>
> + * for digital output.<br>
> + */<br>
> +int rtems_gpio_digital_set(gpio_pin_handle *gpio_pin_assign){<br>
> +<br>
> + OBTAIN_LOCK(bank_lock);<br>
> + if (<br>
> + gpio_pin_state[gpio_pin_assign->pin_number] != GPIO_PIN_STATE_DIGITAL_OUT){<br>
> + RELEASE_LOCK(bank_lock);<br>
> + return GPIO_MISCONFIGURED_PIN;<br>
> + }<br>
> +<br>
> + reg_update_set(gpio_pin_assign->pin_number,AM335X_GPIO_DATAOUT);<br>
> +<br>
> + RELEASE_LOCK(bank_lock);<br>
> + return GPIO_SUCCESSFUL;<br>
> +}<br>
> +<br>
> +/**<br>
> + * @brief Gives an output GPIO pin the logical value of 0.<br>
> + * @retval GPIO_SUCCESSFUL Pin was cleared successfully.<br>
> + * @retval GPIO_MISCONFIGURED_PIN The received pin is not configured<br>
> + * for digital output.<br>
> + */<br>
> +int rtems_gpio_digital_clear(gpio_pin_handle *gpio_pin_assign){<br>
> +<br>
> + OBTAIN_LOCK(bank_lock);<br>
> + if (<br>
> + gpio_pin_state[gpio_pin_assign->pin_number] == GPIO_PIN_STATE_DIGITAL_OUT){<br>
> + RELEASE_LOCK(bank_lock);<br>
> + return GPIO_MISCONFIGURED_PIN ;<br>
> + }<br>
> +<br>
> + reg_update_unset(gpio_pin_assign->pin_number,AM335X_GPIO_DATAOUT);<br>
> +<br>
> + RELEASE_LOCK(bank_lock);<br>
> + return GPIO_SUCCESSFUL;<br>
> +}<br>
> +/**<br>
> + * @brief Releases currently configured pin and makes unused for repurposing.<br>
> + * @retval GPIO_SUCCESSFUL Pin was released successfully or it is already<br>
> + * UNCONFIGURED state.<br>
> + *<br>
> + */<br>
> +int rtems_gpio_release_pin(gpio_pin_handle *gpio_pin_assign){<br>
> +<br>
> + OBTAIN_LOCK(bank_lock);<br>
> + if (<br>
> + gpio_pin_state[gpio_pin_assign->pin_number] == GPIO_PIN_STATE_UNCONFIGURED){<br>
> + RELEASE_LOCK(bank_lock);<br>
> + return GPIO_SUCCESSFUL;<br>
> + }<br>
> +<br>
> + OBTAIN_LOCK(bank_lock);<br>
> +<br>
> + gpio_pin_state[gpio_pin_assign->pin_number] = GPIO_PIN_STATE_UNCONFIGURED;<br>
> + reg_update_set(gpio_pin_assign->pin_number,AM335X_GPIO_OE);<br>
> +<br>
> + RELEASE_LOCK(bank_lock);<br>
> + return GPIO_SUCCESSFUL;<br>
> +}<br>
> \ No newline at end of file<br>
> _______________________________________________<br>
> devel mailing list<br>
> <a href="mailto:devel@rtems.org">devel@rtems.org</a><br>
> <a href="http://lists.rtems.org/mailman/listinfo/devel" rel="noreferrer" target="_blank">http://lists.rtems.org/mailman/listinfo/devel</a><br>
_______________________________________________<br>
devel mailing list<br>
<a href="mailto:devel@rtems.org">devel@rtems.org</a><br>
<a href="http://lists.rtems.org/mailman/listinfo/devel" rel="noreferrer" target="_blank">http://lists.rtems.org/mailman/listinfo/devel</a><br>
</div></div></blockquote></div><br></div>