Update SPI master pin handling: added dynamic pin configuration for McSPI3 (needed if want to use multiple device on this interface. Now following number of Slave devices is available: McSPI1: 4, McSPI2: 2, McSPI3: 6 (2 per each pin configuration), McSPI4: 1. Only McSPI3 and McSPI4 are available now -there are issues with McSPI1 & 2 due to register access (something wrong with mapping? There is Fault Category: Exception Fault Reason: 10000000
--- a/omap3530/beagleboard/bootstrap/beagle.s Wed Sep 22 23:37:20 2010 +0100
+++ b/omap3530/beagleboard/bootstrap/beagle.s Tue Sep 28 02:37:35 2010 +0100
@@ -25,7 +25,7 @@
;
; Platform specific constant definitions
-DRamBankBase EQU 0x80000000 ; 256M of DRAM
+DRamBankBase EQU 0x80000000 ; 256M of DRAM
DRamBankMaxSize EQU 0x10000000
; HW used by bootstrap
@@ -415,7 +415,7 @@
IF :DEF: CFG_CPU_ARM1136 :LAND: (:LNOT: :DEF: CFG_CPU_ARM1136_ERRATUM_364296_FIXED)
DCD BPR_FinalMMUCRSet, ExtraMMUCR + MMUCR_FI
DCD BPR_AuxCRSet, DefaultAuxCRSet + 0x80000000
- ENDIF
+ ENDIF
DCD -1 ; terminator
@@ -577,7 +577,7 @@
MOV r2, #KUART16XMode
STR r2, [r1, #KHwUartMdr1]
-
+
MOV r1, #0x19000 ; Set up delay loop to allow line to settle
SUBS r1, r1, #1
SUBNE pc, pc, #12
@@ -637,7 +637,7 @@
DCD ReservePhysicalMemory ; reserve physical RAM if required
DCD GetParameters ; get platform dependent parameters
DCD FinalInitialise ; Final initialisation before booting the kernel
- DCD HandleAllocRequest ; allocate memory
+ DCD HandleAllocRequest ; allocate memory
DCD GetPdeValue ; usually in generic code
DCD GetPteValue ; usually in generic code
DCD PageTableUpdate ; usually in generic code
--- a/omap3530/beagleboard/src/variant.cpp Wed Sep 22 23:37:20 2010 +0100
+++ b/omap3530/beagleboard/src/variant.cpp Tue Sep 28 02:37:35 2010 +0100
@@ -37,16 +37,16 @@
//These constants define Custom Restart Reasons in SuperPage::iHwStartupReason
const TUint KHtCustomRestartMax = 0xff;
const TUint KHtCustomRestartShift = 8;
-const TUint KHtCustomRestartMask = KHtCustomRestartMax << KHtCustomRestartShift;
+const TUint KHtCustomRestartMask = KHtCustomRestartMax << KHtCustomRestartShift;
//TODO: unncomment when referenced
-const TUint KHtRestartStartupModesMax = 0xf; // Variable, platform dependant
-//const TUint KHtRestartStartupModesShift = 16; // Variable, platform dependant
+const TUint KHtRestartStartupModesMax = 0xf; // Variable, platform dependant
+//const TUint KHtRestartStartupModesShift = 16; // Variable, platform dependant
//const TUint KHtRestartStartupModesMask = KHtRestartStartupModesMax << KHtRestartStartupModesShift;
void BeagleVariantFault(TInt aLine)
{
- Kern::Fault("BeagleVariant",aLine);
+ Kern::Fault("BeagleVariant",aLine);
}
#define V_FAULT() BeagleVariantFault(__LINE__)
@@ -78,15 +78,15 @@
//
// Specify the RAM zone configuration.
//
-// The lowest addressed zone must have the highest preference as the bootstrap
+// The lowest addressed zone must have the highest preference as the bootstrap
// will always allocate from the lowest address up. Once the kernel has initialised
// then the zone preferences will decide from which RAM zone memory is allocated.
//
// const TUint KVariantRamZoneCount = ?;
-// static const SRamZone KRamZoneConfig[KVariantRamZoneCount+1] =
+// static const SRamZone KRamZoneConfig[KVariantRamZoneCount+1] =
// iBase iSize iID iPref iFlags
// {
-// __SRAM_ZONE(0x????????, 0x???????, ?, ?, ?),
+// __SRAM_ZONE(0x????????, 0x???????, ?, ?, ?),
// ...
// __SRAM_ZONE(0x????????, 0x???????, ?, ?, ?),
// __SRAM_ZONE_END, // end of zone list
@@ -117,10 +117,10 @@
// ERamZoneOp_PowerUp: A RAM zone changing from used to empty.
// ERamZoneOp_PowerDown: A RAM zone changing from empty to used.
//
-
+
switch (aOp)
{
- case ERamZoneOp_Init:
+ case ERamZoneOp_Init:
break;
case ERamZoneOp_PowerUp:
break;
@@ -158,13 +158,13 @@
EXPORT_C TInt Variant::GetMsTickPeriod()
{
return TheVariant.MsTickPeriod();
-
+
}
void Beagle::Init3()
{
__KTRACE_OPT(KBOOT,Kern::Printf("Beagle::Init3()"));
-
+
Omap3530Assp::Init3();
Variant::Init3();
@@ -197,13 +197,13 @@
if( portNumber >= 0 )
{
Omap3530Uart::TUart uart( portNumber );
-
+
uart.Init();
uart.DefineMode( Omap3530Uart::TUart::EUart );
uart.SetBaud( Omap3530Uart::TUart::E115200 );
uart.SetDataFormat( Omap3530Uart::TUart::E8Data, Omap3530Uart::TUart::E1Stop, Omap3530Uart::TUart::ENone );
uart.Enable();
-
+
TheVariant.iDebugInitialised=ETrue;
}
}
@@ -245,14 +245,14 @@
//
// TO DO: (optional)
//
- // Idle Tick supression:
+ // Idle Tick supression:
// 1- obtain the number of idle Ticks before the next NTimer expiration (NTimerQ::IdleTime())
// 2- if the number of Ticks is large enough (criteria to be defined) reset the Hardware Timer
// to only interrupt again when the corresponding time has expired.
- // 2.1- the calculation of the new value to program the Hardware Timer with should take in
+ // 2.1- the calculation of the new value to program the Hardware Timer with should take in
// consideration the rounding value (NTimerQ::iRounding)
// 3- call the low level Sleep function (e'g. Bootstrap: address in iIdleFunction)
- // 4- on coming back from Idle need to read the Hardware Timer and determine if woken up due to
+ // 4- on coming back from Idle need to read the Hardware Timer and determine if woken up due to
// timer expiration (system time for new match<=current system time<system time for new match-tick period)
// or some other Interrupt.
// 4.1- if timer expiration, adjust System Time by adding the number of Ticks suppressed to NTimerQ::iMsCount
@@ -260,8 +260,8 @@
// above
//
// Support for different Sleep Modes:
- // Often the Sleep mode a platform can go to depends on how many resources such as clocks/voltages can be
- // turned Off or lowered to a suitable level. If different Sleep modes are supported this code may need
+ // Often the Sleep mode a platform can go to depends on how many resources such as clocks/voltages can be
+ // turned Off or lowered to a suitable level. If different Sleep modes are supported this code may need
// to be able to find out what power resources are On or Off or used to what level. This could be achieved by
// enquiring the Resource Manager (see \beagle_variant\inc\beagle_power.h).
// Then a decision could be made to what Sleep level we go to.
@@ -269,7 +269,7 @@
// Example calls:
// Obtain the number of Idle Ticks before the next NTimer expiration
// TInt aTicksLeft = NTimerQ::IdleTime();
- // ...
+ // ...
// Find out the deepest Sleep mode available for current resource usage and sleeping time
// TemplateResourceManager* aManager = TTemplatePowerController::ResourceManager();
// TemplateResourceManager::TSleepModes aMode = aManager -> MapSleepMode(aTicksLeft*MsTickPeriod());
@@ -368,24 +368,47 @@
}
case EVariantHalLedMaskSet:
{
- //
- // TO DO: (optional)
- //
// Set the state of any on-board LEDs, e.g:
- // TUint32 aLedMask=(TUint32)a1;
- // Variant::ModifyLedState(~aLedMask,aLedMask);
- //
+ TUint aLedMask=(TUint)a1;
+ GPIO::TGpioState led_state;
+ if(aLedMask & 1)
+ led_state = GPIO::EHigh;
+ else
+ led_state = GPIO::ELow;
+
+ r = GPIO::SetOutputState(KGPIO_LED0, led_state);
+
+ if(r == KErrNone)
+ {
+ if(aLedMask & 2)
+ led_state = GPIO::EHigh;
+ else
+ led_state = GPIO::ELow;
+
+ r = GPIO::SetOutputState(KGPIO_LED1, led_state);
+ }
break;
}
case EVariantHalLedMaskGet:
{
- //
- // TO DO: (optional)
- //
- // Read the state of any on-board LEDs, e.g:
- // TUint32 x = Variant::LedState();
- // kumemput32(a1, &x, sizeof(x));
- //
+ // Read the state of on-board LEDs
+ GPIO::TGpioState led_state;
+ TUint x = 0;
+ r = GPIO::GetOutputState(KGPIO_LED0, led_state);
+ if(r == KErrNone)
+ {
+ if(led_state == GPIO::EHigh)
+ x = 1;
+
+ r = GPIO::GetOutputState(KGPIO_LED1, led_state);
+ if(r == KErrNone)
+ {
+ if(led_state == GPIO::EHigh)
+ x |= 1 << 1;
+
+ kumemput32(a1, &x, sizeof(x));
+ }
+ }
break;
}
@@ -445,7 +468,7 @@
// Read the restart startup mode, e.g:
// TInt startup = (Kern::SuperPage().iHwStartupReason & KHtRestartStartupModesMask) >> KHtRestartStartupModesShift;
// kumemput32(a1, &startup, sizeof(TInt));
- break;
+ break;
}
case EVariantHalGetMaximumCustomRestartReasons:
@@ -468,7 +491,7 @@
// kumemput32(a1, &KHtRestartStartupModesMax, sizeof(TUint));
break;
}
-
+
default:
r=KErrNotSupported;
@@ -662,8 +685,8 @@
aDay=0;
aMonth=0;
TInt adjyear = aTime % KSecsDaysPer4Years;
-
-
+
+
if (adjyear<KSecsPerYr + KSecsPerDay)
{
GetMonthData(adjyear/KSecsPerDay, ETrue, aMonth, aDay);
@@ -679,7 +702,7 @@
TInt Beagle::SystemTimeInSecondsFrom2000(TInt& aTime)
{
-
+
if(!TPS65950::Initialized())
{
return KErrNotSupported;
@@ -687,7 +710,7 @@
TPS65950::TRtcTime time;
TPS65950::GetRtcData( time );
-
+
aTime = time.iSecond;
aTime += time.iMinute * KSecsPerMin;
aTime += time.iHour * KSecsPerHour;
@@ -708,9 +731,9 @@
{
aTime += mTab[isLeap][i] * KSecsPerDay;
}
-
+
aTime += (yrs/4) * KSecsDaysPer4Years;
-
+
if ( isLeap )
{
// Add KSecsPerDay, because first year is always a leap year
@@ -725,8 +748,8 @@
{
return KErrNotSupported;
}
-
- TPS65950::TRtcTime rtc;
+
+ TPS65950::TRtcTime rtc;
TInt secs = aTime % KSecsPerMin;
TInt mins_insecs = (aTime % KSecsPerHour) - secs;
TInt hours_insecs = (aTime % KSecsPerDay) - mins_insecs - secs;
@@ -736,7 +759,7 @@
rtc.iHour = hours_insecs/KSecsPerHour;
SecondsToYMD( aTime, rtc.iYear, rtc.iMonth, rtc.iDay);
-
+
TPS65950::SetRtcData( rtc );
return KErrNone;
--- a/omap3530/omap3530_drivers/spi/bld.inf Wed Sep 22 23:37:20 2010 +0100
+++ b/omap3530/omap3530_drivers/spi/bld.inf Tue Sep 28 02:37:35 2010 +0100
@@ -18,7 +18,8 @@
ARMV5
PRJ_EXPORTS
-spi.iby rom/omap3530/
+spi.iby rom/omap3530/
+
PRJ_MMPFILES
spi
--- a/omap3530/omap3530_drivers/spi/master.cpp Wed Sep 22 23:37:20 2010 +0100
+++ b/omap3530/omap3530_drivers/spi/master.cpp Tue Sep 28 02:37:35 2010 +0100
@@ -47,18 +47,17 @@
iTransferEndDfc(TransferEndDfc, this, KIicPslDfcPriority)
{
iChannelNumber = aChannelNumber;
- iIrqId = KMcSpiIrqId[iChannelNumber];
+ iIrqId = KMcSpiIrqId[iChannelNumber];
iHwBase = KMcSpiRegBase[iChannelNumber];
- iState = EIdle;
- iCurrSS = -1;
+ iState = EIdle;
+ iCurrSS = -1; // make sure channel will be fully configured on the first use
DBGPRINT(Kern::Printf("DSpiMasterBeagle::DSpiMasterBeagle: at 0x%x, iChannelNumber = %d", this, iChannelNumber));
}
TInt DSpiMasterBeagle::DoCreate()
{
- DBGPRINT(Kern::Printf("\nDSpiMasterBeagle::DoCreate() ch: %d \n", iChannelNumber));
+ DBGPRINT(Kern::Printf("\nDSpiMasterBeagle::DoCreate() McSPI%d \n", iChannelNumber+1));
DBGPRINT(Kern::Printf("HW revision is %x", AsspRegister::Read32(iHwBase + MCSPI_REVISION)));
-
TInt r = KErrNone;
// Create the DFCQ to be used by the channel
@@ -99,8 +98,8 @@
Prcm::SetClockState( Prcm::EClkMcSpi3_I, Prcm::EClkOn );
// TODO:consider auto-idle for PRCM.CM_AUTOIDLE1_CORE
+ // setup default spi pins. For channel 2 (McSPI3) it can be configured dynamically
SetupSpiPins(iChannelNumber);
- // end of system wide settings..
return r;
}
@@ -148,44 +147,50 @@
iCurrTransaction = aTransaction;
// Configure the hardware to support the transaction
- TInt r = KErrNone;
- if(TransConfigDiffersFromPrev())
+ TInt r = PrepareConfiguration();
+ if(r == KErrNone)
{
r = ConfigureInterface();
- if(r != KErrNone)
+ if(r == KErrNone)
{
- return r;
+ // start processing transfers of this transaction.
+ r = ProcessNextTransfers();
}
}
-
- // start processing transfers of this transaction.
- r = ProcessNextTransfers();
return r;
}
-TBool DSpiMasterBeagle::TransConfigDiffersFromPrev()
+TInt DSpiMasterBeagle::PrepareConfiguration()
{
TConfigSpiV01 &newHeader = (*(TConfigSpiBufV01*) (GetTransactionHeader(iCurrTransaction)))();
// get the slave address (i.e. known as a 'channel' for the current SPI module)
- TInt slaveAddr = GET_SLAVE_ADDR(iCurrTransaction->GetBusId());
- DBGPRINT(Kern::Printf("slaveAddr %x", slaveAddr));
+ TInt busId = iCurrTransaction->GetBusId();
+ TInt slaveAddr = GET_SLAVE_ADDR(busId);
+ TInt slavePinSet = 0;
+
+ if(slaveAddr >= KMcSpiNumSupportedSlaves[iChannelNumber]) // address is 0-based
+ {
+ DBG_ERR(Kern::Printf("Slave address for McSPI%d should be < %, was: %d !",
+ iChannelNumber + 1, KMcSpiNumSupportedSlaves[iChannelNumber], slaveAddr));
+ return KErrArgument; // Slave address out of range
+ }
- // compare it to the previous configuration..
- if(slaveAddr != iCurrSS ||
- newHeader.iWordWidth != iCurrHeader.iWordWidth ||
- newHeader.iClkSpeedHz != iCurrHeader.iClkSpeedHz ||
- newHeader.iClkMode != iCurrHeader.iClkMode ||
- newHeader.iTimeoutPeriod != iCurrHeader.iTimeoutPeriod ||
- newHeader.iBitOrder != iCurrHeader.iBitOrder ||
- newHeader.iTransactionWaitCycles != iCurrHeader.iTransactionWaitCycles ||
- newHeader.iSSPinActiveMode != iCurrHeader.iSSPinActiveMode)
+ // Slave addresses > 1 for McSPI3 (iChannel2) really means alternative pin settings,
+ // so adjust it in such case. *Pin set indexes are +1 to skip over the pin set for McSPI4
+ // channel in the pin configuration table.
+ if(iChannelNumber == 2 && slaveAddr > 1)
{
- iCurrSS = slaveAddr;
- iCurrHeader = newHeader; //copy the header..
- return ETrue;
+ slavePinSet = slaveAddr > 3 ? 3 : 2; // slaveAddr: 2-3: pin set 2(1*); 4-5: pin set 3(2*)
+ slaveAddr &= 1; // modulo 2 (i.e. 2 CS for McSPI3)
}
- return EFalse;
+
+ // store configuration parameters
+ iCurrSS = slaveAddr;
+ iCurrSlavePinSet = slavePinSet;
+ iCurrHeader = newHeader; //copy the header..
+
+ return KErrNone;
}
// Init the hardware with the data provided in the transaction and slave-address field
@@ -194,6 +199,12 @@
{
DBGPRINT(Kern::Printf("ConfigureInterface()"));
+ // make sure pins are set up properly (only for McSPI3)
+ if(iCurrSlavePinSet == 2)
+ {
+ SetupSpiPins(iChannelNumber, iCurrSlavePinSet);
+ }
+
// soft reset the SPI..
TUint val = AsspRegister::Read32(iHwBase + MCSPI_SYSCONFIG);
val = MCSPI_SYSCONFIG_SOFTRESET; // issue reset
@@ -204,9 +215,14 @@
while (!(val & MCSPI_SYSSTATUS_RESETDONE))
val = AsspRegister::Read32(iHwBase + MCSPI_SYSSTATUS);
- //AsspRegister::Write32(iHwBase + MCSPI_SYSCONFIG, MCSPI_SYSCONFIG_CLOCKACTIVITY_ALL_ON);
-
- AsspRegister::Write32(iHwBase + MCSPI_IRQSTATUS, ~0); // clear all interrupts (for now) -- normally only for channel..
+ // disable and clear all interrupts..
+ AsspRegister::Write32(iHwBase + MCSPI_IRQENABLE, 0);
+ AsspRegister::Write32(iHwBase + MCSPI_IRQSTATUS,
+ MCSPI_IRQ_RX_FULL(iCurrSS) |
+ MCSPI_IRQ_RX_FULL(iCurrSS) |
+ MCSPI_IRQ_TX_UNDERFLOW(iCurrSS) |
+ MCSPI_IRQ_TX_EMPTY(iCurrSS) |
+ MCSPI_IRQ_RX_OVERFLOW);
// channel configuration
// Set the SPI1.MCSPI_CHxCONF[18] IS bit to 0 for the spi1_somi pin in receive mode.
@@ -259,24 +275,19 @@
// update the register..
AsspRegister::Write32(iHwBase + MCSPI_CHxCONF(iCurrSS), val);
- // CS (SS) pin direction..
+ // set spim_somi pin direction to input
val = MCSPI_SYST_SPIDATDIR0;
- // drive csx pin high or low
-// val |= (iCurrHeader.iSSPinActiveMode == ESpiCSPinActiveLow)? 1 << iCurrSS : 0;
-// AsspRegister::Modify32(iHwBase + MCSPI_SYST, val);
-
+ // drive csx pin to inactive state
if(iCurrHeader.iSSPinActiveMode == ESpiCSPinActiveLow)
{
- AsspRegister::Modify32(iHwBase + MCSPI_SYST, 1u << iCurrSS, MCSPI_SYST_SPIDATDIR0);
+ AsspRegister::Modify32(iHwBase + MCSPI_SYST, 1u << iCurrSS, 0);
}
else
{
- AsspRegister::Modify32(iHwBase + MCSPI_SYST, 0, (1u << iCurrSS) | MCSPI_SYST_SPIDATDIR0);
+ AsspRegister::Modify32(iHwBase + MCSPI_SYST, 0, (1u << iCurrSS));
}
-
-
// Set the MS bit to 0 to provide the clock (ie. to setup as master)
#ifndef SINGLE_MODE
AsspRegister::Write32(iHwBase + MCSPI_MODULCTRL, MCSPI_MODULCTRL_MS_MASTER);
@@ -477,7 +488,7 @@
AsspRegister::Modify32(iHwBase + MCSPI_CHxCONF(iCurrSS), 0, MCSPI_CHxCONF_FORCE);
// change the pad config - now the SPI drives the line appropriately..
- SetCsActive(iChannelNumber, iCurrSS);
+ SetCsActive(iChannelNumber, iCurrSS, iCurrSlavePinSet);
#endif /*SINGLE_MODE*/
#ifdef USE_TX_FIFO
@@ -538,7 +549,7 @@
AsspRegister::Modify32(iHwBase + MCSPI_CHxCONF(iCurrSS), 0, MCSPI_CHxCONF_FORCE);
// change the pad config - now the SPI drives the line appropriately..
- SetCsActive(iChannelNumber, iCurrSS);
+ SetCsActive(iChannelNumber, iCurrSS, iCurrSlavePinSet);
#endif /*SINGLE_MODE*/
}
else
@@ -761,28 +772,12 @@
Kern::Fault("SPI master: exiting not having received all?", 12));
}
- // make sure the CS pin is asserted..
- if(a->iCurrHeader.iSSPinActiveMode == ESpiCSPinActiveLow)
- {
- AsspRegister::Modify32(a->iHwBase + MCSPI_SYST, 0, 1 << a->iCurrSS);
- }
- else
- {
- AsspRegister::Modify32(a->iHwBase + MCSPI_SYST, 1 << a->iCurrSS, 0);
- }
-
#ifdef SINGLE_MODE
// manually de-assert CS line for this channel
AsspRegister::Modify32(a->iHwBase + MCSPI_CHxCONF(a->iCurrSS), MCSPI_CHxCONF_FORCE, 0);
- // drive csx pin high or low. Doing this here causes, that CS lines are toggled for each transfers.
- TUint val = (a->iCurrHeader.iSSPinActiveMode == ESpiCSPinActiveLow)? 1 << a->iCurrSS : 0;
- if (val)
- {
- AsspRegister::Modify32(a->iHwBase + MCSPI_SYST, 0, val);
- }
// put the CS signal to 'inactive' state (as on channel disable it would have a glitch)
- SetCsInactive(a->iChannelNumber, a->iCurrSS, a->iCurrHeader.iSSPinActiveMode);
+ SetCsInactive(a->iChannelNumber, a->iCurrSS, a->iCurrHeader.iSSPinActiveMode, a->iCurrSlavePinSet);
#endif
@@ -807,15 +802,19 @@
DBGPRINT(Kern::Printf("DSpiMasterBeagle::ExitComplete, aErr %d, aComplete %d", aErr, aComplete));
// make sure CS is in inactive state (for the current / last transaction) on error
- if(!aComplete)
+ // TODO: add extendable transaction support (..i.e. with no de-assertion of CS pin between such transactions)
+ SetCsInactive(iChannelNumber, iCurrSS, iCurrHeader.iSSPinActiveMode, iCurrSlavePinSet);
+
+ // disable this channel
+ AsspRegister::Modify32(iHwBase + MCSPI_CHxCTRL(iCurrSS), MCSPI_CHxCTRL_EN, 0);
+
+ // in the case of error - make sure to reset the channel
+ if(aErr != KErrNone)
{
- SetCsInactive(iChannelNumber, iCurrSS, iCurrHeader.iSSPinActiveMode);
+ AsspRegister::Write32(iHwBase + MCSPI_SYSCONFIG, MCSPI_SYSCONFIG_SOFTRESET);
+ iCurrSS = -1; // make sure the interface will be re-configured at next transaction
}
- // disable this channel (and reset..)
- AsspRegister::Modify32(iHwBase + MCSPI_CHxCTRL(iCurrSS), MCSPI_CHxCTRL_EN, 0);
- AsspRegister::Write32(iHwBase + MCSPI_SYSCONFIG, MCSPI_SYSCONFIG_SOFTRESET);
-
// Disable interrupts for the channel
Interrupt::Disable(iIrqId);
--- a/omap3530/omap3530_drivers/spi/master.h Wed Sep 22 23:37:20 2010 +0100
+++ b/omap3530/omap3530_drivers/spi/master.h Tue Sep 28 02:37:35 2010 +0100
@@ -41,8 +41,8 @@
virtual TInt HandleSlaveTimeout();
// Internal methods
+ TInt PrepareConfiguration();
TInt ConfigureInterface();
- TBool TransConfigDiffersFromPrev();
TInt ProcessNextTransfers();
TInt StartTransfer(TIicBusTransfer* aTransferPtr, TUint8 aType);
TInt DoTransfer(TUint8 aType);
@@ -88,6 +88,7 @@
TConfigSpiV01 iCurrHeader;
TInt iCurrSS;
+ TInt iCurrSlavePinSet;
};
#endif //__OMAP3530_SPI_MASTER_H__
--- a/omap3530/omap3530_drivers/spi/omap3530_spi.h Wed Sep 22 23:37:20 2010 +0100
+++ b/omap3530/omap3530_drivers/spi/omap3530_spi.h Tue Sep 28 02:37:35 2010 +0100
@@ -23,12 +23,10 @@
#include <assp/omap3530_assp/omap3530_scm.h>
#include <assp/omap3530_assp/omap3530_gpio.h>
-
#define BIT_MASK(shift,len) (((1u << (len)) - 1) << (shift))
#define GET_BITS(w,shift,len) (((w) >> (shift)) & ((1 << (len)) - 1))
#define SET_BITS(w,set,shift,len) ((w) &= ~BIT_MASK(shift, len), (w) |= ((set) << (shift)))
-
// Device Instance Summary
const TUint MCSPI1_phys = 0x48098000; // 4Kbytes
const TUint MCSPI2_phys = 0x4809A000; // 4Kbytes
@@ -49,7 +47,6 @@
Omap3530HwBase::TVirtual<MCSPI4_phys>::Value //McSPI module 4
};
-
//.. and IRQ lines for SPI channels
const TUint KMcSpiIrqId[] =
{
@@ -59,15 +56,17 @@
EOmap3530_IRQ48_SPI4_IRQ //McSPI module 4
};
-// available channels per module (i.e. number of 'slave select' inputs/outpus per module)
-const TUint KMcSpiNumChannels[] =
+// available channels per module i.e. number of 'slave select' inputs/outpus signals / addresses
+// per module.
+const TUint KMcSpiNumSupportedSlaves[] =
{
- 4, // channels 0 - 3
- 2, // channels 0 - 1
- 2, // channels 0 - 1
- 1 // channel 0 only
+ 4, // slave address range: 0 - 3
+ 2, // slave address range: 0 - 1
+ 6, // slave address range: 0 - 5 (0,1: pin option 0; 2,3: pin option 1; 4,5: pin option 2)
+ 1 // slave address range: 0 only
};
+
//---------------------------------------------------------------
// MCSPI Registers offsets and bits definitions
//----------------------------------
@@ -370,9 +369,21 @@
}
};
+// McSPI3 supports 3 different pin routing settings
+const TSpiPinConfig TSpiPinConfigMcSpi3_0 =
+ {
+ {CONTROL_PADCONF_MMC2_CLK, SCM::ELsw, 130, SCM::EMode1 | SCM::EInputEnable}, // mcspi3_clk
+ {CONTROL_PADCONF_MMC2_CLK, SCM::EMsw, 131, SCM::EMode1 | SCM::EInputEnable}, // mcspi3_simo
+ {CONTROL_PADCONF_MMC2_DAT0, SCM::ELsw, 132, SCM::EMode1 | SCM::EInputEnable}, // mcspi3_somi
+ {
+ {CONTROL_PADCONF_MMC2_DAT2, SCM::EMsw, 135, SCM::EMode1}, // mcspi3_cs0
+ {CONTROL_PADCONF_MMC2_DAT2, SCM::ELsw, 134, SCM::EMode1}, // mcspi3_cs1
+ {0, SCM::ELsw, 0, 0}, // not supported
+ {0, SCM::ELsw, 0, 0}, // not supported
+ }
+ };
-#if defined(SPI_MODULE_3_PIN_OPTION_2)
-const TSpiPinConfig TSpiPinConfigMcSpi3 =
+const TSpiPinConfig TSpiPinConfigMcSpi3_1 =
{
{CONTROL_PADCONF_DSS_DATA18, SCM::ELsw, 88, SCM::EMode2 | SCM::EInputEnable}, // mcspi3_clk
{CONTROL_PADCONF_DSS_DATA18, SCM::EMsw, 89, SCM::EMode2 | SCM::EInputEnable}, // mcspi3_simo
@@ -384,8 +395,8 @@
{0, SCM::ELsw, 0, 0}, // not supported
}
};
-#elif defined(SPI_MODULE_3_PIN_OPTION_3)
-const TSpiPinConfig TSpiPinConfigMcSpi3 =
+
+const TSpiPinConfig TSpiPinConfigMcSpi3_2 =
{
{CONTROL_PADCONF_ETK_D2, SCM::EMsw, 17, SCM::EMode1 | SCM::EInputEnable}, // mcspi3_clk
{CONTROL_PADCONF_ETK_D0, SCM::ELsw, 14, SCM::EMode1 | SCM::EInputEnable}, // mcspi3_simo
@@ -397,20 +408,6 @@
{0, SCM::ELsw, 0, 0}, // not supported
}
};
-#else // default option (for beagle- these are pins on the extension header)
-const TSpiPinConfig TSpiPinConfigMcSpi3 =
- {
- {CONTROL_PADCONF_MMC2_CLK, SCM::ELsw, 130, SCM::EMode1 | SCM::EInputEnable}, // mcspi3_clk
- {CONTROL_PADCONF_MMC2_CLK, SCM::EMsw, 131, SCM::EMode1 | SCM::EInputEnable}, // mcspi3_simo
- {CONTROL_PADCONF_MMC2_DAT0, SCM::ELsw, 132, SCM::EMode1 | SCM::EInputEnable}, // mcspi3_somi
- {
- {CONTROL_PADCONF_MMC2_DAT2, SCM::EMsw, 135, SCM::EMode1}, // mcspi3_cs0
- {CONTROL_PADCONF_MMC2_DAT2, SCM::ELsw, 134, SCM::EMode1}, // mcspi3_cs1
- {0, SCM::ELsw, 0, 0}, // not supported
- {0, SCM::ELsw, 0, 0}, // not supported
- }
- };
-#endif
const TSpiPinConfig TSpiPinConfigMcSpi4 =
{
@@ -429,10 +426,14 @@
{
TSpiPinConfigMcSpi1,
TSpiPinConfigMcSpi2,
- TSpiPinConfigMcSpi3,
- TSpiPinConfigMcSpi4
+ TSpiPinConfigMcSpi3_0, // (default mode for McSPI3 - SPI addresses: 0 and 1)
+ TSpiPinConfigMcSpi4,
+ TSpiPinConfigMcSpi3_1, // other pin mode for McSPI3.. (spi addresses: 2 and 3)
+ TSpiPinConfigMcSpi3_2 // other pin mode for McSPI3.. (spi addresses: 4 and 5)
};
+
#include "omap3530_spi.inl"
+
#endif /* __OMAP3530_SPI_H__ */
--- a/omap3530/omap3530_drivers/spi/omap3530_spi.inl Wed Sep 22 23:37:20 2010 +0100
+++ b/omap3530/omap3530_drivers/spi/omap3530_spi.inl Tue Sep 28 02:37:35 2010 +0100
@@ -20,23 +20,28 @@
// This sets the CS line to inactive mode (Specify aActiveMode as appropriate for configuration)
// The CS pin will be put back to the opposite mode - using GPIO.. THis is in order to always keep
// the CS line in an 'inactive' state (de-asserted) when the SPI is disabled.
-inline void SetCsInactive(TInt aModule, TInt aChannel, TSpiSsPinMode aActiveMode)
+inline void SetCsInactive(TInt aModule, TInt aChannel, TSpiSsPinMode aActiveMode, TUint aPinSetId = 0)
{
- //__ASSERT_DEBUG(aModule < KMaxSpiChannelsPerModule, Kern::Fault("omap3530_spi.inl, line: ", __LINE__)); // aChannel > module channels
+ __ASSERT_DEBUG(aModule < KMaxSpiChannelsPerModule, Kern::Fault("omap3530_spi.inl, line: ", __LINE__)); // aChannel > module channels
+ __ASSERT_DEBUG( aModule != 2 ? !aPinSetId : ETrue, Kern::Fault("omap3530_spi.inl, line: ", __LINE__)); // only channel 3 supports other pin configurations
+
// set the pin to the opposite to the currently active CS mode..
const TPinConfig& csConf = ModulePinConfig[aModule].iCs[aChannel];
- __ASSERT_DEBUG(csConf.iAddress, Kern::Fault("omap3530_spi.inl, line: ", __LINE__)); // aChannel > module channels
+ __ASSERT_DEBUG(csConf.iAddress, Kern::Fault("omap3530_spi.inl, line: ", __LINE__)); // don't try to use non-existing CS!
// now switch the pin mode..(making sure it is at the proper level before that)
GPIO::SetOutputState(csConf.iPinNumber, aActiveMode == ESpiCSPinActiveLow ? GPIO::EHigh : GPIO::ELow);
SCM::SetPadConfig(csConf.iAddress, csConf.iMswLsw, SCM::EMode4); // always go to mode 4 (gpio)
}
-void SetCsActive(TInt aModule, TInt aChannel)
+
+inline void SetCsActive(TInt aModule, TInt aChannel, TUint aPinSetId = 0)
{
- //__ASSERT_DEBUG(aModule < KMaxSpiChannelsPerModule, Kern::Fault("omap3530_spi.inl, line: ", __LINE__)); // aChannel > module channels
- const TPinConfig &csConf = ModulePinConfig[aModule].iCs[aChannel];
- __ASSERT_DEBUG(csConf.iAddress, Kern::Fault("omap3530_spi.inl, line: ", __LINE__)); // aChannel > module channels
+ __ASSERT_DEBUG(aModule < KMaxSpiChannelsPerModule, Kern::Fault("omap3530_spi.inl, line: ", __LINE__)); // aChannel > module channels
+ __ASSERT_DEBUG( aModule != 2 ? !aPinSetId : ETrue, Kern::Fault("omap3530_spi.inl, line: ", __LINE__)); // only channel 3 supports other pin configurations
+
+ const TPinConfig &csConf = ModulePinConfig[aModule + aPinSetId].iCs[aChannel];
+ __ASSERT_DEBUG(csConf.iAddress, Kern::Fault("omap3530_spi.inl, line: ", __LINE__)); // don't try to use non-existing CS!
// now switch the pin mode back to the SPI
SCM::SetPadConfig(csConf.iAddress, csConf.iMswLsw, csConf.iFlags | SCM::EInputEnable); // revert to intended mode
@@ -44,10 +49,13 @@
// Setup pad function for SPI pins..
-void SetupSpiPins(TUint aSpiModule)
+inline void SetupSpiPins(TUint aModule, TUint aPinSetId = 0)
{
- //__ASSERT_DEBUG(aModule < KMaxSpiChannelsPerModule, Kern::Fault("omap3530_spi.inl, line: ", __LINE__)); // aChannel > module channels
- const TSpiPinConfig& pinCnf = ModulePinConfig[aSpiModule];
+ __ASSERT_DEBUG(aModule < KMaxSpiChannelsPerModule, Kern::Fault("omap3530_spi.inl, line: ", __LINE__)); // aChannel > module channels
+ __ASSERT_DEBUG(aModule != 2 ? !aPinSetId : ETrue, Kern::Fault("omap3530_spi.inl, line: ", __LINE__)); // only channel 3 supports other pin configurations
+
+ const TSpiPinConfig& pinCnf = ModulePinConfig[aModule + aPinSetId];
+
SCM::SetPadConfig(pinCnf.iClk.iAddress, pinCnf.iClk.iMswLsw, pinCnf.iClk.iFlags);
SCM::SetPadConfig(pinCnf.iSimo.iAddress, pinCnf.iSimo.iMswLsw, pinCnf.iSimo.iFlags);
SCM::SetPadConfig(pinCnf.iSomi.iAddress, pinCnf.iSomi.iMswLsw, pinCnf.iSomi.iFlags);
@@ -57,12 +65,13 @@
{
if(pinCnf.iCs[i].iPinNumber)
{
+ // pre-set the GPIO..
GPIO::SetPinDirection(pinCnf.iCs[i].iPinNumber, GPIO::EOutput);
GPIO::SetPinMode(pinCnf.iCs[i].iPinNumber, GPIO::EEnabled);
}
else
{
- break;
+ break; // no more channels (cs signals)
}
}
}
--- a/omap3530/omap3530_drivers/spi/psl_init.cpp Wed Sep 22 23:37:20 2010 +0100
+++ b/omap3530/omap3530_drivers/spi/psl_init.cpp Tue Sep 28 02:37:35 2010 +0100
@@ -50,8 +50,8 @@
// The first argument repesents the PSL-assigned channel number
// The second argument, DIicBusChannel::ESpi, should be replaced with the relevant bus type for the PSL
// chan = DSpiMasterBeagle::New(i, DIicBusChannel::ESpi, DIicBusChannel::EFullDuplex);
- if((TInt)KIicPslNumOfChannels == 1)// TODO: hack - only for the time being - enable channel 3
- chan = DSpiMasterBeagle::New(2, DIicBusChannel::ESpi, DIicBusChannel::EFullDuplex);
+ if((TInt)KIicPslNumOfChannels == 2)// TODO: hack - only for the time being - enable channel 3
+ chan = DSpiMasterBeagle::New(i+2, DIicBusChannel::ESpi, DIicBusChannel::EFullDuplex);
else
{
Kern::Printf("remove hack from here: %s,line %d", __FILE__, __LINE__);
--- a/omap3530/omap3530_drivers/spi/psl_init.h Wed Sep 22 23:37:20 2010 +0100
+++ b/omap3530/omap3530_drivers/spi/psl_init.h Tue Sep 28 02:37:35 2010 +0100
@@ -19,7 +19,8 @@
#ifndef __OMAP3530_SPI_PSL_H__
#define __OMAP3530_SPI_PSL_H__
-const TInt KIicPslNumOfChannels = 1; // Number of channels supported // TODO only one for now..
+const TInt KIicPslNumOfChannels = 2; // Number of channels supported // TODO only two 3 and 4 for now..
+// FIXME - there is a crash when using channels 1 and 2 - when accesing registers at e.g. 0xc609a000
struct TIicOperationType
{
--- a/omap3530/omap3530_drivers/spi/spi.mmp Wed Sep 22 23:37:20 2010 +0100
+++ b/omap3530/omap3530_drivers/spi/spi.mmp Tue Sep 28 02:37:35 2010 +0100
@@ -41,13 +41,6 @@
SOURCE slave.cpp
#endif
-// define one of the below values to switch PIN modes for McSPI3 to match your PCB connections.
-// i.e. McSPI3 can be routed to 3 different pin sets using below defines - if both commented out
-// the default routing is used, which takes McSPI3 out to the extension header (beagleboard).
-// See omap3530_spi.h for more details.
-//macro SPI_MODULE_3_PIN_OPTION_2
-//macro SPI_MODULE_3_PIN_OPTION_3
-
// PIL source
#include "../../../../../os/kernelhwsrv/kernel/eka/drivers/iic/iic_channel.mmh"
--- a/omap3530/omap3530_drivers/spi/test/d_spi_client_m.cpp Wed Sep 22 23:37:20 2010 +0100
+++ b/omap3530/omap3530_drivers/spi/test/d_spi_client_m.cpp Tue Sep 28 02:37:35 2010 +0100
@@ -14,6 +14,8 @@
//
// This test driver is a simple example IIC SPI client implementation - and a test to SPI implementation.
// It is an LDD but PDD or kernel extension can implement / use the IIC SPI bus exactly the same way.
+// There is a lot of code duplication in this test code, but this is in order to provide clear and separate implementation
+// for each of these use cases, which can serve as example usecases that should be easy to adopt for the real purpose.
//
// Note: IMPORTANT! -If you intend to make changes to the driver!
@@ -95,7 +97,9 @@
TInt DSpiClientTestFactory::Create(DLogicalChannelBase*& aChannel)
{
if (iOpenChannels >= KMaxNumChannels)
+ {
return KErrOverflow;
+ }
aChannel = new DSpiClientChannel;
return aChannel ? KErrNone : KErrNoMemory;
@@ -232,7 +236,7 @@
aId, aStatus, a1, a2));
// TODO: There are unimplemented functions - returning KErrNotSupported - treat this as a 'sort of'
- // of test-driven development.. Ideally - they should all be implemented..
+ // test-driven development.. Ideally - they should all be implemented..
TInt r = KErrNone;
switch (aId)
{
@@ -367,7 +371,7 @@
TUint32 busId = 0;
SET_BUS_TYPE(busId, DIicBusChannel::ESpi);
- SET_CHAN_NUM(busId, 2); // THis is the ModuleNumber, i.e. McSPIx (minus one), e.g. 2 for McSPI3
+ SET_CHAN_NUM(busId, 3); // THis is the ModuleNumber, i.e. McSPIx (minus one), e.g. 2 for McSPI3
SET_SLAVE_ADDR(busId, 0); // THis is the ChannelNumber (Slave number of the above McSPIx)
// create header
--- a/omap3530/shared/serialkeyb/serialkeyboard.cpp Wed Sep 22 23:37:20 2010 +0100
+++ b/omap3530/shared/serialkeyb/serialkeyboard.cpp Tue Sep 28 02:37:35 2010 +0100
@@ -323,7 +323,7 @@
static void UartIsr( TAny* aParam );
static void AddKeyDfc( TAny* aParam );
void AddKey( TUint aKey );
-
+
private:
enum TState
@@ -377,8 +377,6 @@
return r;
}
- Kern::Printf("+TSerialKeyboard::Create bound to interrupt" );
-
#ifdef USE_SYMBIAN_PRM
// Ask power resource manager to turn on clocks to the UART
// (this could take some time but we're not in any hurry)
@@ -407,7 +405,7 @@
void TSerialKeyboard::UartIsr( TAny* aParam )
{
TSerialKeyboard* self = reinterpret_cast<TSerialKeyboard*>( aParam );
-
+
const TUint iir = Omap3530Uart::IIR::iMem.Read( self->iUart );
if ( 0 == (iir bitand Omap3530Uart::IIR::IT_PENDING::KMask) )
@@ -419,7 +417,7 @@
if ( (pending bitand Omap3530Uart::IIR::IT_TYPE::ERHR) || (pending bitand Omap3530Uart::IIR::IT_TYPE::ERxLineStatus) )
{
TUint byte = self->iUart.Read();
-
+
if( KMagicCrashValue == byte )
{
Kern::Fault( "SERKEY-FORCED", 0 );
@@ -467,7 +465,7 @@
case EEscaping2:
{
TInt index = self->iKey - KEscapeBase;
-
+
if ( (index >= 0) && (index < KEscapeCount) )
{
self->AddKey( KEscapedScanCode[ index ] );
@@ -498,13 +496,13 @@
TRawEvent e;
-
+
if ( func )
{
e.Set( TRawEvent::EKeyDown, EStdKeyRightFunc, 0 );
Kern::AddEvent( e );
}
-
+
if ( ctrl )
{
e.Set( TRawEvent::EKeyDown, EStdKeyRightCtrl, 0 );