omap3530/omap3530_drivers/spi/test/d_spi_client_m.h
branchBeagle_BSP_dev
changeset 77 e5fd00cbb70a
child 112 fdfa12d9a47a
equal deleted inserted replaced
76:29b14275133a 77:e5fd00cbb70a
       
     1 // This component and the accompanying materials are made available
       
     2 // under the terms of the License "Eclipse Public License v1.0"
       
     3 // which accompanies this distribution, and is available
       
     4 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     5 //
       
     6 // Initial Contributors:
       
     7 // lukasz.forynski@gmail.com
       
     8 //
       
     9 // Contributors:
       
    10 //
       
    11 //
       
    12 // Description:
       
    13 // omap3530_drivers/spi/test/d_spi_client_m.h
       
    14 //
       
    15 
       
    16 #ifndef __D_SPI_CLIENT_MASTER__
       
    17 #define __D_SPI_CLIENT_MASTER__
       
    18 
       
    19 #include <e32cmn.h>
       
    20 #include <e32ver.h>
       
    21 
       
    22 
       
    23 const TInt KIntTestThreadPriority = 24;
       
    24 
       
    25 const TInt KIntTestMajorVersionNumber = 1;
       
    26 const TInt KIntTestMinorVersionNumber = 0;
       
    27 const TInt KIntTestBuildVersionNumber = KE32BuildVersionNumber;
       
    28 
       
    29 _LIT(KLddFileName, "d_spi_client_m.ldd");
       
    30 _LIT(KLddFileNameRoot, "d_spi_client_m");
       
    31 
       
    32 #ifdef __KERNEL_MODE__
       
    33 #include <kernel/kernel.h>
       
    34 
       
    35 // For now - the driver has to know what frequencies are supported and has to specify them directly
       
    36 // in the transaction header. This might be changes in the IIC PIL (kernelhwsrv)-in a way, that the driver
       
    37 // returns supported frequencies with some 'GetCaps' method. For now - standard frequencies for CLK
       
    38 // (that support duty cycle 50-50) are 48MHz divisions per power-of-two.
       
    39 const TInt KSpiClkBaseFreqHz = 48000000;
       
    40 const TInt KSpiClkMaxDivider = 4096;
       
    41 
       
    42 inline TInt SpiFreqHz(TInt aDivider)
       
    43 	{
       
    44 	__ASSERT_DEBUG(aDivider > 0 && aDivider < KSpiClkMaxDivider, Kern::Fault("d_spi_client_master: divider out of range", 13));
       
    45 	__ASSERT_DEBUG(!(aDivider &  (aDivider-1)), Kern::Fault("d_spi_client_master: divider not power of two", 14));
       
    46 	return KSpiClkBaseFreqHz / aDivider;
       
    47 	}
       
    48 #endif
       
    49 
       
    50 class RSpiClientTest: public RBusLogicalChannel
       
    51 	{
       
    52 public:
       
    53 	enum TControl
       
    54 		{
       
    55 		EHalfDuplexSingleWrite,
       
    56 		EHalfDuplexMultipleWrite,
       
    57 		EHalfDuplexSingleRead,
       
    58 		EHalfDuplexMultipleRead,
       
    59 		EHalfDuplexMultipleWriteRead,
       
    60 		EFullDuplexSingle,
       
    61 		EFullDuplexMultiple,
       
    62 		EHalfDuplexExtendable,
       
    63 		EFullDuplexExtendable
       
    64 		};
       
    65 
       
    66 	enum TRequest
       
    67 		{
       
    68 		EAsyncHalfDuplexSingleWrite,
       
    69 		EAsyncHalfDuplexMultipleWrite,
       
    70 		EAsyncHalfDuplexSingleRead,
       
    71 		EAsyncHalfDuplexMultipleRead,
       
    72 		EAsyncHalfDuplexMultipleWriteRead,
       
    73 		EAsyncFullDuplexSingle,
       
    74 		EAsyncFullDuplexMultiple,
       
    75 		EAsyncHalfDuplexExtendable,
       
    76 		EAsyncFullDuplexExtendable
       
    77 		};
       
    78 
       
    79 #ifndef __KERNEL_MODE__
       
    80 public:
       
    81 	TInt Open()
       
    82 		{
       
    83 		return (DoCreate(KLddFileNameRoot,
       
    84 		                 TVersion(KIntTestMajorVersionNumber,KIntTestMinorVersionNumber,KIntTestBuildVersionNumber),
       
    85 		                 -1,
       
    86 		                 NULL,
       
    87 		                 NULL,
       
    88 		                 EOwnerThread));
       
    89 		}
       
    90 
       
    91 	// Synchronous calls
       
    92 	TInt HalfDuplexSingleWrite()
       
    93 		{return DoControl(EHalfDuplexSingleWrite);}
       
    94 
       
    95 	TInt HalfDuplexMultipleWrite()
       
    96 		{return DoControl(EHalfDuplexMultipleWrite);}
       
    97 
       
    98 	TInt HalfDuplexSingleRead()
       
    99 		{return DoControl(EHalfDuplexSingleRead);}
       
   100 
       
   101 	TInt HalfDuplexMultipleRead()
       
   102 		{return DoControl(EHalfDuplexMultipleRead);}
       
   103 
       
   104 	TInt HalfDuplexMultipleWriteRead()
       
   105 		{return DoControl(EHalfDuplexMultipleWriteRead);}
       
   106 
       
   107 	TInt FullDuplexSingle()
       
   108 		{return DoControl(EFullDuplexSingle);}
       
   109 
       
   110 	TInt FullDuplexMultiple()
       
   111 		{return DoControl(EFullDuplexMultiple);}
       
   112 
       
   113 
       
   114 	// Asynchronous calls..
       
   115 	void HalfDuplexSingleWrite(TRequestStatus& aStatus)
       
   116 		{DoRequest(EAsyncHalfDuplexSingleWrite, aStatus, NULL);}
       
   117 
       
   118 	void HalfDuplexMultipleWrite(TRequestStatus& aStatus)
       
   119 		{DoRequest(EAsyncHalfDuplexMultipleWrite, aStatus, NULL);}
       
   120 
       
   121 	void HalfDuplexSingleRead(TRequestStatus& aStatus)
       
   122 		{DoRequest(EAsyncHalfDuplexSingleRead, aStatus, NULL);}
       
   123 
       
   124 	void HalfDuplexMultipleRead(TRequestStatus& aStatus)
       
   125 		{DoRequest(EAsyncHalfDuplexMultipleRead, aStatus, NULL);}
       
   126 
       
   127 	void HalfDuplexMultipleWriteRead(TRequestStatus& aStatus)
       
   128 		{DoRequest(EAsyncHalfDuplexMultipleWriteRead, aStatus, NULL);}
       
   129 
       
   130 	void FullDuplexSingle(TRequestStatus& aStatus)
       
   131 		{DoRequest(EAsyncFullDuplexSingle, aStatus, NULL);}
       
   132 
       
   133 	void FullDuplexMultiple(TRequestStatus& aStatus)
       
   134 		{DoRequest(EAsyncFullDuplexMultiple, aStatus, NULL);}
       
   135 
       
   136 #endif
       
   137 	};
       
   138 
       
   139 #ifdef __KERNEL_MODE__
       
   140 struct TCapsProxyClient
       
   141 	{
       
   142 	TVersion version;
       
   143 	};
       
   144 
       
   145 class DSpiClientTestFactory: public DLogicalDevice
       
   146 	{
       
   147 public:
       
   148 	DSpiClientTestFactory();
       
   149 	~DSpiClientTestFactory();
       
   150 	virtual TInt Install();
       
   151 	virtual void GetCaps(TDes8 &aDes) const;
       
   152 	virtual TInt Create(DLogicalChannelBase*& aChannel);
       
   153 	};
       
   154 
       
   155 // declaration for the client channel
       
   156 class DSpiClientChannel: public DLogicalChannel
       
   157 	{
       
   158 public:
       
   159 	DSpiClientChannel();
       
   160 	~DSpiClientChannel();
       
   161 	virtual TInt DoCreate(TInt aUnit, const TDesC8* aInfo, const TVersion& aVer);
       
   162 
       
   163 protected:
       
   164 	static void Handler(TAny *aParam);
       
   165 	virtual void HandleMsg(TMessageBase* aMsg); // Note: this is a pure virtual in DLogicalChannel
       
   166 	TInt DoControl(TInt aId, TAny* a1, TAny* a2);
       
   167 	TInt DoRequest(TInt aId, TRequestStatus* aStatus, TAny* a1, TAny* a2);
       
   168 
       
   169 	// set of example transfers with transactions queued synchronously
       
   170 	TInt HalfDuplexSingleWrite();
       
   171 	TInt HalfDuplexMultipleWrite();
       
   172 	TInt HalfDuplexSingleRead();
       
   173 	TInt HalfDuplexMultipleRead();
       
   174 	TInt HalfDuplexMultipleWriteRead();
       
   175 	TInt FullDuplexSingle();
       
   176 	TInt FullDuplexMultiple();
       
   177 	TInt HalfDuplexExtendable();
       
   178 	TInt FullDuplexExtendable();
       
   179 
       
   180 
       
   181 private:
       
   182 	TRequestStatus iStatus;
       
   183 	DThread* iClient;
       
   184 	};
       
   185 
       
   186 // Below is additional stuff for testing with local loopback
       
   187 // the IsLoopbackAvailable function checks if McSPI3 is configured to use pins from extension header
       
   188 // (Beagleboard) and if these pins are physically connected (e.g. with jumper)- in order to determine
       
   189 // if duplex transfers should receive the same data that was sent to the bus..
       
   190 #include <assp/omap3530_assp/omap3530_scm.h>
       
   191 #include <assp/omap3530_assp/omap3530_gpio.h>
       
   192 const TInt KSpi3_SIMO_Pin = 131;
       
   193 const TInt KSpi3_SOMI_Pin = 132;
       
   194 
       
   195 inline TBool IsLoopbackAvailable()
       
   196 	{
       
   197 	// first check, if pad is configured to use SPI (this will confirm, if pins are used that way)
       
   198 	// this is their configuration (EMode1)
       
   199 	//	CONTROL_PADCONF_MMC2_CLK,  SCM::EMsw, SCM::EMode1, // mcspi3_simo
       
   200 	//  CONTROL_PADCONF_MMC2_DAT0, SCM::ELsw, SCM::EMode1, // mcspi3_somi
       
   201 	TUint mode_MMC2_CLK = SCM::GetPadConfig(CONTROL_PADCONF_MMC2_CLK, SCM::EMsw);
       
   202 	TUint mode_MMC2_DAT0 = SCM::GetPadConfig(CONTROL_PADCONF_MMC2_DAT0, SCM::ELsw);
       
   203 
       
   204 	if(!(mode_MMC2_CLK & SCM::EMode1) ||
       
   205 	   !(mode_MMC2_DAT0 & SCM::EMode1))
       
   206 		{
       
   207 		return EFalse; // either other pins are used or SPI3 is not configured at all..
       
   208 		}
       
   209 
       
   210 	// swap pins to be GPIO (EMode4)
       
   211 	SCM::SetPadConfig(CONTROL_PADCONF_MMC2_CLK, SCM::EMsw, SCM::EMode4 | SCM::EInputEnable);
       
   212 	SCM::SetPadConfig(CONTROL_PADCONF_MMC2_DAT0, SCM::ELsw, SCM::EMode4 | SCM::EInputEnable);
       
   213 
       
   214 	// set SIMO pin as output
       
   215 	GPIO::SetPinDirection(KSpi3_SIMO_Pin, GPIO::EOutput);
       
   216 	GPIO::SetPinMode(KSpi3_SIMO_Pin, GPIO::EEnabled);
       
   217 
       
   218 	// and SOMI pin as input
       
   219 	GPIO::SetPinDirection(KSpi3_SOMI_Pin, GPIO::EInput);
       
   220 	GPIO::SetPinMode(KSpi3_SOMI_Pin, GPIO::EEnabled);
       
   221 
       
   222 	TBool result = ETrue;
       
   223 	GPIO::TGpioState pinState = GPIO::EHigh;
       
   224 
       
   225 	// test 1: set SIMO to ELow and check if SOMI is the same
       
   226 	GPIO::SetOutputState(KSpi3_SIMO_Pin, GPIO::ELow);
       
   227 	GPIO::GetInputState(KSpi3_SOMI_Pin, pinState);
       
   228 	if(pinState != GPIO::ELow)
       
   229 		{
       
   230 		result = EFalse;
       
   231 		}
       
   232 	else
       
   233 		{
       
   234 		// test 2: set SIMO to EHigh and check if SOMI is the same
       
   235 		GPIO::SetOutputState(KSpi3_SIMO_Pin, GPIO::EHigh);
       
   236 		GPIO::GetInputState(KSpi3_SOMI_Pin, pinState);
       
   237 		if(pinState != GPIO::EHigh)
       
   238 			{
       
   239 			result = EFalse;
       
   240 			}
       
   241 		}
       
   242 
       
   243 	// restore back oryginal pad configuration for these pins
       
   244 	SCM::SetPadConfig(CONTROL_PADCONF_MMC2_CLK,  SCM::EMsw, mode_MMC2_CLK);
       
   245 	SCM::SetPadConfig(CONTROL_PADCONF_MMC2_DAT0, SCM::ELsw, mode_MMC2_DAT0);
       
   246 
       
   247 	return result;
       
   248 	}
       
   249 
       
   250 #endif /* __KERNEL_MODE__ */
       
   251 
       
   252 #endif /* __D_SPI_CLIENT_MASTER__ */