omap3530/omap3530_drivers/spi/master.cpp
branchBeagle_BSP_dev
changeset 85 d93b485c1325
parent 84 09e266454dcf
child 112 fdfa12d9a47a
equal deleted inserted replaced
84:09e266454dcf 85:d93b485c1325
   183 		{
   183 		{
   184 		slavePinSet  =  slaveAddr > 3 ?  3 : 2; // slaveAddr: 2-3: pin set 2(1*); 4-5: pin set 3(2*)
   184 		slavePinSet  =  slaveAddr > 3 ?  3 : 2; // slaveAddr: 2-3: pin set 2(1*); 4-5: pin set 3(2*)
   185 		slaveAddr &= 1; // modulo 2 (i.e. 2 CS for McSPI3)
   185 		slaveAddr &= 1; // modulo 2 (i.e. 2 CS for McSPI3)
   186 		}
   186 		}
   187 
   187 
       
   188 	// reconfigure pins if needed..
       
   189 	if(slavePinSet != iCurrSlavePinSet)
       
   190 		{
       
   191 		iCurrSlavePinSet = slavePinSet;
       
   192 		SetupSpiPins(iChannelNumber, iCurrSlavePinSet);
       
   193 		}
       
   194 
   188 	// store configuration parameters
   195 	// store configuration parameters
   189 	iCurrSS          = slaveAddr;
   196 	iCurrSS          = slaveAddr;
   190 	iCurrSlavePinSet = slavePinSet;
       
   191 	iCurrHeader      = newHeader; //copy the header..
   197 	iCurrHeader      = newHeader; //copy the header..
   192 
   198 
   193 	return KErrNone;
   199 	return KErrNone;
   194 	}
   200 	}
   195 
   201 
   196 // Init the hardware with the data provided in the transaction and slave-address field
   202 // Init the hardware with the data provided in the transaction and slave-address field
   197 // (these values are already stored in the iCurrHeader)
   203 // (these values are already stored in the iCurrHeader)
   198 TInt DSpiMasterBeagle::ConfigureInterface()
   204 TInt DSpiMasterBeagle::ConfigureInterface()
   199 	{
   205 	{
   200 	DBGPRINT(Kern::Printf("ConfigureInterface()"));
   206 	DBGPRINT(Kern::Printf("ConfigureInterface()"));
   201 
       
   202 	// make sure pins are set up properly (only for McSPI3)
       
   203 	if(iCurrSlavePinSet == 2)
       
   204 		{
       
   205 		SetupSpiPins(iChannelNumber, iCurrSlavePinSet);
       
   206 		}
       
   207 
   207 
   208 	// soft reset the SPI..
   208 	// soft reset the SPI..
   209 	TUint val = AsspRegister::Read32(iHwBase + MCSPI_SYSCONFIG);
   209 	TUint val = AsspRegister::Read32(iHwBase + MCSPI_SYSCONFIG);
   210 	val = MCSPI_SYSCONFIG_SOFTRESET;  // issue reset
   210 	val = MCSPI_SYSCONFIG_SOFTRESET;  // issue reset
   211 
   211 
   270 	// but at the momment IIC SPI is used in 'single' mode onlny..
   270 	// but at the momment IIC SPI is used in 'single' mode onlny..
   271 	val |= MCSPI_CHxCONF_FFEW;
   271 	val |= MCSPI_CHxCONF_FFEW;
   272 //	val |= MCSPI_CHxCONF_FFER; // fifo enable for receive.. (TODO)
   272 //	val |= MCSPI_CHxCONF_FFER; // fifo enable for receive.. (TODO)
   273 #endif
   273 #endif
   274 
   274 
       
   275 	val |= (iCurrHeader.iTransactionWaitCycles & 3) << MCSPI_CHxCONF_TCS_SHIFT;
       
   276 
   275 	// update the register..
   277 	// update the register..
   276 	AsspRegister::Write32(iHwBase + MCSPI_CHxCONF(iCurrSS), val);
   278 	AsspRegister::Write32(iHwBase + MCSPI_CHxCONF(iCurrSS), val);
   277 
   279 
   278 	// set spim_somi pin direction to input
   280 	// set spim_somi pin direction to input
   279 	val = MCSPI_SYST_SPIDATDIR0;
   281 	val = MCSPI_SYST_SPIDATDIR0;
   289 		}
   291 		}
   290 
   292 
   291 	// Set the MS bit to 0 to provide the clock (ie. to setup as master)
   293 	// Set the MS bit to 0 to provide the clock (ie. to setup as master)
   292 #ifndef SINGLE_MODE
   294 #ifndef SINGLE_MODE
   293 	AsspRegister::Write32(iHwBase + MCSPI_MODULCTRL, MCSPI_MODULCTRL_MS_MASTER);
   295 	AsspRegister::Write32(iHwBase + MCSPI_MODULCTRL, MCSPI_MODULCTRL_MS_MASTER);
       
   296 	// change the pad config - now the SPI drives the line appropriately..
       
   297 	SetCsActive(iChannelNumber, iCurrSS, iCurrSlavePinSet);
   294 #else
   298 #else
   295 	AsspRegister::Write32(iHwBase + MCSPI_MODULCTRL, MCSPI_MODULCTRL_MS_MASTER | MCSPI_MODULCTRL_SINGLE);
   299 	AsspRegister::Write32(iHwBase + MCSPI_MODULCTRL, MCSPI_MODULCTRL_MS_MASTER | MCSPI_MODULCTRL_SINGLE);
   296 #endif
   300 #endif
   297 
   301 
   298 	return KErrNone;
   302 	return KErrNone;
   799 
   803 
   800 void DSpiMasterBeagle::ExitComplete(TInt aErr, TBool aComplete /*= ETrue*/)
   804 void DSpiMasterBeagle::ExitComplete(TInt aErr, TBool aComplete /*= ETrue*/)
   801 	{
   805 	{
   802 	DBGPRINT(Kern::Printf("DSpiMasterBeagle::ExitComplete, aErr %d, aComplete %d", aErr, aComplete));
   806 	DBGPRINT(Kern::Printf("DSpiMasterBeagle::ExitComplete, aErr %d, aComplete %d", aErr, aComplete));
   803 
   807 
   804 	// make sure CS is in inactive state (for the current / last transaction) on error
       
   805 	// TODO: add extendable transaction support (..i.e. with no de-assertion of CS pin between such transactions)
       
   806 	SetCsInactive(iChannelNumber, iCurrSS, iCurrHeader.iSSPinActiveMode, iCurrSlavePinSet);
       
   807 
       
   808 	// disable this channel
       
   809 	AsspRegister::Modify32(iHwBase + MCSPI_CHxCTRL(iCurrSS), MCSPI_CHxCTRL_EN, 0);
       
   810 
   808 
   811 	// in the case of error - make sure to reset the channel
   809 	// in the case of error - make sure to reset the channel
   812 	if(aErr != KErrNone)
   810 	if(aErr != KErrNone)
   813 		{
   811 		{
       
   812 		// make sure CS is in inactive state (for the current / last transaction) on error
       
   813 		// TODO: add extendable transaction support (..i.e. with no de-assertion of CS pin between such transactions)
       
   814 		SetCsInactive(iChannelNumber, iCurrSS, iCurrHeader.iSSPinActiveMode, iCurrSlavePinSet);
       
   815 
       
   816 		// disable this channel
       
   817 		AsspRegister::Modify32(iHwBase + MCSPI_CHxCTRL(iCurrSS), MCSPI_CHxCTRL_EN, 0);
       
   818 
   814 		AsspRegister::Write32(iHwBase + MCSPI_SYSCONFIG, MCSPI_SYSCONFIG_SOFTRESET);
   819 		AsspRegister::Write32(iHwBase + MCSPI_SYSCONFIG, MCSPI_SYSCONFIG_SOFTRESET);
   815 		iCurrSS = -1; // make sure the interface will be re-configured at next transaction
   820 		iCurrSS = -1; // make sure the interface will be re-configured at next transaction
   816 		}
   821 		}
   817 
   822 
   818 	// Disable interrupts for the channel
   823 	// Disable interrupts for the channel
   861 		TConfigSpiV01 &header = (*(TConfigSpiBufV01*) (aHdrBuff))();
   866 		TConfigSpiV01 &header = (*(TConfigSpiBufV01*) (aHdrBuff))();
   862 
   867 
   863 		// check if word width and clock are supported
   868 		// check if word width and clock are supported
   864 		if(SpiWordWidth(header.iWordWidth) < KMinSpiWordWidth ||
   869 		if(SpiWordWidth(header.iWordWidth) < KMinSpiWordWidth ||
   865 		   SpiClkValue(header.iClkSpeedHz) < 0 || // == KErrNotSupported
   870 		   SpiClkValue(header.iClkSpeedHz) < 0 || // == KErrNotSupported
   866 		   header.iBitOrder == ELsbFirst) // this SPI only transmits MSB fist
   871 		   header.iBitOrder == ELsbFirst ||  // this SPI only transmits MSB fist
       
   872 		   (TUint)header.iTransactionWaitCycles > KMaxTransactionWaitTime) // max 3(+.5) cycles between words
   867 			{
   873 			{
   868 #ifdef _DEBUG
   874 #ifdef _DEBUG
   869 			if(header.iBitOrder == ELsbFirst)
   875 			if(header.iBitOrder == ELsbFirst)
   870 				DBG_ERR(Kern::Printf("iClkSpeedHz value (%d) is not supported", header.iClkSpeedHz));
   876 				DBG_ERR(Kern::Printf("iClkSpeedHz value (%d) is not supported", header.iClkSpeedHz));
   871 			if(SpiClkValue(header.iClkSpeedHz) < 0)
   877 			if(SpiClkValue(header.iClkSpeedHz) < 0)
   872 				DBG_ERR(Kern::Printf("iClkSpeedHz: %d is not supported", header.iClkSpeedHz));
   878 				DBG_ERR(Kern::Printf("iClkSpeedHz: %d is not supported", header.iClkSpeedHz));
   873 			if((SpiWordWidth(header.iWordWidth)+ 1) >> MCSPI_CHxCONF_WL_OFFSET < KMinSpiWordWidth)
   879 			if((SpiWordWidth(header.iWordWidth)+ 1) >> MCSPI_CHxCONF_WL_OFFSET < KMinSpiWordWidth)
   874 				DBG_ERR(Kern::Printf("iWordWidth: %d is not supported, min value is: %d",
   880 				DBG_ERR(Kern::Printf("iWordWidth: %d is not supported, min value is: %d",
   875 						              SpiWordWidth(header.iWordWidth), KMinSpiWordWidth));
   881 						             SpiWordWidth(header.iWordWidth), KMinSpiWordWidth));
       
   882 			if((TUint)header.iTransactionWaitCycles > 3)
       
   883 				DBG_ERR(Kern::Printf("iTransactionWaitCycles: %d is not supported, value should be from 0 to %d",
       
   884 				                     header.iTransactionWaitCycles, KMaxTransactionWaitTime));
       
   885 
   876 			DumpHeader(header);
   886 			DumpHeader(header);
   877 #endif
   887 #endif
   878 			r = KErrNotSupported;
   888 			r = KErrNotSupported;
   879 			DBG_ERR(Kern::Printf("DSpiMasterBeagle::CheckHdr()failed, r = %d", r));
   889 			DBG_ERR(Kern::Printf("DSpiMasterBeagle::CheckHdr()failed, r = %d", r));
   880 			}
   890 			}