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

Ole Reinhardt ole.reinhardt at embedded-it.de
Thu Oct 18 13:03:13 CEST 2012


Hi all,

First of all: Harald thank you very much for leading this discussion in
a constructive way.

Just for formalism I reject all previous RFAs and include a new version
below. This is mostly Uwes version, but cleaned up, as some parts got
messed up and extended with some of Ulrichs and my own requirements.

I fixed the chapter numbering. If any section is new or modified
compared with Uwes version is is marked as such by a line _above_ the
modified section.

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

--- Modified according to Ulrich

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

--- Modified ---
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.
----------------

--- NEW ---
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.

  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.

6.1 The bank index base is target dependent.
6.2 Bank indexes may not be consecutively numbered.
6.3 If the implementation requires a different type, this may be done by
    typecasting the integer index type.

7 The parameter bit specifies the bit within a bank and must be
  specified by an index of type int.
7.1 The bit index base is 0.
7.2 Bit indexes are consecutively numbered.

8 For port-wide operations, the parameter mask specifies the sum
  of the bitvalues (_BV()) from the bit indexes involved.

9 Functions, which set GPIO output values, are of type void.
9.1 The only way to determine the validity of a bank or related bit is
    by configuring it.

--- Sightly modified ---
10 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
------------------------

10.1 A value of 0 is returned, if the pin state is low. Any other value
     indicates a high state.
10.2 If the requested bank or bit is not available on the target, the
     function result is undefined.
10.3 With NUTDEBUG defined, is is usefull if a possible much slower
     codepath is taken that checks for parameter validity.


--- Sightly modified ---
11 The Gpio API will guarantee the following pin configuration
   capabilities for all supported targets as long as the pin supports
   this setting. 
---------------------

11.1 GPIO_CFG_INPUT to switch the pin to input mode
11.2 GPIO_CFG_OUTPUT to switch the pin to output mode
11.3 GPIO_CFG_INIT_HIGH|LOW to switch on the pin in the requested state
     when configured as output

--- Added Haralds proposal again ---
11.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.
------------------------------------

12   The Gpio API may provide the following pin configuration
     capabilities:
12.1 GPIO_CFG_PULLUP to enable the internal pull-up
12.2 GPIO_CFG_OPEN_DRAIN to enable open drain mode of an output,
     otherwise push-pull is assumed

--- Modified ---
12.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
----------------

--- NEW ---
12.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
12.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-
-----------

13 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.
13.1 After registration, interrupts are disabled.

--- Modified ---
13.2 It is expected, that interrupts are triggered on any pin change by
     default.
----------------

--- NEW ---
13.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
     function.
13.4 GpioIrqSetMode() should use the same IRQ mode flags that are
     defined in include/dev/irqreg.h
     These are:
	NUT_IRQMODE_NONE
	NUT_IRQMODE_LOWLEVEL
	NUT_IRQMODE_HIGHLEVEL
	NUT_IRQMODE_FALLINGEDGE
	NUT_IRQMODE_RISINGEDGE
	NUT_IRQMODE_EDGE
	NUT_IRQMODE_LEVEL
	NUT_IRQMODE_BOTHEDGE

    After registration the Interrupt defaults to NUT_IRQMODE_BOTHEDGE
-----------

13.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.

--- Ulrich ---
14 Architecture specific gpio handlers must be located in 
   nut/arch/[architecture] and have a special #define (TBD) in their 
   exported header file.
14.1 architecture specific gpio.h may be included instead of the
     general gpio.h in any application that is not passed as an example
     to nut/app.
14.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
--------------

15 In order to use this API, dev/gpio.h needs be included only.
   Depending on the target, this header may include others.
15.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
flags);

 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
             value);
 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);

--- NEW ---
 extern int GpioIrqStatus(GPIO_SIGNAL * sig, int bit);
-----------


15.2. If not provided in the platform code, dev/gpio.h provides
      GpioPinDrive(), GpioPinRelease(), GpioPortDrive() and 
      GpioPortRelease()
      as empty macros. Platform code can have its own implementation to
      allow fast switching between push/pull and tristate without
      calling Gpio{Pin|Port}ConfigSet() 


15.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().

--- NEW ---

16. The following API extensions should be implemented platform
specific:

Mandatory: 

 extern int GpioCfgAlternateFunction(int bank, int bit, int function);

Optional:

 extern int GpioPinConfigSetExtended(int bank, int bit, uint32_t flags);
 extern int GpioPortConfigSetExtended(int bank, unsigned int mask,
            uint32_t flags);

 extern int GpioIrqSetMode(GPIO_SIGNAL * sig, int bit, int mode);
 

-----------


17 Currently there are several features, mainly pin configurations, used
   by code in the trunk, which is temporarily accepted.
17.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.


Best regards,

Ole

-- 

Thermotemp GmbH, Embedded-IT

Embedded Hard-/ Software and Open Source Development, 
Integration and Consulting

http://www.embedded-it.de

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 mailing list