[En-Nut-Discussion] RFA_5: Nut/OS GPIO API

Uwe Bonnes 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
  in nut/arch.

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
  a purpose.

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
  type gpio_mask_t

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
  type int

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
     bus line.

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
     These are:

    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 (deleted)

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
      ...Set(..., value)
      (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 mailing list