Symbian3/PDK/Source/GUID-E194A923-99E7-5DC1-BB78-D050A4793A60.dita
author Graeme Price <GRAEME.PRICE@NOKIA.COM>
Fri, 15 Oct 2010 14:32:18 +0100
changeset 15 307f4279f433
parent 14 578be2adaf3e
permissions -rw-r--r--
Initial contribution of the Adaptation Documentation.

<?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-E194A923-99E7-5DC1-BB78-D050A4793A60" xml:lang="en"><title>SD Controller
PSL Implementation</title><shortdesc>Describes how to implement the Platform-Specific Layer (PSL) of
the SD controller. </shortdesc><prolog><metadata><keywords/></metadata></prolog><conbody>
<p>The SD controller derives from the MMC controller. Most of the porting
procedure is similar between the two controllers, with the addition of SD-specific
functions and behaviours. </p>
<section id="GUID-47C53B53-D9F8-5C73-8822-C685E4617CEB"><title>Prerequisites</title> <p>Porting
the SD controller for your platform requires to be familiar with the following
material: </p> <ul>
<li id="GUID-C55300E3-EE06-5B9D-BBEB-733EBF93D6C1"><p>the <xref href="http://www.sdcard.org/developers/tech/sdcard/pls/Simplified_Physical_Layer_Spec.pdf" scope="external">Physical Layer Simplified Specification Version 2.00</xref> from
the SD card association </p> </li>
<li id="GUID-F5CFD029-D90A-5769-84FD-7D142A859EA5"><p>the architecture of
the <xref href="GUID-BE6AFD38-5952-537F-848C-C76C8F5FA9BF.dita">MMC controller</xref> and
of the <xref href="GUID-114A23CF-BF8B-54F5-8AF6-FEF007891884.dita">SD controller</xref>  </p> </li>
<li id="GUID-020FEA4D-AB2B-54BA-8E07-44827657BDCF"><p>the <xref href="GUID-E55B4FE5-517C-5A23-8ACA-E28EE202330B.dita">MMC
Porting Implementation Tutorial</xref>. </p> </li>
</ul> </section>
<section id="GUID-59DA32AA-97F3-4001-9B6F-887E986C633D"><title>Source code</title> <p>The source code organization for the
MMC controller is described <xref href="GUID-40F2BC43-5022-5F4E-B445-56FEF43FEB8B.dita">here</xref>. </p> <p>The
Platform-Independent Layer (PIL) of the SD controller can be found here: <filepath>..\eka\drivers\pbus\sdcard\sdcard3c\</filepath>  </p> <p>The
suggested location for the main source file of the PSL is <filepath>..\&lt;VARIANT&gt;\specific\sdcard3c\sdstack.cpp</filepath>  </p> </section>
<section id="GUID-65BC9BCC-2C64-4E19-9AD3-D5CE8EFA0B0C"><title>Implementations</title> <p>The core class of the PSL must
derive from <xref href="GUID-3DC34D4F-E693-3BF0-B5D6-DF22FCE37340.dita"><apiname>DSDStack</apiname></xref> instead of <codeph>DMMCStack</codeph> (see
the <xref href="GUID-114A23CF-BF8B-54F5-8AF6-FEF007891884.dita#GUID-114A23CF-BF8B-54F5-8AF6-FEF007891884/GUID-0EA05AC0-557D-573F-B907-41752445DC60">SD
class diagram</xref>). In addition to the <codeph>DMMCStack</codeph> methods
described in the MMC's <xref href="GUID-E55B4FE5-517C-5A23-8ACA-E28EE202330B.dita">Platform
Specific Layer Implementation</xref>, there is an additional SD-specific abstract
virtual method to implement, and several other features to support. </p> <p>The
following functions require SD-specific porting effort: </p> <ul>
<li id="GUID-7191102F-3DA5-50F7-8996-DF1C0B98C0F7"><p><xref href="GUID-E194A923-99E7-5DC1-BB78-D050A4793A60.dita#GUID-E194A923-99E7-5DC1-BB78-D050A4793A60/GUID-32F6A273-5FEA-5495-A1FB-D2746E05052F">AddressCard()</xref> (new function) </p> </li>
<li id="GUID-F1A52C3D-47D3-5E98-B6DB-F2AF141E2847"><p><xref href="GUID-E194A923-99E7-5DC1-BB78-D050A4793A60.dita#GUID-E194A923-99E7-5DC1-BB78-D050A4793A60/GUID-A144FC39-8F93-5D47-98CF-780400AF81C1">MachineInfo()</xref> </p> </li>
<li id="GUID-7173FE72-7B23-5875-9002-9F0888A74EE8"><p><xref href="GUID-E194A923-99E7-5DC1-BB78-D050A4793A60.dita#GUID-E194A923-99E7-5DC1-BB78-D050A4793A60/GUID-87CA7CA1-C442-5B21-8CB0-FD3315D13B29">AdjustPartialRead()</xref> </p> </li>
<li id="GUID-A6CB1D2D-54AC-5A0D-A13B-01A59C2B02F4"><p><xref href="GUID-E194A923-99E7-5DC1-BB78-D050A4793A60.dita#GUID-E194A923-99E7-5DC1-BB78-D050A4793A60/GUID-C244E98F-88EB-586D-B795-1B11CAA02500">InitClockOnSM()</xref> </p> </li>
<li id="GUID-E7147D7E-39BF-5EEB-B548-9C2D0B1686BA"><p><xref href="GUID-E194A923-99E7-5DC1-BB78-D050A4793A60.dita#GUID-E194A923-99E7-5DC1-BB78-D050A4793A60/GUID-FD94E39A-EF6C-557A-A854-2A4828923307">InitClockOff()</xref> </p> </li>
<li id="GUID-E97BB330-0CB8-5761-94FD-17F070308A14"><p><xref href="GUID-E194A923-99E7-5DC1-BB78-D050A4793A60.dita#GUID-E194A923-99E7-5DC1-BB78-D050A4793A60/GUID-834CF73D-E5A3-5C11-9E1C-8CE150CBE1E0">IssueMMCCommandSM()</xref> </p> </li>
<li id="GUID-6AB865E7-AE57-58FE-B44F-EEA8B7A1384A"><p>For all the other functions,
see the MMC porting guide section describing <xref href="GUID-E55B4FE5-517C-5A23-8ACA-E28EE202330B.dita#GUID-E55B4FE5-517C-5A23-8ACA-E28EE202330B/GUID-4C6CA873-A798-5C79-8838-0CC3C9E914FB">how
to derive the DMMCStack class</xref>. </p> </li>
</ul> <p>For all the other classes (<xref href="GUID-FBCEFDB6-28FF-3201-8E13-F12E3759E36B.dita"><apiname>DMMCPsu</apiname></xref>, <xref href="GUID-2F974AD8-551B-35F0-B72C-99122913714D.dita"><apiname>DMMCMediaChange</apiname></xref>, <xref href="GUID-B1F2C60B-E098-395F-8ED0-FF33E3EC9E4A.dita"><apiname>TMMCardControllerInterface</apiname></xref>),
see the corresponding sections of the MMC's <xref href="GUID-E55B4FE5-517C-5A23-8ACA-E28EE202330B.dita">Platform
Specific Layer Implementation</xref>: <xref href="GUID-E55B4FE5-517C-5A23-8ACA-E28EE202330B.dita#GUID-E55B4FE5-517C-5A23-8ACA-E28EE202330B/GUID-3A1E907E-A74D-59CB-A1D6-FEF4849EF2D5">DMMCPsu</xref>, <xref href="GUID-E55B4FE5-517C-5A23-8ACA-E28EE202330B.dita#GUID-E55B4FE5-517C-5A23-8ACA-E28EE202330B/GUID-C80E57B1-933B-55D7-949B-E68DB9B96B94">DMMCMediaChange</xref>, <xref href="GUID-E55B4FE5-517C-5A23-8ACA-E28EE202330B.dita#GUID-E55B4FE5-517C-5A23-8ACA-E28EE202330B/GUID-7E709B21-8D38-5041-846F-CB7983B66834">TMMCardControllerInterface</xref>. </p> </section>
<section id="GUID-A8CC1E62-469C-432E-A401-AE528F6ACA63"><title>AddressCard()</title><p>The SD card protocol uses a star topology.
In a multi-card stack, it is possible to select each card socket independently
via the hardware interface, or to broadcast to all the SD cards. The MultiMediaCard
protocol relies on a bus topology, which corresponds to the broadcast mode. </p> <p>The <xref href="GUID-3DC34D4F-E693-3BF0-B5D6-DF22FCE37340.dita#GUID-3DC34D4F-E693-3BF0-B5D6-DF22FCE37340/GUID-ADD8E672-9FA6-3D12-BBB9-7D548F9C1FA9"><apiname>DSDStack::AddressCard()</apiname></xref> function
configures the hardware to select the specified card socket for future commands.
Alternatively, the <codeph>KBroadcastToAllCards</codeph> value selects the
broadcast mode. </p> <p>This function takes a <codeph>TInt</codeph> parameter
containing the number of the specified card socket. This parameter must be
between 0 and one less than the maximum number of card sockets supported,
or <codeph>KBroadcastToAllCards</codeph>. </p></section>
<section id="GUID-EF78C596-8B8A-47CB-9205-0B5373BB9A2E"><title>MachineInfo()</title><p>See <xref href="GUID-E55B4FE5-517C-5A23-8ACA-E28EE202330B.dita#GUID-E55B4FE5-517C-5A23-8ACA-E28EE202330B/GUID-CEF0EDF7-4B33-5452-8635-51C5319F78AE">DMMCStack::MachineInfo()</xref>. This function returns configuration information for the SD stack. </p> <p>By
default, the platform-independent layer configures the response type for CMD8
as R1. However, if you implement a controller for SD 2.00 cards, you should
set the <codeph>ESupportsR7</codeph> flag in the <codeph>iFlags</codeph> variable
so the stack sets the CMD8 response type as R7. </p></section>
<section id="GUID-17586EF3-F2EA-4F53-8FA6-DC81A2B2BFB4"><title>InitClockOnSM()</title><p>See <xref href="GUID-E55B4FE5-517C-5A23-8ACA-E28EE202330B.dita#GUID-E55B4FE5-517C-5A23-8ACA-E28EE202330B/GUID-C976320E-80FF-50F8-A882-F89C74F76ED3">DMMCStack::InitClockOnSM()</xref>. The function turns on the clock to the hardware interface. This clock is
always turned on at the Card Identification Mode frequency, and switched to
the Data Transfer Mode later by the <xref href="GUID-E194A923-99E7-5DC1-BB78-D050A4793A60.dita#GUID-E194A923-99E7-5DC1-BB78-D050A4793A60/GUID-FD94E39A-EF6C-557A-A854-2A4828923307">InitClockOff()</xref> function. </p> <p>The SD 2.0 Specification states that when in Card Identification
Mode, the bus clock frequency must be between 100KHz and 400KHz. This function
should enforce this frequency range. </p> <p>This function also sets the Data
Read Timeout value. The SD 2.00 Specification states this value as 100ms. </p> </section>
<section id="GUID-725B13D2-A4AF-42B1-AA3C-014206255F8B"><title>InitClockOff()</title><p>See <xref href="GUID-E55B4FE5-517C-5A23-8ACA-E28EE202330B.dita#GUID-E55B4FE5-517C-5A23-8ACA-E28EE202330B/GUID-49DF2E60-AE31-502E-B7CB-694AFAF69F1B">DMMCStack::InitClockOff()</xref>. The function switches from Card Identification Mode to Data Transfer Mode. </p> <p>Note
that for SD cards supporting it, this function should also switch to high-speed
mode with the CMD6 command. </p> <p>This function should check that the clock
rate for data transfer is below the maximum value. The SD Specifications define
this maximum as 25MHz in revision 1.01 and 50MHz in revision 1.10. The maximum
bus clock value for MultiMediaCards version 4.0+ is 52MHz. </p></section>
<section id="GUID-272B02F6-1114-4BD1-B24C-F7E78807247A"><title>AdjustPartialRead()</title><p>See <xref href="GUID-E55B4FE5-517C-5A23-8ACA-E28EE202330B.dita#GUID-E55B4FE5-517C-5A23-8ACA-E28EE202330B/GUID-A7EC6536-3822-58C8-9A65-B71FDDBA10F3">DMMCStack::AdjustPartialRead()</xref>. </p> <p>If you want your PSL to support
2GB SD cards (compliant with the Specification v1.10), you should be aware
that these cards' CSD register define the maximum block length(<codeph>READ_BL_LEN</codeph>)
as 1024 bytes, but the block length set by the CMD16 command must be 512 bytes. </p> <p>The <xref href="GUID-913FA896-4237-3E47-996F-547E325550AD.dita#GUID-913FA896-4237-3E47-996F-547E325550AD/GUID-DEFCBFC6-C69A-3339-BE6F-249E24FCB8C6"><apiname>TMMCCard::MaxReadBlLen()</apiname></xref> function
returns the maximum block length as a logarithm: for example, it returns 9
for 2GB cards, as 2^9 = 512. You should use the <codeph>MaxRedBlLen()</codeph> function
whenever the block length is needed. It is usually only appropriate in the <codeph>AdjustPartialRead()</codeph> function,
but depending on your implementation you may want to check the rest of the
platform-specific layer. </p> <p>For SD cards complying with the SD Specification
2.00 (with a capacity of 4GB and more), the <codeph>READ_BL_LEN</codeph> field
is always 512 bytes. </p></section>
<section id="GUID-30BE4D29-40FE-48EE-BCCA-3002CCFDB83D"><title>IssueMMCCommandSM()</title><p>See <xref href="GUID-E55B4FE5-517C-5A23-8ACA-E28EE202330B.dita#GUID-E55B4FE5-517C-5A23-8ACA-E28EE202330B/GUID-FABAED76-FC63-577B-9436-DC7C8978E2AE">DMMCStack::IssueMMCCommandSM()</xref> and the <xref href="GUID-E194A923-99E7-5DC1-BB78-D050A4793A60.dita#GUID-E194A923-99E7-5DC1-BB78-D050A4793A60/GUID-E9AD9B13-4691-55F0-856C-8B069A25B605">Note
on SD commands</xref> section. </p> <p>The card type is identified by the
response to the CMD55 command. If this command generates a timeout, then the
card is a MultiMediaCard; otherwise, it is an SD card. </p> <p>When receiving
the response to a <codeph>SET_BUS_WIDTH</codeph> command (ACMD6), this function
must update the configuration register by calling the <xref href="GUID-3DC34D4F-E693-3BF0-B5D6-DF22FCE37340.dita#GUID-3DC34D4F-E693-3BF0-B5D6-DF22FCE37340/GUID-2D21D20F-6275-34F1-90FD-695AF9C592B0"><apiname>DSDStack::SetBusWidth()</apiname></xref> function. </p> <p>To
comply with the SD 2.0 Specification, the <codeph>IssueMMCCommandSM()</codeph> function
must not perform the following operations: </p> <ul>
<li id="GUID-388F8C27-F7D2-5ADE-96C8-458DF0DE244C"><p>Modify the CMD55 command
and its arguments </p> </li>
<li id="GUID-45525868-632A-5E4D-8690-0F16865A559B"><p>Modify the ACMD41 command
and its arguments </p> </li>
<li id="GUID-F20C54CB-9FFE-5B6C-8E32-5CD9D69398EF"><p>Modify reserved bits
of any command argument </p> </li>
</ul></section>
<section id="GUID-E9AD9B13-4691-55F0-856C-8B069A25B605"><title>Note on SD
commands</title> <p>Most SD commands and MMC commands are compatible. However,
there are some significant differences: the table below lists some of the
additional commands supported by SD cards, and one behaviour change. </p> <table id="GUID-BA6429A3-C4D8-5CAC-889F-A9AD1ED03E37">
<tgroup cols="3"><colspec colname="col0"/><colspec colname="col1"/><colspec colname="col2"/>
<tbody>
<row>
<entry><p>Command </p> </entry>
<entry><p>Abbreviation </p> </entry>
<entry><p>Description </p> </entry>
</row>
<row>
<entry><p> <codeph>CMD3</codeph>  </p> </entry>
<entry><p> <codeph>SET_BUS_WIDTH</codeph>  </p> </entry>
<entry><p>Requests a relative address from the SD card, instead of assigning
the address to the card with this command (in the MMC case). </p> </entry>
</row>
<row>
<entry><p> <codeph>ACMD6</codeph>  </p> </entry>
<entry><p> <codeph>SET_BUS_WIDTH</codeph>  </p> </entry>
<entry><p>Defines the width of the data transfer bus. </p> </entry>
</row>
<row>
<entry><p> <codeph>ACMD13</codeph>  </p> </entry>
<entry><p> <codeph>SD_STATUS</codeph>  </p> </entry>
<entry><p>Requests the status of the addressed SD card. </p> </entry>
</row>
<row>
<entry><p> <codeph>ACMD22</codeph>  </p> </entry>
<entry><p> <codeph>SEND_NUM_WR_BLOCKS</codeph>  </p> </entry>
<entry><p>Sends/Requests the number of blocks written without error. </p> </entry>
</row>
<row>
<entry><p> <codeph>ACMD41</codeph>  </p> </entry>
<entry><p> <codeph>SD_APP_OP_COND</codeph>  </p> </entry>
<entry><p>Requests the operating conditions of the addressed SD card (equivalent
to CMD1 in the MMC case). </p> </entry>
</row>
<row>
<entry><p> <codeph>ACMD51</codeph>  </p> </entry>
<entry><p> <codeph>SEND_SCR</codeph>  </p> </entry>
<entry><p>Reads the SD configuration register (SCR). </p> </entry>
</row>
</tbody>
</tgroup>
</table> <p>The following example illustrates how to detect an ACMD6 command: </p> <codeblock id="GUID-CAA2B541-AD7D-58BF-BECB-BA5F25A00272" xml:space="preserve">if ((cmd.iSpec.iCommandClass == KMMCCmdClassApplication) &amp;&amp; (cmd.iCommand == ECmd6))
     {
         /* [...] */ 
     }
</codeblock> </section>
</conbody><related-links>
<link href="GUID-0E5A241A-19F5-5754-B454-45747A8D80E1.dita"><linktext>SD Card Overview</linktext>
</link>
<link href="GUID-114A23CF-BF8B-54F5-8AF6-FEF007891884.dita"><linktext>SD Card Controller</linktext>
</link>
</related-links></concept>