# HG changeset patch # User Lukasz Forynski # Date 1285637855 -3600 # Node ID 09e266454dcf3de83197952f83a243ec19066a9a # Parent bcf33365fd8d0bbd101520fed7cc5455c1b4eb9e 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 diff -r bcf33365fd8d -r 09e266454dcf omap3530/beagleboard/bootstrap/beagle.s --- 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 diff -r bcf33365fd8d -r 09e266454dcf omap3530/beagleboard/src/variant.cpp --- 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 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 (adjyearGetBusId()); - 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); diff -r bcf33365fd8d -r 09e266454dcf omap3530/omap3530_drivers/spi/master.h --- 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__ diff -r bcf33365fd8d -r 09e266454dcf omap3530/omap3530_drivers/spi/omap3530_spi.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 #include - #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::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__ */ diff -r bcf33365fd8d -r 09e266454dcf omap3530/omap3530_drivers/spi/omap3530_spi.inl --- 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) } } } diff -r bcf33365fd8d -r 09e266454dcf omap3530/omap3530_drivers/spi/psl_init.cpp --- 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__); diff -r bcf33365fd8d -r 09e266454dcf omap3530/omap3530_drivers/spi/psl_init.h --- 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 { diff -r bcf33365fd8d -r 09e266454dcf omap3530/omap3530_drivers/spi/spi.mmp --- 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" diff -r bcf33365fd8d -r 09e266454dcf omap3530/omap3530_drivers/spi/test/d_spi_client_m.cpp --- 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 diff -r bcf33365fd8d -r 09e266454dcf omap3530/shared/serialkeyb/serialkeyboard.cpp --- 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( 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 );