Symbian3/PDK/Source/GUID-745273E3-BB3A-59BF-9C33-6C8BB3D850A9.dita
author Dominic Pinkman <Dominic.Pinkman@Nokia.com>
Tue, 30 Mar 2010 11:56:28 +0100
changeset 5 f345bda72bc4
parent 1 25a17d01db0c
permissions -rw-r--r--
Week 12 contribution of PDK documentation_content. See release notes for details. Fixes Bug 2054, Bug 1583, Bug 381, Bug 390, Bug 463, Bug 1897, Bug 344, Bug 1319, Bug 394, Bug 1520, Bug 1522, Bug 1892"

<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (c) 2007-2010 Nokia Corporation and/or its subsidiary(-ies) All rights reserved. -->
<!-- This component and the accompanying materials are made available under the terms of the License 
"Eclipse Public License v1.0" which accompanies this distribution, 
and is available at the URL "http://www.eclipse.org/legal/epl-v10.html". -->
<!-- Initial Contributors:
    Nokia Corporation - initial contribution.
Contributors: 
-->
<!DOCTYPE concept
  PUBLIC "-//OASIS//DTD DITA Concept//EN" "concept.dtd">
<concept id="GUID-745273E3-BB3A-59BF-9C33-6C8BB3D850A9" xml:lang="en"><title>GPIO
Design Considerations</title><shortdesc> General design considerations involved in implementing the Symbian
platform <codeph>GPIO</codeph> class.</shortdesc><prolog><metadata><keywords/></metadata></prolog><conbody>
<section id="GUID-CC35EB0E-6156-50F9-9AFC-7D89F2BE2D8A"><title>Pin IDs</title> <p>To
manipulate a GPIO interface at the level of the pin it is necessary to have
a method of specifying individual pins which is both systematic and intuitive.
For the purposes of porting we need a systematic way of identifying a pin
by its module and bit number: this means specifying the module by its register
address and the bit number by a bit mask. However, device driver writers need
a way of identifying pins which makes it obvious what function each pin serves:
this means an enumeration of human readable names of pins. The implementation
must provide a translation between the names in the enumeration and their
values, which are pairs of module addresses and pin bit numbers. This translation
should be determined at build time from values held in the Configuration Repository. </p> </section>
<section id="GUID-6342758A-C4B6-5915-944C-B5FDA43D8708"><title>Electric states
and logical states</title> <p>For the purposes of GPIO functionality a pin
is in one of two logical states, True or False. Normally the True logical
state is implemented as the High electrical state and the False logical state
as the Low electrical state. This convention is assumed in the documentation
of the Symbian platform GPIO interface. Some platforms use the opposite convention,
True == Low and False == High: this is called negative logic. If GPIO is to
be implemented on a negative logic platform, implementers must make the appropriate
translation. </p> </section>
<section id="GUID-65A90119-F6CF-5EF3-B670-4A85557462D2"><title>Pin and module
modes</title> <p>At the level of the module (and the platform) logical states
other than <codeph>True</codeph> and <codeph>False</codeph> are possible:
the module may be disabled or idle and therefore the pin may be too. These
states are called modes. A GPIO module only works if it is enabled, that is
if power and clocks are supplied to it. A module may be completely disabled
or in a partially enabled state, called idle, in which it is on low power
but some functions such as wakeups and interrupts are enabled. </p> <p>The
Symbian platform GPIO class is specified at the level of the pin and so are
the modes: a pin has three modes: <codeph>Enabled</codeph>, <codeph>Disabled</codeph> and <codeph>Idle</codeph> as
specified in the enumeration <xref href="GUID-C93C53D3-2BE8-36AE-83B8-4CDB4195649B.dita"><apiname>TGpioMode</apiname></xref>. The
mode of the pin affects the mode of the module. When a pin is set to Enabled
or Disabled mode, the implementation should set the module to the same mode.
When a pin is set to Idle, the implementation should attempt to set the module
to Idle, but the state and configuration of the other pins on the module may
override this. When a module is set to Idle the implementation should set
its pins to Idle too. </p> </section>
<section id="GUID-2BAF85D5-2E78-5A4B-A525-453F74AC6A18"><title>Idle mode and
idle state</title> <p>When a pin is in Idle mode it is in a third electrical
state, different from High and Low. This state is called <xref href="GUID-C93C53D3-2BE8-36AE-83B8-4CDB4195649B.dita"><apiname>DefaultIdleState</apiname></xref> and
does not correspond to the logical state of the pin. A pin should never be
in this state when its direction is input because input pins are always in
Enabled or Disabled mode. (A pin might theoretically be in <xref href="GUID-C93C53D3-2BE8-36AE-83B8-4CDB4195649B.dita"><apiname>DefaultIdleState</apiname></xref> because
it has never been enabled, but that would be a programming error.) However,
when a module enters the Idle state so do its pins. There are also circumstances
when it is necessary to know the electrical state of an output pin because
it cannot be deduced from the logical state. For this reason the Symbian platform <xref href="GUID-C93C53D3-2BE8-36AE-83B8-4CDB4195649B.dita"><apiname>GPIO</apiname></xref> class specifies functions to get and set the
electrical state of a pin for three values and not two: </p> <ul>
<li id="GUID-954DF6D9-0772-5239-BC71-EC31E5217AF6"><p> <xref href="GUID-C93C53D3-2BE8-36AE-83B8-4CDB4195649B.dita"><apiname>GetPinMode()</apiname></xref>  </p> </li>
<li id="GUID-9D03EDBF-D28B-5716-AB8C-EC619B3F45DF"><p> <xref href="GUID-C93C53D3-2BE8-36AE-83B8-4CDB4195649B.dita"><apiname>SetPinMode()</apiname></xref>  </p> </li>
</ul> </section>
<section id="GUID-69FFCA37-FB93-543C-8938-9AA1A49720B9"><title>Pin directions</title> <p>Pins
are used as inputs or outputs of binary signals. The Symbian platform GPIO
class does not support bidirectional pins. However, some platforms allow pins
to be in a quiescent state (also called floating or tri-stated). In this case
a pin can be in one of three logical states: True, False or quiescent as specified
in the enumeration <xref href="GUID-C93C53D3-2BE8-36AE-83B8-4CDB4195649B.dita"><apiname>TGpioDirection</apiname></xref>. The relevant
three-valued logic is specified in this table. </p> <table id="GUID-0FACE87C-4EAA-5392-A335-8706F6460EB6">
<tgroup cols="2"><colspec colname="col0"/><colspec colname="col1"/>
<thead>
<row>
<entry>Input </entry>
<entry>Output</entry>
</row>
</thead>
<tbody>
<row>
<entry><p><table id="GUID-0095FACD-4149-5743-8D73-652C3B32EA92">
<tgroup cols="2"><colspec colname="col0"/><colspec colname="col1"/>
<tbody>
<row>
<entry><p>A</p> </entry>
<entry><p>B</p> </entry>
</row>
<row>
<entry><p>0</p> </entry>
<entry><p>0</p> </entry>
</row>
<row>
<entry><p>1</p> </entry>
<entry><p>0</p> </entry>
</row>
<row>
<entry><p>0</p> </entry>
<entry><p>1</p> </entry>
</row>
<row>
<entry><p>1</p> </entry>
<entry><p>1</p> </entry>
</row>
</tbody>
</tgroup>
</table> </p> </entry>
<entry><p><table id="GUID-401A92A7-FE3F-5757-866D-3DC17BFACD39">
<tgroup cols="1"><colspec colname="col0"/>
<tbody>
<row>
<entry><p>C</p> </entry>
</row>
<row>
<entry><p>Z</p> </entry>
</row>
<row>
<entry><p>Z</p> </entry>
</row>
<row>
<entry><p>0</p> </entry>
</row>
<row>
<entry><p>1</p> </entry>
</row>
</tbody>
</tgroup>
</table> </p> </entry>
</row>
</tbody>
</tgroup>
</table> <p>The electrical states corresponding to True and False are High
and Low. The quiescent logical state is often implemented as a high impedance
electrical state. </p> </section>
<section id="GUID-5A0C6110-0EFB-5F93-8645-7C03A3579DF7"><title>Debouncing</title> <p>Debouncing
means filtering out distortions of the signal caused, for instance, by physical
pressure on a key. Some platforms provide hardware mechanisms for debouncing,
otherwise implementers must provide for debouncing by software. Both hardware
and software debouncing involve sampling the signal at a specified interval:
the Symbian platform <xref href="GUID-C93C53D3-2BE8-36AE-83B8-4CDB4195649B.dita"><apiname>GPIO</apiname></xref> class provides
a function <xref href="GUID-C93C53D3-2BE8-36AE-83B8-4CDB4195649B.dita"><apiname>SetDebounceTime()</apiname></xref> to supply that
interval but does not impose any restrictions on the implementation. Software
debouncing can be performed at the level of the pin rather than the module,
and this is strongly recommended where debouncing is performed by software. </p> </section>
<section id="GUID-8A9811B4-C0B5-5692-AF7D-8DD90C08FCF2"><title>Triggers</title> <p>A
trigger is the electrical waveform which signals an interrupt and sometimes
a wakeup. Triggers are detected either by their level (high or low) or by
their edge (rising, falling or both). When you associate an interrupt with
a trigger you must specify the type (level or edge) and then the subtype.
Some configurations of type and subtype are incompatible, for instance level
trigger with rising edge. The Symbian platform GPIO class specifies the possible
combinations in the enumeration <xref href="GUID-C93C53D3-2BE8-36AE-83B8-4CDB4195649B.dita"><apiname>TGpioDetectionTrigger</apiname></xref>.
It is for the implementation to check that a given pin supports a consistent
configuration. </p> </section>
<section id="GUID-DF6588F5-0D6C-5BFD-A098-87F69E02C449"><title>Wakeups</title> <p>One
important use of GPIO input pins is to signal a wakeup request to the CPU.
Wakeup requests will usually take place when the system is idling and clocks
are switched off. This means that the kind of trigger used to signal wakeups
must be detected asynchronously (not on a clock edge) and hence that a wakeup
trigger should probably be configured for edge detection and not level detection.
Since a wakeup is generic to the whole CPU regardless of its origin, wakeups
are usually combined into a single signal by a logical OR operation. </p> </section>
<section id="GUID-5FFB000A-6ACF-54B1-B731-93FAA12BC1E9"><title>Bias</title> <p>Many
platforms will provide programmable bias capability. This means programmable
hardware to stabilise the state of a pin to its high or low state. For input
pins the mechanism is usually a resistor: a pull-up resistor causes a pin
to default to the high state and a pull-down resistor to the low state. Output
pins may also be stablised by resistors or sometimes by a weak drive. The
Symbian platform GPIO class supports three bias modes specified in the enumeration <xref href="GUID-C93C53D3-2BE8-36AE-83B8-4CDB4195649B.dita"><apiname>TGpioBias</apiname></xref>: </p> <ul>
<li id="GUID-3B093EE2-F7E6-5317-BD6B-11EE3B190A4A"><p>pull-up, a bias to the
high state, </p> </li>
<li id="GUID-A399964E-2C3B-55C3-8198-0A78735C9207"><p>pull-down, a bias to
the low state, and </p> </li>
<li id="GUID-2741ACA5-B824-522F-88A0-D5D3036B5905"><p>no drive, an absence
of bias. </p> </li>
</ul> <p>These names refer to electrical states and are not intended to specify
the hardware mechanism used or the logical state corresponding to the electrical
state. </p> </section>
<section id="GUID-C66F5655-2444-5453-A556-DF1F947A0E45"><title>Interrupts</title> <p>A
common use for a pin is as a hardware interrupt source. The treatment of interrupts
is platform dependent. Typically, the hardware multiplexes all interrupts
from a module into a hardware controller: in this case it is part of the GPIO
implementation to demultiplex the requests. A GPIO implementation with the
capability to demultiplex will also have the capability to enable and disable
interrupts and to bind and unbind their handlers. The Symbian platform <xref href="GUID-C93C53D3-2BE8-36AE-83B8-4CDB4195649B.dita"><apiname>GPIO</apiname></xref> class specifies functions to do this: </p> <ul>
<li id="GUID-94D6091C-7BEC-51AB-A755-247801582289"><p> <xref href="GUID-C93C53D3-2BE8-36AE-83B8-4CDB4195649B.dita"><apiname>BindInterrupt()</apiname></xref>  </p> </li>
<li id="GUID-DAB9AE04-760D-5C4C-8141-01418D2360F0"><p> <xref href="GUID-C93C53D3-2BE8-36AE-83B8-4CDB4195649B.dita"><apiname>UnbindInterrupt()</apiname></xref>  </p> </li>
<li id="GUID-023E90D0-2C30-5C09-BA0B-F9779701703E"><p> <xref href="GUID-C93C53D3-2BE8-36AE-83B8-4CDB4195649B.dita"><apiname>EnableInterrupt()</apiname></xref>  </p> </li>
<li id="GUID-8F6D74ED-16A3-5C10-9BFC-7C6D0A8A6B14"><p> <xref href="GUID-C93C53D3-2BE8-36AE-83B8-4CDB4195649B.dita"><apiname>DisableInterrupt()</apiname></xref>  </p> </li>
</ul> <p>In implementing interrupt capability it is important to know whether
or not the hardware clears an interrupt source when the interrupt status has
been read. </p> <p>If it does not, there is a need for a function which explicitly
clears the source, and the Symbian platform <xref href="GUID-C93C53D3-2BE8-36AE-83B8-4CDB4195649B.dita"><apiname>GPIO</apiname></xref> class
provides one to be implemented. If it does, it is not possible to determine
whether the interrupt is still active after the clear operation. Some hardware
allows you to read the raw state of the pin, and doing so will answer that
question: other hardware does not. That is why the interface specifies two
functions to read the interrupt state, one raw and one masked: </p> <ul>
<li id="GUID-DF29D3D3-1CA6-540F-8337-7EEA10A38CCE"><p> <xref href="GUID-C93C53D3-2BE8-36AE-83B8-4CDB4195649B.dita"><apiname>GetMaskedInterruptState()</apiname></xref>  </p> </li>
<li id="GUID-74FCC2DC-2953-5D8C-BB7B-C318BB6D7B08"><p> <xref href="GUID-C93C53D3-2BE8-36AE-83B8-4CDB4195649B.dita"><apiname>GetRawInterruptState()</apiname></xref>  </p> </li>
</ul> </section>
<section id="GUID-0D3C2E2D-BCE4-5E2A-BCC9-42C64D9F5BA3"><title>Pin sharing</title> <p>There
is no general reason why a pin which is available for use for GPIO should
not also be available for some other function, and the Symbian platform GPIO
specification allows for this. There are certain circumstances where pin sharing
should be prevented, for instance when a pin is in use as an interrupt source,
and these cases are specified individually. </p> </section>
<section id="GUID-1C7F0D25-D9D6-528B-B9F5-6353DF560E03"><title>Use of the
API on-chip and off-chip</title> <p>The Symbian platform GPIO class API is
intended for use with both on-chip and off-chip modules. This is why the functions
to get and set the pin state are specified in two versions, synchronous and
asynchronous: </p> <ul>
<li id="GUID-AEE9C49A-59B3-5D30-AD58-E4216964BF62"><p> <codeph>GetInputState(TInt
aId, TGpioState&amp; aState)</codeph>  </p> </li>
<li id="GUID-7168FAB3-63A0-572F-B103-2217C256E7B7"><p> <codeph>GetInputState(TInt
aId, TGpioCallback* aCb)</codeph>  </p> </li>
<li id="GUID-3A0ABE44-D241-5FCB-928D-96EDBCB1B227"><p> <codeph>SetOutputState(TInt
aId, TGpioState aState)</codeph>  </p> </li>
<li id="GUID-38D365F2-F49A-56B4-9DD7-320FA460EA9E"><p> <codeph>SetOutputState(TInt
aId,TGpioState aState,TGpioCallback*                 aCb)</codeph>  </p> </li>
</ul> <p>When the API is used on-chip the operations execute near-instantaneously
in the context of a single calling thread. Under these circumstances it is
appropriate to use synchronous versions of the functions. </p> <p>When the
API is used off-chip the operations do not execute instantaneously, may block
and take a fast mutex, and may pass control to a different thread. Under these
circumstances it is appropriate to use asynchronous versions of the functions
using callbacks. </p> <p>It is possible to implement the API using the synchronous
versions of the functions with off-chip modules. In this case the implementation
must take care to block the client thread during the execution of the API. </p> </section>
<section id="GUID-1E838852-C9D2-50F4-9955-5371FC2AB703"><title>Preconditions
for use of the API</title> <p>The preconditions for using the API are different
when used with on-chip modules and off-chip modules. </p> <p>The preconditions
for using all functions of the API with on-chip modules are: </p> <ul>
<li id="GUID-1213783F-35E3-5A12-9071-00183C9C315A"><p>call in any context
(no preconditions). </p> </li>
</ul> <p>The preconditions for using all functions of the API with off-chip
modules are: </p> <ul>
<li id="GUID-F1443579-585F-5F51-86B7-98C12641B760"><p>kernel must be unlocked, </p> </li>
<li id="GUID-5DDC3022-D187-5940-80C0-6BA1CC7FAC7D"><p>no fast mutex must be
held, </p> </li>
<li id="GUID-FE2D9025-DE4B-5E05-A519-AC8F8F1B5018"><p>interrupts must be enabled,
and </p> </li>
<li id="GUID-A21599F7-683D-5B55-B026-EED8D719A611"><p>call must be from thread
context. </p> </li>
</ul> </section>
<section id="GUID-29CD6B92-9DC3-5839-918E-4C0C5ABC4ADC"><title>Locks</title> <p>It
is expected that the implementation of all the API functions will involve
the use of locks. In principle locks are not necessary where a function can
be implemented exclusively by a single read, write or modify call to the hardware
register API. </p> </section>
</conbody><related-links>
<link href="GUID-48AEF60B-D2B6-55B5-96FD-55C1F1868A3F.dita"><linktext>GPIO Implementation
Guide</linktext></link>
</related-links></concept>