[En-Nut-Discussion] RFA_4: Nut/OS GPIO API
ole.reinhardt at embedded-it.de
Fri Oct 19 15:33:59 CEST 2012
Resend of RFA_3 without comments...
The following rules apply to the Gpio API.
1 The main purpose of the Gpio API is to offer a common interface for
target-independent bit-banged drivers, typically located in nut/dev.
Implementation can be as functions or macros
2 The GPIO API _must_ be used if an application shall be portable. The
GPIO API _must_ be used if the program is intended for Nut/OS
application examples in nut/app
3 The Gpio API may be used by target-specific drivers, typically located
3.1 If the driver requires special function, which are not available in
the Gpio API, then this has to be implemented somewhere else. It is
not acceptable to extend the Gpio API in a target-specific way.
3.2 If target specific settings are needed they must be implemented in
the extended GpioPin/PortConfigSetExteded() function.
4 The GPIO API is not intended to use to for alternate function
configuration. It may not be extended wich any flags intended for such
Each plaform shall provide a platform specific
GpioCfgAlternateFunction() macro or function for this purpose.
5 The parameter bank specifies the GPIO group of bits (aka. port) and
must be specified by index of type int. This fixed type allows callers
to handle them in a common way during runtime.
5.1 The bank index base is target dependent.
5.2 Bank indexes may not be consecutively numbered.
5.3 If the implementation requires a different type, this may be done by
typecasting the integer index type.
6 The parameter bit specifies the bit within a bank and must be
specified by an index of type int.
6.1 The bit index base is 0.
6.2 Bit indexes are consecutively numbered.
7 For port-wide operations, the parameter mask specifies the sum
of the bitvalues (_BV()) from the bit indexes involved.
8 Functions, which set GPIO output values, are of type void.
8.1 The only way to determine the validity of a bank or related bit is
by configuring it.
9 The functionality to query a pin or pin group (aka port is often
implemented as macros and returns a value of the same type as a port
register access. If implemented as function it must return a value of
9.1 A value of 0 is returned, if the pin state is low. Any other value
indicates a high state.
9.2 If the requested bank or bit is not available on the target, the
function result is undefined.
9.3 With NUTDEBUG defined, is is usefull if a possible much slower
codepath is taken that checks for parameter validity.
10 The Gpio API will guarantee the following pin configuration
capabilities for all supported targets as long as the pin supports
10.1 GPIO_CFG_INPUT to switch the pin to input mode
10.2 GPIO_CFG_OUTPUT to switch the pin to output mode
10.3 GPIO_CFG_INIT_HIGH|LOW to switch on the pin in the requested state
when configured as output
10.4 If the requested capability is not available for the specified
pin/port, the API function must return -1 to indicate an error.
Otherwise 0 is returned.
11 The Gpio API may provide the following pin configuration
11.1 GPIO_CFG_PULLUP to enable the internal pull-up
11.2 GPIO_CFG_OPEN_DRAIN to enable open drain mode of an output,
otherwise push-pull is assumed
11.3 The return values are the flags of the requested capabilities with
the not implemented capabilities set to one, all implemented
capabilities masked to 0. So a return value of 0 means that all
capabilities are supported
11.4 Further architecture specific FLAGS like
GPIO_CFG_PULLDOWN to enable the internal pull-down
may be provided by the platform, but applications that shall be
portable may not rely to this feature
11.5 To configure these platform dependent capabilities a new function
GpioPinConfigSetExtended() is introduced that may not be used in
portable applications. Implementation is platform dependend. These
flags shall not be exported in include/dev/gpio.h but in the
architecture specific header-
12 The Gpio API may offer to register an interrupt handler for a
specific bit and to enable and disable this interrupt and a function
to query if the interrupt is enabled or not.
12.1 After registration, interrupts are disabled.
12.2 It is expected, that interrupts are triggered on any pin change by
12.3 If a platform supports futher interrupt trigger modes for the
GPIO pins, it may provide GpioIrqSetMode() to modify the trigger
mode. Application samples may not rely to the availablity of this
12.4 GpioIrqSetMode() should use the same IRQ mode flags that are
defined in include/dev/irqreg.h
After registration the Interrupt defaults to NUT_IRQMODE_BOTHEDGE
12.5 If the requested interrupt is not available on that target or for
the specified pin/port, the API functions must return -1 to
indicate an error. Otherwise 0 is returned.
13 Architecture specific gpio handlers must be located in
nut/arch/[architecture] and have a special #define (TBD) in their
exported header file.
13.1 architecture specific gpio.h may be included instead of the
general gpio.h in any application that is not passed as an example
13.2 the above mentioned #define is automatically detected and may
abort compilation if the wrong platform is selected or the code was
passed to nut/app
14 In order to use this API, dev/gpio.h needs be included only.
Depending on the target, this header may include others.
14.1 The prototypes of all public API functions are:
extern uint32_t GpioPinConfigGet(int bank, int bit);
extern int GpioPinConfigSet(int bank, int bit, uint32_t flags);
extern int GpioPortConfigSet(int bank, unsigned int mask, uint32_t
extern int GpioPinGet(int bank, int bit);
extern void GpioPinSet(int bank, int bit, int value);
extern void GpioPinSetLow(int bank, int bit);
extern void GpioPinSetHigh(int bank, int bit);
extern void GpioPinDrive(int bank, int bit);
extern void GpioPinRelease(int bank, int bit);
void GpioPinToggle(int bank, int bit);
extern unsigned int GpioPortGet(int bank);
extern void GpioPortSet(int bank, unsigned int mask, unsigned int
extern void GpioPortSetLow(int bank, unsigned int mask);
extern void GpioPortSetHigh(int bank, unsigned int mask);
extern void GpioPortDrive(int bank, unsigned int mask);
extern void GpioPortRelease(int bank, unsigned int mask);
extern int GpioRegisterIrqHandler(GPIO_SIGNAL * sig, int bit, void
(*handler) (void *), void *arg);
extern int GpioIrqEnable(GPIO_SIGNAL * sig, int bit);
extern int GpioIrqDisable(GPIO_SIGNAL * sig, int bit);
extern int GpioIrqStatus(GPIO_SIGNAL * sig, int bit);
14.2. If not provided in the platform code, dev/gpio.h provides
GpioPinDrive(), GpioPinRelease(), GpioPortDrive() and
as empty macros. Platform code can have its own implementation to
allow fast switching between push/pull and tristate without
14.3. If not provided in the platform code, dev/gpio.h provides
void GpioPinToggle(int bank, int bit);
as a inlined combination of GpioPinGet() and GpioPinSet().
15. The following API extensions should be implemented platform
extern int GpioCfgAlternateFunction(int bank, int bit, int function);
extern int GpioPinConfigSetExtended(int bank, int bit, uint32_t flags);
extern int GpioPortConfigSetExtended(int bank, unsigned int mask,
extern int GpioIrqSetMode(GPIO_SIGNAL * sig, int bit, int mode);
16 Currently there are several features, mainly pin configurations, used
by code in the trunk, which is temporarily accepted.
16.1 These additional feature can be removed from the API only, if the
same patch (revision) includes alternatives for those parts using
these features. In no way it is acceptable to break any existing
code in the trunk, just to please this RFA.
Thermotemp GmbH, Embedded-IT
Embedded Hard-/ Software and Open Source Development,
Integration and Consulting
Geschäftsstelle Siegen - Steinstraße 67 - D-57072 Siegen -
tel +49 (0)271 5513597, +49 (0)271-73681 - fax +49 (0)271 736 97
Hauptsitz - Hademarscher Weg 7 - 13503 Berlin
Tel +49 (0)30 4315205 - Fax +49 (0)30 43665002
Geschäftsführer: Jörg Friedrichs, Ole Reinhardt
Handelsregister Berlin Charlottenburg HRB 45978 UstID DE 156329280
More information about the En-Nut-Discussion