* Generic GPIO framework
@ 2010-05-28 14:49 Simon Kallweit
2010-05-28 22:06 ` Steven Clugston
2010-05-29 9:17 ` Christophe Coutand
0 siblings, 2 replies; 4+ messages in thread
From: Simon Kallweit @ 2010-05-28 14:49 UTC (permalink / raw)
To: eCos developers
Hello
I've been working on a generic GPIO framework for eCos. I wonder if
there is interest in such a framework by the broad community. If so, I
can take the effort to clean it up and make it ready for use by others.
Let me quickly explain what the framework does in it's current form, any
feature requests are highly appreciated :)
We have a project where we need some simple digital IO (switches,
sensors, LEDs etc.). As we mainly develop on the synth target, we wanted
to be able to have a GPIO framework with drivers for both our hardware
target (an STM32) and the synth target.
The GPIO framework (CYGPKG_IO_GPIO) provides the basic infrastructure to
support GPIO "devices". Using this architecture it would be feasible to
also implement GPIO drivers for let's say SPI-based GPIO expanders.
The user API is very simple:
// GPIO direction
typedef enum {
CYG_GPIO_INPUT,
CYG_GPIO_OUTPUT,
} cyg_gpio_dir_t;
// Checks if a virtual pin number is valid.
cyg_bool cyg_gpio_is_valid(int pin);
// Configures a pin with direction (input/output) and hardware specific
flags.
void cyg_gpio_configure(int pin, cyg_gpio_dir_t dir, int flags);
// Writes to a pin.
void cyg_gpio_set(int pin, int value);
// Reads from a pin.
int cyg_gpio_get(int pin);
// Checks if a pin has a dedicated interrupt.
cyg_bool cyg_gpio_has_irq(int pin);
// Gets the interrupt vector of a pin.
cyg_vector_t cyg_gpio_to_irq(int pin);
Note that the pin number is 'virtual'. In the case of the STM32 GPIO
driver, pins are mapped linearly. PA0 has pin number 0, PA15 has 15, PB0
has 16 and so on. When having multiple GPIO devices, one would have to
define regions for further pins. Do you think this is OK, or should
there be some 'device id' to identify the actual GPIO device to use?
Besides the simple API, there is an API to create 'observers'. An
observer can be used to observe the input value of a GPIO pin. The user
is notified through a callback if the input value changes. Observers can
both by used in a polling mode or in interrupt mode, if the pin supports
it. Also the observer implements debouncing. Observers can be used to
handle simple switches for example.
The observer API looks like this:
// GPIO observer flags
typedef enum {
CYG_GPIO_OBSERVER_DEBOUNCE = (1<<0),
CYG_GPIO_OBSERVER_INTERRUPT = (1<<1),
} cyg_gpio_observer_flags_t;
// GPIO observer handler
typedef void (*cyg_gpio_handler_t)(int pin, int value, void *user);
// Creates an observer.
void cyg_gpio_observer_create(struct cyg_gpio_observer *observer,
int pin,
cyg_gpio_observer_flags_t flags,
cyg_gpio_handler_t handler,
void *user);
// Destroys an observer.
void cyg_gpio_observer_destroy(struct cyg_gpio_observer *observer);
// Enables an observer.
void cyg_gpio_observer_enable(struct cyg_gpio_observer *observer);
// Disables an observer.
void cyg_gpio_observer_disable(struct cyg_gpio_observer *observer);
GPIO drivers can be written relatively simple. One has to basically
provide the following functions:
// Driver functions
struct cyg_gpio_device_funs {
void (*init)(struct cyg_gpio_device *dev);
cyg_bool (*is_valid)(struct cyg_gpio_device *dev, int pin);
void (*configure)(struct cyg_gpio_device *dev, int pin,
cyg_gpio_dir_t dir, int flags);
void (*set)(struct cyg_gpio_device *dev, int pin, int value);
void (*get)(struct cyg_gpio_device *dev, int pin, int *value);
cyg_bool (*has_irq)(struct cyg_gpio_device *dev, int pin);
cyg_vector_t (*to_irq)(struct cyg_gpio_device *dev, int pin);
};
As I said, I already have implemented drivers for the STM32 and the
synthetic target.
The STM32 driver is very straight forward. It lets you define a list of
valid pins for use by the application (optional) and a list of pins that
should be mapped to interrupts. The driver automatically sets up the
EXTI interrupt mappings for the configured pins.
The synth driver is a bit more complex. It comes with integration into
the ecosynth GUI. It lets the user dynamically specify how the GPIOs are
displayed by editing the target.tdf configuration file. Currently the
driver will display a simple list of 'items'. Items can be labels,
generic pins and LEDs (both mono and bi-color). Generic pins have a few
options to simulate switches etc.
Now if anyone is interested to review my current implementation, I can
prepare a tarball and put it up somewhere.
There are a few open questions, but before bringing them up I just
wanted to see if anyone is interested in this.
Simon
^ permalink raw reply [flat|nested] 4+ messages in thread
* RE: Generic GPIO framework
2010-05-28 14:49 Generic GPIO framework Simon Kallweit
@ 2010-05-28 22:06 ` Steven Clugston
2010-05-29 9:17 ` Christophe Coutand
1 sibling, 0 replies; 4+ messages in thread
From: Steven Clugston @ 2010-05-28 22:06 UTC (permalink / raw)
To: ecos-devel
I for one would like to see this included so I hope the maintainers see fit to do so.
This could be used to create drivers that are more generic for add-on devices (bit-bang buses/LCD screens) that otherwise sometimes find their way into HAL because pin platform specific pin macro definitions are needed somewhere to actually act on the hardware. A common GPIO interface could allow a driver to be written for a device without knowing or caring exactly what the pin assignment will be and what HAL macros are needed to change the pin states. Obviously this would need to be defined somewhere board specific instead but at least then the driver code will work for more than one board.
Might slight concern is that checking or changing a pin state often might incur an extra stack push/pop overhead (over the HAL macros) if the get/set functions are not inlined.
Steven
^ permalink raw reply [flat|nested] 4+ messages in thread
* RE: Generic GPIO framework
2010-05-28 14:49 Generic GPIO framework Simon Kallweit
2010-05-28 22:06 ` Steven Clugston
@ 2010-05-29 9:17 ` Christophe Coutand
2010-05-31 7:41 ` Sergei Gavrikov
1 sibling, 1 reply; 4+ messages in thread
From: Christophe Coutand @ 2010-05-29 9:17 UTC (permalink / raw)
To: Simon Kallweit, eCos developers
While I think it is possible to write generic drivers (for sensors, step
motors, LCD etc.) using the platform GPIO, a common way of doing would
make it easier to share drivers.
Maybe the interface should be more compact:
1. cyg_gpio_set_config, which would include:
- An extended version of cyg_gpio_configure (Some devices are
allowing more than setting IN/OUT buffer type. You might have the option
to configure the output in open collector mode etc.. FPGA also allow to
configure the driver type and strength, maybe some CPU have this
option?).
- A way of enable / disabling interrupt for that IO
2. cyg_gpio_get_config, which would include:
- Allow to retrieve all settings from cyg_gpio_set_config
- cyg_gpio_has_irq
- cyg_gpio_to_irq
cyg_gpio_is_valid could also be part of cyg_gpio_get_config
3. cyg_gpio_set
4. cyg_gpio_get
Christophe
-----Original Message-----
From: ecos-devel-owner@ecos.sourceware.org
[mailto:ecos-devel-owner@ecos.sourceware.org] On Behalf Of Simon
Kallweit
Sent: 28. mai 2010 16:49
To: eCos developers
Subject: Generic GPIO framework
Hello
I've been working on a generic GPIO framework for eCos. I wonder if
there is interest in such a framework by the broad community. If so, I
can take the effort to clean it up and make it ready for use by others.
Let me quickly explain what the framework does in it's current form, any
feature requests are highly appreciated :)
We have a project where we need some simple digital IO (switches,
sensors, LEDs etc.). As we mainly develop on the synth target, we wanted
to be able to have a GPIO framework with drivers for both our hardware
target (an STM32) and the synth target.
The GPIO framework (CYGPKG_IO_GPIO) provides the basic infrastructure to
support GPIO "devices". Using this architecture it would be feasible to
also implement GPIO drivers for let's say SPI-based GPIO expanders.
The user API is very simple:
// GPIO direction
typedef enum {
CYG_GPIO_INPUT,
CYG_GPIO_OUTPUT,
} cyg_gpio_dir_t;
// Checks if a virtual pin number is valid.
cyg_bool cyg_gpio_is_valid(int pin);
// Configures a pin with direction (input/output) and hardware specific
flags.
void cyg_gpio_configure(int pin, cyg_gpio_dir_t dir, int flags);
// Writes to a pin.
void cyg_gpio_set(int pin, int value);
// Reads from a pin.
int cyg_gpio_get(int pin);
// Checks if a pin has a dedicated interrupt.
cyg_bool cyg_gpio_has_irq(int pin);
// Gets the interrupt vector of a pin.
cyg_vector_t cyg_gpio_to_irq(int pin);
Note that the pin number is 'virtual'. In the case of the STM32 GPIO
driver, pins are mapped linearly. PA0 has pin number 0, PA15 has 15, PB0
has 16 and so on. When having multiple GPIO devices, one would have to
define regions for further pins. Do you think this is OK, or should
there be some 'device id' to identify the actual GPIO device to use?
Besides the simple API, there is an API to create 'observers'. An
observer can be used to observe the input value of a GPIO pin. The user
is notified through a callback if the input value changes. Observers can
both by used in a polling mode or in interrupt mode, if the pin supports
it. Also the observer implements debouncing. Observers can be used to
handle simple switches for example.
The observer API looks like this:
// GPIO observer flags
typedef enum {
CYG_GPIO_OBSERVER_DEBOUNCE = (1<<0),
CYG_GPIO_OBSERVER_INTERRUPT = (1<<1),
} cyg_gpio_observer_flags_t;
// GPIO observer handler
typedef void (*cyg_gpio_handler_t)(int pin, int value, void *user);
// Creates an observer.
void cyg_gpio_observer_create(struct cyg_gpio_observer *observer,
int pin,
cyg_gpio_observer_flags_t flags,
cyg_gpio_handler_t handler,
void *user);
// Destroys an observer.
void cyg_gpio_observer_destroy(struct cyg_gpio_observer *observer);
// Enables an observer.
void cyg_gpio_observer_enable(struct cyg_gpio_observer *observer);
// Disables an observer.
void cyg_gpio_observer_disable(struct cyg_gpio_observer *observer);
GPIO drivers can be written relatively simple. One has to basically
provide the following functions:
// Driver functions
struct cyg_gpio_device_funs {
void (*init)(struct cyg_gpio_device *dev);
cyg_bool (*is_valid)(struct cyg_gpio_device *dev, int pin);
void (*configure)(struct cyg_gpio_device *dev, int pin,
cyg_gpio_dir_t dir, int flags);
void (*set)(struct cyg_gpio_device *dev, int pin, int value);
void (*get)(struct cyg_gpio_device *dev, int pin, int *value);
cyg_bool (*has_irq)(struct cyg_gpio_device *dev, int pin);
cyg_vector_t (*to_irq)(struct cyg_gpio_device *dev, int pin);
};
As I said, I already have implemented drivers for the STM32 and the
synthetic target.
The STM32 driver is very straight forward. It lets you define a list of
valid pins for use by the application (optional) and a list of pins that
should be mapped to interrupts. The driver automatically sets up the
EXTI interrupt mappings for the configured pins.
The synth driver is a bit more complex. It comes with integration into
the ecosynth GUI. It lets the user dynamically specify how the GPIOs are
displayed by editing the target.tdf configuration file. Currently the
driver will display a simple list of 'items'. Items can be labels,
generic pins and LEDs (both mono and bi-color). Generic pins have a few
options to simulate switches etc.
Now if anyone is interested to review my current implementation, I can
prepare a tarball and put it up somewhere.
There are a few open questions, but before bringing them up I just
wanted to see if anyone is interested in this.
Simon
^ permalink raw reply [flat|nested] 4+ messages in thread
* RE: Generic GPIO framework
2010-05-29 9:17 ` Christophe Coutand
@ 2010-05-31 7:41 ` Sergei Gavrikov
0 siblings, 0 replies; 4+ messages in thread
From: Sergei Gavrikov @ 2010-05-31 7:41 UTC (permalink / raw)
To: Christophe Coutand; +Cc: Simon Kallweit, eCos developers
Hi
And may be to have even more generic I/O driver -- `parport`, then
the driver's interface would be
cyg_io_{read,write}
cyg_io_{set,get}_config
and to get the eCos parallel I/O devices like /dev/parX.
Generic layer:
io/parport/*
Devices:
devs/parport/*
My $0.02.
Sergei
On Sat, 29 May 2010, Christophe Coutand wrote:
> While I think it is possible to write generic drivers (for sensors, step
> motors, LCD etc.) using the platform GPIO, a common way of doing would
> make it easier to share drivers.
>
> Maybe the interface should be more compact:
>
> 1. cyg_gpio_set_config, which would include:
>
> - An extended version of cyg_gpio_configure (Some devices are
> allowing more than setting IN/OUT buffer type. You might have the option
> to configure the output in open collector mode etc.. FPGA also allow to
> configure the driver type and strength, maybe some CPU have this
> option?).
> - A way of enable / disabling interrupt for that IO
>
> 2. cyg_gpio_get_config, which would include:
> - Allow to retrieve all settings from cyg_gpio_set_config
> - cyg_gpio_has_irq
> - cyg_gpio_to_irq
>
> cyg_gpio_is_valid could also be part of cyg_gpio_get_config
>
> 3. cyg_gpio_set
>
> 4. cyg_gpio_get
>
> Christophe
>
>
> -----Original Message-----
> From: ecos-devel-owner@ecos.sourceware.org
> [mailto:ecos-devel-owner@ecos.sourceware.org] On Behalf Of Simon
> Kallweit
> Sent: 28. mai 2010 16:49
> To: eCos developers
> Subject: Generic GPIO framework
>
> Hello
>
> I've been working on a generic GPIO framework for eCos. I wonder if
> there is interest in such a framework by the broad community. If so, I
> can take the effort to clean it up and make it ready for use by others.
>
> Let me quickly explain what the framework does in it's current form, any
>
> feature requests are highly appreciated :)
>
> We have a project where we need some simple digital IO (switches,
> sensors, LEDs etc.). As we mainly develop on the synth target, we wanted
>
> to be able to have a GPIO framework with drivers for both our hardware
> target (an STM32) and the synth target.
>
> The GPIO framework (CYGPKG_IO_GPIO) provides the basic infrastructure to
>
> support GPIO "devices". Using this architecture it would be feasible to
> also implement GPIO drivers for let's say SPI-based GPIO expanders.
>
> The user API is very simple:
>
> // GPIO direction
> typedef enum {
> CYG_GPIO_INPUT,
> CYG_GPIO_OUTPUT,
> } cyg_gpio_dir_t;
>
> // Checks if a virtual pin number is valid.
> cyg_bool cyg_gpio_is_valid(int pin);
>
> // Configures a pin with direction (input/output) and hardware specific
> flags.
> void cyg_gpio_configure(int pin, cyg_gpio_dir_t dir, int flags);
>
> // Writes to a pin.
> void cyg_gpio_set(int pin, int value);
>
> // Reads from a pin.
> int cyg_gpio_get(int pin);
>
> // Checks if a pin has a dedicated interrupt.
> cyg_bool cyg_gpio_has_irq(int pin);
>
> // Gets the interrupt vector of a pin.
> cyg_vector_t cyg_gpio_to_irq(int pin);
>
> Note that the pin number is 'virtual'. In the case of the STM32 GPIO
> driver, pins are mapped linearly. PA0 has pin number 0, PA15 has 15, PB0
>
> has 16 and so on. When having multiple GPIO devices, one would have to
> define regions for further pins. Do you think this is OK, or should
> there be some 'device id' to identify the actual GPIO device to use?
>
> Besides the simple API, there is an API to create 'observers'. An
> observer can be used to observe the input value of a GPIO pin. The user
> is notified through a callback if the input value changes. Observers can
>
> both by used in a polling mode or in interrupt mode, if the pin supports
>
> it. Also the observer implements debouncing. Observers can be used to
> handle simple switches for example.
>
> The observer API looks like this:
>
> // GPIO observer flags
> typedef enum {
> CYG_GPIO_OBSERVER_DEBOUNCE = (1<<0),
> CYG_GPIO_OBSERVER_INTERRUPT = (1<<1),
> } cyg_gpio_observer_flags_t;
>
> // GPIO observer handler
> typedef void (*cyg_gpio_handler_t)(int pin, int value, void *user);
>
> // Creates an observer.
> void cyg_gpio_observer_create(struct cyg_gpio_observer *observer,
> int pin,
> cyg_gpio_observer_flags_t flags,
> cyg_gpio_handler_t handler,
> void *user);
> // Destroys an observer.
> void cyg_gpio_observer_destroy(struct cyg_gpio_observer *observer);
>
> // Enables an observer.
> void cyg_gpio_observer_enable(struct cyg_gpio_observer *observer);
>
> // Disables an observer.
> void cyg_gpio_observer_disable(struct cyg_gpio_observer *observer);
>
> GPIO drivers can be written relatively simple. One has to basically
> provide the following functions:
>
> // Driver functions
> struct cyg_gpio_device_funs {
> void (*init)(struct cyg_gpio_device *dev);
> cyg_bool (*is_valid)(struct cyg_gpio_device *dev, int pin);
> void (*configure)(struct cyg_gpio_device *dev, int pin,
> cyg_gpio_dir_t dir, int flags);
> void (*set)(struct cyg_gpio_device *dev, int pin, int value);
> void (*get)(struct cyg_gpio_device *dev, int pin, int *value);
> cyg_bool (*has_irq)(struct cyg_gpio_device *dev, int pin);
> cyg_vector_t (*to_irq)(struct cyg_gpio_device *dev, int pin);
> };
>
> As I said, I already have implemented drivers for the STM32 and the
> synthetic target.
>
> The STM32 driver is very straight forward. It lets you define a list of
> valid pins for use by the application (optional) and a list of pins that
>
> should be mapped to interrupts. The driver automatically sets up the
> EXTI interrupt mappings for the configured pins.
>
> The synth driver is a bit more complex. It comes with integration into
> the ecosynth GUI. It lets the user dynamically specify how the GPIOs are
>
> displayed by editing the target.tdf configuration file. Currently the
> driver will display a simple list of 'items'. Items can be labels,
> generic pins and LEDs (both mono and bi-color). Generic pins have a few
> options to simulate switches etc.
>
> Now if anyone is interested to review my current implementation, I can
> prepare a tarball and put it up somewhere.
>
> There are a few open questions, but before bringing them up I just
> wanted to see if anyone is interested in this.
>
>
> Simon
>
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2010-05-31 7:41 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-05-28 14:49 Generic GPIO framework Simon Kallweit
2010-05-28 22:06 ` Steven Clugston
2010-05-29 9:17 ` Christophe Coutand
2010-05-31 7:41 ` Sergei Gavrikov
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).