|
1 <?xml version="1.0" encoding="utf-8"?> |
|
2 <!-- Copyright (c) 2007-2010 Nokia Corporation and/or its subsidiary(-ies) All rights reserved. --> |
|
3 <!-- This component and the accompanying materials are made available under the terms of the License |
|
4 "Eclipse Public License v1.0" which accompanies this distribution, |
|
5 and is available at the URL "http://www.eclipse.org/legal/epl-v10.html". --> |
|
6 <!-- Initial Contributors: |
|
7 Nokia Corporation - initial contribution. |
|
8 Contributors: |
|
9 --> |
|
10 <!DOCTYPE concept |
|
11 PUBLIC "-//OASIS//DTD DITA Concept//EN" "concept.dtd"> |
|
12 <concept id="GUID-80E0DB93-A96A-54A8-A201-E11935418BE7" xml:lang="en"><title>State |
|
13 Machines</title><shortdesc>Description of the structure and operation of state machines.</shortdesc><prolog><metadata><keywords/></metadata></prolog><conbody> |
|
14 <p>The MultiMediaCard Controller uses state machines to manage the interactions |
|
15 with the MultiMediaCard hardware. </p> |
|
16 <p>State machines allows the controller to maintain the state of each submitted |
|
17 session – allowing it to schedule a second session when the first becomes |
|
18 blocked, for example. </p> |
|
19 <p>To handle the complex sequence of bus operations involved, the controller |
|
20 implements a state machine stack, allowing a parent state machine function |
|
21 to invoke a child state machine function. The state machine stack allows nesting |
|
22 of children down to a depth of 10 levels. </p> |
|
23 <p>Each session object has its own individual state machine stack because |
|
24 each session runs its own sequence of bus operations, with the controller |
|
25 managing these multiple sequences. This means that each session object has |
|
26 a state machine object, an instance of the <xref href="GUID-022AC0FE-86EE-3908-A9F8-4A33D04A68A5.dita"><apiname>TMMCStateMachine</apiname></xref> class. </p> |
|
27 <fig id="GUID-3CD3F1EF-FB6A-5D5D-B806-75536F8DF533"> |
|
28 <image href="GUID-4592D493-A47C-5622-8C03-F24FABB4381C_d0e19271_href.png" placement="inline"/> |
|
29 </fig> |
|
30 <p>The state machine remembers the next state and child function name, and |
|
31 moves to that state as soon as control returns to the session. </p> |
|
32 <p>The stack chooses the next session to be handled and manages the state |
|
33 machine through the state machine dispatcher. </p> |
|
34 <ul> |
|
35 <li id="GUID-76BEBC23-FC9D-5244-A3EA-2A5424FC02D7"><p> <xref href="GUID-80E0DB93-A96A-54A8-A201-E11935418BE7.dita#GUID-80E0DB93-A96A-54A8-A201-E11935418BE7/GUID-44473E52-82B4-55E7-AE85-15AC88CE5BEB">Structure of the state machine stack</xref> </p> </li> |
|
36 <li id="GUID-0A56A8B9-65D7-54CB-A584-8C3C9AEFE339"><p> <xref href="GUID-80E0DB93-A96A-54A8-A201-E11935418BE7.dita#GUID-80E0DB93-A96A-54A8-A201-E11935418BE7/GUID-E8FCFD65-4664-52EE-B658-FCABF50D501D">Structure of a state machine function</xref> </p> </li> |
|
37 <li id="GUID-85E36E04-60CD-5560-93DE-5C15E8DBDD45"><p> <xref href="GUID-80E0DB93-A96A-54A8-A201-E11935418BE7.dita#GUID-80E0DB93-A96A-54A8-A201-E11935418BE7/GUID-667C5A70-0ABB-525F-A309-58102E380400">Example of a state machine calling sequence</xref> </p> </li> |
|
38 </ul> |
|
39 <section id="GUID-44473E52-82B4-55E7-AE85-15AC88CE5BEB"><title>Structure of |
|
40 the state machine stack</title> <p>The stack itself is represented as an array |
|
41 of <xref href="GUID-DDCE8054-1656-34EF-9CBC-53C796BFD5A6.dita"><apiname>TMMCMachineStackEntry</apiname></xref> objects contained within the state |
|
42 machine object <xref href="GUID-022AC0FE-86EE-3908-A9F8-4A33D04A68A5.dita"><apiname>TMMCStateMachine</apiname></xref>. </p> <p>The state machine |
|
43 maintains a "pointer", <xref href="GUID-022AC0FE-86EE-3908-A9F8-4A33D04A68A5.dita#GUID-022AC0FE-86EE-3908-A9F8-4A33D04A68A5/GUID-5EC9B7D0-A3A9-35DF-A91D-65920372C9A4"><apiname>TMMCStateMachine::iSP</apiname></xref>, to the current |
|
44 state entry. This is not a true pointer, but just a value that indexes into |
|
45 the array. However, for all practical purposes it has the effect of a pointer. |
|
46 Each state entry in the stack is thought of as having a parent-child relationship |
|
47 with the other. </p> <p>Each state entry maintains three pieces of information: </p> <ul> |
|
48 <li id="GUID-81454E68-4603-5211-8F9F-70F0F2F4B95D"><p>A pointer to the state |
|
49 machine function. </p> </li> |
|
50 <li id="GUID-B20834EB-3EAE-5D79-8564-8B2A5490A057"><p>A variable containing |
|
51 the current state; the value and meaning of the state is defined by the state |
|
52 machine function. </p> </li> |
|
53 <li id="GUID-32AFB296-0D5F-5FF7-9ECD-C9F798E04542"><p>A bitmask of <xref href="GUID-FF4AB1CF-7A2C-3FC6-B123-D6819E1BCDCA.dita"><apiname>TMMCErr</apiname></xref> defined |
|
54 error conditions; these are set by the parent state machine function so that |
|
55 it gets the chance to trap those errors if the child state machine function |
|
56 returns those errors. Errors are propagated up the stack, and any error conditions |
|
57 not trapped at any level in the state machine hierarchy leads to the state |
|
58 machine terminating with that error value. </p> </li> |
|
59 </ul> <fig id="GUID-064C53DB-6A96-5C6D-B3CD-B40A0251EF66"> |
|
60 <image href="GUID-D8911BE6-100D-588A-8E5C-A429A72AFCDA_d0e19356_href.png" placement="inline"/> |
|
61 </fig> <p>In general, the overall state of the state machine reflects the |
|
62 state of the current state entry; for example, <xref href="GUID-E32D6BC3-F8D9-3F7E-94F6-56633B645D6A.dita#GUID-E32D6BC3-F8D9-3F7E-94F6-56633B645D6A/GUID-48F37107-2D11-3550-890B-D79844A97DBF"><apiname>TMMCStatemachine::State()</apiname></xref> returns |
|
63 the state held in the current state entry. </p> <p>While the flow of control |
|
64 through a stack can be complex, the following diagram shows a short example |
|
65 snapshot. Here, the current state in the current stack entry is <codeph>Sn</codeph> and |
|
66 is handled by the function <codeph>PF()</codeph>. The code decides to pass |
|
67 control to the child function <codeph>CF()</codeph>, but ensures that, on |
|
68 completion, the next state in the current stack entry will be <codeph>Sn+1</codeph>. </p> <fig id="GUID-6ACBC49E-14EE-526B-A1A3-426B64BF8476"> |
|
69 <image href="GUID-D2D41326-BA88-5A02-805B-5EAEC29ADB5D_d0e19383_href.png" placement="inline"/> |
|
70 </fig> <p>For example, the <xref href="GUID-B5193656-9819-3E00-A335-EEF1726115A5.dita#GUID-B5193656-9819-3E00-A335-EEF1726115A5/GUID-F71A4421-2F9E-39FD-A352-97ECAAFE822D"><apiname>DMMCStack::CIMUpdateAcqSM()</apiname></xref> function |
|
71 implements the CIM_UPDATE_ACQ macro as defined by the <i>MultiMediaCard System |
|
72 Specification</i>, and is a typical state machine function. </p> <p>Most commands |
|
73 and macros involve one or more asynchronous operations and while such operations |
|
74 are outstanding, a session is blocked. While a session is blocked, its state |
|
75 machine dispatch function is not called. As soon an asynchronous event removes |
|
76 the blocking condition, control returns to the state machine. </p> </section> |
|
77 <section id="GUID-E8FCFD65-4664-52EE-B658-FCABF50D501D"><title>Structure of |
|
78 a state machine function</title> <p>State machine functions are defined and |
|
79 implemented in the <xref href="GUID-B5193656-9819-3E00-A335-EEF1726115A5.dita"><apiname>DMMCStack</apiname></xref> class in pairs: one as a static |
|
80 function, and the other as a member function. The static variant takes a <codeph>TAny*</codeph> pointer |
|
81 that is cast to a <xref href="GUID-B5193656-9819-3E00-A335-EEF1726115A5.dita"><apiname>DMMCStack</apiname></xref> pointer, and the <codeph>DMMCStack</codeph> member |
|
82 function is then called: </p> <codeblock id="GUID-F5EEA20F-2312-5394-84C4-5E568995291A" xml:space="preserve">TMMCErr DMMCStack::FunctionNameSMST( TAny* aPtr ) |
|
83 { |
|
84 return( STATIC_CAST(DMMCStack*,aPtr)->FunctionNameSM() ); |
|
85 } |
|
86 </codeblock> <codeblock id="GUID-3C01127E-4EBA-59AC-91F8-1F004A74E45B" xml:space="preserve">TMMCErr DMMCStack::FunctionNameSM() |
|
87 { |
|
88 enum states {EStBegin=0, EStNext,…, EStEnd }; // Enumeration of states for this state machine |
|
89 DMMCSession& s = Session(); |
|
90 |
|
91 SMF_BEGIN |
|
92 // State EStBegin |
|
93 // Actions for state EStBegin |
|
94 |
|
95 SMF_STATE( EStNext ) |
|
96 // State EStNext |
|
97 // Actions for state EStNext |
|
98 |
|
99 SMF_END |
|
100 } |
|
101 </codeblock> <p>A state machine function can release control and wait to be |
|
102 re-entered by returning zero. If its session is not blocked then that will |
|
103 happen immediately. If the state machine function returns non-zero, the session |
|
104 will be completed with that error code unless the parent state machine function |
|
105 has explicitly intercepted such an error by setting the trap mask. </p> <ul> |
|
106 <li id="GUID-BEE3954A-733D-55CE-B09C-4B49304B44E1"><p> <xref href="GUID-80E0DB93-A96A-54A8-A201-E11935418BE7.dita#GUID-80E0DB93-A96A-54A8-A201-E11935418BE7/GUID-901D8456-F8D3-5E92-B3DA-EFE556D8C48B">Important points to note</xref> </p> </li> |
|
107 <li id="GUID-DA29FD1E-93EF-56C1-9650-8CE22B655897"><p> <xref href="GUID-80E0DB93-A96A-54A8-A201-E11935418BE7.dita#GUID-80E0DB93-A96A-54A8-A201-E11935418BE7/GUID-DBBA1450-AE5A-50E5-9B8C-F697CEFAD590">Blocking on an asynchronous request</xref> </p> </li> |
|
108 </ul> <p id="GUID-901D8456-F8D3-5E92-B3DA-EFE556D8C48B"><b>Important points to note</b> </p> <p>Each |
|
109 state machine function must define a list of states that can exist. States |
|
110 are defined as an enumeration whose first and last values <i>must</i> be labelled <codeph>EStBegin</codeph> and <codeph>EStEnd</codeph>, |
|
111 respectively. <codeph>EStBegin</codeph> must have the value zero. Any other |
|
112 intermediate states are program defined. </p> <p>To make the state machine |
|
113 functions more readable, a number of macros exist to help with the layout |
|
114 of the function code, and to control program flow. The most basic macros are <xref href="GUID-C095E583-3E71-31F3-B092-627357D72958.dita"><apiname>SMF_BEGIN</apiname></xref>, <xref href="GUID-38811BD9-F27C-3408-A04F-053314A2CF84.dita"><apiname>SMF_STATE</apiname></xref> and <xref href="GUID-C1089896-DD68-399C-BF34-2495C51A0CA1.dita"><apiname>SMF_END</apiname></xref> that expand into a switch statement. The above code expands |
|
115 to: </p> <codeblock id="GUID-16AE9141-5BE1-5B54-B083-7F60133DD018" xml:space="preserve">TMMCErr DMMCStack::FunctionNameSM() |
|
116 { |
|
117 enum states {EStBegin=0, EStNext,…, EStEnd }; // Enumeration of states for this state machine |
|
118 DMMCSession& s = Session(); |
|
119 |
|
120 TMMCStateMachine& m = Machine(); //SMF_BEGIN |
|
121 const TMMCErr err = m.SetExitCode( 0 ); //SMF_BEGIN |
|
122 for(;;) //SMF_BEGIN |
|
123 { //SMF_BEGIN |
|
124 switch(m.State()) //SMF_BEGIN |
|
125 { //SMF_BEGIN |
|
126 case EStBegin: //SMF_BEGIN |
|
127 { //SMF_BEGIN |
|
128 if(err) (void)0; //SMF_BEGIN |
|
129 // State EStBegin |
|
130 // Actions for state EStBegin |
|
131 |
|
132 } //SMF_STATE |
|
133 case EStNext: //SMF_STATE |
|
134 { //SMF_STATE |
|
135 // State EStNext |
|
136 // Actions for state EStNext |
|
137 |
|
138 case EStEnd: //SMF_END |
|
139 break; //SMF_END |
|
140 default: //SMF_END |
|
141 DMMCController::Panic(DMMCController::EMMCMachineState);//SMF_END |
|
142 } //SMF_END |
|
143 break; //SMF_END |
|
144 } //SMF_END |
|
145 return(m.Pop()); //SMF_END |
|
146 }</codeblock> <p>Notes: </p> <ul> |
|
147 <li id="GUID-7542D030-2641-5A15-A5AF-A02C491B24BB"><p>be aware that SMF_BEGIN |
|
148 generates an open curly bracket while SMF_STATE generates a corresponding |
|
149 close bracket, and SMF_END closes the switch statement. </p> </li> |
|
150 </ul> <p>You need to be aware of the code that is generated by these macros. |
|
151 In particular, some such as SMF_BEGIN generate an opening curly brace, while |
|
152 others such as SMF_STATE generate a corresponding close curly brace. Also, |
|
153 you need to know whether a macro generates a <codeph>break;</codeph> or a <codeph>return;</codeph> statement. |
|
154 Lack of awareness here may cause code to be generated that flows from one |
|
155 case statement to another, which may not be your intent. </p> <ul> |
|
156 <li id="GUID-7C57CF3E-0EB9-56A4-A07A-86027F5B42BA"><p> <xref href="GUID-C095E583-3E71-31F3-B092-627357D72958.dita"><apiname>SMF_BEGIN</apiname></xref> </p> </li> |
|
157 <li id="GUID-9A87EEA6-6D40-53E1-BCEE-F9A20C22D51D"><p> <xref href="GUID-C1089896-DD68-399C-BF34-2495C51A0CA1.dita"><apiname>SMF_END</apiname></xref> </p> </li> |
|
158 <li id="GUID-3ADD2CCB-4C83-54EC-80DB-3C8CFDDDCB7A"><p> <xref href="GUID-2BA7F4A7-ECB0-3839-809B-4C32D4F451BA.dita"><apiname>SMF_NEXTS</apiname></xref> </p> </li> |
|
159 <li id="GUID-41D972A7-18DE-5CE5-B0D6-039B0126199C"><p> <xref href="GUID-ACD776A5-5439-3BE9-8DD8-B537D8C2C637.dita"><apiname>SMF_CALL</apiname></xref> </p> </li> |
|
160 <li id="GUID-87C8FC8C-F810-5B3F-A7CC-99D6515F8F04"><p> <xref href="GUID-3802119E-0FC0-3B7C-9582-21563EC9AF61.dita"><apiname>SMF_CALLWAIT</apiname></xref> </p> </li> |
|
161 <li id="GUID-89669A58-5168-508A-AF9F-34C3347F0A69"><p> <xref href="GUID-2B6FA032-F8F9-3205-9CBB-EFB96691ACC9.dita"><apiname>SMF_CALLMYS</apiname></xref> </p> </li> |
|
162 <li id="GUID-A6C9952A-223E-5687-B67C-D89D50070BDB"><p> <xref href="GUID-C1D65C79-F781-3E22-AA73-F75BA2516F6F.dita"><apiname>SMF_CALLMEWR</apiname></xref> </p> </li> |
|
163 <li id="GUID-7FF0DFC9-D9DC-5E08-B668-4BC62B6E50EC"><p> <xref href="GUID-A143CA61-AA6B-3C5F-9E58-50BAF3786262.dita"><apiname>SMF_INVOKES</apiname></xref> </p> </li> |
|
164 <li id="GUID-F02BE381-0BA2-5E9D-AFB7-9064FBADC64C"><p> <xref href="GUID-A73CAEB2-2413-371E-A56F-2757C0723514.dita"><apiname>SMF_INVOKEWAITS</apiname></xref> </p> </li> |
|
165 <li id="GUID-A39E56F8-DE55-5EDE-A955-24E198026F39"><p> <xref href="GUID-94214574-2CCD-3BE4-ABD4-6A58328B29A2.dita"><apiname>SMF_WAIT</apiname></xref> </p> </li> |
|
166 <li id="GUID-1CB69F09-3BAC-5C41-B20E-5A2896C0E18E"><p> <xref href="GUID-33FBF199-09B8-32C3-BAD6-92D277722DB3.dita"><apiname>SMF_WAITS</apiname></xref> </p> </li> |
|
167 <li id="GUID-46D7BB96-3EC7-5207-BEE4-1E3ABB145D6B"><p> <xref href="GUID-B13D0665-AD49-348F-8795-67E8761B0BC8.dita"><apiname>SMF_RETURN</apiname></xref> </p> </li> |
|
168 <li id="GUID-A9A4DB91-2648-534D-BEA3-57A23147D750"><p> <xref href="GUID-2BA73A03-7379-394C-B9E8-4525316AF91F.dita"><apiname>SMF_EXIT</apiname></xref> </p> </li> |
|
169 <li id="GUID-E75E1BF0-CD8B-5EEA-98EA-13176AE0A308"><p> <xref href="GUID-57CF6330-1EA6-36A9-B2A1-2BB360B1E7FD.dita"><apiname>SMF_EXITWAIT</apiname></xref> </p> </li> |
|
170 <li id="GUID-D0617F39-4CF6-5FA7-995C-50688A82E703"><p> <xref href="GUID-6E9EF7EB-A9A2-3FA1-902D-188B4930927F.dita"><apiname>SMF_JUMP</apiname></xref> </p> </li> |
|
171 <li id="GUID-83791CBF-298A-5B5F-A9A0-8FB902AE81EB"><p> <xref href="GUID-85E63D6B-521B-309A-A1B1-18FDFCF626A0.dita"><apiname>SMF_JUMPWAIT</apiname></xref> </p> </li> |
|
172 <li id="GUID-F657F501-47AE-57D0-BEB6-A051176FC279"><p> <xref href="GUID-BF735A08-6E69-374F-8052-EF6CA101A3C3.dita"><apiname>SMF_GOTONEXTS</apiname></xref> </p> </li> |
|
173 <li id="GUID-F7D1B6D8-51A2-5C73-A709-1BB10CD27620"><p> <xref href="GUID-AA215584-34D9-36DA-A05A-8A4DF4636D5E.dita"><apiname>SMF_GOTOS</apiname></xref> </p> </li> |
|
174 <li id="GUID-042539CB-3019-57A2-B0AD-F1417756F842"><p> <xref href="GUID-38811BD9-F27C-3408-A04F-053314A2CF84.dita"><apiname>SMF_STATE</apiname></xref> </p> </li> |
|
175 <li id="GUID-ADD382E6-32C0-5773-8958-057F440C3FEC"><p> <xref href="GUID-11B9D102-4548-3321-8318-26E940273880.dita"><apiname>SMF_BPOINT</apiname></xref> </p> </li> |
|
176 </ul> <p id="GUID-DBBA1450-AE5A-50E5-9B8C-F697CEFAD590"><b> Blocking on an asynchronous |
|
177 request</b> </p> <p>The state machine can be made to block. This is done so |
|
178 that you can wait for an asynchronous operation to complete. When the operation |
|
179 completes, it unblocks the state machine. There are two stages to blocking |
|
180 a state machine: </p> <ul> |
|
181 <li id="GUID-544A1BE8-2896-5CEB-ADEB-4F63E26389C4"><p>Call <xref href="GUID-B5193656-9819-3E00-A335-EEF1726115A5.dita#GUID-B5193656-9819-3E00-A335-EEF1726115A5/GUID-E7B38752-F9AB-3A66-8FB6-E321717A63B5"><apiname>DMMCStack::BlockCurrentSession()</apiname></xref> to |
|
182 indicate that the state machine associated with the current session is to |
|
183 be blocked </p> </li> |
|
184 <li id="GUID-BDB03808-C220-5518-B0E7-232845FD0AD6"><p>Execute one of the SMF_xxxWAIT |
|
185 macros to return from the current state machine function and wait. </p> </li> |
|
186 </ul> <p>Note that the state machine function <i>must</i> return by calling |
|
187 one of the SMF_xxxWAIT macros. It must not poll or sit in a loop! The state |
|
188 machines are not threaded, and this means that CPU time can only be given |
|
189 to other tasks if the function returns. </p> <p> <xref href="GUID-B5193656-9819-3E00-A335-EEF1726115A5.dita#GUID-B5193656-9819-3E00-A335-EEF1726115A5/GUID-E7B38752-F9AB-3A66-8FB6-E321717A63B5"><apiname>DMMCStack::BlockCurrentSession()</apiname></xref> takes |
|
190 an argument describing the type of block. The state machine will only unblock |
|
191 when an unblock request with the matching argument is called. In the platform |
|
192 specific layer of the MultiMediaCard controller, you should always set the <xref href="GUID-8A9A2DD2-C630-3651-8374-17BCF2A09AC4.dita"><apiname>KMMCBlockOnASSPFunction</apiname></xref> bit |
|
193 in the argument passed to <codeph>BlockCurrentSession()</codeph>. </p> <p>To |
|
194 unblock the state machine, call <xref href="GUID-B5193656-9819-3E00-A335-EEF1726115A5.dita#GUID-B5193656-9819-3E00-A335-EEF1726115A5/GUID-E1FEFAD3-CD02-38AF-8E45-41099192D583"><apiname>DMMCStack::UnBlockCurrentSession()</apiname></xref> setting |
|
195 the <xref href="GUID-8A9A2DD2-C630-3651-8374-17BCF2A09AC4.dita"><apiname>KMMCBlockOnASSPFunction</apiname></xref> bit in the flags argument passed |
|
196 to the function, and also an error code. This will invoke the state machine |
|
197 scheduler, which will re-start the state machine. </p> <p>Note that further |
|
198 state machine processing must take place in a DFC rather than within the interrupt |
|
199 service routine (ISR), and this can be forced by ORing the session status, <xref href="GUID-0186BEDE-8E28-3F8C-8CAE-A8B92F41F47A.dita#GUID-0186BEDE-8E28-3F8C-8CAE-A8B92F41F47A/GUID-252B39FE-C203-37AD-82A4-63E9BFFD3473"><apiname>DMMCSession::iState</apiname></xref>, |
|
200 with the <xref href="GUID-5CF9ED11-2F3A-3E9B-9BFF-87DBE261F097.dita"><apiname>KMMCSessStateDoDFC</apiname></xref> bit <i>before</i> unblocking |
|
201 the session. The bit has the effect of queueing a DFC to resume the state |
|
202 machine at some later stage, before returning to the ISR. </p> <p>The following |
|
203 code shows the idea: </p> <codeblock id="GUID-C4C8C8EA-4A16-5E9C-A64D-194D7D17403C" xml:space="preserve">TMMCErr DMMCStackAssp::DoSomethingSM() |
|
204 { |
|
205 enum states {EStBegin=0, EStDone,EStEnd }; // enumeration of states for this state machine |
|
206 |
|
207 SMF_BEGIN |
|
208 // start the asynchronous operation |
|
209 BlockCurrentSession( KMMCBlockOnASSPFunction ); |
|
210 StartAsynchronousOp(); |
|
211 |
|
212 // block and wait. Go to state EStDone when the asynchronous op is complete |
|
213 SMF_WAITS( EStDone ); |
|
214 |
|
215 SMF_STATE( EStDone ) |
|
216 // operation is complete, check for errors and return from state machine |
|
217 TInt errors = CheckForHardwareErrors(); |
|
218 SMF_RETURN( errors ); |
|
219 |
|
220 SMF_END |
|
221 } |
|
222 </codeblock> <codeblock id="GUID-5CE18C2D-2780-5966-BC26-DD33D31BB5B3" xml:space="preserve">void TMMCInterrupt::Service( TAny* aParam ) |
|
223 { |
|
224 Session().iState |= KMMCSessStateDoDFC; |
|
225 UnBlockCurrentSession(KMMCBlockOnASSPFunction, KMMCErrNone); |
|
226 } |
|
227 </codeblock> </section> |
|
228 <section id="GUID-667C5A70-0ABB-525F-A309-58102E380400"><title>Example of |
|
229 a state machine calling sequence</title> <p>This shows the state machine calling |
|
230 sequence that implements the reading of a single block on a MultiMediaCard, |
|
231 where the card is not yet selected. Note that the lowest level state machine |
|
232 function called is <codeph>IssueMMCCommandSM()</codeph>, which is implemented |
|
233 by the base port. </p> <fig id="GUID-A67E1B8E-322A-5AC8-9EEA-AC24C8868E81"> |
|
234 <image href="GUID-A51C3E48-3ED0-519B-A128-C5175D7E175B_d0e19782_href.png" placement="inline"/> |
|
235 </fig> </section> |
|
236 </conbody></concept> |