|
1 // Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). |
|
2 // All rights reserved. |
|
3 // This component and the accompanying materials are made available |
|
4 // under the terms of the License "Eclipse Public License v1.0" |
|
5 // which accompanies this distribution, and is available |
|
6 // at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
7 // |
|
8 // Initial Contributors: |
|
9 // Nokia Corporation - initial contribution. |
|
10 // |
|
11 // Contributors: |
|
12 // |
|
13 // Description: |
|
14 // e32test/iic/iic_psl/spi.cpp |
|
15 // |
|
16 #include "spi.h" |
|
17 |
|
18 #ifdef IIC_INSTRUMENTATION_MACRO |
|
19 #include <drivers/iic_trace.h> |
|
20 #endif |
|
21 |
|
22 #define NUM_CHANNELS 4 // Arbitrary |
|
23 |
|
24 // Macros to be updated(?) with interaction with Configuration Repository |
|
25 const TInt KChannelTypeArray[NUM_CHANNELS] = {DIicBusChannel::EMaster, DIicBusChannel::EMaster, DIicBusChannel::ESlave, DIicBusChannel::EMaster}; |
|
26 #define CHANNEL_TYPE(n) (KChannelTypeArray[n]) |
|
27 const DIicBusChannel::TChannelDuplex KChannelDuplexArray[NUM_CHANNELS] = {DIicBusChannel::EHalfDuplex, DIicBusChannel::EHalfDuplex, DIicBusChannel::EHalfDuplex, DIicBusChannel::EFullDuplex}; |
|
28 #define CHANNEL_DUPLEX(n) (KChannelDuplexArray[n]) |
|
29 |
|
30 #ifdef LOG_SPI |
|
31 #define SPI_PRINT(str) Kern::Printf str |
|
32 #else |
|
33 #define SPI_PRINT(str) |
|
34 #endif |
|
35 |
|
36 _LIT(KSpiThreadName,"SpiChannelThread"); |
|
37 |
|
38 const TInt KSpiThreadPriority = 5; // Arbitrary, can be 0-7, 7 highest |
|
39 |
|
40 #ifdef STANDALONE_CHANNEL |
|
41 _LIT(KPddNameSpi,"spi_ctrless.pdd"); |
|
42 #else |
|
43 _LIT(KPddNameSpi,"spi.pdd"); |
|
44 #endif |
|
45 |
|
46 #ifndef STANDALONE_CHANNEL |
|
47 LOCAL_C TInt8 AssignChanNum() |
|
48 { |
|
49 static TInt8 iBaseChanNum = KSpiChannelNumBase; |
|
50 SPI_PRINT(("SPI AssignChanNum - on entry, iBaseCanNum = 0x%x\n",iBaseChanNum)); |
|
51 return iBaseChanNum++; // Arbitrary, for illustration |
|
52 } |
|
53 #endif |
|
54 |
|
55 NONSHARABLE_CLASS(DSimulatedSpiDevice) : public DPhysicalDevice |
|
56 { |
|
57 // Class to faciliate loading of the IIC classes |
|
58 public: |
|
59 class TCaps |
|
60 { |
|
61 public: |
|
62 TVersion iVersion; |
|
63 }; |
|
64 public: |
|
65 DSimulatedSpiDevice(); |
|
66 virtual TInt Install(); |
|
67 virtual TInt Create(DBase*& aChannel, TInt aUnit, const TDesC8* anInfo, const TVersion& aVer); |
|
68 virtual TInt Validate(TInt aUnit, const TDesC8* anInfo, const TVersion& aVer); |
|
69 virtual void GetCaps(TDes8& aDes) const; |
|
70 inline static TVersion VersionRequired(); |
|
71 }; |
|
72 |
|
73 TVersion DSimulatedSpiDevice::VersionRequired() |
|
74 { |
|
75 SPI_PRINT(("DSimulatedSpiDevice::VersionRequired\n")); |
|
76 return TVersion(KIicClientMajorVersionNumber,KIicClientMinorVersionNumber,KIicClientBuildVersionNumber); |
|
77 } |
|
78 |
|
79 /** Factory class constructor */ |
|
80 DSimulatedSpiDevice::DSimulatedSpiDevice() |
|
81 { |
|
82 SPI_PRINT(("DSimulatedSpiDevice::DSimulatedSpiDevice\n")); |
|
83 iVersion = DSimulatedSpiDevice::VersionRequired(); |
|
84 } |
|
85 |
|
86 TInt DSimulatedSpiDevice::Install() |
|
87 { |
|
88 SPI_PRINT(("DSimulatedSpiDevice::Install\n")); |
|
89 return(SetName(&KPddNameSpi)); |
|
90 } |
|
91 |
|
92 /** Called by the kernel's device driver framework to create a Physical Channel. */ |
|
93 TInt DSimulatedSpiDevice::Create(DBase*& /*aChannel*/, TInt /*aUint*/, const TDesC8* /*anInfo*/, const TVersion& /*aVer*/) |
|
94 { |
|
95 SPI_PRINT(("DSimulatedSpiDevice::Create\n")); |
|
96 return KErrNone; |
|
97 } |
|
98 |
|
99 /** Called by the kernel's device driver framework to check if this PDD is suitable for use with a Logical Channel.*/ |
|
100 TInt DSimulatedSpiDevice::Validate(TInt /*aUnit*/, const TDesC8* /*anInfo*/, const TVersion& aVer) |
|
101 { |
|
102 SPI_PRINT(("DSimulatedSpiDevice::Validate\n")); |
|
103 if (!Kern::QueryVersionSupported(DSimulatedSpiDevice::VersionRequired(),aVer)) |
|
104 return(KErrNotSupported); |
|
105 return KErrNone; |
|
106 } |
|
107 |
|
108 /** Return the driver capabilities */ |
|
109 void DSimulatedSpiDevice::GetCaps(TDes8& aDes) const |
|
110 { |
|
111 SPI_PRINT(("DSimulatedSpiDevice::GetCaps\n")); |
|
112 // Create a capabilities object |
|
113 TCaps caps; |
|
114 caps.iVersion = iVersion; |
|
115 // Zero the buffer |
|
116 TInt maxLen = aDes.MaxLength(); |
|
117 aDes.FillZ(maxLen); |
|
118 // Copy capabilities |
|
119 TInt size=sizeof(caps); |
|
120 if(size>maxLen) |
|
121 size=maxLen; |
|
122 aDes.Copy((TUint8*)&caps,size); |
|
123 } |
|
124 |
|
125 |
|
126 DSimulatedSpiDevice* gDummyDevice; |
|
127 |
|
128 // supported channels for this implementation |
|
129 static DIicBusChannel* ChannelPtrArray[NUM_CHANNELS]; |
|
130 |
|
131 |
|
132 //DECLARE_EXTENSION_WITH_PRIORITY(BUS_IMPLMENTATION_PRIORITY) |
|
133 DECLARE_STANDARD_PDD() // SPI test driver to be explicitly loaded as an LDD, not kernel extension |
|
134 { |
|
135 if(gDummyDevice == NULL) |
|
136 gDummyDevice = new DSimulatedSpiDevice; |
|
137 if(gDummyDevice == NULL) |
|
138 return NULL; |
|
139 SPI_PRINT(("\n\nSPI PDD, channel creation loop follows ...\n")); |
|
140 |
|
141 #ifndef STANDALONE_CHANNEL |
|
142 DIicBusChannel* chan=NULL; |
|
143 for(TInt i=0; i<NUM_CHANNELS; i++) |
|
144 { |
|
145 SPI_PRINT(("\n")); |
|
146 if(CHANNEL_TYPE(i) == (DIicBusChannel::EMaster)) |
|
147 { |
|
148 chan=new DSimulatedIicBusChannelMasterSpi(BUS_TYPE,CHANNEL_DUPLEX(i)); |
|
149 if(!chan) |
|
150 return NULL; |
|
151 SPI_PRINT(("SPI chan created at 0x%x\n",chan)); |
|
152 if(((DSimulatedIicBusChannelMasterSpi*)chan)->Create()!=KErrNone) |
|
153 return NULL; |
|
154 } |
|
155 else if(CHANNEL_TYPE(i) == DIicBusChannel::EMasterSlave) |
|
156 { |
|
157 DIicBusChannel* chanM=new DSimulatedIicBusChannelMasterSpi(BUS_TYPE,CHANNEL_DUPLEX(i)); |
|
158 if(!chanM) |
|
159 return NULL; |
|
160 DIicBusChannel* chanS=new DSimulatedIicBusChannelSlaveSpi(BUS_TYPE,CHANNEL_DUPLEX(i)); |
|
161 if(!chanS) |
|
162 return NULL; |
|
163 // For MasterSlave channel, the channel number for both the Master and Slave channels must be the same |
|
164 TInt8 msChanNum = ((DSimulatedIicBusChannelMasterSpi*)chanM)->GetChanNum(); |
|
165 ((DSimulatedIicBusChannelSlaveSpi*)chanS)->SetChanNum(msChanNum); |
|
166 |
|
167 chan=new DIicBusChannelMasterSlave(BUS_TYPE,CHANNEL_DUPLEX(i),(DIicBusChannelMaster*)chanM,(DIicBusChannelSlave*)chanS); // Generic implementation |
|
168 if(!chan) |
|
169 return NULL; |
|
170 SPI_PRINT(("SPI chan created at 0x%x\n",chan)); |
|
171 if(((DIicBusChannelMasterSlave*)chan)->DoCreate()!=KErrNone) |
|
172 return NULL; |
|
173 } |
|
174 else |
|
175 { |
|
176 chan=new DSimulatedIicBusChannelSlaveSpi(BUS_TYPE,CHANNEL_DUPLEX(i)); |
|
177 if(!chan) |
|
178 return NULL; |
|
179 SPI_PRINT(("SPI chan created at 0x%x\n",chan)); |
|
180 if(((DSimulatedIicBusChannelSlaveSpi*)chan)->Create()!=KErrNone) |
|
181 return NULL; |
|
182 } |
|
183 ChannelPtrArray[i]=chan; |
|
184 } |
|
185 SPI_PRINT(("\nSPI PDD, channel creation loop done- about to invoke RegisterChannels\n\n")); |
|
186 #ifdef IIC_INSTRUMENTATION_MACRO |
|
187 IIC_REGISTERCHANS_START_PSL_TRACE; |
|
188 #endif |
|
189 |
|
190 TInt r = KErrNone; |
|
191 r=DIicBusController::RegisterChannels(ChannelPtrArray,NUM_CHANNELS); |
|
192 |
|
193 #ifdef IIC_INSTRUMENTATION_MACRO |
|
194 IIC_REGISTERCHANS_END_PSL_TRACE; |
|
195 #endif |
|
196 SPI_PRINT(("\nSPI - returned from RegisterChannels with r=%d\n",r)); |
|
197 if(r!=KErrNone) |
|
198 { |
|
199 delete chan; |
|
200 return NULL; |
|
201 } |
|
202 #endif |
|
203 return gDummyDevice; |
|
204 } |
|
205 |
|
206 #ifdef STANDALONE_CHANNEL |
|
207 EXPORT_C |
|
208 #endif |
|
209 DSimulatedIicBusChannelMasterSpi::DSimulatedIicBusChannelMasterSpi(const TBusType aBusType, const TChannelDuplex aChanDuplex) |
|
210 : DIicBusChannelMaster(aBusType,aChanDuplex) |
|
211 { |
|
212 SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::DSimulatedIicBusChannelMasterSpi, aBusType=%d,aChanDuplex=%d\n",aBusType,aChanDuplex)); |
|
213 #ifndef STANDALONE_CHANNEL |
|
214 iChannelNumber = AssignChanNum(); |
|
215 #endif |
|
216 SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::DSimulatedIicBusChannelMasterSpi, iChannelNumber=%d\n",iChannelNumber)); |
|
217 iTestState = ETestNone; |
|
218 iChannelState = EIdle; |
|
219 } |
|
220 |
|
221 // The time-out call back invoked when the Slave exeecds the allowed response time |
|
222 TInt DSimulatedIicBusChannelMasterSpi::HandleSlaveTimeout() |
|
223 { |
|
224 SPI_PRINT(("HandleSlaveTimeout \n")); |
|
225 return AsynchStateMachine(ETimeExpired); |
|
226 } |
|
227 |
|
228 TInt DSimulatedIicBusChannelMasterSpi::DoCreate() |
|
229 { |
|
230 SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::DoCreate\n")); |
|
231 TInt r=Init(); // PIL Base class initialisation |
|
232 r=Kern::DynamicDfcQCreate(iDynamicDfcQ,KSpiThreadPriority,KSpiThreadName); |
|
233 if(r == KErrNone) |
|
234 SetDfcQ((TDfcQue*)iDynamicDfcQ); |
|
235 DSimulatedIicBusChannelMasterSpi::SetRequestDelayed(this,EFalse); |
|
236 return r; |
|
237 } |
|
238 |
|
239 TInt DSimulatedIicBusChannelMasterSpi::CheckHdr(TDes8* aHdr) |
|
240 { |
|
241 SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::CheckHdr\n")); |
|
242 |
|
243 TConfigSpiBufV01* spiBuf = (TConfigSpiBufV01*)aHdr; |
|
244 TConfigSpiV01* spiPtr = &((*spiBuf)()); |
|
245 |
|
246 // Valid values for the device ID will depend on the bus configuration |
|
247 // |
|
248 // Check that the values for word width, clock speed and clock mode are recognised |
|
249 if((spiPtr->iWordWidth < 0) || (spiPtr->iWordWidth > ESpiWordWidth_16)) |
|
250 { |
|
251 SPI_PRINT(("ERROR: DSimulatedIicBusChannelMasterSpi::CheckHdr unrecognised word width identifier %d\n",spiPtr->iWordWidth)); |
|
252 return KErrArgument; |
|
253 } |
|
254 if(spiPtr->iClkSpeedHz < 0) |
|
255 { |
|
256 SPI_PRINT(("ERROR: DSimulatedIicBusChannelMasterSpi::CheckHdr negative clock speed specified %d\n",spiPtr->iClkSpeedHz)); |
|
257 return KErrArgument; |
|
258 } |
|
259 if((spiPtr->iClkMode < 0) || (spiPtr->iClkMode > ESpiPolarityHighRisingEdge)) |
|
260 { |
|
261 SPI_PRINT(("ERROR: DSimulatedIicBusChannelMasterSpi::CheckHdr unrecognised clock mode identifier %d\n",spiPtr->iClkMode)); |
|
262 return KErrArgument; |
|
263 } |
|
264 // Values for the timeout period are arbitrary - can only check it is not a negative value |
|
265 if(spiPtr->iTimeoutPeriod < 0) |
|
266 { |
|
267 SPI_PRINT(("ERROR: DSimulatedIicBusChannelMasterSpi::CheckHdr negative timeout period %d\n",spiPtr->iTimeoutPeriod)); |
|
268 return KErrArgument; |
|
269 } |
|
270 if((spiPtr->iEndianness < 0) || (spiPtr->iEndianness > ELittleEndian)) |
|
271 { |
|
272 SPI_PRINT(("ERROR: DSimulatedIicBusChannelMasterSpi::CheckHdr unrecognised endianness identifier %d\n",spiPtr->iEndianness)); |
|
273 return KErrArgument; |
|
274 } |
|
275 if((spiPtr->iBitOrder < 0) || (spiPtr->iBitOrder > EMsbFirst)) |
|
276 { |
|
277 SPI_PRINT(("ERROR: DSimulatedIicBusChannelMasterSpi::CheckHdr unrecognised bit order identifier %d\n",spiPtr->iBitOrder)); |
|
278 return KErrArgument; |
|
279 } |
|
280 if((spiPtr->iSSPinActiveMode < 0) || (spiPtr->iSSPinActiveMode > ESpiCSPinActiveHigh)) |
|
281 { |
|
282 SPI_PRINT(("ERROR: DSimulatedIicBusChannelMasterSpi::CheckHdr unrecognised Slave select pin mode identifier %d\n",spiPtr->iSSPinActiveMode)); |
|
283 return KErrArgument; |
|
284 } |
|
285 SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::CheckHdr word width = %d\n",spiPtr->iWordWidth)); |
|
286 SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::CheckHdr clock speed = %d\n",spiPtr->iClkSpeedHz)); |
|
287 SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::CheckHdr clock mode = %d\n",spiPtr->iClkMode)); |
|
288 SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::CheckHdr timeout period = %d\n",spiPtr->iTimeoutPeriod)); |
|
289 SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::CheckHdr endianness = %d\n",spiPtr->iEndianness)); |
|
290 SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::CheckHdr bit order = %d\n",spiPtr->iBitOrder)); |
|
291 SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::CheckHdr transaction wait cycles = %d\n",spiPtr->iTransactionWaitCycles)); |
|
292 SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::CheckHdr slave select pin mode = %d\n",spiPtr->iSSPinActiveMode)); |
|
293 |
|
294 // For the set of tests expecft the following values |
|
295 // ESpiWordWidth_8, 100kHz, ESpiPolarityLowRisingEdge,aTimeoutPeriod=100 |
|
296 // EBigEndian, EMsbFirst, 10 wait cycles, Slave select active low |
|
297 if( (spiPtr->iWordWidth != ESpiWordWidth_8) || |
|
298 (spiPtr->iClkSpeedHz != 100000) || |
|
299 (spiPtr->iClkMode != ESpiPolarityLowRisingEdge) || |
|
300 (spiPtr->iTimeoutPeriod != 100) || |
|
301 (spiPtr->iEndianness != ELittleEndian) || |
|
302 (spiPtr->iBitOrder != EMsbFirst) || |
|
303 (spiPtr->iTransactionWaitCycles != 10) || |
|
304 (spiPtr->iSSPinActiveMode != ESpiCSPinActiveLow) ) |
|
305 return KErrCorrupt; |
|
306 return KErrNone; |
|
307 } |
|
308 |
|
309 TInt DSimulatedIicBusChannelMasterSpi::CompareTransactionOne(TIicBusTransaction* aTransaction) |
|
310 // Compares the indicated TIicBusTransaction with the expected content |
|
311 // Returns KErrNone if there is a match, KErrCorrupt otherwise. |
|
312 { |
|
313 TInt i; |
|
314 // Check the transaction header |
|
315 // Should contain the default header for SPI |
|
316 TDes8* bufPtr = GetTransactionHeader(aTransaction); |
|
317 if(bufPtr == NULL) |
|
318 { |
|
319 SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::CompareTransactionOne ERROR - NULL header\n")); |
|
320 return KErrCorrupt; |
|
321 } |
|
322 TConfigSpiV01 *buf = (TConfigSpiV01 *)(bufPtr->Ptr()); |
|
323 if(buf->iWordWidth != ESpiWordWidth_8) |
|
324 { |
|
325 SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::CompareTransactionOne ERROR - Header wordwidth mis-match\n")); |
|
326 return KErrCorrupt; |
|
327 } |
|
328 if(buf->iClkSpeedHz !=100000) |
|
329 { |
|
330 SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::CompareTransactionOne ERROR - Header clockspeed mis-match\n")); |
|
331 return KErrCorrupt; |
|
332 } |
|
333 if(buf->iClkMode != ESpiPolarityLowRisingEdge) |
|
334 { |
|
335 SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::CompareTransactionOne ERROR - Header polarity mis-match\n")); |
|
336 return KErrCorrupt; |
|
337 } |
|
338 if(buf->iTimeoutPeriod != 100) |
|
339 { |
|
340 SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::CompareTransactionOne ERROR - Header timeout mis-match\n")); |
|
341 return KErrCorrupt; |
|
342 } |
|
343 |
|
344 SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::CompareTransactionOne header OK\n")); |
|
345 |
|
346 // Check the half-duplex transfer list |
|
347 TIicBusTransfer* tfer = GetTransHalfDuplexTferPtr(aTransaction); |
|
348 if(tfer == NULL) |
|
349 { |
|
350 SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::CompareTransactionOne ERROR - NULL half-duplex transfer\n")); |
|
351 return KErrCorrupt; |
|
352 } |
|
353 // Process each transfer in the list |
|
354 TInt8 dummy; |
|
355 |
|
356 // tfer1 = new TIicBusTransfer(TIicBusTransfer::EMasterWrite,8,buf1); |
|
357 // buf1 contains copy of TUint8 KTransOneTferOne[21] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20}; |
|
358 dummy=GetTferType(tfer); |
|
359 if(dummy!=TIicBusTransfer::EMasterWrite) |
|
360 { |
|
361 SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::CompareTransactionOne ERROR - tfer1 type=%d\n")); |
|
362 return KErrCorrupt; |
|
363 } |
|
364 dummy=GetTferBufGranularity(tfer); |
|
365 if(dummy!=8) |
|
366 { |
|
367 SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::CompareTransactionOne ERROR - tfer1 granularity=%d\n",dummy)); |
|
368 return KErrCorrupt; |
|
369 } |
|
370 if((bufPtr = (TDes8*)GetTferBuffer(tfer)) == NULL) |
|
371 { |
|
372 SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::CompareTransactionOne ERROR - tfer1 buffer NULL\n")); |
|
373 return KErrCorrupt; |
|
374 } |
|
375 for(i=0;i<21;++i) |
|
376 { |
|
377 if((*bufPtr)[i]!=i) |
|
378 { |
|
379 SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::CompareTransactionOne ERROR tfer1 buffer element %d has 0x%x\n",i,(*bufPtr)[i])); |
|
380 return KErrCorrupt; |
|
381 } |
|
382 } |
|
383 SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::CompareTransactionOne tfer1 OK\n")); |
|
384 |
|
385 |
|
386 tfer=GetTferNextTfer(tfer); |
|
387 // tfer2 = new TIicBusTransfer(TIicBusTransfer::EMasterRead,8,buf2); |
|
388 // buf2 contains copy of TUint8 KTransOneTferTwo[8] = {17,18,19,20,21,22,23,24}; |
|
389 dummy=GetTferType(tfer); |
|
390 if(dummy!=TIicBusTransfer::EMasterRead) |
|
391 { |
|
392 SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::CompareTransactionOne ERROR - tfer2 type=%d\n",dummy)); |
|
393 return KErrCorrupt; |
|
394 } |
|
395 dummy=GetTferBufGranularity(tfer); |
|
396 if(dummy!=8) |
|
397 { |
|
398 SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::CompareTransactionOne ERROR - tfer2 granularity=%d\n",dummy)); |
|
399 return KErrCorrupt; |
|
400 } |
|
401 if((bufPtr = (TDes8*)GetTferBuffer(tfer)) == NULL) |
|
402 { |
|
403 SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::CompareTransactionOne ERROR - tfer2 buffer NULL\n")); |
|
404 return KErrCorrupt; |
|
405 } |
|
406 for(i=0;i<8;++i) |
|
407 { |
|
408 if((*bufPtr)[i]!=(17+i)) |
|
409 { |
|
410 SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::CompareTransactionOne ERROR tfer2 buffer element %d has 0x%x\n",i,(*bufPtr)[i])); |
|
411 return KErrCorrupt; |
|
412 } |
|
413 } |
|
414 SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::CompareTransactionOne tfer2 OK\n")); |
|
415 |
|
416 tfer=GetTferNextTfer(tfer); |
|
417 // tfer3 = new TIicBusTransfer(TIicBusTransfer::EMasterWrite,8,buf3); |
|
418 // buf2 contains copy of TUint8 KTransOneTferThree[6] = {87,85,83,81,79,77}; |
|
419 dummy=GetTferType(tfer); |
|
420 if(dummy!=TIicBusTransfer::EMasterWrite) |
|
421 { |
|
422 SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::CompareTransactionOne ERROR - tfer3 type=%d\n")); |
|
423 return KErrCorrupt; |
|
424 } |
|
425 dummy=GetTferBufGranularity(tfer); |
|
426 if(dummy!=8) |
|
427 { |
|
428 SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::CompareTransactionOne ERROR - tfer3 granularity=%d\n",dummy)); |
|
429 return KErrCorrupt; |
|
430 } |
|
431 if((bufPtr = (TDes8*)GetTferBuffer(tfer)) == NULL) |
|
432 { |
|
433 SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::CompareTransactionOne ERROR - tfer3 buffer NULL\n")); |
|
434 return KErrCorrupt; |
|
435 } |
|
436 for(i=0;i<6;++i) |
|
437 { |
|
438 if((*bufPtr)[i]!=(87-(2*i))) |
|
439 { |
|
440 SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::CompareTransactionOne ERROR tfer3 buffer element %d has 0x%x\n",i,(*bufPtr)[i])); |
|
441 return KErrCorrupt; |
|
442 } |
|
443 } |
|
444 SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::CompareTransactionOne tfer3 OK\n")); |
|
445 |
|
446 // Shouldn't be any more transfers in the half duplex list |
|
447 if((tfer=GetTferNextTfer(tfer))!=NULL) |
|
448 { |
|
449 SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::CompareTransactionOne ERROR - tfer3 iNext=0x%x\n",tfer)); |
|
450 return KErrCorrupt; |
|
451 } |
|
452 SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::CompareTransactionOne half-duplex transfer OK\n")); |
|
453 |
|
454 // The full duplex transfer should be represented by a NULL pointer |
|
455 if((tfer=GetTransFullDuplexTferPtr(aTransaction))!=NULL) |
|
456 { |
|
457 SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::CompareTransactionOne ERROR - full duplex pointer=0x%x\n",tfer)); |
|
458 return KErrCorrupt; |
|
459 } |
|
460 SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::CompareTransactionOne full duplex pointer is NULL (OK)\n")); |
|
461 |
|
462 // Synchronous transaction, so check the callback pointer is NULL |
|
463 TIicBusCallback* dumCb = NULL; |
|
464 dumCb=GetTransCallback(aTransaction); |
|
465 if(dumCb!=NULL) |
|
466 { |
|
467 SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::CompareTransactionOne ERROR - callback pointer=0x%x\n",dumCb)); |
|
468 return KErrCorrupt; |
|
469 } |
|
470 SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::CompareTransactionOne callback pointer is NULL (OK)\n")); |
|
471 |
|
472 // Check the transaction flags are set to zero |
|
473 TUint8 dumFlags; |
|
474 dumFlags=GetTransFlags(aTransaction); |
|
475 if(dumFlags!=0) |
|
476 { |
|
477 SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::CompareTransactionOne ERROR - flags=0x%x\n",dumFlags)); |
|
478 return KErrCorrupt; |
|
479 } |
|
480 SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::CompareTransactionOne flags are zero (OK)\n")); |
|
481 |
|
482 return KErrNone; |
|
483 } |
|
484 |
|
485 |
|
486 // The THwCallbackFunc gets called if the hardware preparation completes successfully. |
|
487 void THwCallbackFunc(TAny* aPtr) |
|
488 { |
|
489 SPI_PRINT(("Hardware preparation completed, calling the callback function")); |
|
490 DSimulatedIicBusChannelMasterSpi* aChanMasterSpi=(DSimulatedIicBusChannelMasterSpi* )aPtr; |
|
491 TInt r = aChanMasterSpi->DoSimulatedTransaction(); |
|
492 ((DSimulatedIicBusChannelMasterSpi*)aChanMasterSpi)->CompleteReq(r); |
|
493 } |
|
494 |
|
495 TInt DSimulatedIicBusChannelMasterSpi::DoSimulatedTransaction() |
|
496 { |
|
497 TInt r = AsynchStateMachine(EHwTransferDone); |
|
498 if(iTimeoutTimer.Cancel() == FALSE) |
|
499 { |
|
500 SPI_PRINT(("timer is not cancelled")); |
|
501 } |
|
502 return r; |
|
503 } |
|
504 |
|
505 TInt DSimulatedIicBusChannelMasterSpi::DoHwPreparation() |
|
506 { |
|
507 SPI_PRINT(("Preparing hardware for the transaction")); |
|
508 |
|
509 TInt r = KErrNone; |
|
510 // The hardware preparation can either complete successfully or fail. |
|
511 // If successful, invoke the callback function of THwDoneCallBack |
|
512 // if not, execute the timeout machanism |
|
513 // Currently DoHwPreparation is just a simple function. It should be more complicated |
|
514 // for the real hardware. |
|
515 switch(iTestState) |
|
516 { |
|
517 case (ETestSlaveTimeOut): |
|
518 { |
|
519 // In the timeout test, do nothing until the timeout callback function is invoked. |
|
520 SPI_PRINT(("Simulating the timeout process.")); |
|
521 break; |
|
522 } |
|
523 case (ETestNone): |
|
524 { |
|
525 // Pretend the hardware preparation's been done, and a callback function is invoked to call |
|
526 // the Asynchronous State Machine |
|
527 SPI_PRINT(("Hardware preparing work is executing normally.")); |
|
528 iCb->Enque(); |
|
529 break; |
|
530 } |
|
531 default: |
|
532 { |
|
533 SPI_PRINT(("Not a valid test.")); |
|
534 r = KErrNotSupported; |
|
535 break; |
|
536 } |
|
537 } |
|
538 |
|
539 return r; |
|
540 } |
|
541 |
|
542 // Gateway function for PSL implementation, invoked for DFC processing |
|
543 TInt DSimulatedIicBusChannelMasterSpi::DoRequest(TIicBusTransaction* aTransaction) |
|
544 { |
|
545 SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::DoRequest invoked with aTransaction=0x%x\n",aTransaction)); |
|
546 |
|
547 TInt r = KErrNone; |
|
548 iCurrTrans=aTransaction; |
|
549 |
|
550 // Check if the Asynchronous State Machine is available. If not, then return KErrInUse. |
|
551 // This is used to stop the second transaction executing if the machine has already been holding |
|
552 // by a transaction. However, this situation cannot be tested because of the malfunction in PIL |
|
553 if(iChannelState!= EIdle) |
|
554 return KErrInUse; |
|
555 |
|
556 iChannelState = EBusy; |
|
557 #ifdef IIC_INSTRUMENTATION_MACRO |
|
558 IIC_MPROCESSTRANS_START_PSL_TRACE; |
|
559 #endif |
|
560 r = ProcessTrans(aTransaction); |
|
561 |
|
562 SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::DoRequest - exiting\n")); |
|
563 return r; |
|
564 } |
|
565 |
|
566 TInt DSimulatedIicBusChannelMasterSpi::ProcessTrans(TIicBusTransaction* aTransaction) |
|
567 { |
|
568 TInt r=KErrNone; |
|
569 |
|
570 switch(iTestState) |
|
571 { |
|
572 case(ETestWaitTransOne): |
|
573 { |
|
574 // The transaction received should exhibit the expected data |
|
575 // Return KErrArgument if this is not the case |
|
576 // The timer should be started at the beginning of every transaction |
|
577 // For simplicity, we omit the timer here. |
|
578 r=CompareTransactionOne(iCurrTrans); |
|
579 iChannelState = EIdle; |
|
580 CompleteRequest(KErrNone); |
|
581 break; |
|
582 } |
|
583 case(ETestSlaveTimeOut): |
|
584 { |
|
585 // Test the timeout funciton |
|
586 SPI_PRINT(("Test the slave timeout function\n")); |
|
587 |
|
588 // Simulate a timeout |
|
589 // Start a timer and then wait for the Slave response to timeout |
|
590 // A real bus would use its own means to identify a timeout |
|
591 TInt aTime=1000000/NKern::TickPeriod(); |
|
592 r = StartSlaveTimeOutTimer(aTime); |
|
593 if(r != KErrNone) |
|
594 return r; |
|
595 r = DoHwPreparation(); |
|
596 break; |
|
597 } |
|
598 case(ETestWaitPriorityTest): |
|
599 { |
|
600 static TInt TranCount = 0; |
|
601 if(TranCount >= KPriorityTestNum) return KErrUnknown; |
|
602 // block the channel |
|
603 while(IsRequestDelayed(this)) |
|
604 { |
|
605 SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::DoRequest - starting Sleep...\n")); |
|
606 NKern::Sleep(1000); // 1000 is arbitrary |
|
607 SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::DoRequest - completed Sleep, check if still delayed\n")); |
|
608 }; |
|
609 // get transaction header |
|
610 TDes8* bufPtr = GetTransactionHeader(aTransaction); |
|
611 if(bufPtr == NULL) |
|
612 { |
|
613 SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::DoRequest ERROR - NULL header\n")); |
|
614 return KErrCorrupt; |
|
615 } |
|
616 |
|
617 if(TranCount == 0) |
|
618 { |
|
619 // ignore the blocking transaction |
|
620 TranCount++; |
|
621 } |
|
622 else |
|
623 { |
|
624 // store transaction header |
|
625 iPriorityTestResult[TranCount++] = (*bufPtr)[0]; |
|
626 SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::DoRequest Priority test transaction no.:%d Priority:%d", |
|
627 (*bufPtr)[0], aTransaction->iKey)); |
|
628 } |
|
629 iChannelState = EIdle; |
|
630 CompleteRequest(KErrNone); |
|
631 if(TranCount == KPriorityTestNum) iPriorityTestDone = ETrue; |
|
632 break; |
|
633 } |
|
634 |
|
635 |
|
636 |
|
637 case(ETestNone): |
|
638 { |
|
639 SPI_PRINT(("Nothing to be tested, just do the usual transaction")); |
|
640 |
|
641 // Start the timer on the Slave response. |
|
642 // Since no timeout, this timer will be cancelled in the THwCallbackFunc |
|
643 r = StartSlaveTimeOutTimer(100000); |
|
644 if(r != KErrNone) |
|
645 return r; |
|
646 // Use a class THwDoneCallBack derived from TDfc to trigger the asynchronous state machine |
|
647 // when the hardware preparation completes successfully. |
|
648 // The priority is set with an arbitrary number 5 |
|
649 iCb = new THwDoneCallBack(THwCallbackFunc, this, iDynamicDfcQ, 5); |
|
650 r = DoHwPreparation(); |
|
651 break; |
|
652 } |
|
653 default: |
|
654 { |
|
655 SPI_PRINT(("Test status not matched")); |
|
656 return KErrNotSupported; |
|
657 } |
|
658 } |
|
659 |
|
660 return r; |
|
661 } |
|
662 |
|
663 |
|
664 TInt DSimulatedIicBusChannelMasterSpi::AsynchStateMachine(TInt aReason) |
|
665 { |
|
666 TInt r=KErrNone; |
|
667 |
|
668 // The asynchronous state machine has two states, it could either be idle or busy. |
|
669 // Initially, it's in idle state. When a user queues a transaction, the hardware preparation starts |
|
670 // and the state changes to busy. After the hardware preparation completes, either successfully or not, |
|
671 // the state machine will do the corresponding work for the transaction and then goes back to the idle state. |
|
672 switch(iChannelState) |
|
673 { |
|
674 case(EIdle): |
|
675 { |
|
676 return KErrGeneral; |
|
677 } |
|
678 case (EBusy): |
|
679 { |
|
680 switch(aReason) |
|
681 { |
|
682 case(EHwTransferDone): |
|
683 { |
|
684 |
|
685 // Simulate processing - for now, do nothing! |
|
686 // |
|
687 SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::AsynchStateMachine aTransaction->iHeader=0x%x\n",GetTransactionHeader(iCurrTrans))); |
|
688 SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::AsynchStateMachine aTransaction->iHalfDuplexTrans=0x%x\n",GetTransHalfDuplexTferPtr(iCurrTrans))); |
|
689 SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::AsynchStateMachine aTransaction->iFullDuplexTrans=0x%x\n",GetTransFullDuplexTferPtr(iCurrTrans))); |
|
690 SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::AsynchStateMachine aTransaction->iCallback=0x%x\n",GetTransCallback(iCurrTrans))); |
|
691 SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::AsynchStateMachine aTransaction->iFlags=0x%x\n",GetTransFlags(iCurrTrans))); |
|
692 |
|
693 SPI_PRINT(("\nDSimulatedIicBusChannelMasterSpi::AsynchStateMachine, iHeader info \n")); |
|
694 TDes8* bufPtr = GetTransactionHeader(iCurrTrans); |
|
695 if(bufPtr == NULL) |
|
696 { |
|
697 SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::AsynchStateMachine ERROR - NULL header\n")); |
|
698 return KErrCorrupt; |
|
699 } |
|
700 TConfigSpiV01 *buf = (TConfigSpiV01 *)(bufPtr->Ptr()); |
|
701 SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::AsynchStateMachine, header word width=0x%x\n",buf->iWordWidth)); |
|
702 SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::AsynchStateMachine, header clock speed=0x%x\n",buf->iClkSpeedHz)); |
|
703 SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::AsynchStateMachine, header clock mode=0x%x\n",buf->iClkMode)); |
|
704 SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::AsynchStateMachine, header timeout period=0x%x\n",buf->iTimeoutPeriod)); |
|
705 SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::AsynchStateMachine, header endianness=0x%x\n",buf->iEndianness)); |
|
706 SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::AsynchStateMachine, header bit order=0x%x\n",buf->iBitOrder)); |
|
707 SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::AsynchStateMachine, header wait cycles=0x%x\n",buf->iTransactionWaitCycles)); |
|
708 SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::AsynchStateMachine, header Slave select pin mode=0x%x\n",buf->iSSPinActiveMode)); |
|
709 (void)buf; // Silence compiler when SPI_PRINT not used |
|
710 |
|
711 SPI_PRINT(("\nDSimulatedIicBusChannelMasterSpi::AsynchStateMachine, iHalfDuplexTrans info \n")); |
|
712 TIicBusTransfer* halfDuplexPtr=GetTransHalfDuplexTferPtr(iCurrTrans); |
|
713 while(halfDuplexPtr != NULL) |
|
714 { |
|
715 SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::AsynchStateMachine transfer type=0x%x\n",GetTferType(halfDuplexPtr))); |
|
716 SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::AsynchStateMachine granularity=0x%x\n",GetTferBufGranularity(halfDuplexPtr))); |
|
717 SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::AsynchStateMachine transfer buffer=0x%x\n",GetTferBuffer(halfDuplexPtr))); |
|
718 SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::AsynchStateMachine next transfer =0x%x\n",GetTferNextTfer(halfDuplexPtr))); |
|
719 halfDuplexPtr=GetTferNextTfer(halfDuplexPtr); |
|
720 } |
|
721 SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::AsynchStateMachine - End of iHalfDuplexTrans info")); |
|
722 |
|
723 while(IsRequestDelayed(this)) |
|
724 { |
|
725 SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::AsynchStateMachine - starting Sleep...\n")); |
|
726 NKern::Sleep(1000); // 1000 is arbitrary |
|
727 SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::AsynchStateMachine - completed Sleep, check if still delayed\n")); |
|
728 }; |
|
729 |
|
730 iChannelState=EIdle; |
|
731 delete iCb; |
|
732 break; |
|
733 } |
|
734 case(ETimeExpired): |
|
735 { |
|
736 SPI_PRINT(("Time expired, the Asynchrnous State Machine will be Idle again, and wait for the next request.")); |
|
737 iChannelState=EIdle; |
|
738 r = KErrTimedOut; |
|
739 break; |
|
740 } |
|
741 default: |
|
742 { |
|
743 SPI_PRINT(("Request can not be handled, return error code.")); |
|
744 return KErrNotSupported; |
|
745 } |
|
746 } |
|
747 break; |
|
748 } |
|
749 default: |
|
750 { |
|
751 SPI_PRINT(("No matched state")); |
|
752 return KErrGeneral; |
|
753 } |
|
754 } |
|
755 return r; |
|
756 } |
|
757 |
|
758 |
|
759 TBool DSimulatedIicBusChannelMasterSpi::IsRequestDelayed(DSimulatedIicBusChannelMasterSpi* aChan) |
|
760 { |
|
761 SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::IsRequestDelayed invoked for aChan=0x%x\n",aChan)); |
|
762 return aChan->iReqDelayed; |
|
763 } |
|
764 |
|
765 void DSimulatedIicBusChannelMasterSpi::SetRequestDelayed(DSimulatedIicBusChannelMasterSpi* aChan,TBool aDelay) |
|
766 { |
|
767 SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::SetRequestDelayed invoked for aChan=0x%x, with aDelay=0x%d\n",aChan,aDelay)); |
|
768 aChan->iReqDelayed=aDelay; |
|
769 } |
|
770 |
|
771 TInt DSimulatedIicBusChannelMasterSpi::StaticExtension(TUint aFunction, TAny* aParam1, TAny* aParam2) |
|
772 { |
|
773 SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::StaticExtension\n")); |
|
774 #ifdef IIC_INSTRUMENTATION_MACRO |
|
775 IIC_MSTATEXT_START_PSL_TRACE; |
|
776 #endif |
|
777 (void)aParam1; |
|
778 (void)aParam2; |
|
779 TInt r = KErrNone; |
|
780 // Test values of aFunction were shifted left one place by the (test) client driver |
|
781 // and for Slave values the two msb were cleared |
|
782 // Return to its original value. |
|
783 if(aFunction>KTestControlIoPilOffset) |
|
784 aFunction >>= 1; |
|
785 switch(aFunction) |
|
786 { |
|
787 case(RBusDevIicClient::ECtlIoDumpChan): |
|
788 { |
|
789 #ifdef _DEBUG |
|
790 DumpChannel(); |
|
791 #endif |
|
792 break; |
|
793 } |
|
794 case(RBusDevIicClient::ECtlIoBlockReqCompletion): |
|
795 { |
|
796 SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::Blocking request completion\n")); |
|
797 SetRequestDelayed(this, ETrue); |
|
798 break; |
|
799 } |
|
800 case(RBusDevIicClient::ECtlIoUnblockReqCompletion): |
|
801 { |
|
802 SPI_PRINT(("DSimulatedIicBusChannelMasterSpi::Unlocking request completion\n")); |
|
803 SetRequestDelayed(this, EFalse); |
|
804 break; |
|
805 } |
|
806 case(RBusDevIicClient::ECtlIoDeRegChan): |
|
807 { |
|
808 #ifdef IIC_INSTRUMENTATION_MACRO |
|
809 IIC_DEREGISTERCHAN_START_PSL_TRACE; |
|
810 #endif |
|
811 SPI_PRINT(("DSimulatedIicBusChannelMasterSpi: deregister channel\n")); |
|
812 #ifndef STANDALONE_CHANNEL |
|
813 r=DIicBusController::DeRegisterChannel(this); |
|
814 #endif |
|
815 |
|
816 #ifdef IIC_INSTRUMENTATION_MACRO |
|
817 IIC_DEREGISTERCHAN_END_PSL_TRACE; |
|
818 #endif |
|
819 break; |
|
820 } |
|
821 |
|
822 case(RBusDevIicClient::ECtlIoPriorityTest): |
|
823 { |
|
824 SPI_PRINT(("DSimulatedIicBusChannelMasterSpi: warned to expect priority test\n")); |
|
825 iPriorityTestDone = EFalse; |
|
826 iTestState=ETestWaitPriorityTest; |
|
827 break; |
|
828 } |
|
829 case(RBusDevIicClient::EGetTestResult): |
|
830 { |
|
831 if(!iPriorityTestDone) return KErrNotReady; |
|
832 |
|
833 SPI_PRINT(("DSimulatedIicBusChannelMasterSpi: get priority test order\n")); |
|
834 |
|
835 //iPriorityTestResult[0] is the blocking transaction, ignore it. start from entry 1. |
|
836 for(TInt i=1; i<KPriorityTestNum; i++) |
|
837 { |
|
838 if(iPriorityTestResult[i]!=(KPriorityTestNum-i-1)) |
|
839 { |
|
840 r = KErrGeneral; |
|
841 break; |
|
842 } |
|
843 } |
|
844 r = KErrNone; |
|
845 break; |
|
846 } |
|
847 |
|
848 case(RBusDevIicClient::ECtlIoTracnOne): |
|
849 { |
|
850 SPI_PRINT(("DSimulatedIicBusChannelMasterSpi: warned to expect Transaction One\n")); |
|
851 iTestState=ETestWaitTransOne; |
|
852 break; |
|
853 } |
|
854 case(RBusDevIicClient::ECtlIoNone): |
|
855 { |
|
856 SPI_PRINT(("DSimulatedIicBusChannelMasterSpi: terminate ControlIO state\n")); |
|
857 iTestState=ETestNone; |
|
858 break; |
|
859 } |
|
860 case(RBusDevIicClient::ECtlIoSetTimeOutFlag): |
|
861 { |
|
862 SPI_PRINT(("DSimulatedIicBusChannelMasterSpi: test slave time out\n")); |
|
863 iTestState=ETestSlaveTimeOut; |
|
864 break; |
|
865 } |
|
866 default: |
|
867 { |
|
868 Kern::Printf("aFunction %d is not recognised \n",aFunction); |
|
869 r=KErrNotSupported; |
|
870 } |
|
871 } |
|
872 #ifdef IIC_INSTRUMENTATION_MACRO |
|
873 IIC_MSTATEXT_END_PSL_TRACE; |
|
874 #endif |
|
875 return r; |
|
876 } |
|
877 |
|
878 void DSimulatedIicBusChannelMasterSpi::CompleteReq(TInt aResult) |
|
879 { |
|
880 #ifdef IIC_INSTRUMENTATION_MACRO |
|
881 IIC_MPROCESSTRANS_END_PSL_TRACE; |
|
882 #endif |
|
883 CompleteRequest(aResult); |
|
884 } |
|
885 |
|
886 |
|
887 void DSimulatedIicBusChannelSlaveSpi::SlaveAsyncSimCallback(TAny* aPtr) |
|
888 { |
|
889 SPI_PRINT(("SlaveAsyncSimCallback\n")); |
|
890 DSimulatedIicBusChannelSlaveSpi* channel = (DSimulatedIicBusChannelSlaveSpi*)aPtr; |
|
891 TInt r=KErrNone; // Just simulate successfull capture |
|
892 #ifdef IIC_INSTRUMENTATION_MACRO |
|
893 IIC_SCAPTCHANASYNC_END_PSL_TRACE; |
|
894 #endif |
|
895 channel->ChanCaptureCb(r); |
|
896 } |
|
897 |
|
898 #ifdef STANDALONE_CHANNEL |
|
899 EXPORT_C |
|
900 #endif |
|
901 DSimulatedIicBusChannelSlaveSpi::DSimulatedIicBusChannelSlaveSpi(const DIicBusChannel::TBusType aBusType, const DIicBusChannel::TChannelDuplex aChanDuplex) |
|
902 : DIicBusChannelSlave(aBusType,aChanDuplex,0), // 0 to be ignored by base class |
|
903 iSlaveTimer(SlaveAsyncSimCallback,this) |
|
904 { |
|
905 SPI_PRINT(("DSimulatedIicBusChannelSlaveSpi::DSimulatedIicBusChannelSlaveSpi, aBusType=%d,aChanDuplex=%d\n",aBusType,aChanDuplex)); |
|
906 #ifndef STANDALONE_CHANNEL |
|
907 iChannelNumber = AssignChanNum(); |
|
908 #endif |
|
909 SPI_PRINT(("DSimulatedIicBusChannelSlaveSpi::DSimulatedIicBusChannelSlaveSpi, iChannelNumber=%d\n",iChannelNumber)); |
|
910 } |
|
911 |
|
912 TInt DSimulatedIicBusChannelSlaveSpi::CaptureChannelPsl(TDes8* /*aConfigHdr*/, TBool aAsynch) |
|
913 { |
|
914 SPI_PRINT(("DSimulatedIicBusChannelSlaveSpi::CaptureChannelPsl, aAsynch=%d\n",aAsynch)); |
|
915 TInt r = KErrNone; |
|
916 if(aAsynch) |
|
917 { |
|
918 #ifdef IIC_INSTRUMENTATION_MACRO |
|
919 IIC_SCAPTCHANASYNC_START_PSL_TRACE; |
|
920 #endif |
|
921 // To simulate an asynchronous operation, just set a timer to expire |
|
922 iSlaveTimer.OneShot(1000, ETrue); // Arbitrary timeout - expiry executes callback in context of DfcThread1 |
|
923 } |
|
924 else |
|
925 { |
|
926 #ifdef IIC_INSTRUMENTATION_MACRO |
|
927 IIC_SCAPTCHANSYNC_START_PSL_TRACE; |
|
928 #endif |
|
929 // PSL processing would happen here ... |
|
930 // Expected to include implementation of the header configuration information |
|
931 #ifdef IIC_INSTRUMENTATION_MACRO |
|
932 IIC_SCAPTCHANSYNC_END_PSL_TRACE; |
|
933 #endif |
|
934 } |
|
935 SPI_PRINT(("DSimulatedIicBusChannelSlaveI2c::CaptureChanSync ... no real processing to do \n")); |
|
936 |
|
937 return r; |
|
938 } |
|
939 |
|
940 TInt DSimulatedIicBusChannelSlaveSpi::CheckHdr(TDes8* /*aHdr*/) |
|
941 { |
|
942 SPI_PRINT(("DSimulatedIicBusChannelSlaveSpi::CheckHdr\n")); |
|
943 return KErrNone; |
|
944 } |
|
945 |
|
946 TInt DSimulatedIicBusChannelSlaveSpi::DoCreate() |
|
947 { |
|
948 SPI_PRINT(("DSimulatedIicBusChannelSlaveSpi::DoCreate\n")); |
|
949 TInt r=Init(); // PIL Base class initialisation |
|
950 return r; |
|
951 } |
|
952 |
|
953 TInt DSimulatedIicBusChannelSlaveSpi::DoRequest(TInt /*aTrigger*/) |
|
954 { |
|
955 SPI_PRINT(("DSimulatedIicBusChannelSlaveSpi::DoRequest\n")); |
|
956 return KErrNotSupported; |
|
957 } |
|
958 |
|
959 void DSimulatedIicBusChannelSlaveSpi::ProcessData(TInt /*aTrigger*/, TIicBusSlaveCallback* /*aCb*/) |
|
960 { |
|
961 SPI_PRINT(("DSimulatedIicBusChannelSlaveSpi::ProcessData\n")); |
|
962 } |
|
963 |
|
964 TInt DSimulatedIicBusChannelSlaveSpi::StaticExtension(TUint aFunction, TAny* aParam1, TAny* aParam2) |
|
965 { |
|
966 SPI_PRINT(("DSimulatedIicBusChannelSlaveSpi::StaticExtension\n")); |
|
967 #ifdef IIC_INSTRUMENTATION_MACRO |
|
968 IIC_SSTATEXT_START_PSL_TRACE; |
|
969 #endif |
|
970 (void)aParam1; |
|
971 (void)aParam2; |
|
972 // Test values of aFunction were shifted left one place by the (test) client driver |
|
973 // and for Slave values the two msb were cleared |
|
974 // Return to its original value. |
|
975 if(aFunction>KTestControlIoPilOffset) |
|
976 { |
|
977 aFunction |= 0xC0000000; |
|
978 aFunction >>= 1; |
|
979 } |
|
980 TInt r = KErrNone; |
|
981 switch(aFunction) |
|
982 { |
|
983 case(RBusDevIicClient::ECtlIoDumpChan): |
|
984 { |
|
985 #ifdef _DEBUG |
|
986 DumpChannel(); |
|
987 #endif |
|
988 break; |
|
989 } |
|
990 default: |
|
991 { |
|
992 Kern::Printf("aFunction %d is not recognised \n",aFunction); |
|
993 r=KErrNotSupported; |
|
994 } |
|
995 } |
|
996 |
|
997 #ifdef IIC_INSTRUMENTATION_MACRO |
|
998 IIC_SSTATEXT_START_PSL_TRACE; |
|
999 #endif |
|
1000 (void)aFunction; |
|
1001 return r; |
|
1002 } |
|
1003 |
|
1004 |
|
1005 |
|
1006 |
|
1007 |
|
1008 |