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

Ulrich Prinz ulrich.prinz at googlemail.com
Sat Oct 20 01:33:42 CEST 2012


Accepted with, sorry, some simple minimal comments:

 > 9.3 With NUTDEBUG defined, it is usefull if a possible much slower
 > codepath is taken that checks for parameter validity.

This might get difficult if you need / like to write an atomic / thread 
safe GPIO access. But we didn't commit to provide a standardized atomic 
port or pin access function, did we?

With providing emulation drivers for all platforms, this might get a 
problem in future as these drivers may not work while NUTDEBUG is 
enabled or the timing changes if NUTDEBUG is switched.

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

Please declare this more unspecific as one big black hole in Nut/OS is 
error reporting. Please change the text to:

... the API function returns 0 in case of success, while any negative 
value reports an error. For now negative values might differ for the 
architectures and might be standardized later.

 > 12.1 After registration, interrupts are disabled.
 >
 > 12.2 It is expected, that interrupts are triggered on any pin change
 > by default.

If we expect the driver to disable interrupts on registration, why and 
how can it select the interrupt type by default? And remember platforms 
that set disable or type of interrupt in one register.

12.1 After registration, interrupts are disabled. The driver should 
return a negative value in any case the registration fails.

12.2 The type of interrupt needs to be configured by the user. 
Unsupported interrupt types will make the function return a negative 
value. If an interrupt is configured but no interrupt registration has 
been done first, a negative value is returned too, the type of interrupt 
stays disabled.

(It is easier to have a running system supporting me by finding the 
fault than bus faults urging me to connect JTAG and run GDB)


Am 19.10.2012 15:33, schrieb Ole Reinhardt:
> 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 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.
>
> 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 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 the following pin configuration
> capabilities for all supported targets as long as the pin supports
> this setting.
>
> 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
> capabilities:
>
> 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 default.
>
> 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
> function.
>
> 12.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
>
> 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 to
> nut/app.
>
> 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 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); 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
> 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()
>
>
> 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
> 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);
>
>
>
>
> 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.
>
>
> Best regards,
>
> Ole
>


More information about the En-Nut-Discussion mailing list