Adaptation/GUID-AB9175EB-1B61-5341-B6B9-5613A7862D74.dita
changeset 15 307f4279f433
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Adaptation/GUID-AB9175EB-1B61-5341-B6B9-5613A7862D74.dita	Fri Oct 15 14:32:18 2010 +0100
@@ -0,0 +1,278 @@
+<?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-AB9175EB-1B61-5341-B6B9-5613A7862D74" xml:lang="en"><title>Channel
+Implementation</title><shortdesc>Describes how to implement <codeph>DComm</codeph> to drive a serial
+port hardware.</shortdesc><prolog><metadata><keywords/></metadata></prolog><conbody>
+<p>A physical channel defines the interface between the logical device and
+the physical device. The Serial Port Driver physical channel interface is
+defined by the <codeph>DComm</codeph> class. </p>
+<p>The <codeph>DComm</codeph> class is defined in: <filepath>...\e32\include\drivers\comm.h</filepath>,
+which is exported to <filepath>epoc32\include\drivers</filepath>: </p>
+<codeblock id="GUID-F9E58262-51AA-5A58-A113-3FA994F00156" xml:space="preserve">class DComm : public DBase
+    {
+public:
+    virtual TInt Start() =0;
+    virtual void Stop(TStopMode aMode) =0;
+    virtual void Break(TBool aState) =0;
+    virtual void EnableTransmit() =0;
+    virtual TUint Signals() const =0;
+    virtual void SetSignals(TUint aSetMask,TUint aClearMask) =0;
+    virtual TInt ValidateConfig(const TCommConfigV01 &amp;aConfig) const =0;
+    virtual void Configure(TCommConfigV01 &amp;aConfig) =0;
+    virtual void Caps(TDes8 &amp;aCaps) const =0;
+    virtual void CheckConfig(TCommConfigV01&amp; aConfig)=0;
+    virtual TInt DisableIrqs()=0;
+    virtual void RestoreIrqs(TInt aIrq)=0;
+    virtual TDfcQue* DfcQ(TInt aUnit)=0;
+    inline TBool PowerGood(); 
+    inline void SetCurrent(TInt aCurrent);
+    inline void ReceiveIsr(TUint* aChar, TInt aCount, TInt aXonXoff);
+    inline TInt TransmitIsr();inline void CheckTxBuffer();
+    inline void StateIsr(TUint aSignals);
+    inline TBool Transmitting();
+public:
+    DChannelComm *iLdd;
+    TBool iTransmitting;
+    };
+</codeblock>
+<p>Note that <codeph>DComm</codeph> defines the minimum set of functions to
+be used by the LDD. A real physical channel object, typically, requires the
+addition of an interrupt handler, some DFC callback routines (if these are
+not handled in the LDD itself) and various other state variables. </p>
+<section id="GUID-B0D61B54-EDF3-4804-9B1E-370C36E01708"><title>DCommVariant constructor</title> <p>Implement the constructor
+for the channel object. Since there is no unit number argument, the constructor
+is limited to initialising only those members that are common across all possible
+channels, with no access to any specific hardware. </p> </section>
+<section id="GUID-550681C3-F1A6-4298-BAA5-C6F2D9D61624"><title>DCommVariant destructor</title> <p>Implement the destructor
+for the channel object. It should release any hardware and Symbian platform
+resources that have been allocated to the driver, typically unbinding the
+UART interrupt ISR, and any private DFCs that are still in use. The destructor
+merely unbinds the interrupt as no channel specific DFCs are active at destructor
+invocation. </p> </section>
+<section id="GUID-8254536B-E938-4B86-A735-798DD03E3456"><title>DoCreate()</title> <p>Implement the <codeph>DoCreate()</codeph> channel
+initialisation function for the UART driver. In general, defining a <codeph>DoCreate()</codeph> function
+is not mandated by the device driver framework but is useful for drivers that
+make use of unit numbers. This is called by the factory object’s <xref href="GUID-6DE69F29-45B0-5E62-AA13-DA4041B1BC46.dita#GUID-6DE69F29-45B0-5E62-AA13-DA4041B1BC46/GUID-48EF94F9-ACBC-58DA-9F0E-4034E56C6C74">Create()</xref> function after the device object’s allocation has succeeded. </p> <p>Typical
+operations performed by this function are to setup any channel specific hardware
+states and bind the driver’s ISR to the (possibly channel specific) interrupt
+channel, as well as enabling the UART hardware itself. However, since the <xref href="GUID-AB9175EB-1B61-5341-B6B9-5613A7862D74.dita#GUID-AB9175EB-1B61-5341-B6B9-5613A7862D74/GUID-0CAA6D27-FE2E-5569-8747-EB3D4976E7FD">Start()</xref> function
+has not yet been called, it should not enable the UART interrupts/poll routines
+which would actively buffer incoming data; any data I/O requests should be
+discarded until the driver’s <xref href="GUID-AB9175EB-1B61-5341-B6B9-5613A7862D74.dita#GUID-AB9175EB-1B61-5341-B6B9-5613A7862D74/GUID-0CAA6D27-FE2E-5569-8747-EB3D4976E7FD">Start()</xref> routine
+has been called. </p> </section>
+<section id="GUID-0CAA6D27-FE2E-5569-8747-EB3D4976E7FD"><title>Start()</title> <p> Implement
+the <codeph>Start()</codeph> function. This should enable the driver’s receive
+path.</p><p> Received characters are placed in the LDD upstream buffer, either
+by the interrupt handler routine, or by a polling routine that tests for the
+existence of received characters (and their associated error state). This
+is done by calling the LDD’s <codeph>ReceiveIsr()</codeph> routine, with a
+pointer to the buffered characters, a count and a flag indicating whether
+the XON or XOFF flow control characters have been received.</p><p>The function
+is called by the LDD when the owning thread opens the device channel. It should
+complete any UART data I/O enabling that has not already been performed in
+the <codeph>DoCreate()</codeph> function, i.e. the enabling of UART receive
+interrupt processing as a minimum. After this function returns, it is expected
+that incoming data will be placed in a (local) buffer and passed upstream
+to the LDD, until <xref href="GUID-AB9175EB-1B61-5341-B6B9-5613A7862D74.dita#GUID-AB9175EB-1B61-5341-B6B9-5613A7862D74/GUID-9428082D-581D-530B-8838-1DBF6D0EB8E7">Stop()</xref> is
+invoked. Note that since there may have been line activity prior to this call,
+it may be necessary to reset the UART state, as we do not want to report errors/states
+that may have occurred before the UART was (logically) enabled.</p></section>
+<section id="GUID-9428082D-581D-530B-8838-1DBF6D0EB8E7"><title>Stop()</title><p>Implement
+the <codeph>Stop()</codeph> function. This should disable the driver’s transmit
+and receive paths. </p><p>Depending on the type of stop requested, i.e. emergency
+power down, or otherwise, <codeph>Stop()</codeph> may not wait for the UART
+to finish transmitting any characters stored in the transmit FIFO queue. All
+receive paths are stopped instantly and any characters that may be in the
+receive FIFO queue are ignored. </p><p>The function is called by the LDD when
+the owning thread closes the device channel. At this point, the UART device
+should revert to the state in which all data I/O requests are ignored or failed.
+To save OS resources the natural method to accomplish this is to disable the
+UART interrupt processing or disable the UART itself. It may also be necessary
+to cancel any DFCs queued, so that event notifications are not sent to the
+LDD after it has requested an end to I/O. </p></section>
+<section id="GUID-5E4B6533-75F5-47FB-A4DF-55FAA1E1B973"><title>DfcQ()</title><p>Implement the <codeph>DfcQ()</codeph> function.
+This should return the DFC queue on which the LDD will install its DFCs. Usually
+the standard low priority kernel DFC queue 0 is returned. </p></section>
+<section id="GUID-ADC89B5B-0E29-4723-92E6-A6F1A5604710"><title>Break()</title><p>Implement the <codeph>Break()</codeph> function.
+This starts or ends a BREAK condition on the wire. </p><p>This operation is
+explicitly requested by the owning thread through the LDD. A break state requires
+the forcing of the line into an abnormal state, which violates standard data
+format timings (a form of out of band signalling), and is detected by the
+remote device and is usually used to force it to cycle through its baud rate
+detection modes. Forcing a break state requires that the PDD explicitly set
+some state in the UART hardware. </p></section>
+<section id="GUID-82A259A7-54F7-536A-B829-31C0AF3C5C81"><title>Signals()</title><p>Implement
+the <codeph>Signals()</codeph> function. This returns the state of the flow
+and MODEM control inputs, ie. DCD, DSR, CTS and RI (if implemented on the
+device itself). This function is called by the LDD to return the state of
+all the handshaking lines so that it can decide whether further data I/O operations
+are allowed. </p></section>
+<section id="GUID-492D86E5-BEEF-4408-B6E0-6DDA1244CA74"><title>SetSignals()</title><p>Implement the <codeph>SetSignals()</codeph> function.
+This controls the state of the flow and MODEM control outputs. It is used
+by the LDD to control MODEM handshaking and line failure detection, and can
+be invoked in response to a specific user request to change the handshake
+signal’s state, or when the LDD itself decides that the output lines states
+should be changed in response to some transfer state (e.g. requesting no further
+transmissions if buffer availability runs low). </p></section>
+<section id="GUID-CB1FA26C-5D29-50ED-AF40-8CC579AF776F"><title>Caps()</title><p>Implement
+the <codeph>Caps()</codeph> function. This returns the driver supported configurations:
+speed, format, and handshaking. </p><p>It is called by the LDD in response
+to a user request for the device's capabilities. The PDD must fill a <xref href="GUID-98A18771-CA6D-3B68-8784-449CDBEC3D88.dita"><apiname>TCommCapsV02</apiname></xref> object,
+with the capabilities for that port. </p><p>The object is defined in <filepath>d32comm.h</filepath>: </p><codeblock id="GUID-A95D8753-E574-5C86-85DC-6AA10F635612" xml:space="preserve">class TCommCapsV01
+    {
+public:
+    TUint iRate;
+    TUint iDataBits;
+    TUint iStopBits;
+    TUint iParity;
+    TUint iHandshake;
+    TUint iSignals;
+    TUint iFifo;
+    TUint iSIR;
+    };
+
+class TCommCapsV02 : public TCommCapsV01
+    {
+public:
+    TUint iNotificationCaps;
+    TUint iRoleCaps;
+    TUint iFlowControlCaps;
+    };</codeblock> <p>The base object, <xref href="GUID-BDBB61A7-18BC-3C85-A258-77D8B16621AD.dita"><apiname>TCommCapsV01</apiname></xref>, defines
+capabilities in terms of: </p> <ul>
+<li id="GUID-7AE03D23-1013-5522-B219-23153E1B7798"><p>data rate </p> </li>
+<li id="GUID-E2FBD4C1-B704-592A-B3A2-1BCFFC7E5451"><p>word format (i.e. parity,
+data bits, stop bits) </p> </li>
+<li id="GUID-525050DD-8ACE-5580-BDF7-3717295D704E"><p>flow control lines </p> </li>
+<li id="GUID-B5DBE4E6-8184-522A-856A-9BD17E76FF33"><p>MODEM control lines </p> </li>
+<li id="GUID-62ACC296-4B9B-59D3-8531-480E04264FE0"><p>IrDA support. </p> </li>
+</ul> <p>Each attribute range is passed as a bitfield of possible settings,
+all assumed to be orthogonal, i.e. each attribute can assume all the values
+independently of the other attributes. </p> <p>The attribute bitfields are
+defined in <filepath>d32comm.h</filepath>. </p> <p>The <codeph>iSIR</codeph> attribute
+in <xref href="GUID-BDBB61A7-18BC-3C85-A258-77D8B16621AD.dita"><apiname>TCommCapsV01</apiname></xref> indicates whether the port can support
+slow infrared protocol. </p> <p>The <codeph>iNotificationCaps</codeph> attribute
+in <xref href="GUID-98A18771-CA6D-3B68-8784-449CDBEC3D88.dita"><apiname>TCommCapsV02</apiname></xref> allows the driver to describe its ability
+to report asynchronous events, if requested to do so by the client thread.
+The only useful applications seem to be to report data arrival and handshake
+line status change, although fields exist for other capabilities. </p> <p>The <codeph>iRoleCaps</codeph> attribute
+in <xref href="GUID-98A18771-CA6D-3B68-8784-449CDBEC3D88.dita"><apiname>TCommCapsV02</apiname></xref> is intended to indicate that the device
+is capable of acting as a DCE as well as a DTE, i.e. that the port can be
+configured to act like a MODEM port. This essentially reverses the normal
+I/O of the status lines, and could add functionality such as ring indication.
+Normal UART devices will never need to change this field from the default,
+i.e. DTE device personality. </p> <p>The <codeph>iFlowControlCaps</codeph> field
+in <xref href="GUID-98A18771-CA6D-3B68-8784-449CDBEC3D88.dita"><apiname>TCommCapsV02</apiname></xref> is unused and should be set to 0. </p> <p>The <codeph>iHandshake</codeph> field
+in <xref href="GUID-BDBB61A7-18BC-3C85-A258-77D8B16621AD.dita"><apiname>TCommCapsV01</apiname></xref> describes the flow control signal support
+on the device. Input signals have attributes “Obey” and “Fail” e.g. ObeyCts,
+FailCts. Output signals have only the “Free” attribute, which indicates they
+can be driven (via a call to <xref href="GUID-AB9175EB-1B61-5341-B6B9-5613A7862D74.dita#GUID-AB9175EB-1B61-5341-B6B9-5613A7862D74/GUID-82A259A7-54F7-536A-B829-31C0AF3C5C81">Signals()</xref>)
+to any state, independent of the internal state of the UART, i.e. they are
+entirely under LDD control. The Fail attribute implies that the LDD will deem
+operations to have failed if an input line thus labelled becomes disasserted.
+This means that the PDD can report these signal states asynchronously. If,
+for example, a change in CTS state can generate an interrupt, then the PDD
+should report it as possessing both Obey and Fail attributes, whereas if the
+DCD line cannot generate an asynchronous event, it should merely present itself
+as “Obey”. If the line is unimplemented then neither attribute should be reported. </p> </section>
+<section id="GUID-DA860E4A-4240-4C16-B1C0-5E9B7C96F9E8"><title>Configure()</title> <p>Implement the <codeph>Configure()</codeph> function.
+This configures the UART device according to the configuration data passed
+into the function. </p> <p>Configuration data is encapsulated by a <xref href="GUID-0CBAE946-AB8E-3114-89FC-9591125C4BDC.dita"><apiname>TCommConfigV02</apiname></xref> object: </p> <codeblock id="GUID-275DAD25-9EF9-5084-A82B-8E2392CB14E8" xml:space="preserve">class TCommConfigV01
+    {
+public:
+    TBps iRate;
+    TDataBits iDataBits;
+    TStopBits iStopBits;
+    TParity iParity;
+    TUint iHandshake;
+    TUint iParityError;
+    TUint iFifo;
+    TInt iSpecialRate;
+    TInt iTerminatorCount;
+    TText8 iTerminator[KConfigMaxTerminators];
+    TText8 iXonChar;
+    TText8 iXoffChar;
+    TText8 iParityErrorChar;
+    TSir iSIREnable;
+    TUint iSIRSettings;
+    };
+
+class TCommConfigV02: public TCommConfigV01
+    {
+public:
+    TInt iTxShutdownTimeout;
+    };
+</codeblock> <p>This function is called by the LDD when the physical channel
+is opened. The default configuration is set by the LDD when the <codeph>Dcomm</codeph> object
+is constructed, but the user can override the configuration with a <codeph>SetConfig</codeph> request
+on the opened channel. The configuration is described by specifying a set
+of individual capability attributes from the supported ranges returned in
+the <xref href="GUID-AB9175EB-1B61-5341-B6B9-5613A7862D74.dita#GUID-AB9175EB-1B61-5341-B6B9-5613A7862D74/GUID-CB1FA26C-5D29-50ED-AF40-8CC579AF776F">Caps()</xref> call. </p> <p>Note
+that the <codeph>iTerminatorCount</codeph>, the <codeph>iTerminatorArray</codeph> and<codeph> iSpecialRate</codeph> are
+currently unused. The <codeph>iParityErrorChar</codeph> replaces the character
+that the UART determined had a parity violation. This can be used to send
+a prearranged escape character to the upstream LDD. </p> </section>
+<section id="GUID-509C63E0-09D9-48F1-8ECB-F18377B73E8A"><title>CheckConfig()</title> <p>Implement the <codeph>CheckConfig()</codeph> function.
+This is used by autosensing UARTs to pass detected configuration upstream
+to the LDD. This is called by the LDD when it creates the initial channel
+to allow the autosensed state to override any default it has set. If the UART
+device cannot perform autosensing, and most cannot, then the <codeph>CheckConfig()</codeph> function
+should leave the parameter buffer unchanged. </p> </section>
+<section id="GUID-6F26F95A-7115-4E07-BA72-7AEF75DC2912"><title>ValidateConfig()</title> <p>Implement the <codeph>ValidateConfig()</codeph> function.
+This returns true if the specified configuration is supported by the driver.
+This should never return false if the correct capabilities have been setup,
+but may be used to check for cases where, for example, a specific set of attributes
+cannot be applied together. As an example, a data format word size may not
+be generated for some specific baud rate. </p> </section>
+<section id="GUID-10FB213C-47B3-4CFF-AB2B-5868AE4531E0"><title>DisableIrqs()</title> <p>Implement the <codeph>DisableIrqs()</codeph> function.
+This is called by the LDD to disable (all) interrupts during critical sections,
+for example, during LDD buffer manipulation. It calls the kernel utility to
+perform the task. </p> </section>
+<section id="GUID-BFE0DF32-3D2A-4D86-8BEE-6EB5AF32C3BB"><title>RestoreIrqs()</title> <p>Implement the <codeph>RestoreIrqs()</codeph> function,
+called by the LDD to enable (all) interrupts after critical sections have
+completed. Calls the kernel utility to perform the task. </p> </section>
+<section id="GUID-96B9D6FE-1E2C-45C0-B7F4-E5CF9B5BD802"><title>EnableTransmit()</title> <p>Implement the <codeph>EnableTransmit()</codeph> function.
+This initialises the UART transmit hardware, and the transmit ISR code path.
+This function can be called from the ISR (on receipt of an unblocking XON
+character), or to start a transmission of a LDD originated data buffer. It
+causes the UART to generate Tx service interrupts as it finishes transmitting
+a FIFOs worth of data, so that the entire buffer (passed by the LDD) can be
+sent under interrupt control. </p> </section>
+<section id="GUID-593C5E94-A188-48C4-BB02-07268735270A"><title>Data handling routines</title> <p>Implement the main data
+handling routines. These are entirely dependent on the UART hardware interface
+and cannot therefore be described generally. They are typically driven by
+the interrupt service routine as asynchronous events from the UART (eg. data
+received, finished transmission of data, change in handshaking/flow control
+inputs) occur. </p> <p>The main ISR is typically driven by an interrupt multiplexed
+from all the sources in the UART. The ISR, therefore, needs to determine which
+of the interrupt sources requires attention. Since the most critical source
+is the data received state, as this requires that the data is processed before
+following data overwrites earlier data, then this is usually the signal to
+be checked first. To avoid wasting time, the error state of the data is also
+checked – data that has bad parity or framing must be noted as such. Typically
+the receive path will save the currently available data into a temporary buffer,
+and queue a DFC to process the data further at a later time, when more client
+thread context is available (though this is a function of the LDD). The receive
+ISRr just passes the location of the ISR buffer into an LDD function which
+queues a DFC to process it. </p> <p>The transmit path, called when the transmit
+FIFO contents drop below a programmable number, merely requests more data
+from the LDD. If there is none available it disables the transmit interrupt
+so as to prevent further requests when there is no data to be sent. Further
+data to transmit will cause the transmit FIFO empty interrupt to be re-enabled.
+Hence the start of any transmission is always performed on an explicit start
+request from the LDD and then continues under PDD interrupt control until
+the source data is exhausted. </p> <p>The status notification path is present
+to inform the upstream LDD of changes in the input status signals (MODEM and
+flow control status). The UART can generate interrupts when any input handshake
+line changes state – the ISR merely reads the current state and queues a handler
+DFC so that the LDD can be informed. The LDD is responsible for determining
+what status change has occurred and dealing with it. </p> </section>
+</conbody></concept>
\ No newline at end of file