GPIO

API Reference
GPIO sample app


This API is used by apps to control general-purpose digital input/output pins.

A GPIO pin typically has one or more of the following features:

  • configured as an input pin or an output pin.
  • have an internal pull-up resistor or pull-down resistor enabled, or neither.
  • if an output, can be push-pull or open-drain.
  • if an input, can trigger an interrupt (asynchronous notification of state change).

Output pins can be driven in three modes:

  • push-pull one transistor connects to the supply and another transistor connects to ground (only one is operated at a time).
  • tri-state same as push-pull with an added high-impedance (high Z) state to disconnect pin from both ground and supply.
  • open drain transistor connects only to ground. Can only be used to pull low.

Pins also have a polarity mode:

  • active-high polarity pin is read/written as a digital 1 (true) when its voltage is "high" and 0 (false) when its voltage is "low" (grounded).
  • active-low pin is read/written as a digital 1 (true) when its voltage is "low" (grounded) and 0 (false) when its voltage is "high".

The following functions are used to configure the GPIO pin:

  • SetInput() - Configure as an input pin.
  • SetPushPullOutput() - Configure as push-pull output pin (can drive high or low).
  • SetTriStateOutput() - Configure as tri-state output pin (can drive high or low or neither).
  • SetOpenDrainOutput() - Configure as open-drain output pin (only pulls low).
  • EnablePullUp() - Enables the internal pull-up resistor (and disables the pull-down).
  • EnablePullDown() - Enables the internal pull-down resistor (and disables the pull-up).
  • DisableResistors() - Disables the internal pull-up/down resistors.
  • SetEdgeSense() - Set the edge sensing on an input pin (only works if you have an EventHandler).

To set the level of an output pin, call Activate(), Deactivate(), or SetHighZ().

To poll the value of an input pin, call Read().

Use the ChangeEvent to register a notification callback function to be called when the state of an input pin changes. Thje type of edge detection can then be modified by calling SetEdgeSense() or DisableEdgeSense()

Note
The client will be killed for below scenarios:
  • Only one handler can be registered per pin. Subsequent attempts to register a handler will result in the client being killed.
  • If the GPIO object reference is NULL or not initialized.
  • When unable to set edge detection correctly.

The following functions can be used to read the current setting for a GPIO Pin. In a Linux environment these values are read from the sysfs and reflect the actual value at the time the function is called.

  • IsOutput() - Is the pin currently an output?
  • IsInput() - Is the pin currently an input?
  • IsActive() - Is an output pin currently being driven? (corresponds to the value file in sysfs)
  • GetPolarity() - Retrieve the current polarity (active-low or active-high)
  • GetEdgeSense() - What edge sensing has been enabled on an input pin?
  • GetPullUpDown() - What pull-up or pull-down has been enabled?

Each GPIO pin is accessed through a single IPC service. This makes it possible to use bindings to control which GPIO pins each app is allowed to access. It also simplifies the API by removing the need to specify which pin is desired and allows the pins to be named differently in the client and the server, so the client can be more portable. Only one client can connect to each pin.

Using the GPIOs in a thread

Each GPIO pin can be accessed in a thread. APIs le_gpioPinXX_ConnectService or le_gpioPinXXTryConnectService need to be called to connect the GPIOXX to the GPIO service APIs in a thread. Normally, the ConnectService is automatically called for the main thread.

Once the GPIOXX is used, it cannot be accessed by another thread. When no longer used, it can be relinquished by calling API le_gpioPinXX_DisconnectService. The GPIO service for GPIOXX will be disconnected leaving the GPIOXX free to be used by another thread.

Warning
In order to use the GPIO service for GPIOXX in a thread, API le_gpioPinXX_DisconnectService must explicitly be called previously in the main thread.

Using Bindings

To create a binding from your app to pin 22 of the GPIO service, add something like this to your .adef binding section:

bindings:
{
    ui.frontPanel.powerLed -> gpioService.le_gpio22
}

This connects your component called frontPanel to the instance of this API that can be used to drive GPIO 22. Setting the pin high looks like this:

{
// Configure the output type
powerLed_SetPushPullOutput(LE_GPIOPIN22_ACTIVE_HIGH, false);
 
// Some time later ... set the GPIO high
powerLed_Activate();
}

For details on how the GPIOs exposed by this service map to a CF3 module (like the WP85), see GPIO sample app.

Configuring available GPIOs

The GPIOs that are available for use are advertised in the sysfs at

/sys/class/gpio/gpiochip1/mask 

For each entry in this bitmask, a service will be advertised to allow use of the pin. However, if a pin needs to be disabled form being accessed, e.g. it carries out some system function that should not be available to apps, then it can be disabled by adding an entry to the config tree.

For example, to disable pin 6 from being used, add the entry

gpioService:/pins/disabled/n 

where n is the GPIO number. The value should be set to true to disable that service. If the value is either false or absent then the service will run. Entries can be added using the config tool, for example *

config set gpioService:/pins/disabled/13 true bool

will disable the service for pin 13. Note that specifying the type as bool is vital as the config tool defaults to the string type, and hence any value set will default to false.