[En-Nut-Discussion] RFA_5: Nut/OS GPIO API
bon at elektron.ikp.physik.tu-darmstadt.de
Thu Oct 25 13:01:23 CEST 2012
The following rules apply to the Gpio API.
1 The 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
5 The parameter bank specifies the GPIO group of bits (aka. port)
must be specified by index of type gpio_bank_t.
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
6 The parameter bit specifies the bit within a bank and must be
specified by an index of type gpio_pin_t.
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 and is of
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 that the pin can be initialized
in _one_ of the following pin initial states.
10.1 GPIO_INIT_INPUT to switch the pin to input mode
10.2 GPIO_INIT_PULLUP to enable the internal pull-up. Pullup properity
is only guaranteed on a pin configured as input as long as no
action switches pin direction.
10.3 GPIO_INIT_HIGH to switch on the pin push-pull mode high
10.4 GPIO_INIT_LOW to switch on the pin push-pull mode low
10.5 GPIO_INIT_RELEASED to switch on the pin as released wired-or
or bus line with internal pullups active
10.6 If port or pin arguments are invalid, -1 is returned. If the
architecture can find out more reasons why the initial state
can not be set, -1 is returned too.
Otherwise 0 is returned. A return value of 0 is however no
guarantee that the given port/pin argument has a reachable
physical pin on the actual package of the design.
10.7. The user program must configure the pin before use. The pin
may be configured multiple times.
11 The user application may request following additional pin
11.1 GPIO_CFG_PULLUP_NONE to disable any pullup on a releases wired-or or
11.2. More abstracted configuration request aka. implementation hints may be added
later, as long as they are defined in dev/gpio.h and have a common
meaning on push/pull driven and released line. Possible additional
implementation hints are e.g. GPIO_CFG_PULLDOWN, GPIO_CFG_SLEWCTRL
or GPIO_CFG_SPEED_SLOW. Target implementation should do a best effort
to interpret and fullfill these requirements. E.g. STM32 has no pin
slew rate control and so may interpret GPIO_CFG_SLEWCTRL as
GPIO_CFG_SPEED_SLOW, LPC with no speed but slewrate control and so
may interprete GPIO_CFG_SPEED_SLOW as GPIO_CFG_SLEWCTRL.
11.3 The return values are the flags of the requested configuration with
the not implemented configuration set to one, all exact implemented
configurations masked to 0. So a return value of 0 means that all
cobfigurations are supported exact.
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.
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(gpio_bank_t bank, gpio_pin_t pin);
extern int GpioPinConfigSet(gpio_bank_t bank, gpio_pin_t pin, uint32_t flags);
extern int GpioPortConfigSet(gpio_bank_t bank, gpio_mask_t mask, uint32_t
extern int GpioPinGet(gpio_bank_t bank, gpio_pin_t pin);
extern void GpioPinSet(gpio_bank_t bank, gpio_pin_t pin, int value);
extern void GpioPinSetLow(gpio_bank_t bank, gpio_pin_t pin);
extern void GpioPinSetHigh(gpio_bank_t bank, gpio_pin_t pin);
extern void GpioPinDrive(gpio_bank_t bank, gpio_pin_t pin);
extern void GpioPinRelease(gpio_bank_t bank, gpio_pin_t pin);
void GpioPinToggle(gpio_bank_t bank, gpio_pin_t pin);
extern gpio_pin_t GpioPortGet(gpio_bank_t bank);
extern void GpioPortSet(gpio_bank_t bank, gpio_mask_t mask, unsigned int
extern void GpioPortSetLow(gpio_bank_t bank, gpio_mask_t mask);
extern void GpioPortSetHigh(gpio_bank_t bank, gpio_mask_t mask);
extern void GpioPortDrive(gpio_bank_t bank, gpio_mask_t mask);
extern void GpioPortRelease(gpio_bank_t bank, gpio_mask_t mask);
extern int GpioRegisterIrqHandler(GPIO_SIGNAL * sig, gpio_pin_t pin, void
(*handler) (void *), void *arg);
extern int GpioIrqEnable(GPIO_SIGNAL * sig, gpio_pin_t pin);
extern int GpioIrqDisable(GPIO_SIGNAL * sig, gpio_pin_t pin);
extern int GpioIrqStatus(GPIO_SIGNAL * sig, gpio_pin_t pin);
14.2. If not provided in the platform code, dev/gpio.h provides
void GpioPinToggle(gpio_bank_t bank, int bit);
as a inlined combination of GpioPinGet() and GpioPinSet().
14.3. Driving and releasing a wired-or line(s) open drain must be written
in portable code as
14.5. Driving and releasing a bus line(s) push-pull must be written in
portable code as
(more Set(..., value) commands if needed)
14.6. Other combinations may result in more state transistion on the port
pin until indented state is reached.
14.7. A compliant implementation provides "HAS_GPIO_API" in the configurator
and conf/dev/dev.nut evaluates "HAS_GPIO_API" as macro to put it as a
define into include/cfg/arch.h
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.
Uwe Bonnes bon at elektron.ikp.physik.tu-darmstadt.de
Institut fuer Kernphysik Schlossgartenstrasse 9 64289 Darmstadt
--------- Tel. 06151 162516 -------- Fax. 06151 164321 ----------
More information about the En-Nut-Discussion