NAME | SYNOPSIS | API RESTRICTIONS | FEATURES | DESCRIPTION | EXTENDED DESCRIPTION | ATTRIBUTES | SEE ALSO
#include <ddi/gpio/gpio.h>
The function or functions documented here may not be used safely in all application contexts with all APIs provided in the ChorusOS 5.0 product.
See API(5FEA) for details.
DDI
Provides a General Purpose I/O (GPIO) interface for device driver development.
The GPIO DDI abstracts operations for a general purpose I/O port device. Such a device typically implements a number of independent I/O pins. The direction of each pin (input, output or bi-directional) and its function usually depends on the board design.
A GPIO driver allows a client to read the input pin state (raised or dropped) and to drive output pins. In addition, a GPIO driver triggers an interrupt if the state of an input pin is changed. A bi-direction pin has both (input and output) properties.
The GPIO DDI is made up of a number of entry points which may be called by GPIO device driver clients. These entry points are contained in two structures, the GpioDevOps and GpioPinOps structures. A client can obtain a pointer to the driver's GpioDevOps structure by using the svDeviceLookup and svDeviceEntry microkernel calls. The client obtains a pointer to the GpioPinOps structure by issuing a call to a pin_attach entry point.
A GPIO driver is a multi-client device driver. It allows multiple clients to independently manage a non-intersecting sets of pins. So, a GPIO device driver synchronizes concurrent accesses made to the same device from multiple clients. On the other hand, each client has to respect the GPIO driver invocation rules. In particular, a client must serialize invocations of all methods specified by the GpioDevOps structure.
typedef struct GpioDevOps { GpioVersion version; KnError (*open) (GpioId id, GpioIntrHandler handler, void* cookie, GpioConnId* cid); KnError (*pin_attach) (GpioConnId cid, void* pin, GpioPinOps** pops, GpioPinId* pid); void (*pin_detach) (GpioPinId pid); void (*mask) (GpioConnId cid); void (*unmask) (GpioConnId cid); void (*close) (GpioConnId cid); } GpioDevOps; typedef struct GpioPinOps { uint32_f (*load) (GpioPinId pid); void (*store) (GpioPinId pid, uint32_f state); } GpioPinOps;
The version field specifies the highest version number of the GPIO device driver interface supported by the driver. Currently, only one version is available and therefore the version field is always set to zero (GPIO_VERSION_INITIAL). In the future, the GPIO device driver interface may be extended so backward compatibility is guaranteed; extra methods may be added to the GpioDevOps and GpioPinOps structures but the existing methods will remain unchanged.
The open call is the first call a client must make to a GPIO device driver. It is used to establish a connection to the GPIO driver and enables use of the pin_attach, pin_detach, mask, unmask and close routines.
The id input argument is allocated by the device registry to specify the instance of a given GPIO device driver.
The handler input argument is the client interrupt handler servicing the driver. this handler is invoked each time the driver detects a change in the state of at least one of the input pins (attached to this open connection by pin_attach()) . Note that when the open() routine returns to the caller, interrupts are masked. In order to enable the interrupt handler invocation, interrupts must be implicitly unmasked by the client calling the unmask method.
The client interrupt handler may be called in the interrupt context. In this case, the API is restricted by the types of API allowed at interrupt level. In addition, the driver guarantees no re-entrance into the interrupt handler code. In other words, the driver masks interrupts for a given connection during the interrupt handler execution.
The cookie input argument specifies a client cookie which the driver will pass back (as an argument) to the client interrupt handler.
Upon successful completion, the GPIO driver returns K_OK and passes a connection identifier back to the client through the cid output argument. This identifier must be passed back to the GPIO driver as an argument for subsequent calls to its mask(), unmask(), pin_attach(), and close() methods.
Note that, to indicate that an I/O pin has been detached, the pin_detach() method uses a pin identifier (returned by pin_attach()) rather than the connection identifier.
The GPIO driver returns K_ENOMEM if the system is out of memory resources. In this case, the cid output argument is not altered.
The open() method must only be called at base level because it may block.
The pin_attach() method allows a client to logically attach GPIO resources to an open connection.
The cid input argument specifies an open connection identifier returned by open().
The PIN input argument specifies a GPIO resource attached to the connection. It points to a GPIO resource descriptor which is device specific. Typically, such a descriptor identifies a concrete pin among all pins supported by the GPIO device. Optionally, a GPIO driver may allow a client to attach a group of pins. In this case, the GPIO resource descriptor will specify a pin group. Note that the number of pins within a group is limited to 32. Pins within a group have to be enumerated from 0 up to the number of pins minus one. Pin enumeration within a group is important for GpioPinOps operations.
Upon successful completion, the driver returns K_OK and passes a pointer to the GpioPinOps structure, through the pops output argument, and a pin identifier, through the pid output argument, back to the client. The pin identifier must be passed back to the driver as an argument to answer any calls to the GpioPinOps operations (that is, load and store) and pin_detach().
The GPIO driver returns K_ENOMEM if the system is out of memory resources.
The GPIO driver returns K_EINVAL if the pin descriptor is not valid.
The GPIO driver returns K_EBUSY if a given pin (or at least one pin in the pin group) is already attached to a connection.
If an error code is returned by the driver, the pops and pid output arguments are not altered.
The pin_attach() method must only be called at base level because it may block.
The pin_detach() method is used to detach a GPIO resource that has been previously attached by the pin_attach() call.
The pid input argument, returned by pin_attach, ()specifies the pin identifier that is being detached.
Note that if an input pin is detached from a connection, the interrupt handler is no longer invoked by the driver if the pin state has changed. In other words, pin_detach() implicitly masks interrupts caused by the pin in question.
The pin_detach() method must only be called at base level because it may block.
The mask() method is called by the client to mask interrupts from all GPIO resources which are attached to a specific GPIO connection. Pins attached to other unmasked connections remain unmasked after this call.
The cid input argument specifies an open connection identifier returned by open.
When the mask() function returns to the caller, the driver guarantees that the interrupt handler will not be invoked until interrupts are unmasked again via the unmask method.
The mask() method must only be called at base level.
The unmask() method is used to enable interrupts for all of the pins which are currently attached to a given connection. Pins not attached to a given connection are not affected by this call.
The cid input argument specifies an open connection identifier returned by open.
The unmask() routine enables to driver to invoke the interrupt handler (specified in open) when the state of at least one of input pins (attached to the connection) is changed.
The unmask() method must be called at base level only.
Note that the mask/unmask pairs must not be nested.
The close() method is used to close a GPIO connection. This call should be the last call made to the GPIO driver. The client must issue a pin_detach() for each attached pin before calling the close() routine.
The cid input argument specifies an open connection identifier returned by open.
The close method must only be called at base level because it may block.
The load() method is used by the client to obtain the current state of an attached GPIO pin or pin group.
The pid input argument, returned by pin_attach(), specifies the attached GPIO resource (pin or pin group) being examined.
Note that the pin identifier and load() method have to be consistent. Otherwise, driver behavior is unpredictable. A client has to use the pin identifier and GpioPinOps structure, returned by pin_attach(), that have been issued for this particular pin (or pin group).
For a single pin, the driver returns the pin state in the 0 bit. So, 1 is returned if the pin is raised and 0 is returned if the pin is dropped. For a pin group, the state of pin N is returned in bit N. Remember that, pins have to be enumerated within a group from 0 up to the number of pins minus one. Note that the driver returns an atomic (one shot) value for a pin group.
An unpredictable value is returned for a pin which has been configured as an output only pin.
The load() method may be called at interrupt level.
The store method is used to raise or drop an attached GPIO pin or pin group.
The pid input argument, returned by pin_attach, specifies the attached GPIO resource (pin or pin group) being used.
The state input argument specifies a value to set.
Note that the pin identifier and method have to be consistent. Otherwise, the driver behavior is unpredictable. A client has to use the pin identifier and GpioPinOps structure returned by pin_attach, that have been issued for this particular pin (or pin group).
For a single pin, the driver raises the pin if the status argument is 1 and drops the pin if the status argument is 0. For a pin group, the state of pin N is specified by bit N. Remember that pins within a group have to be enumerated from 0 up to the number of pins minus one. Note that the driver changes the state of output pins of a group atomically, all in one shot.
This call is ignored for a pin which has been configured as an input only pin.
The store method may be called at interrupt level.
See attributes(5) for descriptions of the following attributes:
ATTRIBUTE TYPE | ATTRIBUTE VALUE |
---|---|
Interface Stability | Evolving |
NAME | SYNOPSIS | API RESTRICTIONS | FEATURES | DESCRIPTION | EXTENDED DESCRIPTION | ATTRIBUTES | SEE ALSO